clang  7.0.0
SemaOpenMP.cpp
Go to the documentation of this file.
1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 /// \file
10 /// This file implements semantic analysis for OpenMP directives and
11 /// clauses.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #include "TreeTransform.h"
16 #include "clang/AST/ASTContext.h"
19 #include "clang/AST/Decl.h"
20 #include "clang/AST/DeclCXX.h"
21 #include "clang/AST/DeclOpenMP.h"
22 #include "clang/AST/StmtCXX.h"
23 #include "clang/AST/StmtOpenMP.h"
24 #include "clang/AST/StmtVisitor.h"
27 #include "clang/Sema/Lookup.h"
28 #include "clang/Sema/Scope.h"
29 #include "clang/Sema/ScopeInfo.h"
31 #include "llvm/ADT/PointerEmbeddedInt.h"
32 using namespace clang;
33 
34 //===----------------------------------------------------------------------===//
35 // Stack of data-sharing attributes for variables
36 //===----------------------------------------------------------------------===//
37 
39  Sema &SemaRef, Expr *E,
41  OpenMPClauseKind CKind, bool NoDiagnose);
42 
43 namespace {
44 /// Default data sharing attributes, which can be applied to directive.
46  DSA_unspecified = 0, /// Data sharing attribute not specified.
47  DSA_none = 1 << 0, /// Default data sharing attribute 'none'.
48  DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'.
49 };
50 
51 /// Attributes of the defaultmap clause.
53  DMA_unspecified, /// Default mapping is not specified.
54  DMA_tofrom_scalar, /// Default mapping is 'tofrom:scalar'.
55 };
56 
57 /// Stack for tracking declarations used in OpenMP directives and
58 /// clauses and their data-sharing attributes.
59 class DSAStackTy {
60 public:
61  struct DSAVarData {
64  const Expr *RefExpr = nullptr;
65  DeclRefExpr *PrivateCopy = nullptr;
66  SourceLocation ImplicitDSALoc;
67  DSAVarData() = default;
68  DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
69  const Expr *RefExpr, DeclRefExpr *PrivateCopy,
70  SourceLocation ImplicitDSALoc)
71  : DKind(DKind), CKind(CKind), RefExpr(RefExpr),
72  PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {}
73  };
74  using OperatorOffsetTy =
76  using DoacrossDependMapTy =
77  llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
78 
79 private:
80  struct DSAInfo {
81  OpenMPClauseKind Attributes = OMPC_unknown;
82  /// Pointer to a reference expression and a flag which shows that the
83  /// variable is marked as lastprivate(true) or not (false).
84  llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
85  DeclRefExpr *PrivateCopy = nullptr;
86  };
87  using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
88  using AlignedMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
89  using LCDeclInfo = std::pair<unsigned, VarDecl *>;
90  using LoopControlVariablesMapTy =
91  llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
92  /// Struct that associates a component with the clause kind where they are
93  /// found.
94  struct MappedExprComponentTy {
97  };
98  using MappedExprComponentsTy =
99  llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
100  using CriticalsWithHintsTy =
101  llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
102  struct ReductionData {
103  using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
104  SourceRange ReductionRange;
105  llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
106  ReductionData() = default;
107  void set(BinaryOperatorKind BO, SourceRange RR) {
108  ReductionRange = RR;
109  ReductionOp = BO;
110  }
111  void set(const Expr *RefExpr, SourceRange RR) {
112  ReductionRange = RR;
113  ReductionOp = RefExpr;
114  }
115  };
116  using DeclReductionMapTy =
117  llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
118 
119  struct SharingMapTy {
120  DeclSAMapTy SharingMap;
121  DeclReductionMapTy ReductionMap;
122  AlignedMapTy AlignedMap;
123  MappedExprComponentsTy MappedExprComponents;
124  LoopControlVariablesMapTy LCVMap;
125  DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
126  SourceLocation DefaultAttrLoc;
127  DefaultMapAttributes DefaultMapAttr = DMA_unspecified;
128  SourceLocation DefaultMapAttrLoc;
130  DeclarationNameInfo DirectiveName;
131  Scope *CurScope = nullptr;
132  SourceLocation ConstructLoc;
133  /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
134  /// get the data (loop counters etc.) about enclosing loop-based construct.
135  /// This data is required during codegen.
136  DoacrossDependMapTy DoacrossDepends;
137  /// first argument (Expr *) contains optional argument of the
138  /// 'ordered' clause, the second one is true if the regions has 'ordered'
139  /// clause, false otherwise.
141  bool NowaitRegion = false;
142  bool CancelRegion = false;
143  unsigned AssociatedLoops = 1;
144  SourceLocation InnerTeamsRegionLoc;
145  /// Reference to the taskgroup task_reduction reference expression.
146  Expr *TaskgroupReductionRef = nullptr;
147  SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
148  Scope *CurScope, SourceLocation Loc)
149  : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
150  ConstructLoc(Loc) {}
151  SharingMapTy() = default;
152  };
153 
154  using StackTy = SmallVector<SharingMapTy, 4>;
155 
156  /// Stack of used declaration and their data-sharing attributes.
157  DeclSAMapTy Threadprivates;
158  const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
160  /// true, if check for DSA must be from parent directive, false, if
161  /// from current directive.
162  OpenMPClauseKind ClauseKindMode = OMPC_unknown;
163  Sema &SemaRef;
164  bool ForceCapturing = false;
165  CriticalsWithHintsTy Criticals;
166 
167  using iterator = StackTy::const_reverse_iterator;
168 
169  DSAVarData getDSA(iterator &Iter, ValueDecl *D) const;
170 
171  /// Checks if the variable is a local for OpenMP region.
172  bool isOpenMPLocal(VarDecl *D, iterator Iter) const;
173 
174  bool isStackEmpty() const {
175  return Stack.empty() ||
176  Stack.back().second != CurrentNonCapturingFunctionScope ||
177  Stack.back().first.empty();
178  }
179 
180 public:
181  explicit DSAStackTy(Sema &S) : SemaRef(S) {}
182 
183  bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
184  OpenMPClauseKind getClauseParsingMode() const {
185  assert(isClauseParsingMode() && "Must be in clause parsing mode.");
186  return ClauseKindMode;
187  }
188  void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
189 
190  bool isForceVarCapturing() const { return ForceCapturing; }
191  void setForceVarCapturing(bool V) { ForceCapturing = V; }
192 
193  void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
194  Scope *CurScope, SourceLocation Loc) {
195  if (Stack.empty() ||
196  Stack.back().second != CurrentNonCapturingFunctionScope)
197  Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
198  Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
199  Stack.back().first.back().DefaultAttrLoc = Loc;
200  }
201 
202  void pop() {
203  assert(!Stack.back().first.empty() &&
204  "Data-sharing attributes stack is empty!");
205  Stack.back().first.pop_back();
206  }
207 
208  /// Start new OpenMP region stack in new non-capturing function.
209  void pushFunction() {
210  const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
211  assert(!isa<CapturingScopeInfo>(CurFnScope));
212  CurrentNonCapturingFunctionScope = CurFnScope;
213  }
214  /// Pop region stack for non-capturing function.
215  void popFunction(const FunctionScopeInfo *OldFSI) {
216  if (!Stack.empty() && Stack.back().second == OldFSI) {
217  assert(Stack.back().first.empty());
218  Stack.pop_back();
219  }
220  CurrentNonCapturingFunctionScope = nullptr;
221  for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
222  if (!isa<CapturingScopeInfo>(FSI)) {
223  CurrentNonCapturingFunctionScope = FSI;
224  break;
225  }
226  }
227  }
228 
229  void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) {
230  Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
231  }
232  const std::pair<const OMPCriticalDirective *, llvm::APSInt>
233  getCriticalWithHint(const DeclarationNameInfo &Name) const {
234  auto I = Criticals.find(Name.getAsString());
235  if (I != Criticals.end())
236  return I->second;
237  return std::make_pair(nullptr, llvm::APSInt());
238  }
239  /// If 'aligned' declaration for given variable \a D was not seen yet,
240  /// add it and return NULL; otherwise return previous occurrence's expression
241  /// for diagnostics.
242  const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE);
243 
244  /// Register specified variable as loop control variable.
245  void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture);
246  /// Check if the specified variable is a loop control variable for
247  /// current region.
248  /// \return The index of the loop control variable in the list of associated
249  /// for-loops (from outer to inner).
250  const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const;
251  /// Check if the specified variable is a loop control variable for
252  /// parent region.
253  /// \return The index of the loop control variable in the list of associated
254  /// for-loops (from outer to inner).
255  const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const;
256  /// Get the loop control variable for the I-th loop (or nullptr) in
257  /// parent directive.
258  const ValueDecl *getParentLoopControlVariable(unsigned I) const;
259 
260  /// Adds explicit data sharing attribute to the specified declaration.
261  void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
262  DeclRefExpr *PrivateCopy = nullptr);
263 
264  /// Adds additional information for the reduction items with the reduction id
265  /// represented as an operator.
266  void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
267  BinaryOperatorKind BOK);
268  /// Adds additional information for the reduction items with the reduction id
269  /// represented as reduction identifier.
270  void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
271  const Expr *ReductionRef);
272  /// Returns the location and reduction operation from the innermost parent
273  /// region for the given \p D.
274  const DSAVarData
275  getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
276  BinaryOperatorKind &BOK,
277  Expr *&TaskgroupDescriptor) const;
278  /// Returns the location and reduction operation from the innermost parent
279  /// region for the given \p D.
280  const DSAVarData
281  getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
282  const Expr *&ReductionRef,
283  Expr *&TaskgroupDescriptor) const;
284  /// Return reduction reference expression for the current taskgroup.
285  Expr *getTaskgroupReductionRef() const {
286  assert(Stack.back().first.back().Directive == OMPD_taskgroup &&
287  "taskgroup reference expression requested for non taskgroup "
288  "directive.");
289  return Stack.back().first.back().TaskgroupReductionRef;
290  }
291  /// Checks if the given \p VD declaration is actually a taskgroup reduction
292  /// descriptor variable at the \p Level of OpenMP regions.
293  bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
294  return Stack.back().first[Level].TaskgroupReductionRef &&
295  cast<DeclRefExpr>(Stack.back().first[Level].TaskgroupReductionRef)
296  ->getDecl() == VD;
297  }
298 
299  /// Returns data sharing attributes from top of the stack for the
300  /// specified declaration.
301  const DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
302  /// Returns data-sharing attributes for the specified declaration.
303  const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const;
304  /// Checks if the specified variables has data-sharing attributes which
305  /// match specified \a CPred predicate in any directive which matches \a DPred
306  /// predicate.
307  const DSAVarData
308  hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
309  const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
310  bool FromParent) const;
311  /// Checks if the specified variables has data-sharing attributes which
312  /// match specified \a CPred predicate in any innermost directive which
313  /// matches \a DPred predicate.
314  const DSAVarData
315  hasInnermostDSA(ValueDecl *D,
316  const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
317  const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
318  bool FromParent) const;
319  /// Checks if the specified variables has explicit data-sharing
320  /// attributes which match specified \a CPred predicate at the specified
321  /// OpenMP region.
322  bool hasExplicitDSA(const ValueDecl *D,
323  const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
324  unsigned Level, bool NotLastprivate = false) const;
325 
326  /// Returns true if the directive at level \Level matches in the
327  /// specified \a DPred predicate.
328  bool hasExplicitDirective(
329  const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
330  unsigned Level) const;
331 
332  /// Finds a directive which matches specified \a DPred predicate.
333  bool hasDirective(
334  const llvm::function_ref<bool(
336  DPred,
337  bool FromParent) const;
338 
339  /// Returns currently analyzed directive.
340  OpenMPDirectiveKind getCurrentDirective() const {
341  return isStackEmpty() ? OMPD_unknown : Stack.back().first.back().Directive;
342  }
343  /// Returns directive kind at specified level.
344  OpenMPDirectiveKind getDirective(unsigned Level) const {
345  assert(!isStackEmpty() && "No directive at specified level.");
346  return Stack.back().first[Level].Directive;
347  }
348  /// Returns parent directive.
349  OpenMPDirectiveKind getParentDirective() const {
350  if (isStackEmpty() || Stack.back().first.size() == 1)
351  return OMPD_unknown;
352  return std::next(Stack.back().first.rbegin())->Directive;
353  }
354 
355  /// Set default data sharing attribute to none.
356  void setDefaultDSANone(SourceLocation Loc) {
357  assert(!isStackEmpty());
358  Stack.back().first.back().DefaultAttr = DSA_none;
359  Stack.back().first.back().DefaultAttrLoc = Loc;
360  }
361  /// Set default data sharing attribute to shared.
362  void setDefaultDSAShared(SourceLocation Loc) {
363  assert(!isStackEmpty());
364  Stack.back().first.back().DefaultAttr = DSA_shared;
365  Stack.back().first.back().DefaultAttrLoc = Loc;
366  }
367  /// Set default data mapping attribute to 'tofrom:scalar'.
368  void setDefaultDMAToFromScalar(SourceLocation Loc) {
369  assert(!isStackEmpty());
370  Stack.back().first.back().DefaultMapAttr = DMA_tofrom_scalar;
371  Stack.back().first.back().DefaultMapAttrLoc = Loc;
372  }
373 
374  DefaultDataSharingAttributes getDefaultDSA() const {
375  return isStackEmpty() ? DSA_unspecified
376  : Stack.back().first.back().DefaultAttr;
377  }
378  SourceLocation getDefaultDSALocation() const {
379  return isStackEmpty() ? SourceLocation()
380  : Stack.back().first.back().DefaultAttrLoc;
381  }
382  DefaultMapAttributes getDefaultDMA() const {
383  return isStackEmpty() ? DMA_unspecified
384  : Stack.back().first.back().DefaultMapAttr;
385  }
386  DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const {
387  return Stack.back().first[Level].DefaultMapAttr;
388  }
389  SourceLocation getDefaultDMALocation() const {
390  return isStackEmpty() ? SourceLocation()
391  : Stack.back().first.back().DefaultMapAttrLoc;
392  }
393 
394  /// Checks if the specified variable is a threadprivate.
395  bool isThreadPrivate(VarDecl *D) {
396  const DSAVarData DVar = getTopDSA(D, false);
397  return isOpenMPThreadPrivate(DVar.CKind);
398  }
399 
400  /// Marks current region as ordered (it has an 'ordered' clause).
401  void setOrderedRegion(bool IsOrdered, const Expr *Param,
402  OMPOrderedClause *Clause) {
403  assert(!isStackEmpty());
404  if (IsOrdered)
405  Stack.back().first.back().OrderedRegion.emplace(Param, Clause);
406  else
407  Stack.back().first.back().OrderedRegion.reset();
408  }
409  /// Returns true, if region is ordered (has associated 'ordered' clause),
410  /// false - otherwise.
411  bool isOrderedRegion() const {
412  if (isStackEmpty())
413  return false;
414  return Stack.back().first.rbegin()->OrderedRegion.hasValue();
415  }
416  /// Returns optional parameter for the ordered region.
417  std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
418  if (isStackEmpty() ||
419  !Stack.back().first.rbegin()->OrderedRegion.hasValue())
420  return std::make_pair(nullptr, nullptr);
421  return Stack.back().first.rbegin()->OrderedRegion.getValue();
422  }
423  /// Returns true, if parent region is ordered (has associated
424  /// 'ordered' clause), false - otherwise.
425  bool isParentOrderedRegion() const {
426  if (isStackEmpty() || Stack.back().first.size() == 1)
427  return false;
428  return std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue();
429  }
430  /// Returns optional parameter for the ordered region.
431  std::pair<const Expr *, OMPOrderedClause *>
432  getParentOrderedRegionParam() const {
433  if (isStackEmpty() || Stack.back().first.size() == 1 ||
434  !std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue())
435  return std::make_pair(nullptr, nullptr);
436  return std::next(Stack.back().first.rbegin())->OrderedRegion.getValue();
437  }
438  /// Marks current region as nowait (it has a 'nowait' clause).
439  void setNowaitRegion(bool IsNowait = true) {
440  assert(!isStackEmpty());
441  Stack.back().first.back().NowaitRegion = IsNowait;
442  }
443  /// Returns true, if parent region is nowait (has associated
444  /// 'nowait' clause), false - otherwise.
445  bool isParentNowaitRegion() const {
446  if (isStackEmpty() || Stack.back().first.size() == 1)
447  return false;
448  return std::next(Stack.back().first.rbegin())->NowaitRegion;
449  }
450  /// Marks parent region as cancel region.
451  void setParentCancelRegion(bool Cancel = true) {
452  if (!isStackEmpty() && Stack.back().first.size() > 1) {
453  auto &StackElemRef = *std::next(Stack.back().first.rbegin());
454  StackElemRef.CancelRegion |= StackElemRef.CancelRegion || Cancel;
455  }
456  }
457  /// Return true if current region has inner cancel construct.
458  bool isCancelRegion() const {
459  return isStackEmpty() ? false : Stack.back().first.back().CancelRegion;
460  }
461 
462  /// Set collapse value for the region.
463  void setAssociatedLoops(unsigned Val) {
464  assert(!isStackEmpty());
465  Stack.back().first.back().AssociatedLoops = Val;
466  }
467  /// Return collapse value for region.
468  unsigned getAssociatedLoops() const {
469  return isStackEmpty() ? 0 : Stack.back().first.back().AssociatedLoops;
470  }
471 
472  /// Marks current target region as one with closely nested teams
473  /// region.
474  void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
475  if (!isStackEmpty() && Stack.back().first.size() > 1) {
476  std::next(Stack.back().first.rbegin())->InnerTeamsRegionLoc =
477  TeamsRegionLoc;
478  }
479  }
480  /// Returns true, if current region has closely nested teams region.
481  bool hasInnerTeamsRegion() const {
482  return getInnerTeamsRegionLoc().isValid();
483  }
484  /// Returns location of the nested teams region (if any).
485  SourceLocation getInnerTeamsRegionLoc() const {
486  return isStackEmpty() ? SourceLocation()
487  : Stack.back().first.back().InnerTeamsRegionLoc;
488  }
489 
490  Scope *getCurScope() const {
491  return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope;
492  }
493  SourceLocation getConstructLoc() const {
494  return isStackEmpty() ? SourceLocation()
495  : Stack.back().first.back().ConstructLoc;
496  }
497 
498  /// Do the check specified in \a Check to all component lists and return true
499  /// if any issue is found.
500  bool checkMappableExprComponentListsForDecl(
501  const ValueDecl *VD, bool CurrentRegionOnly,
502  const llvm::function_ref<
505  Check) const {
506  if (isStackEmpty())
507  return false;
508  auto SI = Stack.back().first.rbegin();
509  auto SE = Stack.back().first.rend();
510 
511  if (SI == SE)
512  return false;
513 
514  if (CurrentRegionOnly)
515  SE = std::next(SI);
516  else
517  std::advance(SI, 1);
518 
519  for (; SI != SE; ++SI) {
520  auto MI = SI->MappedExprComponents.find(VD);
521  if (MI != SI->MappedExprComponents.end())
523  MI->second.Components)
524  if (Check(L, MI->second.Kind))
525  return true;
526  }
527  return false;
528  }
529 
530  /// Do the check specified in \a Check to all component lists at a given level
531  /// and return true if any issue is found.
532  bool checkMappableExprComponentListsForDeclAtLevel(
533  const ValueDecl *VD, unsigned Level,
534  const llvm::function_ref<
537  Check) const {
538  if (isStackEmpty())
539  return false;
540 
541  auto StartI = Stack.back().first.begin();
542  auto EndI = Stack.back().first.end();
543  if (std::distance(StartI, EndI) <= (int)Level)
544  return false;
545  std::advance(StartI, Level);
546 
547  auto MI = StartI->MappedExprComponents.find(VD);
548  if (MI != StartI->MappedExprComponents.end())
550  MI->second.Components)
551  if (Check(L, MI->second.Kind))
552  return true;
553  return false;
554  }
555 
556  /// Create a new mappable expression component list associated with a given
557  /// declaration and initialize it with the provided list of components.
558  void addMappableExpressionComponents(
559  const ValueDecl *VD,
561  OpenMPClauseKind WhereFoundClauseKind) {
562  assert(!isStackEmpty() &&
563  "Not expecting to retrieve components from a empty stack!");
564  MappedExprComponentTy &MEC =
565  Stack.back().first.back().MappedExprComponents[VD];
566  // Create new entry and append the new components there.
567  MEC.Components.resize(MEC.Components.size() + 1);
568  MEC.Components.back().append(Components.begin(), Components.end());
569  MEC.Kind = WhereFoundClauseKind;
570  }
571 
572  unsigned getNestingLevel() const {
573  assert(!isStackEmpty());
574  return Stack.back().first.size() - 1;
575  }
576  void addDoacrossDependClause(OMPDependClause *C,
577  const OperatorOffsetTy &OpsOffs) {
578  assert(!isStackEmpty() && Stack.back().first.size() > 1);
579  SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin());
580  assert(isOpenMPWorksharingDirective(StackElem.Directive));
581  StackElem.DoacrossDepends.try_emplace(C, OpsOffs);
582  }
583  llvm::iterator_range<DoacrossDependMapTy::const_iterator>
584  getDoacrossDependClauses() const {
585  assert(!isStackEmpty());
586  const SharingMapTy &StackElem = Stack.back().first.back();
587  if (isOpenMPWorksharingDirective(StackElem.Directive)) {
588  const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
589  return llvm::make_range(Ref.begin(), Ref.end());
590  }
591  return llvm::make_range(StackElem.DoacrossDepends.end(),
592  StackElem.DoacrossDepends.end());
593  }
594 };
595 bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) {
596  return isOpenMPParallelDirective(DKind) || isOpenMPTaskingDirective(DKind) ||
597  isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown;
598 }
599 
600 } // namespace
601 
602 static const Expr *getExprAsWritten(const Expr *E) {
603  if (const auto *ExprTemp = dyn_cast<ExprWithCleanups>(E))
604  E = ExprTemp->getSubExpr();
605 
606  if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
607  E = MTE->GetTemporaryExpr();
608 
609  while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
610  E = Binder->getSubExpr();
611 
612  if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
613  E = ICE->getSubExprAsWritten();
614  return E->IgnoreParens();
615 }
616 
618  return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
619 }
620 
621 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
622  if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
623  if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
624  D = ME->getMemberDecl();
625  const auto *VD = dyn_cast<VarDecl>(D);
626  const auto *FD = dyn_cast<FieldDecl>(D);
627  if (VD != nullptr) {
628  VD = VD->getCanonicalDecl();
629  D = VD;
630  } else {
631  assert(FD);
632  FD = FD->getCanonicalDecl();
633  D = FD;
634  }
635  return D;
636 }
637 
639  return const_cast<ValueDecl *>(
640  getCanonicalDecl(const_cast<const ValueDecl *>(D)));
641 }
642 
643 DSAStackTy::DSAVarData DSAStackTy::getDSA(iterator &Iter,
644  ValueDecl *D) const {
645  D = getCanonicalDecl(D);
646  auto *VD = dyn_cast<VarDecl>(D);
647  const auto *FD = dyn_cast<FieldDecl>(D);
648  DSAVarData DVar;
649  if (isStackEmpty() || Iter == Stack.back().first.rend()) {
650  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
651  // in a region but not in construct]
652  // File-scope or namespace-scope variables referenced in called routines
653  // in the region are shared unless they appear in a threadprivate
654  // directive.
655  if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
656  DVar.CKind = OMPC_shared;
657 
658  // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
659  // in a region but not in construct]
660  // Variables with static storage duration that are declared in called
661  // routines in the region are shared.
662  if (VD && VD->hasGlobalStorage())
663  DVar.CKind = OMPC_shared;
664 
665  // Non-static data members are shared by default.
666  if (FD)
667  DVar.CKind = OMPC_shared;
668 
669  return DVar;
670  }
671 
672  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
673  // in a Construct, C/C++, predetermined, p.1]
674  // Variables with automatic storage duration that are declared in a scope
675  // inside the construct are private.
676  if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
677  (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
678  DVar.CKind = OMPC_private;
679  return DVar;
680  }
681 
682  DVar.DKind = Iter->Directive;
683  // Explicitly specified attributes and local variables with predetermined
684  // attributes.
685  if (Iter->SharingMap.count(D)) {
686  const DSAInfo &Data = Iter->SharingMap.lookup(D);
687  DVar.RefExpr = Data.RefExpr.getPointer();
688  DVar.PrivateCopy = Data.PrivateCopy;
689  DVar.CKind = Data.Attributes;
690  DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
691  return DVar;
692  }
693 
694  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
695  // in a Construct, C/C++, implicitly determined, p.1]
696  // In a parallel or task construct, the data-sharing attributes of these
697  // variables are determined by the default clause, if present.
698  switch (Iter->DefaultAttr) {
699  case DSA_shared:
700  DVar.CKind = OMPC_shared;
701  DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
702  return DVar;
703  case DSA_none:
704  return DVar;
705  case DSA_unspecified:
706  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
707  // in a Construct, implicitly determined, p.2]
708  // In a parallel construct, if no default clause is present, these
709  // variables are shared.
710  DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
711  if (isOpenMPParallelDirective(DVar.DKind) ||
712  isOpenMPTeamsDirective(DVar.DKind)) {
713  DVar.CKind = OMPC_shared;
714  return DVar;
715  }
716 
717  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
718  // in a Construct, implicitly determined, p.4]
719  // In a task construct, if no default clause is present, a variable that in
720  // the enclosing context is determined to be shared by all implicit tasks
721  // bound to the current team is shared.
722  if (isOpenMPTaskingDirective(DVar.DKind)) {
723  DSAVarData DVarTemp;
724  iterator I = Iter, E = Stack.back().first.rend();
725  do {
726  ++I;
727  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
728  // Referenced in a Construct, implicitly determined, p.6]
729  // In a task construct, if no default clause is present, a variable
730  // whose data-sharing attribute is not determined by the rules above is
731  // firstprivate.
732  DVarTemp = getDSA(I, D);
733  if (DVarTemp.CKind != OMPC_shared) {
734  DVar.RefExpr = nullptr;
735  DVar.CKind = OMPC_firstprivate;
736  return DVar;
737  }
738  } while (I != E && !isParallelOrTaskRegion(I->Directive));
739  DVar.CKind =
740  (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
741  return DVar;
742  }
743  }
744  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
745  // in a Construct, implicitly determined, p.3]
746  // For constructs other than task, if no default clause is present, these
747  // variables inherit their data-sharing attributes from the enclosing
748  // context.
749  return getDSA(++Iter, D);
750 }
751 
752 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
753  const Expr *NewDE) {
754  assert(!isStackEmpty() && "Data sharing attributes stack is empty");
755  D = getCanonicalDecl(D);
756  SharingMapTy &StackElem = Stack.back().first.back();
757  auto It = StackElem.AlignedMap.find(D);
758  if (It == StackElem.AlignedMap.end()) {
759  assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
760  StackElem.AlignedMap[D] = NewDE;
761  return nullptr;
762  }
763  assert(It->second && "Unexpected nullptr expr in the aligned map");
764  return It->second;
765 }
766 
767 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
768  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
769  D = getCanonicalDecl(D);
770  SharingMapTy &StackElem = Stack.back().first.back();
771  StackElem.LCVMap.try_emplace(
772  D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
773 }
774 
775 const DSAStackTy::LCDeclInfo
776 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
777  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
778  D = getCanonicalDecl(D);
779  const SharingMapTy &StackElem = Stack.back().first.back();
780  auto It = StackElem.LCVMap.find(D);
781  if (It != StackElem.LCVMap.end())
782  return It->second;
783  return {0, nullptr};
784 }
785 
786 const DSAStackTy::LCDeclInfo
787 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
788  assert(!isStackEmpty() && Stack.back().first.size() > 1 &&
789  "Data-sharing attributes stack is empty");
790  D = getCanonicalDecl(D);
791  const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin());
792  auto It = StackElem.LCVMap.find(D);
793  if (It != StackElem.LCVMap.end())
794  return It->second;
795  return {0, nullptr};
796 }
797 
798 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
799  assert(!isStackEmpty() && Stack.back().first.size() > 1 &&
800  "Data-sharing attributes stack is empty");
801  const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin());
802  if (StackElem.LCVMap.size() < I)
803  return nullptr;
804  for (const auto &Pair : StackElem.LCVMap)
805  if (Pair.second.first == I)
806  return Pair.first;
807  return nullptr;
808 }
809 
810 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
811  DeclRefExpr *PrivateCopy) {
812  D = getCanonicalDecl(D);
813  if (A == OMPC_threadprivate) {
814  DSAInfo &Data = Threadprivates[D];
815  Data.Attributes = A;
816  Data.RefExpr.setPointer(E);
817  Data.PrivateCopy = nullptr;
818  } else {
819  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
820  DSAInfo &Data = Stack.back().first.back().SharingMap[D];
821  assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
822  (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
823  (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
824  (isLoopControlVariable(D).first && A == OMPC_private));
825  if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
826  Data.RefExpr.setInt(/*IntVal=*/true);
827  return;
828  }
829  const bool IsLastprivate =
830  A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
831  Data.Attributes = A;
832  Data.RefExpr.setPointerAndInt(E, IsLastprivate);
833  Data.PrivateCopy = PrivateCopy;
834  if (PrivateCopy) {
835  DSAInfo &Data =
836  Stack.back().first.back().SharingMap[PrivateCopy->getDecl()];
837  Data.Attributes = A;
838  Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
839  Data.PrivateCopy = nullptr;
840  }
841  }
842 }
843 
844 /// Build a variable declaration for OpenMP loop iteration variable.
846  StringRef Name, const AttrVec *Attrs = nullptr,
847  DeclRefExpr *OrigRef = nullptr) {
848  DeclContext *DC = SemaRef.CurContext;
849  IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
850  TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
851  auto *Decl =
852  VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
853  if (Attrs) {
854  for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
855  I != E; ++I)
856  Decl->addAttr(*I);
857  }
858  Decl->setImplicit();
859  if (OrigRef) {
860  Decl->addAttr(
861  OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
862  }
863  return Decl;
864 }
865 
867  SourceLocation Loc,
868  bool RefersToCapture = false) {
869  D->setReferenced();
870  D->markUsed(S.Context);
872  SourceLocation(), D, RefersToCapture, Loc, Ty,
873  VK_LValue);
874 }
875 
876 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
877  BinaryOperatorKind BOK) {
878  D = getCanonicalDecl(D);
879  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
880  assert(
881  Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction &&
882  "Additional reduction info may be specified only for reduction items.");
883  ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D];
884  assert(ReductionData.ReductionRange.isInvalid() &&
885  Stack.back().first.back().Directive == OMPD_taskgroup &&
886  "Additional reduction info may be specified only once for reduction "
887  "items.");
888  ReductionData.set(BOK, SR);
889  Expr *&TaskgroupReductionRef =
890  Stack.back().first.back().TaskgroupReductionRef;
891  if (!TaskgroupReductionRef) {
892  VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
893  SemaRef.Context.VoidPtrTy, ".task_red.");
894  TaskgroupReductionRef =
895  buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
896  }
897 }
898 
899 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
900  const Expr *ReductionRef) {
901  D = getCanonicalDecl(D);
902  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
903  assert(
904  Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction &&
905  "Additional reduction info may be specified only for reduction items.");
906  ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D];
907  assert(ReductionData.ReductionRange.isInvalid() &&
908  Stack.back().first.back().Directive == OMPD_taskgroup &&
909  "Additional reduction info may be specified only once for reduction "
910  "items.");
911  ReductionData.set(ReductionRef, SR);
912  Expr *&TaskgroupReductionRef =
913  Stack.back().first.back().TaskgroupReductionRef;
914  if (!TaskgroupReductionRef) {
915  VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
916  SemaRef.Context.VoidPtrTy, ".task_red.");
917  TaskgroupReductionRef =
918  buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
919  }
920 }
921 
922 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
923  const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
924  Expr *&TaskgroupDescriptor) const {
925  D = getCanonicalDecl(D);
926  assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
927  if (Stack.back().first.empty())
928  return DSAVarData();
929  for (iterator I = std::next(Stack.back().first.rbegin(), 1),
930  E = Stack.back().first.rend();
931  I != E; std::advance(I, 1)) {
932  const DSAInfo &Data = I->SharingMap.lookup(D);
933  if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
934  continue;
935  const ReductionData &ReductionData = I->ReductionMap.lookup(D);
936  if (!ReductionData.ReductionOp ||
937  ReductionData.ReductionOp.is<const Expr *>())
938  return DSAVarData();
939  SR = ReductionData.ReductionRange;
940  BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
941  assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
942  "expression for the descriptor is not "
943  "set.");
944  TaskgroupDescriptor = I->TaskgroupReductionRef;
945  return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
946  Data.PrivateCopy, I->DefaultAttrLoc);
947  }
948  return DSAVarData();
949 }
950 
951 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
952  const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
953  Expr *&TaskgroupDescriptor) const {
954  D = getCanonicalDecl(D);
955  assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
956  if (Stack.back().first.empty())
957  return DSAVarData();
958  for (iterator I = std::next(Stack.back().first.rbegin(), 1),
959  E = Stack.back().first.rend();
960  I != E; std::advance(I, 1)) {
961  const DSAInfo &Data = I->SharingMap.lookup(D);
962  if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
963  continue;
964  const ReductionData &ReductionData = I->ReductionMap.lookup(D);
965  if (!ReductionData.ReductionOp ||
966  !ReductionData.ReductionOp.is<const Expr *>())
967  return DSAVarData();
968  SR = ReductionData.ReductionRange;
969  ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
970  assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
971  "expression for the descriptor is not "
972  "set.");
973  TaskgroupDescriptor = I->TaskgroupReductionRef;
974  return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
975  Data.PrivateCopy, I->DefaultAttrLoc);
976  }
977  return DSAVarData();
978 }
979 
980 bool DSAStackTy::isOpenMPLocal(VarDecl *D, iterator Iter) const {
981  D = D->getCanonicalDecl();
982  if (!isStackEmpty()) {
983  iterator I = Iter, E = Stack.back().first.rend();
984  Scope *TopScope = nullptr;
985  while (I != E && !isParallelOrTaskRegion(I->Directive) &&
986  !isOpenMPTargetExecutionDirective(I->Directive))
987  ++I;
988  if (I == E)
989  return false;
990  TopScope = I->CurScope ? I->CurScope->getParent() : nullptr;
991  Scope *CurScope = getCurScope();
992  while (CurScope != TopScope && !CurScope->isDeclScope(D))
993  CurScope = CurScope->getParent();
994  return CurScope != TopScope;
995  }
996  return false;
997 }
998 
999 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1000  bool FromParent) {
1001  D = getCanonicalDecl(D);
1002  DSAVarData DVar;
1003 
1004  auto *VD = dyn_cast<VarDecl>(D);
1005  auto TI = Threadprivates.find(D);
1006  if (TI != Threadprivates.end()) {
1007  DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1008  DVar.CKind = OMPC_threadprivate;
1009  return DVar;
1010  }
1011  if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1012  DVar.RefExpr = buildDeclRefExpr(
1013  SemaRef, VD, D->getType().getNonReferenceType(),
1014  VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1015  DVar.CKind = OMPC_threadprivate;
1016  addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1017  return DVar;
1018  }
1019  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1020  // in a Construct, C/C++, predetermined, p.1]
1021  // Variables appearing in threadprivate directives are threadprivate.
1022  if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1023  !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1024  SemaRef.getLangOpts().OpenMPUseTLS &&
1025  SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1026  (VD && VD->getStorageClass() == SC_Register &&
1027  VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1028  DVar.RefExpr = buildDeclRefExpr(
1029  SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1030  DVar.CKind = OMPC_threadprivate;
1031  addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1032  return DVar;
1033  }
1034  if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1035  VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1036  !isLoopControlVariable(D).first) {
1037  iterator IterTarget =
1038  std::find_if(Stack.back().first.rbegin(), Stack.back().first.rend(),
1039  [](const SharingMapTy &Data) {
1040  return isOpenMPTargetExecutionDirective(Data.Directive);
1041  });
1042  if (IterTarget != Stack.back().first.rend()) {
1043  iterator ParentIterTarget = std::next(IterTarget, 1);
1044  for (iterator Iter = Stack.back().first.rbegin();
1045  Iter != ParentIterTarget; std::advance(Iter, 1)) {
1046  if (isOpenMPLocal(VD, Iter)) {
1047  DVar.RefExpr =
1048  buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1049  D->getLocation());
1050  DVar.CKind = OMPC_threadprivate;
1051  return DVar;
1052  }
1053  }
1054  if (!isClauseParsingMode() || IterTarget != Stack.back().first.rbegin()) {
1055  auto DSAIter = IterTarget->SharingMap.find(D);
1056  if (DSAIter != IterTarget->SharingMap.end() &&
1057  isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1058  DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1059  DVar.CKind = OMPC_threadprivate;
1060  return DVar;
1061  }
1062  iterator End = Stack.back().first.rend();
1063  if (!SemaRef.isOpenMPCapturedByRef(
1064  D, std::distance(ParentIterTarget, End))) {
1065  DVar.RefExpr =
1066  buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1067  IterTarget->ConstructLoc);
1068  DVar.CKind = OMPC_threadprivate;
1069  return DVar;
1070  }
1071  }
1072  }
1073  }
1074 
1075  if (isStackEmpty())
1076  // Not in OpenMP execution region and top scope was already checked.
1077  return DVar;
1078 
1079  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1080  // in a Construct, C/C++, predetermined, p.4]
1081  // Static data members are shared.
1082  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1083  // in a Construct, C/C++, predetermined, p.7]
1084  // Variables with static storage duration that are declared in a scope
1085  // inside the construct are shared.
1086  auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
1087  if (VD && VD->isStaticDataMember()) {
1088  DSAVarData DVarTemp = hasDSA(D, isOpenMPPrivate, MatchesAlways, FromParent);
1089  if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1090  return DVar;
1091 
1092  DVar.CKind = OMPC_shared;
1093  return DVar;
1094  }
1095 
1097  bool IsConstant = Type.isConstant(SemaRef.getASTContext());
1098  Type = SemaRef.getASTContext().getBaseElementType(Type);
1099  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1100  // in a Construct, C/C++, predetermined, p.6]
1101  // Variables with const qualified type having no mutable member are
1102  // shared.
1103  const CXXRecordDecl *RD =
1104  SemaRef.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr;
1105  if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1106  if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1107  RD = CTD->getTemplatedDecl();
1108  if (IsConstant &&
1109  !(SemaRef.getLangOpts().CPlusPlus && RD && RD->hasDefinition() &&
1110  RD->hasMutableFields())) {
1111  // Variables with const-qualified type having no mutable member may be
1112  // listed in a firstprivate clause, even if they are static data members.
1113  DSAVarData DVarTemp =
1114  hasDSA(D, [](OpenMPClauseKind C) { return C == OMPC_firstprivate; },
1115  MatchesAlways, FromParent);
1116  if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr)
1117  return DVarTemp;
1118 
1119  DVar.CKind = OMPC_shared;
1120  return DVar;
1121  }
1122 
1123  // Explicitly specified attributes and local variables with predetermined
1124  // attributes.
1125  iterator I = Stack.back().first.rbegin();
1126  iterator EndI = Stack.back().first.rend();
1127  if (FromParent && I != EndI)
1128  std::advance(I, 1);
1129  auto It = I->SharingMap.find(D);
1130  if (It != I->SharingMap.end()) {
1131  const DSAInfo &Data = It->getSecond();
1132  DVar.RefExpr = Data.RefExpr.getPointer();
1133  DVar.PrivateCopy = Data.PrivateCopy;
1134  DVar.CKind = Data.Attributes;
1135  DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1136  DVar.DKind = I->Directive;
1137  }
1138 
1139  return DVar;
1140 }
1141 
1142 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1143  bool FromParent) const {
1144  if (isStackEmpty()) {
1145  iterator I;
1146  return getDSA(I, D);
1147  }
1148  D = getCanonicalDecl(D);
1149  iterator StartI = Stack.back().first.rbegin();
1150  iterator EndI = Stack.back().first.rend();
1151  if (FromParent && StartI != EndI)
1152  std::advance(StartI, 1);
1153  return getDSA(StartI, D);
1154 }
1155 
1156 const DSAStackTy::DSAVarData
1157 DSAStackTy::hasDSA(ValueDecl *D,
1158  const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1159  const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1160  bool FromParent) const {
1161  if (isStackEmpty())
1162  return {};
1163  D = getCanonicalDecl(D);
1164  iterator I = Stack.back().first.rbegin();
1165  iterator EndI = Stack.back().first.rend();
1166  if (FromParent && I != EndI)
1167  std::advance(I, 1);
1168  for (; I != EndI; std::advance(I, 1)) {
1169  if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive))
1170  continue;
1171  iterator NewI = I;
1172  DSAVarData DVar = getDSA(NewI, D);
1173  if (I == NewI && CPred(DVar.CKind))
1174  return DVar;
1175  }
1176  return {};
1177 }
1178 
1179 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1180  ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1181  const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1182  bool FromParent) const {
1183  if (isStackEmpty())
1184  return {};
1185  D = getCanonicalDecl(D);
1186  iterator StartI = Stack.back().first.rbegin();
1187  iterator EndI = Stack.back().first.rend();
1188  if (FromParent && StartI != EndI)
1189  std::advance(StartI, 1);
1190  if (StartI == EndI || !DPred(StartI->Directive))
1191  return {};
1192  iterator NewI = StartI;
1193  DSAVarData DVar = getDSA(NewI, D);
1194  return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData();
1195 }
1196 
1197 bool DSAStackTy::hasExplicitDSA(
1198  const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1199  unsigned Level, bool NotLastprivate) const {
1200  if (isStackEmpty())
1201  return false;
1202  D = getCanonicalDecl(D);
1203  auto StartI = Stack.back().first.begin();
1204  auto EndI = Stack.back().first.end();
1205  if (std::distance(StartI, EndI) <= (int)Level)
1206  return false;
1207  std::advance(StartI, Level);
1208  auto I = StartI->SharingMap.find(D);
1209  return (I != StartI->SharingMap.end()) &&
1210  I->getSecond().RefExpr.getPointer() &&
1211  CPred(I->getSecond().Attributes) &&
1212  (!NotLastprivate || !I->getSecond().RefExpr.getInt());
1213 }
1214 
1215 bool DSAStackTy::hasExplicitDirective(
1216  const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1217  unsigned Level) const {
1218  if (isStackEmpty())
1219  return false;
1220  auto StartI = Stack.back().first.begin();
1221  auto EndI = Stack.back().first.end();
1222  if (std::distance(StartI, EndI) <= (int)Level)
1223  return false;
1224  std::advance(StartI, Level);
1225  return DPred(StartI->Directive);
1226 }
1227 
1228 bool DSAStackTy::hasDirective(
1229  const llvm::function_ref<bool(OpenMPDirectiveKind,
1231  DPred,
1232  bool FromParent) const {
1233  // We look only in the enclosing region.
1234  if (isStackEmpty())
1235  return false;
1236  auto StartI = std::next(Stack.back().first.rbegin());
1237  auto EndI = Stack.back().first.rend();
1238  if (FromParent && StartI != EndI)
1239  StartI = std::next(StartI);
1240  for (auto I = StartI, EE = EndI; I != EE; ++I) {
1241  if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1242  return true;
1243  }
1244  return false;
1245 }
1246 
1247 void Sema::InitDataSharingAttributesStack() {
1248  VarDataSharingAttributesStack = new DSAStackTy(*this);
1249 }
1250 
1251 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1252 
1253 void Sema::pushOpenMPFunctionRegion() {
1254  DSAStack->pushFunction();
1255 }
1256 
1257 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
1258  DSAStack->popFunction(OldFSI);
1259 }
1260 
1261 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level) const {
1262  assert(LangOpts.OpenMP && "OpenMP is not allowed");
1263 
1264  ASTContext &Ctx = getASTContext();
1265  bool IsByRef = true;
1266 
1267  // Find the directive that is associated with the provided scope.
1268  D = cast<ValueDecl>(D->getCanonicalDecl());
1269  QualType Ty = D->getType();
1270 
1271  if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
1272  // This table summarizes how a given variable should be passed to the device
1273  // given its type and the clauses where it appears. This table is based on
1274  // the description in OpenMP 4.5 [2.10.4, target Construct] and
1275  // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
1276  //
1277  // =========================================================================
1278  // | type | defaultmap | pvt | first | is_device_ptr | map | res. |
1279  // | |(tofrom:scalar)| | pvt | | | |
1280  // =========================================================================
1281  // | scl | | | | - | | bycopy|
1282  // | scl | | - | x | - | - | bycopy|
1283  // | scl | | x | - | - | - | null |
1284  // | scl | x | | | - | | byref |
1285  // | scl | x | - | x | - | - | bycopy|
1286  // | scl | x | x | - | - | - | null |
1287  // | scl | | - | - | - | x | byref |
1288  // | scl | x | - | - | - | x | byref |
1289  //
1290  // | agg | n.a. | | | - | | byref |
1291  // | agg | n.a. | - | x | - | - | byref |
1292  // | agg | n.a. | x | - | - | - | null |
1293  // | agg | n.a. | - | - | - | x | byref |
1294  // | agg | n.a. | - | - | - | x[] | byref |
1295  //
1296  // | ptr | n.a. | | | - | | bycopy|
1297  // | ptr | n.a. | - | x | - | - | bycopy|
1298  // | ptr | n.a. | x | - | - | - | null |
1299  // | ptr | n.a. | - | - | - | x | byref |
1300  // | ptr | n.a. | - | - | - | x[] | bycopy|
1301  // | ptr | n.a. | - | - | x | | bycopy|
1302  // | ptr | n.a. | - | - | x | x | bycopy|
1303  // | ptr | n.a. | - | - | x | x[] | bycopy|
1304  // =========================================================================
1305  // Legend:
1306  // scl - scalar
1307  // ptr - pointer
1308  // agg - aggregate
1309  // x - applies
1310  // - - invalid in this combination
1311  // [] - mapped with an array section
1312  // byref - should be mapped by reference
1313  // byval - should be mapped by value
1314  // null - initialize a local variable to null on the device
1315  //
1316  // Observations:
1317  // - All scalar declarations that show up in a map clause have to be passed
1318  // by reference, because they may have been mapped in the enclosing data
1319  // environment.
1320  // - If the scalar value does not fit the size of uintptr, it has to be
1321  // passed by reference, regardless the result in the table above.
1322  // - For pointers mapped by value that have either an implicit map or an
1323  // array section, the runtime library may pass the NULL value to the
1324  // device instead of the value passed to it by the compiler.
1325 
1326  if (Ty->isReferenceType())
1327  Ty = Ty->castAs<ReferenceType>()->getPointeeType();
1328 
1329  // Locate map clauses and see if the variable being captured is referred to
1330  // in any of those clauses. Here we only care about variables, not fields,
1331  // because fields are part of aggregates.
1332  bool IsVariableUsedInMapClause = false;
1333  bool IsVariableAssociatedWithSection = false;
1334 
1335  DSAStack->checkMappableExprComponentListsForDeclAtLevel(
1336  D, Level,
1337  [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D](
1339  MapExprComponents,
1340  OpenMPClauseKind WhereFoundClauseKind) {
1341  // Only the map clause information influences how a variable is
1342  // captured. E.g. is_device_ptr does not require changing the default
1343  // behavior.
1344  if (WhereFoundClauseKind != OMPC_map)
1345  return false;
1346 
1347  auto EI = MapExprComponents.rbegin();
1348  auto EE = MapExprComponents.rend();
1349 
1350  assert(EI != EE && "Invalid map expression!");
1351 
1352  if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
1353  IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
1354 
1355  ++EI;
1356  if (EI == EE)
1357  return false;
1358 
1359  if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
1360  isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
1361  isa<MemberExpr>(EI->getAssociatedExpression())) {
1362  IsVariableAssociatedWithSection = true;
1363  // There is nothing more we need to know about this variable.
1364  return true;
1365  }
1366 
1367  // Keep looking for more map info.
1368  return false;
1369  });
1370 
1371  if (IsVariableUsedInMapClause) {
1372  // If variable is identified in a map clause it is always captured by
1373  // reference except if it is a pointer that is dereferenced somehow.
1374  IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
1375  } else {
1376  // By default, all the data that has a scalar type is mapped by copy
1377  // (except for reduction variables).
1378  IsByRef =
1379  !Ty->isScalarType() ||
1380  DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar ||
1381  DSAStack->hasExplicitDSA(
1382  D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level);
1383  }
1384  }
1385 
1386  if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
1387  IsByRef =
1388  !DSAStack->hasExplicitDSA(
1389  D,
1390  [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; },
1391  Level, /*NotLastprivate=*/true) &&
1392  // If the variable is artificial and must be captured by value - try to
1393  // capture by value.
1394  !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
1395  !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue());
1396  }
1397 
1398  // When passing data by copy, we need to make sure it fits the uintptr size
1399  // and alignment, because the runtime library only deals with uintptr types.
1400  // If it does not fit the uintptr size, we need to pass the data by reference
1401  // instead.
1402  if (!IsByRef &&
1403  (Ctx.getTypeSizeInChars(Ty) >
1404  Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
1405  Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
1406  IsByRef = true;
1407  }
1408 
1409  return IsByRef;
1410 }
1411 
1412 unsigned Sema::getOpenMPNestingLevel() const {
1413  assert(getLangOpts().OpenMP);
1414  return DSAStack->getNestingLevel();
1415 }
1416 
1418  return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) &&
1419  !DSAStack->isClauseParsingMode()) ||
1420  DSAStack->hasDirective(
1422  SourceLocation) -> bool {
1423  return isOpenMPTargetExecutionDirective(K);
1424  },
1425  false);
1426 }
1427 
1429  assert(LangOpts.OpenMP && "OpenMP is not allowed");
1430  D = getCanonicalDecl(D);
1431 
1432  // If we are attempting to capture a global variable in a directive with
1433  // 'target' we return true so that this global is also mapped to the device.
1434  //
1435  auto *VD = dyn_cast<VarDecl>(D);
1436  if (VD && !VD->hasLocalStorage() && isInOpenMPTargetExecutionDirective()) {
1437  // If the declaration is enclosed in a 'declare target' directive,
1438  // then it should not be captured.
1439  //
1440  if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
1441  return nullptr;
1442  return VD;
1443  }
1444 
1445  if (DSAStack->getCurrentDirective() != OMPD_unknown &&
1446  (!DSAStack->isClauseParsingMode() ||
1447  DSAStack->getParentDirective() != OMPD_unknown)) {
1448  auto &&Info = DSAStack->isLoopControlVariable(D);
1449  if (Info.first ||
1450  (VD && VD->hasLocalStorage() &&
1451  isParallelOrTaskRegion(DSAStack->getCurrentDirective())) ||
1452  (VD && DSAStack->isForceVarCapturing()))
1453  return VD ? VD : Info.second;
1454  DSAStackTy::DSAVarData DVarPrivate =
1455  DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
1456  if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind))
1457  return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1458  DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate,
1459  [](OpenMPDirectiveKind) { return true; },
1460  DSAStack->isClauseParsingMode());
1461  if (DVarPrivate.CKind != OMPC_unknown)
1462  return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1463  }
1464  return nullptr;
1465 }
1466 
1467 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
1468  unsigned Level) const {
1470  getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level));
1471  FunctionScopesIndex -= Regions.size();
1472 }
1473 
1474 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const {
1475  assert(LangOpts.OpenMP && "OpenMP is not allowed");
1476  return DSAStack->hasExplicitDSA(
1477  D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) ||
1478  (DSAStack->isClauseParsingMode() &&
1479  DSAStack->getClauseParsingMode() == OMPC_private) ||
1480  // Consider taskgroup reduction descriptor variable a private to avoid
1481  // possible capture in the region.
1482  (DSAStack->hasExplicitDirective(
1483  [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; },
1484  Level) &&
1485  DSAStack->isTaskgroupReductionRef(D, Level));
1486 }
1487 
1489  unsigned Level) {
1490  assert(LangOpts.OpenMP && "OpenMP is not allowed");
1491  D = getCanonicalDecl(D);
1493  for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) {
1494  const unsigned NewLevel = I - 1;
1495  if (DSAStack->hasExplicitDSA(D,
1496  [&OMPC](const OpenMPClauseKind K) {
1497  if (isOpenMPPrivate(K)) {
1498  OMPC = K;
1499  return true;
1500  }
1501  return false;
1502  },
1503  NewLevel))
1504  break;
1505  if (DSAStack->checkMappableExprComponentListsForDeclAtLevel(
1506  D, NewLevel,
1508  OpenMPClauseKind) { return true; })) {
1509  OMPC = OMPC_map;
1510  break;
1511  }
1512  if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
1513  NewLevel)) {
1514  OMPC = OMPC_map;
1515  if (D->getType()->isScalarType() &&
1516  DSAStack->getDefaultDMAAtLevel(NewLevel) !=
1517  DefaultMapAttributes::DMA_tofrom_scalar)
1518  OMPC = OMPC_firstprivate;
1519  break;
1520  }
1521  }
1522  if (OMPC != OMPC_unknown)
1523  FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC));
1524 }
1525 
1527  unsigned Level) const {
1528  assert(LangOpts.OpenMP && "OpenMP is not allowed");
1529  // Return true if the current level is no longer enclosed in a target region.
1530 
1531  const auto *VD = dyn_cast<VarDecl>(D);
1532  return VD && !VD->hasLocalStorage() &&
1533  DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
1534  Level);
1535 }
1536 
1537 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
1538 
1540  const DeclarationNameInfo &DirName,
1541  Scope *CurScope, SourceLocation Loc) {
1542  DSAStack->push(DKind, DirName, CurScope, Loc);
1543  PushExpressionEvaluationContext(
1544  ExpressionEvaluationContext::PotentiallyEvaluated);
1545 }
1546 
1548  DSAStack->setClauseParsingMode(K);
1549 }
1550 
1552  DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
1553 }
1554 
1555 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
1556  // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
1557  // A variable of class type (or array thereof) that appears in a lastprivate
1558  // clause requires an accessible, unambiguous default constructor for the
1559  // class type, unless the list item is also specified in a firstprivate
1560  // clause.
1561  if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
1562  for (OMPClause *C : D->clauses()) {
1563  if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
1564  SmallVector<Expr *, 8> PrivateCopies;
1565  for (Expr *DE : Clause->varlists()) {
1566  if (DE->isValueDependent() || DE->isTypeDependent()) {
1567  PrivateCopies.push_back(nullptr);
1568  continue;
1569  }
1570  auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
1571  auto *VD = cast<VarDecl>(DRE->getDecl());
1572  QualType Type = VD->getType().getNonReferenceType();
1573  const DSAStackTy::DSAVarData DVar =
1574  DSAStack->getTopDSA(VD, /*FromParent=*/false);
1575  if (DVar.CKind == OMPC_lastprivate) {
1576  // Generate helper private variable and initialize it with the
1577  // default value. The address of the original variable is replaced
1578  // by the address of the new private variable in CodeGen. This new
1579  // variable is not added to IdResolver, so the code in the OpenMP
1580  // region uses original variable for proper diagnostics.
1581  VarDecl *VDPrivate = buildVarDecl(
1582  *this, DE->getExprLoc(), Type.getUnqualifiedType(),
1583  VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
1584  ActOnUninitializedDecl(VDPrivate);
1585  if (VDPrivate->isInvalidDecl())
1586  continue;
1587  PrivateCopies.push_back(buildDeclRefExpr(
1588  *this, VDPrivate, DE->getType(), DE->getExprLoc()));
1589  } else {
1590  // The variable is also a firstprivate, so initialization sequence
1591  // for private copy is generated already.
1592  PrivateCopies.push_back(nullptr);
1593  }
1594  }
1595  // Set initializers to private copies if no errors were found.
1596  if (PrivateCopies.size() == Clause->varlist_size())
1597  Clause->setPrivateCopies(PrivateCopies);
1598  }
1599  }
1600  }
1601 
1602  DSAStack->pop();
1603  DiscardCleanupsInEvaluationContext();
1604  PopExpressionEvaluationContext();
1605 }
1606 
1607 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
1608  Expr *NumIterations, Sema &SemaRef,
1609  Scope *S, DSAStackTy *Stack);
1610 
1611 namespace {
1612 
1613 class VarDeclFilterCCC final : public CorrectionCandidateCallback {
1614 private:
1615  Sema &SemaRef;
1616 
1617 public:
1618  explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
1619  bool ValidateCandidate(const TypoCorrection &Candidate) override {
1620  NamedDecl *ND = Candidate.getCorrectionDecl();
1621  if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
1622  return VD->hasGlobalStorage() &&
1623  SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
1624  SemaRef.getCurScope());
1625  }
1626  return false;
1627  }
1628 };
1629 
1630 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
1631 private:
1632  Sema &SemaRef;
1633 
1634 public:
1635  explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
1636  bool ValidateCandidate(const TypoCorrection &Candidate) override {
1637  NamedDecl *ND = Candidate.getCorrectionDecl();
1638  if (ND && (isa<VarDecl>(ND) || isa<FunctionDecl>(ND))) {
1639  return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
1640  SemaRef.getCurScope());
1641  }
1642  return false;
1643  }
1644 };
1645 
1646 } // namespace
1647 
1649  CXXScopeSpec &ScopeSpec,
1650  const DeclarationNameInfo &Id) {
1651  LookupResult Lookup(*this, Id, LookupOrdinaryName);
1652  LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
1653 
1654  if (Lookup.isAmbiguous())
1655  return ExprError();
1656 
1657  VarDecl *VD;
1658  if (!Lookup.isSingleResult()) {
1659  if (TypoCorrection Corrected = CorrectTypo(
1660  Id, LookupOrdinaryName, CurScope, nullptr,
1661  llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) {
1662  diagnoseTypo(Corrected,
1663  PDiag(Lookup.empty()
1664  ? diag::err_undeclared_var_use_suggest
1665  : diag::err_omp_expected_var_arg_suggest)
1666  << Id.getName());
1667  VD = Corrected.getCorrectionDeclAs<VarDecl>();
1668  } else {
1669  Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
1670  : diag::err_omp_expected_var_arg)
1671  << Id.getName();
1672  return ExprError();
1673  }
1674  } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
1675  Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
1676  Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
1677  return ExprError();
1678  }
1679  Lookup.suppressDiagnostics();
1680 
1681  // OpenMP [2.9.2, Syntax, C/C++]
1682  // Variables must be file-scope, namespace-scope, or static block-scope.
1683  if (!VD->hasGlobalStorage()) {
1684  Diag(Id.getLoc(), diag::err_omp_global_var_arg)
1685  << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal();
1686  bool IsDecl =
1688  Diag(VD->getLocation(),
1689  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1690  << VD;
1691  return ExprError();
1692  }
1693 
1694  VarDecl *CanonicalVD = VD->getCanonicalDecl();
1695  NamedDecl *ND = CanonicalVD;
1696  // OpenMP [2.9.2, Restrictions, C/C++, p.2]
1697  // A threadprivate directive for file-scope variables must appear outside
1698  // any definition or declaration.
1699  if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
1700  !getCurLexicalContext()->isTranslationUnit()) {
1701  Diag(Id.getLoc(), diag::err_omp_var_scope)
1702  << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1703  bool IsDecl =
1705  Diag(VD->getLocation(),
1706  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1707  << VD;
1708  return ExprError();
1709  }
1710  // OpenMP [2.9.2, Restrictions, C/C++, p.3]
1711  // A threadprivate directive for static class member variables must appear
1712  // in the class definition, in the same scope in which the member
1713  // variables are declared.
1714  if (CanonicalVD->isStaticDataMember() &&
1715  !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
1716  Diag(Id.getLoc(), diag::err_omp_var_scope)
1717  << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1718  bool IsDecl =
1720  Diag(VD->getLocation(),
1721  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1722  << VD;
1723  return ExprError();
1724  }
1725  // OpenMP [2.9.2, Restrictions, C/C++, p.4]
1726  // A threadprivate directive for namespace-scope variables must appear
1727  // outside any definition or declaration other than the namespace
1728  // definition itself.
1729  if (CanonicalVD->getDeclContext()->isNamespace() &&
1730  (!getCurLexicalContext()->isFileContext() ||
1731  !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
1732  Diag(Id.getLoc(), diag::err_omp_var_scope)
1733  << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1734  bool IsDecl =
1736  Diag(VD->getLocation(),
1737  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1738  << VD;
1739  return ExprError();
1740  }
1741  // OpenMP [2.9.2, Restrictions, C/C++, p.6]
1742  // A threadprivate directive for static block-scope variables must appear
1743  // in the scope of the variable and not in a nested scope.
1744  if (CanonicalVD->isStaticLocal() && CurScope &&
1745  !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
1746  Diag(Id.getLoc(), diag::err_omp_var_scope)
1747  << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1748  bool IsDecl =
1750  Diag(VD->getLocation(),
1751  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1752  << VD;
1753  return ExprError();
1754  }
1755 
1756  // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
1757  // A threadprivate directive must lexically precede all references to any
1758  // of the variables in its list.
1759  if (VD->isUsed() && !DSAStack->isThreadPrivate(VD)) {
1760  Diag(Id.getLoc(), diag::err_omp_var_used)
1761  << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1762  return ExprError();
1763  }
1764 
1765  QualType ExprType = VD->getType().getNonReferenceType();
1766  return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
1767  SourceLocation(), VD,
1768  /*RefersToEnclosingVariableOrCapture=*/false,
1769  Id.getLoc(), ExprType, VK_LValue);
1770 }
1771 
1774  ArrayRef<Expr *> VarList) {
1775  if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
1776  CurContext->addDecl(D);
1777  return DeclGroupPtrTy::make(DeclGroupRef(D));
1778  }
1779  return nullptr;
1780 }
1781 
1782 namespace {
1783 class LocalVarRefChecker final
1784  : public ConstStmtVisitor<LocalVarRefChecker, bool> {
1785  Sema &SemaRef;
1786 
1787 public:
1788  bool VisitDeclRefExpr(const DeclRefExpr *E) {
1789  if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
1790  if (VD->hasLocalStorage()) {
1791  SemaRef.Diag(E->getLocStart(),
1792  diag::err_omp_local_var_in_threadprivate_init)
1793  << E->getSourceRange();
1794  SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
1795  << VD << VD->getSourceRange();
1796  return true;
1797  }
1798  }
1799  return false;
1800  }
1801  bool VisitStmt(const Stmt *S) {
1802  for (const Stmt *Child : S->children()) {
1803  if (Child && Visit(Child))
1804  return true;
1805  }
1806  return false;
1807  }
1808  explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
1809 };
1810 } // namespace
1811 
1815  for (Expr *RefExpr : VarList) {
1816  auto *DE = cast<DeclRefExpr>(RefExpr);
1817  auto *VD = cast<VarDecl>(DE->getDecl());
1818  SourceLocation ILoc = DE->getExprLoc();
1819 
1820  // Mark variable as used.
1821  VD->setReferenced();
1822  VD->markUsed(Context);
1823 
1824  QualType QType = VD->getType();
1825  if (QType->isDependentType() || QType->isInstantiationDependentType()) {
1826  // It will be analyzed later.
1827  Vars.push_back(DE);
1828  continue;
1829  }
1830 
1831  // OpenMP [2.9.2, Restrictions, C/C++, p.10]
1832  // A threadprivate variable must not have an incomplete type.
1833  if (RequireCompleteType(ILoc, VD->getType(),
1834  diag::err_omp_threadprivate_incomplete_type)) {
1835  continue;
1836  }
1837 
1838  // OpenMP [2.9.2, Restrictions, C/C++, p.10]
1839  // A threadprivate variable must not have a reference type.
1840  if (VD->getType()->isReferenceType()) {
1841  Diag(ILoc, diag::err_omp_ref_type_arg)
1842  << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
1843  bool IsDecl =
1844  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1845  Diag(VD->getLocation(),
1846  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1847  << VD;
1848  continue;
1849  }
1850 
1851  // Check if this is a TLS variable. If TLS is not being supported, produce
1852  // the corresponding diagnostic.
1853  if ((VD->getTLSKind() != VarDecl::TLS_None &&
1854  !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1855  getLangOpts().OpenMPUseTLS &&
1856  getASTContext().getTargetInfo().isTLSSupported())) ||
1857  (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
1858  !VD->isLocalVarDecl())) {
1859  Diag(ILoc, diag::err_omp_var_thread_local)
1860  << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
1861  bool IsDecl =
1862  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1863  Diag(VD->getLocation(),
1864  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1865  << VD;
1866  continue;
1867  }
1868 
1869  // Check if initial value of threadprivate variable reference variable with
1870  // local storage (it is not supported by runtime).
1871  if (const Expr *Init = VD->getAnyInitializer()) {
1872  LocalVarRefChecker Checker(*this);
1873  if (Checker.Visit(Init))
1874  continue;
1875  }
1876 
1877  Vars.push_back(RefExpr);
1878  DSAStack->addDSA(VD, DE, OMPC_threadprivate);
1879  VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
1880  Context, SourceRange(Loc, Loc)));
1881  if (ASTMutationListener *ML = Context.getASTMutationListener())
1882  ML->DeclarationMarkedOpenMPThreadPrivate(VD);
1883  }
1884  OMPThreadPrivateDecl *D = nullptr;
1885  if (!Vars.empty()) {
1886  D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
1887  Vars);
1888  D->setAccess(AS_public);
1889  }
1890  return D;
1891 }
1892 
1893 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
1894  const ValueDecl *D,
1895  const DSAStackTy::DSAVarData &DVar,
1896  bool IsLoopIterVar = false) {
1897  if (DVar.RefExpr) {
1898  SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
1899  << getOpenMPClauseName(DVar.CKind);
1900  return;
1901  }
1902  enum {
1903  PDSA_StaticMemberShared,
1904  PDSA_StaticLocalVarShared,
1905  PDSA_LoopIterVarPrivate,
1906  PDSA_LoopIterVarLinear,
1907  PDSA_LoopIterVarLastprivate,
1908  PDSA_ConstVarShared,
1909  PDSA_GlobalVarShared,
1910  PDSA_TaskVarFirstprivate,
1911  PDSA_LocalVarPrivate,
1912  PDSA_Implicit
1913  } Reason = PDSA_Implicit;
1914  bool ReportHint = false;
1915  auto ReportLoc = D->getLocation();
1916  auto *VD = dyn_cast<VarDecl>(D);
1917  if (IsLoopIterVar) {
1918  if (DVar.CKind == OMPC_private)
1919  Reason = PDSA_LoopIterVarPrivate;
1920  else if (DVar.CKind == OMPC_lastprivate)
1921  Reason = PDSA_LoopIterVarLastprivate;
1922  else
1923  Reason = PDSA_LoopIterVarLinear;
1924  } else if (isOpenMPTaskingDirective(DVar.DKind) &&
1925  DVar.CKind == OMPC_firstprivate) {
1926  Reason = PDSA_TaskVarFirstprivate;
1927  ReportLoc = DVar.ImplicitDSALoc;
1928  } else if (VD && VD->isStaticLocal())
1929  Reason = PDSA_StaticLocalVarShared;
1930  else if (VD && VD->isStaticDataMember())
1931  Reason = PDSA_StaticMemberShared;
1932  else if (VD && VD->isFileVarDecl())
1933  Reason = PDSA_GlobalVarShared;
1934  else if (D->getType().isConstant(SemaRef.getASTContext()))
1935  Reason = PDSA_ConstVarShared;
1936  else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
1937  ReportHint = true;
1938  Reason = PDSA_LocalVarPrivate;
1939  }
1940  if (Reason != PDSA_Implicit) {
1941  SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
1942  << Reason << ReportHint
1943  << getOpenMPDirectiveName(Stack->getCurrentDirective());
1944  } else if (DVar.ImplicitDSALoc.isValid()) {
1945  SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
1946  << getOpenMPClauseName(DVar.CKind);
1947  }
1948 }
1949 
1950 namespace {
1951 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
1952  DSAStackTy *Stack;
1953  Sema &SemaRef;
1954  bool ErrorFound = false;
1955  CapturedStmt *CS = nullptr;
1956  llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
1957  llvm::SmallVector<Expr *, 4> ImplicitMap;
1958  Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
1959  llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
1960 
1961 public:
1962  void VisitDeclRefExpr(DeclRefExpr *E) {
1963  if (E->isTypeDependent() || E->isValueDependent() ||
1965  return;
1966  if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
1967  VD = VD->getCanonicalDecl();
1968  // Skip internally declared variables.
1969  if (VD->hasLocalStorage() && !CS->capturesVariable(VD))
1970  return;
1971 
1972  DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
1973  // Check if the variable has explicit DSA set and stop analysis if it so.
1974  if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
1975  return;
1976 
1977  // Skip internally declared static variables.
1979  OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
1980  if (VD->hasGlobalStorage() && !CS->capturesVariable(VD) &&
1981  (!Res || *Res != OMPDeclareTargetDeclAttr::MT_Link))
1982  return;
1983 
1984  SourceLocation ELoc = E->getExprLoc();
1985  OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
1986  // The default(none) clause requires that each variable that is referenced
1987  // in the construct, and does not have a predetermined data-sharing
1988  // attribute, must have its data-sharing attribute explicitly determined
1989  // by being listed in a data-sharing attribute clause.
1990  if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none &&
1991  isParallelOrTaskRegion(DKind) &&
1992  VarsWithInheritedDSA.count(VD) == 0) {
1993  VarsWithInheritedDSA[VD] = E;
1994  return;
1995  }
1996 
1997  if (isOpenMPTargetExecutionDirective(DKind) &&
1998  !Stack->isLoopControlVariable(VD).first) {
1999  if (!Stack->checkMappableExprComponentListsForDecl(
2000  VD, /*CurrentRegionOnly=*/true,
2002  StackComponents,
2003  OpenMPClauseKind) {
2004  // Variable is used if it has been marked as an array, array
2005  // section or the variable iself.
2006  return StackComponents.size() == 1 ||
2007  std::all_of(
2008  std::next(StackComponents.rbegin()),
2009  StackComponents.rend(),
2010  [](const OMPClauseMappableExprCommon::
2011  MappableComponent &MC) {
2012  return MC.getAssociatedDeclaration() ==
2013  nullptr &&
2014  (isa<OMPArraySectionExpr>(
2015  MC.getAssociatedExpression()) ||
2016  isa<ArraySubscriptExpr>(
2017  MC.getAssociatedExpression()));
2018  });
2019  })) {
2020  bool IsFirstprivate = false;
2021  // By default lambdas are captured as firstprivates.
2022  if (const auto *RD =
2023  VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
2024  IsFirstprivate = RD->isLambda();
2025  IsFirstprivate =
2026  IsFirstprivate ||
2027  (VD->getType().getNonReferenceType()->isScalarType() &&
2028  Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res);
2029  if (IsFirstprivate)
2030  ImplicitFirstprivate.emplace_back(E);
2031  else
2032  ImplicitMap.emplace_back(E);
2033  return;
2034  }
2035  }
2036 
2037  // OpenMP [2.9.3.6, Restrictions, p.2]
2038  // A list item that appears in a reduction clause of the innermost
2039  // enclosing worksharing or parallel construct may not be accessed in an
2040  // explicit task.
2041  DVar = Stack->hasInnermostDSA(
2042  VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
2043  [](OpenMPDirectiveKind K) {
2044  return isOpenMPParallelDirective(K) ||
2046  },
2047  /*FromParent=*/true);
2048  if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
2049  ErrorFound = true;
2050  SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
2051  reportOriginalDsa(SemaRef, Stack, VD, DVar);
2052  return;
2053  }
2054 
2055  // Define implicit data-sharing attributes for task.
2056  DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
2057  if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
2058  !Stack->isLoopControlVariable(VD).first)
2059  ImplicitFirstprivate.push_back(E);
2060  }
2061  }
2062  void VisitMemberExpr(MemberExpr *E) {
2063  if (E->isTypeDependent() || E->isValueDependent() ||
2065  return;
2066  auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
2067  OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
2068  if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
2069  if (!FD)
2070  return;
2071  DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
2072  // Check if the variable has explicit DSA set and stop analysis if it
2073  // so.
2074  if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
2075  return;
2076 
2077  if (isOpenMPTargetExecutionDirective(DKind) &&
2078  !Stack->isLoopControlVariable(FD).first &&
2079  !Stack->checkMappableExprComponentListsForDecl(
2080  FD, /*CurrentRegionOnly=*/true,
2082  StackComponents,
2083  OpenMPClauseKind) {
2084  return isa<CXXThisExpr>(
2085  cast<MemberExpr>(
2086  StackComponents.back().getAssociatedExpression())
2087  ->getBase()
2088  ->IgnoreParens());
2089  })) {
2090  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
2091  // A bit-field cannot appear in a map clause.
2092  //
2093  if (FD->isBitField())
2094  return;
2095  ImplicitMap.emplace_back(E);
2096  return;
2097  }
2098 
2099  SourceLocation ELoc = E->getExprLoc();
2100  // OpenMP [2.9.3.6, Restrictions, p.2]
2101  // A list item that appears in a reduction clause of the innermost
2102  // enclosing worksharing or parallel construct may not be accessed in
2103  // an explicit task.
2104  DVar = Stack->hasInnermostDSA(
2105  FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
2106  [](OpenMPDirectiveKind K) {
2107  return isOpenMPParallelDirective(K) ||
2109  },
2110  /*FromParent=*/true);
2111  if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
2112  ErrorFound = true;
2113  SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
2114  reportOriginalDsa(SemaRef, Stack, FD, DVar);
2115  return;
2116  }
2117 
2118  // Define implicit data-sharing attributes for task.
2119  DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
2120  if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
2121  !Stack->isLoopControlVariable(FD).first)
2122  ImplicitFirstprivate.push_back(E);
2123  return;
2124  }
2125  if (isOpenMPTargetExecutionDirective(DKind)) {
2127  if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
2128  /*NoDiagnose=*/true))
2129  return;
2130  const auto *VD = cast<ValueDecl>(
2131  CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
2132  if (!Stack->checkMappableExprComponentListsForDecl(
2133  VD, /*CurrentRegionOnly=*/true,
2134  [&CurComponents](
2136  StackComponents,
2137  OpenMPClauseKind) {
2138  auto CCI = CurComponents.rbegin();
2139  auto CCE = CurComponents.rend();
2140  for (const auto &SC : llvm::reverse(StackComponents)) {
2141  // Do both expressions have the same kind?
2142  if (CCI->getAssociatedExpression()->getStmtClass() !=
2143  SC.getAssociatedExpression()->getStmtClass())
2144  if (!(isa<OMPArraySectionExpr>(
2145  SC.getAssociatedExpression()) &&
2146  isa<ArraySubscriptExpr>(
2147  CCI->getAssociatedExpression())))
2148  return false;
2149 
2150  const Decl *CCD = CCI->getAssociatedDeclaration();
2151  const Decl *SCD = SC.getAssociatedDeclaration();
2152  CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
2153  SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
2154  if (SCD != CCD)
2155  return false;
2156  std::advance(CCI, 1);
2157  if (CCI == CCE)
2158  break;
2159  }
2160  return true;
2161  })) {
2162  Visit(E->getBase());
2163  }
2164  } else {
2165  Visit(E->getBase());
2166  }
2167  }
2168  void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
2169  for (OMPClause *C : S->clauses()) {
2170  // Skip analysis of arguments of implicitly defined firstprivate clause
2171  // for task|target directives.
2172  // Skip analysis of arguments of implicitly defined map clause for target
2173  // directives.
2174  if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
2175  C->isImplicit())) {
2176  for (Stmt *CC : C->children()) {
2177  if (CC)
2178  Visit(CC);
2179  }
2180  }
2181  }
2182  }
2183  void VisitStmt(Stmt *S) {
2184  for (Stmt *C : S->children()) {
2185  if (C && !isa<OMPExecutableDirective>(C))
2186  Visit(C);
2187  }
2188  }
2189 
2190  bool isErrorFound() const { return ErrorFound; }
2191  ArrayRef<Expr *> getImplicitFirstprivate() const {
2192  return ImplicitFirstprivate;
2193  }
2194  ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; }
2195  const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
2196  return VarsWithInheritedDSA;
2197  }
2198 
2199  DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
2200  : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {}
2201 };
2202 } // namespace
2203 
2205  switch (DKind) {
2206  case OMPD_parallel:
2207  case OMPD_parallel_for:
2208  case OMPD_parallel_for_simd:
2209  case OMPD_parallel_sections:
2210  case OMPD_teams:
2211  case OMPD_teams_distribute:
2212  case OMPD_teams_distribute_simd: {
2213  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2214  QualType KmpInt32PtrTy =
2215  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2216  Sema::CapturedParamNameType Params[] = {
2217  std::make_pair(".global_tid.", KmpInt32PtrTy),
2218  std::make_pair(".bound_tid.", KmpInt32PtrTy),
2219  std::make_pair(StringRef(), QualType()) // __context with shared vars
2220  };
2221  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2222  Params);
2223  break;
2224  }
2225  case OMPD_target_teams:
2226  case OMPD_target_parallel:
2227  case OMPD_target_parallel_for:
2228  case OMPD_target_parallel_for_simd:
2229  case OMPD_target_teams_distribute:
2230  case OMPD_target_teams_distribute_simd: {
2231  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2232  QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2233  QualType KmpInt32PtrTy =
2234  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2235  QualType Args[] = {VoidPtrTy};
2237  EPI.Variadic = true;
2238  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2239  Sema::CapturedParamNameType Params[] = {
2240  std::make_pair(".global_tid.", KmpInt32Ty),
2241  std::make_pair(".part_id.", KmpInt32PtrTy),
2242  std::make_pair(".privates.", VoidPtrTy),
2243  std::make_pair(
2244  ".copy_fn.",
2245  Context.getPointerType(CopyFnType).withConst().withRestrict()),
2246  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2247  std::make_pair(StringRef(), QualType()) // __context with shared vars
2248  };
2249  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2250  Params);
2251  // Mark this captured region as inlined, because we don't use outlined
2252  // function directly.
2253  getCurCapturedRegion()->TheCapturedDecl->addAttr(
2254  AlwaysInlineAttr::CreateImplicit(
2255  Context, AlwaysInlineAttr::Keyword_forceinline));
2256  Sema::CapturedParamNameType ParamsTarget[] = {
2257  std::make_pair(StringRef(), QualType()) // __context with shared vars
2258  };
2259  // Start a captured region for 'target' with no implicit parameters.
2260  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2261  ParamsTarget);
2262  Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
2263  std::make_pair(".global_tid.", KmpInt32PtrTy),
2264  std::make_pair(".bound_tid.", KmpInt32PtrTy),
2265  std::make_pair(StringRef(), QualType()) // __context with shared vars
2266  };
2267  // Start a captured region for 'teams' or 'parallel'. Both regions have
2268  // the same implicit parameters.
2269  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2270  ParamsTeamsOrParallel);
2271  break;
2272  }
2273  case OMPD_target:
2274  case OMPD_target_simd: {
2275  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2276  QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2277  QualType KmpInt32PtrTy =
2278  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2279  QualType Args[] = {VoidPtrTy};
2281  EPI.Variadic = true;
2282  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2283  Sema::CapturedParamNameType Params[] = {
2284  std::make_pair(".global_tid.", KmpInt32Ty),
2285  std::make_pair(".part_id.", KmpInt32PtrTy),
2286  std::make_pair(".privates.", VoidPtrTy),
2287  std::make_pair(
2288  ".copy_fn.",
2289  Context.getPointerType(CopyFnType).withConst().withRestrict()),
2290  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2291  std::make_pair(StringRef(), QualType()) // __context with shared vars
2292  };
2293  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2294  Params);
2295  // Mark this captured region as inlined, because we don't use outlined
2296  // function directly.
2297  getCurCapturedRegion()->TheCapturedDecl->addAttr(
2298  AlwaysInlineAttr::CreateImplicit(
2299  Context, AlwaysInlineAttr::Keyword_forceinline));
2300  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2301  std::make_pair(StringRef(), QualType()));
2302  break;
2303  }
2304  case OMPD_simd:
2305  case OMPD_for:
2306  case OMPD_for_simd:
2307  case OMPD_sections:
2308  case OMPD_section:
2309  case OMPD_single:
2310  case OMPD_master:
2311  case OMPD_critical:
2312  case OMPD_taskgroup:
2313  case OMPD_distribute:
2314  case OMPD_distribute_simd:
2315  case OMPD_ordered:
2316  case OMPD_atomic:
2317  case OMPD_target_data: {
2318  Sema::CapturedParamNameType Params[] = {
2319  std::make_pair(StringRef(), QualType()) // __context with shared vars
2320  };
2321  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2322  Params);
2323  break;
2324  }
2325  case OMPD_task: {
2326  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2327  QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2328  QualType KmpInt32PtrTy =
2329  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2330  QualType Args[] = {VoidPtrTy};
2332  EPI.Variadic = true;
2333  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2334  Sema::CapturedParamNameType Params[] = {
2335  std::make_pair(".global_tid.", KmpInt32Ty),
2336  std::make_pair(".part_id.", KmpInt32PtrTy),
2337  std::make_pair(".privates.", VoidPtrTy),
2338  std::make_pair(
2339  ".copy_fn.",
2340  Context.getPointerType(CopyFnType).withConst().withRestrict()),
2341  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2342  std::make_pair(StringRef(), QualType()) // __context with shared vars
2343  };
2344  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2345  Params);
2346  // Mark this captured region as inlined, because we don't use outlined
2347  // function directly.
2348  getCurCapturedRegion()->TheCapturedDecl->addAttr(
2349  AlwaysInlineAttr::CreateImplicit(
2350  Context, AlwaysInlineAttr::Keyword_forceinline));
2351  break;
2352  }
2353  case OMPD_taskloop:
2354  case OMPD_taskloop_simd: {
2355  QualType KmpInt32Ty =
2356  Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
2357  .withConst();
2358  QualType KmpUInt64Ty =
2359  Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
2360  .withConst();
2361  QualType KmpInt64Ty =
2362  Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
2363  .withConst();
2364  QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2365  QualType KmpInt32PtrTy =
2366  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2367  QualType Args[] = {VoidPtrTy};
2369  EPI.Variadic = true;
2370  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2371  Sema::CapturedParamNameType Params[] = {
2372  std::make_pair(".global_tid.", KmpInt32Ty),
2373  std::make_pair(".part_id.", KmpInt32PtrTy),
2374  std::make_pair(".privates.", VoidPtrTy),
2375  std::make_pair(
2376  ".copy_fn.",
2377  Context.getPointerType(CopyFnType).withConst().withRestrict()),
2378  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2379  std::make_pair(".lb.", KmpUInt64Ty),
2380  std::make_pair(".ub.", KmpUInt64Ty),
2381  std::make_pair(".st.", KmpInt64Ty),
2382  std::make_pair(".liter.", KmpInt32Ty),
2383  std::make_pair(".reductions.", VoidPtrTy),
2384  std::make_pair(StringRef(), QualType()) // __context with shared vars
2385  };
2386  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2387  Params);
2388  // Mark this captured region as inlined, because we don't use outlined
2389  // function directly.
2390  getCurCapturedRegion()->TheCapturedDecl->addAttr(
2391  AlwaysInlineAttr::CreateImplicit(
2392  Context, AlwaysInlineAttr::Keyword_forceinline));
2393  break;
2394  }
2395  case OMPD_distribute_parallel_for_simd:
2396  case OMPD_distribute_parallel_for: {
2397  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2398  QualType KmpInt32PtrTy =
2399  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2400  Sema::CapturedParamNameType Params[] = {
2401  std::make_pair(".global_tid.", KmpInt32PtrTy),
2402  std::make_pair(".bound_tid.", KmpInt32PtrTy),
2403  std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
2404  std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
2405  std::make_pair(StringRef(), QualType()) // __context with shared vars
2406  };
2407  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2408  Params);
2409  break;
2410  }
2411  case OMPD_target_teams_distribute_parallel_for:
2412  case OMPD_target_teams_distribute_parallel_for_simd: {
2413  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2414  QualType KmpInt32PtrTy =
2415  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2416  QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2417 
2418  QualType Args[] = {VoidPtrTy};
2420  EPI.Variadic = true;
2421  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2422  Sema::CapturedParamNameType Params[] = {
2423  std::make_pair(".global_tid.", KmpInt32Ty),
2424  std::make_pair(".part_id.", KmpInt32PtrTy),
2425  std::make_pair(".privates.", VoidPtrTy),
2426  std::make_pair(
2427  ".copy_fn.",
2428  Context.getPointerType(CopyFnType).withConst().withRestrict()),
2429  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2430  std::make_pair(StringRef(), QualType()) // __context with shared vars
2431  };
2432  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2433  Params);
2434  // Mark this captured region as inlined, because we don't use outlined
2435  // function directly.
2436  getCurCapturedRegion()->TheCapturedDecl->addAttr(
2437  AlwaysInlineAttr::CreateImplicit(
2438  Context, AlwaysInlineAttr::Keyword_forceinline));
2439  Sema::CapturedParamNameType ParamsTarget[] = {
2440  std::make_pair(StringRef(), QualType()) // __context with shared vars
2441  };
2442  // Start a captured region for 'target' with no implicit parameters.
2443  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2444  ParamsTarget);
2445 
2446  Sema::CapturedParamNameType ParamsTeams[] = {
2447  std::make_pair(".global_tid.", KmpInt32PtrTy),
2448  std::make_pair(".bound_tid.", KmpInt32PtrTy),
2449  std::make_pair(StringRef(), QualType()) // __context with shared vars
2450  };
2451  // Start a captured region for 'target' with no implicit parameters.
2452  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2453  ParamsTeams);
2454 
2455  Sema::CapturedParamNameType ParamsParallel[] = {
2456  std::make_pair(".global_tid.", KmpInt32PtrTy),
2457  std::make_pair(".bound_tid.", KmpInt32PtrTy),
2458  std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
2459  std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
2460  std::make_pair(StringRef(), QualType()) // __context with shared vars
2461  };
2462  // Start a captured region for 'teams' or 'parallel'. Both regions have
2463  // the same implicit parameters.
2464  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2465  ParamsParallel);
2466  break;
2467  }
2468 
2469  case OMPD_teams_distribute_parallel_for:
2470  case OMPD_teams_distribute_parallel_for_simd: {
2471  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2472  QualType KmpInt32PtrTy =
2473  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2474 
2475  Sema::CapturedParamNameType ParamsTeams[] = {
2476  std::make_pair(".global_tid.", KmpInt32PtrTy),
2477  std::make_pair(".bound_tid.", KmpInt32PtrTy),
2478  std::make_pair(StringRef(), QualType()) // __context with shared vars
2479  };
2480  // Start a captured region for 'target' with no implicit parameters.
2481  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2482  ParamsTeams);
2483 
2484  Sema::CapturedParamNameType ParamsParallel[] = {
2485  std::make_pair(".global_tid.", KmpInt32PtrTy),
2486  std::make_pair(".bound_tid.", KmpInt32PtrTy),
2487  std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
2488  std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
2489  std::make_pair(StringRef(), QualType()) // __context with shared vars
2490  };
2491  // Start a captured region for 'teams' or 'parallel'. Both regions have
2492  // the same implicit parameters.
2493  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2494  ParamsParallel);
2495  break;
2496  }
2497  case OMPD_target_update:
2498  case OMPD_target_enter_data:
2499  case OMPD_target_exit_data: {
2500  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2501  QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2502  QualType KmpInt32PtrTy =
2503  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2504  QualType Args[] = {VoidPtrTy};
2506  EPI.Variadic = true;
2507  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2508  Sema::CapturedParamNameType Params[] = {
2509  std::make_pair(".global_tid.", KmpInt32Ty),
2510  std::make_pair(".part_id.", KmpInt32PtrTy),
2511  std::make_pair(".privates.", VoidPtrTy),
2512  std::make_pair(
2513  ".copy_fn.",
2514  Context.getPointerType(CopyFnType).withConst().withRestrict()),
2515  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2516  std::make_pair(StringRef(), QualType()) // __context with shared vars
2517  };
2518  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2519  Params);
2520  // Mark this captured region as inlined, because we don't use outlined
2521  // function directly.
2522  getCurCapturedRegion()->TheCapturedDecl->addAttr(
2523  AlwaysInlineAttr::CreateImplicit(
2524  Context, AlwaysInlineAttr::Keyword_forceinline));
2525  break;
2526  }
2527  case OMPD_threadprivate:
2528  case OMPD_taskyield:
2529  case OMPD_barrier:
2530  case OMPD_taskwait:
2531  case OMPD_cancellation_point:
2532  case OMPD_cancel:
2533  case OMPD_flush:
2534  case OMPD_declare_reduction:
2535  case OMPD_declare_simd:
2536  case OMPD_declare_target:
2537  case OMPD_end_declare_target:
2538  llvm_unreachable("OpenMP Directive is not allowed");
2539  case OMPD_unknown:
2540  llvm_unreachable("Unknown OpenMP directive");
2541  }
2542 }
2543 
2545  SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2546  getOpenMPCaptureRegions(CaptureRegions, DKind);
2547  return CaptureRegions.size();
2548 }
2549 
2551  Expr *CaptureExpr, bool WithInit,
2552  bool AsExpression) {
2553  assert(CaptureExpr);
2554  ASTContext &C = S.getASTContext();
2555  Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
2556  QualType Ty = Init->getType();
2557  if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
2558  if (S.getLangOpts().CPlusPlus) {
2559  Ty = C.getLValueReferenceType(Ty);
2560  } else {
2561  Ty = C.getPointerType(Ty);
2562  ExprResult Res =
2563  S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
2564  if (!Res.isUsable())
2565  return nullptr;
2566  Init = Res.get();
2567  }
2568  WithInit = true;
2569  }
2570  auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
2571  CaptureExpr->getLocStart());
2572  if (!WithInit)
2573  CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
2574  S.CurContext->addHiddenDecl(CED);
2575  S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
2576  return CED;
2577 }
2578 
2579 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2580  bool WithInit) {
2581  OMPCapturedExprDecl *CD;
2582  if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
2583  CD = cast<OMPCapturedExprDecl>(VD);
2584  else
2585  CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
2586  /*AsExpression=*/false);
2587  return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
2588  CaptureExpr->getExprLoc());
2589 }
2590 
2591 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
2592  CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
2593  if (!Ref) {
2595  S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
2596  /*WithInit=*/true, /*AsExpression=*/true);
2597  Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
2598  CaptureExpr->getExprLoc());
2599  }
2600  ExprResult Res = Ref;
2601  if (!S.getLangOpts().CPlusPlus &&
2602  CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
2603  Ref->getType()->isPointerType()) {
2604  Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
2605  if (!Res.isUsable())
2606  return ExprError();
2607  }
2608  return S.DefaultLvalueConversion(Res.get());
2609 }
2610 
2611 namespace {
2612 // OpenMP directives parsed in this section are represented as a
2613 // CapturedStatement with an associated statement. If a syntax error
2614 // is detected during the parsing of the associated statement, the
2615 // compiler must abort processing and close the CapturedStatement.
2616 //
2617 // Combined directives such as 'target parallel' have more than one
2618 // nested CapturedStatements. This RAII ensures that we unwind out
2619 // of all the nested CapturedStatements when an error is found.
2620 class CaptureRegionUnwinderRAII {
2621 private:
2622  Sema &S;
2623  bool &ErrorFound;
2625 
2626 public:
2627  CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
2628  OpenMPDirectiveKind DKind)
2629  : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
2630  ~CaptureRegionUnwinderRAII() {
2631  if (ErrorFound) {
2632  int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
2633  while (--ThisCaptureLevel >= 0)
2635  }
2636  }
2637 };
2638 } // namespace
2639 
2641  ArrayRef<OMPClause *> Clauses) {
2642  bool ErrorFound = false;
2643  CaptureRegionUnwinderRAII CaptureRegionUnwinder(
2644  *this, ErrorFound, DSAStack->getCurrentDirective());
2645  if (!S.isUsable()) {
2646  ErrorFound = true;
2647  return StmtError();
2648  }
2649 
2650  SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2651  getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective());
2652  OMPOrderedClause *OC = nullptr;
2653  OMPScheduleClause *SC = nullptr;
2656  // This is required for proper codegen.
2657  for (OMPClause *Clause : Clauses) {
2658  if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
2659  Clause->getClauseKind() == OMPC_in_reduction) {
2660  // Capture taskgroup task_reduction descriptors inside the tasking regions
2661  // with the corresponding in_reduction items.
2662  auto *IRC = cast<OMPInReductionClause>(Clause);
2663  for (Expr *E : IRC->taskgroup_descriptors())
2664  if (E)
2665  MarkDeclarationsReferencedInExpr(E);
2666  }
2667  if (isOpenMPPrivate(Clause->getClauseKind()) ||
2668  Clause->getClauseKind() == OMPC_copyprivate ||
2669  (getLangOpts().OpenMPUseTLS &&
2670  getASTContext().getTargetInfo().isTLSSupported() &&
2671  Clause->getClauseKind() == OMPC_copyin)) {
2672  DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
2673  // Mark all variables in private list clauses as used in inner region.
2674  for (Stmt *VarRef : Clause->children()) {
2675  if (auto *E = cast_or_null<Expr>(VarRef)) {
2676  MarkDeclarationsReferencedInExpr(E);
2677  }
2678  }
2679  DSAStack->setForceVarCapturing(/*V=*/false);
2680  } else if (CaptureRegions.size() > 1 ||
2681  CaptureRegions.back() != OMPD_unknown) {
2682  if (auto *C = OMPClauseWithPreInit::get(Clause))
2683  PICs.push_back(C);
2684  if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
2685  if (Expr *E = C->getPostUpdateExpr())
2686  MarkDeclarationsReferencedInExpr(E);
2687  }
2688  }
2689  if (Clause->getClauseKind() == OMPC_schedule)
2690  SC = cast<OMPScheduleClause>(Clause);
2691  else if (Clause->getClauseKind() == OMPC_ordered)
2692  OC = cast<OMPOrderedClause>(Clause);
2693  else if (Clause->getClauseKind() == OMPC_linear)
2694  LCs.push_back(cast<OMPLinearClause>(Clause));
2695  }
2696  // OpenMP, 2.7.1 Loop Construct, Restrictions
2697  // The nonmonotonic modifier cannot be specified if an ordered clause is
2698  // specified.
2699  if (SC &&
2700  (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
2701  SC->getSecondScheduleModifier() ==
2702  OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
2703  OC) {
2704  Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
2707  diag::err_omp_schedule_nonmonotonic_ordered)
2708  << SourceRange(OC->getLocStart(), OC->getLocEnd());
2709  ErrorFound = true;
2710  }
2711  if (!LCs.empty() && OC && OC->getNumForLoops()) {
2712  for (const OMPLinearClause *C : LCs) {
2713  Diag(C->getLocStart(), diag::err_omp_linear_ordered)
2714  << SourceRange(OC->getLocStart(), OC->getLocEnd());
2715  }
2716  ErrorFound = true;
2717  }
2718  if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
2719  isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
2720  OC->getNumForLoops()) {
2721  Diag(OC->getLocStart(), diag::err_omp_ordered_simd)
2722  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
2723  ErrorFound = true;
2724  }
2725  if (ErrorFound) {
2726  return StmtError();
2727  }
2728  StmtResult SR = S;
2729  for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
2730  // Mark all variables in private list clauses as used in inner region.
2731  // Required for proper codegen of combined directives.
2732  // TODO: add processing for other clauses.
2733  if (ThisCaptureRegion != OMPD_unknown) {
2734  for (const clang::OMPClauseWithPreInit *C : PICs) {
2735  OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
2736  // Find the particular capture region for the clause if the
2737  // directive is a combined one with multiple capture regions.
2738  // If the directive is not a combined one, the capture region
2739  // associated with the clause is OMPD_unknown and is generated
2740  // only once.
2741  if (CaptureRegion == ThisCaptureRegion ||
2742  CaptureRegion == OMPD_unknown) {
2743  if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
2744  for (Decl *D : DS->decls())
2745  MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
2746  }
2747  }
2748  }
2749  }
2750  SR = ActOnCapturedRegionEnd(SR.get());
2751  }
2752  return SR;
2753 }
2754 
2755 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
2756  OpenMPDirectiveKind CancelRegion,
2757  SourceLocation StartLoc) {
2758  // CancelRegion is only needed for cancel and cancellation_point.
2759  if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
2760  return false;
2761 
2762  if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
2763  CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
2764  return false;
2765 
2766  SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
2767  << getOpenMPDirectiveName(CancelRegion);
2768  return true;
2769 }
2770 
2771 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
2772  OpenMPDirectiveKind CurrentRegion,
2773  const DeclarationNameInfo &CurrentName,
2774  OpenMPDirectiveKind CancelRegion,
2775  SourceLocation StartLoc) {
2776  if (Stack->getCurScope()) {
2777  OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
2778  OpenMPDirectiveKind OffendingRegion = ParentRegion;
2779  bool NestingProhibited = false;
2780  bool CloseNesting = true;
2781  bool OrphanSeen = false;
2782  enum {
2783  NoRecommend,
2784  ShouldBeInParallelRegion,
2785  ShouldBeInOrderedRegion,
2786  ShouldBeInTargetRegion,
2787  ShouldBeInTeamsRegion
2788  } Recommend = NoRecommend;
2789  if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) {
2790  // OpenMP [2.16, Nesting of Regions]
2791  // OpenMP constructs may not be nested inside a simd region.
2792  // OpenMP [2.8.1,simd Construct, Restrictions]
2793  // An ordered construct with the simd clause is the only OpenMP
2794  // construct that can appear in the simd region.
2795  // Allowing a SIMD construct nested in another SIMD construct is an
2796  // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
2797  // message.
2798  SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
2799  ? diag::err_omp_prohibited_region_simd
2800  : diag::warn_omp_nesting_simd);
2801  return CurrentRegion != OMPD_simd;
2802  }
2803  if (ParentRegion == OMPD_atomic) {
2804  // OpenMP [2.16, Nesting of Regions]
2805  // OpenMP constructs may not be nested inside an atomic region.
2806  SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
2807  return true;
2808  }
2809  if (CurrentRegion == OMPD_section) {
2810  // OpenMP [2.7.2, sections Construct, Restrictions]
2811  // Orphaned section directives are prohibited. That is, the section
2812  // directives must appear within the sections construct and must not be
2813  // encountered elsewhere in the sections region.
2814  if (ParentRegion != OMPD_sections &&
2815  ParentRegion != OMPD_parallel_sections) {
2816  SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
2817  << (ParentRegion != OMPD_unknown)
2818  << getOpenMPDirectiveName(ParentRegion);
2819  return true;
2820  }
2821  return false;
2822  }
2823  // Allow some constructs (except teams) to be orphaned (they could be
2824  // used in functions, called from OpenMP regions with the required
2825  // preconditions).
2826  if (ParentRegion == OMPD_unknown &&
2827  !isOpenMPNestingTeamsDirective(CurrentRegion))
2828  return false;
2829  if (CurrentRegion == OMPD_cancellation_point ||
2830  CurrentRegion == OMPD_cancel) {
2831  // OpenMP [2.16, Nesting of Regions]
2832  // A cancellation point construct for which construct-type-clause is
2833  // taskgroup must be nested inside a task construct. A cancellation
2834  // point construct for which construct-type-clause is not taskgroup must
2835  // be closely nested inside an OpenMP construct that matches the type
2836  // specified in construct-type-clause.
2837  // A cancel construct for which construct-type-clause is taskgroup must be
2838  // nested inside a task construct. A cancel construct for which
2839  // construct-type-clause is not taskgroup must be closely nested inside an
2840  // OpenMP construct that matches the type specified in
2841  // construct-type-clause.
2842  NestingProhibited =
2843  !((CancelRegion == OMPD_parallel &&
2844  (ParentRegion == OMPD_parallel ||
2845  ParentRegion == OMPD_target_parallel)) ||
2846  (CancelRegion == OMPD_for &&
2847  (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
2848  ParentRegion == OMPD_target_parallel_for ||
2849  ParentRegion == OMPD_distribute_parallel_for ||
2850  ParentRegion == OMPD_teams_distribute_parallel_for ||
2851  ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
2852  (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) ||
2853  (CancelRegion == OMPD_sections &&
2854  (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
2855  ParentRegion == OMPD_parallel_sections)));
2856  } else if (CurrentRegion == OMPD_master) {
2857  // OpenMP [2.16, Nesting of Regions]
2858  // A master region may not be closely nested inside a worksharing,
2859  // atomic, or explicit task region.
2860  NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
2861  isOpenMPTaskingDirective(ParentRegion);
2862  } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
2863  // OpenMP [2.16, Nesting of Regions]
2864  // A critical region may not be nested (closely or otherwise) inside a
2865  // critical region with the same name. Note that this restriction is not
2866  // sufficient to prevent deadlock.
2867  SourceLocation PreviousCriticalLoc;
2868  bool DeadLock = Stack->hasDirective(
2869  [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
2870  const DeclarationNameInfo &DNI,
2871  SourceLocation Loc) {
2872  if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
2873  PreviousCriticalLoc = Loc;
2874  return true;
2875  }
2876  return false;
2877  },
2878  false /* skip top directive */);
2879  if (DeadLock) {
2880  SemaRef.Diag(StartLoc,
2881  diag::err_omp_prohibited_region_critical_same_name)
2882  << CurrentName.getName();
2883  if (PreviousCriticalLoc.isValid())
2884  SemaRef.Diag(PreviousCriticalLoc,
2885  diag::note_omp_previous_critical_region);
2886  return true;
2887  }
2888  } else if (CurrentRegion == OMPD_barrier) {
2889  // OpenMP [2.16, Nesting of Regions]
2890  // A barrier region may not be closely nested inside a worksharing,
2891  // explicit task, critical, ordered, atomic, or master region.
2892  NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
2893  isOpenMPTaskingDirective(ParentRegion) ||
2894  ParentRegion == OMPD_master ||
2895  ParentRegion == OMPD_critical ||
2896  ParentRegion == OMPD_ordered;
2897  } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
2898  !isOpenMPParallelDirective(CurrentRegion) &&
2899  !isOpenMPTeamsDirective(CurrentRegion)) {
2900  // OpenMP [2.16, Nesting of Regions]
2901  // A worksharing region may not be closely nested inside a worksharing,
2902  // explicit task, critical, ordered, atomic, or master region.
2903  NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
2904  isOpenMPTaskingDirective(ParentRegion) ||
2905  ParentRegion == OMPD_master ||
2906  ParentRegion == OMPD_critical ||
2907  ParentRegion == OMPD_ordered;
2908  Recommend = ShouldBeInParallelRegion;
2909  } else if (CurrentRegion == OMPD_ordered) {
2910  // OpenMP [2.16, Nesting of Regions]
2911  // An ordered region may not be closely nested inside a critical,
2912  // atomic, or explicit task region.
2913  // An ordered region must be closely nested inside a loop region (or
2914  // parallel loop region) with an ordered clause.
2915  // OpenMP [2.8.1,simd Construct, Restrictions]
2916  // An ordered construct with the simd clause is the only OpenMP construct
2917  // that can appear in the simd region.
2918  NestingProhibited = ParentRegion == OMPD_critical ||
2919  isOpenMPTaskingDirective(ParentRegion) ||
2920  !(isOpenMPSimdDirective(ParentRegion) ||
2921  Stack->isParentOrderedRegion());
2922  Recommend = ShouldBeInOrderedRegion;
2923  } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
2924  // OpenMP [2.16, Nesting of Regions]
2925  // If specified, a teams construct must be contained within a target
2926  // construct.
2927  NestingProhibited = ParentRegion != OMPD_target;
2928  OrphanSeen = ParentRegion == OMPD_unknown;
2929  Recommend = ShouldBeInTargetRegion;
2930  }
2931  if (!NestingProhibited &&
2932  !isOpenMPTargetExecutionDirective(CurrentRegion) &&
2933  !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
2934  (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
2935  // OpenMP [2.16, Nesting of Regions]
2936  // distribute, parallel, parallel sections, parallel workshare, and the
2937  // parallel loop and parallel loop SIMD constructs are the only OpenMP
2938  // constructs that can be closely nested in the teams region.
2939  NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
2940  !isOpenMPDistributeDirective(CurrentRegion);
2941  Recommend = ShouldBeInParallelRegion;
2942  }
2943  if (!NestingProhibited &&
2944  isOpenMPNestingDistributeDirective(CurrentRegion)) {
2945  // OpenMP 4.5 [2.17 Nesting of Regions]
2946  // The region associated with the distribute construct must be strictly
2947  // nested inside a teams region
2948  NestingProhibited =
2949  (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
2950  Recommend = ShouldBeInTeamsRegion;
2951  }
2952  if (!NestingProhibited &&
2953  (isOpenMPTargetExecutionDirective(CurrentRegion) ||
2954  isOpenMPTargetDataManagementDirective(CurrentRegion))) {
2955  // OpenMP 4.5 [2.17 Nesting of Regions]
2956  // If a target, target update, target data, target enter data, or
2957  // target exit data construct is encountered during execution of a
2958  // target region, the behavior is unspecified.
2959  NestingProhibited = Stack->hasDirective(
2960  [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2961  SourceLocation) {
2963  OffendingRegion = K;
2964  return true;
2965  }
2966  return false;
2967  },
2968  false /* don't skip top directive */);
2969  CloseNesting = false;
2970  }
2971  if (NestingProhibited) {
2972  if (OrphanSeen) {
2973  SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
2974  << getOpenMPDirectiveName(CurrentRegion) << Recommend;
2975  } else {
2976  SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
2977  << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
2978  << Recommend << getOpenMPDirectiveName(CurrentRegion);
2979  }
2980  return true;
2981  }
2982  }
2983  return false;
2984 }
2985 
2987  ArrayRef<OMPClause *> Clauses,
2988  ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
2989  bool ErrorFound = false;
2990  unsigned NamedModifiersNumber = 0;
2992  OMPD_unknown + 1);
2993  SmallVector<SourceLocation, 4> NameModifierLoc;
2994  for (const OMPClause *C : Clauses) {
2995  if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
2996  // At most one if clause without a directive-name-modifier can appear on
2997  // the directive.
2998  OpenMPDirectiveKind CurNM = IC->getNameModifier();
2999  if (FoundNameModifiers[CurNM]) {
3000  S.Diag(C->getLocStart(), diag::err_omp_more_one_clause)
3001  << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
3002  << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
3003  ErrorFound = true;
3004  } else if (CurNM != OMPD_unknown) {
3005  NameModifierLoc.push_back(IC->getNameModifierLoc());
3006  ++NamedModifiersNumber;
3007  }
3008  FoundNameModifiers[CurNM] = IC;
3009  if (CurNM == OMPD_unknown)
3010  continue;
3011  // Check if the specified name modifier is allowed for the current
3012  // directive.
3013  // At most one if clause with the particular directive-name-modifier can
3014  // appear on the directive.
3015  bool MatchFound = false;
3016  for (auto NM : AllowedNameModifiers) {
3017  if (CurNM == NM) {
3018  MatchFound = true;
3019  break;
3020  }
3021  }
3022  if (!MatchFound) {
3023  S.Diag(IC->getNameModifierLoc(),
3024  diag::err_omp_wrong_if_directive_name_modifier)
3026  ErrorFound = true;
3027  }
3028  }
3029  }
3030  // If any if clause on the directive includes a directive-name-modifier then
3031  // all if clauses on the directive must include a directive-name-modifier.
3032  if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
3033  if (NamedModifiersNumber == AllowedNameModifiers.size()) {
3034  S.Diag(FoundNameModifiers[OMPD_unknown]->getLocStart(),
3035  diag::err_omp_no_more_if_clause);
3036  } else {
3037  std::string Values;
3038  std::string Sep(", ");
3039  unsigned AllowedCnt = 0;
3040  unsigned TotalAllowedNum =
3041  AllowedNameModifiers.size() - NamedModifiersNumber;
3042  for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
3043  ++Cnt) {
3044  OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
3045  if (!FoundNameModifiers[NM]) {
3046  Values += "'";
3047  Values += getOpenMPDirectiveName(NM);
3048  Values += "'";
3049  if (AllowedCnt + 2 == TotalAllowedNum)
3050  Values += " or ";
3051  else if (AllowedCnt + 1 != TotalAllowedNum)
3052  Values += Sep;
3053  ++AllowedCnt;
3054  }
3055  }
3056  S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getLocStart(),
3057  diag::err_omp_unnamed_if_clause)
3058  << (TotalAllowedNum > 1) << Values;
3059  }
3060  for (SourceLocation Loc : NameModifierLoc) {
3061  S.Diag(Loc, diag::note_omp_previous_named_if_clause);
3062  }
3063  ErrorFound = true;
3064  }
3065  return ErrorFound;
3066 }
3067 
3070  OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
3071  Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
3072  StmtResult Res = StmtError();
3073  // First check CancelRegion which is then used in checkNestingOfRegions.
3074  if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
3075  checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
3076  StartLoc))
3077  return StmtError();
3078 
3079  llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
3080  VarsWithInheritedDSAType VarsWithInheritedDSA;
3081  bool ErrorFound = false;
3082  ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
3083  if (AStmt && !CurContext->isDependentContext()) {
3084  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
3085 
3086  // Check default data sharing attributes for referenced variables.
3087  DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
3088  int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
3089  Stmt *S = AStmt;
3090  while (--ThisCaptureLevel >= 0)
3091  S = cast<CapturedStmt>(S)->getCapturedStmt();
3092  DSAChecker.Visit(S);
3093  if (DSAChecker.isErrorFound())
3094  return StmtError();
3095  // Generate list of implicitly defined firstprivate variables.
3096  VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
3097 
3098  SmallVector<Expr *, 4> ImplicitFirstprivates(
3099  DSAChecker.getImplicitFirstprivate().begin(),
3100  DSAChecker.getImplicitFirstprivate().end());
3101  SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(),
3102  DSAChecker.getImplicitMap().end());
3103  // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
3104  for (OMPClause *C : Clauses) {
3105  if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
3106  for (Expr *E : IRC->taskgroup_descriptors())
3107  if (E)
3108  ImplicitFirstprivates.emplace_back(E);
3109  }
3110  }
3111  if (!ImplicitFirstprivates.empty()) {
3112  if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
3113  ImplicitFirstprivates, SourceLocation(), SourceLocation(),
3114  SourceLocation())) {
3115  ClausesWithImplicit.push_back(Implicit);
3116  ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
3117  ImplicitFirstprivates.size();
3118  } else {
3119  ErrorFound = true;
3120  }
3121  }
3122  if (!ImplicitMaps.empty()) {
3123  if (OMPClause *Implicit = ActOnOpenMPMapClause(
3124  OMPC_MAP_unknown, OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true,
3125  SourceLocation(), SourceLocation(), ImplicitMaps,
3127  ClausesWithImplicit.emplace_back(Implicit);
3128  ErrorFound |=
3129  cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size();
3130  } else {
3131  ErrorFound = true;
3132  }
3133  }
3134  }
3135 
3136  llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
3137  switch (Kind) {
3138  case OMPD_parallel:
3139  Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
3140  EndLoc);
3141  AllowedNameModifiers.push_back(OMPD_parallel);
3142  break;
3143  case OMPD_simd:
3144  Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
3145  VarsWithInheritedDSA);
3146  break;
3147  case OMPD_for:
3148  Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
3149  VarsWithInheritedDSA);
3150  break;
3151  case OMPD_for_simd:
3152  Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3153  EndLoc, VarsWithInheritedDSA);
3154  break;
3155  case OMPD_sections:
3156  Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
3157  EndLoc);
3158  break;
3159  case OMPD_section:
3160  assert(ClausesWithImplicit.empty() &&
3161  "No clauses are allowed for 'omp section' directive");
3162  Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
3163  break;
3164  case OMPD_single:
3165  Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
3166  EndLoc);
3167  break;
3168  case OMPD_master:
3169  assert(ClausesWithImplicit.empty() &&
3170  "No clauses are allowed for 'omp master' directive");
3171  Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
3172  break;
3173  case OMPD_critical:
3174  Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
3175  StartLoc, EndLoc);
3176  break;
3177  case OMPD_parallel_for:
3178  Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
3179  EndLoc, VarsWithInheritedDSA);
3180  AllowedNameModifiers.push_back(OMPD_parallel);
3181  break;
3182  case OMPD_parallel_for_simd:
3183  Res = ActOnOpenMPParallelForSimdDirective(
3184  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3185  AllowedNameModifiers.push_back(OMPD_parallel);
3186  break;
3187  case OMPD_parallel_sections:
3188  Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
3189  StartLoc, EndLoc);
3190  AllowedNameModifiers.push_back(OMPD_parallel);
3191  break;
3192  case OMPD_task:
3193  Res =
3194  ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
3195  AllowedNameModifiers.push_back(OMPD_task);
3196  break;
3197  case OMPD_taskyield:
3198  assert(ClausesWithImplicit.empty() &&
3199  "No clauses are allowed for 'omp taskyield' directive");
3200  assert(AStmt == nullptr &&
3201  "No associated statement allowed for 'omp taskyield' directive");
3202  Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
3203  break;
3204  case OMPD_barrier:
3205  assert(ClausesWithImplicit.empty() &&
3206  "No clauses are allowed for 'omp barrier' directive");
3207  assert(AStmt == nullptr &&
3208  "No associated statement allowed for 'omp barrier' directive");
3209  Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
3210  break;
3211  case OMPD_taskwait:
3212  assert(ClausesWithImplicit.empty() &&
3213  "No clauses are allowed for 'omp taskwait' directive");
3214  assert(AStmt == nullptr &&
3215  "No associated statement allowed for 'omp taskwait' directive");
3216  Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
3217  break;
3218  case OMPD_taskgroup:
3219  Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
3220  EndLoc);
3221  break;
3222  case OMPD_flush:
3223  assert(AStmt == nullptr &&
3224  "No associated statement allowed for 'omp flush' directive");
3225  Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
3226  break;
3227  case OMPD_ordered:
3228  Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
3229  EndLoc);
3230  break;
3231  case OMPD_atomic:
3232  Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
3233  EndLoc);
3234  break;
3235  case OMPD_teams:
3236  Res =
3237  ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
3238  break;
3239  case OMPD_target:
3240  Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
3241  EndLoc);
3242  AllowedNameModifiers.push_back(OMPD_target);
3243  break;
3244  case OMPD_target_parallel:
3245  Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
3246  StartLoc, EndLoc);
3247  AllowedNameModifiers.push_back(OMPD_target);
3248  AllowedNameModifiers.push_back(OMPD_parallel);
3249  break;
3250  case OMPD_target_parallel_for:
3251  Res = ActOnOpenMPTargetParallelForDirective(
3252  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3253  AllowedNameModifiers.push_back(OMPD_target);
3254  AllowedNameModifiers.push_back(OMPD_parallel);
3255  break;
3256  case OMPD_cancellation_point:
3257  assert(ClausesWithImplicit.empty() &&
3258  "No clauses are allowed for 'omp cancellation point' directive");
3259  assert(AStmt == nullptr && "No associated statement allowed for 'omp "
3260  "cancellation point' directive");
3261  Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
3262  break;
3263  case OMPD_cancel:
3264  assert(AStmt == nullptr &&
3265  "No associated statement allowed for 'omp cancel' directive");
3266  Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
3267  CancelRegion);
3268  AllowedNameModifiers.push_back(OMPD_cancel);
3269  break;
3270  case OMPD_target_data:
3271  Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
3272  EndLoc);
3273  AllowedNameModifiers.push_back(OMPD_target_data);
3274  break;
3275  case OMPD_target_enter_data:
3276  Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
3277  EndLoc, AStmt);
3278  AllowedNameModifiers.push_back(OMPD_target_enter_data);
3279  break;
3280  case OMPD_target_exit_data:
3281  Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
3282  EndLoc, AStmt);
3283  AllowedNameModifiers.push_back(OMPD_target_exit_data);
3284  break;
3285  case OMPD_taskloop:
3286  Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
3287  EndLoc, VarsWithInheritedDSA);
3288  AllowedNameModifiers.push_back(OMPD_taskloop);
3289  break;
3290  case OMPD_taskloop_simd:
3291  Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3292  EndLoc, VarsWithInheritedDSA);
3293  AllowedNameModifiers.push_back(OMPD_taskloop);
3294  break;
3295  case OMPD_distribute:
3296  Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
3297  EndLoc, VarsWithInheritedDSA);
3298  break;
3299  case OMPD_target_update:
3300  Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
3301  EndLoc, AStmt);
3302  AllowedNameModifiers.push_back(OMPD_target_update);
3303  break;
3304  case OMPD_distribute_parallel_for:
3305  Res = ActOnOpenMPDistributeParallelForDirective(
3306  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3307  AllowedNameModifiers.push_back(OMPD_parallel);
3308  break;
3309  case OMPD_distribute_parallel_for_simd:
3310  Res = ActOnOpenMPDistributeParallelForSimdDirective(
3311  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3312  AllowedNameModifiers.push_back(OMPD_parallel);
3313  break;
3314  case OMPD_distribute_simd:
3315  Res = ActOnOpenMPDistributeSimdDirective(
3316  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3317  break;
3318  case OMPD_target_parallel_for_simd:
3319  Res = ActOnOpenMPTargetParallelForSimdDirective(
3320  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3321  AllowedNameModifiers.push_back(OMPD_target);
3322  AllowedNameModifiers.push_back(OMPD_parallel);
3323  break;
3324  case OMPD_target_simd:
3325  Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3326  EndLoc, VarsWithInheritedDSA);
3327  AllowedNameModifiers.push_back(OMPD_target);
3328  break;
3329  case OMPD_teams_distribute:
3330  Res = ActOnOpenMPTeamsDistributeDirective(
3331  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3332  break;
3333  case OMPD_teams_distribute_simd:
3334  Res = ActOnOpenMPTeamsDistributeSimdDirective(
3335  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3336  break;
3337  case OMPD_teams_distribute_parallel_for_simd:
3338  Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
3339  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3340  AllowedNameModifiers.push_back(OMPD_parallel);
3341  break;
3342  case OMPD_teams_distribute_parallel_for:
3343  Res = ActOnOpenMPTeamsDistributeParallelForDirective(
3344  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3345  AllowedNameModifiers.push_back(OMPD_parallel);
3346  break;
3347  case OMPD_target_teams:
3348  Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
3349  EndLoc);
3350  AllowedNameModifiers.push_back(OMPD_target);
3351  break;
3352  case OMPD_target_teams_distribute:
3353  Res = ActOnOpenMPTargetTeamsDistributeDirective(
3354  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3355  AllowedNameModifiers.push_back(OMPD_target);
3356  break;
3357  case OMPD_target_teams_distribute_parallel_for:
3358  Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
3359  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3360  AllowedNameModifiers.push_back(OMPD_target);
3361  AllowedNameModifiers.push_back(OMPD_parallel);
3362  break;
3363  case OMPD_target_teams_distribute_parallel_for_simd:
3364  Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
3365  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3366  AllowedNameModifiers.push_back(OMPD_target);
3367  AllowedNameModifiers.push_back(OMPD_parallel);
3368  break;
3369  case OMPD_target_teams_distribute_simd:
3370  Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
3371  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3372  AllowedNameModifiers.push_back(OMPD_target);
3373  break;
3374  case OMPD_declare_target:
3375  case OMPD_end_declare_target:
3376  case OMPD_threadprivate:
3377  case OMPD_declare_reduction:
3378  case OMPD_declare_simd:
3379  llvm_unreachable("OpenMP Directive is not allowed");
3380  case OMPD_unknown:
3381  llvm_unreachable("Unknown OpenMP directive");
3382  }
3383 
3384  for (const auto &P : VarsWithInheritedDSA) {
3385  Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
3386  << P.first << P.second->getSourceRange();
3387  }
3388  ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound;
3389 
3390  if (!AllowedNameModifiers.empty())
3391  ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
3392  ErrorFound;
3393 
3394  if (ErrorFound)
3395  return StmtError();
3396  return Res;
3397 }
3398 
3400  DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
3401  ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
3402  ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
3403  ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
3404  assert(Aligneds.size() == Alignments.size());
3405  assert(Linears.size() == LinModifiers.size());
3406  assert(Linears.size() == Steps.size());
3407  if (!DG || DG.get().isNull())
3408  return DeclGroupPtrTy();
3409 
3410  if (!DG.get().isSingleDecl()) {
3411  Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd);
3412  return DG;
3413  }
3414  Decl *ADecl = DG.get().getSingleDecl();
3415  if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
3416  ADecl = FTD->getTemplatedDecl();
3417 
3418  auto *FD = dyn_cast<FunctionDecl>(ADecl);
3419  if (!FD) {
3420  Diag(ADecl->getLocation(), diag::err_omp_function_expected);
3421  return DeclGroupPtrTy();
3422  }
3423 
3424  // OpenMP [2.8.2, declare simd construct, Description]
3425  // The parameter of the simdlen clause must be a constant positive integer
3426  // expression.
3427  ExprResult SL;
3428  if (Simdlen)
3429  SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
3430  // OpenMP [2.8.2, declare simd construct, Description]
3431  // The special this pointer can be used as if was one of the arguments to the
3432  // function in any of the linear, aligned, or uniform clauses.
3433  // The uniform clause declares one or more arguments to have an invariant
3434  // value for all concurrent invocations of the function in the execution of a
3435  // single SIMD loop.
3436  llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
3437  const Expr *UniformedLinearThis = nullptr;
3438  for (const Expr *E : Uniforms) {
3439  E = E->IgnoreParenImpCasts();
3440  if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
3441  if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
3442  if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3443  FD->getParamDecl(PVD->getFunctionScopeIndex())
3444  ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
3445  UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
3446  continue;
3447  }
3448  if (isa<CXXThisExpr>(E)) {
3449  UniformedLinearThis = E;
3450  continue;
3451  }
3452  Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3453  << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3454  }
3455  // OpenMP [2.8.2, declare simd construct, Description]
3456  // The aligned clause declares that the object to which each list item points
3457  // is aligned to the number of bytes expressed in the optional parameter of
3458  // the aligned clause.
3459  // The special this pointer can be used as if was one of the arguments to the
3460  // function in any of the linear, aligned, or uniform clauses.
3461  // The type of list items appearing in the aligned clause must be array,
3462  // pointer, reference to array, or reference to pointer.
3463  llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
3464  const Expr *AlignedThis = nullptr;
3465  for (const Expr *E : Aligneds) {
3466  E = E->IgnoreParenImpCasts();
3467  if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
3468  if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3469  const VarDecl *CanonPVD = PVD->getCanonicalDecl();
3470  if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3471  FD->getParamDecl(PVD->getFunctionScopeIndex())
3472  ->getCanonicalDecl() == CanonPVD) {
3473  // OpenMP [2.8.1, simd construct, Restrictions]
3474  // A list-item cannot appear in more than one aligned clause.
3475  if (AlignedArgs.count(CanonPVD) > 0) {
3476  Diag(E->getExprLoc(), diag::err_omp_aligned_twice)
3477  << 1 << E->getSourceRange();
3478  Diag(AlignedArgs[CanonPVD]->getExprLoc(),
3479  diag::note_omp_explicit_dsa)
3480  << getOpenMPClauseName(OMPC_aligned);
3481  continue;
3482  }
3483  AlignedArgs[CanonPVD] = E;
3484  QualType QTy = PVD->getType()
3485  .getNonReferenceType()
3486  .getUnqualifiedType()
3487  .getCanonicalType();
3488  const Type *Ty = QTy.getTypePtrOrNull();
3489  if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
3490  Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
3491  << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
3492  Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
3493  }
3494  continue;
3495  }
3496  }
3497  if (isa<CXXThisExpr>(E)) {
3498  if (AlignedThis) {
3499  Diag(E->getExprLoc(), diag::err_omp_aligned_twice)
3500  << 2 << E->getSourceRange();
3501  Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
3502  << getOpenMPClauseName(OMPC_aligned);
3503  }
3504  AlignedThis = E;
3505  continue;
3506  }
3507  Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3508  << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3509  }
3510  // The optional parameter of the aligned clause, alignment, must be a constant
3511  // positive integer expression. If no optional parameter is specified,
3512  // implementation-defined default alignments for SIMD instructions on the
3513  // target platforms are assumed.
3514  SmallVector<const Expr *, 4> NewAligns;
3515  for (Expr *E : Alignments) {
3516  ExprResult Align;
3517  if (E)
3518  Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
3519  NewAligns.push_back(Align.get());
3520  }
3521  // OpenMP [2.8.2, declare simd construct, Description]
3522  // The linear clause declares one or more list items to be private to a SIMD
3523  // lane and to have a linear relationship with respect to the iteration space
3524  // of a loop.
3525  // The special this pointer can be used as if was one of the arguments to the
3526  // function in any of the linear, aligned, or uniform clauses.
3527  // When a linear-step expression is specified in a linear clause it must be
3528  // either a constant integer expression or an integer-typed parameter that is
3529  // specified in a uniform clause on the directive.
3530  llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
3531  const bool IsUniformedThis = UniformedLinearThis != nullptr;
3532  auto MI = LinModifiers.begin();
3533  for (const Expr *E : Linears) {
3534  auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
3535  ++MI;
3536  E = E->IgnoreParenImpCasts();
3537  if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
3538  if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3539  const VarDecl *CanonPVD = PVD->getCanonicalDecl();
3540  if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3541  FD->getParamDecl(PVD->getFunctionScopeIndex())
3542  ->getCanonicalDecl() == CanonPVD) {
3543  // OpenMP [2.15.3.7, linear Clause, Restrictions]
3544  // A list-item cannot appear in more than one linear clause.
3545  if (LinearArgs.count(CanonPVD) > 0) {
3546  Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3547  << getOpenMPClauseName(OMPC_linear)
3548  << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
3549  Diag(LinearArgs[CanonPVD]->getExprLoc(),
3550  diag::note_omp_explicit_dsa)
3551  << getOpenMPClauseName(OMPC_linear);
3552  continue;
3553  }
3554  // Each argument can appear in at most one uniform or linear clause.
3555  if (UniformedArgs.count(CanonPVD) > 0) {
3556  Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3557  << getOpenMPClauseName(OMPC_linear)
3559  Diag(UniformedArgs[CanonPVD]->getExprLoc(),
3560  diag::note_omp_explicit_dsa)
3562  continue;
3563  }
3564  LinearArgs[CanonPVD] = E;
3565  if (E->isValueDependent() || E->isTypeDependent() ||
3566  E->isInstantiationDependent() ||
3568  continue;
3569  (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
3570  PVD->getOriginalType());
3571  continue;
3572  }
3573  }
3574  if (isa<CXXThisExpr>(E)) {
3575  if (UniformedLinearThis) {
3576  Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3577  << getOpenMPClauseName(OMPC_linear)
3578  << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
3579  << E->getSourceRange();
3580  Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
3581  << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
3582  : OMPC_linear);
3583  continue;
3584  }
3585  UniformedLinearThis = E;
3586  if (E->isValueDependent() || E->isTypeDependent() ||
3588  continue;
3589  (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
3590  E->getType());
3591  continue;
3592  }
3593  Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3594  << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3595  }
3596  Expr *Step = nullptr;
3597  Expr *NewStep = nullptr;
3598  SmallVector<Expr *, 4> NewSteps;
3599  for (Expr *E : Steps) {
3600  // Skip the same step expression, it was checked already.
3601  if (Step == E || !E) {
3602  NewSteps.push_back(E ? NewStep : nullptr);
3603  continue;
3604  }
3605  Step = E;
3606  if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
3607  if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3608  const VarDecl *CanonPVD = PVD->getCanonicalDecl();
3609  if (UniformedArgs.count(CanonPVD) == 0) {
3610  Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
3611  << Step->getSourceRange();
3612  } else if (E->isValueDependent() || E->isTypeDependent() ||
3613  E->isInstantiationDependent() ||
3615  CanonPVD->getType()->hasIntegerRepresentation()) {
3616  NewSteps.push_back(Step);
3617  } else {
3618  Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
3619  << Step->getSourceRange();
3620  }
3621  continue;
3622  }
3623  NewStep = Step;
3624  if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
3625  !Step->isInstantiationDependent() &&
3627  NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
3628  .get();
3629  if (NewStep)
3630  NewStep = VerifyIntegerConstantExpression(NewStep).get();
3631  }
3632  NewSteps.push_back(NewStep);
3633  }
3634  auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
3635  Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
3636  Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
3637  const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
3638  const_cast<Expr **>(Linears.data()), Linears.size(),
3639  const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
3640  NewSteps.data(), NewSteps.size(), SR);
3641  ADecl->addAttr(NewAttr);
3642  return ConvertDeclToDeclGroup(ADecl);
3643 }
3644 
3646  Stmt *AStmt,
3647  SourceLocation StartLoc,
3648  SourceLocation EndLoc) {
3649  if (!AStmt)
3650  return StmtError();
3651 
3652  auto *CS = cast<CapturedStmt>(AStmt);
3653  // 1.2.2 OpenMP Language Terminology
3654  // Structured block - An executable statement with a single entry at the
3655  // top and a single exit at the bottom.
3656  // The point of exit cannot be a branch out of the structured block.
3657  // longjmp() and throw() must not violate the entry/exit criteria.
3658  CS->getCapturedDecl()->setNothrow();
3659 
3660  setFunctionHasBranchProtectedScope();
3661 
3662  return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
3663  DSAStack->isCancelRegion());
3664 }
3665 
3666 namespace {
3667 /// Helper class for checking canonical form of the OpenMP loops and
3668 /// extracting iteration space of each loop in the loop nest, that will be used
3669 /// for IR generation.
3670 class OpenMPIterationSpaceChecker {
3671  /// Reference to Sema.
3672  Sema &SemaRef;
3673  /// A location for diagnostics (when there is no some better location).
3674  SourceLocation DefaultLoc;
3675  /// A location for diagnostics (when increment is not compatible).
3676  SourceLocation ConditionLoc;
3677  /// A source location for referring to loop init later.
3678  SourceRange InitSrcRange;
3679  /// A source location for referring to condition later.
3680  SourceRange ConditionSrcRange;
3681  /// A source location for referring to increment later.
3682  SourceRange IncrementSrcRange;
3683  /// Loop variable.
3684  ValueDecl *LCDecl = nullptr;
3685  /// Reference to loop variable.
3686  Expr *LCRef = nullptr;
3687  /// Lower bound (initializer for the var).
3688  Expr *LB = nullptr;
3689  /// Upper bound.
3690  Expr *UB = nullptr;
3691  /// Loop step (increment).
3692  Expr *Step = nullptr;
3693  /// This flag is true when condition is one of:
3694  /// Var < UB
3695  /// Var <= UB
3696  /// UB > Var
3697  /// UB >= Var
3698  bool TestIsLessOp = false;
3699  /// This flag is true when condition is strict ( < or > ).
3700  bool TestIsStrictOp = false;
3701  /// This flag is true when step is subtracted on each iteration.
3702  bool SubtractStep = false;
3703 
3704 public:
3705  OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc)
3706  : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
3707  /// Check init-expr for canonical loop form and save loop counter
3708  /// variable - #Var and its initialization value - #LB.
3709  bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
3710  /// Check test-expr for canonical form, save upper-bound (#UB), flags
3711  /// for less/greater and for strict/non-strict comparison.
3712  bool checkAndSetCond(Expr *S);
3713  /// Check incr-expr for canonical loop form and return true if it
3714  /// does not conform, otherwise save loop step (#Step).
3715  bool checkAndSetInc(Expr *S);
3716  /// Return the loop counter variable.
3717  ValueDecl *getLoopDecl() const { return LCDecl; }
3718  /// Return the reference expression to loop counter variable.
3719  Expr *getLoopDeclRefExpr() const { return LCRef; }
3720  /// Source range of the loop init.
3721  SourceRange getInitSrcRange() const { return InitSrcRange; }
3722  /// Source range of the loop condition.
3723  SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
3724  /// Source range of the loop increment.
3725  SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
3726  /// True if the step should be subtracted.
3727  bool shouldSubtractStep() const { return SubtractStep; }
3728  /// Build the expression to calculate the number of iterations.
3729  Expr *buildNumIterations(
3730  Scope *S, const bool LimitedType,
3731  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
3732  /// Build the precondition expression for the loops.
3733  Expr *
3734  buildPreCond(Scope *S, Expr *Cond,
3735  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
3736  /// Build reference expression to the counter be used for codegen.
3737  DeclRefExpr *
3738  buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
3739  DSAStackTy &DSA) const;
3740  /// Build reference expression to the private counter be used for
3741  /// codegen.
3742  Expr *buildPrivateCounterVar() const;
3743  /// Build initialization of the counter be used for codegen.
3744  Expr *buildCounterInit() const;
3745  /// Build step of the counter be used for codegen.
3746  Expr *buildCounterStep() const;
3747  /// Build loop data with counter value for depend clauses in ordered
3748  /// directives.
3749  Expr *
3750  buildOrderedLoopData(Scope *S, Expr *Counter,
3751  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
3752  SourceLocation Loc, Expr *Inc = nullptr,
3753  OverloadedOperatorKind OOK = OO_Amp);
3754  /// Return true if any expression is dependent.
3755  bool dependent() const;
3756 
3757 private:
3758  /// Check the right-hand side of an assignment in the increment
3759  /// expression.
3760  bool checkAndSetIncRHS(Expr *RHS);
3761  /// Helper to set loop counter variable and its initializer.
3762  bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB);
3763  /// Helper to set upper bound.
3764  bool setUB(Expr *NewUB, bool LessOp, bool StrictOp, SourceRange SR,
3765  SourceLocation SL);
3766  /// Helper to set loop increment.
3767  bool setStep(Expr *NewStep, bool Subtract);
3768 };
3769 
3770 bool OpenMPIterationSpaceChecker::dependent() const {
3771  if (!LCDecl) {
3772  assert(!LB && !UB && !Step);
3773  return false;
3774  }
3775  return LCDecl->getType()->isDependentType() ||
3776  (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
3777  (Step && Step->isValueDependent());
3778 }
3779 
3780 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
3781  Expr *NewLCRefExpr,
3782  Expr *NewLB) {
3783  // State consistency checking to ensure correct usage.
3784  assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
3785  UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
3786  if (!NewLCDecl || !NewLB)
3787  return true;
3788  LCDecl = getCanonicalDecl(NewLCDecl);
3789  LCRef = NewLCRefExpr;
3790  if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
3791  if (const CXXConstructorDecl *Ctor = CE->getConstructor())
3792  if ((Ctor->isCopyOrMoveConstructor() ||
3793  Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
3794  CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
3795  NewLB = CE->getArg(0)->IgnoreParenImpCasts();
3796  LB = NewLB;
3797  return false;
3798 }
3799 
3800 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, bool LessOp, bool StrictOp,
3801  SourceRange SR, SourceLocation SL) {
3802  // State consistency checking to ensure correct usage.
3803  assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&
3804  Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
3805  if (!NewUB)
3806  return true;
3807  UB = NewUB;
3808  TestIsLessOp = LessOp;
3809  TestIsStrictOp = StrictOp;
3810  ConditionSrcRange = SR;
3811  ConditionLoc = SL;
3812  return false;
3813 }
3814 
3815 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
3816  // State consistency checking to ensure correct usage.
3817  assert(LCDecl != nullptr && LB != nullptr && Step == nullptr);
3818  if (!NewStep)
3819  return true;
3820  if (!NewStep->isValueDependent()) {
3821  // Check that the step is integer expression.
3822  SourceLocation StepLoc = NewStep->getLocStart();
3824  StepLoc, getExprAsWritten(NewStep));
3825  if (Val.isInvalid())
3826  return true;
3827  NewStep = Val.get();
3828 
3829  // OpenMP [2.6, Canonical Loop Form, Restrictions]
3830  // If test-expr is of form var relational-op b and relational-op is < or
3831  // <= then incr-expr must cause var to increase on each iteration of the
3832  // loop. If test-expr is of form var relational-op b and relational-op is
3833  // > or >= then incr-expr must cause var to decrease on each iteration of
3834  // the loop.
3835  // If test-expr is of form b relational-op var and relational-op is < or
3836  // <= then incr-expr must cause var to decrease on each iteration of the
3837  // loop. If test-expr is of form b relational-op var and relational-op is
3838  // > or >= then incr-expr must cause var to increase on each iteration of
3839  // the loop.
3840  llvm::APSInt Result;
3841  bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context);
3842  bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
3843  bool IsConstNeg =
3844  IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
3845  bool IsConstPos =
3846  IsConstant && Result.isSigned() && (Subtract == Result.isNegative());
3847  bool IsConstZero = IsConstant && !Result.getBoolValue();
3848  if (UB && (IsConstZero ||
3849  (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract))
3850  : (IsConstPos || (IsUnsigned && !Subtract))))) {
3851  SemaRef.Diag(NewStep->getExprLoc(),
3852  diag::err_omp_loop_incr_not_compatible)
3853  << LCDecl << TestIsLessOp << NewStep->getSourceRange();
3854  SemaRef.Diag(ConditionLoc,
3855  diag::note_omp_loop_cond_requres_compatible_incr)
3856  << TestIsLessOp << ConditionSrcRange;
3857  return true;
3858  }
3859  if (TestIsLessOp == Subtract) {
3860  NewStep =
3861  SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
3862  .get();
3863  Subtract = !Subtract;
3864  }
3865  }
3866 
3867  Step = NewStep;
3868  SubtractStep = Subtract;
3869  return false;
3870 }
3871 
3872 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
3873  // Check init-expr for canonical loop form and save loop counter
3874  // variable - #Var and its initialization value - #LB.
3875  // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
3876  // var = lb
3877  // integer-type var = lb
3878  // random-access-iterator-type var = lb
3879  // pointer-type var = lb
3880  //
3881  if (!S) {
3882  if (EmitDiags) {
3883  SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
3884  }
3885  return true;
3886  }
3887  if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
3888  if (!ExprTemp->cleanupsHaveSideEffects())
3889  S = ExprTemp->getSubExpr();
3890 
3891  InitSrcRange = S->getSourceRange();
3892  if (Expr *E = dyn_cast<Expr>(S))
3893  S = E->IgnoreParens();
3894  if (auto *BO = dyn_cast<BinaryOperator>(S)) {
3895  if (BO->getOpcode() == BO_Assign) {
3896  Expr *LHS = BO->getLHS()->IgnoreParens();
3897  if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
3898  if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
3899  if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
3900  return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3901  return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS());
3902  }
3903  if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
3904  if (ME->isArrow() &&
3905  isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3906  return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3907  }
3908  }
3909  } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
3910  if (DS->isSingleDecl()) {
3911  if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
3912  if (Var->hasInit() && !Var->getType()->isReferenceType()) {
3913  // Accept non-canonical init form here but emit ext. warning.
3914  if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
3915  SemaRef.Diag(S->getLocStart(),
3916  diag::ext_omp_loop_not_canonical_init)
3917  << S->getSourceRange();
3918  return setLCDeclAndLB(
3919  Var,
3920  buildDeclRefExpr(SemaRef, Var,
3921  Var->getType().getNonReferenceType(),
3922  DS->getLocStart()),
3923  Var->getInit());
3924  }
3925  }
3926  }
3927  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
3928  if (CE->getOperator() == OO_Equal) {
3929  Expr *LHS = CE->getArg(0);
3930  if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
3931  if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
3932  if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
3933  return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3934  return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1));
3935  }
3936  if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
3937  if (ME->isArrow() &&
3938  isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3939  return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3940  }
3941  }
3942  }
3943 
3944  if (dependent() || SemaRef.CurContext->isDependentContext())
3945  return false;
3946  if (EmitDiags) {
3947  SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_init)
3948  << S->getSourceRange();
3949  }
3950  return true;
3951 }
3952 
3953 /// Ignore parenthesizes, implicit casts, copy constructor and return the
3954 /// variable (which may be the loop variable) if possible.
3955 static const ValueDecl *getInitLCDecl(const Expr *E) {
3956  if (!E)
3957  return nullptr;
3958  E = getExprAsWritten(E);
3959  if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
3960  if (const CXXConstructorDecl *Ctor = CE->getConstructor())
3961  if ((Ctor->isCopyOrMoveConstructor() ||
3962  Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
3963  CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
3964  E = CE->getArg(0)->IgnoreParenImpCasts();
3965  if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
3966  if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
3967  return getCanonicalDecl(VD);
3968  }
3969  if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
3970  if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3971  return getCanonicalDecl(ME->getMemberDecl());
3972  return nullptr;
3973 }
3974 
3975 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
3976  // Check test-expr for canonical form, save upper-bound UB, flags for
3977  // less/greater and for strict/non-strict comparison.
3978  // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
3979  // var relational-op b
3980  // b relational-op var
3981  //
3982  if (!S) {
3983  SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl;
3984  return true;
3985  }
3986  S = getExprAsWritten(S);
3987  SourceLocation CondLoc = S->getLocStart();
3988  if (auto *BO = dyn_cast<BinaryOperator>(S)) {
3989  if (BO->isRelationalOp()) {
3990  if (getInitLCDecl(BO->getLHS()) == LCDecl)
3991  return setUB(BO->getRHS(),
3992  (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
3993  (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
3994  BO->getSourceRange(), BO->getOperatorLoc());
3995  if (getInitLCDecl(BO->getRHS()) == LCDecl)
3996  return setUB(BO->getLHS(),
3997  (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
3998  (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
3999  BO->getSourceRange(), BO->getOperatorLoc());
4000  }
4001  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
4002  if (CE->getNumArgs() == 2) {
4003  auto Op = CE->getOperator();
4004  switch (Op) {
4005  case OO_Greater:
4006  case OO_GreaterEqual:
4007  case OO_Less:
4008  case OO_LessEqual:
4009  if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4010  return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
4011  Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
4012  CE->getOperatorLoc());
4013  if (getInitLCDecl(CE->getArg(1)) == LCDecl)
4014  return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
4015  Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
4016  CE->getOperatorLoc());
4017  break;
4018  default:
4019  break;
4020  }
4021  }
4022  }
4023  if (dependent() || SemaRef.CurContext->isDependentContext())
4024  return false;
4025  SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
4026  << S->getSourceRange() << LCDecl;
4027  return true;
4028 }
4029 
4030 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
4031  // RHS of canonical loop form increment can be:
4032  // var + incr
4033  // incr + var
4034  // var - incr
4035  //
4036  RHS = RHS->IgnoreParenImpCasts();
4037  if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
4038  if (BO->isAdditiveOp()) {
4039  bool IsAdd = BO->getOpcode() == BO_Add;
4040  if (getInitLCDecl(BO->getLHS()) == LCDecl)
4041  return setStep(BO->getRHS(), !IsAdd);
4042  if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
4043  return setStep(BO->getLHS(), /*Subtract=*/false);
4044  }
4045  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
4046  bool IsAdd = CE->getOperator() == OO_Plus;
4047  if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
4048  if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4049  return setStep(CE->getArg(1), !IsAdd);
4050  if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
4051  return setStep(CE->getArg(0), /*Subtract=*/false);
4052  }
4053  }
4054  if (dependent() || SemaRef.CurContext->isDependentContext())
4055  return false;
4056  SemaRef.Diag(RHS->getLocStart(), diag::err_omp_loop_not_canonical_incr)
4057  << RHS->getSourceRange() << LCDecl;
4058  return true;
4059 }
4060 
4061 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
4062  // Check incr-expr for canonical loop form and return true if it
4063  // does not conform.
4064  // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
4065  // ++var
4066  // var++
4067  // --var
4068  // var--
4069  // var += incr
4070  // var -= incr
4071  // var = var + incr
4072  // var = incr + var
4073  // var = var - incr
4074  //
4075  if (!S) {
4076  SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
4077  return true;
4078  }
4079  if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
4080  if (!ExprTemp->cleanupsHaveSideEffects())
4081  S = ExprTemp->getSubExpr();
4082 
4083  IncrementSrcRange = S->getSourceRange();
4084  S = S->IgnoreParens();
4085  if (auto *UO = dyn_cast<UnaryOperator>(S)) {
4086  if (UO->isIncrementDecrementOp() &&
4087  getInitLCDecl(UO->getSubExpr()) == LCDecl)
4088  return setStep(SemaRef
4089  .ActOnIntegerConstant(UO->getLocStart(),
4090  (UO->isDecrementOp() ? -1 : 1))
4091  .get(),
4092  /*Subtract=*/false);
4093  } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
4094  switch (BO->getOpcode()) {
4095  case BO_AddAssign:
4096  case BO_SubAssign:
4097  if (getInitLCDecl(BO->getLHS()) == LCDecl)
4098  return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
4099  break;
4100  case BO_Assign:
4101  if (getInitLCDecl(BO->getLHS()) == LCDecl)
4102  return checkAndSetIncRHS(BO->getRHS());
4103  break;
4104  default:
4105  break;
4106  }
4107  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
4108  switch (CE->getOperator()) {
4109  case OO_PlusPlus:
4110  case OO_MinusMinus:
4111  if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4112  return setStep(SemaRef
4113  .ActOnIntegerConstant(
4114  CE->getLocStart(),
4115  ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
4116  .get(),
4117  /*Subtract=*/false);
4118  break;
4119  case OO_PlusEqual:
4120  case OO_MinusEqual:
4121  if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4122  return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
4123  break;
4124  case OO_Equal:
4125  if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4126  return checkAndSetIncRHS(CE->getArg(1));
4127  break;
4128  default:
4129  break;
4130  }
4131  }
4132  if (dependent() || SemaRef.CurContext->isDependentContext())
4133  return false;
4134  SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_incr)
4135  << S->getSourceRange() << LCDecl;
4136  return true;
4137 }
4138 
4139 static ExprResult
4140 tryBuildCapture(Sema &SemaRef, Expr *Capture,
4141  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
4142  if (SemaRef.CurContext->isDependentContext())
4143  return ExprResult(Capture);
4144  if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
4145  return SemaRef.PerformImplicitConversion(
4146  Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
4147  /*AllowExplicit=*/true);
4148  auto I = Captures.find(Capture);
4149  if (I != Captures.end())
4150  return buildCapture(SemaRef, Capture, I->second);
4151  DeclRefExpr *Ref = nullptr;
4152  ExprResult Res = buildCapture(SemaRef, Capture, Ref);
4153  Captures[Capture] = Ref;
4154  return Res;
4155 }
4156 
4157 /// Build the expression to calculate the number of iterations.
4158 Expr *OpenMPIterationSpaceChecker::buildNumIterations(
4159  Scope *S, const bool LimitedType,
4160  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
4161  ExprResult Diff;
4162  QualType VarType = LCDecl->getType().getNonReferenceType();
4163  if (VarType->isIntegerType() || VarType->isPointerType() ||
4164  SemaRef.getLangOpts().CPlusPlus) {
4165  // Upper - Lower
4166  Expr *UBExpr = TestIsLessOp ? UB : LB;
4167  Expr *LBExpr = TestIsLessOp ? LB : UB;
4168  Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
4169  Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
4170  if (!Upper || !Lower)
4171  return nullptr;
4172 
4173  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
4174 
4175  if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) {
4176  // BuildBinOp already emitted error, this one is to point user to upper
4177  // and lower bound, and to tell what is passed to 'operator-'.
4178  SemaRef.Diag(Upper->getLocStart(), diag::err_omp_loop_diff_cxx)
4179  << Upper->getSourceRange() << Lower->getSourceRange();
4180  return nullptr;
4181  }
4182  }
4183 
4184  if (!Diff.isUsable())
4185  return nullptr;
4186 
4187  // Upper - Lower [- 1]
4188  if (TestIsStrictOp)
4189  Diff = SemaRef.BuildBinOp(
4190  S, DefaultLoc, BO_Sub, Diff.get(),
4191  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
4192  if (!Diff.isUsable())
4193  return nullptr;
4194 
4195  // Upper - Lower [- 1] + Step
4196  ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
4197  if (!NewStep.isUsable())
4198  return nullptr;
4199  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
4200  if (!Diff.isUsable())
4201  return nullptr;
4202 
4203  // Parentheses (for dumping/debugging purposes only).
4204  Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
4205  if (!Diff.isUsable())
4206  return nullptr;
4207 
4208  // (Upper - Lower [- 1] + Step) / Step
4209  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
4210  if (!Diff.isUsable())
4211  return nullptr;
4212 
4213  // OpenMP runtime requires 32-bit or 64-bit loop variables.
4214  QualType Type = Diff.get()->getType();
4215  ASTContext &C = SemaRef.Context;
4216  bool UseVarType = VarType->hasIntegerRepresentation() &&
4217  C.getTypeSize(Type) > C.getTypeSize(VarType);
4218  if (!Type->isIntegerType() || UseVarType) {
4219  unsigned NewSize =
4220  UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
4221  bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
4223  Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
4224  if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
4225  Diff = SemaRef.PerformImplicitConversion(
4226  Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
4227  if (!Diff.isUsable())
4228  return nullptr;
4229  }
4230  }
4231  if (LimitedType) {
4232  unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
4233  if (NewSize != C.getTypeSize(Type)) {
4234  if (NewSize < C.getTypeSize(Type)) {
4235  assert(NewSize == 64 && "incorrect loop var size");
4236  SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
4237  << InitSrcRange << ConditionSrcRange;
4238  }
4239  QualType NewType = C.getIntTypeForBitwidth(
4240  NewSize, Type->hasSignedIntegerRepresentation() ||
4241  C.getTypeSize(Type) < NewSize);
4242  if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
4243  Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
4244  Sema::AA_Converting, true);
4245  if (!Diff.isUsable())
4246  return nullptr;
4247  }
4248  }
4249  }
4250 
4251  return Diff.get();
4252 }
4253 
4254 Expr *OpenMPIterationSpaceChecker::buildPreCond(
4255  Scope *S, Expr *Cond,
4256  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
4257  // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
4258  bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
4259  SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
4260 
4261  ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
4262  ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
4263  if (!NewLB.isUsable() || !NewUB.isUsable())
4264  return nullptr;
4265 
4266  ExprResult CondExpr =
4267  SemaRef.BuildBinOp(S, DefaultLoc,
4268  TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE)
4269  : (TestIsStrictOp ? BO_GT : BO_GE),
4270  NewLB.get(), NewUB.get());
4271  if (CondExpr.isUsable()) {
4272  if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
4273  SemaRef.Context.BoolTy))
4274  CondExpr = SemaRef.PerformImplicitConversion(
4275  CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
4276  /*AllowExplicit=*/true);
4277  }
4278  SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
4279  // Otherwise use original loop conditon and evaluate it in runtime.
4280  return CondExpr.isUsable() ? CondExpr.get() : Cond;
4281 }
4282 
4283 /// Build reference expression to the counter be used for codegen.
4284 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
4285  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
4286  DSAStackTy &DSA) const {
4287  auto *VD = dyn_cast<VarDecl>(LCDecl);
4288  if (!VD) {
4289  VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
4291  SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
4292  const DSAStackTy::DSAVarData Data =
4293  DSA.getTopDSA(LCDecl, /*FromParent=*/false);
4294  // If the loop control decl is explicitly marked as private, do not mark it
4295  // as captured again.
4296  if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
4297  Captures.insert(std::make_pair(LCRef, Ref));
4298  return Ref;
4299  }
4300  return buildDeclRefExpr(SemaRef, VD, VD->getType().getNonReferenceType(),
4301  DefaultLoc);
4302 }
4303 
4304 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
4305  if (LCDecl && !LCDecl->isInvalidDecl()) {
4306  QualType Type = LCDecl->getType().getNonReferenceType();
4307  VarDecl *PrivateVar = buildVarDecl(
4308  SemaRef, DefaultLoc, Type, LCDecl->getName(),
4309  LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
4310  isa<VarDecl>(LCDecl)
4311  ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
4312  : nullptr);
4313  if (PrivateVar->isInvalidDecl())
4314  return nullptr;
4315  return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
4316  }
4317  return nullptr;
4318 }
4319 
4320 /// Build initialization of the counter to be used for codegen.
4322 
4323 /// Build step of the counter be used for codegen.
4324 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
4325 
4326 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
4327  Scope *S, Expr *Counter,
4328  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
4329  Expr *Inc, OverloadedOperatorKind OOK) {
4330  Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
4331  if (!Cnt)
4332  return nullptr;
4333  if (Inc) {
4334  assert((OOK == OO_Plus || OOK == OO_Minus) &&
4335  "Expected only + or - operations for depend clauses.");
4336  BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
4337  Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
4338  if (!Cnt)
4339  return nullptr;
4340  }
4341  ExprResult Diff;
4342  QualType VarType = LCDecl->getType().getNonReferenceType();
4343  if (VarType->isIntegerType() || VarType->isPointerType() ||
4344  SemaRef.getLangOpts().CPlusPlus) {
4345  // Upper - Lower
4346  Expr *Upper =
4347  TestIsLessOp ? Cnt : tryBuildCapture(SemaRef, UB, Captures).get();
4348  Expr *Lower =
4349  TestIsLessOp ? tryBuildCapture(SemaRef, LB, Captures).get() : Cnt;
4350  if (!Upper || !Lower)
4351  return nullptr;
4352 
4353  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
4354 
4355  if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) {
4356  // BuildBinOp already emitted error, this one is to point user to upper
4357  // and lower bound, and to tell what is passed to 'operator-'.
4358  SemaRef.Diag(Upper->getLocStart(), diag::err_omp_loop_diff_cxx)
4359  << Upper->getSourceRange() << Lower->getSourceRange();
4360  return nullptr;
4361  }
4362  }
4363 
4364  if (!Diff.isUsable())
4365  return nullptr;
4366 
4367  // Parentheses (for dumping/debugging purposes only).
4368  Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
4369  if (!Diff.isUsable())
4370  return nullptr;
4371 
4372  ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
4373  if (!NewStep.isUsable())
4374  return nullptr;
4375  // (Upper - Lower) / Step
4376  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
4377  if (!Diff.isUsable())
4378  return nullptr;
4379 
4380  return Diff.get();
4381 }
4382 
4383 /// Iteration space of a single for loop.
4384 struct LoopIterationSpace final {
4385  /// Condition of the loop.
4386  Expr *PreCond = nullptr;
4387  /// This expression calculates the number of iterations in the loop.
4388  /// It is always possible to calculate it before starting the loop.
4389  Expr *NumIterations = nullptr;
4390  /// The loop counter variable.
4391  Expr *CounterVar = nullptr;
4392  /// Private loop counter variable.
4393  Expr *PrivateCounterVar = nullptr;
4394  /// This is initializer for the initial value of #CounterVar.
4395  Expr *CounterInit = nullptr;
4396  /// This is step for the #CounterVar used to generate its update:
4397  /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
4398  Expr *CounterStep = nullptr;
4399  /// Should step be subtracted?
4400  bool Subtract = false;
4401  /// Source range of the loop init.
4402  SourceRange InitSrcRange;
4403  /// Source range of the loop condition.
4404  SourceRange CondSrcRange;
4405  /// Source range of the loop increment.
4406  SourceRange IncSrcRange;
4407 };
4408 
4409 } // namespace
4410 
4412  assert(getLangOpts().OpenMP && "OpenMP is not active.");
4413  assert(Init && "Expected loop in canonical form.");
4414  unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
4415  if (AssociatedLoops > 0 &&
4416  isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
4417  OpenMPIterationSpaceChecker ISC(*this, ForLoc);
4418  if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
4419  if (ValueDecl *D = ISC.getLoopDecl()) {
4420  auto *VD = dyn_cast<VarDecl>(D);
4421  if (!VD) {
4422  if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
4423  VD = Private;
4424  } else {
4425  DeclRefExpr *Ref = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
4426  /*WithInit=*/false);
4427  VD = cast<VarDecl>(Ref->getDecl());
4428  }
4429  }
4430  DSAStack->addLoopControlVariable(D, VD);
4431  }
4432  }
4433  DSAStack->setAssociatedLoops(AssociatedLoops - 1);
4434  }
4435 }
4436 
4437 /// Called on a for stmt to check and extract its iteration space
4438 /// for further processing (such as collapsing).
4440  OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
4441  unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
4442  unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
4443  Expr *OrderedLoopCountExpr,
4444  Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
4445  LoopIterationSpace &ResultIterSpace,
4446  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
4447  // OpenMP [2.6, Canonical Loop Form]
4448  // for (init-expr; test-expr; incr-expr) structured-block
4449  auto *For = dyn_cast_or_null<ForStmt>(S);
4450  if (!For) {
4451  SemaRef.Diag(S->getLocStart(), diag::err_omp_not_for)
4452  << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
4453  << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
4454  << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
4455  if (TotalNestedLoopCount > 1) {
4456  if (CollapseLoopCountExpr && OrderedLoopCountExpr)
4457  SemaRef.Diag(DSA.getConstructLoc(),
4458  diag::note_omp_collapse_ordered_expr)
4459  << 2 << CollapseLoopCountExpr->getSourceRange()
4460  << OrderedLoopCountExpr->getSourceRange();
4461  else if (CollapseLoopCountExpr)
4462  SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
4463  diag::note_omp_collapse_ordered_expr)
4464  << 0 << CollapseLoopCountExpr->getSourceRange();
4465  else
4466  SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
4467  diag::note_omp_collapse_ordered_expr)
4468  << 1 << OrderedLoopCountExpr->getSourceRange();
4469  }
4470  return true;
4471  }
4472  assert(For->getBody());
4473 
4474  OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc());
4475 
4476  // Check init.
4477  Stmt *Init = For->getInit();
4478  if (ISC.checkAndSetInit(Init))
4479  return true;
4480 
4481  bool HasErrors = false;
4482 
4483  // Check loop variable's type.
4484  if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
4485  Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
4486 
4487  // OpenMP [2.6, Canonical Loop Form]
4488  // Var is one of the following:
4489  // A variable of signed or unsigned integer type.
4490  // For C++, a variable of a random access iterator type.
4491  // For C, a variable of a pointer type.
4492  QualType VarType = LCDecl->getType().getNonReferenceType();
4493  if (!VarType->isDependentType() && !VarType->isIntegerType() &&
4494  !VarType->isPointerType() &&
4495  !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
4496  SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_variable_type)
4497  << SemaRef.getLangOpts().CPlusPlus;
4498  HasErrors = true;
4499  }
4500 
4501  // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
4502  // a Construct
4503  // The loop iteration variable(s) in the associated for-loop(s) of a for or
4504  // parallel for construct is (are) private.
4505  // The loop iteration variable in the associated for-loop of a simd
4506  // construct with just one associated for-loop is linear with a
4507  // constant-linear-step that is the increment of the associated for-loop.
4508  // Exclude loop var from the list of variables with implicitly defined data
4509  // sharing attributes.
4510  VarsWithImplicitDSA.erase(LCDecl);
4511 
4512  // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
4513  // in a Construct, C/C++].
4514  // The loop iteration variable in the associated for-loop of a simd
4515  // construct with just one associated for-loop may be listed in a linear
4516  // clause with a constant-linear-step that is the increment of the
4517  // associated for-loop.
4518  // The loop iteration variable(s) in the associated for-loop(s) of a for or
4519  // parallel for construct may be listed in a private or lastprivate clause.
4520  DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl, false);
4521  // If LoopVarRefExpr is nullptr it means the corresponding loop variable is
4522  // declared in the loop and it is predetermined as a private.
4523  OpenMPClauseKind PredeterminedCKind =
4524  isOpenMPSimdDirective(DKind)
4525  ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate)
4526  : OMPC_private;
4527  if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
4528  DVar.CKind != PredeterminedCKind) ||
4529  ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
4530  isOpenMPDistributeDirective(DKind)) &&
4531  !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
4532  DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
4533  (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
4534  SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa)
4535  << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind)
4536  << getOpenMPClauseName(PredeterminedCKind);
4537  if (DVar.RefExpr == nullptr)
4538  DVar.CKind = PredeterminedCKind;
4539  reportOriginalDsa(SemaRef, &DSA, LCDecl, DVar, /*IsLoopIterVar=*/true);
4540  HasErrors = true;
4541  } else if (LoopDeclRefExpr != nullptr) {
4542  // Make the loop iteration variable private (for worksharing constructs),
4543  // linear (for simd directives with the only one associated loop) or
4544  // lastprivate (for simd directives with several collapsed or ordered
4545  // loops).
4546  if (DVar.CKind == OMPC_unknown)
4547  DVar = DSA.hasDSA(LCDecl, isOpenMPPrivate,
4548  [](OpenMPDirectiveKind) -> bool { return true; },
4549  /*FromParent=*/false);
4550  DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind);
4551  }
4552 
4553  assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
4554 
4555  // Check test-expr.
4556  HasErrors |= ISC.checkAndSetCond(For->getCond());
4557 
4558  // Check incr-expr.
4559  HasErrors |= ISC.checkAndSetInc(For->getInc());
4560  }
4561 
4562  if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
4563  return HasErrors;
4564 
4565  // Build the loop's iteration space representation.
4566  ResultIterSpace.PreCond =
4567  ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures);
4568  ResultIterSpace.NumIterations = ISC.buildNumIterations(
4569  DSA.getCurScope(),
4570  (isOpenMPWorksharingDirective(DKind) ||
4572  Captures);
4573  ResultIterSpace.CounterVar = ISC.buildCounterVar(Captures, DSA);
4574  ResultIterSpace.PrivateCounterVar = ISC.buildPrivateCounterVar();
4575  ResultIterSpace.CounterInit = ISC.buildCounterInit();
4576  ResultIterSpace.CounterStep = ISC.buildCounterStep();
4577  ResultIterSpace.InitSrcRange = ISC.getInitSrcRange();
4578  ResultIterSpace.CondSrcRange = ISC.getConditionSrcRange();
4579  ResultIterSpace.IncSrcRange = ISC.getIncrementSrcRange();
4580  ResultIterSpace.Subtract = ISC.shouldSubtractStep();
4581 
4582  HasErrors |= (ResultIterSpace.PreCond == nullptr ||
4583  ResultIterSpace.NumIterations == nullptr ||
4584  ResultIterSpace.CounterVar == nullptr ||
4585  ResultIterSpace.PrivateCounterVar == nullptr ||
4586  ResultIterSpace.CounterInit == nullptr ||
4587  ResultIterSpace.CounterStep == nullptr);
4588  if (!HasErrors && DSA.isOrderedRegion()) {
4589  if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
4590  if (CurrentNestedLoopCount <
4591  DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
4592  DSA.getOrderedRegionParam().second->setLoopNumIterations(
4593  CurrentNestedLoopCount, ResultIterSpace.NumIterations);
4594  DSA.getOrderedRegionParam().second->setLoopCounter(
4595  CurrentNestedLoopCount, ResultIterSpace.CounterVar);
4596  }
4597  }
4598  for (auto &Pair : DSA.getDoacrossDependClauses()) {
4599  if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
4600  // Erroneous case - clause has some problems.
4601  continue;
4602  }
4603  if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
4604  Pair.second.size() <= CurrentNestedLoopCount) {
4605  // Erroneous case - clause has some problems.
4606  Pair.first->setLoopData(CurrentNestedLoopCount, nullptr);
4607  continue;
4608  }
4609  Expr *CntValue;
4610  if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
4611  CntValue = ISC.buildOrderedLoopData(
4612  DSA.getCurScope(), ResultIterSpace.CounterVar, Captures,
4613  Pair.first->getDependencyLoc());
4614  else
4615  CntValue = ISC.buildOrderedLoopData(
4616  DSA.getCurScope(), ResultIterSpace.CounterVar, Captures,
4617  Pair.first->getDependencyLoc(),
4618  Pair.second[CurrentNestedLoopCount].first,
4619  Pair.second[CurrentNestedLoopCount].second);
4620  Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
4621  }
4622  }
4623 
4624  return HasErrors;
4625 }
4626 
4627 /// Build 'VarRef = Start.
4628 static ExprResult
4630  ExprResult Start,
4631  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
4632  // Build 'VarRef = Start.
4633  ExprResult NewStart = tryBuildCapture(SemaRef, Start.get(), Captures);
4634  if (!NewStart.isUsable())
4635  return ExprError();
4636  if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
4637  VarRef.get()->getType())) {
4638  NewStart = SemaRef.PerformImplicitConversion(
4639  NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
4640  /*AllowExplicit=*/true);
4641  if (!NewStart.isUsable())
4642  return ExprError();
4643  }
4644 
4645  ExprResult Init =
4646  SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
4647  return Init;
4648 }
4649 
4650 /// Build 'VarRef = Start + Iter * Step'.
4652  Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
4653  ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
4654  llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
4655  // Add parentheses (for debugging purposes only).
4656  Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
4657  if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
4658  !Step.isUsable())
4659  return ExprError();
4660 
4661  ExprResult NewStep = Step;
4662  if (Captures)
4663  NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
4664  if (NewStep.isInvalid())
4665  return ExprError();
4666  ExprResult Update =
4667  SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
4668  if (!Update.isUsable())
4669  return ExprError();
4670 
4671  // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
4672  // 'VarRef = Start (+|-) Iter * Step'.
4673  ExprResult NewStart = Start;
4674  if (Captures)
4675  NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
4676  if (NewStart.isInvalid())
4677  return ExprError();
4678 
4679  // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
4680  ExprResult SavedUpdate = Update;
4681  ExprResult UpdateVal;
4682  if (VarRef.get()->getType()->isOverloadableType() ||
4683  NewStart.get()->getType()->isOverloadableType() ||
4684  Update.get()->getType()->isOverloadableType()) {
4685  bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
4686  SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
4687  Update =
4688  SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
4689  if (Update.isUsable()) {
4690  UpdateVal =
4691  SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
4692  VarRef.get(), SavedUpdate.get());
4693  if (UpdateVal.isUsable()) {
4694  Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
4695  UpdateVal.get());
4696  }
4697  }
4698  SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
4699  }
4700 
4701  // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
4702  if (!Update.isUsable() || !UpdateVal.isUsable()) {
4703  Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
4704  NewStart.get(), SavedUpdate.get());
4705  if (!Update.isUsable())
4706  return ExprError();
4707 
4708  if (!SemaRef.Context.hasSameType(Update.get()->getType(),
4709  VarRef.get()->getType())) {
4710  Update = SemaRef.PerformImplicitConversion(
4711  Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
4712  if (!Update.isUsable())
4713  return ExprError();
4714  }
4715 
4716  Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
4717  }
4718  return Update;
4719 }
4720 
4721 /// Convert integer expression \a E to make it have at least \a Bits
4722 /// bits.
4723 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
4724  if (E == nullptr)
4725  return ExprError();
4726  ASTContext &C = SemaRef.Context;
4727  QualType OldType = E->getType();
4728  unsigned HasBits = C.getTypeSize(OldType);
4729  if (HasBits >= Bits)
4730  return ExprResult(E);
4731  // OK to convert to signed, because new type has more bits than old.
4732  QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
4733  return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
4734  true);
4735 }
4736 
4737 /// Check if the given expression \a E is a constant integer that fits
4738 /// into \a Bits bits.
4739 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
4740  if (E == nullptr)
4741  return false;
4742  llvm::APSInt Result;
4743  if (E->isIntegerConstantExpr(Result, SemaRef.Context))
4744  return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits);
4745  return false;
4746 }
4747 
4748 /// Build preinits statement for the given declarations.
4749 static Stmt *buildPreInits(ASTContext &Context,
4750  MutableArrayRef<Decl *> PreInits) {
4751  if (!PreInits.empty()) {
4752  return new (Context) DeclStmt(
4753  DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
4755  }
4756  return nullptr;
4757 }
4758 
4759 /// Build preinits statement for the given declarations.
4760 static Stmt *
4762  const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
4763  if (!Captures.empty()) {
4764  SmallVector<Decl *, 16> PreInits;
4765  for (const auto &Pair : Captures)
4766  PreInits.push_back(Pair.second->getDecl());
4767  return buildPreInits(Context, PreInits);
4768  }
4769  return nullptr;
4770 }
4771 
4772 /// Build postupdate expression for the given list of postupdates expressions.
4773 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
4774  Expr *PostUpdate = nullptr;
4775  if (!PostUpdates.empty()) {
4776  for (Expr *E : PostUpdates) {
4777  Expr *ConvE = S.BuildCStyleCastExpr(
4778  E->getExprLoc(),
4780  E->getExprLoc(), E)
4781  .get();
4782  PostUpdate = PostUpdate
4783  ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
4784  PostUpdate, ConvE)
4785  .get()
4786  : ConvE;
4787  }
4788  }
4789  return PostUpdate;
4790 }
4791 
4792 /// Called on a for stmt to check itself and nested loops (if any).
4793 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
4794 /// number of collapsed loops otherwise.
4795 static unsigned
4796 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
4797  Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
4798  DSAStackTy &DSA,
4799  Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
4801  unsigned NestedLoopCount = 1;
4802  if (CollapseLoopCountExpr) {
4803  // Found 'collapse' clause - calculate collapse number.
4804  llvm::APSInt Result;
4805  if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext()))
4806  NestedLoopCount = Result.getLimitedValue();
4807  }
4808  unsigned OrderedLoopCount = 1;
4809  if (OrderedLoopCountExpr) {
4810  // Found 'ordered' clause - calculate collapse number.
4811  llvm::APSInt Result;
4812  if (OrderedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
4813  if (Result.getLimitedValue() < NestedLoopCount) {
4814  SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
4815  diag::err_omp_wrong_ordered_loop_count)
4816  << OrderedLoopCountExpr->getSourceRange();
4817  SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
4818  diag::note_collapse_loop_count)
4819  << CollapseLoopCountExpr->getSourceRange();
4820  }
4821  OrderedLoopCount = Result.getLimitedValue();
4822  }
4823  }
4824  // This is helper routine for loop directives (e.g., 'for', 'simd',
4825  // 'for simd', etc.).
4826  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
4828  IterSpaces.resize(std::max(OrderedLoopCount, NestedLoopCount));
4829  Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true);
4830  for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
4832  DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
4833  std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
4834  OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt],
4835  Captures))
4836  return 0;
4837  // Move on to the next nested for loop, or to the loop body.
4838  // OpenMP [2.8.1, simd construct, Restrictions]
4839  // All loops associated with the construct must be perfectly nested; that
4840  // is, there must be no intervening code nor any OpenMP directive between
4841  // any two loops.
4842  CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers();
4843  }
4844  for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) {
4846  DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
4847  std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
4848  OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt],
4849  Captures))
4850  return 0;
4851  if (Cnt > 0 && IterSpaces[Cnt].CounterVar) {
4852  // Handle initialization of captured loop iterator variables.
4853  auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
4854  if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
4855  Captures[DRE] = DRE;
4856  }
4857  }
4858  // Move on to the next nested for loop, or to the loop body.
4859  // OpenMP [2.8.1, simd construct, Restrictions]
4860  // All loops associated with the construct must be perfectly nested; that
4861  // is, there must be no intervening code nor any OpenMP directive between
4862  // any two loops.
4863  CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers();
4864  }
4865 
4866  Built.clear(/* size */ NestedLoopCount);
4867 
4868  if (SemaRef.CurContext->isDependentContext())
4869  return NestedLoopCount;
4870 
4871  // An example of what is generated for the following code:
4872  //
4873  // #pragma omp simd collapse(2) ordered(2)
4874  // for (i = 0; i < NI; ++i)
4875  // for (k = 0; k < NK; ++k)
4876  // for (j = J0; j < NJ; j+=2) {
4877  // <loop body>
4878  // }
4879  //
4880  // We generate the code below.
4881  // Note: the loop body may be outlined in CodeGen.
4882  // Note: some counters may be C++ classes, operator- is used to find number of
4883  // iterations and operator+= to calculate counter value.
4884  // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
4885  // or i64 is currently supported).
4886  //
4887  // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
4888  // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
4889  // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
4890  // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
4891  // // similar updates for vars in clauses (e.g. 'linear')
4892  // <loop body (using local i and j)>
4893  // }
4894  // i = NI; // assign final values of counters
4895  // j = NJ;
4896  //
4897 
4898  // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
4899  // the iteration counts of the collapsed for loops.
4900  // Precondition tests if there is at least one iteration (all conditions are
4901  // true).
4902  auto PreCond = ExprResult(IterSpaces[0].PreCond);
4903  Expr *N0 = IterSpaces[0].NumIterations;
4904  ExprResult LastIteration32 =
4905  widenIterationCount(/*Bits=*/32,
4906  SemaRef
4907  .PerformImplicitConversion(
4908  N0->IgnoreImpCasts(), N0->getType(),
4909  Sema::AA_Converting, /*AllowExplicit=*/true)
4910  .get(),
4911  SemaRef);
4912  ExprResult LastIteration64 = widenIterationCount(
4913  /*Bits=*/64,
4914  SemaRef
4915  .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
4917  /*AllowExplicit=*/true)
4918  .get(),
4919  SemaRef);
4920 
4921  if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
4922  return NestedLoopCount;
4923 
4924  ASTContext &C = SemaRef.Context;
4925  bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
4926 
4927  Scope *CurScope = DSA.getCurScope();
4928  for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
4929  if (PreCond.isUsable()) {
4930  PreCond =
4931  SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
4932  PreCond.get(), IterSpaces[Cnt].PreCond);
4933  }
4934  Expr *N = IterSpaces[Cnt].NumIterations;
4935  SourceLocation Loc = N->getExprLoc();
4936  AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
4937  if (LastIteration32.isUsable())
4938  LastIteration32 = SemaRef.BuildBinOp(
4939  CurScope, Loc, BO_Mul, LastIteration32.get(),
4940  SemaRef
4943  /*AllowExplicit=*/true)
4944  .get());
4945  if (LastIteration64.isUsable())
4946  LastIteration64 = SemaRef.BuildBinOp(
4947  CurScope, Loc, BO_Mul, LastIteration64.get(),
4948  SemaRef
4951  /*AllowExplicit=*/true)
4952  .get());
4953  }
4954 
4955  // Choose either the 32-bit or 64-bit version.
4956  ExprResult LastIteration = LastIteration64;
4957  if (LastIteration32.isUsable() &&
4958  C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
4959  (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
4960  fitsInto(
4961  /*Bits=*/32,
4962  LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
4963  LastIteration64.get(), SemaRef)))
4964  LastIteration = LastIteration32;
4965  QualType VType = LastIteration.get()->getType();
4966  QualType RealVType = VType;
4967  QualType StrideVType = VType;
4968  if (isOpenMPTaskLoopDirective(DKind)) {
4969  VType =
4970  SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
4971  StrideVType =
4972  SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
4973  }
4974 
4975  if (!LastIteration.isUsable())
4976  return 0;
4977 
4978  // Save the number of iterations.
4979  ExprResult NumIterations = LastIteration;
4980  {
4981  LastIteration = SemaRef.BuildBinOp(
4982  CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
4983  LastIteration.get(),
4984  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
4985  if (!LastIteration.isUsable())
4986  return 0;
4987  }
4988 
4989  // Calculate the last iteration number beforehand instead of doing this on
4990  // each iteration. Do not do this if the number of iterations may be kfold-ed.
4991  llvm::APSInt Result;
4992  bool IsConstant =
4993  LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context);
4994  ExprResult CalcLastIteration;
4995  if (!IsConstant) {
4996  ExprResult SaveRef =
4997  tryBuildCapture(SemaRef, LastIteration.get(), Captures);
4998  LastIteration = SaveRef;
4999 
5000  // Prepare SaveRef + 1.
5001  NumIterations = SemaRef.BuildBinOp(
5002  CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
5003  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
5004  if (!NumIterations.isUsable())
5005  return 0;
5006  }
5007 
5008  SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
5009 
5010  // Build variables passed into runtime, necessary for worksharing directives.
5011  ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
5013  isOpenMPDistributeDirective(DKind)) {
5014  // Lower bound variable, initialized with zero.
5015  VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
5016  LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
5017  SemaRef.AddInitializerToDecl(LBDecl,
5018  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
5019  /*DirectInit*/ false);
5020 
5021  // Upper bound variable, initialized with last iteration number.
5022  VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
5023  UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
5024  SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
5025  /*DirectInit*/ false);
5026 
5027  // A 32-bit variable-flag where runtime returns 1 for the last iteration.
5028  // This will be used to implement clause 'lastprivate'.
5029  QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
5030  VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
5031  IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
5032  SemaRef.AddInitializerToDecl(ILDecl,
5033  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
5034  /*DirectInit*/ false);
5035 
5036  // Stride variable returned by runtime (we initialize it to 1 by default).
5037  VarDecl *STDecl =
5038  buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
5039  ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
5040  SemaRef.AddInitializerToDecl(STDecl,
5041  SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
5042  /*DirectInit*/ false);
5043 
5044  // Build expression: UB = min(UB, LastIteration)
5045  // It is necessary for CodeGen of directives with static scheduling.
5046  ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
5047  UB.get(), LastIteration.get());
5048  ExprResult CondOp = SemaRef.ActOnConditionalOp(
5049  LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
5050  LastIteration.get(), UB.get());
5051  EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
5052  CondOp.get());
5053  EUB = SemaRef.ActOnFinishFullExpr(EUB.get());
5054 
5055  // If we have a combined directive that combines 'distribute', 'for' or
5056  // 'simd' we need to be able to access the bounds of the schedule of the
5057  // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
5058  // by scheduling 'distribute' have to be passed to the schedule of 'for'.
5059  if (isOpenMPLoopBoundSharingDirective(DKind)) {
5060  // Lower bound variable, initialized with zero.
5061  VarDecl *CombLBDecl =
5062  buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
5063  CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
5064  SemaRef.AddInitializerToDecl(
5065  CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
5066  /*DirectInit*/ false);
5067 
5068  // Upper bound variable, initialized with last iteration number.
5069  VarDecl *CombUBDecl =
5070  buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
5071  CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
5072  SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
5073  /*DirectInit*/ false);
5074 
5075  ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
5076  CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
5077  ExprResult CombCondOp =
5078  SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
5079  LastIteration.get(), CombUB.get());
5080  CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
5081  CombCondOp.get());
5082  CombEUB = SemaRef.ActOnFinishFullExpr(CombEUB.get());
5083 
5084  const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
5085  // We expect to have at least 2 more parameters than the 'parallel'
5086  // directive does - the lower and upper bounds of the previous schedule.
5087  assert(CD->getNumParams() >= 4 &&
5088  "Unexpected number of parameters in loop combined directive");
5089 
5090  // Set the proper type for the bounds given what we learned from the
5091  // enclosed loops.
5092  ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
5093  ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
5094 
5095  // Previous lower and upper bounds are obtained from the region
5096  // parameters.
5097  PrevLB =
5098  buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
5099  PrevUB =
5100  buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
5101  }
5102  }
5103 
5104  // Build the iteration variable and its initialization before loop.
5105  ExprResult IV;
5106  ExprResult Init, CombInit;
5107  {
5108  VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
5109  IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
5110  Expr *RHS =
5111  (isOpenMPWorksharingDirective(DKind) ||
5113  ? LB.get()
5114  : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
5115  Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
5116  Init = SemaRef.ActOnFinishFullExpr(Init.get());
5117 
5118  if (isOpenMPLoopBoundSharingDirective(DKind)) {
5119  Expr *CombRHS =
5120  (isOpenMPWorksharingDirective(DKind) ||
5121  isOpenMPTaskLoopDirective(DKind) ||
5123  ? CombLB.get()
5124  : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
5125  CombInit =
5126  SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
5127  CombInit = SemaRef.ActOnFinishFullExpr(CombInit.get());
5128  }
5129  }
5130 
5131  // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops.
5132  SourceLocation CondLoc = AStmt->getLocStart();
5133  ExprResult Cond =
5134  (isOpenMPWorksharingDirective(DKind) ||
5136  ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get())
5137  : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
5138  NumIterations.get());
5139  ExprResult CombCond;
5140  if (isOpenMPLoopBoundSharingDirective(DKind)) {
5141  CombCond =
5142  SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), CombUB.get());
5143  }
5144  // Loop increment (IV = IV + 1)
5145  SourceLocation IncLoc = AStmt->getLocStart();
5146  ExprResult Inc =
5147  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
5148  SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
5149  if (!Inc.isUsable())
5150  return 0;
5151  Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
5152  Inc = SemaRef.ActOnFinishFullExpr(Inc.get());
5153  if (!Inc.isUsable())
5154  return 0;
5155 
5156  // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
5157  // Used for directives with static scheduling.
5158  // In combined construct, add combined version that use CombLB and CombUB
5159  // base variables for the update
5160  ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
5162  isOpenMPDistributeDirective(DKind)) {
5163  // LB + ST
5164  NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
5165  if (!NextLB.isUsable())
5166  return 0;
5167  // LB = LB + ST
5168  NextLB =
5169  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
5170  NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get());
5171  if (!NextLB.isUsable())
5172  return 0;
5173  // UB + ST
5174  NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
5175  if (!NextUB.isUsable())
5176  return 0;
5177  // UB = UB + ST
5178  NextUB =
5179  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
5180  NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get());
5181  if (!NextUB.isUsable())
5182  return 0;
5183  if (isOpenMPLoopBoundSharingDirective(DKind)) {
5184  CombNextLB =
5185  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
5186  if (!NextLB.isUsable())
5187  return 0;
5188  // LB = LB + ST
5189  CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
5190  CombNextLB.get());
5191  CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get());
5192  if (!CombNextLB.isUsable())
5193  return 0;
5194  // UB + ST
5195  CombNextUB =
5196  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
5197  if (!CombNextUB.isUsable())
5198  return 0;
5199  // UB = UB + ST
5200  CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
5201  CombNextUB.get());
5202  CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get());
5203  if (!CombNextUB.isUsable())
5204  return 0;
5205  }
5206  }
5207 
5208  // Create increment expression for distribute loop when combined in a same
5209  // directive with for as IV = IV + ST; ensure upper bound expression based
5210  // on PrevUB instead of NumIterations - used to implement 'for' when found
5211  // in combination with 'distribute', like in 'distribute parallel for'
5212  SourceLocation DistIncLoc = AStmt->getLocStart();
5213  ExprResult DistCond, DistInc, PrevEUB;
5214  if (isOpenMPLoopBoundSharingDirective(DKind)) {
5215  DistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get());
5216  assert(DistCond.isUsable() && "distribute cond expr was not built");
5217 
5218  DistInc =
5219  SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
5220  assert(DistInc.isUsable() && "distribute inc expr was not built");
5221  DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
5222  DistInc.get());
5223  DistInc = SemaRef.ActOnFinishFullExpr(DistInc.get());
5224  assert(DistInc.isUsable() && "distribute inc expr was not built");
5225 
5226  // Build expression: UB = min(UB, prevUB) for #for in composite or combined
5227  // construct
5228  SourceLocation DistEUBLoc = AStmt->getLocStart();
5229  ExprResult IsUBGreater =
5230  SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get());
5231  ExprResult CondOp = SemaRef.ActOnConditionalOp(
5232  DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
5233  PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
5234  CondOp.get());
5235  PrevEUB = SemaRef.ActOnFinishFullExpr(PrevEUB.get());
5236  }
5237 
5238  // Build updates and final values of the loop counters.
5239  bool HasErrors = false;
5240  Built.Counters.resize(NestedLoopCount);
5241  Built.Inits.resize(NestedLoopCount);
5242  Built.Updates.resize(NestedLoopCount);
5243  Built.Finals.resize(NestedLoopCount);
5244  {
5245  ExprResult Div;
5246  // Go from inner nested loop to outer.
5247  for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) {
5248  LoopIterationSpace &IS = IterSpaces[Cnt];
5249  SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
5250  // Build: Iter = (IV / Div) % IS.NumIters
5251  // where Div is product of previous iterations' IS.NumIters.
5252  ExprResult Iter;
5253  if (Div.isUsable()) {
5254  Iter =
5255  SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, IV.get(), Div.get());
5256  } else {
5257  Iter = IV;
5258  assert((Cnt == (int)NestedLoopCount - 1) &&
5259  "unusable div expected on first iteration only");
5260  }
5261 
5262  if (Cnt != 0 && Iter.isUsable())
5263  Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.get(),
5264  IS.NumIterations);
5265  if (!Iter.isUsable()) {
5266  HasErrors = true;
5267  break;
5268  }
5269 
5270  // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
5271  auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
5272  DeclRefExpr *CounterVar = buildDeclRefExpr(
5273  SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
5274  /*RefersToCapture=*/true);
5275  ExprResult Init = buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
5276  IS.CounterInit, Captures);
5277  if (!Init.isUsable()) {
5278  HasErrors = true;
5279  break;
5280  }
5282  SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
5283  IS.CounterStep, IS.Subtract, &Captures);
5284  if (!Update.isUsable()) {
5285  HasErrors = true;
5286  break;
5287  }
5288 
5289  // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
5291  SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit,
5292  IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures);
5293  if (!Final.isUsable()) {
5294  HasErrors = true;
5295  break;
5296  }
5297 
5298  // Build Div for the next iteration: Div <- Div * IS.NumIters
5299  if (Cnt != 0) {
5300  if (Div.isUnset())
5301  Div = IS.NumIterations;
5302  else
5303  Div = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.get(),
5304  IS.NumIterations);
5305 
5306  // Add parentheses (for debugging purposes only).
5307  if (Div.isUsable())
5308  Div = tryBuildCapture(SemaRef, Div.get(), Captures);
5309  if (!Div.isUsable()) {
5310  HasErrors = true;
5311  break;
5312  }
5313  }
5314  if (!Update.isUsable() || !Final.isUsable()) {
5315  HasErrors = true;
5316  break;
5317  }
5318  // Save results
5319  Built.Counters[Cnt] = IS.CounterVar;
5320  Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
5321  Built.Inits[Cnt] = Init.get();
5322  Built.Updates[Cnt] = Update.get();
5323  Built.Finals[Cnt] = Final.get();
5324  }
5325  }
5326 
5327  if (HasErrors)
5328  return 0;
5329 
5330  // Save results
5331  Built.IterationVarRef = IV.get();
5332  Built.LastIteration = LastIteration.get();
5333  Built.NumIterations = NumIterations.get();
5334  Built.CalcLastIteration =
5335  SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get();
5336  Built.PreCond = PreCond.get();
5337  Built.PreInits = buildPreInits(C, Captures);
5338  Built.Cond = Cond.get();
5339  Built.Init = Init.get();
5340  Built.Inc = Inc.get();
5341  Built.LB = LB.get();
5342  Built.UB = UB.get();
5343  Built.IL = IL.get();
5344  Built.ST = ST.get();
5345  Built.EUB = EUB.get();
5346  Built.NLB = NextLB.get();
5347  Built.NUB = NextUB.get();
5348  Built.PrevLB = PrevLB.get();
5349  Built.PrevUB = PrevUB.get();
5350  Built.DistInc = DistInc.get();
5351  Built.PrevEUB = PrevEUB.get();
5352  Built.DistCombinedFields.LB = CombLB.get();
5353  Built.DistCombinedFields.UB = CombUB.get();
5354  Built.DistCombinedFields.EUB = CombEUB.get();
5355  Built.DistCombinedFields.Init = CombInit.get();
5356  Built.DistCombinedFields.Cond = CombCond.get();
5357  Built.DistCombinedFields.NLB = CombNextLB.get();
5358  Built.DistCombinedFields.NUB = CombNextUB.get();
5359 
5360  return NestedLoopCount;
5361 }
5362 
5364  auto CollapseClauses =
5365  OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
5366  if (CollapseClauses.begin() != CollapseClauses.end())
5367  return (*CollapseClauses.begin())->getNumForLoops();
5368  return nullptr;
5369 }
5370 
5372  auto OrderedClauses =
5373  OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
5374  if (OrderedClauses.begin() != OrderedClauses.end())
5375  return (*OrderedClauses.begin())->getNumForLoops();
5376  return nullptr;
5377 }
5378 
5380  const ArrayRef<OMPClause *> Clauses) {
5381  const OMPSafelenClause *Safelen = nullptr;
5382  const OMPSimdlenClause *Simdlen = nullptr;
5383 
5384  for (const OMPClause *Clause : Clauses) {
5385  if (Clause->getClauseKind() == OMPC_safelen)
5386  Safelen = cast<OMPSafelenClause>(Clause);
5387  else if (Clause->getClauseKind() == OMPC_simdlen)
5388  Simdlen = cast<OMPSimdlenClause>(Clause);
5389  if (Safelen && Simdlen)
5390  break;
5391  }
5392 
5393  if (Simdlen && Safelen) {
5394  llvm::APSInt SimdlenRes, SafelenRes;
5395  const Expr *SimdlenLength = Simdlen->getSimdlen();
5396  const Expr *SafelenLength = Safelen->getSafelen();
5397  if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
5398  SimdlenLength->isInstantiationDependent() ||
5399  SimdlenLength->containsUnexpandedParameterPack())
5400  return false;
5401  if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
5402  SafelenLength->isInstantiationDependent() ||
5403  SafelenLength->containsUnexpandedParameterPack())
5404  return false;
5405  SimdlenLength->EvaluateAsInt(SimdlenRes, S.Context);
5406  SafelenLength->EvaluateAsInt(SafelenRes, S.Context);
5407  // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
5408  // If both simdlen and safelen clauses are specified, the value of the
5409  // simdlen parameter must be less than or equal to the value of the safelen
5410  // parameter.
5411  if (SimdlenRes > SafelenRes) {
5412  S.Diag(SimdlenLength->getExprLoc(),
5413  diag::err_omp_wrong_simdlen_safelen_values)
5414  << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
5415  return true;
5416  }
5417  }
5418  return false;
5419 }
5420 
5421 StmtResult
5423  SourceLocation StartLoc, SourceLocation EndLoc,
5424  VarsWithInheritedDSAType &VarsWithImplicitDSA) {
5425  if (!AStmt)
5426  return StmtError();
5427 
5428  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5430  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5431  // define the nested loops number.
5432  unsigned NestedLoopCount = checkOpenMPLoop(
5433  OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
5434  AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
5435  if (NestedLoopCount == 0)
5436  return StmtError();
5437 
5438  assert((CurContext->isDependentContext() || B.builtAll()) &&
5439  "omp simd loop exprs were not built");
5440 
5441  if (!CurContext->isDependentContext()) {
5442  // Finalize the clauses that need pre-built expressions for CodeGen.
5443  for (OMPClause *C : Clauses) {
5444  if (auto *LC = dyn_cast<OMPLinearClause>(C))
5445  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5446  B.NumIterations, *this, CurScope,
5447  DSAStack))
5448  return StmtError();
5449  }
5450  }
5451 
5452  if (checkSimdlenSafelenSpecified(*this, Clauses))
5453  return StmtError();
5454 
5455  setFunctionHasBranchProtectedScope();
5456  return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5457  Clauses, AStmt, B);
5458 }
5459 
5460 StmtResult
5462  SourceLocation StartLoc, SourceLocation EndLoc,
5463  VarsWithInheritedDSAType &VarsWithImplicitDSA) {
5464  if (!AStmt)
5465  return StmtError();
5466 
5467  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5469  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5470  // define the nested loops number.
5471  unsigned NestedLoopCount = checkOpenMPLoop(
5472  OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
5473  AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
5474  if (NestedLoopCount == 0)
5475  return StmtError();
5476 
5477  assert((CurContext->isDependentContext() || B.builtAll()) &&
5478  "omp for loop exprs were not built");
5479 
5480  if (!CurContext->isDependentContext()) {
5481  // Finalize the clauses that need pre-built expressions for CodeGen.
5482  for (OMPClause *C : Clauses) {
5483  if (auto *LC = dyn_cast<OMPLinearClause>(C))
5484  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5485  B.NumIterations, *this, CurScope,
5486  DSAStack))
5487  return StmtError();
5488  }
5489  }
5490 
5491  setFunctionHasBranchProtectedScope();
5492  return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5493  Clauses, AStmt, B, DSAStack->isCancelRegion());
5494 }
5495 
5497  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5498  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
5499  if (!AStmt)
5500  return StmtError();
5501 
5502  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5504  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5505  // define the nested loops number.
5506  unsigned NestedLoopCount =
5507  checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
5508  getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
5509  VarsWithImplicitDSA, B);
5510  if (NestedLoopCount == 0)
5511  return StmtError();
5512 
5513  assert((CurContext->isDependentContext() || B.builtAll()) &&
5514  "omp for simd loop exprs were not built");
5515 
5516  if (!CurContext->isDependentContext()) {
5517  // Finalize the clauses that need pre-built expressions for CodeGen.
5518  for (OMPClause *C : Clauses) {
5519  if (auto *LC = dyn_cast<OMPLinearClause>(C))
5520  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5521  B.NumIterations, *this, CurScope,
5522  DSAStack))
5523  return StmtError();
5524  }
5525  }
5526 
5527  if (checkSimdlenSafelenSpecified(*this, Clauses))
5528  return StmtError();
5529 
5530  setFunctionHasBranchProtectedScope();
5531  return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5532  Clauses, AStmt, B);
5533 }
5534 
5536  Stmt *AStmt,
5537  SourceLocation StartLoc,
5538  SourceLocation EndLoc) {
5539  if (!AStmt)
5540  return StmtError();
5541 
5542  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5543  auto BaseStmt = AStmt;
5544  while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
5545  BaseStmt = CS->getCapturedStmt();
5546  if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
5547  auto S = C->children();
5548  if (S.begin() == S.end())
5549  return StmtError();
5550  // All associated statements must be '#pragma omp section' except for
5551  // the first one.
5552  for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
5553  if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
5554  if (SectionStmt)
5555  Diag(SectionStmt->getLocStart(),
5556  diag::err_omp_sections_substmt_not_section);
5557  return StmtError();
5558  }
5559  cast<OMPSectionDirective>(SectionStmt)
5560  ->setHasCancel(DSAStack->isCancelRegion());
5561  }
5562  } else {
5563  Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt);
5564  return StmtError();
5565  }
5566 
5567  setFunctionHasBranchProtectedScope();
5568 
5569  return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
5570  DSAStack->isCancelRegion());
5571 }
5572 
5574  SourceLocation StartLoc,
5575  SourceLocation EndLoc) {
5576  if (!AStmt)
5577  return StmtError();
5578 
5579  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5580 
5581  setFunctionHasBranchProtectedScope();
5582  DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
5583 
5584  return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
5585  DSAStack->isCancelRegion());
5586 }
5587 
5589  Stmt *AStmt,
5590  SourceLocation StartLoc,
5591  SourceLocation EndLoc) {
5592  if (!AStmt)
5593  return StmtError();
5594 
5595  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5596 
5597  setFunctionHasBranchProtectedScope();
5598 
5599  // OpenMP [2.7.3, single Construct, Restrictions]
5600  // The copyprivate clause must not be used with the nowait clause.
5601  const OMPClause *Nowait = nullptr;
5602  const OMPClause *Copyprivate = nullptr;
5603  for (const OMPClause *Clause : Clauses) {
5604  if (Clause->getClauseKind() == OMPC_nowait)
5605  Nowait = Clause;
5606  else if (Clause->getClauseKind() == OMPC_copyprivate)
5607  Copyprivate = Clause;
5608  if (Copyprivate && Nowait) {
5609  Diag(Copyprivate->getLocStart(),
5610  diag::err_omp_single_copyprivate_with_nowait);
5611  Diag(Nowait->getLocStart(), diag::note_omp_nowait_clause_here);
5612  return StmtError();
5613  }
5614  }
5615 
5616  return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
5617 }
5618 
5620  SourceLocation StartLoc,
5621  SourceLocation EndLoc) {
5622  if (!AStmt)
5623  return StmtError();
5624 
5625  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5626 
5627  setFunctionHasBranchProtectedScope();
5628 
5629  return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
5630 }
5631 
5633  const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
5634  Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
5635  if (!AStmt)
5636  return StmtError();
5637 
5638  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5639 
5640  bool ErrorFound = false;
5641  llvm::APSInt Hint;
5642  SourceLocation HintLoc;
5643  bool DependentHint = false;
5644  for (const OMPClause *C : Clauses) {
5645  if (C->getClauseKind() == OMPC_hint) {
5646  if (!DirName.getName()) {
5647  Diag(C->getLocStart(), diag::err_omp_hint_clause_no_name);
5648  ErrorFound = true;
5649  }
5650  Expr *E = cast<OMPHintClause>(C)->getHint();
5651  if (E->isTypeDependent() || E->isValueDependent() ||
5652  E->isInstantiationDependent()) {
5653  DependentHint = true;
5654  } else {
5655  Hint = E->EvaluateKnownConstInt(Context);
5656  HintLoc = C->getLocStart();
5657  }
5658  }
5659  }
5660  if (ErrorFound)
5661  return StmtError();
5662  const auto Pair = DSAStack->getCriticalWithHint(DirName);
5663  if (Pair.first && DirName.getName() && !DependentHint) {
5664  if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
5665  Diag(StartLoc, diag::err_omp_critical_with_hint);
5666  if (HintLoc.isValid())
5667  Diag(HintLoc, diag::note_omp_critical_hint_here)
5668  << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false);
5669  else
5670  Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
5671  if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
5672  Diag(C->getLocStart(), diag::note_omp_critical_hint_here)
5673  << 1
5674  << C->getHint()->EvaluateKnownConstInt(Context).toString(
5675  /*Radix=*/10, /*Signed=*/false);
5676  } else {
5677  Diag(Pair.first->getLocStart(), diag::note_omp_critical_no_hint) << 1;
5678  }
5679  }
5680  }
5681 
5682  setFunctionHasBranchProtectedScope();
5683 
5684  auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
5685  Clauses, AStmt);
5686  if (!Pair.first && DirName.getName() && !DependentHint)
5687  DSAStack->addCriticalWithHint(Dir, Hint);
5688  return Dir;
5689 }
5690 
5692  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5693  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
5694  if (!AStmt)
5695  return StmtError();
5696 
5697  auto *CS = cast<CapturedStmt>(AStmt);
5698  // 1.2.2 OpenMP Language Terminology
5699  // Structured block - An executable statement with a single entry at the
5700  // top and a single exit at the bottom.
5701  // The point of exit cannot be a branch out of the structured block.
5702  // longjmp() and throw() must not violate the entry/exit criteria.
5703  CS->getCapturedDecl()->setNothrow();
5704 
5706  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5707  // define the nested loops number.
5708  unsigned NestedLoopCount =
5709  checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
5710  getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
5711  VarsWithImplicitDSA, B);
5712  if (NestedLoopCount == 0)
5713  return StmtError();
5714 
5715  assert((CurContext->isDependentContext() || B.builtAll()) &&
5716  "omp parallel for loop exprs were not built");
5717 
5718  if (!CurContext->isDependentContext()) {
5719  // Finalize the clauses that need pre-built expressions for CodeGen.
5720  for (OMPClause *C : Clauses) {
5721  if (auto *LC = dyn_cast<OMPLinearClause>(C))
5722  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5723  B.NumIterations, *this, CurScope,
5724  DSAStack))
5725  return StmtError();
5726  }
5727  }
5728 
5729  setFunctionHasBranchProtectedScope();
5730  return OMPParallelForDirective::Create(Context, StartLoc, EndLoc,
5731  NestedLoopCount, Clauses, AStmt, B,
5732  DSAStack->isCancelRegion());
5733 }
5734 
5736  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5737  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
5738  if (!AStmt)
5739  return StmtError();
5740 
5741  auto *CS = cast<CapturedStmt>(AStmt);
5742  // 1.2.2 OpenMP Language Terminology
5743  // Structured block - An executable statement with a single entry at the
5744  // top and a single exit at the bottom.
5745  // The point of exit cannot be a branch out of the structured block.
5746  // longjmp() and throw() must not violate the entry/exit criteria.
5747  CS->getCapturedDecl()->setNothrow();
5748 
5750  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5751  // define the nested loops number.
5752  unsigned NestedLoopCount =
5753  checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
5754  getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
5755  VarsWithImplicitDSA, B);
5756  if (NestedLoopCount == 0)
5757  return StmtError();
5758 
5759  if (!CurContext->isDependentContext()) {
5760  // Finalize the clauses that need pre-built expressions for CodeGen.
5761  for (OMPClause *C : Clauses) {
5762  if (auto *LC = dyn_cast<OMPLinearClause>(C))
5763  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5764  B.NumIterations, *this, CurScope,
5765  DSAStack))
5766  return StmtError();
5767  }
5768  }
5769 
5770  if (checkSimdlenSafelenSpecified(*this, Clauses))
5771  return StmtError();
5772 
5773  setFunctionHasBranchProtectedScope();
5775  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
5776 }
5777 
5778 StmtResult
5780  Stmt *AStmt, SourceLocation StartLoc,
5781  SourceLocation EndLoc) {
5782  if (!AStmt)
5783  return StmtError();
5784 
5785  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5786  auto BaseStmt = AStmt;
5787  while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
5788  BaseStmt = CS->getCapturedStmt();
5789  if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
5790  auto S = C->children();
5791  if (S.begin() == S.end())
5792  return StmtError();
5793  // All associated statements must be '#pragma omp section' except for
5794  // the first one.
5795  for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
5796  if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
5797  if (SectionStmt)
5798  Diag(SectionStmt->getLocStart(),
5799  diag::err_omp_parallel_sections_substmt_not_section);
5800  return StmtError();
5801  }
5802  cast<OMPSectionDirective>(SectionStmt)
5803  ->setHasCancel(DSAStack->isCancelRegion());
5804  }
5805  } else {
5806  Diag(AStmt->getLocStart(),
5807  diag::err_omp_parallel_sections_not_compound_stmt);
5808  return StmtError();
5809  }
5810 
5811  setFunctionHasBranchProtectedScope();
5812 
5814  Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion());
5815 }
5816 
5818  Stmt *AStmt, SourceLocation StartLoc,
5819  SourceLocation EndLoc) {
5820  if (!AStmt)
5821  return StmtError();
5822 
5823  auto *CS = cast<CapturedStmt>(AStmt);
5824  // 1.2.2 OpenMP Language Terminology
5825  // Structured block - An executable statement with a single entry at the
5826  // top and a single exit at the bottom.
5827  // The point of exit cannot be a branch out of the structured block.
5828  // longjmp() and throw() must not violate the entry/exit criteria.
5829  CS->getCapturedDecl()->setNothrow();
5830 
5831  setFunctionHasBranchProtectedScope();
5832 
5833  return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
5834  DSAStack->isCancelRegion());
5835 }
5836 
5838  SourceLocation EndLoc) {
5839  return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
5840 }
5841 
5843  SourceLocation EndLoc) {
5844  return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
5845 }
5846 
5848  SourceLocation EndLoc) {
5849  return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
5850 }
5851 
5853  Stmt *AStmt,
5854  SourceLocation StartLoc,
5855  SourceLocation EndLoc) {
5856  if (!AStmt)
5857  return StmtError();
5858 
5859  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5860 
5861  setFunctionHasBranchProtectedScope();
5862 
5863  return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
5864  AStmt,
5865  DSAStack->getTaskgroupReductionRef());
5866 }
5867 
5869  SourceLocation StartLoc,
5870  SourceLocation EndLoc) {
5871  assert(Clauses.size() <= 1 && "Extra clauses in flush directive");
5872  return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
5873 }
5874 
5876  Stmt *AStmt,
5877  SourceLocation StartLoc,
5878  SourceLocation EndLoc) {
5879  const OMPClause *DependFound = nullptr;
5880  const OMPClause *DependSourceClause = nullptr;
5881  const OMPClause *DependSinkClause = nullptr;
5882  bool ErrorFound = false;
5883  const OMPThreadsClause *TC = nullptr;
5884  const OMPSIMDClause *SC = nullptr;
5885  for (const OMPClause *C : Clauses) {
5886  if (auto *DC = dyn_cast<OMPDependClause>(C)) {
5887  DependFound = C;
5888  if (DC->getDependencyKind() == OMPC_DEPEND_source) {
5889  if (DependSourceClause) {
5890  Diag(C->getLocStart(), diag::err_omp_more_one_clause)
5891  << getOpenMPDirectiveName(OMPD_ordered)
5892  << getOpenMPClauseName(OMPC_depend) << 2;
5893  ErrorFound = true;
5894  } else {
5895  DependSourceClause = C;
5896  }
5897  if (DependSinkClause) {
5898  Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed)
5899  << 0;
5900  ErrorFound = true;
5901  }
5902  } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
5903  if (DependSourceClause) {
5904  Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed)
5905  << 1;
5906  ErrorFound = true;
5907  }
5908  DependSinkClause = C;
5909  }
5910  } else if (C->getClauseKind() == OMPC_threads) {
5911  TC = cast<OMPThreadsClause>(C);
5912  } else if (C->getClauseKind() == OMPC_simd) {
5913  SC = cast<OMPSIMDClause>(C);
5914  }
5915  }
5916  if (!ErrorFound && !SC &&
5917  isOpenMPSimdDirective(DSAStack->getParentDirective())) {
5918  // OpenMP [2.8.1,simd Construct, Restrictions]
5919  // An ordered construct with the simd clause is the only OpenMP construct
5920  // that can appear in the simd region.
5921  Diag(StartLoc, diag::err_omp_prohibited_region_simd);
5922  ErrorFound = true;
5923  } else if (DependFound && (TC || SC)) {
5924  Diag(DependFound->getLocStart(), diag::err_omp_depend_clause_thread_simd)
5925  << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
5926  ErrorFound = true;
5927  } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) {
5928  Diag(DependFound->getLocStart(),
5929  diag::err_omp_ordered_directive_without_param);
5930  ErrorFound = true;
5931  } else if (TC || Clauses.empty()) {
5932  if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) {
5933  SourceLocation ErrLoc = TC ? TC->getLocStart() : StartLoc;
5934  Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
5935  << (TC != nullptr);
5936  Diag(Param->getLocStart(), diag::note_omp_ordered_param);
5937  ErrorFound = true;
5938  }
5939  }
5940  if ((!AStmt && !DependFound) || ErrorFound)
5941  return StmtError();
5942 
5943  if (AStmt) {
5944  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5945 
5946  setFunctionHasBranchProtectedScope();
5947  }
5948 
5949  return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
5950 }
5951 
5952 namespace {
5953 /// Helper class for checking expression in 'omp atomic [update]'
5954 /// construct.
5955 class OpenMPAtomicUpdateChecker {
5956  /// Error results for atomic update expressions.
5957  enum ExprAnalysisErrorCode {
5958  /// A statement is not an expression statement.
5959  NotAnExpression,
5960  /// Expression is not builtin binary or unary operation.
5961  NotABinaryOrUnaryExpression,
5962  /// Unary operation is not post-/pre- increment/decrement operation.
5963  NotAnUnaryIncDecExpression,
5964  /// An expression is not of scalar type.
5965  NotAScalarType,
5966  /// A binary operation is not an assignment operation.
5967  NotAnAssignmentOp,
5968  /// RHS part of the binary operation is not a binary expression.
5969  NotABinaryExpression,
5970  /// RHS part is not additive/multiplicative/shift/biwise binary
5971  /// expression.
5972  NotABinaryOperator,
5973  /// RHS binary operation does not have reference to the updated LHS
5974  /// part.
5975  NotAnUpdateExpression,
5976  /// No errors is found.
5977  NoError
5978  };
5979  /// Reference to Sema.
5980  Sema &SemaRef;
5981  /// A location for note diagnostics (when error is found).
5982  SourceLocation NoteLoc;
5983  /// 'x' lvalue part of the source atomic expression.
5984  Expr *X;
5985  /// 'expr' rvalue part of the source atomic expression.
5986  Expr *E;
5987  /// Helper expression of the form
5988  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
5989  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
5990  Expr *UpdateExpr;
5991  /// Is 'x' a LHS in a RHS part of full update expression. It is
5992  /// important for non-associative operations.
5993  bool IsXLHSInRHSPart;
5994  BinaryOperatorKind Op;
5995  SourceLocation OpLoc;
5996  /// true if the source expression is a postfix unary operation, false
5997  /// if it is a prefix unary operation.
5998  bool IsPostfixUpdate;
5999 
6000 public:
6001  OpenMPAtomicUpdateChecker(Sema &SemaRef)
6002  : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
6003  IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
6004  /// Check specified statement that it is suitable for 'atomic update'
6005  /// constructs and extract 'x', 'expr' and Operation from the original
6006  /// expression. If DiagId and NoteId == 0, then only check is performed
6007  /// without error notification.
6008  /// \param DiagId Diagnostic which should be emitted if error is found.
6009  /// \param NoteId Diagnostic note for the main error message.
6010  /// \return true if statement is not an update expression, false otherwise.
6011  bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
6012  /// Return the 'x' lvalue part of the source atomic expression.
6013  Expr *getX() const { return X; }
6014  /// Return the 'expr' rvalue part of the source atomic expression.
6015  Expr *getExpr() const { return E; }
6016  /// Return the update expression used in calculation of the updated
6017  /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
6018  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
6019  Expr *getUpdateExpr() const { return UpdateExpr; }
6020  /// Return true if 'x' is LHS in RHS part of full update expression,
6021  /// false otherwise.
6022  bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
6023 
6024  /// true if the source expression is a postfix unary operation, false
6025  /// if it is a prefix unary operation.
6026  bool isPostfixUpdate() const { return IsPostfixUpdate; }
6027 
6028 private:
6029  bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
6030  unsigned NoteId = 0);
6031 };
6032 } // namespace
6033 
6034 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
6035  BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
6036  ExprAnalysisErrorCode ErrorFound = NoError;
6037  SourceLocation ErrorLoc, NoteLoc;
6038  SourceRange ErrorRange, NoteRange;
6039  // Allowed constructs are:
6040  // x = x binop expr;
6041  // x = expr binop x;
6042  if (AtomicBinOp->getOpcode() == BO_Assign) {
6043  X = AtomicBinOp->getLHS();
6044  if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
6045  AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
6046  if (AtomicInnerBinOp->isMultiplicativeOp() ||
6047  AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
6048  AtomicInnerBinOp->isBitwiseOp()) {
6049  Op = AtomicInnerBinOp->getOpcode();
6050  OpLoc = AtomicInnerBinOp->getOperatorLoc();
6051  Expr *LHS = AtomicInnerBinOp->getLHS();
6052  Expr *RHS = AtomicInnerBinOp->getRHS();
6053  llvm::FoldingSetNodeID XId, LHSId, RHSId;
6054  X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
6055  /*Canonical=*/true);
6056  LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
6057  /*Canonical=*/true);
6058  RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
6059  /*Canonical=*/true);
6060  if (XId == LHSId) {
6061  E = RHS;
6062  IsXLHSInRHSPart = true;
6063  } else if (XId == RHSId) {
6064  E = LHS;
6065  IsXLHSInRHSPart = false;
6066  } else {
6067  ErrorLoc = AtomicInnerBinOp->getExprLoc();
6068  ErrorRange = AtomicInnerBinOp->getSourceRange();
6069  NoteLoc = X->getExprLoc();
6070  NoteRange = X->getSourceRange();
6071  ErrorFound = NotAnUpdateExpression;
6072  }
6073  } else {
6074  ErrorLoc = AtomicInnerBinOp->getExprLoc();
6075  ErrorRange = AtomicInnerBinOp->getSourceRange();
6076  NoteLoc = AtomicInnerBinOp->getOperatorLoc();
6077  NoteRange = SourceRange(NoteLoc, NoteLoc);
6078  ErrorFound = NotABinaryOperator;
6079  }
6080  } else {
6081  NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
6082  NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
6083  ErrorFound = NotABinaryExpression;
6084  }
6085  } else {
6086  ErrorLoc = AtomicBinOp->getExprLoc();
6087  ErrorRange = AtomicBinOp->getSourceRange();
6088  NoteLoc = AtomicBinOp->getOperatorLoc();
6089  NoteRange = SourceRange(NoteLoc, NoteLoc);
6090  ErrorFound = NotAnAssignmentOp;
6091  }
6092  if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
6093  SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
6094  SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
6095  return true;
6096  }
6097  if (SemaRef.CurContext->isDependentContext())
6098  E = X = UpdateExpr = nullptr;
6099  return ErrorFound != NoError;
6100 }
6101 
6102 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
6103  unsigned NoteId) {
6104  ExprAnalysisErrorCode ErrorFound = NoError;
6105  SourceLocation ErrorLoc, NoteLoc;
6106  SourceRange ErrorRange, NoteRange;
6107  // Allowed constructs are:
6108  // x++;
6109  // x--;
6110  // ++x;
6111  // --x;
6112  // x binop= expr;
6113  // x = x binop expr;
6114  // x = expr binop x;
6115  if (auto *AtomicBody = dyn_cast<Expr>(S)) {
6116  AtomicBody = AtomicBody->IgnoreParenImpCasts();
6117  if (AtomicBody->getType()->isScalarType() ||
6118  AtomicBody->isInstantiationDependent()) {
6119  if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
6120  AtomicBody->IgnoreParenImpCasts())) {
6121  // Check for Compound Assignment Operation
6123  AtomicCompAssignOp->getOpcode());
6124  OpLoc = AtomicCompAssignOp->getOperatorLoc();
6125  E = AtomicCompAssignOp->getRHS();
6126  X = AtomicCompAssignOp->getLHS()->IgnoreParens();
6127  IsXLHSInRHSPart = true;
6128  } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
6129  AtomicBody->IgnoreParenImpCasts())) {
6130  // Check for Binary Operation
6131  if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
6132  return true;
6133  } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
6134  AtomicBody->IgnoreParenImpCasts())) {
6135  // Check for Unary Operation
6136  if (AtomicUnaryOp->isIncrementDecrementOp()) {
6137  IsPostfixUpdate = AtomicUnaryOp->isPostfix();
6138  Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
6139  OpLoc = AtomicUnaryOp->getOperatorLoc();
6140  X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
6141  E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
6142  IsXLHSInRHSPart = true;
6143  } else {
6144  ErrorFound = NotAnUnaryIncDecExpression;
6145  ErrorLoc = AtomicUnaryOp->getExprLoc();
6146  ErrorRange = AtomicUnaryOp->getSourceRange();
6147  NoteLoc = AtomicUnaryOp->getOperatorLoc();
6148  NoteRange = SourceRange(NoteLoc, NoteLoc);
6149  }
6150  } else if (!AtomicBody->isInstantiationDependent()) {
6151  ErrorFound = NotABinaryOrUnaryExpression;
6152  NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
6153  NoteRange = ErrorRange = AtomicBody->getSourceRange();
6154  }
6155  } else {
6156  ErrorFound = NotAScalarType;
6157  NoteLoc = ErrorLoc = AtomicBody->getLocStart();
6158  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
6159  }
6160  } else {
6161  ErrorFound = NotAnExpression;
6162  NoteLoc = ErrorLoc = S->getLocStart();
6163  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
6164  }
6165  if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
6166  SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
6167  SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
6168  return true;
6169  }
6170  if (SemaRef.CurContext->isDependentContext())
6171  E = X = UpdateExpr = nullptr;
6172  if (ErrorFound == NoError && E && X) {
6173  // Build an update expression of form 'OpaqueValueExpr(x) binop
6174  // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
6175  // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
6176  auto *OVEX = new (SemaRef.getASTContext())
6177  OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue);
6178  auto *OVEExpr = new (SemaRef.getASTContext())
6180  ExprResult Update =
6181  SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
6182  IsXLHSInRHSPart ? OVEExpr : OVEX);
6183  if (Update.isInvalid())
6184  return true;
6185  Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
6187  if (Update.isInvalid())
6188  return true;
6189  UpdateExpr = Update.get();
6190  }
6191  return ErrorFound != NoError;
6192 }
6193 
6195  Stmt *AStmt,
6196  SourceLocation StartLoc,
6197  SourceLocation EndLoc) {
6198  if (!AStmt)
6199  return StmtError();
6200 
6201  auto *CS = cast<CapturedStmt>(AStmt);
6202  // 1.2.2 OpenMP Language Terminology
6203  // Structured block - An executable statement with a single entry at the
6204  // top and a single exit at the bottom.
6205  // The point of exit cannot be a branch out of the structured block.
6206  // longjmp() and throw() must not violate the entry/exit criteria.
6207  OpenMPClauseKind AtomicKind = OMPC_unknown;
6208  SourceLocation AtomicKindLoc;
6209  for (const OMPClause *C : Clauses) {
6210  if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
6211  C->getClauseKind() == OMPC_update ||
6212  C->getClauseKind() == OMPC_capture) {
6213  if (AtomicKind != OMPC_unknown) {
6214  Diag(C->getLocStart(), diag::err_omp_atomic_several_clauses)
6215  << SourceRange(C->getLocStart(), C->getLocEnd());
6216  Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause)
6217  << getOpenMPClauseName(AtomicKind);
6218  } else {
6219  AtomicKind = C->getClauseKind();
6220  AtomicKindLoc = C->getLocStart();
6221  }
6222  }
6223  }
6224 
6225  Stmt *Body = CS->getCapturedStmt();
6226  if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
6227  Body = EWC->getSubExpr();
6228 
6229  Expr *X = nullptr;
6230  Expr *V = nullptr;
6231  Expr *E = nullptr;
6232  Expr *UE = nullptr;
6233  bool IsXLHSInRHSPart = false;
6234  bool IsPostfixUpdate = false;
6235  // OpenMP [2.12.6, atomic Construct]
6236  // In the next expressions:
6237  // * x and v (as applicable) are both l-value expressions with scalar type.
6238  // * During the execution of an atomic region, multiple syntactic
6239  // occurrences of x must designate the same storage location.
6240  // * Neither of v and expr (as applicable) may access the storage location
6241  // designated by x.
6242  // * Neither of x and expr (as applicable) may access the storage location
6243  // designated by v.
6244  // * expr is an expression with scalar type.
6245  // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
6246  // * binop, binop=, ++, and -- are not overloaded operators.
6247  // * The expression x binop expr must be numerically equivalent to x binop
6248  // (expr). This requirement is satisfied if the operators in expr have
6249  // precedence greater than binop, or by using parentheses around expr or
6250  // subexpressions of expr.
6251  // * The expression expr binop x must be numerically equivalent to (expr)
6252  // binop x. This requirement is satisfied if the operators in expr have
6253  // precedence equal to or greater than binop, or by using parentheses around
6254  // expr or subexpressions of expr.
6255  // * For forms that allow multiple occurrences of x, the number of times
6256  // that x is evaluated is unspecified.
6257  if (AtomicKind == OMPC_read) {
6258  enum {
6259  NotAnExpression,
6260  NotAnAssignmentOp,
6261  NotAScalarType,
6262  NotAnLValue,
6263  NoError
6264  } ErrorFound = NoError;
6265  SourceLocation ErrorLoc, NoteLoc;
6266  SourceRange ErrorRange, NoteRange;
6267  // If clause is read:
6268  // v = x;
6269  if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
6270  const auto *AtomicBinOp =
6271  dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
6272  if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
6273  X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
6274  V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
6275  if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
6276  (V->isInstantiationDependent() || V->getType()->isScalarType())) {
6277  if (!X->isLValue() || !V->isLValue()) {
6278  const Expr *NotLValueExpr = X->isLValue() ? V : X;
6279  ErrorFound = NotAnLValue;
6280  ErrorLoc = AtomicBinOp->getExprLoc();
6281  ErrorRange = AtomicBinOp->getSourceRange();
6282  NoteLoc = NotLValueExpr->getExprLoc();
6283  NoteRange = NotLValueExpr->getSourceRange();
6284  }
6285  } else if (!X->isInstantiationDependent() ||
6286  !V->isInstantiationDependent()) {
6287  const Expr *NotScalarExpr =
6289  ? V
6290  : X;
6291  ErrorFound = NotAScalarType;
6292  ErrorLoc = AtomicBinOp->getExprLoc();
6293  ErrorRange = AtomicBinOp->getSourceRange();
6294  NoteLoc = NotScalarExpr->getExprLoc();
6295  NoteRange = NotScalarExpr->getSourceRange();
6296  }
6297  } else if (!AtomicBody->isInstantiationDependent()) {
6298  ErrorFound = NotAnAssignmentOp;
6299  ErrorLoc = AtomicBody->getExprLoc();
6300  ErrorRange = AtomicBody->getSourceRange();
6301  NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
6302  : AtomicBody->getExprLoc();
6303  NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
6304  : AtomicBody->getSourceRange();
6305  }
6306  } else {
6307  ErrorFound = NotAnExpression;
6308  NoteLoc = ErrorLoc = Body->getLocStart();
6309  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
6310  }
6311  if (ErrorFound != NoError) {
6312  Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
6313  << ErrorRange;
6314  Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
6315  << NoteRange;
6316  return StmtError();
6317  }
6318  if (CurContext->isDependentContext())
6319  V = X = nullptr;
6320  } else if (AtomicKind == OMPC_write) {
6321  enum {
6322  NotAnExpression,
6323  NotAnAssignmentOp,
6324  NotAScalarType,
6325  NotAnLValue,
6326  NoError
6327  } ErrorFound = NoError;
6328  SourceLocation ErrorLoc, NoteLoc;
6329  SourceRange ErrorRange, NoteRange;
6330  // If clause is write:
6331  // x = expr;
6332  if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
6333  const auto *AtomicBinOp =
6334  dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
6335  if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
6336  X = AtomicBinOp->getLHS();
6337  E = AtomicBinOp->getRHS();
6338  if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
6339  (E->isInstantiationDependent() || E->getType()->isScalarType())) {
6340  if (!X->isLValue()) {
6341  ErrorFound = NotAnLValue;
6342  ErrorLoc = AtomicBinOp->getExprLoc();
6343  ErrorRange = AtomicBinOp->getSourceRange();
6344  NoteLoc = X->getExprLoc();
6345  NoteRange = X->getSourceRange();
6346  }
6347  } else if (!X->isInstantiationDependent() ||
6348  !E->isInstantiationDependent()) {
6349  const Expr *NotScalarExpr =
6351  ? E
6352  : X;
6353  ErrorFound = NotAScalarType;
6354  ErrorLoc = AtomicBinOp->getExprLoc();
6355  ErrorRange = AtomicBinOp->getSourceRange();
6356  NoteLoc = NotScalarExpr->getExprLoc();
6357  NoteRange = NotScalarExpr->getSourceRange();
6358  }
6359  } else if (!AtomicBody->isInstantiationDependent()) {
6360  ErrorFound = NotAnAssignmentOp;
6361  ErrorLoc = AtomicBody->getExprLoc();
6362  ErrorRange = AtomicBody->getSourceRange();
6363  NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
6364  : AtomicBody->getExprLoc();
6365  NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
6366  : AtomicBody->getSourceRange();
6367  }
6368  } else {
6369  ErrorFound = NotAnExpression;
6370  NoteLoc = ErrorLoc = Body->getLocStart();
6371  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
6372  }
6373  if (ErrorFound != NoError) {
6374  Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
6375  << ErrorRange;
6376  Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
6377  << NoteRange;
6378  return StmtError();
6379  }
6380  if (CurContext->isDependentContext())
6381  E = X = nullptr;
6382  } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
6383  // If clause is update:
6384  // x++;
6385  // x--;
6386  // ++x;
6387  // --x;
6388  // x binop= expr;
6389  // x = x binop expr;
6390  // x = expr binop x;
6391  OpenMPAtomicUpdateChecker Checker(*this);
6392  if (Checker.checkStatement(
6393  Body, (AtomicKind == OMPC_update)
6394  ? diag::err_omp_atomic_update_not_expression_statement
6395  : diag::err_omp_atomic_not_expression_statement,
6396  diag::note_omp_atomic_update))
6397  return StmtError();
6398  if (!CurContext->isDependentContext()) {
6399  E = Checker.getExpr();
6400  X = Checker.getX();
6401  UE = Checker.getUpdateExpr();
6402  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6403  }
6404  } else if (AtomicKind == OMPC_capture) {
6405  enum {
6406  NotAnAssignmentOp,
6407  NotACompoundStatement,
6408  NotTwoSubstatements,
6409  NotASpecificExpression,
6410  NoError
6411  } ErrorFound = NoError;
6412  SourceLocation ErrorLoc, NoteLoc;
6413  SourceRange ErrorRange, NoteRange;
6414  if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
6415  // If clause is a capture:
6416  // v = x++;
6417  // v = x--;
6418  // v = ++x;
6419  // v = --x;
6420  // v = x binop= expr;
6421  // v = x = x binop expr;
6422  // v = x = expr binop x;
6423  const auto *AtomicBinOp =
6424  dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
6425  if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
6426  V = AtomicBinOp->getLHS();
6427  Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
6428  OpenMPAtomicUpdateChecker Checker(*this);
6429  if (Checker.checkStatement(
6430  Body, diag::err_omp_atomic_capture_not_expression_statement,
6431  diag::note_omp_atomic_update))
6432  return StmtError();
6433  E = Checker.getExpr();
6434  X = Checker.getX();
6435  UE = Checker.getUpdateExpr();
6436  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6437  IsPostfixUpdate = Checker.isPostfixUpdate();
6438  } else if (!AtomicBody->isInstantiationDependent()) {
6439  ErrorLoc = AtomicBody->getExprLoc();
6440  ErrorRange = AtomicBody->getSourceRange();
6441  NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
6442  : AtomicBody->getExprLoc();
6443  NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
6444  : AtomicBody->getSourceRange();
6445  ErrorFound = NotAnAssignmentOp;
6446  }
6447  if (ErrorFound != NoError) {
6448  Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
6449  << ErrorRange;
6450  Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
6451  return StmtError();
6452  }
6453  if (CurContext->isDependentContext())
6454  UE = V = E = X = nullptr;
6455  } else {
6456  // If clause is a capture:
6457  // { v = x; x = expr; }
6458  // { v = x; x++; }
6459  // { v = x; x--; }
6460  // { v = x; ++x; }
6461  // { v = x; --x; }
6462  // { v = x; x binop= expr; }
6463  // { v = x; x = x binop expr; }
6464  // { v = x; x = expr binop x; }
6465  // { x++; v = x; }
6466  // { x--; v = x; }
6467  // { ++x; v = x; }
6468  // { --x; v = x; }
6469  // { x binop= expr; v = x; }
6470  // { x = x binop expr; v = x; }
6471  // { x = expr binop x; v = x; }
6472  if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
6473  // Check that this is { expr1; expr2; }
6474  if (CS->size() == 2) {
6475  Stmt *First = CS->body_front();
6476  Stmt *Second = CS->body_back();
6477  if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
6478  First = EWC->getSubExpr()->IgnoreParenImpCasts();
6479  if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
6480  Second = EWC->getSubExpr()->IgnoreParenImpCasts();
6481  // Need to find what subexpression is 'v' and what is 'x'.
6482  OpenMPAtomicUpdateChecker Checker(*this);
6483  bool IsUpdateExprFound = !Checker.checkStatement(Second);
6484  BinaryOperator *BinOp = nullptr;
6485  if (IsUpdateExprFound) {
6486  BinOp = dyn_cast<BinaryOperator>(First);
6487  IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
6488  }
6489  if (IsUpdateExprFound && !CurContext->isDependentContext()) {
6490  // { v = x; x++; }
6491  // { v = x; x--; }
6492  // { v = x; ++x; }
6493  // { v = x; --x; }
6494  // { v = x; x binop= expr; }
6495  // { v = x; x = x binop expr; }
6496  // { v = x; x = expr binop x; }
6497  // Check that the first expression has form v = x.
6498  Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
6499  llvm::FoldingSetNodeID XId, PossibleXId;
6500  Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
6501  PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
6502  IsUpdateExprFound = XId == PossibleXId;
6503  if (IsUpdateExprFound) {
6504  V = BinOp->getLHS();
6505  X = Checker.getX();
6506  E = Checker.getExpr();
6507  UE = Checker.getUpdateExpr();
6508  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6509  IsPostfixUpdate = true;
6510  }
6511  }
6512  if (!IsUpdateExprFound) {
6513  IsUpdateExprFound = !Checker.checkStatement(First);
6514  BinOp = nullptr;
6515  if (IsUpdateExprFound) {
6516  BinOp = dyn_cast<BinaryOperator>(Second);
6517  IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
6518  }
6519  if (IsUpdateExprFound && !CurContext->isDependentContext()) {
6520  // { x++; v = x; }
6521  // { x--; v = x; }
6522  // { ++x; v = x; }
6523  // { --x; v = x; }
6524  // { x binop= expr; v = x; }
6525  // { x = x binop expr; v = x; }
6526  // { x = expr binop x; v = x; }
6527  // Check that the second expression has form v = x.
6528  Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
6529  llvm::FoldingSetNodeID XId, PossibleXId;
6530  Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
6531  PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
6532  IsUpdateExprFound = XId == PossibleXId;
6533  if (IsUpdateExprFound) {
6534  V = BinOp->getLHS();
6535  X = Checker.getX();
6536  E = Checker.getExpr();
6537  UE = Checker.getUpdateExpr();
6538  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6539  IsPostfixUpdate = false;
6540  }
6541  }
6542  }
6543  if (!IsUpdateExprFound) {
6544  // { v = x; x = expr; }
6545  auto *FirstExpr = dyn_cast<Expr>(First);
6546  auto *SecondExpr = dyn_cast<Expr>(Second);
6547  if (!FirstExpr || !SecondExpr ||
6548  !(FirstExpr->isInstantiationDependent() ||
6549  SecondExpr->isInstantiationDependent())) {
6550  auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
6551  if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
6552  ErrorFound = NotAnAssignmentOp;
6553  NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
6554  : First->getLocStart();
6555  NoteRange = ErrorRange = FirstBinOp
6556  ? FirstBinOp->getSourceRange()
6557  : SourceRange(ErrorLoc, ErrorLoc);
6558  } else {
6559  auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
6560  if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
6561  ErrorFound = NotAnAssignmentOp;
6562  NoteLoc = ErrorLoc = SecondBinOp
6563  ? SecondBinOp->getOperatorLoc()
6564  : Second->getLocStart();
6565  NoteRange = ErrorRange =
6566  SecondBinOp ? SecondBinOp->getSourceRange()
6567  : SourceRange(ErrorLoc, ErrorLoc);
6568  } else {
6569  Expr *PossibleXRHSInFirst =
6570  FirstBinOp->getRHS()->IgnoreParenImpCasts();
6571  Expr *PossibleXLHSInSecond =
6572  SecondBinOp->getLHS()->IgnoreParenImpCasts();
6573  llvm::FoldingSetNodeID X1Id, X2Id;
6574  PossibleXRHSInFirst->Profile(X1Id, Context,
6575  /*Canonical=*/true);
6576  PossibleXLHSInSecond->Profile(X2Id, Context,
6577  /*Canonical=*/true);
6578  IsUpdateExprFound = X1Id == X2Id;
6579  if (IsUpdateExprFound) {
6580  V = FirstBinOp->getLHS();
6581  X = SecondBinOp->getLHS();
6582  E = SecondBinOp->getRHS();
6583  UE = nullptr;
6584  IsXLHSInRHSPart = false;
6585  IsPostfixUpdate = true;
6586  } else {
6587  ErrorFound = NotASpecificExpression;
6588  ErrorLoc = FirstBinOp->getExprLoc();
6589  ErrorRange = FirstBinOp->getSourceRange();
6590  NoteLoc = SecondBinOp->getLHS()->getExprLoc();
6591  NoteRange = SecondBinOp->getRHS()->getSourceRange();
6592  }
6593  }
6594  }
6595  }
6596  }
6597  } else {
6598  NoteLoc = ErrorLoc = Body->getLocStart();
6599  NoteRange = ErrorRange =
6600  SourceRange(Body->getLocStart(), Body->getLocStart());
6601  ErrorFound = NotTwoSubstatements;
6602  }
6603  } else {
6604  NoteLoc = ErrorLoc = Body->getLocStart();
6605  NoteRange = ErrorRange =
6606  SourceRange(Body->getLocStart(), Body->getLocStart());
6607  ErrorFound = NotACompoundStatement;
6608  }
6609  if (ErrorFound != NoError) {
6610  Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
6611  << ErrorRange;
6612  Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
6613  return StmtError();
6614  }
6615  if (CurContext->isDependentContext())
6616  UE = V = E = X = nullptr;
6617  }
6618  }
6619 
6620  setFunctionHasBranchProtectedScope();
6621 
6622  return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
6623  X, V, E, UE, IsXLHSInRHSPart,
6624  IsPostfixUpdate);
6625 }
6626 
6628  Stmt *AStmt,
6629  SourceLocation StartLoc,
6630  SourceLocation EndLoc) {
6631  if (!AStmt)
6632  return StmtError();
6633 
6634  auto *CS = cast<CapturedStmt>(AStmt);
6635  // 1.2.2 OpenMP Language Terminology
6636  // Structured block - An executable statement with a single entry at the
6637  // top and a single exit at the bottom.
6638  // The point of exit cannot be a branch out of the structured block.
6639  // longjmp() and throw() must not violate the entry/exit criteria.
6640  CS->getCapturedDecl()->setNothrow();
6641  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
6642  ThisCaptureLevel > 1; --ThisCaptureLevel) {
6643  CS = cast<CapturedStmt>(CS->getCapturedStmt());
6644  // 1.2.2 OpenMP Language Terminology
6645  // Structured block - An executable statement with a single entry at the
6646  // top and a single exit at the bottom.
6647  // The point of exit cannot be a branch out of the structured block.
6648  // longjmp() and throw() must not violate the entry/exit criteria.
6649  CS->getCapturedDecl()->setNothrow();
6650  }
6651 
6652  // OpenMP [2.16, Nesting of Regions]
6653  // If specified, a teams construct must be contained within a target
6654  // construct. That target construct must contain no statements or directives
6655  // outside of the teams construct.
6656  if (DSAStack->hasInnerTeamsRegion()) {
6657  const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
6658  bool OMPTeamsFound = true;
6659  if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
6660  auto I = CS->body_begin();
6661  while (I != CS->body_end()) {
6662  const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
6663  if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind())) {
6664  OMPTeamsFound = false;
6665  break;
6666  }
6667  ++I;
6668  }
6669  assert(I != CS->body_end() && "Not found statement");
6670  S = *I;
6671  } else {
6672  const auto *OED = dyn_cast<OMPExecutableDirective>(S);
6673  OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
6674  }
6675  if (!OMPTeamsFound) {
6676  Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
6677  Diag(DSAStack->getInnerTeamsRegionLoc(),
6678  diag::note_omp_nested_teams_construct_here);
6679  Diag(S->getLocStart(), diag::note_omp_nested_statement_here)
6680  << isa<OMPExecutableDirective>(S);
6681  return StmtError();
6682  }
6683  }
6684 
6685  setFunctionHasBranchProtectedScope();
6686 
6687  return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
6688 }
6689 
6690 StmtResult
6692  Stmt *AStmt, SourceLocation StartLoc,
6693  SourceLocation EndLoc) {
6694  if (!AStmt)
6695  return StmtError();
6696 
6697  auto *CS = cast<CapturedStmt>(AStmt);
6698  // 1.2.2 OpenMP Language Terminology
6699  // Structured block - An executable statement with a single entry at the
6700  // top and a single exit at the bottom.
6701  // The point of exit cannot be a branch out of the structured block.
6702  // longjmp() and throw() must not violate the entry/exit criteria.
6703  CS->getCapturedDecl()->setNothrow();
6704  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
6705  ThisCaptureLevel > 1; --ThisCaptureLevel) {
6706  CS = cast<CapturedStmt>(CS->getCapturedStmt());
6707  // 1.2.2 OpenMP Language Terminology
6708  // Structured block - An executable statement with a single entry at the
6709  // top and a single exit at the bottom.
6710  // The point of exit cannot be a branch out of the structured block.
6711  // longjmp() and throw() must not violate the entry/exit criteria.
6712  CS->getCapturedDecl()->setNothrow();
6713  }
6714 
6715  setFunctionHasBranchProtectedScope();
6716 
6717  return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses,
6718  AStmt);
6719 }
6720 
6722  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6723  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
6724  if (!AStmt)
6725  return StmtError();
6726 
6727  auto *CS = cast<CapturedStmt>(AStmt);
6728  // 1.2.2 OpenMP Language Terminology
6729  // Structured block - An executable statement with a single entry at the
6730  // top and a single exit at the bottom.
6731  // The point of exit cannot be a branch out of the structured block.
6732  // longjmp() and throw() must not violate the entry/exit criteria.
6733  CS->getCapturedDecl()->setNothrow();
6734  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
6735  ThisCaptureLevel > 1; --ThisCaptureLevel) {
6736  CS = cast<CapturedStmt>(CS->getCapturedStmt());
6737  // 1.2.2 OpenMP Language Terminology
6738  // Structured block - An executable statement with a single entry at the
6739  // top and a single exit at the bottom.
6740  // The point of exit cannot be a branch out of the structured block.
6741  // longjmp() and throw() must not violate the entry/exit criteria.
6742  CS->getCapturedDecl()->setNothrow();
6743  }
6744 
6746  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6747  // define the nested loops number.
6748  unsigned NestedLoopCount =
6749  checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
6750  getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
6751  VarsWithImplicitDSA, B);
6752  if (NestedLoopCount == 0)
6753  return StmtError();
6754 
6755  assert((CurContext->isDependentContext() || B.builtAll()) &&
6756  "omp target parallel for loop exprs were not built");
6757 
6758  if (!CurContext->isDependentContext()) {
6759  // Finalize the clauses that need pre-built expressions for CodeGen.
6760  for (OMPClause *C : Clauses) {
6761  if (auto *LC = dyn_cast<OMPLinearClause>(C))
6762  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
6763  B.NumIterations, *this, CurScope,
6764  DSAStack))
6765  return StmtError();
6766  }
6767  }
6768 
6769  setFunctionHasBranchProtectedScope();
6770  return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc,
6771  NestedLoopCount, Clauses, AStmt,
6772  B, DSAStack->isCancelRegion());
6773 }
6774 
6775 /// Check for existence of a map clause in the list of clauses.
6776 static bool hasClauses(ArrayRef<OMPClause *> Clauses,
6777  const OpenMPClauseKind K) {
6778  return llvm::any_of(
6779  Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
6780 }
6781 
6782 template <typename... Params>
6784  const Params... ClauseTypes) {
6785  return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
6786 }
6787 
6789  Stmt *AStmt,
6790  SourceLocation StartLoc,
6791  SourceLocation EndLoc) {
6792  if (!AStmt)
6793  return StmtError();
6794 
6795  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6796 
6797  // OpenMP [2.10.1, Restrictions, p. 97]
6798  // At least one map clause must appear on the directive.
6799  if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) {
6800  Diag(StartLoc, diag::err_omp_no_clause_for_directive)
6801  << "'map' or 'use_device_ptr'"
6802  << getOpenMPDirectiveName(OMPD_target_data);
6803  return StmtError();
6804  }
6805 
6806  setFunctionHasBranchProtectedScope();
6807 
6808  return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
6809  AStmt);
6810 }
6811 
6812 StmtResult
6814  SourceLocation StartLoc,
6815  SourceLocation EndLoc, Stmt *AStmt) {
6816  if (!AStmt)
6817  return StmtError();
6818 
6819  auto *CS = cast<CapturedStmt>(AStmt);
6820  // 1.2.2 OpenMP Language Terminology
6821  // Structured block - An executable statement with a single entry at the
6822  // top and a single exit at the bottom.
6823  // The point of exit cannot be a branch out of the structured block.
6824  // longjmp() and throw() must not violate the entry/exit criteria.
6825  CS->getCapturedDecl()->setNothrow();
6826  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
6827  ThisCaptureLevel > 1; --ThisCaptureLevel) {
6828  CS = cast<CapturedStmt>(CS->getCapturedStmt());
6829  // 1.2.2 OpenMP Language Terminology
6830  // Structured block - An executable statement with a single entry at the
6831  // top and a single exit at the bottom.
6832  // The point of exit cannot be a branch out of the structured block.
6833  // longjmp() and throw() must not violate the entry/exit criteria.
6834  CS->getCapturedDecl()->setNothrow();
6835  }
6836 
6837  // OpenMP [2.10.2, Restrictions, p. 99]
6838  // At least one map clause must appear on the directive.
6839  if (!hasClauses(Clauses, OMPC_map)) {
6840  Diag(StartLoc, diag::err_omp_no_clause_for_directive)
6841  << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
6842  return StmtError();
6843  }
6844 
6845  return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
6846  AStmt);
6847 }
6848 
6849 StmtResult
6851  SourceLocation StartLoc,
6852  SourceLocation EndLoc, Stmt *AStmt) {
6853  if (!AStmt)
6854  return StmtError();
6855 
6856  auto *CS = cast<CapturedStmt>(AStmt);
6857  // 1.2.2 OpenMP Language Terminology
6858  // Structured block - An executable statement with a single entry at the
6859  // top and a single exit at the bottom.
6860  // The point of exit cannot be a branch out of the structured block.
6861  // longjmp() and throw() must not violate the entry/exit criteria.
6862  CS->getCapturedDecl()->setNothrow();
6863  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
6864  ThisCaptureLevel > 1; --ThisCaptureLevel) {
6865  CS = cast<CapturedStmt>(CS->getCapturedStmt());
6866  // 1.2.2 OpenMP Language Terminology
6867  // Structured block - An executable statement with a single entry at the
6868  // top and a single exit at the bottom.
6869  // The point of exit cannot be a branch out of the structured block.
6870  // longjmp() and throw() must not violate the entry/exit criteria.
6871  CS->getCapturedDecl()->setNothrow();
6872  }
6873 
6874  // OpenMP [2.10.3, Restrictions, p. 102]
6875  // At least one map clause must appear on the directive.
6876  if (!hasClauses(Clauses, OMPC_map)) {
6877  Diag(StartLoc, diag::err_omp_no_clause_for_directive)
6878  << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
6879  return StmtError();
6880  }
6881 
6882  return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
6883  AStmt);
6884 }
6885 
6887  SourceLocation StartLoc,
6888  SourceLocation EndLoc,
6889  Stmt *AStmt) {
6890  if (!AStmt)
6891  return StmtError();
6892 
6893  auto *CS = cast<CapturedStmt>(AStmt);
6894  // 1.2.2 OpenMP Language Terminology
6895  // Structured block - An executable statement with a single entry at the
6896  // top and a single exit at the bottom.
6897  // The point of exit cannot be a branch out of the structured block.
6898  // longjmp() and throw() must not violate the entry/exit criteria.
6899  CS->getCapturedDecl()->setNothrow();
6900  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
6901  ThisCaptureLevel > 1; --ThisCaptureLevel) {
6902  CS = cast<CapturedStmt>(CS->getCapturedStmt());
6903  // 1.2.2 OpenMP Language Terminology
6904  // Structured block - An executable statement with a single entry at the
6905  // top and a single exit at the bottom.
6906  // The point of exit cannot be a branch out of the structured block.
6907  // longjmp() and throw() must not violate the entry/exit criteria.
6908  CS->getCapturedDecl()->setNothrow();
6909  }
6910 
6911  if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
6912  Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
6913  return StmtError();
6914  }
6915  return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
6916  AStmt);
6917 }
6918 
6920  Stmt *AStmt, SourceLocation StartLoc,
6921  SourceLocation EndLoc) {
6922  if (!AStmt)
6923  return StmtError();
6924 
6925  auto *CS = cast<CapturedStmt>(AStmt);
6926  // 1.2.2 OpenMP Language Terminology
6927  // Structured block - An executable statement with a single entry at the
6928  // top and a single exit at the bottom.
6929  // The point of exit cannot be a branch out of the structured block.
6930  // longjmp() and throw() must not violate the entry/exit criteria.
6931  CS->getCapturedDecl()->setNothrow();
6932 
6933  setFunctionHasBranchProtectedScope();
6934 
6935  DSAStack->setParentTeamsRegionLoc(StartLoc);
6936 
6937  return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
6938 }
6939 
6940 StmtResult
6942  SourceLocation EndLoc,
6943  OpenMPDirectiveKind CancelRegion) {
6944  if (DSAStack->isParentNowaitRegion()) {
6945  Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
6946  return StmtError();
6947  }
6948  if (DSAStack->isParentOrderedRegion()) {
6949  Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
6950  return StmtError();
6951  }
6952  return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
6953  CancelRegion);
6954 }
6955 
6957  SourceLocation StartLoc,
6958  SourceLocation EndLoc,
6959  OpenMPDirectiveKind CancelRegion) {
6960  if (DSAStack->isParentNowaitRegion()) {
6961  Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
6962  return StmtError();
6963  }
6964  if (DSAStack->isParentOrderedRegion()) {
6965  Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
6966  return StmtError();
6967  }
6968  DSAStack->setParentCancelRegion(/*Cancel=*/true);
6969  return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
6970  CancelRegion);
6971 }
6972 
6974  ArrayRef<OMPClause *> Clauses) {
6975  const OMPClause *PrevClause = nullptr;
6976  bool ErrorFound = false;
6977  for (const OMPClause *C : Clauses) {
6978  if (C->getClauseKind() == OMPC_grainsize ||
6979  C->getClauseKind() == OMPC_num_tasks) {
6980  if (!PrevClause)
6981  PrevClause = C;
6982  else if (PrevClause->getClauseKind() != C->getClauseKind()) {
6983  S.Diag(C->getLocStart(),
6984  diag::err_omp_grainsize_num_tasks_mutually_exclusive)
6985  << getOpenMPClauseName(C->getClauseKind())
6986  << getOpenMPClauseName(PrevClause->getClauseKind());
6987  S.Diag(PrevClause->getLocStart(),
6988  diag::note_omp_previous_grainsize_num_tasks)
6989  << getOpenMPClauseName(PrevClause->getClauseKind());
6990  ErrorFound = true;
6991  }
6992  }
6993  }
6994  return ErrorFound;
6995 }
6996 
6998  ArrayRef<OMPClause *> Clauses) {
6999  const OMPClause *ReductionClause = nullptr;
7000  const OMPClause *NogroupClause = nullptr;
7001  for (const OMPClause *C : Clauses) {
7002  if (C->getClauseKind() == OMPC_reduction) {
7003  ReductionClause = C;
7004  if (NogroupClause)
7005  break;
7006  continue;
7007  }
7008  if (C->getClauseKind() == OMPC_nogroup) {
7009  NogroupClause = C;
7010  if (ReductionClause)
7011  break;
7012  continue;
7013  }
7014  }
7015  if (ReductionClause && NogroupClause) {
7016  S.Diag(ReductionClause->getLocStart(), diag::err_omp_reduction_with_nogroup)
7017  << SourceRange(NogroupClause->getLocStart(),
7018  NogroupClause->getLocEnd());
7019  return true;
7020  }
7021  return false;
7022 }
7023 
7025  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7026  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7027  if (!AStmt)
7028  return StmtError();
7029 
7030  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
7032  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7033  // define the nested loops number.
7034  unsigned NestedLoopCount =
7035  checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
7036  /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
7037  VarsWithImplicitDSA, B);
7038  if (NestedLoopCount == 0)
7039  return StmtError();
7040 
7041  assert((CurContext->isDependentContext() || B.builtAll()) &&
7042  "omp for loop exprs were not built");
7043 
7044  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
7045  // The grainsize clause and num_tasks clause are mutually exclusive and may
7046  // not appear on the same taskloop directive.
7047  if (checkGrainsizeNumTasksClauses(*this, Clauses))
7048  return StmtError();
7049  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
7050  // If a reduction clause is present on the taskloop directive, the nogroup
7051  // clause must not be specified.
7052  if (checkReductionClauseWithNogroup(*this, Clauses))
7053  return StmtError();
7054 
7055  setFunctionHasBranchProtectedScope();
7056  return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
7057  NestedLoopCount, Clauses, AStmt, B);
7058 }
7059 
7061  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7062  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7063  if (!AStmt)
7064  return StmtError();
7065 
7066  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
7068  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7069  // define the nested loops number.
7070  unsigned NestedLoopCount =
7071  checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
7072  /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
7073  VarsWithImplicitDSA, B);
7074  if (NestedLoopCount == 0)
7075  return StmtError();
7076 
7077  assert((CurContext->isDependentContext() || B.builtAll()) &&
7078  "omp for loop exprs were not built");
7079 
7080  if (!CurContext->isDependentContext()) {
7081  // Finalize the clauses that need pre-built expressions for CodeGen.
7082  for (OMPClause *C : Clauses) {
7083  if (auto *LC = dyn_cast<OMPLinearClause>(C))
7084  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7085  B.NumIterations, *this, CurScope,
7086  DSAStack))
7087  return StmtError();
7088  }
7089  }
7090 
7091  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
7092  // The grainsize clause and num_tasks clause are mutually exclusive and may
7093  // not appear on the same taskloop directive.
7094  if (checkGrainsizeNumTasksClauses(*this, Clauses))
7095  return StmtError();
7096  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
7097  // If a reduction clause is present on the taskloop directive, the nogroup
7098  // clause must not be specified.
7099  if (checkReductionClauseWithNogroup(*this, Clauses))
7100  return StmtError();
7101  if (checkSimdlenSafelenSpecified(*this, Clauses))
7102  return StmtError();
7103 
7104  setFunctionHasBranchProtectedScope();
7105  return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
7106  NestedLoopCount, Clauses, AStmt, B);
7107 }
7108 
7110  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7111  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7112  if (!AStmt)
7113  return StmtError();
7114 
7115  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
7117  // In presence of clause 'collapse' with number of loops, it will
7118  // define the nested loops number.
7119  unsigned NestedLoopCount =
7120  checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
7121  nullptr /*ordered not a clause on distribute*/, AStmt,
7122  *this, *DSAStack, VarsWithImplicitDSA, B);
7123  if (NestedLoopCount == 0)
7124  return StmtError();
7125 
7126  assert((CurContext->isDependentContext() || B.builtAll()) &&
7127  "omp for loop exprs were not built");
7128 
7129  setFunctionHasBranchProtectedScope();
7130  return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
7131  NestedLoopCount, Clauses, AStmt, B);
7132 }
7133 
7135  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7136  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7137  if (!AStmt)
7138  return StmtError();
7139 
7140  auto *CS = cast<CapturedStmt>(AStmt);
7141  // 1.2.2 OpenMP Language Terminology
7142  // Structured block - An executable statement with a single entry at the
7143  // top and a single exit at the bottom.
7144  // The point of exit cannot be a branch out of the structured block.
7145  // longjmp() and throw() must not violate the entry/exit criteria.
7146  CS->getCapturedDecl()->setNothrow();
7147  for (int ThisCaptureLevel =
7148  getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
7149  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7150  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7151  // 1.2.2 OpenMP Language Terminology
7152  // Structured block - An executable statement with a single entry at the
7153  // top and a single exit at the bottom.
7154  // The point of exit cannot be a branch out of the structured block.
7155  // longjmp() and throw() must not violate the entry/exit criteria.
7156  CS->getCapturedDecl()->setNothrow();
7157  }
7158 
7160  // In presence of clause 'collapse' with number of loops, it will
7161  // define the nested loops number.
7162  unsigned NestedLoopCount = checkOpenMPLoop(
7163  OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
7164  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7165  VarsWithImplicitDSA, B);
7166  if (NestedLoopCount == 0)
7167  return StmtError();
7168 
7169  assert((CurContext->isDependentContext() || B.builtAll()) &&
7170  "omp for loop exprs were not built");
7171 
7172  setFunctionHasBranchProtectedScope();
7174  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
7175  DSAStack->isCancelRegion());
7176 }
7177 
7179  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7180  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7181  if (!AStmt)
7182  return StmtError();
7183 
7184  auto *CS = cast<CapturedStmt>(AStmt);
7185  // 1.2.2 OpenMP Language Terminology
7186  // Structured block - An executable statement with a single entry at the
7187  // top and a single exit at the bottom.
7188  // The point of exit cannot be a branch out of the structured block.
7189  // longjmp() and throw() must not violate the entry/exit criteria.
7190  CS->getCapturedDecl()->setNothrow();
7191  for (int ThisCaptureLevel =
7192  getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
7193  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7194  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7195  // 1.2.2 OpenMP Language Terminology
7196  // Structured block - An executable statement with a single entry at the
7197  // top and a single exit at the bottom.
7198  // The point of exit cannot be a branch out of the structured block.
7199  // longjmp() and throw() must not violate the entry/exit criteria.
7200  CS->getCapturedDecl()->setNothrow();
7201  }
7202 
7204  // In presence of clause 'collapse' with number of loops, it will
7205  // define the nested loops number.
7206  unsigned NestedLoopCount = checkOpenMPLoop(
7207  OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
7208  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7209  VarsWithImplicitDSA, B);
7210  if (NestedLoopCount == 0)
7211  return StmtError();
7212 
7213  assert((CurContext->isDependentContext() || B.builtAll()) &&
7214  "omp for loop exprs were not built");
7215 
7216  if (!CurContext->isDependentContext()) {
7217  // Finalize the clauses that need pre-built expressions for CodeGen.
7218  for (OMPClause *C : Clauses) {
7219  if (auto *LC = dyn_cast<OMPLinearClause>(C))
7220  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7221  B.NumIterations, *this, CurScope,
7222  DSAStack))
7223  return StmtError();
7224  }
7225  }
7226 
7227  if (checkSimdlenSafelenSpecified(*this, Clauses))
7228  return StmtError();
7229 
7230  setFunctionHasBranchProtectedScope();
7232  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7233 }
7234 
7236  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7237  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7238  if (!AStmt)
7239  return StmtError();
7240 
7241  auto *CS = cast<CapturedStmt>(AStmt);
7242  // 1.2.2 OpenMP Language Terminology
7243  // Structured block - An executable statement with a single entry at the
7244  // top and a single exit at the bottom.
7245  // The point of exit cannot be a branch out of the structured block.
7246  // longjmp() and throw() must not violate the entry/exit criteria.
7247  CS->getCapturedDecl()->setNothrow();
7248  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
7249  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7250  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7251  // 1.2.2 OpenMP Language Terminology
7252  // Structured block - An executable statement with a single entry at the
7253  // top and a single exit at the bottom.
7254  // The point of exit cannot be a branch out of the structured block.
7255  // longjmp() and throw() must not violate the entry/exit criteria.
7256  CS->getCapturedDecl()->setNothrow();
7257  }
7258 
7260  // In presence of clause 'collapse' with number of loops, it will
7261  // define the nested loops number.
7262  unsigned NestedLoopCount =
7263  checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
7264  nullptr /*ordered not a clause on distribute*/, CS, *this,
7265  *DSAStack, VarsWithImplicitDSA, B);
7266  if (NestedLoopCount == 0)
7267  return StmtError();
7268 
7269  assert((CurContext->isDependentContext() || B.builtAll()) &&
7270  "omp for loop exprs were not built");
7271 
7272  if (!CurContext->isDependentContext()) {
7273  // Finalize the clauses that need pre-built expressions for CodeGen.
7274  for (OMPClause *C : Clauses) {
7275  if (auto *LC = dyn_cast<OMPLinearClause>(C))
7276  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7277  B.NumIterations, *this, CurScope,
7278  DSAStack))
7279  return StmtError();
7280  }
7281  }
7282 
7283  if (checkSimdlenSafelenSpecified(*this, Clauses))
7284  return StmtError();
7285 
7286  setFunctionHasBranchProtectedScope();
7287  return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
7288  NestedLoopCount, Clauses, AStmt, B);
7289 }
7290 
7292  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7293  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7294  if (!AStmt)
7295  return StmtError();
7296 
7297  auto *CS = cast<CapturedStmt>(AStmt);
7298  // 1.2.2 OpenMP Language Terminology
7299  // Structured block - An executable statement with a single entry at the
7300  // top and a single exit at the bottom.
7301  // The point of exit cannot be a branch out of the structured block.
7302  // longjmp() and throw() must not violate the entry/exit criteria.
7303  CS->getCapturedDecl()->setNothrow();
7304  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
7305  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7306  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7307  // 1.2.2 OpenMP Language Terminology
7308  // Structured block - An executable statement with a single entry at the
7309  // top and a single exit at the bottom.
7310  // The point of exit cannot be a branch out of the structured block.
7311  // longjmp() and throw() must not violate the entry/exit criteria.
7312  CS->getCapturedDecl()->setNothrow();
7313  }
7314 
7316  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7317  // define the nested loops number.
7318  unsigned NestedLoopCount = checkOpenMPLoop(
7319  OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
7320  getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
7321  VarsWithImplicitDSA, B);
7322  if (NestedLoopCount == 0)
7323  return StmtError();
7324 
7325  assert((CurContext->isDependentContext() || B.builtAll()) &&
7326  "omp target parallel for simd loop exprs were not built");
7327 
7328  if (!CurContext->isDependentContext()) {
7329  // Finalize the clauses that need pre-built expressions for CodeGen.
7330  for (OMPClause *C : Clauses) {
7331  if (auto *LC = dyn_cast<OMPLinearClause>(C))
7332  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7333  B.NumIterations, *this, CurScope,
7334  DSAStack))
7335  return StmtError();
7336  }
7337  }
7338  if (checkSimdlenSafelenSpecified(*this, Clauses))
7339  return StmtError();
7340 
7341  setFunctionHasBranchProtectedScope();
7343  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7344 }
7345 
7347  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7348  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7349  if (!AStmt)
7350  return StmtError();
7351 
7352  auto *CS = cast<CapturedStmt>(AStmt);
7353  // 1.2.2 OpenMP Language Terminology
7354  // Structured block - An executable statement with a single entry at the
7355  // top and a single exit at the bottom.
7356  // The point of exit cannot be a branch out of the structured block.
7357  // longjmp() and throw() must not violate the entry/exit criteria.
7358  CS->getCapturedDecl()->setNothrow();
7359  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
7360  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7361  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7362  // 1.2.2 OpenMP Language Terminology
7363  // Structured block - An executable statement with a single entry at the
7364  // top and a single exit at the bottom.
7365  // The point of exit cannot be a branch out of the structured block.
7366  // longjmp() and throw() must not violate the entry/exit criteria.
7367  CS->getCapturedDecl()->setNothrow();
7368  }
7369 
7371  // In presence of clause 'collapse' with number of loops, it will define the
7372  // nested loops number.
7373  unsigned NestedLoopCount =
7374  checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
7375  getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
7376  VarsWithImplicitDSA, B);
7377  if (NestedLoopCount == 0)
7378  return StmtError();
7379 
7380  assert((CurContext->isDependentContext() || B.builtAll()) &&
7381  "omp target simd loop exprs were not built");
7382 
7383  if (!CurContext->isDependentContext()) {
7384  // Finalize the clauses that need pre-built expressions for CodeGen.
7385  for (OMPClause *C : Clauses) {
7386  if (auto *LC = dyn_cast<OMPLinearClause>(C))
7387  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7388  B.NumIterations, *this, CurScope,
7389  DSAStack))
7390  return StmtError();
7391  }
7392  }
7393 
7394  if (checkSimdlenSafelenSpecified(*this, Clauses))
7395  return StmtError();
7396 
7397  setFunctionHasBranchProtectedScope();
7398  return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
7399  NestedLoopCount, Clauses, AStmt, B);
7400 }
7401 
7403  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7404  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7405  if (!AStmt)
7406  return StmtError();
7407 
7408  auto *CS = cast<CapturedStmt>(AStmt);
7409  // 1.2.2 OpenMP Language Terminology
7410  // Structured block - An executable statement with a single entry at the
7411  // top and a single exit at the bottom.
7412  // The point of exit cannot be a branch out of the structured block.
7413  // longjmp() and throw() must not violate the entry/exit criteria.
7414  CS->getCapturedDecl()->setNothrow();
7415  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
7416  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7417  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7418  // 1.2.2 OpenMP Language Terminology
7419  // Structured block - An executable statement with a single entry at the
7420  // top and a single exit at the bottom.
7421  // The point of exit cannot be a branch out of the structured block.
7422  // longjmp() and throw() must not violate the entry/exit criteria.
7423  CS->getCapturedDecl()->setNothrow();
7424  }
7425 
7427  // In presence of clause 'collapse' with number of loops, it will
7428  // define the nested loops number.
7429  unsigned NestedLoopCount =
7430  checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
7431  nullptr /*ordered not a clause on distribute*/, CS, *this,
7432  *DSAStack, VarsWithImplicitDSA, B);
7433  if (NestedLoopCount == 0)
7434  return StmtError();
7435 
7436  assert((CurContext->isDependentContext() || B.builtAll()) &&
7437  "omp teams distribute loop exprs were not built");
7438 
7439  setFunctionHasBranchProtectedScope();
7440 
7441  DSAStack->setParentTeamsRegionLoc(StartLoc);
7442 
7444  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7445 }
7446 
7448  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7449  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7450  if (!AStmt)
7451  return StmtError();
7452 
7453  auto *CS = cast<CapturedStmt>(AStmt);
7454  // 1.2.2 OpenMP Language Terminology
7455  // Structured block - An executable statement with a single entry at the
7456  // top and a single exit at the bottom.
7457  // The point of exit cannot be a branch out of the structured block.
7458  // longjmp() and throw() must not violate the entry/exit criteria.
7459  CS->getCapturedDecl()->setNothrow();
7460  for (int ThisCaptureLevel =
7461  getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
7462  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7463  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7464  // 1.2.2 OpenMP Language Terminology
7465  // Structured block - An executable statement with a single entry at the
7466  // top and a single exit at the bottom.
7467  // The point of exit cannot be a branch out of the structured block.
7468  // longjmp() and throw() must not violate the entry/exit criteria.
7469  CS->getCapturedDecl()->setNothrow();
7470  }
7471 
7472 
7474  // In presence of clause 'collapse' with number of loops, it will
7475  // define the nested loops number.
7476  unsigned NestedLoopCount = checkOpenMPLoop(
7477  OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
7478  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7479  VarsWithImplicitDSA, B);
7480 
7481  if (NestedLoopCount == 0)
7482  return StmtError();
7483 
7484  assert((CurContext->isDependentContext() || B.builtAll()) &&
7485  "omp teams distribute simd loop exprs were not built");
7486 
7487  if (!CurContext->isDependentContext()) {
7488  // Finalize the clauses that need pre-built expressions for CodeGen.
7489  for (OMPClause *C : Clauses) {
7490  if (auto *LC = dyn_cast<OMPLinearClause>(C))
7491  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7492  B.NumIterations, *this, CurScope,
7493  DSAStack))
7494  return StmtError();
7495  }
7496  }
7497 
7498  if (checkSimdlenSafelenSpecified(*this, Clauses))
7499  return StmtError();
7500 
7501  setFunctionHasBranchProtectedScope();
7502 
7503  DSAStack->setParentTeamsRegionLoc(StartLoc);
7504 
7506  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7507 }
7508 
7510  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7511  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7512  if (!AStmt)
7513  return StmtError();
7514 
7515  auto *CS = cast<CapturedStmt>(AStmt);
7516  // 1.2.2 OpenMP Language Terminology
7517  // Structured block - An executable statement with a single entry at the
7518  // top and a single exit at the bottom.
7519  // The point of exit cannot be a branch out of the structured block.
7520  // longjmp() and throw() must not violate the entry/exit criteria.
7521  CS->getCapturedDecl()->setNothrow();
7522 
7523  for (int ThisCaptureLevel =
7524  getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
7525  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7526  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7527  // 1.2.2 OpenMP Language Terminology
7528  // Structured block - An executable statement with a single entry at the
7529  // top and a single exit at the bottom.
7530  // The point of exit cannot be a branch out of the structured block.
7531  // longjmp() and throw() must not violate the entry/exit criteria.
7532  CS->getCapturedDecl()->setNothrow();
7533  }
7534 
7536  // In presence of clause 'collapse' with number of loops, it will
7537  // define the nested loops number.
7538  unsigned NestedLoopCount = checkOpenMPLoop(
7539  OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
7540  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7541  VarsWithImplicitDSA, B);
7542 
7543  if (NestedLoopCount == 0)
7544  return StmtError();
7545 
7546  assert((CurContext->isDependentContext() || B.builtAll()) &&
7547  "omp for loop exprs were not built");
7548 
7549  if (!CurContext->isDependentContext()) {
7550  // Finalize the clauses that need pre-built expressions for CodeGen.
7551  for (OMPClause *C : Clauses) {
7552  if (auto *LC = dyn_cast<OMPLinearClause>(C))
7553  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7554  B.NumIterations, *this, CurScope,
7555  DSAStack))
7556  return StmtError();
7557  }
7558  }
7559 
7560  if (checkSimdlenSafelenSpecified(*this, Clauses))
7561  return StmtError();
7562 
7563  setFunctionHasBranchProtectedScope();
7564 
7565  DSAStack->setParentTeamsRegionLoc(StartLoc);
7566 
7568  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7569 }
7570 
7572  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7573  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7574  if (!AStmt)
7575  return StmtError();
7576 
7577  auto *CS = cast<CapturedStmt>(AStmt);
7578  // 1.2.2 OpenMP Language Terminology
7579  // Structured block - An executable statement with a single entry at the
7580  // top and a single exit at the bottom.
7581  // The point of exit cannot be a branch out of the structured block.
7582  // longjmp() and throw() must not violate the entry/exit criteria.
7583  CS->getCapturedDecl()->setNothrow();
7584 
7585  for (int ThisCaptureLevel =
7586  getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
7587  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7588  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7589  // 1.2.2 OpenMP Language Terminology
7590  // Structured block - An executable statement with a single entry at the
7591  // top and a single exit at the bottom.
7592  // The point of exit cannot be a branch out of the structured block.
7593  // longjmp() and throw() must not violate the entry/exit criteria.
7594  CS->getCapturedDecl()->setNothrow();
7595  }
7596 
7598  // In presence of clause 'collapse' with number of loops, it will
7599  // define the nested loops number.
7600  unsigned NestedLoopCount = checkOpenMPLoop(
7601  OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
7602  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7603  VarsWithImplicitDSA, B);
7604 
7605  if (NestedLoopCount == 0)
7606  return StmtError();
7607 
7608  assert((CurContext->isDependentContext() || B.builtAll()) &&
7609  "omp for loop exprs were not built");
7610 
7611  setFunctionHasBranchProtectedScope();
7612 
7613  DSAStack->setParentTeamsRegionLoc(StartLoc);
7614 
7616  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
7617  DSAStack->isCancelRegion());
7618 }
7619 
7621  Stmt *AStmt,
7622  SourceLocation StartLoc,
7623  SourceLocation EndLoc) {
7624  if (!AStmt)
7625  return StmtError();
7626 
7627  auto *CS = cast<CapturedStmt>(AStmt);
7628  // 1.2.2 OpenMP Language Terminology
7629  // Structured block - An executable statement with a single entry at the
7630  // top and a single exit at the bottom.
7631  // The point of exit cannot be a branch out of the structured block.
7632  // longjmp() and throw() must not violate the entry/exit criteria.
7633  CS->getCapturedDecl()->setNothrow();
7634 
7635  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
7636  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7637  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7638  // 1.2.2 OpenMP Language Terminology
7639  // Structured block - An executable statement with a single entry at the
7640  // top and a single exit at the bottom.
7641  // The point of exit cannot be a branch out of the structured block.
7642  // longjmp() and throw() must not violate the entry/exit criteria.
7643  CS->getCapturedDecl()->setNothrow();
7644  }
7645  setFunctionHasBranchProtectedScope();
7646 
7647  return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
7648  AStmt);
7649 }
7650 
7652  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7653  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7654  if (!AStmt)
7655  return StmtError();
7656 
7657  auto *CS = cast<CapturedStmt>(AStmt);
7658  // 1.2.2 OpenMP Language Terminology
7659  // Structured block - An executable statement with a single entry at the
7660  // top and a single exit at the bottom.
7661  // The point of exit cannot be a branch out of the structured block.
7662  // longjmp() and throw() must not violate the entry/exit criteria.
7663  CS->getCapturedDecl()->setNothrow();
7664  for (int ThisCaptureLevel =
7665  getOpenMPCaptureLevels(OMPD_target_teams_distribute);
7666  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7667  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7668  // 1.2.2 OpenMP Language Terminology
7669  // Structured block - An executable statement with a single entry at the
7670  // top and a single exit at the bottom.
7671  // The point of exit cannot be a branch out of the structured block.
7672  // longjmp() and throw() must not violate the entry/exit criteria.
7673  CS->getCapturedDecl()->setNothrow();
7674  }
7675 
7677  // In presence of clause 'collapse' with number of loops, it will
7678  // define the nested loops number.
7679  unsigned NestedLoopCount = checkOpenMPLoop(
7680  OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
7681  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7682  VarsWithImplicitDSA, B);
7683  if (NestedLoopCount == 0)
7684  return StmtError();
7685 
7686  assert((CurContext->isDependentContext() || B.builtAll()) &&
7687  "omp target teams distribute loop exprs were not built");
7688 
7689  setFunctionHasBranchProtectedScope();
7691  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7692 }
7693 
7695  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7696  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7697  if (!AStmt)
7698  return StmtError();
7699 
7700  auto *CS = cast<CapturedStmt>(AStmt);
7701  // 1.2.2 OpenMP Language Terminology
7702  // Structured block - An executable statement with a single entry at the
7703  // top and a single exit at the bottom.
7704  // The point of exit cannot be a branch out of the structured block.
7705  // longjmp() and throw() must not violate the entry/exit criteria.
7706  CS->getCapturedDecl()->setNothrow();
7707  for (int ThisCaptureLevel =
7708  getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
7709  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7710  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7711  // 1.2.2 OpenMP Language Terminology
7712  // Structured block - An executable statement with a single entry at the
7713  // top and a single exit at the bottom.
7714  // The point of exit cannot be a branch out of the structured block.
7715  // longjmp() and throw() must not violate the entry/exit criteria.
7716  CS->getCapturedDecl()->setNothrow();
7717  }
7718 
7720  // In presence of clause 'collapse' with number of loops, it will
7721  // define the nested loops number.
7722  unsigned NestedLoopCount = checkOpenMPLoop(
7723  OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
7724  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7725  VarsWithImplicitDSA, B);
7726  if (NestedLoopCount == 0)
7727  return StmtError();
7728 
7729  assert((CurContext->isDependentContext() || B.builtAll()) &&
7730  "omp target teams distribute parallel for loop exprs were not built");
7731 
7732  if (!CurContext->isDependentContext()) {
7733  // Finalize the clauses that need pre-built expressions for CodeGen.
7734  for (OMPClause *C : Clauses) {
7735  if (auto *LC = dyn_cast<OMPLinearClause>(C))
7736  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7737  B.NumIterations, *this, CurScope,
7738  DSAStack))
7739  return StmtError();
7740  }
7741  }
7742 
7743  setFunctionHasBranchProtectedScope();
7745  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
7746  DSAStack->isCancelRegion());
7747 }
7748 
7750  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7751  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7752  if (!AStmt)
7753  return StmtError();
7754 
7755  auto *CS = cast<CapturedStmt>(AStmt);
7756  // 1.2.2 OpenMP Language Terminology
7757  // Structured block - An executable statement with a single entry at the
7758  // top and a single exit at the bottom.
7759  // The point of exit cannot be a branch out of the structured block.
7760  // longjmp() and throw() must not violate the entry/exit criteria.
7761  CS->getCapturedDecl()->setNothrow();
7762  for (int ThisCaptureLevel = getOpenMPCaptureLevels(
7763  OMPD_target_teams_distribute_parallel_for_simd);
7764  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7765  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7766  // 1.2.2 OpenMP Language Terminology
7767  // Structured block - An executable statement with a single entry at the
7768  // top and a single exit at the bottom.
7769  // The point of exit cannot be a branch out of the structured block.
7770  // longjmp() and throw() must not violate the entry/exit criteria.
7771  CS->getCapturedDecl()->setNothrow();
7772  }
7773 
7775  // In presence of clause 'collapse' with number of loops, it will
7776  // define the nested loops number.
7777  unsigned NestedLoopCount =
7778  checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
7779  getCollapseNumberExpr(Clauses),
7780  nullptr /*ordered not a clause on distribute*/, CS, *this,
7781  *DSAStack, VarsWithImplicitDSA, B);
7782  if (NestedLoopCount == 0)
7783  return StmtError();
7784 
7785  assert((CurContext->isDependentContext() || B.builtAll()) &&
7786  "omp target teams distribute parallel for simd loop exprs were not "
7787  "built");
7788 
7789  if (!CurContext->isDependentContext()) {
7790  // Finalize the clauses that need pre-built expressions for CodeGen.
7791  for (OMPClause *C : Clauses) {
7792  if (auto *LC = dyn_cast<OMPLinearClause>(C))
7793  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7794  B.NumIterations, *this, CurScope,
7795  DSAStack))
7796  return StmtError();
7797  }
7798  }
7799 
7800  if (checkSimdlenSafelenSpecified(*this, Clauses))
7801  return StmtError();
7802 
7803  setFunctionHasBranchProtectedScope();
7805  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7806 }
7807 
7809  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7810  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7811  if (!AStmt)
7812  return StmtError();
7813 
7814  auto *CS = cast<CapturedStmt>(AStmt);
7815  // 1.2.2 OpenMP Language Terminology
7816  // Structured block - An executable statement with a single entry at the
7817  // top and a single exit at the bottom.
7818  // The point of exit cannot be a branch out of the structured block.
7819  // longjmp() and throw() must not violate the entry/exit criteria.
7820  CS->getCapturedDecl()->setNothrow();
7821  for (int ThisCaptureLevel =
7822  getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
7823  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7824  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7825  // 1.2.2 OpenMP Language Terminology
7826  // Structured block - An executable statement with a single entry at the
7827  // top and a single exit at the bottom.
7828  // The point of exit cannot be a branch out of the structured block.
7829  // longjmp() and throw() must not violate the entry/exit criteria.
7830  CS->getCapturedDecl()->setNothrow();
7831  }
7832 
7834  // In presence of clause 'collapse' with number of loops, it will
7835  // define the nested loops number.
7836  unsigned NestedLoopCount = checkOpenMPLoop(
7837  OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
7838  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7839  VarsWithImplicitDSA, B);
7840  if (NestedLoopCount == 0)
7841  return StmtError();
7842 
7843  assert((CurContext->isDependentContext() || B.builtAll()) &&
7844  "omp target teams distribute simd loop exprs were not built");
7845 
7846  if (!CurContext->isDependentContext()) {
7847  // Finalize the clauses that need pre-built expressions for CodeGen.
7848  for (OMPClause *C : Clauses) {
7849  if (auto *LC = dyn_cast<OMPLinearClause>(C))
7850  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7851  B.NumIterations, *this, CurScope,
7852  DSAStack))
7853  return StmtError();
7854  }
7855  }
7856 
7857  if (checkSimdlenSafelenSpecified(*this, Clauses))
7858  return StmtError();
7859 
7860  setFunctionHasBranchProtectedScope();
7862  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7863 }
7864 
7866  SourceLocation StartLoc,
7867  SourceLocation LParenLoc,
7868  SourceLocation EndLoc) {
7869  OMPClause *Res = nullptr;
7870  switch (Kind) {
7871  case OMPC_final:
7872  Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
7873  break;
7874  case OMPC_num_threads:
7875  Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
7876  break;
7877  case OMPC_safelen:
7878  Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
7879  break;
7880  case OMPC_simdlen:
7881  Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
7882  break;
7883  case OMPC_collapse:
7884  Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
7885  break;
7886  case OMPC_ordered:
7887  Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
7888  break;
7889  case OMPC_device:
7890  Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc);
7891  break;
7892  case OMPC_num_teams:
7893  Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
7894  break;
7895  case OMPC_thread_limit:
7896  Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
7897  break;
7898  case OMPC_priority:
7899  Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
7900  break;
7901  case OMPC_grainsize:
7902  Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
7903  break;
7904  case OMPC_num_tasks:
7905  Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
7906  break;
7907  case OMPC_hint:
7908  Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
7909  break;
7910  case OMPC_if:
7911  case OMPC_default:
7912  case OMPC_proc_bind:
7913  case OMPC_schedule:
7914  case OMPC_private:
7915  case OMPC_firstprivate:
7916  case OMPC_lastprivate:
7917  case OMPC_shared:
7918  case OMPC_reduction:
7919  case OMPC_task_reduction:
7920  case OMPC_in_reduction:
7921  case OMPC_linear:
7922  case OMPC_aligned:
7923  case OMPC_copyin:
7924  case OMPC_copyprivate:
7925  case OMPC_nowait:
7926  case OMPC_untied:
7927  case OMPC_mergeable:
7928  case OMPC_threadprivate:
7929  case OMPC_flush:
7930  case OMPC_read:
7931  case OMPC_write:
7932  case OMPC_update:
7933  case OMPC_capture:
7934  case OMPC_seq_cst:
7935  case OMPC_depend:
7936  case OMPC_threads:
7937  case OMPC_simd:
7938  case OMPC_map:
7939  case OMPC_nogroup:
7940  case OMPC_dist_schedule:
7941  case OMPC_defaultmap:
7942  case OMPC_unknown:
7943  case OMPC_uniform:
7944  case OMPC_to:
7945  case OMPC_from:
7946  case OMPC_use_device_ptr:
7947  case OMPC_is_device_ptr:
7948  llvm_unreachable("Clause is not allowed.");
7949  }
7950  return Res;
7951 }
7952 
7953 // An OpenMP directive such as 'target parallel' has two captured regions:
7954 // for the 'target' and 'parallel' respectively. This function returns
7955 // the region in which to capture expressions associated with a clause.
7956 // A return value of OMPD_unknown signifies that the expression should not
7957 // be captured.
7960  OpenMPDirectiveKind NameModifier = OMPD_unknown) {
7961  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
7962  switch (CKind) {
7963  case OMPC_if:
7964  switch (DKind) {
7965  case OMPD_target_parallel:
7966  case OMPD_target_parallel_for:
7967  case OMPD_target_parallel_for_simd:
7968  // If this clause applies to the nested 'parallel' region, capture within
7969  // the 'target' region, otherwise do not capture.
7970  if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
7971  CaptureRegion = OMPD_target;
7972  break;
7973  case OMPD_target_teams_distribute_parallel_for:
7974  case OMPD_target_teams_distribute_parallel_for_simd:
7975  // If this clause applies to the nested 'parallel' region, capture within
7976  // the 'teams' region, otherwise do not capture.
7977  if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
7978  CaptureRegion = OMPD_teams;
7979  break;
7980  case OMPD_teams_distribute_parallel_for:
7981  case OMPD_teams_distribute_parallel_for_simd:
7982  CaptureRegion = OMPD_teams;
7983  break;
7984  case OMPD_target_update:
7985  case OMPD_target_enter_data:
7986  case OMPD_target_exit_data:
7987  CaptureRegion = OMPD_task;
7988  break;
7989  case OMPD_cancel:
7990  case OMPD_parallel:
7991  case OMPD_parallel_sections:
7992  case OMPD_parallel_for:
7993  case OMPD_parallel_for_simd:
7994  case OMPD_target:
7995  case OMPD_target_simd:
7996  case OMPD_target_teams:
7997  case OMPD_target_teams_distribute:
7998  case OMPD_target_teams_distribute_simd:
7999  case OMPD_distribute_parallel_for:
8000  case OMPD_distribute_parallel_for_simd:
8001  case OMPD_task:
8002  case OMPD_taskloop:
8003  case OMPD_taskloop_simd:
8004  case OMPD_target_data:
8005  // Do not capture if-clause expressions.
8006  break;
8007  case OMPD_threadprivate:
8008  case OMPD_taskyield:
8009  case OMPD_barrier:
8010  case OMPD_taskwait:
8011  case OMPD_cancellation_point:
8012  case OMPD_flush:
8013  case OMPD_declare_reduction:
8014  case OMPD_declare_simd:
8015  case OMPD_declare_target:
8016  case OMPD_end_declare_target:
8017  case OMPD_teams:
8018  case OMPD_simd:
8019  case OMPD_for:
8020  case OMPD_for_simd:
8021  case OMPD_sections:
8022  case OMPD_section:
8023  case OMPD_single:
8024  case OMPD_master:
8025  case OMPD_critical:
8026  case OMPD_taskgroup:
8027  case OMPD_distribute:
8028  case OMPD_ordered:
8029  case OMPD_atomic:
8030  case OMPD_distribute_simd:
8031  case OMPD_teams_distribute:
8032  case OMPD_teams_distribute_simd:
8033  llvm_unreachable("Unexpected OpenMP directive with if-clause");
8034  case OMPD_unknown:
8035  llvm_unreachable("Unknown OpenMP directive");
8036  }
8037  break;
8038  case OMPC_num_threads:
8039  switch (DKind) {
8040  case OMPD_target_parallel:
8041  case OMPD_target_parallel_for:
8042  case OMPD_target_parallel_for_simd:
8043  CaptureRegion = OMPD_target;
8044  break;
8045  case OMPD_teams_distribute_parallel_for:
8046  case OMPD_teams_distribute_parallel_for_simd:
8047  case OMPD_target_teams_distribute_parallel_for:
8048  case OMPD_target_teams_distribute_parallel_for_simd:
8049  CaptureRegion = OMPD_teams;
8050  break;
8051  case OMPD_parallel:
8052  case OMPD_parallel_sections:
8053  case OMPD_parallel_for:
8054  case OMPD_parallel_for_simd:
8055  case OMPD_distribute_parallel_for:
8056  case OMPD_distribute_parallel_for_simd:
8057  // Do not capture num_threads-clause expressions.
8058  break;
8059  case OMPD_target_data:
8060  case OMPD_target_enter_data:
8061  case OMPD_target_exit_data:
8062  case OMPD_target_update:
8063  case OMPD_target:
8064  case OMPD_target_simd:
8065  case OMPD_target_teams:
8066  case OMPD_target_teams_distribute:
8067  case OMPD_target_teams_distribute_simd:
8068  case OMPD_cancel:
8069  case OMPD_task:
8070  case OMPD_taskloop:
8071  case OMPD_taskloop_simd:
8072  case OMPD_threadprivate:
8073  case OMPD_taskyield:
8074  case OMPD_barrier:
8075  case OMPD_taskwait:
8076  case OMPD_cancellation_point:
8077  case OMPD_flush:
8078  case OMPD_declare_reduction:
8079  case OMPD_declare_simd:
8080  case OMPD_declare_target:
8081  case OMPD_end_declare_target:
8082  case OMPD_teams:
8083  case OMPD_simd:
8084  case OMPD_for:
8085  case OMPD_for_simd:
8086  case OMPD_sections:
8087  case OMPD_section:
8088  case OMPD_single:
8089  case OMPD_master:
8090  case OMPD_critical:
8091  case OMPD_taskgroup:
8092  case OMPD_distribute:
8093  case OMPD_ordered:
8094  case OMPD_atomic:
8095  case OMPD_distribute_simd:
8096  case OMPD_teams_distribute:
8097  case OMPD_teams_distribute_simd:
8098  llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
8099  case OMPD_unknown:
8100  llvm_unreachable("Unknown OpenMP directive");
8101  }
8102  break;
8103  case OMPC_num_teams:
8104  switch (DKind) {
8105  case OMPD_target_teams:
8106  case OMPD_target_teams_distribute:
8107  case OMPD_target_teams_distribute_simd:
8108  case OMPD_target_teams_distribute_parallel_for:
8109  case OMPD_target_teams_distribute_parallel_for_simd:
8110  CaptureRegion = OMPD_target;
8111  break;
8112  case OMPD_teams_distribute_parallel_for:
8113  case OMPD_teams_distribute_parallel_for_simd:
8114  case OMPD_teams:
8115  case OMPD_teams_distribute:
8116  case OMPD_teams_distribute_simd:
8117  // Do not capture num_teams-clause expressions.
8118  break;
8119  case OMPD_distribute_parallel_for:
8120  case OMPD_distribute_parallel_for_simd:
8121  case OMPD_task:
8122  case OMPD_taskloop:
8123  case OMPD_taskloop_simd:
8124  case OMPD_target_data:
8125  case OMPD_target_enter_data:
8126  case OMPD_target_exit_data:
8127  case OMPD_target_update:
8128  case OMPD_cancel:
8129  case OMPD_parallel:
8130  case OMPD_parallel_sections:
8131  case OMPD_parallel_for:
8132  case OMPD_parallel_for_simd:
8133  case OMPD_target:
8134  case OMPD_target_simd:
8135  case OMPD_target_parallel:
8136  case OMPD_target_parallel_for:
8137  case OMPD_target_parallel_for_simd:
8138  case OMPD_threadprivate:
8139  case OMPD_taskyield:
8140  case OMPD_barrier:
8141  case OMPD_taskwait:
8142  case OMPD_cancellation_point:
8143  case OMPD_flush:
8144  case OMPD_declare_reduction:
8145  case OMPD_declare_simd:
8146  case OMPD_declare_target:
8147  case OMPD_end_declare_target:
8148  case OMPD_simd:
8149  case OMPD_for:
8150  case OMPD_for_simd:
8151  case OMPD_sections:
8152  case OMPD_section:
8153  case OMPD_single:
8154  case OMPD_master:
8155  case OMPD_critical:
8156  case OMPD_taskgroup:
8157  case OMPD_distribute:
8158  case OMPD_ordered:
8159  case OMPD_atomic:
8160  case OMPD_distribute_simd:
8161  llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
8162  case OMPD_unknown:
8163  llvm_unreachable("Unknown OpenMP directive");
8164  }
8165  break;
8166  case OMPC_thread_limit:
8167  switch (DKind) {
8168  case OMPD_target_teams:
8169  case OMPD_target_teams_distribute:
8170  case OMPD_target_teams_distribute_simd:
8171  case OMPD_target_teams_distribute_parallel_for:
8172  case OMPD_target_teams_distribute_parallel_for_simd:
8173  CaptureRegion = OMPD_target;
8174  break;
8175  case OMPD_teams_distribute_parallel_for:
8176  case OMPD_teams_distribute_parallel_for_simd:
8177  case OMPD_teams:
8178  case OMPD_teams_distribute:
8179  case OMPD_teams_distribute_simd:
8180  // Do not capture thread_limit-clause expressions.
8181  break;
8182  case OMPD_distribute_parallel_for:
8183  case OMPD_distribute_parallel_for_simd:
8184  case OMPD_task:
8185  case OMPD_taskloop:
8186  case OMPD_taskloop_simd:
8187  case OMPD_target_data:
8188  case OMPD_target_enter_data:
8189  case OMPD_target_exit_data:
8190  case OMPD_target_update:
8191  case OMPD_cancel:
8192  case OMPD_parallel:
8193  case OMPD_parallel_sections:
8194  case OMPD_parallel_for:
8195  case OMPD_parallel_for_simd:
8196  case OMPD_target:
8197  case OMPD_target_simd:
8198  case OMPD_target_parallel:
8199  case OMPD_target_parallel_for:
8200  case OMPD_target_parallel_for_simd:
8201  case OMPD_threadprivate:
8202  case OMPD_taskyield:
8203  case OMPD_barrier:
8204  case OMPD_taskwait:
8205  case OMPD_cancellation_point:
8206  case OMPD_flush:
8207  case OMPD_declare_reduction:
8208  case OMPD_declare_simd:
8209  case OMPD_declare_target:
8210  case OMPD_end_declare_target:
8211  case OMPD_simd:
8212  case OMPD_for:
8213  case OMPD_for_simd:
8214  case OMPD_sections:
8215  case OMPD_section:
8216  case OMPD_single:
8217  case OMPD_master:
8218  case OMPD_critical:
8219  case OMPD_taskgroup:
8220  case OMPD_distribute:
8221  case OMPD_ordered:
8222  case OMPD_atomic:
8223  case OMPD_distribute_simd:
8224  llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
8225  case OMPD_unknown:
8226  llvm_unreachable("Unknown OpenMP directive");
8227  }
8228  break;
8229  case OMPC_schedule:
8230  switch (DKind) {
8231  case OMPD_parallel_for:
8232  case OMPD_parallel_for_simd:
8233  case OMPD_distribute_parallel_for:
8234  case OMPD_distribute_parallel_for_simd:
8235  case OMPD_teams_distribute_parallel_for:
8236  case OMPD_teams_distribute_parallel_for_simd:
8237  case OMPD_target_parallel_for:
8238  case OMPD_target_parallel_for_simd:
8239  case OMPD_target_teams_distribute_parallel_for:
8240  case OMPD_target_teams_distribute_parallel_for_simd:
8241  CaptureRegion = OMPD_parallel;
8242  break;
8243  case OMPD_for:
8244  case OMPD_for_simd:
8245  // Do not capture schedule-clause expressions.
8246  break;
8247  case OMPD_task:
8248  case OMPD_taskloop:
8249  case OMPD_taskloop_simd:
8250  case OMPD_target_data:
8251  case OMPD_target_enter_data:
8252  case OMPD_target_exit_data:
8253  case OMPD_target_update:
8254  case OMPD_teams:
8255  case OMPD_teams_distribute:
8256  case OMPD_teams_distribute_simd:
8257  case OMPD_target_teams_distribute:
8258  case OMPD_target_teams_distribute_simd:
8259  case OMPD_target:
8260  case OMPD_target_simd:
8261  case OMPD_target_parallel:
8262  case OMPD_cancel:
8263  case OMPD_parallel:
8264  case OMPD_parallel_sections:
8265  case OMPD_threadprivate:
8266  case OMPD_taskyield:
8267  case OMPD_barrier:
8268  case OMPD_taskwait:
8269  case OMPD_cancellation_point:
8270  case OMPD_flush:
8271  case OMPD_declare_reduction:
8272  case OMPD_declare_simd:
8273  case OMPD_declare_target:
8274  case OMPD_end_declare_target:
8275  case OMPD_simd:
8276  case OMPD_sections:
8277  case OMPD_section:
8278  case OMPD_single:
8279  case OMPD_master:
8280  case OMPD_critical:
8281  case OMPD_taskgroup:
8282  case OMPD_distribute:
8283  case OMPD_ordered:
8284  case OMPD_atomic:
8285  case OMPD_distribute_simd:
8286  case OMPD_target_teams:
8287  llvm_unreachable("Unexpected OpenMP directive with schedule clause");
8288  case OMPD_unknown:
8289  llvm_unreachable("Unknown OpenMP directive");
8290  }
8291  break;
8292  case OMPC_dist_schedule:
8293  switch (DKind) {
8294  case OMPD_teams_distribute_parallel_for:
8295  case OMPD_teams_distribute_parallel_for_simd:
8296  case OMPD_teams_distribute:
8297  case OMPD_teams_distribute_simd:
8298  case OMPD_target_teams_distribute_parallel_for:
8299  case OMPD_target_teams_distribute_parallel_for_simd:
8300  case OMPD_target_teams_distribute:
8301  case OMPD_target_teams_distribute_simd:
8302  CaptureRegion = OMPD_teams;
8303  break;
8304  case OMPD_distribute_parallel_for:
8305  case OMPD_distribute_parallel_for_simd:
8306  case OMPD_distribute:
8307  case OMPD_distribute_simd:
8308  // Do not capture thread_limit-clause expressions.
8309  break;
8310  case OMPD_parallel_for:
8311  case OMPD_parallel_for_simd:
8312  case OMPD_target_parallel_for_simd:
8313  case OMPD_target_parallel_for:
8314  case OMPD_task:
8315  case OMPD_taskloop:
8316  case OMPD_taskloop_simd:
8317  case OMPD_target_data:
8318  case OMPD_target_enter_data:
8319  case OMPD_target_exit_data:
8320  case OMPD_target_update:
8321  case OMPD_teams:
8322  case OMPD_target:
8323  case OMPD_target_simd:
8324  case OMPD_target_parallel:
8325  case OMPD_cancel:
8326  case OMPD_parallel:
8327  case OMPD_parallel_sections:
8328  case OMPD_threadprivate:
8329  case OMPD_taskyield:
8330  case OMPD_barrier:
8331  case OMPD_taskwait:
8332  case OMPD_cancellation_point:
8333  case OMPD_flush:
8334  case OMPD_declare_reduction:
8335  case OMPD_declare_simd:
8336  case OMPD_declare_target:
8337  case OMPD_end_declare_target:
8338  case OMPD_simd:
8339  case OMPD_for:
8340  case OMPD_for_simd:
8341  case OMPD_sections:
8342  case OMPD_section:
8343  case OMPD_single:
8344  case OMPD_master:
8345  case OMPD_critical:
8346  case OMPD_taskgroup:
8347  case OMPD_ordered:
8348  case OMPD_atomic:
8349  case OMPD_target_teams:
8350  llvm_unreachable("Unexpected OpenMP directive with schedule clause");
8351  case OMPD_unknown:
8352  llvm_unreachable("Unknown OpenMP directive");
8353  }
8354  break;
8355  case OMPC_device:
8356  switch (DKind) {
8357  case OMPD_target_update:
8358  case OMPD_target_enter_data:
8359  case OMPD_target_exit_data:
8360  case OMPD_target:
8361  case OMPD_target_simd:
8362  case OMPD_target_teams:
8363  case OMPD_target_parallel:
8364  case OMPD_target_teams_distribute:
8365  case OMPD_target_teams_distribute_simd:
8366  case OMPD_target_parallel_for:
8367  case OMPD_target_parallel_for_simd:
8368  case OMPD_target_teams_distribute_parallel_for:
8369  case OMPD_target_teams_distribute_parallel_for_simd:
8370  CaptureRegion = OMPD_task;
8371  break;
8372  case OMPD_target_data:
8373  // Do not capture device-clause expressions.
8374  break;
8375  case OMPD_teams_distribute_parallel_for:
8376  case OMPD_teams_distribute_parallel_for_simd:
8377  case OMPD_teams:
8378  case OMPD_teams_distribute:
8379  case OMPD_teams_distribute_simd:
8380  case OMPD_distribute_parallel_for:
8381  case OMPD_distribute_parallel_for_simd:
8382  case OMPD_task:
8383  case OMPD_taskloop:
8384  case OMPD_taskloop_simd:
8385  case OMPD_cancel:
8386  case OMPD_parallel:
8387  case OMPD_parallel_sections:
8388  case OMPD_parallel_for:
8389  case OMPD_parallel_for_simd:
8390  case OMPD_threadprivate:
8391  case OMPD_taskyield:
8392  case OMPD_barrier:
8393  case OMPD_taskwait:
8394  case OMPD_cancellation_point:
8395  case OMPD_flush:
8396  case OMPD_declare_reduction:
8397  case OMPD_declare_simd:
8398  case OMPD_declare_target:
8399  case OMPD_end_declare_target:
8400  case OMPD_simd:
8401  case OMPD_for:
8402  case OMPD_for_simd:
8403  case OMPD_sections:
8404  case OMPD_section:
8405  case OMPD_single:
8406  case OMPD_master:
8407  case OMPD_critical:
8408  case OMPD_taskgroup:
8409  case OMPD_distribute:
8410  case OMPD_ordered:
8411  case OMPD_atomic:
8412  case OMPD_distribute_simd:
8413  llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
8414  case OMPD_unknown:
8415  llvm_unreachable("Unknown OpenMP directive");
8416  }
8417  break;
8418  case OMPC_firstprivate:
8419  case OMPC_lastprivate:
8420  case OMPC_reduction:
8421  case OMPC_task_reduction:
8422  case OMPC_in_reduction:
8423  case OMPC_linear:
8424  case OMPC_default:
8425  case OMPC_proc_bind:
8426  case OMPC_final:
8427  case OMPC_safelen:
8428  case OMPC_simdlen:
8429  case OMPC_collapse:
8430  case OMPC_private:
8431  case OMPC_shared:
8432  case OMPC_aligned:
8433  case OMPC_copyin:
8434  case OMPC_copyprivate:
8435  case OMPC_ordered:
8436  case OMPC_nowait:
8437  case OMPC_untied:
8438  case OMPC_mergeable:
8439  case OMPC_threadprivate:
8440  case OMPC_flush:
8441  case OMPC_read:
8442  case OMPC_write:
8443  case OMPC_update:
8444  case OMPC_capture:
8445  case OMPC_seq_cst:
8446  case OMPC_depend:
8447  case OMPC_threads:
8448  case OMPC_simd:
8449  case OMPC_map:
8450  case OMPC_priority:
8451  case OMPC_grainsize:
8452  case OMPC_nogroup:
8453  case OMPC_num_tasks:
8454  case OMPC_hint:
8455  case OMPC_defaultmap:
8456  case OMPC_unknown:
8457  case OMPC_uniform:
8458  case OMPC_to:
8459  case OMPC_from:
8460  case OMPC_use_device_ptr:
8461  case OMPC_is_device_ptr:
8462  llvm_unreachable("Unexpected OpenMP clause.");
8463  }
8464  return CaptureRegion;
8465 }
8466 
8468  Expr *Condition, SourceLocation StartLoc,
8469  SourceLocation LParenLoc,
8470  SourceLocation NameModifierLoc,
8472  SourceLocation EndLoc) {
8473  Expr *ValExpr = Condition;
8474  Stmt *HelperValStmt = nullptr;
8475  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
8476  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
8477  !Condition->isInstantiationDependent() &&
8478  !Condition->containsUnexpandedParameterPack()) {
8479  ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
8480  if (Val.isInvalid())
8481  return nullptr;
8482 
8483  ValExpr = Val.get();
8484 
8485  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
8486  CaptureRegion =
8487  getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier);
8488  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
8489  ValExpr = MakeFullExpr(ValExpr).get();
8490  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
8491  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
8492  HelperValStmt = buildPreInits(Context, Captures);
8493  }
8494  }
8495 
8496  return new (Context)
8497  OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
8498  LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
8499 }
8500 
8502  SourceLocation StartLoc,
8503  SourceLocation LParenLoc,
8504  SourceLocation EndLoc) {
8505  Expr *ValExpr = Condition;
8506  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
8507  !Condition->isInstantiationDependent() &&
8508  !Condition->containsUnexpandedParameterPack()) {
8509  ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
8510  if (Val.isInvalid())
8511  return nullptr;
8512 
8513  ValExpr = MakeFullExpr(Val.get()).get();
8514  }
8515 
8516  return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc);
8517 }
8519  Expr *Op) {
8520  if (!Op)
8521  return ExprError();
8522 
8523  class IntConvertDiagnoser : public ICEConvertDiagnoser {
8524  public:
8525  IntConvertDiagnoser()
8526  : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
8527  SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
8528  QualType T) override {
8529  return S.Diag(Loc, diag::err_omp_not_integral) << T;
8530  }
8531  SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
8532  QualType T) override {
8533  return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
8534  }
8535  SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
8536  QualType T,
8537  QualType ConvTy) override {
8538  return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
8539  }
8540  SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
8541  QualType ConvTy) override {
8542  return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
8543  << ConvTy->isEnumeralType() << ConvTy;
8544  }
8545  SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
8546  QualType T) override {
8547  return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
8548  }
8549  SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
8550  QualType ConvTy) override {
8551  return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
8552  << ConvTy->isEnumeralType() << ConvTy;
8553  }
8554  SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
8555  QualType) override {
8556  llvm_unreachable("conversion functions are permitted");
8557  }
8558  } ConvertDiagnoser;
8559  return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
8560 }
8561 
8562 static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef,
8563  OpenMPClauseKind CKind,
8564  bool StrictlyPositive) {
8565  if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
8566  !ValExpr->isInstantiationDependent()) {
8567  SourceLocation Loc = ValExpr->getExprLoc();
8568  ExprResult Value =
8569  SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
8570  if (Value.isInvalid())
8571  return false;
8572 
8573  ValExpr = Value.get();
8574  // The expression must evaluate to a non-negative integer value.
8575  llvm::APSInt Result;
8576  if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) &&
8577  Result.isSigned() &&
8578  !((!StrictlyPositive && Result.isNonNegative()) ||
8579  (StrictlyPositive && Result.isStrictlyPositive()))) {
8580  SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
8581  << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
8582  << ValExpr->getSourceRange();
8583  return false;
8584  }
8585  }
8586  return true;
8587 }
8588 
8590  SourceLocation StartLoc,
8591  SourceLocation LParenLoc,
8592  SourceLocation EndLoc) {
8593  Expr *ValExpr = NumThreads;
8594  Stmt *HelperValStmt = nullptr;
8595 
8596  // OpenMP [2.5, Restrictions]
8597  // The num_threads expression must evaluate to a positive integer value.
8598  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
8599  /*StrictlyPositive=*/true))
8600  return nullptr;
8601 
8602  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
8603  OpenMPDirectiveKind CaptureRegion =
8604  getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads);
8605  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
8606  ValExpr = MakeFullExpr(ValExpr).get();
8607  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
8608  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
8609  HelperValStmt = buildPreInits(Context, Captures);
8610  }
8611 
8612  return new (Context) OMPNumThreadsClause(
8613  ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
8614 }
8615 
8616 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
8617  OpenMPClauseKind CKind,
8618  bool StrictlyPositive) {
8619  if (!E)
8620  return ExprError();
8621  if (E->isValueDependent() || E->isTypeDependent() ||
8623  return E;
8624  llvm::APSInt Result;
8625  ExprResult ICE = VerifyIntegerConstantExpression(E, &Result);
8626  if (ICE.isInvalid())
8627  return ExprError();
8628  if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
8629  (!StrictlyPositive && !Result.isNonNegative())) {
8630  Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
8631  << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
8632  << E->getSourceRange();
8633  return ExprError();
8634  }
8635  if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
8636  Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
8637  << E->getSourceRange();
8638  return ExprError();
8639  }
8640  if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
8641  DSAStack->setAssociatedLoops(Result.getExtValue());
8642  else if (CKind == OMPC_ordered)
8643  DSAStack->setAssociatedLoops(Result.getExtValue());
8644  return ICE;
8645 }
8646 
8648  SourceLocation LParenLoc,
8649  SourceLocation EndLoc) {
8650  // OpenMP [2.8.1, simd construct, Description]
8651  // The parameter of the safelen clause must be a constant
8652  // positive integer expression.
8653  ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
8654  if (Safelen.isInvalid())
8655  return nullptr;
8656  return new (Context)
8657  OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
8658 }
8659 
8661  SourceLocation LParenLoc,
8662  SourceLocation EndLoc) {
8663  // OpenMP [2.8.1, simd construct, Description]
8664  // The parameter of the simdlen clause must be a constant
8665  // positive integer expression.
8666  ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
8667  if (Simdlen.isInvalid())
8668  return nullptr;
8669  return new (Context)
8670  OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
8671 }
8672 
8674  SourceLocation StartLoc,
8675  SourceLocation LParenLoc,
8676  SourceLocation EndLoc) {
8677  // OpenMP [2.7.1, loop construct, Description]
8678  // OpenMP [2.8.1, simd construct, Description]
8679  // OpenMP [2.9.6, distribute construct, Description]
8680  // The parameter of the collapse clause must be a constant
8681  // positive integer expression.
8682  ExprResult NumForLoopsResult =
8683  VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
8684  if (NumForLoopsResult.isInvalid())
8685  return nullptr;
8686  return new (Context)
8687  OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
8688 }
8689 
8691  SourceLocation EndLoc,
8692  SourceLocation LParenLoc,
8693  Expr *NumForLoops) {
8694  // OpenMP [2.7.1, loop construct, Description]
8695  // OpenMP [2.8.1, simd construct, Description]
8696  // OpenMP [2.9.6, distribute construct, Description]
8697  // The parameter of the ordered clause must be a constant
8698  // positive integer expression if any.
8699  if (NumForLoops && LParenLoc.isValid()) {
8700  ExprResult NumForLoopsResult =
8701  VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
8702  if (NumForLoopsResult.isInvalid())
8703  return nullptr;
8704  NumForLoops = NumForLoopsResult.get();
8705  } else {
8706  NumForLoops = nullptr;
8707  }
8708  auto *Clause = OMPOrderedClause::Create(
8709  Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0,
8710  StartLoc, LParenLoc, EndLoc);
8711  DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
8712  return Clause;
8713 }
8714 
8716  OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
8717  SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
8718  OMPClause *Res = nullptr;
8719  switch (Kind) {
8720  case OMPC_default:
8721  Res =
8722  ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument),
8723  ArgumentLoc, StartLoc, LParenLoc, EndLoc);
8724  break;
8725  case OMPC_proc_bind:
8726  Res = ActOnOpenMPProcBindClause(
8727  static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc,
8728  LParenLoc, EndLoc);
8729  break;
8730  case OMPC_if:
8731  case OMPC_final:
8732  case OMPC_num_threads:
8733  case OMPC_safelen:
8734  case OMPC_simdlen:
8735  case OMPC_collapse:
8736  case OMPC_schedule:
8737  case OMPC_private:
8738  case OMPC_firstprivate:
8739  case OMPC_lastprivate:
8740  case OMPC_shared:
8741  case OMPC_reduction:
8742  case OMPC_task_reduction:
8743  case OMPC_in_reduction:
8744  case OMPC_linear:
8745  case OMPC_aligned:
8746  case OMPC_copyin:
8747  case OMPC_copyprivate:
8748  case OMPC_ordered:
8749  case OMPC_nowait:
8750  case OMPC_untied:
8751  case OMPC_mergeable:
8752  case OMPC_threadprivate:
8753  case OMPC_flush:
8754  case OMPC_read:
8755  case OMPC_write:
8756  case OMPC_update:
8757  case OMPC_capture:
8758  case OMPC_seq_cst:
8759  case OMPC_depend:
8760  case OMPC_device:
8761  case OMPC_threads:
8762  case OMPC_simd:
8763  case OMPC_map:
8764  case OMPC_num_teams:
8765  case OMPC_thread_limit:
8766  case OMPC_priority:
8767  case OMPC_grainsize:
8768  case OMPC_nogroup:
8769  case OMPC_num_tasks:
8770  case OMPC_hint:
8771  case OMPC_dist_schedule:
8772  case OMPC_defaultmap:
8773  case OMPC_unknown:
8774  case OMPC_uniform:
8775  case OMPC_to:
8776  case OMPC_from:
8777  case OMPC_use_device_ptr:
8778  case OMPC_is_device_ptr:
8779  llvm_unreachable("Clause is not allowed.");
8780  }
8781  return Res;
8782 }
8783 
8784 static std::string
8786  ArrayRef<unsigned> Exclude = llvm::None) {
8787  SmallString<256> Buffer;
8788  llvm::raw_svector_ostream Out(Buffer);
8789  unsigned Bound = Last >= 2 ? Last - 2 : 0;
8790  unsigned Skipped = Exclude.size();
8791  auto S = Exclude.begin(), E = Exclude.end();
8792  for (unsigned I = First; I < Last; ++I) {
8793  if (std::find(S, E, I) != E) {
8794  --Skipped;
8795  continue;
8796  }
8797  Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
8798  if (I == Bound - Skipped)
8799  Out << " or ";
8800  else if (I != Bound + 1 - Skipped)
8801  Out << ", ";
8802  }
8803  return Out.str();
8804 }
8805 
8807  SourceLocation KindKwLoc,
8808  SourceLocation StartLoc,
8809  SourceLocation LParenLoc,
8810  SourceLocation EndLoc) {
8811  if (Kind == OMPC_DEFAULT_unknown) {
8812  static_assert(OMPC_DEFAULT_unknown > 0,
8813  "OMPC_DEFAULT_unknown not greater than 0");
8814  Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
8815  << getListOfPossibleValues(OMPC_default, /*First=*/0,
8816  /*Last=*/OMPC_DEFAULT_unknown)
8817  << getOpenMPClauseName(OMPC_default);
8818  return nullptr;
8819  }
8820  switch (Kind) {
8821  case OMPC_DEFAULT_none:
8822  DSAStack->setDefaultDSANone(KindKwLoc);
8823  break;
8824  case OMPC_DEFAULT_shared:
8825  DSAStack->setDefaultDSAShared(KindKwLoc);
8826  break;
8827  case OMPC_DEFAULT_unknown:
8828  llvm_unreachable("Clause kind is not allowed.");
8829  break;
8830  }
8831  return new (Context)
8832  OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
8833 }
8834 
8836  SourceLocation KindKwLoc,
8837  SourceLocation StartLoc,
8838  SourceLocation LParenLoc,
8839  SourceLocation EndLoc) {
8840  if (Kind == OMPC_PROC_BIND_unknown) {
8841  Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
8842  << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0,
8843  /*Last=*/OMPC_PROC_BIND_unknown)
8844  << getOpenMPClauseName(OMPC_proc_bind);
8845  return nullptr;
8846  }
8847  return new (Context)
8848  OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
8849 }
8850 
8853  SourceLocation StartLoc, SourceLocation LParenLoc,
8854  ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
8855  SourceLocation EndLoc) {
8856  OMPClause *Res = nullptr;
8857  switch (Kind) {
8858  case OMPC_schedule:
8859  enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
8860  assert(Argument.size() == NumberOfElements &&
8861  ArgumentLoc.size() == NumberOfElements);
8862  Res = ActOnOpenMPScheduleClause(
8863  static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
8864  static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
8865  static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
8866  StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
8867  ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
8868  break;
8869  case OMPC_if:
8870  assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
8871  Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
8872  Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
8873  DelimLoc, EndLoc);
8874  break;
8875  case OMPC_dist_schedule:
8876  Res = ActOnOpenMPDistScheduleClause(
8877  static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
8878  StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
8879  break;
8880  case OMPC_defaultmap:
8881  enum { Modifier, DefaultmapKind };
8882  Res = ActOnOpenMPDefaultmapClause(
8883  static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
8884  static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
8885  StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
8886  EndLoc);
8887  break;
8888  case OMPC_final:
8889  case OMPC_num_threads:
8890  case OMPC_safelen:
8891  case OMPC_simdlen:
8892  case OMPC_collapse:
8893  case OMPC_default:
8894  case OMPC_proc_bind:
8895  case OMPC_private:
8896  case OMPC_firstprivate:
8897  case OMPC_lastprivate:
8898  case OMPC_shared:
8899  case OMPC_reduction:
8900  case OMPC_task_reduction:
8901  case OMPC_in_reduction:
8902  case OMPC_linear:
8903  case OMPC_aligned:
8904  case OMPC_copyin:
8905  case OMPC_copyprivate:
8906  case OMPC_ordered:
8907  case OMPC_nowait:
8908  case OMPC_untied:
8909  case OMPC_mergeable:
8910  case OMPC_threadprivate:
8911  case OMPC_flush:
8912  case OMPC_read:
8913  case OMPC_write:
8914  case OMPC_update:
8915  case OMPC_capture:
8916  case OMPC_seq_cst:
8917  case OMPC_depend:
8918  case OMPC_device:
8919  case OMPC_threads:
8920  case OMPC_simd:
8921  case OMPC_map:
8922  case OMPC_num_teams:
8923  case OMPC_thread_limit:
8924  case OMPC_priority:
8925  case OMPC_grainsize:
8926  case OMPC_nogroup:
8927  case OMPC_num_tasks:
8928  case OMPC_hint:
8929  case OMPC_unknown:
8930  case OMPC_uniform:
8931  case OMPC_to:
8932  case OMPC_from:
8933  case OMPC_use_device_ptr:
8934  case OMPC_is_device_ptr:
8935  llvm_unreachable("Clause is not allowed.");
8936  }
8937  return Res;
8938 }
8939 
8942  SourceLocation M1Loc, SourceLocation M2Loc) {
8943  if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
8944  SmallVector<unsigned, 2> Excluded;
8946  Excluded.push_back(M2);
8947  if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
8948  Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
8949  if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
8950  Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
8951  S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
8952  << getListOfPossibleValues(OMPC_schedule,
8953  /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
8954  /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
8955  Excluded)
8956  << getOpenMPClauseName(OMPC_schedule);
8957  return true;
8958  }
8959  return false;
8960 }
8961 
8964  OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
8965  SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
8966  SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
8967  if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
8968  checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
8969  return nullptr;
8970  // OpenMP, 2.7.1, Loop Construct, Restrictions
8971  // Either the monotonic modifier or the nonmonotonic modifier can be specified
8972  // but not both.
8973  if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
8974  (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
8975  M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
8976  (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
8977  M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
8978  Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
8979  << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
8980  << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
8981  return nullptr;
8982  }
8983  if (Kind == OMPC_SCHEDULE_unknown) {
8984  std::string Values;
8985  if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
8986  unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
8987  Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
8988  /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
8989  Exclude);
8990  } else {
8991  Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
8992  /*Last=*/OMPC_SCHEDULE_unknown);
8993  }
8994  Diag(KindLoc, diag::err_omp_unexpected_clause_value)
8995  << Values << getOpenMPClauseName(OMPC_schedule);
8996  return nullptr;
8997  }
8998  // OpenMP, 2.7.1, Loop Construct, Restrictions
8999  // The nonmonotonic modifier can only be specified with schedule(dynamic) or
9000  // schedule(guided).
9001  if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
9002  M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
9003  Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
9004  Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
9005  diag::err_omp_schedule_nonmonotonic_static);
9006  return nullptr;
9007  }
9008  Expr *ValExpr = ChunkSize;
9009  Stmt *HelperValStmt = nullptr;
9010  if (ChunkSize) {
9011  if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
9012  !ChunkSize->isInstantiationDependent() &&
9013  !ChunkSize->containsUnexpandedParameterPack()) {
9014  SourceLocation ChunkSizeLoc = ChunkSize->getLocStart();
9015  ExprResult Val =
9016  PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
9017  if (Val.isInvalid())
9018  return nullptr;
9019 
9020  ValExpr = Val.get();
9021 
9022  // OpenMP [2.7.1, Restrictions]
9023  // chunk_size must be a loop invariant integer expression with a positive
9024  // value.
9025  llvm::APSInt Result;
9026  if (ValExpr->isIntegerConstantExpr(Result, Context)) {
9027  if (Result.isSigned() && !Result.isStrictlyPositive()) {
9028  Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
9029  << "schedule" << 1 << ChunkSize->getSourceRange();
9030  return nullptr;
9031  }
9033  DSAStack->getCurrentDirective(), OMPC_schedule) !=
9034  OMPD_unknown &&
9035  !CurContext->isDependentContext()) {
9036  ValExpr = MakeFullExpr(ValExpr).get();
9037  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
9038  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
9039  HelperValStmt = buildPreInits(Context, Captures);
9040  }
9041  }
9042  }
9043 
9044  return new (Context)
9045  OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
9046  ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
9047 }
9048 
9050  SourceLocation StartLoc,
9051  SourceLocation EndLoc) {
9052  OMPClause *Res = nullptr;
9053  switch (Kind) {
9054  case OMPC_ordered:
9055  Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
9056  break;
9057  case OMPC_nowait:
9058  Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
9059  break;
9060  case OMPC_untied:
9061  Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
9062  break;
9063  case OMPC_mergeable:
9064  Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
9065  break;
9066  case OMPC_read:
9067  Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
9068  break;
9069  case OMPC_write:
9070  Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
9071  break;
9072  case OMPC_update:
9073  Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
9074  break;
9075  case OMPC_capture:
9076  Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
9077  break;
9078  case OMPC_seq_cst:
9079  Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
9080  break;
9081  case OMPC_threads:
9082  Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
9083  break;
9084  case OMPC_simd:
9085  Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
9086  break;
9087  case OMPC_nogroup:
9088  Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
9089  break;
9090  case OMPC_if:
9091  case OMPC_final:
9092  case OMPC_num_threads:
9093  case OMPC_safelen:
9094  case OMPC_simdlen:
9095  case OMPC_collapse:
9096  case OMPC_schedule:
9097  case OMPC_private:
9098  case OMPC_firstprivate:
9099  case OMPC_lastprivate:
9100  case OMPC_shared:
9101  case OMPC_reduction:
9102  case OMPC_task_reduction:
9103  case OMPC_in_reduction:
9104  case OMPC_linear:
9105  case OMPC_aligned:
9106  case OMPC_copyin:
9107  case OMPC_copyprivate:
9108  case OMPC_default:
9109  case OMPC_proc_bind:
9110  case OMPC_threadprivate:
9111  case OMPC_flush:
9112  case OMPC_depend:
9113  case OMPC_device:
9114  case OMPC_map:
9115  case OMPC_num_teams:
9116  case OMPC_thread_limit:
9117  case OMPC_priority:
9118  case OMPC_grainsize:
9119  case OMPC_num_tasks:
9120  case OMPC_hint:
9121  case OMPC_dist_schedule:
9122  case OMPC_defaultmap:
9123  case OMPC_unknown:
9124  case OMPC_uniform:
9125  case OMPC_to:
9126  case OMPC_from:
9127  case OMPC_use_device_ptr:
9128  case OMPC_is_device_ptr:
9129  llvm_unreachable("Clause is not allowed.");
9130  }
9131  return Res;
9132 }
9133 
9135  SourceLocation EndLoc) {
9136  DSAStack->setNowaitRegion();
9137  return new (Context) OMPNowaitClause(StartLoc, EndLoc);
9138 }
9139 
9141  SourceLocation EndLoc) {
9142  return new (Context) OMPUntiedClause(StartLoc, EndLoc);
9143 }
9144 
9146  SourceLocation EndLoc) {
9147  return new (Context) OMPMergeableClause(StartLoc, EndLoc);
9148 }
9149 
9151  SourceLocation EndLoc) {
9152  return new (Context) OMPReadClause(StartLoc, EndLoc);
9153 }
9154 
9156  SourceLocation EndLoc) {
9157  return new (Context) OMPWriteClause(StartLoc, EndLoc);
9158 }
9159 
9161  SourceLocation EndLoc) {
9162  return new (Context) OMPUpdateClause(StartLoc, EndLoc);
9163 }
9164 
9166  SourceLocation EndLoc) {
9167  return new (Context) OMPCaptureClause(StartLoc, EndLoc);
9168 }
9169 
9171  SourceLocation EndLoc) {
9172  return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
9173 }
9174 
9176  SourceLocation EndLoc) {
9177  return new (Context) OMPThreadsClause(StartLoc, EndLoc);
9178 }
9179 
9181  SourceLocation EndLoc) {
9182  return new (Context) OMPSIMDClause(StartLoc, EndLoc);
9183 }
9184 
9186  SourceLocation EndLoc) {
9187  return new (Context) OMPNogroupClause(StartLoc, EndLoc);
9188 }
9189 
9191  OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr,
9193  SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
9194  const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind,
9195  OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier,
9196  OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
9197  SourceLocation DepLinMapLoc) {
9198  OMPClause *Res = nullptr;
9199  switch (Kind) {
9200  case OMPC_private:
9201  Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9202  break;
9203  case OMPC_firstprivate:
9204  Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9205  break;
9206  case OMPC_lastprivate:
9207  Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9208  break;
9209  case OMPC_shared:
9210  Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
9211  break;
9212  case OMPC_reduction:
9213  Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
9214  EndLoc, ReductionIdScopeSpec, ReductionId);
9215  break;
9216  case OMPC_task_reduction:
9217  Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
9218  EndLoc, ReductionIdScopeSpec,
9219  ReductionId);
9220  break;
9221  case OMPC_in_reduction:
9222  Res =
9223  ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
9224  EndLoc, ReductionIdScopeSpec, ReductionId);
9225  break;
9226  case OMPC_linear:
9227  Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc,
9228  LinKind, DepLinMapLoc, ColonLoc, EndLoc);
9229  break;
9230  case OMPC_aligned:
9231  Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc,
9232  ColonLoc, EndLoc);
9233  break;
9234  case OMPC_copyin:
9235  Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
9236  break;
9237  case OMPC_copyprivate:
9238  Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9239  break;
9240  case OMPC_flush:
9241  Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
9242  break;
9243  case OMPC_depend:
9244  Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList,
9245  StartLoc, LParenLoc, EndLoc);
9246  break;
9247  case OMPC_map:
9248  Res = ActOnOpenMPMapClause(MapTypeModifier, MapType, IsMapTypeImplicit,
9249  DepLinMapLoc, ColonLoc, VarList, StartLoc,
9250  LParenLoc, EndLoc);
9251  break;
9252  case OMPC_to:
9253  Res = ActOnOpenMPToClause(VarList, StartLoc, LParenLoc, EndLoc);
9254  break;
9255  case OMPC_from:
9256  Res = ActOnOpenMPFromClause(VarList, StartLoc, LParenLoc, EndLoc);
9257  break;
9258  case OMPC_use_device_ptr:
9259  Res = ActOnOpenMPUseDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc);
9260  break;
9261  case OMPC_is_device_ptr:
9262  Res = ActOnOpenMPIsDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc);
9263  break;
9264  case OMPC_if:
9265  case OMPC_final:
9266  case OMPC_num_threads:
9267  case OMPC_safelen:
9268  case OMPC_simdlen:
9269  case OMPC_collapse:
9270  case OMPC_default:
9271  case OMPC_proc_bind:
9272  case OMPC_schedule:
9273  case OMPC_ordered:
9274  case OMPC_nowait:
9275  case OMPC_untied:
9276  case OMPC_mergeable:
9277  case OMPC_threadprivate:
9278  case OMPC_read:
9279  case OMPC_write:
9280  case OMPC_update:
9281  case OMPC_capture:
9282  case OMPC_seq_cst:
9283  case OMPC_device:
9284  case OMPC_threads:
9285  case OMPC_simd:
9286  case OMPC_num_teams:
9287  case OMPC_thread_limit:
9288  case OMPC_priority:
9289  case OMPC_grainsize:
9290  case OMPC_nogroup:
9291  case OMPC_num_tasks:
9292  case OMPC_hint:
9293  case OMPC_dist_schedule:
9294  case OMPC_defaultmap:
9295  case OMPC_unknown:
9296  case OMPC_uniform:
9297  llvm_unreachable("Clause is not allowed.");
9298  }
9299  return Res;
9300 }
9301 
9303  ExprObjectKind OK, SourceLocation Loc) {
9304  ExprResult Res = BuildDeclRefExpr(
9305  Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
9306  if (!Res.isUsable())
9307  return ExprError();
9308  if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
9309  Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
9310  if (!Res.isUsable())
9311  return ExprError();
9312  }
9313  if (VK != VK_LValue && Res.get()->isGLValue()) {
9314  Res = DefaultLvalueConversion(Res.get());
9315  if (!Res.isUsable())
9316  return ExprError();
9317  }
9318  return Res;
9319 }
9320 
9321 static std::pair<ValueDecl *, bool>
9323  SourceRange &ERange, bool AllowArraySection = false) {
9324  if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
9326  return std::make_pair(nullptr, true);
9327 
9328  // OpenMP [3.1, C/C++]
9329  // A list item is a variable name.
9330  // OpenMP [2.9.3.3, Restrictions, p.1]
9331  // A variable that is part of another variable (as an array or
9332  // structure element) cannot appear in a private clause.
9333  RefExpr = RefExpr->IgnoreParens();
9334  enum {
9335  NoArrayExpr = -1,
9336  ArraySubscript = 0,
9337  OMPArraySection = 1
9338  } IsArrayExpr = NoArrayExpr;
9339  if (AllowArraySection) {
9340  if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
9341  Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
9342  while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
9343  Base = TempASE->getBase()->IgnoreParenImpCasts();
9344  RefExpr = Base;
9345  IsArrayExpr = ArraySubscript;
9346  } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
9347  Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
9348  while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
9349  Base = TempOASE->getBase()->IgnoreParenImpCasts();
9350  while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
9351  Base = TempASE->getBase()->IgnoreParenImpCasts();
9352  RefExpr = Base;
9353  IsArrayExpr = OMPArraySection;
9354  }
9355  }
9356  ELoc = RefExpr->getExprLoc();
9357  ERange = RefExpr->getSourceRange();
9358  RefExpr = RefExpr->IgnoreParenImpCasts();
9359  auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
9360  auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
9361  if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
9362  (S.getCurrentThisType().isNull() || !ME ||
9363  !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
9364  !isa<FieldDecl>(ME->getMemberDecl()))) {
9365  if (IsArrayExpr != NoArrayExpr) {
9366  S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
9367  << ERange;
9368  } else {
9369  S.Diag(ELoc,
9370  AllowArraySection
9371  ? diag::err_omp_expected_var_name_member_expr_or_array_item
9372  : diag::err_omp_expected_var_name_member_expr)
9373  << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
9374  }
9375  return std::make_pair(nullptr, false);
9376  }
9377  return std::make_pair(
9378  getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
9379 }
9380 
9382  SourceLocation StartLoc,
9383  SourceLocation LParenLoc,
9384  SourceLocation EndLoc) {
9386  SmallVector<Expr *, 8> PrivateCopies;
9387  for (Expr *RefExpr : VarList) {
9388  assert(RefExpr && "NULL expr in OpenMP private clause.");
9389  SourceLocation ELoc;
9390  SourceRange ERange;
9391  Expr *SimpleRefExpr = RefExpr;
9392  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
9393  if (Res.second) {
9394  // It will be analyzed later.
9395  Vars.push_back(RefExpr);
9396  PrivateCopies.push_back(nullptr);
9397  }
9398  ValueDecl *D = Res.first;
9399  if (!D)
9400  continue;
9401 
9402  QualType Type = D->getType();
9403  auto *VD = dyn_cast<VarDecl>(D);
9404 
9405  // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
9406  // A variable that appears in a private clause must not have an incomplete
9407  // type or a reference type.
9408  if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
9409  continue;
9410  Type = Type.getNonReferenceType();
9411 
9412  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
9413  // in a Construct]
9414  // Variables with the predetermined data-sharing attributes may not be
9415  // listed in data-sharing attributes clauses, except for the cases
9416  // listed below. For these exceptions only, listing a predetermined
9417  // variable in a data-sharing attribute clause is allowed and overrides
9418  // the variable's predetermined data-sharing attributes.
9419  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
9420  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
9421  Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
9422  << getOpenMPClauseName(OMPC_private);
9423  reportOriginalDsa(*this, DSAStack, D, DVar);
9424  continue;
9425  }
9426 
9427  OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
9428  // Variably modified types are not supported for tasks.
9429  if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
9430  isOpenMPTaskingDirective(CurrDir)) {
9431  Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
9432  << getOpenMPClauseName(OMPC_private) << Type
9433  << getOpenMPDirectiveName(CurrDir);
9434  bool IsDecl =
9435  !VD ||
9436  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
9437  Diag(D->getLocation(),
9438  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9439  << D;
9440  continue;
9441  }
9442 
9443  // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
9444  // A list item cannot appear in both a map clause and a data-sharing
9445  // attribute clause on the same construct
9446  if (isOpenMPTargetExecutionDirective(CurrDir)) {
9447  OpenMPClauseKind ConflictKind;
9448  if (DSAStack->checkMappableExprComponentListsForDecl(
9449  VD, /*CurrentRegionOnly=*/true,
9451  OpenMPClauseKind WhereFoundClauseKind) -> bool {
9452  ConflictKind = WhereFoundClauseKind;
9453  return true;
9454  })) {
9455  Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
9456  << getOpenMPClauseName(OMPC_private)
9457  << getOpenMPClauseName(ConflictKind)
9458  << getOpenMPDirectiveName(CurrDir);
9459  reportOriginalDsa(*this, DSAStack, D, DVar);
9460  continue;
9461  }
9462  }
9463 
9464  // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
9465  // A variable of class type (or array thereof) that appears in a private
9466  // clause requires an accessible, unambiguous default constructor for the
9467  // class type.
9468  // Generate helper private variable and initialize it with the default
9469  // value. The address of the original variable is replaced by the address of
9470  // the new private variable in CodeGen. This new variable is not added to
9471  // IdResolver, so the code in the OpenMP region uses original variable for
9472  // proper diagnostics.
9473  Type = Type.getUnqualifiedType();
9474  VarDecl *VDPrivate =
9475  buildVarDecl(*this, ELoc, Type, D->getName(),
9476  D->hasAttrs() ? &D->getAttrs() : nullptr,
9477  VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
9478  ActOnUninitializedDecl(VDPrivate);
9479  if (VDPrivate->isInvalidDecl())
9480  continue;
9481  DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
9482  *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
9483 
9484  DeclRefExpr *Ref = nullptr;
9485  if (!VD && !CurContext->isDependentContext())
9486  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
9487  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
9488  Vars.push_back((VD || CurContext->isDependentContext())
9489  ? RefExpr->IgnoreParens()
9490  : Ref);
9491  PrivateCopies.push_back(VDPrivateRefExpr);
9492  }
9493 
9494  if (Vars.empty())
9495  return nullptr;
9496 
9497  return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
9498  PrivateCopies);
9499 }
9500 
9501 namespace {
9502 class DiagsUninitializedSeveretyRAII {
9503 private:
9504  DiagnosticsEngine &Diags;
9505  SourceLocation SavedLoc;
9506  bool IsIgnored = false;
9507 
9508 public:
9509  DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
9510  bool IsIgnored)
9511  : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
9512  if (!IsIgnored) {
9513  Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
9514  /*Map*/ diag::Severity::Ignored, Loc);
9515  }
9516  }
9517  ~DiagsUninitializedSeveretyRAII() {
9518  if (!IsIgnored)
9519  Diags.popMappings(SavedLoc);
9520  }
9521 };
9522 }
9523 
9525  SourceLocation StartLoc,
9526  SourceLocation LParenLoc,
9527  SourceLocation EndLoc) {
9529  SmallVector<Expr *, 8> PrivateCopies;
9531  SmallVector<Decl *, 4> ExprCaptures;
9532  bool IsImplicitClause =
9533  StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
9534  SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc();
9535 
9536  for (Expr *RefExpr : VarList) {
9537  assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
9538  SourceLocation ELoc;
9539  SourceRange ERange;
9540  Expr *SimpleRefExpr = RefExpr;
9541  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
9542  if (Res.second) {
9543  // It will be analyzed later.
9544  Vars.push_back(RefExpr);
9545  PrivateCopies.push_back(nullptr);
9546  Inits.push_back(nullptr);
9547  }
9548  ValueDecl *D = Res.first;
9549  if (!D)
9550  continue;
9551 
9552  ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
9553  QualType Type = D->getType();
9554  auto *VD = dyn_cast<VarDecl>(D);
9555 
9556  // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
9557  // A variable that appears in a private clause must not have an incomplete
9558  // type or a reference type.
9559  if (RequireCompleteType(ELoc, Type,
9560  diag::err_omp_firstprivate_incomplete_type))
9561  continue;
9562  Type = Type.getNonReferenceType();
9563 
9564  // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
9565  // A variable of class type (or array thereof) that appears in a private
9566  // clause requires an accessible, unambiguous copy constructor for the
9567  // class type.
9568  QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
9569 
9570  // If an implicit firstprivate variable found it was checked already.
9571  DSAStackTy::DSAVarData TopDVar;
9572  if (!IsImplicitClause) {
9573  DSAStackTy::DSAVarData DVar =
9574  DSAStack->getTopDSA(D, /*FromParent=*/false);
9575  TopDVar = DVar;
9576  OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
9577  bool IsConstant = ElemType.isConstant(Context);
9578  // OpenMP [2.4.13, Data-sharing Attribute Clauses]
9579  // A list item that specifies a given variable may not appear in more
9580  // than one clause on the same directive, except that a variable may be
9581  // specified in both firstprivate and lastprivate clauses.
9582  // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
9583  // A list item may appear in a firstprivate or lastprivate clause but not
9584  // both.
9585  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
9586  (isOpenMPDistributeDirective(CurrDir) ||
9587  DVar.CKind != OMPC_lastprivate) &&
9588  DVar.RefExpr) {
9589  Diag(ELoc, diag::err_omp_wrong_dsa)
9590  << getOpenMPClauseName(DVar.CKind)
9591  << getOpenMPClauseName(OMPC_firstprivate);
9592  reportOriginalDsa(*this, DSAStack, D, DVar);
9593  continue;
9594  }
9595 
9596  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
9597  // in a Construct]
9598  // Variables with the predetermined data-sharing attributes may not be
9599  // listed in data-sharing attributes clauses, except for the cases
9600  // listed below. For these exceptions only, listing a predetermined
9601  // variable in a data-sharing attribute clause is allowed and overrides
9602  // the variable's predetermined data-sharing attributes.
9603  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
9604  // in a Construct, C/C++, p.2]
9605  // Variables with const-qualified type having no mutable member may be
9606  // listed in a firstprivate clause, even if they are static data members.
9607  if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
9608  DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
9609  Diag(ELoc, diag::err_omp_wrong_dsa)
9610  << getOpenMPClauseName(DVar.CKind)
9611  << getOpenMPClauseName(OMPC_firstprivate);
9612  reportOriginalDsa(*this, DSAStack, D, DVar);
9613  continue;
9614  }
9615 
9616  // OpenMP [2.9.3.4, Restrictions, p.2]
9617  // A list item that is private within a parallel region must not appear
9618  // in a firstprivate clause on a worksharing construct if any of the
9619  // worksharing regions arising from the worksharing construct ever bind
9620  // to any of the parallel regions arising from the parallel construct.
9621  // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
9622  // A list item that is private within a teams region must not appear in a
9623  // firstprivate clause on a distribute construct if any of the distribute
9624  // regions arising from the distribute construct ever bind to any of the
9625  // teams regions arising from the teams construct.
9626  // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
9627  // A list item that appears in a reduction clause of a teams construct
9628  // must not appear in a firstprivate clause on a distribute construct if
9629  // any of the distribute regions arising from the distribute construct
9630  // ever bind to any of the teams regions arising from the teams construct.
9631  if ((isOpenMPWorksharingDirective(CurrDir) ||
9632  isOpenMPDistributeDirective(CurrDir)) &&
9633  !isOpenMPParallelDirective(CurrDir) &&
9634  !isOpenMPTeamsDirective(CurrDir)) {
9635  DVar = DSAStack->getImplicitDSA(D, true);
9636  if (DVar.CKind != OMPC_shared &&
9637  (isOpenMPParallelDirective(DVar.DKind) ||
9638  isOpenMPTeamsDirective(DVar.DKind) ||
9639  DVar.DKind == OMPD_unknown)) {
9640  Diag(ELoc, diag::err_omp_required_access)
9641  << getOpenMPClauseName(OMPC_firstprivate)
9642  << getOpenMPClauseName(OMPC_shared);
9643  reportOriginalDsa(*this, DSAStack, D, DVar);
9644  continue;
9645  }
9646  }
9647  // OpenMP [2.9.3.4, Restrictions, p.3]
9648  // A list item that appears in a reduction clause of a parallel construct
9649  // must not appear in a firstprivate clause on a worksharing or task
9650  // construct if any of the worksharing or task regions arising from the
9651  // worksharing or task construct ever bind to any of the parallel regions
9652  // arising from the parallel construct.
9653  // OpenMP [2.9.3.4, Restrictions, p.4]
9654  // A list item that appears in a reduction clause in worksharing
9655  // construct must not appear in a firstprivate clause in a task construct
9656  // encountered during execution of any of the worksharing regions arising
9657  // from the worksharing construct.
9658  if (isOpenMPTaskingDirective(CurrDir)) {
9659  DVar = DSAStack->hasInnermostDSA(
9660  D, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
9661  [](OpenMPDirectiveKind K) {
9662  return isOpenMPParallelDirective(K) ||
9665  },
9666  /*FromParent=*/true);
9667  if (DVar.CKind == OMPC_reduction &&
9668  (isOpenMPParallelDirective(DVar.DKind) ||
9669  isOpenMPWorksharingDirective(DVar.DKind) ||
9670  isOpenMPTeamsDirective(DVar.DKind))) {
9671  Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
9672  << getOpenMPDirectiveName(DVar.DKind);
9673  reportOriginalDsa(*this, DSAStack, D, DVar);
9674  continue;
9675  }
9676  }
9677 
9678  // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
9679  // A list item cannot appear in both a map clause and a data-sharing
9680  // attribute clause on the same construct
9681  if (isOpenMPTargetExecutionDirective(CurrDir)) {
9682  OpenMPClauseKind ConflictKind;
9683  if (DSAStack->checkMappableExprComponentListsForDecl(
9684  VD, /*CurrentRegionOnly=*/true,
9685  [&ConflictKind](
9687  OpenMPClauseKind WhereFoundClauseKind) {
9688  ConflictKind = WhereFoundClauseKind;
9689  return true;
9690  })) {
9691  Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
9692  << getOpenMPClauseName(OMPC_firstprivate)
9693  << getOpenMPClauseName(ConflictKind)
9694  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
9695  reportOriginalDsa(*this, DSAStack, D, DVar);
9696  continue;
9697  }
9698  }
9699  }
9700 
9701  // Variably modified types are not supported for tasks.
9702  if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
9703  isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
9704  Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
9705  << getOpenMPClauseName(OMPC_firstprivate) << Type
9706  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
9707  bool IsDecl =
9708  !VD ||
9709  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
9710  Diag(D->getLocation(),
9711  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9712  << D;
9713  continue;
9714  }
9715 
9716  Type = Type.getUnqualifiedType();
9717  VarDecl *VDPrivate =
9718  buildVarDecl(*this, ELoc, Type, D->getName(),
9719  D->hasAttrs() ? &D->getAttrs() : nullptr,
9720  VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
9721  // Generate helper private variable and initialize it with the value of the
9722  // original variable. The address of the original variable is replaced by
9723  // the address of the new private variable in the CodeGen. This new variable
9724  // is not added to IdResolver, so the code in the OpenMP region uses
9725  // original variable for proper diagnostics and variable capturing.
9726  Expr *VDInitRefExpr = nullptr;
9727  // For arrays generate initializer for single element and replace it by the
9728  // original array element in CodeGen.
9729  if (Type->isArrayType()) {
9730  VarDecl *VDInit =
9731  buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
9732  VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
9733  Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
9734  ElemType = ElemType.getUnqualifiedType();
9735  VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
9736  ".firstprivate.temp");
9737  InitializedEntity Entity =
9740 
9741  InitializationSequence InitSeq(*this, Entity, Kind, Init);
9742  ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
9743  if (Result.isInvalid())
9744  VDPrivate->setInvalidDecl();
9745  else
9746  VDPrivate->setInit(Result.getAs<Expr>());
9747  // Remove temp variable declaration.
9748  Context.Deallocate(VDInitTemp);
9749  } else {
9750  VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
9751  ".firstprivate.temp");
9752  VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
9753  RefExpr->getExprLoc());
9754  AddInitializerToDecl(VDPrivate,
9755  DefaultLvalueConversion(VDInitRefExpr).get(),
9756  /*DirectInit=*/false);
9757  }
9758  if (VDPrivate->isInvalidDecl()) {
9759  if (IsImplicitClause) {
9760  Diag(RefExpr->getExprLoc(),
9761  diag::note_omp_task_predetermined_firstprivate_here);
9762  }
9763  continue;
9764  }
9765  CurContext->addDecl(VDPrivate);
9766  DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
9767  *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
9768  RefExpr->getExprLoc());
9769  DeclRefExpr *Ref = nullptr;
9770  if (!VD && !CurContext->isDependentContext()) {
9771  if (TopDVar.CKind == OMPC_lastprivate) {
9772  Ref = TopDVar.PrivateCopy;
9773  } else {
9774  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
9775  if (!isOpenMPCapturedDecl(D))
9776  ExprCaptures.push_back(Ref->getDecl());
9777  }
9778  }
9779  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
9780  Vars.push_back((VD || CurContext->isDependentContext())
9781  ? RefExpr->IgnoreParens()
9782  : Ref);
9783  PrivateCopies.push_back(VDPrivateRefExpr);
9784  Inits.push_back(VDInitRefExpr);
9785  }
9786 
9787  if (Vars.empty())
9788  return nullptr;
9789 
9790  return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
9791  Vars, PrivateCopies, Inits,
9792  buildPreInits(Context, ExprCaptures));
9793 }
9794 
9796  SourceLocation StartLoc,
9797  SourceLocation LParenLoc,
9798  SourceLocation EndLoc) {
9800  SmallVector<Expr *, 8> SrcExprs;
9801  SmallVector<Expr *, 8> DstExprs;
9802  SmallVector<Expr *, 8> AssignmentOps;
9803  SmallVector<Decl *, 4> ExprCaptures;
9804  SmallVector<Expr *, 4> ExprPostUpdates;
9805  for (Expr *RefExpr : VarList) {
9806  assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
9807  SourceLocation ELoc;
9808  SourceRange ERange;
9809  Expr *SimpleRefExpr = RefExpr;
9810  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
9811  if (Res.second) {
9812  // It will be analyzed later.
9813  Vars.push_back(RefExpr);
9814  SrcExprs.push_back(nullptr);
9815  DstExprs.push_back(nullptr);
9816  AssignmentOps.push_back(nullptr);
9817  }
9818  ValueDecl *D = Res.first;
9819  if (!D)
9820  continue;
9821 
9822  QualType Type = D->getType();
9823  auto *VD = dyn_cast<VarDecl>(D);
9824 
9825  // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
9826  // A variable that appears in a lastprivate clause must not have an
9827  // incomplete type or a reference type.
9828  if (RequireCompleteType(ELoc, Type,
9829  diag::err_omp_lastprivate_incomplete_type))
9830  continue;
9831  Type = Type.getNonReferenceType();
9832 
9833  OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
9834  // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
9835  // in a Construct]
9836  // Variables with the predetermined data-sharing attributes may not be
9837  // listed in data-sharing attributes clauses, except for the cases
9838  // listed below.
9839  // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
9840  // A list item may appear in a firstprivate or lastprivate clause but not
9841  // both.
9842  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
9843  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
9844  (isOpenMPDistributeDirective(CurrDir) ||
9845  DVar.CKind != OMPC_firstprivate) &&
9846  (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
9847  Diag(ELoc, diag::err_omp_wrong_dsa)
9848  << getOpenMPClauseName(DVar.CKind)
9849  << getOpenMPClauseName(OMPC_lastprivate);
9850  reportOriginalDsa(*this, DSAStack, D, DVar);
9851  continue;
9852  }
9853 
9854  // OpenMP [2.14.3.5, Restrictions, p.2]
9855  // A list item that is private within a parallel region, or that appears in
9856  // the reduction clause of a parallel construct, must not appear in a
9857  // lastprivate clause on a worksharing construct if any of the corresponding
9858  // worksharing regions ever binds to any of the corresponding parallel
9859  // regions.
9860  DSAStackTy::DSAVarData TopDVar = DVar;
9861  if (isOpenMPWorksharingDirective(CurrDir) &&
9862  !isOpenMPParallelDirective(CurrDir) &&
9863  !isOpenMPTeamsDirective(CurrDir)) {
9864  DVar = DSAStack->getImplicitDSA(D, true);
9865  if (DVar.CKind != OMPC_shared) {
9866  Diag(ELoc, diag::err_omp_required_access)
9867  << getOpenMPClauseName(OMPC_lastprivate)
9868  << getOpenMPClauseName(OMPC_shared);
9869  reportOriginalDsa(*this, DSAStack, D, DVar);
9870  continue;
9871  }
9872  }
9873 
9874  // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
9875  // A variable of class type (or array thereof) that appears in a
9876  // lastprivate clause requires an accessible, unambiguous default
9877  // constructor for the class type, unless the list item is also specified
9878  // in a firstprivate clause.
9879  // A variable of class type (or array thereof) that appears in a
9880  // lastprivate clause requires an accessible, unambiguous copy assignment
9881  // operator for the class type.
9882  Type = Context.getBaseElementType(Type).getNonReferenceType();
9883  VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
9884  Type.getUnqualifiedType(), ".lastprivate.src",
9885  D->hasAttrs() ? &D->getAttrs() : nullptr);
9886  DeclRefExpr *PseudoSrcExpr =
9887  buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
9888  VarDecl *DstVD =
9889  buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
9890  D->hasAttrs() ? &D->getAttrs() : nullptr);
9891  DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
9892  // For arrays generate assignment operation for single element and replace
9893  // it by the original array element in CodeGen.
9894  ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
9895  PseudoDstExpr, PseudoSrcExpr);
9896  if (AssignmentOp.isInvalid())
9897  continue;
9898  AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc,
9899  /*DiscardedValue=*/true);
9900  if (AssignmentOp.isInvalid())
9901  continue;
9902 
9903  DeclRefExpr *Ref = nullptr;
9904  if (!VD && !CurContext->isDependentContext()) {
9905  if (TopDVar.CKind == OMPC_firstprivate) {
9906  Ref = TopDVar.PrivateCopy;
9907  } else {
9908  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
9909  if (!isOpenMPCapturedDecl(D))
9910  ExprCaptures.push_back(Ref->getDecl());
9911  }
9912  if (TopDVar.CKind == OMPC_firstprivate ||
9913  (!isOpenMPCapturedDecl(D) &&
9914  Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
9915  ExprResult RefRes = DefaultLvalueConversion(Ref);
9916  if (!RefRes.isUsable())
9917  continue;
9918  ExprResult PostUpdateRes =
9919  BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
9920  RefRes.get());
9921  if (!PostUpdateRes.isUsable())
9922  continue;
9923  ExprPostUpdates.push_back(
9924  IgnoredValueConversions(PostUpdateRes.get()).get());
9925  }
9926  }
9927  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
9928  Vars.push_back((VD || CurContext->isDependentContext())
9929  ? RefExpr->IgnoreParens()
9930  : Ref);
9931  SrcExprs.push_back(PseudoSrcExpr);
9932  DstExprs.push_back(PseudoDstExpr);
9933  AssignmentOps.push_back(AssignmentOp.get());
9934  }
9935 
9936  if (Vars.empty())
9937  return nullptr;
9938 
9939  return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
9940  Vars, SrcExprs, DstExprs, AssignmentOps,
9941  buildPreInits(Context, ExprCaptures),
9942  buildPostUpdate(*this, ExprPostUpdates));
9943 }
9944 
9946  SourceLocation StartLoc,
9947  SourceLocation LParenLoc,
9948  SourceLocation EndLoc) {
9950  for (Expr *RefExpr : VarList) {
9951  assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
9952  SourceLocation ELoc;
9953  SourceRange ERange;
9954  Expr *SimpleRefExpr = RefExpr;
9955  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
9956  if (Res.second) {
9957  // It will be analyzed later.
9958  Vars.push_back(RefExpr);
9959  }
9960  ValueDecl *D = Res.first;
9961  if (!D)
9962  continue;
9963 
9964  auto *VD = dyn_cast<VarDecl>(D);
9965  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
9966  // in a Construct]
9967  // Variables with the predetermined data-sharing attributes may not be
9968  // listed in data-sharing attributes clauses, except for the cases
9969  // listed below. For these exceptions only, listing a predetermined
9970  // variable in a data-sharing attribute clause is allowed and overrides
9971  // the variable's predetermined data-sharing attributes.
9972  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
9973  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
9974  DVar.RefExpr) {
9975  Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
9976  << getOpenMPClauseName(OMPC_shared);
9977  reportOriginalDsa(*this, DSAStack, D, DVar);
9978  continue;
9979  }
9980 
9981  DeclRefExpr *Ref = nullptr;
9982  if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
9983  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
9984  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
9985  Vars.push_back((VD || !Ref || CurContext->isDependentContext())
9986  ? RefExpr->IgnoreParens()
9987  : Ref);
9988  }
9989 
9990  if (Vars.empty())
9991  return nullptr;
9992 
9993  return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
9994 }
9995 
9996 namespace {
9997 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
9998  DSAStackTy *Stack;
9999 
10000 public:
10001  bool VisitDeclRefExpr(DeclRefExpr *E) {
10002  if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
10003  DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
10004  if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
10005  return false;
10006  if (DVar.CKind != OMPC_unknown)
10007  return true;
10008  DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
10009  VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; },
10010  /*FromParent=*/true);
10011  return DVarPrivate.CKind != OMPC_unknown;
10012  }
10013  return false;
10014  }
10015  bool VisitStmt(Stmt *S) {
10016  for (Stmt *Child : S->children()) {
10017  if (Child && Visit(Child))
10018  return true;
10019  }
10020  return false;
10021  }
10022  explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
10023 };
10024 } // namespace
10025 
10026 namespace {
10027 // Transform MemberExpression for specified FieldDecl of current class to
10028 // DeclRefExpr to specified OMPCapturedExprDecl.
10029 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
10030  typedef TreeTransform<TransformExprToCaptures> BaseTransform;
10031  ValueDecl *Field = nullptr;
10032  DeclRefExpr *CapturedExpr = nullptr;
10033 
10034 public:
10035  TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
10036  : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
10037 
10038  ExprResult TransformMemberExpr(MemberExpr *E) {
10039  if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
10040  E->getMemberDecl() == Field) {
10041  CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
10042  return CapturedExpr;
10043  }
10044  return BaseTransform::TransformMemberExpr(E);
10045  }
10046  DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
10047 };
10048 } // namespace
10049 
10050 template <typename T, typename U>
10052  const llvm::function_ref<T(ValueDecl *)> Gen) {
10053  for (U &Set : Lookups) {
10054  for (auto *D : Set) {
10055  if (T Res = Gen(cast<ValueDecl>(D)))
10056  return Res;
10057  }
10058  }
10059  return T();
10060 }
10061 
10062 static ExprResult
10064  Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
10065  const DeclarationNameInfo &ReductionId, QualType Ty,
10066  CXXCastPath &BasePath, Expr *UnresolvedReduction) {
10067  if (ReductionIdScopeSpec.isInvalid())
10068  return ExprError();
10069  SmallVector<UnresolvedSet<8>, 4> Lookups;
10070  if (S) {
10071  LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
10072  Lookup.suppressDiagnostics();
10073  while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
10074  NamedDecl *D = Lookup.getRepresentativeDecl();
10075  do {
10076  S = S->getParent();
10077  } while (S && !S->isDeclScope(D));
10078  if (S)
10079  S = S->getParent();
10080  Lookups.push_back(UnresolvedSet<8>());
10081  Lookups.back().append(Lookup.begin(), Lookup.end());
10082  Lookup.clear();
10083  }
10084  } else if (auto *ULE =
10085  cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
10086  Lookups.push_back(UnresolvedSet<8>());
10087  Decl *PrevD = nullptr;
10088  for (NamedDecl *D : ULE->decls()) {
10089  if (D == PrevD)
10090  Lookups.push_back(UnresolvedSet<8>());
10091  else if (auto *DRD = cast<OMPDeclareReductionDecl>(D))
10092  Lookups.back().addDecl(DRD);
10093  PrevD = D;
10094  }
10095  }
10096  if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
10099  filterLookupForUDR<bool>(Lookups, [](ValueDecl *D) {
10100  return !D->isInvalidDecl() &&
10101  (D->getType()->isDependentType() ||
10104  })) {
10105  UnresolvedSet<8> ResSet;
10106  for (const UnresolvedSet<8> &Set : Lookups) {
10107  ResSet.append(Set.begin(), Set.end());
10108  // The last item marks the end of all declarations at the specified scope.
10109  ResSet.addDecl(Set[Set.size() - 1]);
10110  }
10112  SemaRef.Context, /*NamingClass=*/nullptr,
10113  ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
10114  /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
10115  }
10116  if (auto *VD = filterLookupForUDR<ValueDecl *>(
10117  Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
10118  if (!D->isInvalidDecl() &&
10119  SemaRef.Context.hasSameType(D->getType(), Ty))
10120  return D;
10121  return nullptr;
10122  }))
10123  return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc);
10124  if (auto *VD = filterLookupForUDR<ValueDecl *>(
10125  Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
10126  if (!D->isInvalidDecl() &&
10127  SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
10128  !Ty.isMoreQualifiedThan(D->getType()))
10129  return D;
10130  return nullptr;
10131  })) {
10132  CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
10133  /*DetectVirtual=*/false);
10134  if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
10135  if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
10136  VD->getType().getUnqualifiedType()))) {
10137  if (SemaRef.CheckBaseClassAccess(Loc, VD->getType(), Ty, Paths.front(),
10138  /*DiagID=*/0) !=
10140  SemaRef.BuildBasePathArray(Paths, BasePath);
10141  return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc);
10142  }
10143  }
10144  }
10145  }
10146  if (ReductionIdScopeSpec.isSet()) {
10147  SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range;
10148  return ExprError();
10149  }
10150  return ExprEmpty();
10151 }
10152 
10153 namespace {
10154 /// Data for the reduction-based clauses.
10155 struct ReductionData {
10156  /// List of original reduction items.
10158  /// List of private copies of the reduction items.
10160  /// LHS expressions for the reduction_op expressions.
10162  /// RHS expressions for the reduction_op expressions.
10164  /// Reduction operation expression.
10165  SmallVector<Expr *, 8> ReductionOps;
10166  /// Taskgroup descriptors for the corresponding reduction items in
10167  /// in_reduction clauses.
10168  SmallVector<Expr *, 8> TaskgroupDescriptors;
10169  /// List of captures for clause.
10170  SmallVector<Decl *, 4> ExprCaptures;
10171  /// List of postupdate expressions.
10172  SmallVector<Expr *, 4> ExprPostUpdates;
10173  ReductionData() = delete;
10174  /// Reserves required memory for the reduction data.
10175  ReductionData(unsigned Size) {
10176  Vars.reserve(Size);
10177  Privates.reserve(Size);
10178  LHSs.reserve(Size);
10179  RHSs.reserve(Size);
10180  ReductionOps.reserve(Size);
10181  TaskgroupDescriptors.reserve(Size);
10182  ExprCaptures.reserve(Size);
10183  ExprPostUpdates.reserve(Size);
10184  }
10185  /// Stores reduction item and reduction operation only (required for dependent
10186  /// reduction item).
10187  void push(Expr *Item, Expr *ReductionOp) {
10188  Vars.emplace_back(Item);
10189  Privates.emplace_back(nullptr);
10190  LHSs.emplace_back(nullptr);
10191  RHSs.emplace_back(nullptr);
10192  ReductionOps.emplace_back(ReductionOp);
10193  TaskgroupDescriptors.emplace_back(nullptr);
10194  }
10195  /// Stores reduction data.
10196  void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
10197  Expr *TaskgroupDescriptor) {
10198  Vars.emplace_back(Item);
10199  Privates.emplace_back(Private);
10200  LHSs.emplace_back(LHS);
10201  RHSs.emplace_back(RHS);
10202  ReductionOps.emplace_back(ReductionOp);
10203  TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
10204  }
10205 };
10206 } // namespace
10207 
10209  ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
10210  SmallVectorImpl<llvm::APSInt> &ArraySizes) {
10211  const Expr *Length = OASE->getLength();
10212  if (Length == nullptr) {
10213  // For array sections of the form [1:] or [:], we would need to analyze
10214  // the lower bound...
10215  if (OASE->getColonLoc().isValid())
10216  return false;
10217 
10218  // This is an array subscript which has implicit length 1!
10219  SingleElement = true;
10220  ArraySizes.push_back(llvm::APSInt::get(1));
10221  } else {
10222  llvm::APSInt ConstantLengthValue;
10223  if (!Length->EvaluateAsInt(ConstantLengthValue, Context))
10224  return false;
10225 
10226  SingleElement = (ConstantLengthValue.getSExtValue() == 1);
10227  ArraySizes.push_back(ConstantLengthValue);
10228  }
10229 
10230  // Get the base of this array section and walk up from there.
10231  const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
10232 
10233  // We require length = 1 for all array sections except the right-most to
10234  // guarantee that the memory region is contiguous and has no holes in it.
10235  while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
10236  Length = TempOASE->getLength();
10237  if (Length == nullptr) {
10238  // For array sections of the form [1:] or [:], we would need to analyze
10239  // the lower bound...
10240  if (OASE->getColonLoc().isValid())
10241  return false;
10242 
10243  // This is an array subscript which has implicit length 1!
10244  ArraySizes.push_back(llvm::APSInt::get(1));
10245  } else {
10246  llvm::APSInt ConstantLengthValue;
10247  if (!Length->EvaluateAsInt(ConstantLengthValue, Context) ||
10248  ConstantLengthValue.getSExtValue() != 1)
10249  return false;
10250 
10251  ArraySizes.push_back(ConstantLengthValue);
10252  }
10253  Base = TempOASE->getBase()->IgnoreParenImpCasts();
10254  }
10255 
10256  // If we have a single element, we don't need to add the implicit lengths.
10257  if (!SingleElement) {
10258  while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
10259  // Has implicit length 1!
10260  ArraySizes.push_back(llvm::APSInt::get(1));
10261  Base = TempASE->getBase()->IgnoreParenImpCasts();
10262  }
10263  }
10264 
10265  // This array section can be privatized as a single value or as a constant
10266  // sized array.
10267  return true;
10268 }
10269 
10271  Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
10272  ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
10274  CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
10275  ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
10276  DeclarationName DN = ReductionId.getName();
10278  BinaryOperatorKind BOK = BO_Comma;
10279 
10280  ASTContext &Context = S.Context;
10281  // OpenMP [2.14.3.6, reduction clause]
10282  // C
10283  // reduction-identifier is either an identifier or one of the following
10284  // operators: +, -, *, &, |, ^, && and ||
10285  // C++
10286  // reduction-identifier is either an id-expression or one of the following
10287  // operators: +, -, *, &, |, ^, && and ||
10288  switch (OOK) {
10289  case OO_Plus:
10290  case OO_Minus:
10291  BOK = BO_Add;
10292  break;
10293  case OO_Star:
10294  BOK = BO_Mul;
10295  break;
10296  case OO_Amp:
10297  BOK = BO_And;
10298  break;
10299  case OO_Pipe:
10300  BOK = BO_Or;
10301  break;
10302  case OO_Caret:
10303  BOK = BO_Xor;
10304  break;
10305  case OO_AmpAmp:
10306  BOK = BO_LAnd;
10307  break;
10308  case OO_PipePipe:
10309  BOK = BO_LOr;
10310  break;
10311  case OO_New:
10312  case OO_Delete:
10313  case OO_Array_New:
10314  case OO_Array_Delete:
10315  case OO_Slash:
10316  case OO_Percent:
10317  case OO_Tilde:
10318  case OO_Exclaim:
10319  case OO_Equal:
10320  case OO_Less:
10321  case OO_Greater:
10322  case OO_LessEqual:
10323  case OO_GreaterEqual:
10324  case OO_PlusEqual:
10325  case OO_MinusEqual:
10326  case OO_StarEqual:
10327  case OO_SlashEqual:
10328  case OO_PercentEqual:
10329  case OO_CaretEqual:
10330  case OO_AmpEqual:
10331  case OO_PipeEqual:
10332  case OO_LessLess:
10333  case OO_GreaterGreater:
10334  case OO_LessLessEqual:
10335  case OO_GreaterGreaterEqual:
10336  case OO_EqualEqual:
10337  case OO_ExclaimEqual:
10338  case OO_Spaceship:
10339  case OO_PlusPlus:
10340  case OO_MinusMinus:
10341  case OO_Comma:
10342  case OO_ArrowStar:
10343  case OO_Arrow:
10344  case OO_Call:
10345  case OO_Subscript:
10346  case OO_Conditional:
10347  case OO_Coawait:
10349  llvm_unreachable("Unexpected reduction identifier");
10350  case OO_None:
10351  if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
10352  if (II->isStr("max"))
10353  BOK = BO_GT;
10354  else if (II->isStr("min"))
10355  BOK = BO_LT;
10356  }
10357  break;
10358  }
10359  SourceRange ReductionIdRange;
10360  if (ReductionIdScopeSpec.isValid())
10361  ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
10362  else
10363  ReductionIdRange.setBegin(ReductionId.getBeginLoc());
10364  ReductionIdRange.setEnd(ReductionId.getEndLoc());
10365 
10366  auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
10367  bool FirstIter = true;
10368  for (Expr *RefExpr : VarList) {
10369  assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
10370  // OpenMP [2.1, C/C++]
10371  // A list item is a variable or array section, subject to the restrictions
10372  // specified in Section 2.4 on page 42 and in each of the sections
10373  // describing clauses and directives for which a list appears.
10374  // OpenMP [2.14.3.3, Restrictions, p.1]
10375  // A variable that is part of another variable (as an array or
10376  // structure element) cannot appear in a private clause.
10377  if (!FirstIter && IR != ER)
10378  ++IR;
10379  FirstIter = false;
10380  SourceLocation ELoc;
10381  SourceRange ERange;
10382  Expr *SimpleRefExpr = RefExpr;
10383  auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
10384  /*AllowArraySection=*/true);
10385  if (Res.second) {
10386  // Try to find 'declare reduction' corresponding construct before using
10387  // builtin/overloaded operators.
10388  QualType Type = Context.DependentTy;
10389  CXXCastPath BasePath;
10390  ExprResult DeclareReductionRef = buildDeclareReductionRef(
10391  S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
10392  ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
10393  Expr *ReductionOp = nullptr;
10394  if (S.CurContext->isDependentContext() &&
10395  (DeclareReductionRef.isUnset() ||
10396  isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
10397  ReductionOp = DeclareReductionRef.get();
10398  // It will be analyzed later.
10399  RD.push(RefExpr, ReductionOp);
10400  }
10401  ValueDecl *D = Res.first;
10402  if (!D)
10403  continue;
10404 
10405  Expr *TaskgroupDescriptor = nullptr;
10406  QualType Type;
10407  auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
10408  auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
10409  if (ASE) {
10410  Type = ASE->getType().getNonReferenceType();
10411  } else if (OASE) {
10412  QualType BaseType =
10414  if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
10415  Type = ATy->getElementType();
10416  else
10417  Type = BaseType->getPointeeType();
10418  Type = Type.getNonReferenceType();
10419  } else {
10420  Type = Context.getBaseElementType(D->getType().getNonReferenceType());
10421  }
10422  auto *VD = dyn_cast<VarDecl>(D);
10423 
10424  // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
10425  // A variable that appears in a private clause must not have an incomplete
10426  // type or a reference type.
10427  if (S.RequireCompleteType(ELoc, D->getType(),
10428  diag::err_omp_reduction_incomplete_type))
10429  continue;
10430  // OpenMP [2.14.3.6, reduction clause, Restrictions]
10431  // A list item that appears in a reduction clause must not be
10432  // const-qualified.
10433  if (Type.getNonReferenceType().isConstant(Context)) {
10434  S.Diag(ELoc, diag::err_omp_const_reduction_list_item) << ERange;
10435  if (!ASE && !OASE) {
10436  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
10438  S.Diag(D->getLocation(),
10439  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10440  << D;
10441  }
10442  continue;
10443  }
10444  // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
10445  // If a list-item is a reference type then it must bind to the same object
10446  // for all threads of the team.
10447  if (!ASE && !OASE && VD) {
10448  VarDecl *VDDef = VD->getDefinition();
10449  if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
10450  DSARefChecker Check(Stack);
10451  if (Check.Visit(VDDef->getInit())) {
10452  S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
10453  << getOpenMPClauseName(ClauseKind) << ERange;
10454  S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
10455  continue;
10456  }
10457  }
10458  }
10459 
10460  // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
10461  // in a Construct]
10462  // Variables with the predetermined data-sharing attributes may not be
10463  // listed in data-sharing attributes clauses, except for the cases
10464  // listed below. For these exceptions only, listing a predetermined
10465  // variable in a data-sharing attribute clause is allowed and overrides
10466  // the variable's predetermined data-sharing attributes.
10467  // OpenMP [2.14.3.6, Restrictions, p.3]
10468  // Any number of reduction clauses can be specified on the directive,
10469  // but a list item can appear only once in the reduction clauses for that
10470  // directive.
10471  DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
10472  if (DVar.CKind == OMPC_reduction) {
10473  S.Diag(ELoc, diag::err_omp_once_referenced)
10474  << getOpenMPClauseName(ClauseKind);
10475  if (DVar.RefExpr)
10476  S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
10477  continue;
10478  }
10479  if (DVar.CKind != OMPC_unknown) {
10480  S.Diag(ELoc, diag::err_omp_wrong_dsa)
10481  << getOpenMPClauseName(DVar.CKind)
10482  << getOpenMPClauseName(OMPC_reduction);
10483  reportOriginalDsa(S, Stack, D, DVar);
10484  continue;
10485  }
10486 
10487  // OpenMP [2.14.3.6, Restrictions, p.1]
10488  // A list item that appears in a reduction clause of a worksharing
10489  // construct must be shared in the parallel regions to which any of the
10490  // worksharing regions arising from the worksharing construct bind.
10491  OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
10492  if (isOpenMPWorksharingDirective(CurrDir) &&
10493  !isOpenMPParallelDirective(CurrDir) &&
10494  !isOpenMPTeamsDirective(CurrDir)) {
10495  DVar = Stack->getImplicitDSA(D, true);
10496  if (DVar.CKind != OMPC_shared) {
10497  S.Diag(ELoc, diag::err_omp_required_access)
10498  << getOpenMPClauseName(OMPC_reduction)
10499  << getOpenMPClauseName(OMPC_shared);
10500  reportOriginalDsa(S, Stack, D, DVar);
10501  continue;
10502  }
10503  }
10504 
10505  // Try to find 'declare reduction' corresponding construct before using
10506  // builtin/overloaded operators.
10507  CXXCastPath BasePath;
10508  ExprResult DeclareReductionRef = buildDeclareReductionRef(
10509  S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
10510  ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
10511  if (DeclareReductionRef.isInvalid())
10512  continue;
10513  if (S.CurContext->isDependentContext() &&
10514  (DeclareReductionRef.isUnset() ||
10515  isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
10516  RD.push(RefExpr, DeclareReductionRef.get());
10517  continue;
10518  }
10519  if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
10520  // Not allowed reduction identifier is found.
10521  S.Diag(ReductionId.getLocStart(),
10522  diag::err_omp_unknown_reduction_identifier)
10523  << Type << ReductionIdRange;
10524  continue;
10525  }
10526 
10527  // OpenMP [2.14.3.6, reduction clause, Restrictions]
10528  // The type of a list item that appears in a reduction clause must be valid
10529  // for the reduction-identifier. For a max or min reduction in C, the type
10530  // of the list item must be an allowed arithmetic data type: char, int,
10531  // float, double, or _Bool, possibly modified with long, short, signed, or
10532  // unsigned. For a max or min reduction in C++, the type of the list item
10533  // must be an allowed arithmetic data type: char, wchar_t, int, float,
10534  // double, or bool, possibly modified with long, short, signed, or unsigned.
10535  if (DeclareReductionRef.isUnset()) {
10536  if ((BOK == BO_GT || BOK == BO_LT) &&
10537  !(Type->isScalarType() ||
10538  (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
10539  S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
10540  << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
10541  if (!ASE && !OASE) {
10542  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
10544  S.Diag(D->getLocation(),
10545  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10546  << D;
10547  }
10548  continue;
10549  }
10550  if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
10551  !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
10552  S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
10553  << getOpenMPClauseName(ClauseKind);
10554  if (!ASE && !OASE) {
10555  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
10557  S.Diag(D->getLocation(),
10558  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10559  << D;
10560  }
10561  continue;
10562  }
10563  }
10564 
10565  Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
10566  VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
10567  D->hasAttrs() ? &D->getAttrs() : nullptr);
10568  VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
10569  D->hasAttrs() ? &D->getAttrs() : nullptr);
10570  QualType PrivateTy = Type;
10571 
10572  // Try if we can determine constant lengths for all array sections and avoid
10573  // the VLA.
10574  bool ConstantLengthOASE = false;
10575  if (OASE) {
10576  bool SingleElement;
10578  ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
10579  Context, OASE, SingleElement, ArraySizes);
10580 
10581  // If we don't have a single element, we must emit a constant array type.
10582  if (ConstantLengthOASE && !SingleElement) {
10583  for (llvm::APSInt &Size : ArraySizes)
10584  PrivateTy = Context.getConstantArrayType(
10585  PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0);
10586  }
10587  }
10588 
10589  if ((OASE && !ConstantLengthOASE) ||
10590  (!OASE && !ASE &&
10592  if (!Context.getTargetInfo().isVLASupported() &&
10594  S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
10595  S.Diag(ELoc, diag::note_vla_unsupported);
10596  continue;
10597  }
10598  // For arrays/array sections only:
10599  // Create pseudo array type for private copy. The size for this array will
10600  // be generated during codegen.
10601  // For array subscripts or single variables Private Ty is the same as Type
10602  // (type of the variable or single array element).
10603  PrivateTy = Context.getVariableArrayType(
10604  Type,
10605  new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue),
10606  ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
10607  } else if (!ASE && !OASE &&
10608  Context.getAsArrayType(D->getType().getNonReferenceType())) {
10609  PrivateTy = D->getType().getNonReferenceType();
10610  }
10611  // Private copy.
10612  VarDecl *PrivateVD =
10613  buildVarDecl(S, ELoc, PrivateTy, D->getName(),
10614  D->hasAttrs() ? &D->getAttrs() : nullptr,
10615  VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
10616  // Add initializer for private variable.
10617  Expr *Init = nullptr;
10618  DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
10619  DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
10620  if (DeclareReductionRef.isUsable()) {
10621  auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
10622  auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
10623  if (DRD->getInitializer()) {
10624  Init = DRDRef;
10625  RHSVD->setInit(DRDRef);
10626  RHSVD->setInitStyle(VarDecl::CallInit);
10627  }
10628  } else {
10629  switch (BOK) {
10630  case BO_Add:
10631  case BO_Xor:
10632  case BO_Or:
10633  case BO_LOr:
10634  // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
10635  if (Type->isScalarType() || Type->isAnyComplexType())
10636  Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
10637  break;
10638  case BO_Mul:
10639  case BO_LAnd:
10640  if (Type->isScalarType() || Type->isAnyComplexType()) {
10641  // '*' and '&&' reduction ops - initializer is '1'.
10642  Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
10643  }
10644  break;
10645  case BO_And: {
10646  // '&' reduction op - initializer is '~0'.
10647  QualType OrigType = Type;
10648  if (auto *ComplexTy = OrigType->getAs<ComplexType>())
10649  Type = ComplexTy->getElementType();
10650  if (Type->isRealFloatingType()) {
10651  llvm::APFloat InitValue =
10652  llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type),
10653  /*isIEEE=*/true);
10654  Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
10655  Type, ELoc);
10656  } else if (Type->isScalarType()) {
10657  uint64_t Size = Context.getTypeSize(Type);
10658  QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
10659  llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
10660  Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
10661  }
10662  if (Init && OrigType->isAnyComplexType()) {
10663  // Init = 0xFFFF + 0xFFFFi;
10664  auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
10665  Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
10666  }
10667  Type = OrigType;
10668  break;
10669  }
10670  case BO_LT:
10671  case BO_GT: {
10672  // 'min' reduction op - initializer is 'Largest representable number in
10673  // the reduction list item type'.
10674  // 'max' reduction op - initializer is 'Least representable number in
10675  // the reduction list item type'.
10676  if (Type->isIntegerType() || Type->isPointerType()) {
10677  bool IsSigned = Type->hasSignedIntegerRepresentation();
10678  uint64_t Size = Context.getTypeSize(Type);
10679  QualType IntTy =
10680  Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
10681  llvm::APInt InitValue =
10682  (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
10683  : llvm::APInt::getMinValue(Size)
10684  : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
10685  : llvm::APInt::getMaxValue(Size);
10686  Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
10687  if (Type->isPointerType()) {
10688  // Cast to pointer type.
10690  ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
10691  if (CastExpr.isInvalid())
10692  continue;
10693  Init = CastExpr.get();
10694  }
10695  } else if (Type->isRealFloatingType()) {
10696  llvm::APFloat InitValue = llvm::APFloat::getLargest(
10697  Context.getFloatTypeSemantics(Type), BOK != BO_LT);
10698  Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
10699  Type, ELoc);
10700  }
10701  break;
10702  }
10703  case BO_PtrMemD:
10704  case BO_PtrMemI:
10705  case BO_MulAssign:
10706  case BO_Div:
10707  case BO_Rem:
10708  case BO_Sub:
10709  case BO_Shl:
10710  case BO_Shr:
10711  case BO_LE:
10712  case BO_GE:
10713  case BO_EQ:
10714  case BO_NE:
10715  case BO_Cmp:
10716  case BO_AndAssign:
10717  case BO_XorAssign:
10718  case BO_OrAssign:
10719  case BO_Assign:
10720  case BO_AddAssign:
10721  case BO_SubAssign:
10722  case BO_DivAssign:
10723  case BO_RemAssign:
10724  case BO_ShlAssign:
10725  case BO_ShrAssign:
10726  case BO_Comma:
10727  llvm_unreachable("Unexpected reduction operation");
10728  }
10729  }
10730  if (Init && DeclareReductionRef.isUnset())
10731  S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
10732  else if (!Init)
10733  S.ActOnUninitializedDecl(RHSVD);
10734  if (RHSVD->isInvalidDecl())
10735  continue;
10736  if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) {
10737  S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
10738  << Type << ReductionIdRange;
10739  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
10741  S.Diag(D->getLocation(),
10742  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10743  << D;
10744  continue;
10745  }
10746  // Store initializer for single element in private copy. Will be used during
10747  // codegen.
10748  PrivateVD->setInit(RHSVD->getInit());
10749  PrivateVD->setInitStyle(RHSVD->getInitStyle());
10750  DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
10751  ExprResult ReductionOp;
10752  if (DeclareReductionRef.isUsable()) {
10753  QualType RedTy = DeclareReductionRef.get()->getType();
10754  QualType PtrRedTy = Context.getPointerType(RedTy);
10755  ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
10756  ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
10757  if (!BasePath.empty()) {
10758  LHS = S.DefaultLvalueConversion(LHS.get());
10759  RHS = S.DefaultLvalueConversion(RHS.get());
10760  LHS = ImplicitCastExpr::Create(Context, PtrRedTy,
10761  CK_UncheckedDerivedToBase, LHS.get(),
10762  &BasePath, LHS.get()->getValueKind());
10763  RHS = ImplicitCastExpr::Create(Context, PtrRedTy,
10764  CK_UncheckedDerivedToBase, RHS.get(),
10765  &BasePath, RHS.get()->getValueKind());
10766  }
10768  QualType Params[] = {PtrRedTy, PtrRedTy};
10769  QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
10770  auto *OVE = new (Context) OpaqueValueExpr(
10771  ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary,
10772  S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
10773  Expr *Args[] = {LHS.get(), RHS.get()};
10774  ReductionOp = new (Context)
10775  CallExpr(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc);
10776  } else {
10777  ReductionOp = S.BuildBinOp(
10778  Stack->getCurScope(), ReductionId.getLocStart(), BOK, LHSDRE, RHSDRE);
10779  if (ReductionOp.isUsable()) {
10780  if (BOK != BO_LT && BOK != BO_GT) {
10781  ReductionOp =
10782  S.BuildBinOp(Stack->getCurScope(), ReductionId.getLocStart(),
10783  BO_Assign, LHSDRE, ReductionOp.get());
10784  } else {
10785  auto *ConditionalOp = new (Context)
10786  ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE,
10787  Type, VK_LValue, OK_Ordinary);
10788  ReductionOp =
10789  S.BuildBinOp(Stack->getCurScope(), ReductionId.getLocStart(),
10790  BO_Assign, LHSDRE, ConditionalOp);
10791  }
10792  if (ReductionOp.isUsable())
10793  ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get());
10794  }
10795  if (!ReductionOp.isUsable())
10796  continue;
10797  }
10798 
10799  // OpenMP [2.15.4.6, Restrictions, p.2]
10800  // A list item that appears in an in_reduction clause of a task construct
10801  // must appear in a task_reduction clause of a construct associated with a
10802  // taskgroup region that includes the participating task in its taskgroup
10803  // set. The construct associated with the innermost region that meets this
10804  // condition must specify the same reduction-identifier as the in_reduction
10805  // clause.
10806  if (ClauseKind == OMPC_in_reduction) {
10807  SourceRange ParentSR;
10808  BinaryOperatorKind ParentBOK;
10809  const Expr *ParentReductionOp;
10810  Expr *ParentBOKTD, *ParentReductionOpTD;
10811  DSAStackTy::DSAVarData ParentBOKDSA =
10812  Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
10813  ParentBOKTD);
10814  DSAStackTy::DSAVarData ParentReductionOpDSA =
10815  Stack->getTopMostTaskgroupReductionData(
10816  D, ParentSR, ParentReductionOp, ParentReductionOpTD);
10817  bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
10818  bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
10819  if (!IsParentBOK && !IsParentReductionOp) {
10820  S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction);
10821  continue;
10822  }
10823  if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
10824  (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK ||
10825  IsParentReductionOp) {
10826  bool EmitError = true;
10827  if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
10828  llvm::FoldingSetNodeID RedId, ParentRedId;
10829  ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
10830  DeclareReductionRef.get()->Profile(RedId, Context,
10831  /*Canonical=*/true);
10832  EmitError = RedId != ParentRedId;
10833  }
10834  if (EmitError) {
10835  S.Diag(ReductionId.getLocStart(),
10836  diag::err_omp_reduction_identifier_mismatch)
10837  << ReductionIdRange << RefExpr->getSourceRange();
10838  S.Diag(ParentSR.getBegin(),
10839  diag::note_omp_previous_reduction_identifier)
10840  << ParentSR
10841  << (IsParentBOK ? ParentBOKDSA.RefExpr
10842  : ParentReductionOpDSA.RefExpr)
10843  ->getSourceRange();
10844  continue;
10845  }
10846  }
10847  TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
10848  assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined.");
10849  }
10850 
10851  DeclRefExpr *Ref = nullptr;
10852  Expr *VarsExpr = RefExpr->IgnoreParens();
10853  if (!VD && !S.CurContext->isDependentContext()) {
10854  if (ASE || OASE) {
10855  TransformExprToCaptures RebuildToCapture(S, D);
10856  VarsExpr =
10857  RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
10858  Ref = RebuildToCapture.getCapturedExpr();
10859  } else {
10860  VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
10861  }
10862  if (!S.isOpenMPCapturedDecl(D)) {
10863  RD.ExprCaptures.emplace_back(Ref->getDecl());
10864  if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
10865  ExprResult RefRes = S.DefaultLvalueConversion(Ref);
10866  if (!RefRes.isUsable())
10867  continue;
10868  ExprResult PostUpdateRes =
10869  S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
10870  RefRes.get());
10871  if (!PostUpdateRes.isUsable())
10872  continue;
10873  if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
10874  Stack->getCurrentDirective() == OMPD_taskgroup) {
10875  S.Diag(RefExpr->getExprLoc(),
10876  diag::err_omp_reduction_non_addressable_expression)
10877  << RefExpr->getSourceRange();
10878  continue;
10879  }
10880  RD.ExprPostUpdates.emplace_back(
10881  S.IgnoredValueConversions(PostUpdateRes.get()).get());
10882  }
10883  }
10884  }
10885  // All reduction items are still marked as reduction (to do not increase
10886  // code base size).
10887  Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref);
10888  if (CurrDir == OMPD_taskgroup) {
10889  if (DeclareReductionRef.isUsable())
10890  Stack->addTaskgroupReductionData(D, ReductionIdRange,
10891  DeclareReductionRef.get());
10892  else
10893  Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
10894  }
10895  RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
10896  TaskgroupDescriptor);
10897  }
10898  return RD.Vars.empty();
10899 }
10900 
10902  ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
10904  CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
10905  ArrayRef<Expr *> UnresolvedReductions) {
10906  ReductionData RD(VarList.size());
10907  if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList,
10908  StartLoc, LParenLoc, ColonLoc, EndLoc,
10909  ReductionIdScopeSpec, ReductionId,
10910  UnresolvedReductions, RD))
10911  return nullptr;
10912 
10914  Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
10915  ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
10916  RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
10917  buildPreInits(Context, RD.ExprCaptures),
10918  buildPostUpdate(*this, RD.ExprPostUpdates));
10919 }
10920 
10922  ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
10924  CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
10925  ArrayRef<Expr *> UnresolvedReductions) {
10926  ReductionData RD(VarList.size());
10927  if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList,
10928  StartLoc, LParenLoc, ColonLoc, EndLoc,
10929  ReductionIdScopeSpec, ReductionId,
10930  UnresolvedReductions, RD))
10931  return nullptr;
10932 
10934  Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
10935  ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
10936  RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
10937  buildPreInits(Context, RD.ExprCaptures),
10938  buildPostUpdate(*this, RD.ExprPostUpdates));
10939 }
10940 
10942  ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
10944  CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
10945  ArrayRef<Expr *> UnresolvedReductions) {
10946  ReductionData RD(VarList.size());
10947  if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList,
10948  StartLoc, LParenLoc, ColonLoc, EndLoc,
10949  ReductionIdScopeSpec, ReductionId,
10950  UnresolvedReductions, RD))
10951  return nullptr;
10952 
10954  Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
10955  ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
10956  RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
10957  buildPreInits(Context, RD.ExprCaptures),
10958  buildPostUpdate(*this, RD.ExprPostUpdates));
10959 }
10960 
10962  SourceLocation LinLoc) {
10963  if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
10964  LinKind == OMPC_LINEAR_unknown) {
10965  Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
10966  return true;
10967  }
10968  return false;
10969 }
10970 
10972  OpenMPLinearClauseKind LinKind,
10973  QualType Type) {
10974  const auto *VD = dyn_cast_or_null<VarDecl>(D);
10975  // A variable must not have an incomplete type or a reference type.
10976  if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
10977  return true;
10978  if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
10979  !Type->isReferenceType()) {
10980  Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
10981  << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
10982  return true;
10983  }
10984  Type = Type.getNonReferenceType();
10985 
10986  // A list item must not be const-qualified.
10987  if (Type.isConstant(Context)) {
10988  Diag(ELoc, diag::err_omp_const_variable)
10989  << getOpenMPClauseName(OMPC_linear);
10990  if (D) {
10991  bool IsDecl =
10992  !VD ||
10993  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
10994  Diag(D->getLocation(),
10995  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10996  << D;
10997  }
10998  return true;
10999  }
11000 
11001  // A list item must be of integral or pointer type.
11002  Type = Type.getUnqualifiedType().getCanonicalType();
11003  const auto *Ty = Type.getTypePtrOrNull();
11004  if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
11005  !Ty->isPointerType())) {
11006  Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
11007  if (D) {
11008  bool IsDecl =
11009  !VD ||
11010  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
11011  Diag(D->getLocation(),
11012  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11013  << D;
11014  }
11015  return true;
11016  }
11017  return false;
11018 }
11019 
11021  ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
11022  SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
11027  SmallVector<Decl *, 4> ExprCaptures;
11028  SmallVector<Expr *, 4> ExprPostUpdates;
11029  if (CheckOpenMPLinearModifier(LinKind, LinLoc))
11030  LinKind = OMPC_LINEAR_val;
11031  for (Expr *RefExpr : VarList) {
11032  assert(RefExpr && "NULL expr in OpenMP linear clause.");
11033  SourceLocation ELoc;
11034  SourceRange ERange;
11035  Expr *SimpleRefExpr = RefExpr;
11036  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
11037  /*AllowArraySection=*/false);
11038  if (Res.second) {
11039  // It will be analyzed later.
11040  Vars.push_back(RefExpr);
11041  Privates.push_back(nullptr);
11042  Inits.push_back(nullptr);
11043  }
11044  ValueDecl *D = Res.first;
11045  if (!D)
11046  continue;
11047 
11048  QualType Type = D->getType();
11049  auto *VD = dyn_cast<VarDecl>(D);
11050 
11051  // OpenMP [2.14.3.7, linear clause]
11052  // A list-item cannot appear in more than one linear clause.
11053  // A list-item that appears in a linear clause cannot appear in any
11054  // other data-sharing attribute clause.
11055  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
11056  if (DVar.RefExpr) {
11057  Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
11058  << getOpenMPClauseName(OMPC_linear);
11059  reportOriginalDsa(*this, DSAStack, D, DVar);
11060  continue;
11061  }
11062 
11063  if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
11064  continue;
11066 
11067  // Build private copy of original var.
11068  VarDecl *Private =
11069  buildVarDecl(*this, ELoc, Type, D->getName(),
11070  D->hasAttrs() ? &D->getAttrs() : nullptr,
11071  VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
11072  DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
11073  // Build var to save initial value.
11074  VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
11075  Expr *InitExpr;
11076  DeclRefExpr *Ref = nullptr;
11077  if (!VD && !CurContext->isDependentContext()) {
11078  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
11079  if (!isOpenMPCapturedDecl(D)) {
11080  ExprCaptures.push_back(Ref->getDecl());
11081  if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
11082  ExprResult RefRes = DefaultLvalueConversion(Ref);
11083  if (!RefRes.isUsable())
11084  continue;
11085  ExprResult PostUpdateRes =
11086  BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
11087  SimpleRefExpr, RefRes.get());
11088  if (!PostUpdateRes.isUsable())
11089  continue;
11090  ExprPostUpdates.push_back(
11091  IgnoredValueConversions(PostUpdateRes.get()).get());
11092  }
11093  }
11094  }
11095  if (LinKind == OMPC_LINEAR_uval)
11096  InitExpr = VD ? VD->getInit() : SimpleRefExpr;
11097  else
11098  InitExpr = VD ? SimpleRefExpr : Ref;
11099  AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
11100  /*DirectInit=*/false);
11101  DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
11102 
11103  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
11104  Vars.push_back((VD || CurContext->isDependentContext())
11105  ? RefExpr->IgnoreParens()
11106  : Ref);
11107  Privates.push_back(PrivateRef);
11108  Inits.push_back(InitRef);
11109  }
11110 
11111  if (Vars.empty())
11112  return nullptr;
11113 
11114  Expr *StepExpr = Step;
11115  Expr *CalcStepExpr = nullptr;
11116  if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
11117  !Step->isInstantiationDependent() &&
11119  SourceLocation StepLoc = Step->getLocStart();
11120  ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
11121  if (Val.isInvalid())
11122  return nullptr;
11123  StepExpr = Val.get();
11124 
11125  // Build var to save the step value.
11126  VarDecl *SaveVar =
11127  buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
11128  ExprResult SaveRef =
11129  buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
11131  BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
11132  CalcStep = ActOnFinishFullExpr(CalcStep.get());
11133 
11134  // Warn about zero linear step (it would be probably better specified as
11135  // making corresponding variables 'const').
11136  llvm::APSInt Result;
11137  bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context);
11138  if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive())
11139  Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0]
11140  << (Vars.size() > 1);
11141  if (!IsConstant && CalcStep.isUsable()) {
11142  // Calculate the step beforehand instead of doing this on each iteration.
11143  // (This is not used if the number of iterations may be kfold-ed).
11144  CalcStepExpr = CalcStep.get();
11145  }
11146  }
11147 
11148  return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
11149  ColonLoc, EndLoc, Vars, Privates, Inits,
11150  StepExpr, CalcStepExpr,
11151  buildPreInits(Context, ExprCaptures),
11152  buildPostUpdate(*this, ExprPostUpdates));
11153 }
11154 
11156  Expr *NumIterations, Sema &SemaRef,
11157  Scope *S, DSAStackTy *Stack) {
11158  // Walk the vars and build update/final expressions for the CodeGen.
11161  Expr *Step = Clause.getStep();
11162  Expr *CalcStep = Clause.getCalcStep();
11163  // OpenMP [2.14.3.7, linear clause]
11164  // If linear-step is not specified it is assumed to be 1.
11165  if (!Step)
11166  Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
11167  else if (CalcStep)
11168  Step = cast<BinaryOperator>(CalcStep)->getLHS();
11169  bool HasErrors = false;
11170  auto CurInit = Clause.inits().begin();
11171  auto CurPrivate = Clause.privates().begin();
11172  OpenMPLinearClauseKind LinKind = Clause.getModifier();
11173  for (Expr *RefExpr : Clause.varlists()) {
11174  SourceLocation ELoc;
11175  SourceRange ERange;
11176  Expr *SimpleRefExpr = RefExpr;
11177  auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange,
11178  /*AllowArraySection=*/false);
11179  ValueDecl *D = Res.first;
11180  if (Res.second || !D) {
11181  Updates.push_back(nullptr);
11182  Finals.push_back(nullptr);
11183  HasErrors = true;
11184  continue;
11185  }
11186  auto &&Info = Stack->isLoopControlVariable(D);
11187  // OpenMP [2.15.11, distribute simd Construct]
11188  // A list item may not appear in a linear clause, unless it is the loop
11189  // iteration variable.
11190  if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
11191  isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
11192  SemaRef.Diag(ELoc,
11193  diag::err_omp_linear_distribute_var_non_loop_iteration);
11194  Updates.push_back(nullptr);
11195  Finals.push_back(nullptr);
11196  HasErrors = true;
11197  continue;
11198  }
11199  Expr *InitExpr = *CurInit;
11200 
11201  // Build privatized reference to the current linear var.
11202  auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
11203  Expr *CapturedRef;
11204  if (LinKind == OMPC_LINEAR_uval)
11205  CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
11206  else
11207  CapturedRef =
11208  buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
11209  DE->getType().getUnqualifiedType(), DE->getExprLoc(),
11210  /*RefersToCapture=*/true);
11211 
11212  // Build update: Var = InitExpr + IV * Step
11214  if (!Info.first)
11215  Update =
11216  buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate,
11217  InitExpr, IV, Step, /* Subtract */ false);
11218  else
11219  Update = *CurPrivate;
11220  Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getLocStart(),
11221  /*DiscardedValue=*/true);
11222 
11223  // Build final: Var = InitExpr + NumIterations * Step
11224  ExprResult Final;
11225  if (!Info.first)
11226  Final =
11227  buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
11228  InitExpr, NumIterations, Step, /*Subtract=*/false);
11229  else
11230  Final = *CurPrivate;
11231  Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getLocStart(),
11232  /*DiscardedValue=*/true);
11233 
11234  if (!Update.isUsable() || !Final.isUsable()) {
11235  Updates.push_back(nullptr);
11236  Finals.push_back(nullptr);
11237  HasErrors = true;
11238  } else {
11239  Updates.push_back(Update.get());
11240  Finals.push_back(Final.get());
11241  }
11242  ++CurInit;
11243  ++CurPrivate;
11244  }
11245  Clause.setUpdates(Updates);
11246  Clause.setFinals(Finals);
11247  return HasErrors;
11248 }
11249 
11251  ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
11254  for (Expr *RefExpr : VarList) {
11255  assert(RefExpr && "NULL expr in OpenMP linear clause.");
11256  SourceLocation ELoc;
11257  SourceRange ERange;
11258  Expr *SimpleRefExpr = RefExpr;
11259  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
11260  /*AllowArraySection=*/false);
11261  if (Res.second) {
11262  // It will be analyzed later.
11263  Vars.push_back(RefExpr);
11264  }
11265  ValueDecl *D = Res.first;
11266  if (!D)
11267  continue;
11268 
11269  QualType QType = D->getType();
11270  auto *VD = dyn_cast<VarDecl>(D);
11271 
11272  // OpenMP [2.8.1, simd construct, Restrictions]
11273  // The type of list items appearing in the aligned clause must be
11274  // array, pointer, reference to array, or reference to pointer.
11276  const Type *Ty = QType.getTypePtrOrNull();
11277  if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
11278  Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
11279  << QType << getLangOpts().CPlusPlus << ERange;
11280  bool IsDecl =
11281  !VD ||
11282  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
11283  Diag(D->getLocation(),
11284  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11285  << D;
11286  continue;
11287  }
11288 
11289  // OpenMP [2.8.1, simd construct, Restrictions]
11290  // A list-item cannot appear in more than one aligned clause.
11291  if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
11292  Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange;
11293  Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
11294  << getOpenMPClauseName(OMPC_aligned);
11295  continue;
11296  }
11297 
11298  DeclRefExpr *Ref = nullptr;
11299  if (!VD && isOpenMPCapturedDecl(D))
11300  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
11301  Vars.push_back(DefaultFunctionArrayConversion(
11302  (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
11303  .get());
11304  }
11305 
11306  // OpenMP [2.8.1, simd construct, Description]
11307  // The parameter of the aligned clause, alignment, must be a constant
11308  // positive integer expression.
11309  // If no optional parameter is specified, implementation-defined default
11310  // alignments for SIMD instructions on the target platforms are assumed.
11311  if (Alignment != nullptr) {
11312  ExprResult AlignResult =
11313  VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
11314  if (AlignResult.isInvalid())
11315  return nullptr;
11316  Alignment = AlignResult.get();
11317  }
11318  if (Vars.empty())
11319  return nullptr;
11320 
11321  return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
11322  EndLoc, Vars, Alignment);
11323 }
11324 
11326  SourceLocation StartLoc,
11327  SourceLocation LParenLoc,
11328  SourceLocation EndLoc) {
11330  SmallVector<Expr *, 8> SrcExprs;
11331  SmallVector<Expr *, 8> DstExprs;
11332  SmallVector<Expr *, 8> AssignmentOps;
11333  for (Expr *RefExpr : VarList) {
11334  assert(RefExpr && "NULL expr in OpenMP copyin clause.");
11335  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
11336  // It will be analyzed later.
11337  Vars.push_back(RefExpr);
11338  SrcExprs.push_back(nullptr);
11339  DstExprs.push_back(nullptr);
11340  AssignmentOps.push_back(nullptr);
11341  continue;
11342  }
11343 
11344  SourceLocation ELoc = RefExpr->getExprLoc();
11345  // OpenMP [2.1, C/C++]
11346  // A list item is a variable name.
11347  // OpenMP [2.14.4.1, Restrictions, p.1]
11348  // A list item that appears in a copyin clause must be threadprivate.
11349  auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
11350  if (!DE || !isa<VarDecl>(DE->getDecl())) {
11351  Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
11352  << 0 << RefExpr->getSourceRange();
11353  continue;
11354  }
11355 
11356  Decl *D = DE->getDecl();
11357  auto *VD = cast<VarDecl>(D);
11358 
11359  QualType Type = VD->getType();
11360  if (Type->isDependentType() || Type->isInstantiationDependentType()) {
11361  // It will be analyzed later.
11362  Vars.push_back(DE);
11363  SrcExprs.push_back(nullptr);
11364  DstExprs.push_back(nullptr);
11365  AssignmentOps.push_back(nullptr);
11366  continue;
11367  }
11368 
11369  // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
11370  // A list item that appears in a copyin clause must be threadprivate.
11371  if (!DSAStack->isThreadPrivate(VD)) {
11372  Diag(ELoc, diag::err_omp_required_access)
11373  << getOpenMPClauseName(OMPC_copyin)
11374  << getOpenMPDirectiveName(OMPD_threadprivate);
11375  continue;
11376  }
11377 
11378  // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
11379  // A variable of class type (or array thereof) that appears in a
11380  // copyin clause requires an accessible, unambiguous copy assignment
11381  // operator for the class type.
11382  QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
11383  VarDecl *SrcVD =
11384  buildVarDecl(*this, DE->getLocStart(), ElemType.getUnqualifiedType(),
11385  ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
11386  DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
11387  *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
11388  VarDecl *DstVD =
11389  buildVarDecl(*this, DE->getLocStart(), ElemType, ".copyin.dst",
11390  VD->hasAttrs() ? &VD->getAttrs() : nullptr);
11391  DeclRefExpr *PseudoDstExpr =
11392  buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
11393  // For arrays generate assignment operation for single element and replace
11394  // it by the original array element in CodeGen.
11395  ExprResult AssignmentOp =
11396  BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
11397  PseudoSrcExpr);
11398  if (AssignmentOp.isInvalid())
11399  continue;
11400  AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
11401  /*DiscardedValue=*/true);
11402  if (AssignmentOp.isInvalid())
11403  continue;
11404 
11405  DSAStack->addDSA(VD, DE, OMPC_copyin);
11406  Vars.push_back(DE);
11407  SrcExprs.push_back(PseudoSrcExpr);
11408  DstExprs.push_back(PseudoDstExpr);
11409  AssignmentOps.push_back(AssignmentOp.get());
11410  }
11411 
11412  if (Vars.empty())
11413  return nullptr;
11414 
11415  return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
11416  SrcExprs, DstExprs, AssignmentOps);
11417 }
11418 
11420  SourceLocation StartLoc,
11421  SourceLocation LParenLoc,
11422  SourceLocation EndLoc) {
11424  SmallVector<Expr *, 8> SrcExprs;
11425  SmallVector<Expr *, 8> DstExprs;
11426  SmallVector<Expr *, 8> AssignmentOps;
11427  for (Expr *RefExpr : VarList) {
11428  assert(RefExpr && "NULL expr in OpenMP linear clause.");
11429  SourceLocation ELoc;
11430  SourceRange ERange;
11431  Expr *SimpleRefExpr = RefExpr;
11432  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
11433  /*AllowArraySection=*/false);
11434  if (Res.second) {
11435  // It will be analyzed later.
11436  Vars.push_back(RefExpr);
11437  SrcExprs.push_back(nullptr);
11438  DstExprs.push_back(nullptr);
11439  AssignmentOps.push_back(nullptr);
11440  }
11441  ValueDecl *D = Res.first;
11442  if (!D)
11443  continue;
11444 
11445  QualType Type = D->getType();
11446  auto *VD = dyn_cast<VarDecl>(D);
11447 
11448  // OpenMP [2.14.4.2, Restrictions, p.2]
11449  // A list item that appears in a copyprivate clause may not appear in a
11450  // private or firstprivate clause on the single construct.
11451  if (!VD || !DSAStack->isThreadPrivate(VD)) {
11452  DSAStackTy::DSAVarData DVar =
11453  DSAStack->getTopDSA(D, /*FromParent=*/false);
11454  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
11455  DVar.RefExpr) {
11456  Diag(ELoc, diag::err_omp_wrong_dsa)
11457  << getOpenMPClauseName(DVar.CKind)
11458  << getOpenMPClauseName(OMPC_copyprivate);
11459  reportOriginalDsa(*this, DSAStack, D, DVar);
11460  continue;
11461  }
11462 
11463  // OpenMP [2.11.4.2, Restrictions, p.1]
11464  // All list items that appear in a copyprivate clause must be either
11465  // threadprivate or private in the enclosing context.
11466  if (DVar.CKind == OMPC_unknown) {
11467  DVar = DSAStack->getImplicitDSA(D, false);
11468  if (DVar.CKind == OMPC_shared) {
11469  Diag(ELoc, diag::err_omp_required_access)
11470  << getOpenMPClauseName(OMPC_copyprivate)
11471  << "threadprivate or private in the enclosing context";
11472  reportOriginalDsa(*this, DSAStack, D, DVar);
11473  continue;
11474  }
11475  }
11476  }
11477 
11478  // Variably modified types are not supported.
11479  if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
11480  Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
11481  << getOpenMPClauseName(OMPC_copyprivate) << Type
11482  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
11483  bool IsDecl =
11484  !VD ||
11485  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
11486  Diag(D->getLocation(),
11487  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11488  << D;
11489  continue;
11490  }
11491 
11492  // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
11493  // A variable of class type (or array thereof) that appears in a
11494  // copyin clause requires an accessible, unambiguous copy assignment
11495  // operator for the class type.
11496  Type = Context.getBaseElementType(Type.getNonReferenceType())
11497  .getUnqualifiedType();
11498  VarDecl *SrcVD =
11499  buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.src",
11500  D->hasAttrs() ? &D->getAttrs() : nullptr);
11501  DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
11502  VarDecl *DstVD =
11503  buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.dst",
11504  D->hasAttrs() ? &D->getAttrs() : nullptr);
11505  DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
11506  ExprResult AssignmentOp = BuildBinOp(
11507  DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
11508  if (AssignmentOp.isInvalid())
11509  continue;
11510  AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc,
11511  /*DiscardedValue=*/true);
11512  if (AssignmentOp.isInvalid())
11513  continue;
11514 
11515  // No need to mark vars as copyprivate, they are already threadprivate or
11516  // implicitly private.
11517  assert(VD || isOpenMPCapturedDecl(D));
11518  Vars.push_back(
11519  VD ? RefExpr->IgnoreParens()
11520  : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
11521  SrcExprs.push_back(PseudoSrcExpr);
11522  DstExprs.push_back(PseudoDstExpr);
11523  AssignmentOps.push_back(AssignmentOp.get());
11524  }
11525 
11526  if (Vars.empty())
11527  return nullptr;
11528 
11529  return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
11530  Vars, SrcExprs, DstExprs, AssignmentOps);
11531 }
11532 
11534  SourceLocation StartLoc,
11535  SourceLocation LParenLoc,
11536  SourceLocation EndLoc) {
11537  if (VarList.empty())
11538  return nullptr;
11539 
11540  return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
11541 }
11542 
11543 OMPClause *
11546  ArrayRef<Expr *> VarList, SourceLocation StartLoc,
11547  SourceLocation LParenLoc, SourceLocation EndLoc) {
11548  if (DSAStack->getCurrentDirective() == OMPD_ordered &&
11549  DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
11550  Diag(DepLoc, diag::err_omp_unexpected_clause_value)
11551  << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
11552  return nullptr;
11553  }
11554  if (DSAStack->getCurrentDirective() != OMPD_ordered &&
11555  (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
11556  DepKind == OMPC_DEPEND_sink)) {
11557  unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink};
11558  Diag(DepLoc, diag::err_omp_unexpected_clause_value)
11559  << getListOfPossibleValues(OMPC_depend, /*First=*/0,
11560  /*Last=*/OMPC_DEPEND_unknown, Except)
11561  << getOpenMPClauseName(OMPC_depend);
11562  return nullptr;
11563  }
11566  llvm::APSInt DepCounter(/*BitWidth=*/32);
11567  llvm::APSInt TotalDepCount(/*BitWidth=*/32);
11568  if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
11569  if (const Expr *OrderedCountExpr =
11570  DSAStack->getParentOrderedRegionParam().first) {
11571  TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
11572  TotalDepCount.setIsUnsigned(/*Val=*/true);
11573  }
11574  }
11575  for (Expr *RefExpr : VarList) {
11576  assert(RefExpr && "NULL expr in OpenMP shared clause.");
11577  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
11578  // It will be analyzed later.
11579  Vars.push_back(RefExpr);
11580  continue;
11581  }
11582 
11583  SourceLocation ELoc = RefExpr->getExprLoc();
11584  Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
11585  if (DepKind == OMPC_DEPEND_sink) {
11586  if (DSAStack->getParentOrderedRegionParam().first &&
11587  DepCounter >= TotalDepCount) {
11588  Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
11589  continue;
11590  }
11591  ++DepCounter;
11592  // OpenMP [2.13.9, Summary]
11593  // depend(dependence-type : vec), where dependence-type is:
11594  // 'sink' and where vec is the iteration vector, which has the form:
11595  // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
11596  // where n is the value specified by the ordered clause in the loop
11597  // directive, xi denotes the loop iteration variable of the i-th nested
11598  // loop associated with the loop directive, and di is a constant
11599  // non-negative integer.
11600  if (CurContext->isDependentContext()) {
11601  // It will be analyzed later.
11602  Vars.push_back(RefExpr);
11603  continue;
11604  }
11605  SimpleExpr = SimpleExpr->IgnoreImplicit();
11607  SourceLocation OOLoc;
11608  Expr *LHS = SimpleExpr;
11609  Expr *RHS = nullptr;
11610  if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
11611  OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
11612  OOLoc = BO->getOperatorLoc();
11613  LHS = BO->getLHS()->IgnoreParenImpCasts();
11614  RHS = BO->getRHS()->IgnoreParenImpCasts();
11615  } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
11616  OOK = OCE->getOperator();
11617  OOLoc = OCE->getOperatorLoc();
11618  LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
11619  RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
11620  } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
11621  OOK = MCE->getMethodDecl()
11622  ->getNameInfo()
11623  .getName()
11624  .getCXXOverloadedOperator();
11625  OOLoc = MCE->getCallee()->getExprLoc();
11626  LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
11627  RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
11628  }
11629  SourceLocation ELoc;
11630  SourceRange ERange;
11631  auto Res = getPrivateItem(*this, LHS, ELoc, ERange,
11632  /*AllowArraySection=*/false);
11633  if (Res.second) {
11634  // It will be analyzed later.
11635  Vars.push_back(RefExpr);
11636  }
11637  ValueDecl *D = Res.first;
11638  if (!D)
11639  continue;
11640 
11641  if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
11642  Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
11643  continue;
11644  }
11645  if (RHS) {
11646  ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
11647  RHS, OMPC_depend, /*StrictlyPositive=*/false);
11648  if (RHSRes.isInvalid())
11649  continue;
11650  }
11651  if (!CurContext->isDependentContext() &&
11652  DSAStack->getParentOrderedRegionParam().first &&
11653  DepCounter != DSAStack->isParentLoopControlVariable(D).first) {
11654  const ValueDecl *VD =
11655  DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue());
11656  if (VD)
11657  Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
11658  << 1 << VD;
11659  else
11660  Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
11661  continue;
11662  }
11663  OpsOffs.emplace_back(RHS, OOK);
11664  } else {
11665  auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
11666  if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
11667  (ASE &&
11668  !ASE->getBase()->getType().getNonReferenceType()->isPointerType() &&
11669  !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
11670  Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
11671  << RefExpr->getSourceRange();
11672  continue;
11673  }
11674  bool Suppress = getDiagnostics().getSuppressAllDiagnostics();
11675  getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
11676  ExprResult Res =
11677  CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RefExpr->IgnoreParenImpCasts());
11678  getDiagnostics().setSuppressAllDiagnostics(Suppress);
11679  if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) {
11680  Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
11681  << RefExpr->getSourceRange();
11682  continue;
11683  }
11684  }
11685  Vars.push_back(RefExpr->IgnoreParenImpCasts());
11686  }
11687 
11688  if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
11689  TotalDepCount > VarList.size() &&
11690  DSAStack->getParentOrderedRegionParam().first &&
11691  DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
11692  Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
11693  << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1);
11694  }
11695  if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
11696  Vars.empty())
11697  return nullptr;
11698 
11699  auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
11700  DepKind, DepLoc, ColonLoc, Vars,
11701  TotalDepCount.getZExtValue());
11702  if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
11703  DSAStack->isParentOrderedRegion())
11704  DSAStack->addDoacrossDependClause(C, OpsOffs);
11705  return C;
11706 }
11707 
11709  SourceLocation LParenLoc,
11710  SourceLocation EndLoc) {
11711  Expr *ValExpr = Device;
11712  Stmt *HelperValStmt = nullptr;
11713 
11714  // OpenMP [2.9.1, Restrictions]
11715  // The device expression must evaluate to a non-negative integer value.
11716  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
11717  /*StrictlyPositive=*/false))
11718  return nullptr;
11719 
11720  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
11721  OpenMPDirectiveKind CaptureRegion =
11722  getOpenMPCaptureRegionForClause(DKind, OMPC_device);
11723  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
11724  ValExpr = MakeFullExpr(ValExpr).get();
11725  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
11726  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
11727  HelperValStmt = buildPreInits(Context, Captures);
11728  }
11729 
11730  return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion,
11731  StartLoc, LParenLoc, EndLoc);
11732 }
11733 
11734 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
11735  DSAStackTy *Stack, QualType QTy,
11736  bool FullCheck = true) {
11737  NamedDecl *ND;
11738  if (QTy->isIncompleteType(&ND)) {
11739  SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR;
11740  return false;
11741  }
11742  if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
11743  !QTy.isTrivialType(SemaRef.Context))
11744  SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
11745  return true;
11746 }
11747 
11748 /// Return true if it can be proven that the provided array expression
11749 /// (array section or array subscript) does NOT specify the whole size of the
11750 /// array whose base type is \a BaseQTy.
11752  const Expr *E,
11753  QualType BaseQTy) {
11754  const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
11755 
11756  // If this is an array subscript, it refers to the whole size if the size of
11757  // the dimension is constant and equals 1. Also, an array section assumes the
11758  // format of an array subscript if no colon is used.
11759  if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) {
11760  if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
11761  return ATy->getSize().getSExtValue() != 1;
11762  // Size can't be evaluated statically.
11763  return false;
11764  }
11765 
11766  assert(OASE && "Expecting array section if not an array subscript.");
11767  const Expr *LowerBound = OASE->getLowerBound();
11768  const Expr *Length = OASE->getLength();
11769 
11770  // If there is a lower bound that does not evaluates to zero, we are not
11771  // covering the whole dimension.
11772  if (LowerBound) {
11773  llvm::APSInt ConstLowerBound;
11774  if (!LowerBound->EvaluateAsInt(ConstLowerBound, SemaRef.getASTContext()))
11775  return false; // Can't get the integer value as a constant.
11776  if (ConstLowerBound.getSExtValue())
11777  return true;
11778  }
11779 
11780  // If we don't have a length we covering the whole dimension.
11781  if (!Length)
11782  return false;
11783 
11784  // If the base is a pointer, we don't have a way to get the size of the
11785  // pointee.
11786  if (BaseQTy->isPointerType())
11787  return false;
11788 
11789  // We can only check if the length is the same as the size of the dimension
11790  // if we have a constant array.
11791  const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
11792  if (!CATy)
11793  return false;
11794 
11795  llvm::APSInt ConstLength;
11796  if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext()))
11797  return false; // Can't get the integer value as a constant.
11798 
11799  return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
11800 }
11801 
11802 // Return true if it can be proven that the provided array expression (array
11803 // section or array subscript) does NOT specify a single element of the array
11804 // whose base type is \a BaseQTy.
11806  const Expr *E,
11807  QualType BaseQTy) {
11808  const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
11809 
11810  // An array subscript always refer to a single element. Also, an array section
11811  // assumes the format of an array subscript if no colon is used.
11812  if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid()))
11813  return false;
11814 
11815  assert(OASE && "Expecting array section if not an array subscript.");
11816  const Expr *Length = OASE->getLength();
11817 
11818  // If we don't have a length we have to check if the array has unitary size
11819  // for this dimension. Also, we should always expect a length if the base type
11820  // is pointer.
11821  if (!Length) {
11822  if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
11823  return ATy->getSize().getSExtValue() != 1;
11824  // We cannot assume anything.
11825  return false;
11826  }
11827 
11828  // Check if the length evaluates to 1.
11829  llvm::APSInt ConstLength;
11830  if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext()))
11831  return false; // Can't get the integer value as a constant.
11832 
11833  return ConstLength.getSExtValue() != 1;
11834 }
11835 
11836 // Return the expression of the base of the mappable expression or null if it
11837 // cannot be determined and do all the necessary checks to see if the expression
11838 // is valid as a standalone mappable expression. In the process, record all the
11839 // components of the expression.
11841  Sema &SemaRef, Expr *E,
11843  OpenMPClauseKind CKind, bool NoDiagnose) {
11844  SourceLocation ELoc = E->getExprLoc();
11845  SourceRange ERange = E->getSourceRange();
11846 
11847  // The base of elements of list in a map clause have to be either:
11848  // - a reference to variable or field.
11849  // - a member expression.
11850  // - an array expression.
11851  //
11852  // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
11853  // reference to 'r'.
11854  //
11855  // If we have:
11856  //
11857  // struct SS {
11858  // Bla S;
11859  // foo() {
11860  // #pragma omp target map (S.Arr[:12]);
11861  // }
11862  // }
11863  //
11864  // We want to retrieve the member expression 'this->S';
11865 
11866  const Expr *RelevantExpr = nullptr;
11867 
11868  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2]
11869  // If a list item is an array section, it must specify contiguous storage.
11870  //
11871  // For this restriction it is sufficient that we make sure only references
11872  // to variables or fields and array expressions, and that no array sections
11873  // exist except in the rightmost expression (unless they cover the whole
11874  // dimension of the array). E.g. these would be invalid:
11875  //
11876  // r.ArrS[3:5].Arr[6:7]
11877  //
11878  // r.ArrS[3:5].x
11879  //
11880  // but these would be valid:
11881  // r.ArrS[3].Arr[6:7]
11882  //
11883  // r.ArrS[3].x
11884 
11885  bool AllowUnitySizeArraySection = true;
11886  bool AllowWholeSizeArraySection = true;
11887 
11888  while (!RelevantExpr) {
11889  E = E->IgnoreParenImpCasts();
11890 
11891  if (auto *CurE = dyn_cast<DeclRefExpr>(E)) {
11892  if (!isa<VarDecl>(CurE->getDecl()))
11893  return nullptr;
11894 
11895  RelevantExpr = CurE;
11896 
11897  // If we got a reference to a declaration, we should not expect any array
11898  // section before that.
11899  AllowUnitySizeArraySection = false;
11900  AllowWholeSizeArraySection = false;
11901 
11902  // Record the component.
11903  CurComponents.emplace_back(CurE, CurE->getDecl());
11904  } else if (auto *CurE = dyn_cast<MemberExpr>(E)) {
11905  Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts();
11906 
11907  if (isa<CXXThisExpr>(BaseE))
11908  // We found a base expression: this->Val.
11909  RelevantExpr = CurE;
11910  else
11911  E = BaseE;
11912 
11913  if (!isa<FieldDecl>(CurE->getMemberDecl())) {
11914  if (!NoDiagnose) {
11915  SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
11916  << CurE->getSourceRange();
11917  return nullptr;
11918  }
11919  if (RelevantExpr)
11920  return nullptr;
11921  continue;
11922  }
11923 
11924  auto *FD = cast<FieldDecl>(CurE->getMemberDecl());
11925 
11926  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
11927  // A bit-field cannot appear in a map clause.
11928  //
11929  if (FD->isBitField()) {
11930  if (!NoDiagnose) {
11931  SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
11932  << CurE->getSourceRange() << getOpenMPClauseName(CKind);
11933  return nullptr;
11934  }
11935  if (RelevantExpr)
11936  return nullptr;
11937  continue;
11938  }
11939 
11940  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
11941  // If the type of a list item is a reference to a type T then the type
11942  // will be considered to be T for all purposes of this clause.
11943  QualType CurType = BaseE->getType().getNonReferenceType();
11944 
11945  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
11946  // A list item cannot be a variable that is a member of a structure with
11947  // a union type.
11948  //
11949  if (CurType->isUnionType()) {
11950  if (!NoDiagnose) {
11951  SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
11952  << CurE->getSourceRange();
11953  return nullptr;
11954  }
11955  continue;
11956  }
11957 
11958  // If we got a member expression, we should not expect any array section
11959  // before that:
11960  //
11961  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
11962  // If a list item is an element of a structure, only the rightmost symbol
11963  // of the variable reference can be an array section.
11964  //
11965  AllowUnitySizeArraySection = false;
11966  AllowWholeSizeArraySection = false;
11967 
11968  // Record the component.
11969  CurComponents.emplace_back(CurE, FD);
11970  } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) {
11971  E = CurE->getBase()->IgnoreParenImpCasts();
11972 
11973  if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
11974  if (!NoDiagnose) {
11975  SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
11976  << 0 << CurE->getSourceRange();
11977  return nullptr;
11978  }
11979  continue;
11980  }
11981 
11982  // If we got an array subscript that express the whole dimension we
11983  // can have any array expressions before. If it only expressing part of
11984  // the dimension, we can only have unitary-size array expressions.
11986  E->getType()))
11987  AllowWholeSizeArraySection = false;
11988 
11989  // Record the component - we don't have any declaration associated.
11990  CurComponents.emplace_back(CurE, nullptr);
11991  } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) {
11992  assert(!NoDiagnose && "Array sections cannot be implicitly mapped.");
11993  E = CurE->getBase()->IgnoreParenImpCasts();
11994 
11995  QualType CurType =
11997 
11998  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
11999  // If the type of a list item is a reference to a type T then the type
12000  // will be considered to be T for all purposes of this clause.
12001  if (CurType->isReferenceType())
12002  CurType = CurType->getPointeeType();
12003 
12004  bool IsPointer = CurType->isAnyPointerType();
12005 
12006  if (!IsPointer && !CurType->isArrayType()) {
12007  SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
12008  << 0 << CurE->getSourceRange();
12009  return nullptr;
12010  }
12011 
12012  bool NotWhole =
12013  checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType);
12014  bool NotUnity =
12015  checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType);
12016 
12017  if (AllowWholeSizeArraySection) {
12018  // Any array section is currently allowed. Allowing a whole size array
12019  // section implies allowing a unity array section as well.
12020  //
12021  // If this array section refers to the whole dimension we can still
12022  // accept other array sections before this one, except if the base is a
12023  // pointer. Otherwise, only unitary sections are accepted.
12024  if (NotWhole || IsPointer)
12025  AllowWholeSizeArraySection = false;
12026  } else if (AllowUnitySizeArraySection && NotUnity) {
12027  // A unity or whole array section is not allowed and that is not
12028  // compatible with the properties of the current array section.
12029  SemaRef.Diag(
12030  ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
12031  << CurE->getSourceRange();
12032  return nullptr;
12033  }
12034 
12035  // Record the component - we don't have any declaration associated.
12036  CurComponents.emplace_back(CurE, nullptr);
12037  } else {
12038  if (!NoDiagnose) {
12039  // If nothing else worked, this is not a valid map clause expression.
12040  SemaRef.Diag(
12041  ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
12042  << ERange;
12043  }
12044  return nullptr;
12045  }
12046  }
12047 
12048  return RelevantExpr;
12049 }
12050 
12051 // Return true if expression E associated with value VD has conflicts with other
12052 // map information.
12053 static bool checkMapConflicts(
12054  Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
12055  bool CurrentRegionOnly,
12057  OpenMPClauseKind CKind) {
12058  assert(VD && E);
12059  SourceLocation ELoc = E->getExprLoc();
12060  SourceRange ERange = E->getSourceRange();
12061 
12062  // In order to easily check the conflicts we need to match each component of
12063  // the expression under test with the components of the expressions that are
12064  // already in the stack.
12065 
12066  assert(!CurComponents.empty() && "Map clause expression with no components!");
12067  assert(CurComponents.back().getAssociatedDeclaration() == VD &&
12068  "Map clause expression with unexpected base!");
12069 
12070  // Variables to help detecting enclosing problems in data environment nests.
12071  bool IsEnclosedByDataEnvironmentExpr = false;
12072  const Expr *EnclosingExpr = nullptr;
12073 
12074  bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
12075  VD, CurrentRegionOnly,
12076  [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
12077  ERange, CKind, &EnclosingExpr,
12079  StackComponents,
12080  OpenMPClauseKind) {
12081  assert(!StackComponents.empty() &&
12082  "Map clause expression with no components!");
12083  assert(StackComponents.back().getAssociatedDeclaration() == VD &&
12084  "Map clause expression with unexpected base!");
12085  (void)VD;
12086 
12087  // The whole expression in the stack.
12088  const Expr *RE = StackComponents.front().getAssociatedExpression();
12089 
12090  // Expressions must start from the same base. Here we detect at which
12091  // point both expressions diverge from each other and see if we can
12092  // detect if the memory referred to both expressions is contiguous and
12093  // do not overlap.
12094  auto CI = CurComponents.rbegin();
12095  auto CE = CurComponents.rend();
12096  auto SI = StackComponents.rbegin();
12097  auto SE = StackComponents.rend();
12098  for (; CI != CE && SI != SE; ++CI, ++SI) {
12099 
12100  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
12101  // At most one list item can be an array item derived from a given
12102  // variable in map clauses of the same construct.
12103  if (CurrentRegionOnly &&
12104  (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
12105  isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) &&
12106  (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
12107  isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) {
12108  SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
12109  diag::err_omp_multiple_array_items_in_map_clause)
12110  << CI->getAssociatedExpression()->getSourceRange();
12111  SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
12112  diag::note_used_here)
12113  << SI->getAssociatedExpression()->getSourceRange();
12114  return true;
12115  }
12116 
12117  // Do both expressions have the same kind?
12118  if (CI->getAssociatedExpression()->getStmtClass() !=
12119  SI->getAssociatedExpression()->getStmtClass())
12120  break;
12121 
12122  // Are we dealing with different variables/fields?
12123  if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
12124  break;
12125  }
12126  // Check if the extra components of the expressions in the enclosing
12127  // data environment are redundant for the current base declaration.
12128  // If they are, the maps completely overlap, which is legal.
12129  for (; SI != SE; ++SI) {
12130  QualType Type;
12131  if (const auto *ASE =
12132  dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
12133  Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
12134  } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
12135  SI->getAssociatedExpression())) {
12136  const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
12137  Type =
12139  }
12140  if (Type.isNull() || Type->isAnyPointerType() ||
12142  SemaRef, SI->getAssociatedExpression(), Type))
12143  break;
12144  }
12145 
12146  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
12147  // List items of map clauses in the same construct must not share
12148  // original storage.
12149  //
12150  // If the expressions are exactly the same or one is a subset of the
12151  // other, it means they are sharing storage.
12152  if (CI == CE && SI == SE) {
12153  if (CurrentRegionOnly) {
12154  if (CKind == OMPC_map) {
12155  SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
12156  } else {
12157  assert(CKind == OMPC_to || CKind == OMPC_from);
12158  SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
12159  << ERange;
12160  }
12161  SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
12162  << RE->getSourceRange();
12163  return true;
12164  }
12165  // If we find the same expression in the enclosing data environment,
12166  // that is legal.
12167  IsEnclosedByDataEnvironmentExpr = true;
12168  return false;
12169  }
12170 
12171  QualType DerivedType =
12172  std::prev(CI)->getAssociatedDeclaration()->getType();
12173  SourceLocation DerivedLoc =
12174  std::prev(CI)->getAssociatedExpression()->getExprLoc();
12175 
12176  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
12177  // If the type of a list item is a reference to a type T then the type
12178  // will be considered to be T for all purposes of this clause.
12179  DerivedType = DerivedType.getNonReferenceType();
12180 
12181  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
12182  // A variable for which the type is pointer and an array section
12183  // derived from that variable must not appear as list items of map
12184  // clauses of the same construct.
12185  //
12186  // Also, cover one of the cases in:
12187  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
12188  // If any part of the original storage of a list item has corresponding
12189  // storage in the device data environment, all of the original storage
12190  // must have corresponding storage in the device data environment.
12191  //
12192  if (DerivedType->isAnyPointerType()) {
12193  if (CI == CE || SI == SE) {
12194  SemaRef.Diag(
12195  DerivedLoc,
12196  diag::err_omp_pointer_mapped_along_with_derived_section)
12197  << DerivedLoc;
12198  SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
12199  << RE->getSourceRange();
12200  return true;
12201  }
12202  if (CI->getAssociatedExpression()->getStmtClass() !=
12203  SI->getAssociatedExpression()->getStmtClass() ||
12204  CI->getAssociatedDeclaration()->getCanonicalDecl() ==
12205  SI->getAssociatedDeclaration()->getCanonicalDecl()) {
12206  assert(CI != CE && SI != SE);
12207  SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
12208  << DerivedLoc;
12209  SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
12210  << RE->getSourceRange();
12211  return true;
12212  }
12213  }
12214 
12215  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
12216  // List items of map clauses in the same construct must not share
12217  // original storage.
12218  //
12219  // An expression is a subset of the other.
12220  if (CurrentRegionOnly && (CI == CE || SI == SE)) {
12221  if (CKind == OMPC_map) {
12222  SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
12223  } else {
12224  assert(CKind == OMPC_to || CKind == OMPC_from);
12225  SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
12226  << ERange;
12227  }
12228  SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
12229  << RE->getSourceRange();
12230  return true;
12231  }
12232 
12233  // The current expression uses the same base as other expression in the
12234  // data environment but does not contain it completely.
12235  if (!CurrentRegionOnly && SI != SE)
12236  EnclosingExpr = RE;
12237 
12238  // The current expression is a subset of the expression in the data
12239  // environment.
12240  IsEnclosedByDataEnvironmentExpr |=
12241  (!CurrentRegionOnly && CI != CE && SI == SE);
12242 
12243  return false;
12244  });
12245 
12246  if (CurrentRegionOnly)
12247  return FoundError;
12248 
12249  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
12250  // If any part of the original storage of a list item has corresponding
12251  // storage in the device data environment, all of the original storage must
12252  // have corresponding storage in the device data environment.
12253  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
12254  // If a list item is an element of a structure, and a different element of
12255  // the structure has a corresponding list item in the device data environment
12256  // prior to a task encountering the construct associated with the map clause,
12257  // then the list item must also have a corresponding list item in the device
12258  // data environment prior to the task encountering the construct.
12259  //
12260  if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
12261  SemaRef.Diag(ELoc,
12262  diag::err_omp_original_storage_is_shared_and_does_not_contain)
12263  << ERange;
12264  SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
12265  << EnclosingExpr->getSourceRange();
12266  return true;
12267  }
12268 
12269  return FoundError;
12270 }
12271 
12272 namespace {
12273 // Utility struct that gathers all the related lists associated with a mappable
12274 // expression.
12275 struct MappableVarListInfo {
12276  // The list of expressions.
12277  ArrayRef<Expr *> VarList;
12278  // The list of processed expressions.
12279  SmallVector<Expr *, 16> ProcessedVarList;
12280  // The mappble components for each expression.
12282  // The base declaration of the variable.
12283  SmallVector<ValueDecl *, 16> VarBaseDeclarations;
12284 
12285  MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
12286  // We have a list of components and base declarations for each entry in the
12287  // variable list.
12288  VarComponents.reserve(VarList.size());
12289  VarBaseDeclarations.reserve(VarList.size());
12290  }
12291 };
12292 }
12293 
12294 // Check the validity of the provided variable list for the provided clause kind
12295 // \a CKind. In the check process the valid expressions, and mappable expression
12296 // components and variables are extracted and used to fill \a Vars,
12297 // \a ClauseComponents, and \a ClauseBaseDeclarations. \a MapType and
12298 // \a IsMapTypeImplicit are expected to be valid if the clause kind is 'map'.
12299 static void
12300 checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS,
12301  OpenMPClauseKind CKind, MappableVarListInfo &MVLI,
12302  SourceLocation StartLoc,
12304  bool IsMapTypeImplicit = false) {
12305  // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
12306  assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
12307  "Unexpected clause kind with mappable expressions!");
12308 
12309  // Keep track of the mappable components and base declarations in this clause.
12310  // Each entry in the list is going to have a list of components associated. We
12311  // record each set of the components so that we can build the clause later on.
12312  // In the end we should have the same amount of declarations and component
12313  // lists.
12314 
12315  for (Expr *RE : MVLI.VarList) {
12316  assert(RE && "Null expr in omp to/from/map clause");
12317  SourceLocation ELoc = RE->getExprLoc();
12318 
12319  const Expr *VE = RE->IgnoreParenLValueCasts();
12320 
12321  if (VE->isValueDependent() || VE->isTypeDependent() ||
12322  VE->isInstantiationDependent() ||
12324  // We can only analyze this information once the missing information is
12325  // resolved.
12326  MVLI.ProcessedVarList.push_back(RE);
12327  continue;
12328  }
12329 
12330  Expr *SimpleExpr = RE->IgnoreParenCasts();
12331 
12332  if (!RE->IgnoreParenImpCasts()->isLValue()) {
12333  SemaRef.Diag(ELoc,
12334  diag::err_omp_expected_named_var_member_or_array_expression)
12335  << RE->getSourceRange();
12336  continue;
12337  }
12338 
12340  ValueDecl *CurDeclaration = nullptr;
12341 
12342  // Obtain the array or member expression bases if required. Also, fill the
12343  // components array with all the components identified in the process.
12344  const Expr *BE = checkMapClauseExpressionBase(
12345  SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false);
12346  if (!BE)
12347  continue;
12348 
12349  assert(!CurComponents.empty() &&
12350  "Invalid mappable expression information.");
12351 
12352  // For the following checks, we rely on the base declaration which is
12353  // expected to be associated with the last component. The declaration is
12354  // expected to be a variable or a field (if 'this' is being mapped).
12355  CurDeclaration = CurComponents.back().getAssociatedDeclaration();
12356  assert(CurDeclaration && "Null decl on map clause.");
12357  assert(
12358  CurDeclaration->isCanonicalDecl() &&
12359  "Expecting components to have associated only canonical declarations.");
12360 
12361  auto *VD = dyn_cast<VarDecl>(CurDeclaration);
12362  const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
12363 
12364  assert((VD || FD) && "Only variables or fields are expected here!");
12365  (void)FD;
12366 
12367  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
12368  // threadprivate variables cannot appear in a map clause.
12369  // OpenMP 4.5 [2.10.5, target update Construct]
12370  // threadprivate variables cannot appear in a from clause.
12371  if (VD && DSAS->isThreadPrivate(VD)) {
12372  DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
12373  SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
12374  << getOpenMPClauseName(CKind);
12375  reportOriginalDsa(SemaRef, DSAS, VD, DVar);
12376  continue;
12377  }
12378 
12379  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
12380  // A list item cannot appear in both a map clause and a data-sharing
12381  // attribute clause on the same construct.
12382 
12383  // Check conflicts with other map clause expressions. We check the conflicts
12384  // with the current construct separately from the enclosing data
12385  // environment, because the restrictions are different. We only have to
12386  // check conflicts across regions for the map clauses.
12387  if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
12388  /*CurrentRegionOnly=*/true, CurComponents, CKind))
12389  break;
12390  if (CKind == OMPC_map &&
12391  checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
12392  /*CurrentRegionOnly=*/false, CurComponents, CKind))
12393  break;
12394 
12395  // OpenMP 4.5 [2.10.5, target update Construct]
12396  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
12397  // If the type of a list item is a reference to a type T then the type will
12398  // be considered to be T for all purposes of this clause.
12399  auto I = llvm::find_if(
12400  CurComponents,
12402  return MC.getAssociatedDeclaration();
12403  });
12404  assert(I != CurComponents.end() && "Null decl on map clause.");
12405  QualType Type =
12406  I->getAssociatedDeclaration()->getType().getNonReferenceType();
12407 
12408  // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
12409  // A list item in a to or from clause must have a mappable type.
12410  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
12411  // A list item must have a mappable type.
12412  if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
12413  DSAS, Type))
12414  continue;
12415 
12416  if (CKind == OMPC_map) {
12417  // target enter data
12418  // OpenMP [2.10.2, Restrictions, p. 99]
12419  // A map-type must be specified in all map clauses and must be either
12420  // to or alloc.
12421  OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
12422  if (DKind == OMPD_target_enter_data &&
12423  !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
12424  SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
12425  << (IsMapTypeImplicit ? 1 : 0)
12426  << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
12427  << getOpenMPDirectiveName(DKind);
12428  continue;
12429  }
12430 
12431  // target exit_data
12432  // OpenMP [2.10.3, Restrictions, p. 102]
12433  // A map-type must be specified in all map clauses and must be either
12434  // from, release, or delete.
12435  if (DKind == OMPD_target_exit_data &&
12436  !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
12437  MapType == OMPC_MAP_delete)) {
12438  SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
12439  << (IsMapTypeImplicit ? 1 : 0)
12440  << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
12441  << getOpenMPDirectiveName(DKind);
12442  continue;
12443  }
12444 
12445  // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
12446  // A list item cannot appear in both a map clause and a data-sharing
12447  // attribute clause on the same construct
12448  if (VD && isOpenMPTargetExecutionDirective(DKind)) {
12449  DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
12450  if (isOpenMPPrivate(DVar.CKind)) {
12451  SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
12452  << getOpenMPClauseName(DVar.CKind)
12453  << getOpenMPClauseName(OMPC_map)
12454  << getOpenMPDirectiveName(DSAS->getCurrentDirective());
12455  reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
12456  continue;
12457  }
12458  }
12459  }
12460 
12461  // Save the current expression.
12462  MVLI.ProcessedVarList.push_back(RE);
12463 
12464  // Store the components in the stack so that they can be used to check
12465  // against other clauses later on.
12466  DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
12467  /*WhereFoundClauseKind=*/OMPC_map);
12468 
12469  // Save the components and declaration to create the clause. For purposes of
12470  // the clause creation, any component list that has has base 'this' uses
12471  // null as base declaration.
12472  MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
12473  MVLI.VarComponents.back().append(CurComponents.begin(),
12474  CurComponents.end());
12475  MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
12476  : CurDeclaration);
12477  }
12478 }
12479 
12480 OMPClause *
12482  OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
12484  ArrayRef<Expr *> VarList, SourceLocation StartLoc,
12485  SourceLocation LParenLoc, SourceLocation EndLoc) {
12486  MappableVarListInfo MVLI(VarList);
12487  checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, StartLoc,
12488  MapType, IsMapTypeImplicit);
12489 
12490  // We need to produce a map clause even if we don't have variables so that
12491  // other diagnostics related with non-existing map clauses are accurate.
12492  return OMPMapClause::Create(Context, StartLoc, LParenLoc, EndLoc,
12493  MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
12494  MVLI.VarComponents, MapTypeModifier, MapType,
12495  IsMapTypeImplicit, MapLoc);
12496 }
12497 
12500  assert(ParsedType.isUsable());
12501 
12502  QualType ReductionType = GetTypeFromParser(ParsedType.get());
12503  if (ReductionType.isNull())
12504  return QualType();
12505 
12506  // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
12507  // A type name in a declare reduction directive cannot be a function type, an
12508  // array type, a reference type, or a type qualified with const, volatile or
12509  // restrict.
12510  if (ReductionType.hasQualifiers()) {
12511  Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
12512  return QualType();
12513  }
12514 
12515  if (ReductionType->isFunctionType()) {
12516  Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
12517  return QualType();
12518  }
12519  if (ReductionType->isReferenceType()) {
12520  Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
12521  return QualType();
12522  }
12523  if (ReductionType->isArrayType()) {
12524  Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
12525  return QualType();
12526  }
12527  return ReductionType;
12528 }
12529 
12531  Scope *S, DeclContext *DC, DeclarationName Name,
12532  ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
12533  AccessSpecifier AS, Decl *PrevDeclInScope) {
12534  SmallVector<Decl *, 8> Decls;
12535  Decls.reserve(ReductionTypes.size());
12536 
12537  LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
12538  forRedeclarationInCurContext());
12539  // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
12540  // A reduction-identifier may not be re-declared in the current scope for the
12541  // same type or for a type that is compatible according to the base language
12542  // rules.
12543  llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
12544  OMPDeclareReductionDecl *PrevDRD = nullptr;
12545  bool InCompoundScope = true;
12546  if (S != nullptr) {
12547  // Find previous declaration with the same name not referenced in other
12548  // declarations.
12549  FunctionScopeInfo *ParentFn = getEnclosingFunction();
12550  InCompoundScope =
12551  (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
12552  LookupName(Lookup, S);
12553  FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
12554  /*AllowInlineNamespace=*/false);
12555  llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
12556  LookupResult::Filter Filter = Lookup.makeFilter();
12557  while (Filter.hasNext()) {
12558  auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
12559  if (InCompoundScope) {
12560  auto I = UsedAsPrevious.find(PrevDecl);
12561  if (I == UsedAsPrevious.end())
12562  UsedAsPrevious[PrevDecl] = false;
12563  if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
12564  UsedAsPrevious[D] = true;
12565  }
12566  PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
12567  PrevDecl->getLocation();
12568  }
12569  Filter.done();
12570  if (InCompoundScope) {
12571  for (const auto &PrevData : UsedAsPrevious) {
12572  if (!PrevData.second) {
12573  PrevDRD = PrevData.first;
12574  break;
12575  }
12576  }
12577  }
12578  } else if (PrevDeclInScope != nullptr) {
12579  auto *PrevDRDInScope = PrevDRD =
12580  cast<OMPDeclareReductionDecl>(PrevDeclInScope);
12581  do {
12582  PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
12583  PrevDRDInScope->getLocation();
12584  PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
12585  } while (PrevDRDInScope != nullptr);
12586  }
12587  for (const auto &TyData : ReductionTypes) {
12588  const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
12589  bool Invalid = false;
12590  if (I != PreviousRedeclTypes.end()) {
12591  Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
12592  << TyData.first;
12593  Diag(I->second, diag::note_previous_definition);
12594  Invalid = true;
12595  }
12596  PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
12597  auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
12598  Name, TyData.first, PrevDRD);
12599  DC->addDecl(DRD);
12600  DRD->setAccess(AS);
12601  Decls.push_back(DRD);
12602  if (Invalid)
12603  DRD->setInvalidDecl();
12604  else
12605  PrevDRD = DRD;
12606  }
12607 
12608  return DeclGroupPtrTy::make(
12609  DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
12610 }
12611 
12613  auto *DRD = cast<OMPDeclareReductionDecl>(D);
12614 
12615  // Enter new function scope.
12616  PushFunctionScope();
12617  setFunctionHasBranchProtectedScope();
12618  getCurFunction()->setHasOMPDeclareReductionCombiner();
12619 
12620  if (S != nullptr)
12621  PushDeclContext(S, DRD);
12622  else
12623  CurContext = DRD;
12624 
12625  PushExpressionEvaluationContext(
12626  ExpressionEvaluationContext::PotentiallyEvaluated);
12627 
12628  QualType ReductionType = DRD->getType();
12629  // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
12630  // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
12631  // uses semantics of argument handles by value, but it should be passed by
12632  // reference. C lang does not support references, so pass all parameters as
12633  // pointers.
12634  // Create 'T omp_in;' variable.
12635  VarDecl *OmpInParm =
12636  buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
12637  // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
12638  // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
12639  // uses semantics of argument handles by value, but it should be passed by
12640  // reference. C lang does not support references, so pass all parameters as
12641  // pointers.
12642  // Create 'T omp_out;' variable.
12643  VarDecl *OmpOutParm =
12644  buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
12645  if (S != nullptr) {
12646  PushOnScopeChains(OmpInParm, S);
12647  PushOnScopeChains(OmpOutParm, S);
12648  } else {
12649  DRD->addDecl(OmpInParm);
12650  DRD->addDecl(OmpOutParm);
12651  }
12652 }
12653 
12655  auto *DRD = cast<OMPDeclareReductionDecl>(D);
12656  DiscardCleanupsInEvaluationContext();
12657  PopExpressionEvaluationContext();
12658 
12659  PopDeclContext();
12660  PopFunctionScopeInfo();
12661 
12662  if (Combiner != nullptr)
12663  DRD->setCombiner(Combiner);
12664  else
12665  DRD->setInvalidDecl();
12666 }
12667 
12669  auto *DRD = cast<OMPDeclareReductionDecl>(D);
12670 
12671  // Enter new function scope.
12672  PushFunctionScope();
12673  setFunctionHasBranchProtectedScope();
12674 
12675  if (S != nullptr)
12676  PushDeclContext(S, DRD);
12677  else
12678  CurContext = DRD;
12679 
12680  PushExpressionEvaluationContext(
12681  ExpressionEvaluationContext::PotentiallyEvaluated);
12682 
12683  QualType ReductionType = DRD->getType();
12684  // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
12685  // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
12686  // uses semantics of argument handles by value, but it should be passed by
12687  // reference. C lang does not support references, so pass all parameters as
12688  // pointers.
12689  // Create 'T omp_priv;' variable.
12690  VarDecl *OmpPrivParm =
12691  buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
12692  // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
12693  // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
12694  // uses semantics of argument handles by value, but it should be passed by
12695  // reference. C lang does not support references, so pass all parameters as
12696  // pointers.
12697  // Create 'T omp_orig;' variable.
12698  VarDecl *OmpOrigParm =
12699  buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
12700  if (S != nullptr) {
12701  PushOnScopeChains(OmpPrivParm, S);
12702  PushOnScopeChains(OmpOrigParm, S);
12703  } else {
12704  DRD->addDecl(OmpPrivParm);
12705  DRD->addDecl(OmpOrigParm);
12706  }
12707  return OmpPrivParm;
12708 }
12709 
12711  VarDecl *OmpPrivParm) {
12712  auto *DRD = cast<OMPDeclareReductionDecl>(D);
12713  DiscardCleanupsInEvaluationContext();
12714  PopExpressionEvaluationContext();
12715 
12716  PopDeclContext();
12717  PopFunctionScopeInfo();
12718 
12719  if (Initializer != nullptr) {
12720  DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
12721  } else if (OmpPrivParm->hasInit()) {
12722  DRD->setInitializer(OmpPrivParm->getInit(),
12723  OmpPrivParm->isDirectInit()
12726  } else {
12727  DRD->setInvalidDecl();
12728  }
12729 }
12730 
12732  Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
12733  for (Decl *D : DeclReductions.get()) {
12734  if (IsValid) {
12735  if (S)
12736  PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
12737  /*AddToContext=*/false);
12738  } else {
12739  D->setInvalidDecl();
12740  }
12741  }
12742  return DeclReductions;
12743 }
12744 
12746  SourceLocation StartLoc,
12747  SourceLocation LParenLoc,
12748  SourceLocation EndLoc) {
12749  Expr *ValExpr = NumTeams;
12750  Stmt *HelperValStmt = nullptr;
12751 
12752  // OpenMP [teams Constrcut, Restrictions]
12753  // The num_teams expression must evaluate to a positive integer value.
12754  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
12755  /*StrictlyPositive=*/true))
12756  return nullptr;
12757 
12758  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
12759  OpenMPDirectiveKind CaptureRegion =
12760  getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams);
12761  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12762  ValExpr = MakeFullExpr(ValExpr).get();
12763  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12764  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12765  HelperValStmt = buildPreInits(Context, Captures);
12766  }
12767 
12768  return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
12769  StartLoc, LParenLoc, EndLoc);
12770 }
12771 
12773  SourceLocation StartLoc,
12774  SourceLocation LParenLoc,
12775  SourceLocation EndLoc) {
12776  Expr *ValExpr = ThreadLimit;
12777  Stmt *HelperValStmt = nullptr;
12778 
12779  // OpenMP [teams Constrcut, Restrictions]
12780  // The thread_limit expression must evaluate to a positive integer value.
12781  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
12782  /*StrictlyPositive=*/true))
12783  return nullptr;
12784 
12785  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
12786  OpenMPDirectiveKind CaptureRegion =
12787  getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit);
12788  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12789  ValExpr = MakeFullExpr(ValExpr).get();
12790  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12791  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12792  HelperValStmt = buildPreInits(Context, Captures);
12793  }
12794 
12795  return new (Context) OMPThreadLimitClause(
12796  ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
12797 }
12798 
12800  SourceLocation StartLoc,
12801  SourceLocation LParenLoc,
12802  SourceLocation EndLoc) {
12803  Expr *ValExpr = Priority;
12804 
12805  // OpenMP [2.9.1, task Constrcut]
12806  // The priority-value is a non-negative numerical scalar expression.
12807  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_priority,
12808  /*StrictlyPositive=*/false))
12809  return nullptr;
12810 
12811  return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc);
12812 }
12813 
12815  SourceLocation StartLoc,
12816  SourceLocation LParenLoc,
12817  SourceLocation EndLoc) {
12818  Expr *ValExpr = Grainsize;
12819 
12820  // OpenMP [2.9.2, taskloop Constrcut]
12821  // The parameter of the grainsize clause must be a positive integer
12822  // expression.
12823  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize,
12824  /*StrictlyPositive=*/true))
12825  return nullptr;
12826 
12827  return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc);
12828 }
12829 
12831  SourceLocation StartLoc,
12832  SourceLocation LParenLoc,
12833  SourceLocation EndLoc) {
12834  Expr *ValExpr = NumTasks;
12835 
12836  // OpenMP [2.9.2, taskloop Constrcut]
12837  // The parameter of the num_tasks clause must be a positive integer
12838  // expression.
12839  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks,
12840  /*StrictlyPositive=*/true))
12841  return nullptr;
12842 
12843  return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc);
12844 }
12845 
12847  SourceLocation LParenLoc,
12848  SourceLocation EndLoc) {
12849  // OpenMP [2.13.2, critical construct, Description]
12850  // ... where hint-expression is an integer constant expression that evaluates
12851  // to a valid lock hint.
12852  ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
12853  if (HintExpr.isInvalid())
12854  return nullptr;
12855  return new (Context)
12856  OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
12857 }
12858 
12860  OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
12861  SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
12862  SourceLocation EndLoc) {
12863  if (Kind == OMPC_DIST_SCHEDULE_unknown) {
12864  std::string Values;
12865  Values += "'";
12866  Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
12867  Values += "'";
12868  Diag(KindLoc, diag::err_omp_unexpected_clause_value)
12869  << Values << getOpenMPClauseName(OMPC_dist_schedule);
12870  return nullptr;
12871  }
12872  Expr *ValExpr = ChunkSize;
12873  Stmt *HelperValStmt = nullptr;
12874  if (ChunkSize) {
12875  if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
12876  !ChunkSize->isInstantiationDependent() &&
12877  !ChunkSize->containsUnexpandedParameterPack()) {
12878  SourceLocation ChunkSizeLoc = ChunkSize->getLocStart();
12879  ExprResult Val =
12880  PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
12881  if (Val.isInvalid())
12882  return nullptr;
12883 
12884  ValExpr = Val.get();
12885 
12886  // OpenMP [2.7.1, Restrictions]
12887  // chunk_size must be a loop invariant integer expression with a positive
12888  // value.
12889  llvm::APSInt Result;
12890  if (ValExpr->isIntegerConstantExpr(Result, Context)) {
12891  if (Result.isSigned() && !Result.isStrictlyPositive()) {
12892  Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
12893  << "dist_schedule" << ChunkSize->getSourceRange();
12894  return nullptr;
12895  }
12897  DSAStack->getCurrentDirective(), OMPC_dist_schedule) !=
12898  OMPD_unknown &&
12899  !CurContext->isDependentContext()) {
12900  ValExpr = MakeFullExpr(ValExpr).get();
12901  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12902  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12903  HelperValStmt = buildPreInits(Context, Captures);
12904  }
12905  }
12906  }
12907 
12908  return new (Context)
12909  OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
12910  Kind, ValExpr, HelperValStmt);
12911 }
12912 
12915  SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
12916  SourceLocation KindLoc, SourceLocation EndLoc) {
12917  // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)'
12918  if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) {
12919  std::string Value;
12920  SourceLocation Loc;
12921  Value += "'";
12922  if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
12923  Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
12924  OMPC_DEFAULTMAP_MODIFIER_tofrom);
12925  Loc = MLoc;
12926  } else {
12927  Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
12928  OMPC_DEFAULTMAP_scalar);
12929  Loc = KindLoc;
12930  }
12931  Value += "'";
12932  Diag(Loc, diag::err_omp_unexpected_clause_value)
12933  << Value << getOpenMPClauseName(OMPC_defaultmap);
12934  return nullptr;
12935  }
12936  DSAStack->setDefaultDMAToFromScalar(StartLoc);
12937 
12938  return new (Context)
12939  OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
12940 }
12941 
12943  DeclContext *CurLexicalContext = getCurLexicalContext();
12944  if (!CurLexicalContext->isFileContext() &&
12945  !CurLexicalContext->isExternCContext() &&
12946  !CurLexicalContext->isExternCXXContext() &&
12947  !isa<CXXRecordDecl>(CurLexicalContext) &&
12948  !isa<ClassTemplateDecl>(CurLexicalContext) &&
12949  !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
12950  !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
12951  Diag(Loc, diag::err_omp_region_not_file_context);
12952  return false;
12953  }
12954  if (IsInOpenMPDeclareTargetContext) {
12955  Diag(Loc, diag::err_omp_enclosed_declare_target);
12956  return false;
12957  }
12958 
12959  IsInOpenMPDeclareTargetContext = true;
12960  return true;
12961 }
12962 
12964  assert(IsInOpenMPDeclareTargetContext &&
12965  "Unexpected ActOnFinishOpenMPDeclareTargetDirective");
12966  IsInOpenMPDeclareTargetContext = false;
12967 }
12968 
12970  CXXScopeSpec &ScopeSpec,
12971  const DeclarationNameInfo &Id,
12972  OMPDeclareTargetDeclAttr::MapTypeTy MT,
12973  NamedDeclSetType &SameDirectiveDecls) {
12974  LookupResult Lookup(*this, Id, LookupOrdinaryName);
12975  LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
12976 
12977  if (Lookup.isAmbiguous())
12978  return;
12979  Lookup.suppressDiagnostics();
12980 
12981  if (!Lookup.isSingleResult()) {
12982  if (TypoCorrection Corrected =
12983  CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr,
12984  llvm::make_unique<VarOrFuncDeclFilterCCC>(*this),
12985  CTK_ErrorRecovery)) {
12986  diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
12987  << Id.getName());
12988  checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
12989  return;
12990  }
12991 
12992  Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
12993  return;
12994  }
12995 
12996  NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
12997  if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND)) {
12998  if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl())))
12999  Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName();
13000  if (!ND->hasAttr<OMPDeclareTargetDeclAttr>()) {
13001  auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT);
13002  ND->addAttr(A);
13003  if (ASTMutationListener *ML = Context.getASTMutationListener())
13004  ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
13005  checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Id.getLoc());
13006  } else if (ND->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() != MT) {
13007  Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link)
13008  << Id.getName();
13009  }
13010  } else {
13011  Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
13012  }
13013 }
13014 
13016  Sema &SemaRef, Decl *D) {
13017  if (!D)
13018  return;
13019  const Decl *LD = nullptr;
13020  if (isa<TagDecl>(D)) {
13021  LD = cast<TagDecl>(D)->getDefinition();
13022  } else if (isa<VarDecl>(D)) {
13023  LD = cast<VarDecl>(D)->getDefinition();
13024 
13025  // If this is an implicit variable that is legal and we do not need to do
13026  // anything.
13027  if (cast<VarDecl>(D)->isImplicit()) {
13028  auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
13029  SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To);
13030  D->addAttr(A);
13032  ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
13033  return;
13034  }
13035  } else if (const auto *F = dyn_cast<FunctionDecl>(D)) {
13036  const FunctionDecl *FD = nullptr;
13037  if (cast<FunctionDecl>(D)->hasBody(FD)) {
13038  LD = FD;
13039  // If the definition is associated with the current declaration in the
13040  // target region (it can be e.g. a lambda) that is legal and we do not
13041  // need to do anything else.
13042  if (LD == D) {
13043  auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
13044  SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To);
13045  D->addAttr(A);
13047  ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
13048  return;
13049  }
13050  } else if (F->isFunctionTemplateSpecialization() &&
13051  F->getTemplateSpecializationKind() ==
13053  // Check if the function is implicitly instantiated from the template
13054  // defined in the declare target region.
13055  const FunctionTemplateDecl *FTD = F->getPrimaryTemplate();
13056  if (FTD && FTD->hasAttr<OMPDeclareTargetDeclAttr>())
13057  return;
13058  }
13059  }
13060  if (!LD)
13061  LD = D;
13062  if (LD && !LD->hasAttr<OMPDeclareTargetDeclAttr>() &&
13063  ((isa<VarDecl>(LD) && !isa<ParmVarDecl>(LD)) || isa<FunctionDecl>(LD))) {
13064  // Outlined declaration is not declared target.
13065  if (!isa<FunctionDecl>(LD)) {
13066  if (LD->isOutOfLine()) {
13067  SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context);
13068  SemaRef.Diag(SL, diag::note_used_here) << SR;
13069  } else {
13070  const DeclContext *DC = LD->getDeclContext();
13071  while (DC &&
13072  (!isa<FunctionDecl>(DC) ||
13073  !cast<FunctionDecl>(DC)->hasAttr<OMPDeclareTargetDeclAttr>()))
13074  DC = DC->getParent();
13075  if (DC)
13076  return;
13077 
13078  // Is not declared in target context.
13079  SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context);
13080  SemaRef.Diag(SL, diag::note_used_here) << SR;
13081  }
13082  }
13083  // Mark decl as declared target to prevent further diagnostic.
13084  auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
13085  SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To);
13086  D->addAttr(A);
13088  ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
13089  }
13090 }
13091 
13093  Sema &SemaRef, DSAStackTy *Stack,
13094  ValueDecl *VD) {
13095  return VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
13096  checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
13097  /*FullCheck=*/false);
13098 }
13099 
13101  SourceLocation IdLoc) {
13102  if (!D || D->isInvalidDecl())
13103  return;
13104  SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
13105  SourceLocation SL = E ? E->getLocStart() : D->getLocation();
13106  if (auto *VD = dyn_cast<VarDecl>(D)) {
13107  // Only global variables can be marked as declare target.
13108  if (VD->isLocalVarDeclOrParm())
13109  return;
13110  // 2.10.6: threadprivate variable cannot appear in a declare target
13111  // directive.
13112  if (DSAStack->isThreadPrivate(VD)) {
13113  Diag(SL, diag::err_omp_threadprivate_in_target);
13114  reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false));
13115  return;
13116  }
13117  }
13118  if (auto *VD = dyn_cast<ValueDecl>(D)) {
13119  // Problem if any with var declared with incomplete type will be reported
13120  // as normal, so no need to check it here.
13121  if ((E || !VD->getType()->isIncompleteType()) &&
13122  !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) {
13123  // Mark decl as declared target to prevent further diagnostic.
13124  if (isa<VarDecl>(VD) || isa<FunctionDecl>(VD) ||
13125  isa<FunctionTemplateDecl>(VD)) {
13126  auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
13127  Context, OMPDeclareTargetDeclAttr::MT_To);
13128  VD->addAttr(A);
13129  if (ASTMutationListener *ML = Context.getASTMutationListener())
13130  ML->DeclarationMarkedOpenMPDeclareTarget(VD, A);
13131  }
13132  return;
13133  }
13134  }
13135  if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
13136  D = FTD->getTemplatedDecl();
13137  if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
13138  if (FD->hasAttr<OMPDeclareTargetDeclAttr>() &&
13139  (FD->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() ==
13140  OMPDeclareTargetDeclAttr::MT_Link)) {
13141  assert(IdLoc.isValid() && "Source location is expected");
13142  Diag(IdLoc, diag::err_omp_function_in_link_clause);
13143  Diag(FD->getLocation(), diag::note_defined_here) << FD;
13144  return;
13145  }
13146  }
13147  if (!E) {
13148  // Checking declaration inside declare target region.
13149  if (!D->hasAttr<OMPDeclareTargetDeclAttr>() &&
13150  (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
13151  isa<FunctionTemplateDecl>(D))) {
13152  auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
13153  Context, OMPDeclareTargetDeclAttr::MT_To);
13154  D->addAttr(A);
13155  if (ASTMutationListener *ML = Context.getASTMutationListener())
13156  ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
13157  }
13158  return;
13159  }
13160  checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
13161 }
13162 
13164  SourceLocation StartLoc,
13165  SourceLocation LParenLoc,
13166  SourceLocation EndLoc) {
13167  MappableVarListInfo MVLI(VarList);
13168  checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, StartLoc);
13169  if (MVLI.ProcessedVarList.empty())
13170  return nullptr;
13171 
13172  return OMPToClause::Create(Context, StartLoc, LParenLoc, EndLoc,
13173  MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
13174  MVLI.VarComponents);
13175 }
13176 
13178  SourceLocation StartLoc,
13179  SourceLocation LParenLoc,
13180  SourceLocation EndLoc) {
13181  MappableVarListInfo MVLI(VarList);
13182  checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, StartLoc);
13183  if (MVLI.ProcessedVarList.empty())
13184  return nullptr;
13185 
13186  return OMPFromClause::Create(Context, StartLoc, LParenLoc, EndLoc,
13187  MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
13188  MVLI.VarComponents);
13189 }
13190 
13192  SourceLocation StartLoc,
13193  SourceLocation LParenLoc,
13194  SourceLocation EndLoc) {
13195  MappableVarListInfo MVLI(VarList);
13196  SmallVector<Expr *, 8> PrivateCopies;
13198 
13199  for (Expr *RefExpr : VarList) {
13200  assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
13201  SourceLocation ELoc;
13202  SourceRange ERange;
13203  Expr *SimpleRefExpr = RefExpr;
13204  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
13205  if (Res.second) {
13206  // It will be analyzed later.
13207  MVLI.ProcessedVarList.push_back(RefExpr);
13208  PrivateCopies.push_back(nullptr);
13209  Inits.push_back(nullptr);
13210  }
13211  ValueDecl *D = Res.first;
13212  if (!D)
13213  continue;
13214 
13215  QualType Type = D->getType();
13216  Type = Type.getNonReferenceType().getUnqualifiedType();
13217 
13218  auto *VD = dyn_cast<VarDecl>(D);
13219 
13220  // Item should be a pointer or reference to pointer.
13221  if (!Type->isPointerType()) {
13222  Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
13223  << 0 << RefExpr->getSourceRange();
13224  continue;
13225  }
13226 
13227  // Build the private variable and the expression that refers to it.
13228  auto VDPrivate =
13229  buildVarDecl(*this, ELoc, Type, D->getName(),
13230  D->hasAttrs() ? &D->getAttrs() : nullptr,
13231  VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
13232  if (VDPrivate->isInvalidDecl())
13233  continue;
13234 
13235  CurContext->addDecl(VDPrivate);
13236  DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
13237  *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
13238 
13239  // Add temporary variable to initialize the private copy of the pointer.
13240  VarDecl *VDInit =
13241  buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
13242  DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
13243  *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
13244  AddInitializerToDecl(VDPrivate,
13245  DefaultLvalueConversion(VDInitRefExpr).get(),
13246  /*DirectInit=*/false);
13247 
13248  // If required, build a capture to implement the privatization initialized
13249  // with the current list item value.
13250  DeclRefExpr *Ref = nullptr;
13251  if (!VD)
13252  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
13253  MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
13254  PrivateCopies.push_back(VDPrivateRefExpr);
13255  Inits.push_back(VDInitRefExpr);
13256 
13257  // We need to add a data sharing attribute for this variable to make sure it
13258  // is correctly captured. A variable that shows up in a use_device_ptr has
13259  // similar properties of a first private variable.
13260  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
13261 
13262  // Create a mappable component for the list item. List items in this clause
13263  // only need a component.
13264  MVLI.VarBaseDeclarations.push_back(D);
13265  MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
13266  MVLI.VarComponents.back().push_back(
13268  }
13269 
13270  if (MVLI.ProcessedVarList.empty())
13271  return nullptr;
13272 
13274  Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList,
13275  PrivateCopies, Inits, MVLI.VarBaseDeclarations, MVLI.VarComponents);
13276 }
13277 
13279  SourceLocation StartLoc,
13280  SourceLocation LParenLoc,
13281  SourceLocation EndLoc) {
13282  MappableVarListInfo MVLI(VarList);
13283  for (Expr *RefExpr : VarList) {
13284  assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
13285  SourceLocation ELoc;
13286  SourceRange ERange;
13287  Expr *SimpleRefExpr = RefExpr;
13288  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
13289  if (Res.second) {
13290  // It will be analyzed later.
13291  MVLI.ProcessedVarList.push_back(RefExpr);
13292  }
13293  ValueDecl *D = Res.first;
13294  if (!D)
13295  continue;
13296 
13297  QualType Type = D->getType();
13298  // item should be a pointer or array or reference to pointer or array
13299  if (!Type.getNonReferenceType()->isPointerType() &&
13300  !Type.getNonReferenceType()->isArrayType()) {
13301  Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
13302  << 0 << RefExpr->getSourceRange();
13303  continue;
13304  }
13305 
13306  // Check if the declaration in the clause does not show up in any data
13307  // sharing attribute.
13308  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
13309  if (isOpenMPPrivate(DVar.CKind)) {
13310  Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
13311  << getOpenMPClauseName(DVar.CKind)
13312  << getOpenMPClauseName(OMPC_is_device_ptr)
13313  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
13314  reportOriginalDsa(*this, DSAStack, D, DVar);
13315  continue;
13316  }
13317 
13318  const Expr *ConflictExpr;
13319  if (DSAStack->checkMappableExprComponentListsForDecl(
13320  D, /*CurrentRegionOnly=*/true,
13321  [&ConflictExpr](
13323  OpenMPClauseKind) -> bool {
13324  ConflictExpr = R.front().getAssociatedExpression();
13325  return true;
13326  })) {
13327  Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
13328  Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
13329  << ConflictExpr->getSourceRange();
13330  continue;
13331  }
13332 
13333  // Store the components in the stack so that they can be used to check
13334  // against other clauses later on.
13336  DSAStack->addMappableExpressionComponents(
13337  D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
13338 
13339  // Record the expression we've just processed.
13340  MVLI.ProcessedVarList.push_back(SimpleRefExpr);
13341 
13342  // Create a mappable component for the list item. List items in this clause
13343  // only need a component. We use a null declaration to signal fields in
13344  // 'this'.
13345  assert((isa<DeclRefExpr>(SimpleRefExpr) ||
13346  isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
13347  "Unexpected device pointer expression!");
13348  MVLI.VarBaseDeclarations.push_back(
13349  isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
13350  MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
13351  MVLI.VarComponents.back().push_back(MC);
13352  }
13353 
13354  if (MVLI.ProcessedVarList.empty())
13355  return nullptr;
13356 
13358  Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList,
13359  MVLI.VarBaseDeclarations, MVLI.VarComponents);
13360 }
static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, SourceLocation M1Loc, SourceLocation M2Loc)
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.
Expr * NLB
Update of LowerBound for statically scheduled &#39;omp for&#39; loops.
Definition: StmtOpenMP.h:674
SourceLocation getLoc() const
getLoc - Returns the main location of the declaration name.
Defines the clang::ASTContext interface.
SmallVector< Expr *, 4 > Finals
Final loop counter values for GodeGen.
Definition: StmtOpenMP.h:702
Expr * NUB
Update of UpperBound for statically scheduled omp loops for outer loop in combined constructs (e...
Definition: StmtOpenMP.h:641
QualType getCurrentThisType()
Try to retrieve the type of the &#39;this&#39; pointer.
SmallVector< Expr *, 4 > Updates
Expressions for loop counters update for CodeGen.
Definition: StmtOpenMP.h:700
StmtResult ActOnOpenMPMasterDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp master&#39; after parsing of the associated statement.
QualType withConst() const
Retrieves a version of this type with const applied.
ExprResult ActOnOpenMPIdExpression(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id)
Called on correct id-expression from the &#39;#pragma omp threadprivate&#39;.
StmtResult ActOnOpenMPFlushDirective(ArrayRef< OMPClause *> Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp flush&#39;.
void setImplicit(bool I=true)
Definition: DeclBase.h:555
Represents a function declaration or definition.
Definition: Decl.h:1716
OMPClause * ActOnOpenMPSimdlenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;simdlen&#39; clause.
This represents &#39;thread_limit&#39; clause in the &#39;#pragma omp ...&#39; directive.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
static bool checkOpenMPIterationSpace(OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, LoopIterationSpace &ResultIterSpace, llvm::MapVector< const Expr *, DeclRefExpr *> &Captures)
Called on a for stmt to check and extract its iteration space for further processing (such as collaps...
StmtResult ActOnOpenMPSectionDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp section&#39; after parsing of the associated statement.
OMPClause * ActOnOpenMPTaskReductionClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr *> UnresolvedReductions=llvm::None)
Called on well-formed &#39;task_reduction&#39; clause.
static OMPDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
SourceLocation getLocEnd() const LLVM_READONLY
Returns the ending location of the clause.
Definition: OpenMPClause.h:71
PtrTy get() const
Definition: Ownership.h:81
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
CanQualType VoidPtrTy
Definition: ASTContext.h:1032
bool ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc)
Called on the start of target region i.e. &#39;#pragma omp declare target&#39;.
A (possibly-)qualified type.
Definition: Type.h:655
void ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D)
Initialize declare reduction construct initializer.
Simple class containing the result of Sema::CorrectTypo.
static OMPAtomicDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V, Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate)
Creates directive with a list of Clauses and &#39;x&#39;, &#39;v&#39; and &#39;expr&#39; parts of the atomic construct (see S...
Definition: StmtOpenMP.cpp:643
bool isArrayType() const
Definition: Type.h:6162
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
Definition: Expr.h:2596
ArrayRef< OMPClause * > clauses()
Definition: StmtOpenMP.h:262
StmtResult ActOnOpenMPTargetUpdateDirective(ArrayRef< OMPClause *> Clauses, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AStmt)
Called on well-formed &#39;#pragma omp target update&#39;.
static Opcode getOpForCompoundAssignment(Opcode Opc)
Definition: Expr.h:3279
ExprResult ActOnConditionalOp(SourceLocation QuestionLoc, SourceLocation ColonLoc, Expr *CondExpr, Expr *LHSExpr, Expr *RHSExpr)
ActOnConditionalOp - Parse a ?: operation.
Definition: SemaExpr.cpp:7283
StmtResult ActOnOpenMPCancelDirective(ArrayRef< OMPClause *> Clauses, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Called on well-formed &#39;#pragma omp cancel&#39;.
ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val)
Definition: SemaExpr.cpp:3153
static ClassTemplateDecl * getDefinition(ClassTemplateDecl *D)
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:195
void EndOpenMPDSABlock(Stmt *CurDirective)
Called on end of data sharing attribute block.
SourceLocation getLocStart() const LLVM_READONLY
Definition: Expr.h:1069
OpenMPDefaultmapClauseKind
OpenMP attributes for &#39;defaultmap&#39; clause.
Definition: OpenMPKinds.h:107
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.
static OMPTeamsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:840
StmtResult ActOnOpenMPDistributeDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp distribute&#39; after parsing of the associated statement.
StmtResult ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName, ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp critical&#39; after parsing of the associated statement.
static UnresolvedLookupExpr * Create(const ASTContext &C, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, bool ADL, bool Overloaded, UnresolvedSetIterator Begin, UnresolvedSetIterator End)
Definition: ExprCXX.h:2869
OMPClause * ActOnOpenMPUntiedClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;untied&#39; clause.
static OMPClauseWithPreInit * get(OMPClause *C)
Stmt - This represents one statement.
Definition: Stmt.h:66
Filter makeFilter()
Create a filter for this result set.
Definition: Lookup.h:671
static OMPTaskgroupDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *ReductionRef)
Creates directive.
Definition: StmtOpenMP.cpp:525
StmtResult ActOnOpenMPTargetDataDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp target data&#39; after parsing of the associated statement.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
Definition: Type.cpp:497
Class that handles pre-initialization statement for some clauses, like &#39;shedule&#39;, &#39;firstprivate&#39; etc...
Definition: OpenMPClause.h:101
static OMPTargetTeamsDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
bool isOpenMPNestingDistributeDirective(OpenMPDirectiveKind DKind)
Checks if the specified composite/combined directive constitutes a distribute directive in the outerm...
static bool hasClauses(ArrayRef< OMPClause *> Clauses, const OpenMPClauseKind K)
Check for existence of a map clause in the list of clauses.
Expr * EUB
EnsureUpperBound – expression UB = min(UB, NumIterations).
Definition: StmtOpenMP.h:672
Expr * DistInc
DistInc - increment expression for distribute loop when found combined with a further loop level (e...
Definition: StmtOpenMP.h:686
Expr * getBase() const
Definition: Expr.h:2590
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type...
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
Definition: Sema.h:1281
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
static OMPUseDevicePtrClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> Vars, ArrayRef< Expr *> PrivateVars, ArrayRef< Expr *> Inits, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
specific_attr_iterator - Iterates over a subrange of an AttrVec, only providing attributes that are o...
Definition: AttrIterator.h:54
This represents &#39;grainsize&#39; clause in the &#39;#pragma omp ...&#39; directive.
static OMPSectionDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt, bool HasCancel)
Creates directive.
Definition: StmtOpenMP.cpp:246
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
Definition: Decl.cpp:2112
static Expr * getOrderedNumberExpr(ArrayRef< OMPClause *> Clauses)
This represents &#39;if&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:242
OMPClause * ActOnOpenMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;threads&#39; clause.
Opcode getOpcode() const
Definition: Expr.h:3184
bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS, bool AllowBuiltinCreation=false, bool EnteringContext=false)
Performs name lookup for a name that was parsed in the source code, and may contain a C++ scope speci...
StringRef P
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
Definition: Type.h:6062
This represents &#39;priority&#39; clause in the &#39;#pragma omp ...&#39; directive.
bool isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target data offload directive.
The base class of the type hierarchy.
Definition: Type.h:1428
StmtResult ActOnOpenMPTargetTeamsDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp target teams&#39; after parsing of the associated statement.
OMPClause * ActOnOpenMPGrainsizeClause(Expr *Size, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;grainsize&#39; clause.
SourceLocation getBeginLoc() const
getBeginLoc - Retrieve the location of the first token.
const char * getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type)
static OMPDeclareReductionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, QualType T, OMPDeclareReductionDecl *PrevDeclInScope)
Create declare reduction node.
Definition: DeclOpenMP.cpp:62
SourceLocation getEndLoc() const LLVM_READONLY
QualType withConst() const
Definition: Type.h:827
StmtResult ActOnOpenMPForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp for simd&#39; after parsing of the associated statement.
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:679
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
Definition: Specifiers.h:98
A container of type source information.
Definition: Decl.h:86
This represents &#39;update&#39; clause in the &#39;#pragma omp atomic&#39; directive.
Wrapper for void* pointer.
Definition: Ownership.h:51
static bool checkMapConflicts(Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, bool CurrentRegionOnly, OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, OpenMPClauseKind CKind)
bool CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, SourceLocation LinLoc)
Checks correctness of linear modifiers.
OMPClause * ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;proc_bind&#39; clause.
OMPClause * ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;hint&#39; clause.
static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, DSAStackTy *Stack, QualType QTy, bool FullCheck=true)
StmtResult ActOnOpenMPTaskDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp task&#39; after parsing of the associated statement.
void setInitStyle(InitializationStyle Style)
Definition: Decl.h:1264
bool hasNext() const
Definition: Lookup.h:628
static OMPTeamsDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2477
static std::pair< ValueDecl *, bool > getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, SourceRange &ERange, bool AllowArraySection=false)
OpenMPDefaultmapClauseModifier
OpenMP modifiers for &#39;defaultmap&#39; clause.
Definition: OpenMPKinds.h:115
static bool checkReductionClauseWithNogroup(Sema &S, ArrayRef< OMPClause *> Clauses)
float __ovld __cnfn distance(float p0, float p1)
Returns the distance between p0 and p1.
OMPClause * ActOnOpenMPPriorityClause(Expr *Priority, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;priority&#39; clause.
static int getOpenMPCaptureLevels(OpenMPDirectiveKind Kind)
Return the number of captured regions created for an OpenMP directive.
SourceLocation getSecondScheduleModifierLoc() const
Get the second modifier location.
Definition: OpenMPClause.h:897
static const ValueDecl * getCanonicalDecl(const ValueDecl *D)
Definition: SemaOpenMP.cpp:621
bool capturesVariable(const VarDecl *Var) const
True if this variable has been captured.
Definition: Stmt.cpp:1124
StmtResult ActOnOpenMPTargetTeamsDistributeParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp target teams distribute parallel for&#39; after parsing of the associa...
StmtResult ActOnOpenMPTargetParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp target parallel for&#39; after parsing of the associated statement...
bool isTrivialType(const ASTContext &Context) const
Return true if this is a trivial type per (C++0x [basic.types]p9)
Definition: Type.cpp:2160
Expr * PrevLB
PreviousLowerBound - local variable passed to runtime in the enclosing schedule or null if that does ...
Definition: StmtOpenMP.h:679
Retains information about a function, method, or block that is currently being parsed.
Definition: ScopeInfo.h:96
void setNothrow(bool Nothrow=true)
Definition: Decl.cpp:4356
bool EvaluateAsInt(llvm::APSInt &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer...
This represents &#39;read&#39; clause in the &#39;#pragma omp atomic&#39; directive.
static OMPTeamsDistributeDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Represents a variable declaration or definition.
Definition: Decl.h:814
ActionResult< Stmt * > StmtResult
Definition: Ownership.h:268
static OMPToClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> Vars, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
This represents &#39;num_threads&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:384
bool isEnumeralType() const
Definition: Type.h:6190
OMPClause * ActOnOpenMPFinalClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;final&#39; clause.
const T * getAs() const
Member-template getAs<specific type>&#39;.
Definition: Type.h:6526
bool isOverloadableType() const
Determines whether this is a type for which one can define an overloaded operator.
Definition: Type.h:6466
varlist_range varlists()
Definition: OpenMPClause.h:209
Extra information about a function prototype.
Definition: Type.h:3551
This represents &#39;defaultmap&#39; clause in the &#39;#pragma omp ...&#39; directive.
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical) const
Produce a unique representation of the given statement.
bool isExternCContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
Definition: DeclBase.cpp:1091
bool isAmbiguous() const
Definition: Lookup.h:290
Expr * IgnoreImplicit() LLVM_READONLY
IgnoreImplicit - Skip past any implicit AST nodes which might surround this expression.
Definition: Expr.h:741
static OMPTeamsDistributeParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
bool isInvalidDecl() const
Definition: DeclBase.h:549
void setBegin(SourceLocation b)
Not a TLS variable.
Definition: Decl.h:831
static const Expr * getExprAsWritten(const Expr *E)
Definition: SemaOpenMP.cpp:602
OMPClause * ActOnOpenMPLastprivateClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;lastprivate&#39; clause.
StmtResult ActOnOpenMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp barrier&#39;.
bool hasDefinition() const
Definition: DeclCXX.h:778
OMPClause * ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;depend&#39; clause.
StmtResult ActOnOpenMPParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp parallel for&#39; after parsing of the associated statement.
bool isUnset() const
Definition: Ownership.h:172
This represents &#39;nogroup&#39; clause in the &#39;#pragma omp ...&#39; directive.
This represents &#39;safelen&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:449
Expr * LastIteration
Loop last iteration number.
Definition: StmtOpenMP.h:650
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveStart(Scope *S, DeclContext *DC, DeclarationName Name, ArrayRef< std::pair< QualType, SourceLocation >> ReductionTypes, AccessSpecifier AS, Decl *PrevDeclInScope=nullptr)
Called on start of &#39;#pragma omp declare reduction&#39;.
ExprResult PerformImplicitConversion(Expr *From, QualType ToType, AssignmentAction Action, bool AllowExplicit=false)
PerformImplicitConversion - Perform an implicit conversion of the expression From to the type ToType...
DeclGroupPtrTy ActOnOpenMPDeclareSimdDirective(DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, ArrayRef< Expr *> Uniforms, ArrayRef< Expr *> Aligneds, ArrayRef< Expr *> Alignments, ArrayRef< Expr *> Linears, ArrayRef< unsigned > LinModifiers, ArrayRef< Expr *> Steps, SourceRange SR)
Called on well-formed &#39;#pragma omp declare simd&#39; after parsing of the associated method/function.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:269
void ActOnUninitializedDecl(Decl *dcl)
Definition: SemaDecl.cpp:11395
Expr * IgnoreImpCasts() LLVM_READONLY
IgnoreImpCasts - Skip past any implicit casts which might surround this expression.
Definition: Expr.h:3016
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.
A semantic tree transformation that allows one to transform one abstract syntax tree into another...
Definition: TreeTransform.h:96
const char * getOpenMPClauseName(OpenMPClauseKind Kind)
Definition: OpenMPKinds.cpp:62
static OMPTargetParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
One of these records is kept for each identifier that is lexed.
CalcStep
Definition: OpenMPClause.h:146
static OMPIsDevicePtrClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> Vars, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
FieldDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
Definition: Decl.h:2729
Step
Definition: OpenMPClause.h:146
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.
static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, const Expr *E, QualType BaseQTy)
OMPClause * ActOnOpenMPFirstprivateClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;firstprivate&#39; clause.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:150
A C++ nested-name-specifier augmented with source location information.
ExprResult ExprEmpty()
Definition: Ownership.h:289
This represents &#39;simd&#39; clause in the &#39;#pragma omp ...&#39; directive.
static OMPTargetEnterDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:796
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base)
Determine whether the type Derived is a C++ class that is derived from the type Base.
bool isOpenMPTaskingDirective(OpenMPDirectiveKind Kind)
Checks if the specified directive kind is one of tasking directives - task, taskloop or taksloop simd...
OpenMPLinearClauseKind
OpenMP attributes for &#39;linear&#39; clause.
Definition: OpenMPKinds.h:84
Represents a member of a struct/union/class.
Definition: Decl.h:2534
OMPClause * ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation NameModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed &#39;if&#39; clause.
StmtResult ActOnOpenMPTeamsDistributeDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp teams distribute&#39; after parsing of the associated statement...
bool isNamespace() const
Definition: DeclBase.h:1421
static OMPTargetUpdateDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
StmtResult ActOnOpenMPRegionEnd(StmtResult S, ArrayRef< OMPClause *> Clauses)
End of OpenMP region.
void StartOpenMPDSABlock(OpenMPDirectiveKind K, const DeclarationNameInfo &DirName, Scope *CurScope, SourceLocation Loc)
Called on start of new data sharing attribute block.
SourceLocation getExprLoc() const LLVM_READONLY
Definition: Expr.h:2708
bool isReferenceType() const
Definition: Type.h:6125
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Definition: DeclBase.h:405
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr)
Definition: Expr.cpp:391
static OMPTaskDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:459
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC...
Definition: DeclBase.h:1463
Defines some OpenMP-specific enums and functions.
StmtResult ActOnOpenMPTargetExitDataDirective(ArrayRef< OMPClause *> Clauses, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AStmt)
Called on well-formed &#39;#pragma omp target exit data&#39; after parsing of the associated statement...
Expr * getSafelen() const
Return safe iteration space distance.
Definition: OpenMPClause.h:483
static Stmt * buildPreInits(ASTContext &Context, MutableArrayRef< Decl *> PreInits)
Build preinits statement for the given declarations.
static OMPDistributeDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:963
This represents &#39;#pragma omp critical&#39; directive.
Definition: StmtOpenMP.h:1446
void EndOpenMPClause()
End analysis of clauses.
IdentifierTable & Idents
Definition: ASTContext.h:545
StmtResult ActOnOpenMPTargetEnterDataDirective(ArrayRef< OMPClause *> Clauses, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AStmt)
Called on well-formed &#39;#pragma omp target enter data&#39; after parsing of the associated statement...
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
Definition: Specifiers.h:110
DeclClass * getAsSingle() const
Definition: Lookup.h:496
OpenMPDistScheduleClauseKind
OpenMP attributes for &#39;dist_schedule&#39; clause.
Definition: OpenMPKinds.h:100
bool isGLValue() const
Definition: Expr.h:252
BinaryOperatorKind
OMPClause * ActOnOpenMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;num_teams&#39; clause.
Represents the results of name lookup.
Definition: Lookup.h:47
PtrTy get() const
Definition: Ownership.h:174
StmtResult ActOnOpenMPSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp simd&#39; after parsing of the associated statement.
Expr * LB
DistributeLowerBound - used when composing &#39;omp distribute&#39; with &#39;omp for&#39; in a same construct...
Definition: StmtOpenMP.h:622
Expr * EUB
DistributeEnsureUpperBound - used when composing &#39;omp distribute&#39; with &#39;omp for&#39; in a same construct...
Definition: StmtOpenMP.h:628
bool isOpenMPTeamsDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a teams-kind directive.
OMPClause * ActOnOpenMPNogroupClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;nogroup&#39; clause.
OMPClause * ActOnOpenMPReadClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;read&#39; clause.
StmtResult ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp target teams distribute parallel for simd&#39; after parsing of the as...
OMPClause * ActOnOpenMPScheduleClause(OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Called on well-formed &#39;schedule&#39; clause.
static OMPTeamsDistributeSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPLastprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> SrcExprs, ArrayRef< Expr *> DstExprs, ArrayRef< Expr *> AssignmentOps, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type...
Definition: Type.h:6575
static DeclRefExpr * buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, SourceLocation Loc, bool RefersToCapture=false)
Definition: SemaOpenMP.cpp:866
static ExprResult buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, Scope *S, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, QualType Ty, CXXCastPath &BasePath, Expr *UnresolvedReduction)
child_range children()
Definition: Stmt.cpp:227
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:149
StmtResult StmtError()
Definition: Ownership.h:284
static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef)
Convert integer expression E to make it have at least Bits bits.
bool containsUnexpandedParameterPack() const
Whether this type is or contains an unexpanded parameter pack, used to support C++0x variadic templat...
Definition: Type.h:1711
OMPClause * ActOnOpenMPCaptureClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;capture&#39; clause.
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:3143
Look up the name of an OpenMP user-defined reduction operation.
Definition: Sema.h:3054
OMPClause * ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc, SourceLocation EndLoc)
std::pair< StringRef, QualType > CapturedParamNameType
Definition: Sema.h:3818
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
This represents &#39;default&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:608
Expr * IgnoreParenCasts() LLVM_READONLY
IgnoreParenCasts - Ignore parentheses and casts.
Definition: Expr.cpp:2544
Scope - A scope is a transient data structure that is used while parsing the program.
Definition: Scope.h:40
ExprResult Perform(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, MultiExprArg Args, QualType *ResultType=nullptr)
Perform the actual initialization of the given entity based on the computed initialization sequence...
Definition: SemaInit.cpp:7154
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:5889
OMPClause * ActOnOpenMPLinearClause(ArrayRef< Expr *> VarList, Expr *Step, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed &#39;linear&#39; clause.
This represents &#39;final&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:332
This represents &#39;mergeable&#39; clause in the &#39;#pragma omp ...&#39; directive.
bool isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target code offload directive.
static OMPFlushDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:595
void append(iterator I, iterator E)
Expr * CalcLastIteration
Calculation of last iteration.
Definition: StmtOpenMP.h:654
Represents a C++ nested-name-specifier or a global scope specifier.
Definition: DeclSpec.h:63
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition: Expr.h:2827
static OMPTargetTeamsDistributeDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static DeclRefExpr * buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, bool WithInit)
bool isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a worksharing directive.
Preprocessor & PP
Definition: Sema.h:318
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
Definition: Decl.cpp:1898
const LangOptions & getLangOpts() const
Definition: Sema.h:1204
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value &#39;V&#39; and type &#39;type&#39;.
Definition: Expr.cpp:752
StmtResult ActOnOpenMPForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp for&#39; after parsing of the associated statement.
bool isTypeDependent() const
isTypeDependent - Determines whether this expression is type-dependent (C++ [temp.dep.expr]), which means that its type could change from one template instantiation to the next.
Definition: Expr.h:167
bool isScalarType() const
Definition: Type.h:6425
An ordinary object is located at an address in memory.
Definition: Specifiers.h:126
StmtResult ActOnOpenMPTargetTeamsDistributeDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp target teams distribute&#39; after parsing of the associated statement...
Represents the body of a CapturedStmt, and serves as its DeclContext.
Definition: Decl.h:4037
static OMPParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:384
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const
Retrieve a nested-name-specifier with location information, copied into the given AST context...
Definition: DeclSpec.cpp:143
OMPClause * ActOnOpenMPSafelenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;safelen&#39; clause.
OMPClause * ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;default&#39; clause.
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclBase.h:877
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.
Expr * NUB
Update of UpperBound for statically scheduled &#39;omp for&#39; loops.
Definition: StmtOpenMP.h:676
static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, ArrayRef< OMPClause *> Clauses, ArrayRef< OpenMPDirectiveKind > AllowedNameModifiers)
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.
Expr * Cond
Loop condition.
Definition: StmtOpenMP.h:658
VarDecl * ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D)
Initialize declare reduction construct initializer.
static OMPDistributeSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPTargetParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:724
DiagnosticsEngine & getDiagnostics() const
Definition: Sema.h:1208
static OMPTargetParallelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:700
Expr * PreCond
Loop pre-condition.
Definition: StmtOpenMP.h:656
child_range children()
OpenMP 4.0 [2.4, Array Sections].
Definition: ExprOpenMP.h:45
The expressions built for the OpenMP loop CodeGen for the whole collapsed loop nest.
Definition: StmtOpenMP.h:646
OMPClause * ActOnOpenMPWriteClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;write&#39; clause.
static bool checkSimdlenSafelenSpecified(Sema &S, const ArrayRef< OMPClause *> Clauses)
bool hasAttr() const
Definition: DeclBase.h:538
ConditionalOperator - The ?: ternary operator.
Definition: Expr.h:3429
static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, Expr *NumIterations, Sema &SemaRef, Scope *S, DSAStackTy *Stack)
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:277
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1627
This represents &#39;threads&#39; clause in the &#39;#pragma omp ...&#39; directive.
ExprResult CreateBuiltinBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
CreateBuiltinBinOp - Creates a new built-in binary operation with operator Opc at location TokLoc...
Definition: SemaExpr.cpp:11998
Expr * getSimdlen() const
Return safe iteration space distance.
Definition: OpenMPClause.h:537
OMPClause * ActOnOpenMPNowaitClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;nowait&#39; clause.
StmtResult ActOnOpenMPSectionsDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp sections&#39; after parsing of the associated statement.
bool isMoreQualifiedThan(QualType Other) const
Determine whether this type is more qualified than the other given type, requiring exact equality for...
Definition: Type.h:6033
bool isOpenMPPrivate(OpenMPClauseKind Kind)
Checks if the specified clause is one of private clauses like &#39;private&#39;, &#39;firstprivate&#39;, &#39;reduction&#39; etc.
OpenMPClauseKind getClauseKind() const
Returns kind of OpenMP clause (private, shared, reduction, etc.).
Definition: OpenMPClause.h:81
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat)
Definition: Expr.cpp:1785
OverloadedOperatorKind getCXXOverloadedOperator() const
getCXXOverloadedOperator - If this name is the name of an overloadable operator in C++ (e...
static OMPCriticalDirective * Create(const ASTContext &C, const DeclarationNameInfo &Name, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive.
Definition: StmtOpenMP.cpp:310
static OMPOrderedClause * Create(const ASTContext &C, Expr *Num, unsigned NumLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build &#39;ordered&#39; clause.
static bool checkGrainsizeNumTasksClauses(Sema &S, ArrayRef< OMPClause *> Clauses)
Expr * IterationVarRef
Loop iteration variable.
Definition: StmtOpenMP.h:648
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location, which defaults to the empty location.
static OMPDistributeParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Expr * Init
Distribute loop iteration variable init used when composing &#39;omp distribute&#39; with &#39;omp for&#39; in a same...
Definition: StmtOpenMP.h:632
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Scope * getCurScope() const
Retrieve the parser&#39;s current scope.
Definition: Sema.h:10618
This represents implicit clause &#39;depend&#39; for the &#39;#pragma omp task&#39; directive.
VarDecl * isOpenMPCapturedDecl(ValueDecl *D) const
Check if the specified variable is used in one of the private clauses (private, firstprivate, lastprivate, reduction etc.) in OpenMP constructs.
bool CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, OpenMPLinearClauseKind LinKind, QualType Type)
Checks that the specified declaration matches requirements for the linear decls.
This represents &#39;proc_bind&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:677
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:637
Expr - This represents one expression.
Definition: Expr.h:106
void StartOpenMPClause(OpenMPClauseKind K)
Start analysis of clauses.
QualType getPointeeType() const
Definition: Type.h:2550
Allow any unmodeled side effect.
Definition: Expr.h:598
SourceLocation End
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
Definition: Specifiers.h:107
bool isDeclScope(Decl *D)
isDeclScope - Return true if this is the scope that the specified decl is declared in...
Definition: Scope.h:320
int Id
Definition: ASTDiff.cpp:191
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
Definition: Decl.h:1035
void ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner)
Finish current declare reduction construct initializer.
static OMPTargetTeamsDistributeParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
void BuildBasePathArray(const CXXBasePaths &Paths, CXXCastPath &BasePath)
This represents &#39;simdlen&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:503
Stmt * IgnoreContainers(bool IgnoreCaptured=false)
Skip no-op (attributed, compound) container stmts and skip captured stmt at the top, if IgnoreCaptured is true.
Definition: Stmt.cpp:133
OMPThreadPrivateDecl * CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef< Expr *> VarList)
Builds a new OpenMPThreadPrivateDecl and checks its correctness.
bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a parallel-kind directive.
OMPClause * ActOnOpenMPCopyinClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;copyin&#39; clause.
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:6589
OMPClause * ActOnOpenMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;mergeable&#39; clause.
Inits[]
Definition: OpenMPClause.h:145
static InitializedEntity InitializeVariable(VarDecl *Var)
Create the initialization entity for a variable.
unsigned getNumParams() const
Definition: Decl.h:4082
static OMPMasterDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt)
Creates directive.
Definition: StmtOpenMP.cpp:292
void setInit(Expr *I)
Definition: Decl.cpp:2185
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
Definition: DeclBase.cpp:132
static OMPTargetSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
OpenMPClauseKind
OpenMP clauses.
Definition: OpenMPKinds.h:33
bool isFileContext() const
Definition: DeclBase.h:1409
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
StmtResult ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp taskyield&#39;.
SourceLocation getBeginLoc() const
Definition: DeclSpec.h:72
DeclContext * getDeclContext()
Definition: DeclBase.h:428
bool isAnyComplexType() const
Definition: Type.h:6194
static OMPTargetDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:674
static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, OpenMPDirectiveKind CurrentRegion, const DeclarationNameInfo &CurrentName, OpenMPDirectiveKind CancelRegion, SourceLocation StartLoc)
An abstract interface that should be implemented by listeners that want to be notified when an AST en...
static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, Sema &SemaRef, DSAStackTy *Stack, ValueDecl *VD)
OMPClause * ActOnOpenMPDefaultmapClause(OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, SourceLocation KindLoc, SourceLocation EndLoc)
Called on well-formed &#39;defaultmap&#39; clause.
bool isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const
Check if the specified variable is used in &#39;private&#39; clause.
static FloatingLiteral * Create(const ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L)
Definition: Expr.cpp:808
StmtResult ActOnOpenMPTargetParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp target parallel for simd&#39; after parsing of the associated statemen...
bool RequireCompleteType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Definition: SemaType.cpp:7497
OMPClause * ActOnOpenMPPrivateClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;private&#39; clause.
bool builtAll()
Check if all the expressions are built (does not check the worksharing ones).
Definition: StmtOpenMP.h:711
This represents &#39;ordered&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:927
IdentifierInfo * getAsIdentifierInfo() const
getAsIdentifierInfo - Retrieve the IdentifierInfo * stored in this declaration name, or NULL if this declaration name isn&#39;t a simple identifier.
Expr * PrevUB
PreviousUpperBound - local variable passed to runtime in the enclosing schedule or null if that does ...
Definition: StmtOpenMP.h:682
static OMPOrderedDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive.
Definition: StmtOpenMP.cpp:617
QualType getType() const
Definition: Expr.h:128
SmallVector< sema::FunctionScopeInfo *, 4 > FunctionScopes
Stack containing information about each of the nested function, block, and method scopes that are cur...
Definition: Sema.h:538
bool isSingleResult() const
Determines if this names a single result which is not an unresolved value using decl.
Definition: Lookup.h:297
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:1343
static const Expr * checkMapClauseExpressionBase(Sema &SemaRef, Expr *E, OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, OpenMPClauseKind CKind, bool NoDiagnose)
bool isInvalid() const
Definition: Ownership.h:170
OMPClause * ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind, ArrayRef< unsigned > Arguments, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, ArrayRef< SourceLocation > ArgumentsLoc, SourceLocation DelimLoc, SourceLocation EndLoc)
OMPClause * ActOnOpenMPInReductionClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr *> UnresolvedReductions=llvm::None)
Called on well-formed &#39;in_reduction&#39; clause.
bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a taskloop directive.
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
Definition: ASTContext.h:1365
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
Definition: DeclBase.cpp:1040
OMPClause * ActOnOpenMPNumTasksClause(Expr *NumTasks, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;num_tasks&#39; clause.
This represents &#39;collapse&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:557
ValueDecl * getDecl()
Definition: Expr.h:1059
bool isUsable() const
Definition: Ownership.h:171
Represents a C++ conversion function within a class.
Definition: DeclCXX.h:2762
Expr * NLB
Update of LowerBound for statically scheduled omp loops for outer loop in combined constructs (e...
Definition: StmtOpenMP.h:638
The result type of a method or function.
This template specialization was implicitly instantiated from a template.
Definition: Specifiers.h:152
bool isUnionType() const
Definition: Type.cpp:467
StmtResult ActOnOpenMPTaskLoopDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp taskloop&#39; after parsing of the associated statement.
bool isNull() const
Return true if this QualType doesn&#39;t point to a type yet.
Definition: Type.h:720
OpenMPProcBindClauseKind
OpenMP attributes for &#39;proc_bind&#39; clause.
Definition: OpenMPKinds.h:51
StmtResult ActOnOpenMPParallelDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp parallel&#39; after parsing of the associated statement.
StmtResult ActOnOpenMPTargetSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp target simd&#39; after parsing of the associated statement.
void checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, SourceLocation IdLoc=SourceLocation())
Check declaration inside target region.
void setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, unsigned Level)
Sets OpenMP capture kind (OMPC_private, OMPC_firstprivate, OMPC_map etc.) for FD based on DSA for the...
OMPClause * ActOnOpenMPFlushClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;flush&#39; pseudo clause.
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition: Decl.cpp:2006
DefaultDataSharingAttributes
Default data sharing attributes, which can be applied to directive.
Definition: SemaOpenMP.cpp:45
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1...
Definition: Expr.h:1535
bool isDirectInit() const
Whether the initializer is a direct-initializer (list or call).
Definition: Decl.h:1283
OMPClause * ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;device&#39; clause.
Expr * NumIterations
Loop number of iterations.
Definition: StmtOpenMP.h:652
static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)
Create a copy initialization.
ExprResult ActOnFinishFullExpr(Expr *Expr)
Definition: Sema.h:5317
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
Definition: Expr.h:412
This represents &#39;seq_cst&#39; clause in the &#39;#pragma omp atomic&#39; directive.
AttrVec & getAttrs()
Definition: DeclBase.h:480
This represents &#39;untied&#39; clause in the &#39;#pragma omp ...&#39; directive.
bool hasAttrs() const
Definition: DeclBase.h:474
ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)
Definition: SemaCast.cpp:2713
ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E)
Definition: SemaExpr.cpp:3558
static OMPForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:123
Expr * ST
Stride - local variable passed to runtime.
Definition: StmtOpenMP.h:670
void addAttr(Attr *A)
Definition: DeclBase.h:487
SmallVector< Expr *, 4 > PrivateCounters
PrivateCounters Loop counters.
Definition: StmtOpenMP.h:696
This represents &#39;num_teams&#39; clause in the &#39;#pragma omp ...&#39; directive.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class...
Definition: Expr.h:875
#define false
Definition: stdbool.h:33
Kind
This captures a statement into a function.
Definition: Stmt.h:2125
OMPClause * ActOnOpenMPSharedClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;shared&#39; clause.
QualType getCanonicalType() const
Definition: Type.h:5928
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, bool IsMapTypeImplicit, SourceLocation DepLinMapLoc)
ActionResult - This structure is used while parsing/acting on expressions, stmts, etc...
Definition: Ownership.h:157
SmallVector< Expr *, 4 > Counters
Counters Loop counters.
Definition: StmtOpenMP.h:694
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on a template...
Definition: Expr.h:191
ASTContext & getASTContext() const
Definition: Sema.h:1211
llvm::SmallDenseMap< const ValueDecl *, const Expr *, 4 > VarsWithInheritedDSAType
Definition: Sema.h:8787
Encodes a location in the source.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
This represents &#39;hint&#39; clause in the &#39;#pragma omp ...&#39; directive.
OpenMPDependClauseKind
OpenMP attributes for &#39;depend&#39; clause.
Definition: OpenMPKinds.h:76
SourceLocation getOperatorLoc() const
Definition: Expr.h:3181
This represents &#39;#pragma omp declare reduction ...&#39; directive.
Definition: DeclOpenMP.h:102
StmtResult ActOnOpenMPTeamsDistributeSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp teams distribute simd&#39; after parsing of the associated statement...
QualType getUIntPtrType() const
Return a type compatible with "uintptr_t" (C99 7.18.1.4), as defined by the target.
Pseudo declaration for capturing expressions.
Definition: DeclOpenMP.h:187
StmtResult ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, OpenMPDirectiveKind CancelRegion, ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
Definition: Type.h:1958
This is a basic class for representing single OpenMP executable directive.
Definition: StmtOpenMP.h:33
static OMPMapClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> Vars, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists, OpenMPMapClauseKind TypeModifier, OpenMPMapClauseKind Type, bool TypeIsImplicit, SourceLocation TypeLoc)
Creates clause with a list of variables VL.
DeclarationName getName() const
getName - Returns the embedded declaration name.
This represents &#39;schedule&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:746
static unsigned checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, DSAStackTy &DSA, Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, OMPLoopDirective::HelperExprs &Built)
Called on a for stmt to check itself and nested loops (if any).
static OMPParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:335
SourceLocation getLocStart() const LLVM_READONLY
Definition: Stmt.h:401
static Expr * buildPostUpdate(Sema &S, ArrayRef< Expr *> PostUpdates)
Build postupdate expression for the given list of postupdates expressions.
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
Definition: Stmt.h:503
void setReferenced(bool R=true)
Definition: DeclBase.h:584
OpenMPDirectiveKind
OpenMP directives.
Definition: OpenMPKinds.h:23
IdentifierTable & getIdentifierTable()
Definition: Preprocessor.h:829
StmtResult ActOnOpenMPTeamsDistributeParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp teams distribute parallel for simd&#39; after parsing of the associate...
ExprObjectKind
A further classification of the kind of object referenced by an l-value or x-value.
Definition: Specifiers.h:124
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
DeclarationNameInfo getDirectiveName() const
Return name of the directive.
Definition: StmtOpenMP.h:1504
static OMPParallelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:57
StmtResult ActOnOpenMPDistributeSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp distribute simd&#39; after parsing of the associated statement...
static OMPTargetExitDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:818
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:186
SourceLocation getColonLoc() const
Definition: ExprOpenMP.h:111
StmtResult ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Called on well-formed &#39;#pragma omp cancellation point&#39;.
OpenMPLinearClauseKind Modifier
Modifier of &#39;linear&#39; clause.
Definition: OpenMPClause.h:96
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
Definition: Decl.h:1077
ExprResult DefaultLvalueConversion(Expr *E)
Definition: SemaExpr.cpp:532
C-style initialization with assignment.
Definition: Decl.h:819
Expr * PrevEUB
PrevEUB - expression similar to EUB but to be used when loop scheduling uses PrevLB and PrevUB (e...
Definition: StmtOpenMP.h:692
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.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
This is a basic class for representing single OpenMP clause.
Definition: OpenMPClause.h:51
OMPClause * ActOnOpenMPUpdateClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;update&#39; clause.
CanQualType VoidTy
Definition: ASTContext.h:1004
bool isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind)
Checks if the specified directive kind is one of the composite or combined directives that need loop ...
void addDecl(NamedDecl *D)
Definition: UnresolvedSet.h:89
OMPClause * ActOnOpenMPCopyprivateClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;copyprivate&#39; clause.
Describes the kind of initialization being performed, along with location information for tokens rela...
bool isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level) const
Return true if the provided declaration VD should be captured by reference.
bool isValueDependent() const
isValueDependent - Determines whether this expression is value-dependent (C++ [temp.dep.constexpr]).
Definition: Expr.h:149
StmtResult ActOnOpenMPOrderedDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp ordered&#39; after parsing of the associated statement.
bool isAnyPointerType() const
Definition: Type.h:6117
static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, OpenMPDirectiveKind CancelRegion, SourceLocation StartLoc)
A class for iterating through a result set and possibly filtering out results.
Definition: Lookup.h:606
This declaration is only a declaration.
Definition: Decl.h:1146
StmtResult ActOnOpenMPTargetDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp target&#39; after parsing of the associated statement.
SourceLocation getLocStart() const LLVM_READONLY
Returns the starting location of the clause.
Definition: OpenMPClause.h:67
static VarDecl * buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, StringRef Name, const AttrVec *Attrs=nullptr, DeclRefExpr *OrigRef=nullptr)
Build a variable declaration for OpenMP loop iteration variable.
Definition: SemaOpenMP.cpp:845
Stmt * getCapturedStmt()
Retrieve the statement being captured.
Definition: Stmt.h:2226
OMPClause * ActOnOpenMPSeqCstClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;seq_cst&#39; clause.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language...
Definition: Expr.h:249
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required...
Definition: DeclBase.cpp:397
Updates[]
Definition: OpenMPClause.h:145
static void checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, MappableVarListInfo &MVLI, SourceLocation StartLoc, OpenMPMapClauseKind MapType=OMPC_MAP_unknown, bool IsMapTypeImplicit=false)
DistCombinedHelperExprs DistCombinedFields
Expressions used when combining OpenMP loop pragmas.
Definition: StmtOpenMP.h:707
static OMPForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:172
Expr * LB
LowerBound - local variable passed to runtime.
Definition: StmtOpenMP.h:666
void clear(unsigned Size)
Initialize all the fields to null.
Definition: StmtOpenMP.h:719
DefaultMapAttributes
Attributes of the defaultmap clause.
Definition: SemaOpenMP.cpp:52
NamedDecl * next()
Definition: Lookup.h:632
Expr * Init
Loop iteration variable init.
Definition: StmtOpenMP.h:660
ExprResult PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc, Expr *Op)
#define DSAStack
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.
bool isVLASupported() const
Whether target supports variable-length arrays.
Definition: TargetInfo.h:1136
bool isInvalid() const
An error occurred during parsing of the scope specifier.
Definition: DeclSpec.h:194
StmtResult ActOnOpenMPTargetParallelDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp target parallel&#39; after parsing of the associated statement...
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
Definition: ASTContext.h:2275
virtual bool isOutOfLine() const
Determine whether this declaration is declared out of line (outside its semantic context).
Definition: Decl.cpp:99
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
Definition: Type.h:1948
static OMPSingleDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:266
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.
OMPClause * ActOnOpenMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Called on well-formed &#39;dist_schedule&#39; clause.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Definition: Expr.cpp:216
OMPClause * ActOnOpenMPSIMDClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;simd&#39; clause.
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat &#39;semantics&#39; for the specified scalar floating point type.
static bool checkOMPArraySectionConstantForReduction(ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, SmallVectorImpl< llvm::APSInt > &ArraySizes)
Expr * getLHS() const
Definition: Expr.h:3187
static Expr * getCollapseNumberExpr(ArrayRef< OMPClause *> Clauses)
void setStep(Expr *Step)
Sets the linear step for clause.
Definition: OpenMPClause.h:105
static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, const ValueDecl *D, const DSAStackTy::DSAVarData &DVar, bool IsLoopIterVar=false)
OMPClause * ActOnOpenMPNumThreadsClause(Expr *NumThreads, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;num_threads&#39; clause.
static DeclGroupRef Create(ASTContext &C, Decl **Decls, unsigned NumDecls)
Definition: DeclGroup.h:69
* Finals[]
Definition: OpenMPClause.h:146
QualType withRestrict() const
Definition: Type.h:843
static OMPCapturedExprDecl * Create(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, QualType T, SourceLocation StartLoc)
Definition: DeclOpenMP.cpp:92
OpenMPScheduleClauseModifier
OpenMP modifiers for &#39;schedule&#39; clause.
Definition: OpenMPKinds.h:67
Dataflow Directional Tag Classes.
std::string getAsString() const
getAsString - Retrieve the human-readable string for this name.
This represents &#39;device&#39; clause in the &#39;#pragma omp ...&#39; directive.
bool isValid() const
Return true if this is a valid SourceLocation object.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1264
static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, const Expr *E, QualType BaseQTy)
Return true if it can be proven that the provided array expression (array section or array subscript)...
SmallVector< Expr *, 4 > Inits
Expressions for loop counters inits for CodeGen.
Definition: StmtOpenMP.h:698
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
Definition: OperatorKinds.h:22
static OMPThreadPrivateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef< Expr *> VL)
Definition: DeclOpenMP.cpp:29
const Scope * getParent() const
getParent - Return the scope that this is nested in.
Definition: Scope.h:225
static ExprResult buildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, llvm::MapVector< const Expr *, DeclRefExpr *> *Captures=nullptr)
Build &#39;VarRef = Start + Iter * Step&#39;.
void ActOnCapturedRegionError()
Definition: SemaStmt.cpp:4267
static std::string getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, ArrayRef< unsigned > Exclude=llvm::None)
static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, OpenMPDirectiveKind NameModifier=OMPD_unknown)
static OMPParallelSectionsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:433
OMPClause * ActOnOpenMPSimpleClause(OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
const Expr * getInit() const
Definition: Decl.h:1219
void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope)
Initialization of captured region for OpenMP region.
NamedDecl * getCorrectionDecl() const
Gets the pointer to the declaration of the typo correction.
DeclarationName - The name of a declaration.
bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a simd directive.
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup.
Definition: Lookup.h:506
static OMPCapturedExprDecl * buildCaptureDecl(Sema &S, IdentifierInfo *Id, Expr *CaptureExpr, bool WithInit, bool AsExpression)
OMPClause * ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;map&#39; clause.
bool shouldDiagnoseTargetSupportFromOpenMP() const
Return true if (un)supported features for the current target should be diagnosed if OpenMP (offloadin...
Definition: Sema.h:8759
static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, bool StrictlyPositive)
OMPClause * ActOnOpenMPUseDevicePtrClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;use_device_ptr&#39; clause.
This represents clause &#39;linear&#39; in the &#39;#pragma omp ...&#39; directives.
bool isAmbiguous(CanQualType BaseType)
Determine whether the path from the most-derived type to the given base type is ambiguous (i...
bool isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level) const
Check if the specified variable is captured by &#39;target&#39; directive.
bool isIntegerConstantExpr(llvm::APSInt &Result, const ASTContext &Ctx, SourceLocation *Loc=nullptr, bool isEvaluated=true) const
isIntegerConstantExpr - Return true if this expression is a valid integer constant expression...
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveEnd(Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid)
Called at the end of &#39;#pragma omp declare reduction&#39;.
static bool actOnOMPReductionKindClause(Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr *> UnresolvedReductions, ReductionData &RD)
bool isOpenMPThreadPrivate(OpenMPClauseKind Kind)
Checks if the specified clause is one of threadprivate clauses like &#39;threadprivate&#39;, &#39;copyin&#39; or &#39;copyprivate&#39;.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspnd...
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.
static OMPFromClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> Vars, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit)
AddInitializerToDecl - Adds the initializer Init to the declaration dcl.
Definition: SemaDecl.cpp:10936
bool isValid() const
A scope specifier is present, and it refers to a real scope.
Definition: DeclSpec.h:196
Expr * IgnoreParenImpCasts() LLVM_READONLY
IgnoreParenImpCasts - Ignore parentheses and implicit casts.
Definition: Expr.cpp:2631
ExprResult IgnoredValueConversions(Expr *E)
IgnoredValueConversions - Given that an expression&#39;s result is syntactically ignored, perform any conversions that are required.
Class that represents a component of a mappable expression.
StmtResult ActOnOpenMPTargetTeamsDistributeSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp target teams distribute simd&#39; after parsing of the associated stat...
Not an overloaded operator.
Definition: OperatorKinds.h:23
void getOpenMPCaptureRegions(llvm::SmallVectorImpl< OpenMPDirectiveKind > &CaptureRegions, OpenMPDirectiveKind DKind)
Return the captured regions of an OpenMP directive.
void ActOnFinishOpenMPDeclareTargetDirective()
Called at the end of target region i.e. &#39;#pragme omp end declare target&#39;.
Complex values, per C99 6.2.5p11.
Definition: Type.h:2333
bool isInOpenMPTargetExecutionDirective() const
Return true inside OpenMP target region.
bool isOpenMPDistributeDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a distribute directive.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Definition: Expr.h:2226
This file defines OpenMP AST classes for executable directives and clauses.
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
Definition: Type.h:6374
T * getAttr() const
Definition: DeclBase.h:534
void setSeverity(diag::kind Diag, diag::Severity Map, SourceLocation Loc)
This allows the client to specify that certain warnings are ignored.
Definition: Diagnostic.cpp:335
static OMPSectionsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:221
const llvm::APInt & getSize() const
Definition: Type.h:2746
CanQualType DependentTy
Definition: ASTContext.h:1033
bool isDeclInScope(NamedDecl *D, DeclContext *Ctx, Scope *S=nullptr, bool AllowInlineNamespace=false)
isDeclInScope - If &#39;Ctx&#39; is a function/method, isDeclInScope returns true if &#39;D&#39; is in Scope &#39;S&#39;...
Definition: SemaDecl.cpp:1407
OMPClause * ActOnOpenMPIsDevicePtrClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;is_device_ptr&#39; clause.
void ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, VarDecl *OmpPrivParm)
Finish current declare reduction construct initializer.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
Definition: Decl.h:1059
Expr * Inc
Loop increment.
Definition: StmtOpenMP.h:662
DeclContext * getCurLexicalContext() const
Definition: Sema.h:10629
OMPClause * ActOnOpenMPToClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;to&#39; clause.
OpenMPScheduleClauseKind
OpenMP attributes for &#39;schedule&#39; clause.
Definition: OpenMPKinds.h:59
Expr * IgnoreParenLValueCasts() LLVM_READONLY
Ignore parentheses and lvalue casts.
Definition: Expr.cpp:2591
bool popMappings(SourceLocation Loc)
Pops the current DiagMappings off the top of the stack, causing the new top of the stack to be the ac...
Definition: Diagnostic.cpp:102
CXXBasePath & front()
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:2529
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
Definition: ASTContext.h:2251
ImplicitParamDecl * getParam(unsigned i) const
Definition: Decl.h:4084
OMPClause * ActOnOpenMPReductionClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr *> UnresolvedReductions=llvm::None)
Called on well-formed &#39;reduction&#39; clause.
QualType ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, TypeResult ParsedType)
Check if the specified type is allowed to be used in &#39;omp declare reduction&#39; construct.
ExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *InputExpr)
Definition: SemaExpr.cpp:12608
static ExprResult buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, llvm::MapVector< const Expr *, DeclRefExpr *> &Captures)
Build &#39;VarRef = Start.
OpenMPDefaultClauseKind
OpenMP attributes for &#39;default&#39; clause.
Definition: OpenMPKinds.h:43
void addDecl(Decl *D)
Add the declaration D into this context.
Definition: DeclBase.cpp:1460
StmtResult ActOnOpenMPDistributeParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp distribute parallel for simd&#39; after parsing of the associated stat...
static OMPTargetTeamsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
SourceLocation getExprLoc() const LLVM_READONLY
Definition: Expr.h:3180
This represents &#39;write&#39; clause in the &#39;#pragma omp atomic&#39; directive.
const char * getOpenMPDirectiveName(OpenMPDirectiveKind Kind)
Definition: OpenMPKinds.cpp:31
const Type * getTypePtrOrNull() const
Definition: Type.h:5893
StmtResult ActOnOpenMPParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp parallel for simd&#39; after parsing of the associated statement...
void markUsed(ASTContext &C)
Mark the declaration used, in the sense of odr-use.
Definition: DeclBase.cpp:412
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
Definition: ASTContext.h:2052
static OMPTaskLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:866
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types...
Definition: Type.cpp:2034
StmtResult ActOnOpenMPTaskLoopSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp taskloop simd&#39; after parsing of the associated statement...
ASTMutationListener * getASTMutationListener() const
Retrieve a pointer to the AST mutation listener associated with this AST context, if any...
Definition: ASTContext.h:1083
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Definition: ASTContext.h:2235
bool isSet() const
Deprecated.
Definition: DeclSpec.h:209
Expr * UB
DistributeUpperBound - used when composing &#39;omp distribute&#39; with &#39;omp for&#39; in a same construct...
Definition: StmtOpenMP.h:625
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
Definition: SemaDecl.cpp:13820
bool hasMutableFields() const
Determine whether this class, or any of its class subobjects, contains a mutable field.
Definition: DeclCXX.h:1360
StmtResult ActOnOpenMPTeamsDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp teams&#39; after parsing of the associated statement.
CapturedDecl * getCapturedDecl()
Retrieve the outlined function declaration.
Definition: Stmt.cpp:1100
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
Call-style initialization (C++98)
Definition: Decl.h:822
static OMPTaskyieldDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
Definition: StmtOpenMP.cpp:482
ExprResult BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, SourceLocation Loc, const CXXScopeSpec *SS=nullptr)
Definition: SemaExpr.cpp:1643
OpenMPScheduleClauseModifier getSecondScheduleModifier() const
Get the second modifier of the clause.
Definition: OpenMPClause.h:881
void Deallocate(void *Ptr) const
Definition: ASTContext.h:664
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition: Expr.h:2500
static OMPTargetDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:774
StmtResult ActOnOpenMPTaskgroupDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp taskgroup&#39;.
void setSuppressAllDiagnostics(bool Val=true)
Suppress all diagnostics, to silence the front end when we know that we don&#39;t want any more diagnosti...
Definition: Diagnostic.h:632
Expr * UB
UpperBound - local variable passed to runtime.
Definition: StmtOpenMP.h:668
static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, Sema &SemaRef, Decl *D)
Describes the sequence of initializations required to initialize a given object or reference with a s...
ActionResult< Expr * > ExprResult
Definition: Ownership.h:267
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition: Type.h:5969
This represents &#39;nowait&#39; clause in the &#39;#pragma omp ...&#39; directive.
void setEnd(SourceLocation e)
void ActOnOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id, OMPDeclareTargetDeclAttr::MapTypeTy MT, NamedDeclSetType &SameDirectiveDecls)
Called on correct id-expression from the &#39;#pragma omp declare target&#39;.
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g., it is an signed integer type or a vector.
Definition: Type.cpp:1878
Represents a C++ struct/union/class.
Definition: DeclCXX.h:302
OpenMPScheduleClauseModifier getFirstScheduleModifier() const
Get the first modifier of the clause.
Definition: OpenMPClause.h:876
This represents &#39;num_tasks&#39; clause in the &#39;#pragma omp ...&#39; directive.
sema::FunctionScopeInfo * getCurFunction() const
Definition: Sema.h:1331
static QualType getBaseOriginalType(const Expr *Base)
Return original type of the base expression for array section.
Definition: Expr.cpp:4166
StmtResult ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp taskwait&#39;.
bool hasIntegerRepresentation() const
Determine whether this type has an integer representation of some sort, e.g., it is an integer type o...
Definition: Type.cpp:1737
static OMPBarrierDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
Definition: StmtOpenMP.cpp:497
Privates[]
Gets the list of initial values for linear variables.
Definition: OpenMPClause.h:145
OpenMPMapClauseKind
OpenMP mapping kind for &#39;map&#39; clause.
Definition: OpenMPKinds.h:92
void addHiddenDecl(Decl *D)
Add the declaration D to this context without modifying any lookup tables.
Definition: DeclBase.cpp:1434
SourceLocation getFirstScheduleModifierLoc() const
Get the first modifier location.
Definition: OpenMPClause.h:892
Do not present this diagnostic, ignore it.
AccessResult CheckBaseClassAccess(SourceLocation AccessLoc, QualType Base, QualType Derived, const CXXBasePath &Path, unsigned DiagID, bool ForceCheck=false, bool ForceUnprivileged=false)
Checks access for a hierarchy conversion.
OMPClause * ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;thread_limit&#39; clause.
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
Definition: Sema.h:331
bool containsUnexpandedParameterPack() const
Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates)...
Definition: Expr.h:214
Declaration of a class template.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
StmtResult ActOnOpenMPAtomicDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp atomic&#39; after parsing of the associated statement.
static OMPSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:83
StmtResult ActOnOpenMPSingleDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp single&#39; after parsing of the associated statement.
iterator end() const
Definition: Lookup.h:325
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:266
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2316
DeclGroupPtrTy ActOnOpenMPThreadprivateDirective(SourceLocation Loc, ArrayRef< Expr *> VarList)
Called on well-formed &#39;#pragma omp threadprivate&#39;.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:275
ExprResult ExprError()
Definition: Ownership.h:283
This represents &#39;dist_schedule&#39; clause in the &#39;#pragma omp ...&#39; directive.
__DEVICE__ int max(int __a, int __b)
static OMPTaskwaitDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
Definition: StmtOpenMP.cpp:511
Expr * Cond
Distribute Loop condition used when composing &#39;omp distribute&#39; with &#39;omp for&#39; in a same construct...
Definition: StmtOpenMP.h:635
Stmt * PreInits
Init statement for all captured expressions.
Definition: StmtOpenMP.h:704
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:1942
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:974
Expr * getRHS() const
Definition: Expr.h:3189
void ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init)
Check if the current region is an OpenMP loop region and if it is, mark loop control variable...
static OMPTargetTeamsDistributeSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
bool isPointerType() const
Definition: Type.h:6113
static OverloadedOperatorKind getOverloadedOperator(Opcode Opc)
Retrieve the overloaded operator kind that corresponds to the given binary opcode.
Definition: Expr.cpp:1884
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef)
Check if the given expression E is a constant integer that fits into Bits bits.
static OMPFlushClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL)
Creates clause with a list of variables VL.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
OMPClause * ActOnOpenMPAlignedClause(ArrayRef< Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed &#39;aligned&#39; clause.
DefinitionKind isThisDeclarationADefinition(ASTContext &) const
Check whether this declaration is a definition.
Definition: Decl.cpp:2009
bool isStaticDataMember() const
Determines whether this is a static data member.
Definition: Decl.h:1134
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
Definition: Lookup.h:572
SmallVector< CompoundScopeInfo, 4 > CompoundScopes
The stack of currently active compound stamement scopes in the function.
Definition: ScopeInfo.h:203
QualType getType() const
Definition: Decl.h:648
bool empty() const
Return true if no decls were found.
Definition: Lookup.h:328
An l-value expression is a reference to an object with independent storage.
Definition: Specifiers.h:114
StmtResult ActOnOpenMPParallelSectionsDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp parallel sections&#39; after parsing of the associated statement...
static OMPCancelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion)
Creates directive.
Definition: StmtOpenMP.cpp:571
bool isOpenMPLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a directive with an associated loop construct.
OMPClause * ActOnOpenMPFromClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;from&#39; clause.
Expr * IL
IsLastIteration - local flag variable passed to runtime.
Definition: StmtOpenMP.h:664
A trivial tuple used to represent a source range.
ASTContext & Context
Definition: Sema.h:319
This represents a decl that may have a name.
Definition: Decl.h:248
static OMPCancellationPointDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Creates directive.
Definition: StmtOpenMP.cpp:550
bool isTranslationUnit() const
Definition: DeclBase.h:1413
void setAccess(AccessSpecifier AS)
Definition: DeclBase.h:458
CanQualType BoolTy
Definition: ASTContext.h:1005
static T filterLookupForUDR(SmallVectorImpl< U > &Lookups, const llvm::function_ref< T(ValueDecl *)> Gen)
OMPClause * ActOnOpenMPOrderedClause(SourceLocation StartLoc, SourceLocation EndLoc, SourceLocation LParenLoc=SourceLocation(), Expr *NumForLoops=nullptr)
Called on well-formed &#39;ordered&#39; clause.
Directive - Abstract class representing a parsed verify directive.
QualType getVariableArrayType(QualType EltTy, Expr *NumElts, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals, SourceRange Brackets) const
Return a non-unique reference to the type for a variable array of the specified element type...
OMPClause * ActOnOpenMPCollapseClause(Expr *NumForLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;collapse&#39; clause.
bool isConstant(const ASTContext &Ctx) const
Definition: Type.h:790
ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
Definition: SemaExpr.cpp:12492
static OMPClauseWithPostUpdate * get(OMPClause *C)
iterator begin() const
Definition: Lookup.h:324
Describes an entity that is being initialized.
NamedDecl * getRepresentativeDecl() const
Fetches a representative decl. Useful for lazy diagnostics.
Definition: Lookup.h:513
bool hasInit() const
Definition: Decl.cpp:2144
SourceLocation getBegin() const
SourceLocation ColonLoc
Location of &#39;:&#39;.
Definition: OpenMPClause.h:102
static OMPTaskLoopSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:915
This represents &#39;#pragma omp threadprivate ...&#39; directive.
Definition: DeclOpenMP.h:39
VerifyDiagnosticConsumer::Directive Directive
bool isExternCXXContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
Definition: DeclBase.cpp:1106
Represents the canonical version of C arrays with a specified constant size.
Definition: Type.h:2728
Declaration of a template function.
Definition: DeclTemplate.h:968
bool getSuppressAllDiagnostics() const
Definition: Diagnostic.h:635
void clear()
Clears out any current state.
Definition: Lookup.h:543
OMPClause * ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
SourceLocation getLocation() const
Definition: DeclBase.h:419
StmtResult ActOnOpenMPTeamsDistributeParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp teams distribute parallel for&#39; after parsing of the associated sta...
Expr * getLength()
Get length of array section.
Definition: ExprOpenMP.h:99
QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const
getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth, signed/unsigned.
StmtResult ActOnOpenMPDistributeParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp distribute parallel for&#39; after parsing of the associated statement...
bool isOpenMPNestingTeamsDirective(OpenMPDirectiveKind DKind)
Checks if the specified composite/combined directive constitutes a teams directive in the outermost n...
Helper class that creates diagnostics with optional template instantiation stacks.
Definition: Sema.h:1234
Expr * IgnoreParens() LLVM_READONLY
IgnoreParens - Ignore parentheses.
Definition: Expr.cpp:2513
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.
ExprResult getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, ExprObjectKind OK, SourceLocation Loc)
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
Expr * getBase()
An array section can be written only as Base[LowerBound:Length].
Definition: ExprOpenMP.h:82