clang  6.0.0svn
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 /// \brief 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 /// \brief Default data sharing attributes, which can be applied to directive.
46  DSA_unspecified = 0, /// \brief Data sharing attribute not specified.
47  DSA_none = 1 << 0, /// \brief Default data sharing attribute 'none'.
48  DSA_shared = 1 << 1, /// \brief 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 /// \brief Stack for tracking declarations used in OpenMP directives and
58 /// clauses and their data-sharing attributes.
59 class DSAStackTy final {
60 public:
61  struct DSAVarData final {
64  Expr *RefExpr = nullptr;
65  DeclRefExpr *PrivateCopy = nullptr;
66  SourceLocation ImplicitDSALoc;
67  DSAVarData() = default;
68  DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, Expr *RefExpr,
69  DeclRefExpr *PrivateCopy, SourceLocation ImplicitDSALoc)
70  : DKind(DKind), CKind(CKind), RefExpr(RefExpr),
71  PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {}
72  };
74  OperatorOffsetTy;
75 
76 private:
77  struct DSAInfo final {
78  OpenMPClauseKind Attributes = OMPC_unknown;
79  /// Pointer to a reference expression and a flag which shows that the
80  /// variable is marked as lastprivate(true) or not (false).
81  llvm::PointerIntPair<Expr *, 1, bool> RefExpr;
82  DeclRefExpr *PrivateCopy = nullptr;
83  };
84  typedef llvm::DenseMap<ValueDecl *, DSAInfo> DeclSAMapTy;
85  typedef llvm::DenseMap<ValueDecl *, Expr *> AlignedMapTy;
86  typedef std::pair<unsigned, VarDecl *> LCDeclInfo;
87  typedef llvm::DenseMap<ValueDecl *, LCDeclInfo> LoopControlVariablesMapTy;
88  /// Struct that associates a component with the clause kind where they are
89  /// found.
90  struct MappedExprComponentTy {
93  };
94  typedef llvm::DenseMap<ValueDecl *, MappedExprComponentTy>
95  MappedExprComponentsTy;
96  typedef llvm::StringMap<std::pair<OMPCriticalDirective *, llvm::APSInt>>
97  CriticalsWithHintsTy;
98  typedef llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>
99  DoacrossDependMapTy;
100  struct ReductionData {
101  typedef llvm::PointerEmbeddedInt<BinaryOperatorKind, 16> BOKPtrType;
102  SourceRange ReductionRange;
103  llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
104  ReductionData() = default;
105  void set(BinaryOperatorKind BO, SourceRange RR) {
106  ReductionRange = RR;
107  ReductionOp = BO;
108  }
109  void set(const Expr *RefExpr, SourceRange RR) {
110  ReductionRange = RR;
111  ReductionOp = RefExpr;
112  }
113  };
114  typedef llvm::DenseMap<ValueDecl *, ReductionData> DeclReductionMapTy;
115 
116  struct SharingMapTy final {
117  DeclSAMapTy SharingMap;
118  DeclReductionMapTy ReductionMap;
119  AlignedMapTy AlignedMap;
120  MappedExprComponentsTy MappedExprComponents;
121  LoopControlVariablesMapTy LCVMap;
122  DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
123  SourceLocation DefaultAttrLoc;
124  DefaultMapAttributes DefaultMapAttr = DMA_unspecified;
125  SourceLocation DefaultMapAttrLoc;
127  DeclarationNameInfo DirectiveName;
128  Scope *CurScope = nullptr;
129  SourceLocation ConstructLoc;
130  /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
131  /// get the data (loop counters etc.) about enclosing loop-based construct.
132  /// This data is required during codegen.
133  DoacrossDependMapTy DoacrossDepends;
134  /// \brief first argument (Expr *) contains optional argument of the
135  /// 'ordered' clause, the second one is true if the regions has 'ordered'
136  /// clause, false otherwise.
137  llvm::PointerIntPair<Expr *, 1, bool> OrderedRegion;
138  bool NowaitRegion = false;
139  bool CancelRegion = false;
140  unsigned AssociatedLoops = 1;
141  SourceLocation InnerTeamsRegionLoc;
142  /// Reference to the taskgroup task_reduction reference expression.
143  Expr *TaskgroupReductionRef = nullptr;
144  SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
145  Scope *CurScope, SourceLocation Loc)
146  : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
147  ConstructLoc(Loc) {}
148  SharingMapTy() = default;
149  };
150 
151  typedef SmallVector<SharingMapTy, 4> StackTy;
152 
153  /// \brief Stack of used declaration and their data-sharing attributes.
154  DeclSAMapTy Threadprivates;
155  const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
157  /// \brief true, if check for DSA must be from parent directive, false, if
158  /// from current directive.
159  OpenMPClauseKind ClauseKindMode = OMPC_unknown;
160  Sema &SemaRef;
161  bool ForceCapturing = false;
162  CriticalsWithHintsTy Criticals;
163 
164  typedef SmallVector<SharingMapTy, 8>::reverse_iterator reverse_iterator;
165 
166  DSAVarData getDSA(StackTy::reverse_iterator &Iter, ValueDecl *D);
167 
168  /// \brief Checks if the variable is a local for OpenMP region.
169  bool isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter);
170 
171  bool isStackEmpty() const {
172  return Stack.empty() ||
173  Stack.back().second != CurrentNonCapturingFunctionScope ||
174  Stack.back().first.empty();
175  }
176 
177 public:
178  explicit DSAStackTy(Sema &S) : SemaRef(S) {}
179 
180  bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
181  OpenMPClauseKind getClauseParsingMode() const {
182  assert(isClauseParsingMode() && "Must be in clause parsing mode.");
183  return ClauseKindMode;
184  }
185  void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
186 
187  bool isForceVarCapturing() const { return ForceCapturing; }
188  void setForceVarCapturing(bool V) { ForceCapturing = V; }
189 
190  void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
191  Scope *CurScope, SourceLocation Loc) {
192  if (Stack.empty() ||
193  Stack.back().second != CurrentNonCapturingFunctionScope)
194  Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
195  Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
196  Stack.back().first.back().DefaultAttrLoc = Loc;
197  }
198 
199  void pop() {
200  assert(!Stack.back().first.empty() &&
201  "Data-sharing attributes stack is empty!");
202  Stack.back().first.pop_back();
203  }
204 
205  /// Start new OpenMP region stack in new non-capturing function.
206  void pushFunction() {
207  const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
208  assert(!isa<CapturingScopeInfo>(CurFnScope));
209  CurrentNonCapturingFunctionScope = CurFnScope;
210  }
211  /// Pop region stack for non-capturing function.
212  void popFunction(const FunctionScopeInfo *OldFSI) {
213  if (!Stack.empty() && Stack.back().second == OldFSI) {
214  assert(Stack.back().first.empty());
215  Stack.pop_back();
216  }
217  CurrentNonCapturingFunctionScope = nullptr;
218  for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
219  if (!isa<CapturingScopeInfo>(FSI)) {
220  CurrentNonCapturingFunctionScope = FSI;
221  break;
222  }
223  }
224  }
225 
226  void addCriticalWithHint(OMPCriticalDirective *D, llvm::APSInt Hint) {
227  Criticals[D->getDirectiveName().getAsString()] = std::make_pair(D, Hint);
228  }
229  const std::pair<OMPCriticalDirective *, llvm::APSInt>
230  getCriticalWithHint(const DeclarationNameInfo &Name) const {
231  auto I = Criticals.find(Name.getAsString());
232  if (I != Criticals.end())
233  return I->second;
234  return std::make_pair(nullptr, llvm::APSInt());
235  }
236  /// \brief If 'aligned' declaration for given variable \a D was not seen yet,
237  /// add it and return NULL; otherwise return previous occurrence's expression
238  /// for diagnostics.
239  Expr *addUniqueAligned(ValueDecl *D, Expr *NewDE);
240 
241  /// \brief Register specified variable as loop control variable.
242  void addLoopControlVariable(ValueDecl *D, VarDecl *Capture);
243  /// \brief Check if the specified variable is a loop control variable for
244  /// current region.
245  /// \return The index of the loop control variable in the list of associated
246  /// for-loops (from outer to inner).
247  LCDeclInfo isLoopControlVariable(ValueDecl *D);
248  /// \brief Check if the specified variable is a loop control variable for
249  /// parent region.
250  /// \return The index of the loop control variable in the list of associated
251  /// for-loops (from outer to inner).
252  LCDeclInfo isParentLoopControlVariable(ValueDecl *D);
253  /// \brief Get the loop control variable for the I-th loop (or nullptr) in
254  /// parent directive.
255  ValueDecl *getParentLoopControlVariable(unsigned I);
256 
257  /// \brief Adds explicit data sharing attribute to the specified declaration.
258  void addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A,
259  DeclRefExpr *PrivateCopy = nullptr);
260 
261  /// Adds additional information for the reduction items with the reduction id
262  /// represented as an operator.
263  void addTaskgroupReductionData(ValueDecl *D, SourceRange SR,
264  BinaryOperatorKind BOK);
265  /// Adds additional information for the reduction items with the reduction id
266  /// represented as reduction identifier.
267  void addTaskgroupReductionData(ValueDecl *D, SourceRange SR,
268  const Expr *ReductionRef);
269  /// Returns the location and reduction operation from the innermost parent
270  /// region for the given \p D.
271  DSAVarData getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR,
272  BinaryOperatorKind &BOK,
273  Expr *&TaskgroupDescriptor);
274  /// Returns the location and reduction operation from the innermost parent
275  /// region for the given \p D.
276  DSAVarData getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR,
277  const Expr *&ReductionRef,
278  Expr *&TaskgroupDescriptor);
279  /// Return reduction reference expression for the current taskgroup.
280  Expr *getTaskgroupReductionRef() const {
281  assert(Stack.back().first.back().Directive == OMPD_taskgroup &&
282  "taskgroup reference expression requested for non taskgroup "
283  "directive.");
284  return Stack.back().first.back().TaskgroupReductionRef;
285  }
286  /// Checks if the given \p VD declaration is actually a taskgroup reduction
287  /// descriptor variable at the \p Level of OpenMP regions.
288  bool isTaskgroupReductionRef(ValueDecl *VD, unsigned Level) const {
289  return Stack.back().first[Level].TaskgroupReductionRef &&
290  cast<DeclRefExpr>(Stack.back().first[Level].TaskgroupReductionRef)
291  ->getDecl() == VD;
292  }
293 
294  /// \brief Returns data sharing attributes from top of the stack for the
295  /// specified declaration.
296  DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
297  /// \brief Returns data-sharing attributes for the specified declaration.
298  DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent);
299  /// \brief Checks if the specified variables has data-sharing attributes which
300  /// match specified \a CPred predicate in any directive which matches \a DPred
301  /// predicate.
302  DSAVarData hasDSA(ValueDecl *D,
303  const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
304  const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
305  bool FromParent);
306  /// \brief Checks if the specified variables has data-sharing attributes which
307  /// match specified \a CPred predicate in any innermost directive which
308  /// matches \a DPred predicate.
309  DSAVarData
310  hasInnermostDSA(ValueDecl *D,
311  const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
312  const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
313  bool FromParent);
314  /// \brief Checks if the specified variables has explicit data-sharing
315  /// attributes which match specified \a CPred predicate at the specified
316  /// OpenMP region.
317  bool hasExplicitDSA(ValueDecl *D,
318  const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
319  unsigned Level, bool NotLastprivate = false);
320 
321  /// \brief Returns true if the directive at level \Level matches in the
322  /// specified \a DPred predicate.
323  bool hasExplicitDirective(
324  const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
325  unsigned Level);
326 
327  /// \brief Finds a directive which matches specified \a DPred predicate.
328  bool hasDirective(const llvm::function_ref<bool(OpenMPDirectiveKind,
329  const DeclarationNameInfo &,
330  SourceLocation)> &DPred,
331  bool FromParent);
332 
333  /// \brief Returns currently analyzed directive.
334  OpenMPDirectiveKind getCurrentDirective() const {
335  return isStackEmpty() ? OMPD_unknown : Stack.back().first.back().Directive;
336  }
337  /// \brief Returns directive kind at specified level.
338  OpenMPDirectiveKind getDirective(unsigned Level) const {
339  assert(!isStackEmpty() && "No directive at specified level.");
340  return Stack.back().first[Level].Directive;
341  }
342  /// \brief Returns parent directive.
343  OpenMPDirectiveKind getParentDirective() const {
344  if (isStackEmpty() || Stack.back().first.size() == 1)
345  return OMPD_unknown;
346  return std::next(Stack.back().first.rbegin())->Directive;
347  }
348 
349  /// \brief Set default data sharing attribute to none.
350  void setDefaultDSANone(SourceLocation Loc) {
351  assert(!isStackEmpty());
352  Stack.back().first.back().DefaultAttr = DSA_none;
353  Stack.back().first.back().DefaultAttrLoc = Loc;
354  }
355  /// \brief Set default data sharing attribute to shared.
356  void setDefaultDSAShared(SourceLocation Loc) {
357  assert(!isStackEmpty());
358  Stack.back().first.back().DefaultAttr = DSA_shared;
359  Stack.back().first.back().DefaultAttrLoc = Loc;
360  }
361  /// Set default data mapping attribute to 'tofrom:scalar'.
362  void setDefaultDMAToFromScalar(SourceLocation Loc) {
363  assert(!isStackEmpty());
364  Stack.back().first.back().DefaultMapAttr = DMA_tofrom_scalar;
365  Stack.back().first.back().DefaultMapAttrLoc = Loc;
366  }
367 
368  DefaultDataSharingAttributes getDefaultDSA() const {
369  return isStackEmpty() ? DSA_unspecified
370  : Stack.back().first.back().DefaultAttr;
371  }
372  SourceLocation getDefaultDSALocation() const {
373  return isStackEmpty() ? SourceLocation()
374  : Stack.back().first.back().DefaultAttrLoc;
375  }
376  DefaultMapAttributes getDefaultDMA() const {
377  return isStackEmpty() ? DMA_unspecified
378  : Stack.back().first.back().DefaultMapAttr;
379  }
380  DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const {
381  return Stack.back().first[Level].DefaultMapAttr;
382  }
383  SourceLocation getDefaultDMALocation() const {
384  return isStackEmpty() ? SourceLocation()
385  : Stack.back().first.back().DefaultMapAttrLoc;
386  }
387 
388  /// \brief Checks if the specified variable is a threadprivate.
389  bool isThreadPrivate(VarDecl *D) {
390  DSAVarData DVar = getTopDSA(D, false);
391  return isOpenMPThreadPrivate(DVar.CKind);
392  }
393 
394  /// \brief Marks current region as ordered (it has an 'ordered' clause).
395  void setOrderedRegion(bool IsOrdered, Expr *Param) {
396  assert(!isStackEmpty());
397  Stack.back().first.back().OrderedRegion.setInt(IsOrdered);
398  Stack.back().first.back().OrderedRegion.setPointer(Param);
399  }
400  /// \brief Returns true, if parent region is ordered (has associated
401  /// 'ordered' clause), false - otherwise.
402  bool isParentOrderedRegion() const {
403  if (isStackEmpty() || Stack.back().first.size() == 1)
404  return false;
405  return std::next(Stack.back().first.rbegin())->OrderedRegion.getInt();
406  }
407  /// \brief Returns optional parameter for the ordered region.
408  Expr *getParentOrderedRegionParam() const {
409  if (isStackEmpty() || Stack.back().first.size() == 1)
410  return nullptr;
411  return std::next(Stack.back().first.rbegin())->OrderedRegion.getPointer();
412  }
413  /// \brief Marks current region as nowait (it has a 'nowait' clause).
414  void setNowaitRegion(bool IsNowait = true) {
415  assert(!isStackEmpty());
416  Stack.back().first.back().NowaitRegion = IsNowait;
417  }
418  /// \brief Returns true, if parent region is nowait (has associated
419  /// 'nowait' clause), false - otherwise.
420  bool isParentNowaitRegion() const {
421  if (isStackEmpty() || Stack.back().first.size() == 1)
422  return false;
423  return std::next(Stack.back().first.rbegin())->NowaitRegion;
424  }
425  /// \brief Marks parent region as cancel region.
426  void setParentCancelRegion(bool Cancel = true) {
427  if (!isStackEmpty() && Stack.back().first.size() > 1) {
428  auto &StackElemRef = *std::next(Stack.back().first.rbegin());
429  StackElemRef.CancelRegion |= StackElemRef.CancelRegion || Cancel;
430  }
431  }
432  /// \brief Return true if current region has inner cancel construct.
433  bool isCancelRegion() const {
434  return isStackEmpty() ? false : Stack.back().first.back().CancelRegion;
435  }
436 
437  /// \brief Set collapse value for the region.
438  void setAssociatedLoops(unsigned Val) {
439  assert(!isStackEmpty());
440  Stack.back().first.back().AssociatedLoops = Val;
441  }
442  /// \brief Return collapse value for region.
443  unsigned getAssociatedLoops() const {
444  return isStackEmpty() ? 0 : Stack.back().first.back().AssociatedLoops;
445  }
446 
447  /// \brief Marks current target region as one with closely nested teams
448  /// region.
449  void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
450  if (!isStackEmpty() && Stack.back().first.size() > 1) {
451  std::next(Stack.back().first.rbegin())->InnerTeamsRegionLoc =
452  TeamsRegionLoc;
453  }
454  }
455  /// \brief Returns true, if current region has closely nested teams region.
456  bool hasInnerTeamsRegion() const {
457  return getInnerTeamsRegionLoc().isValid();
458  }
459  /// \brief Returns location of the nested teams region (if any).
460  SourceLocation getInnerTeamsRegionLoc() const {
461  return isStackEmpty() ? SourceLocation()
462  : Stack.back().first.back().InnerTeamsRegionLoc;
463  }
464 
465  Scope *getCurScope() const {
466  return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope;
467  }
468  Scope *getCurScope() {
469  return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope;
470  }
471  SourceLocation getConstructLoc() {
472  return isStackEmpty() ? SourceLocation()
473  : Stack.back().first.back().ConstructLoc;
474  }
475 
476  /// Do the check specified in \a Check to all component lists and return true
477  /// if any issue is found.
478  bool checkMappableExprComponentListsForDecl(
479  ValueDecl *VD, bool CurrentRegionOnly,
480  const llvm::function_ref<
482  OpenMPClauseKind)> &Check) {
483  if (isStackEmpty())
484  return false;
485  auto SI = Stack.back().first.rbegin();
486  auto SE = Stack.back().first.rend();
487 
488  if (SI == SE)
489  return false;
490 
491  if (CurrentRegionOnly) {
492  SE = std::next(SI);
493  } else {
494  ++SI;
495  }
496 
497  for (; SI != SE; ++SI) {
498  auto MI = SI->MappedExprComponents.find(VD);
499  if (MI != SI->MappedExprComponents.end())
500  for (auto &L : MI->second.Components)
501  if (Check(L, MI->second.Kind))
502  return true;
503  }
504  return false;
505  }
506 
507  /// Do the check specified in \a Check to all component lists at a given level
508  /// and return true if any issue is found.
509  bool checkMappableExprComponentListsForDeclAtLevel(
510  ValueDecl *VD, unsigned Level,
511  const llvm::function_ref<
513  OpenMPClauseKind)> &Check) {
514  if (isStackEmpty())
515  return false;
516 
517  auto StartI = Stack.back().first.begin();
518  auto EndI = Stack.back().first.end();
519  if (std::distance(StartI, EndI) <= (int)Level)
520  return false;
521  std::advance(StartI, Level);
522 
523  auto MI = StartI->MappedExprComponents.find(VD);
524  if (MI != StartI->MappedExprComponents.end())
525  for (auto &L : MI->second.Components)
526  if (Check(L, MI->second.Kind))
527  return true;
528  return false;
529  }
530 
531  /// Create a new mappable expression component list associated with a given
532  /// declaration and initialize it with the provided list of components.
533  void addMappableExpressionComponents(
534  ValueDecl *VD,
536  OpenMPClauseKind WhereFoundClauseKind) {
537  assert(!isStackEmpty() &&
538  "Not expecting to retrieve components from a empty stack!");
539  auto &MEC = Stack.back().first.back().MappedExprComponents[VD];
540  // Create new entry and append the new components there.
541  MEC.Components.resize(MEC.Components.size() + 1);
542  MEC.Components.back().append(Components.begin(), Components.end());
543  MEC.Kind = WhereFoundClauseKind;
544  }
545 
546  unsigned getNestingLevel() const {
547  assert(!isStackEmpty());
548  return Stack.back().first.size() - 1;
549  }
550  void addDoacrossDependClause(OMPDependClause *C, OperatorOffsetTy &OpsOffs) {
551  assert(!isStackEmpty() && Stack.back().first.size() > 1);
552  auto &StackElem = *std::next(Stack.back().first.rbegin());
553  assert(isOpenMPWorksharingDirective(StackElem.Directive));
554  StackElem.DoacrossDepends.insert({C, OpsOffs});
555  }
556  llvm::iterator_range<DoacrossDependMapTy::const_iterator>
557  getDoacrossDependClauses() const {
558  assert(!isStackEmpty());
559  auto &StackElem = Stack.back().first.back();
560  if (isOpenMPWorksharingDirective(StackElem.Directive)) {
561  auto &Ref = StackElem.DoacrossDepends;
562  return llvm::make_range(Ref.begin(), Ref.end());
563  }
564  return llvm::make_range(StackElem.DoacrossDepends.end(),
565  StackElem.DoacrossDepends.end());
566  }
567 };
568 bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) {
569  return isOpenMPParallelDirective(DKind) || isOpenMPTaskingDirective(DKind) ||
570  isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown;
571 }
572 } // namespace
573 
575  if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(E))
576  E = ExprTemp->getSubExpr();
577 
578  if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
579  E = MTE->GetTemporaryExpr();
580 
581  while (auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
582  E = Binder->getSubExpr();
583 
584  if (auto *ICE = dyn_cast<ImplicitCastExpr>(E))
585  E = ICE->getSubExprAsWritten();
586  return E->IgnoreParens();
587 }
588 
590  if (auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
591  if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
592  D = ME->getMemberDecl();
593  auto *VD = dyn_cast<VarDecl>(D);
594  auto *FD = dyn_cast<FieldDecl>(D);
595  if (VD != nullptr) {
596  VD = VD->getCanonicalDecl();
597  D = VD;
598  } else {
599  assert(FD);
600  FD = FD->getCanonicalDecl();
601  D = FD;
602  }
603  return D;
604 }
605 
606 DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator &Iter,
607  ValueDecl *D) {
608  D = getCanonicalDecl(D);
609  auto *VD = dyn_cast<VarDecl>(D);
610  auto *FD = dyn_cast<FieldDecl>(D);
611  DSAVarData DVar;
612  if (isStackEmpty() || Iter == Stack.back().first.rend()) {
613  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
614  // in a region but not in construct]
615  // File-scope or namespace-scope variables referenced in called routines
616  // in the region are shared unless they appear in a threadprivate
617  // directive.
618  if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(D))
619  DVar.CKind = OMPC_shared;
620 
621  // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
622  // in a region but not in construct]
623  // Variables with static storage duration that are declared in called
624  // routines in the region are shared.
625  if (VD && VD->hasGlobalStorage())
626  DVar.CKind = OMPC_shared;
627 
628  // Non-static data members are shared by default.
629  if (FD)
630  DVar.CKind = OMPC_shared;
631 
632  return DVar;
633  }
634 
635  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
636  // in a Construct, C/C++, predetermined, p.1]
637  // Variables with automatic storage duration that are declared in a scope
638  // inside the construct are private.
639  if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
640  (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
641  DVar.CKind = OMPC_private;
642  return DVar;
643  }
644 
645  DVar.DKind = Iter->Directive;
646  // Explicitly specified attributes and local variables with predetermined
647  // attributes.
648  if (Iter->SharingMap.count(D)) {
649  DVar.RefExpr = Iter->SharingMap[D].RefExpr.getPointer();
650  DVar.PrivateCopy = Iter->SharingMap[D].PrivateCopy;
651  DVar.CKind = Iter->SharingMap[D].Attributes;
652  DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
653  return DVar;
654  }
655 
656  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
657  // in a Construct, C/C++, implicitly determined, p.1]
658  // In a parallel or task construct, the data-sharing attributes of these
659  // variables are determined by the default clause, if present.
660  switch (Iter->DefaultAttr) {
661  case DSA_shared:
662  DVar.CKind = OMPC_shared;
663  DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
664  return DVar;
665  case DSA_none:
666  return DVar;
667  case DSA_unspecified:
668  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
669  // in a Construct, implicitly determined, p.2]
670  // In a parallel construct, if no default clause is present, these
671  // variables are shared.
672  DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
673  if (isOpenMPParallelDirective(DVar.DKind) ||
674  isOpenMPTeamsDirective(DVar.DKind)) {
675  DVar.CKind = OMPC_shared;
676  return DVar;
677  }
678 
679  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
680  // in a Construct, implicitly determined, p.4]
681  // In a task construct, if no default clause is present, a variable that in
682  // the enclosing context is determined to be shared by all implicit tasks
683  // bound to the current team is shared.
684  if (isOpenMPTaskingDirective(DVar.DKind)) {
685  DSAVarData DVarTemp;
686  auto I = Iter, E = Stack.back().first.rend();
687  do {
688  ++I;
689  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
690  // Referenced in a Construct, implicitly determined, p.6]
691  // In a task construct, if no default clause is present, a variable
692  // whose data-sharing attribute is not determined by the rules above is
693  // firstprivate.
694  DVarTemp = getDSA(I, D);
695  if (DVarTemp.CKind != OMPC_shared) {
696  DVar.RefExpr = nullptr;
697  DVar.CKind = OMPC_firstprivate;
698  return DVar;
699  }
700  } while (I != E && !isParallelOrTaskRegion(I->Directive));
701  DVar.CKind =
702  (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
703  return DVar;
704  }
705  }
706  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
707  // in a Construct, implicitly determined, p.3]
708  // For constructs other than task, if no default clause is present, these
709  // variables inherit their data-sharing attributes from the enclosing
710  // context.
711  return getDSA(++Iter, D);
712 }
713 
714 Expr *DSAStackTy::addUniqueAligned(ValueDecl *D, Expr *NewDE) {
715  assert(!isStackEmpty() && "Data sharing attributes stack is empty");
716  D = getCanonicalDecl(D);
717  auto &StackElem = Stack.back().first.back();
718  auto It = StackElem.AlignedMap.find(D);
719  if (It == StackElem.AlignedMap.end()) {
720  assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
721  StackElem.AlignedMap[D] = NewDE;
722  return nullptr;
723  } else {
724  assert(It->second && "Unexpected nullptr expr in the aligned map");
725  return It->second;
726  }
727  return nullptr;
728 }
729 
730 void DSAStackTy::addLoopControlVariable(ValueDecl *D, VarDecl *Capture) {
731  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
732  D = getCanonicalDecl(D);
733  auto &StackElem = Stack.back().first.back();
734  StackElem.LCVMap.insert(
735  {D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)});
736 }
737 
738 DSAStackTy::LCDeclInfo DSAStackTy::isLoopControlVariable(ValueDecl *D) {
739  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
740  D = getCanonicalDecl(D);
741  auto &StackElem = Stack.back().first.back();
742  auto It = StackElem.LCVMap.find(D);
743  if (It != StackElem.LCVMap.end())
744  return It->second;
745  return {0, nullptr};
746 }
747 
748 DSAStackTy::LCDeclInfo DSAStackTy::isParentLoopControlVariable(ValueDecl *D) {
749  assert(!isStackEmpty() && Stack.back().first.size() > 1 &&
750  "Data-sharing attributes stack is empty");
751  D = getCanonicalDecl(D);
752  auto &StackElem = *std::next(Stack.back().first.rbegin());
753  auto It = StackElem.LCVMap.find(D);
754  if (It != StackElem.LCVMap.end())
755  return It->second;
756  return {0, nullptr};
757 }
758 
759 ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) {
760  assert(!isStackEmpty() && Stack.back().first.size() > 1 &&
761  "Data-sharing attributes stack is empty");
762  auto &StackElem = *std::next(Stack.back().first.rbegin());
763  if (StackElem.LCVMap.size() < I)
764  return nullptr;
765  for (auto &Pair : StackElem.LCVMap)
766  if (Pair.second.first == I)
767  return Pair.first;
768  return nullptr;
769 }
770 
771 void DSAStackTy::addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A,
772  DeclRefExpr *PrivateCopy) {
773  D = getCanonicalDecl(D);
774  if (A == OMPC_threadprivate) {
775  auto &Data = Threadprivates[D];
776  Data.Attributes = A;
777  Data.RefExpr.setPointer(E);
778  Data.PrivateCopy = nullptr;
779  } else {
780  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
781  auto &Data = Stack.back().first.back().SharingMap[D];
782  assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
783  (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
784  (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
785  (isLoopControlVariable(D).first && A == OMPC_private));
786  if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
787  Data.RefExpr.setInt(/*IntVal=*/true);
788  return;
789  }
790  const bool IsLastprivate =
791  A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
792  Data.Attributes = A;
793  Data.RefExpr.setPointerAndInt(E, IsLastprivate);
794  Data.PrivateCopy = PrivateCopy;
795  if (PrivateCopy) {
796  auto &Data = Stack.back().first.back().SharingMap[PrivateCopy->getDecl()];
797  Data.Attributes = A;
798  Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
799  Data.PrivateCopy = nullptr;
800  }
801  }
802 }
803 
804 /// \brief Build a variable declaration for OpenMP loop iteration variable.
806  StringRef Name, const AttrVec *Attrs = nullptr) {
807  DeclContext *DC = SemaRef.CurContext;
808  IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
809  TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
810  VarDecl *Decl =
811  VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
812  if (Attrs) {
813  for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
814  I != E; ++I)
815  Decl->addAttr(*I);
816  }
817  Decl->setImplicit();
818  return Decl;
819 }
820 
822  SourceLocation Loc,
823  bool RefersToCapture = false) {
824  D->setReferenced();
825  D->markUsed(S.Context);
827  SourceLocation(), D, RefersToCapture, Loc, Ty,
828  VK_LValue);
829 }
830 
831 void DSAStackTy::addTaskgroupReductionData(ValueDecl *D, SourceRange SR,
832  BinaryOperatorKind BOK) {
833  D = getCanonicalDecl(D);
834  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
835  assert(
836  Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction &&
837  "Additional reduction info may be specified only for reduction items.");
838  auto &ReductionData = Stack.back().first.back().ReductionMap[D];
839  assert(ReductionData.ReductionRange.isInvalid() &&
840  Stack.back().first.back().Directive == OMPD_taskgroup &&
841  "Additional reduction info may be specified only once for reduction "
842  "items.");
843  ReductionData.set(BOK, SR);
844  Expr *&TaskgroupReductionRef =
845  Stack.back().first.back().TaskgroupReductionRef;
846  if (!TaskgroupReductionRef) {
847  auto *VD = buildVarDecl(SemaRef, SR.getBegin(),
848  SemaRef.Context.VoidPtrTy, ".task_red.");
849  TaskgroupReductionRef =
850  buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
851  }
852 }
853 
854 void DSAStackTy::addTaskgroupReductionData(ValueDecl *D, SourceRange SR,
855  const Expr *ReductionRef) {
856  D = getCanonicalDecl(D);
857  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
858  assert(
859  Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction &&
860  "Additional reduction info may be specified only for reduction items.");
861  auto &ReductionData = Stack.back().first.back().ReductionMap[D];
862  assert(ReductionData.ReductionRange.isInvalid() &&
863  Stack.back().first.back().Directive == OMPD_taskgroup &&
864  "Additional reduction info may be specified only once for reduction "
865  "items.");
866  ReductionData.set(ReductionRef, SR);
867  Expr *&TaskgroupReductionRef =
868  Stack.back().first.back().TaskgroupReductionRef;
869  if (!TaskgroupReductionRef) {
870  auto *VD = buildVarDecl(SemaRef, SR.getBegin(), SemaRef.Context.VoidPtrTy,
871  ".task_red.");
872  TaskgroupReductionRef =
873  buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
874  }
875 }
876 
877 DSAStackTy::DSAVarData
878 DSAStackTy::getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR,
879  BinaryOperatorKind &BOK,
880  Expr *&TaskgroupDescriptor) {
881  D = getCanonicalDecl(D);
882  assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
883  if (Stack.back().first.empty())
884  return DSAVarData();
885  for (auto I = std::next(Stack.back().first.rbegin(), 1),
886  E = Stack.back().first.rend();
887  I != E; std::advance(I, 1)) {
888  auto &Data = I->SharingMap[D];
889  if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
890  continue;
891  auto &ReductionData = I->ReductionMap[D];
892  if (!ReductionData.ReductionOp ||
893  ReductionData.ReductionOp.is<const Expr *>())
894  return DSAVarData();
895  SR = ReductionData.ReductionRange;
896  BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
897  assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
898  "expression for the descriptor is not "
899  "set.");
900  TaskgroupDescriptor = I->TaskgroupReductionRef;
901  return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
902  Data.PrivateCopy, I->DefaultAttrLoc);
903  }
904  return DSAVarData();
905 }
906 
907 DSAStackTy::DSAVarData
908 DSAStackTy::getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR,
909  const Expr *&ReductionRef,
910  Expr *&TaskgroupDescriptor) {
911  D = getCanonicalDecl(D);
912  assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
913  if (Stack.back().first.empty())
914  return DSAVarData();
915  for (auto I = std::next(Stack.back().first.rbegin(), 1),
916  E = Stack.back().first.rend();
917  I != E; std::advance(I, 1)) {
918  auto &Data = I->SharingMap[D];
919  if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
920  continue;
921  auto &ReductionData = I->ReductionMap[D];
922  if (!ReductionData.ReductionOp ||
923  !ReductionData.ReductionOp.is<const Expr *>())
924  return DSAVarData();
925  SR = ReductionData.ReductionRange;
926  ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
927  assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
928  "expression for the descriptor is not "
929  "set.");
930  TaskgroupDescriptor = I->TaskgroupReductionRef;
931  return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
932  Data.PrivateCopy, I->DefaultAttrLoc);
933  }
934  return DSAVarData();
935 }
936 
937 bool DSAStackTy::isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter) {
938  D = D->getCanonicalDecl();
939  if (!isStackEmpty() && Stack.back().first.size() > 1) {
940  reverse_iterator I = Iter, E = Stack.back().first.rend();
941  Scope *TopScope = nullptr;
942  while (I != E && !isParallelOrTaskRegion(I->Directive))
943  ++I;
944  if (I == E)
945  return false;
946  TopScope = I->CurScope ? I->CurScope->getParent() : nullptr;
947  Scope *CurScope = getCurScope();
948  while (CurScope != TopScope && !CurScope->isDeclScope(D))
949  CurScope = CurScope->getParent();
950  return CurScope != TopScope;
951  }
952  return false;
953 }
954 
955 DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, bool FromParent) {
956  D = getCanonicalDecl(D);
957  DSAVarData DVar;
958 
959  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
960  // in a Construct, C/C++, predetermined, p.1]
961  // Variables appearing in threadprivate directives are threadprivate.
962  auto *VD = dyn_cast<VarDecl>(D);
963  if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
964  !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
965  SemaRef.getLangOpts().OpenMPUseTLS &&
966  SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
967  (VD && VD->getStorageClass() == SC_Register &&
968  VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
969  addDSA(D, buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
970  D->getLocation()),
972  }
973  auto TI = Threadprivates.find(D);
974  if (TI != Threadprivates.end()) {
975  DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
976  DVar.CKind = OMPC_threadprivate;
977  return DVar;
978  } else if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
979  DVar.RefExpr = buildDeclRefExpr(
980  SemaRef, VD, D->getType().getNonReferenceType(),
981  VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
982  DVar.CKind = OMPC_threadprivate;
983  addDSA(D, DVar.RefExpr, OMPC_threadprivate);
984  }
985 
986  if (isStackEmpty())
987  // Not in OpenMP execution region and top scope was already checked.
988  return DVar;
989 
990  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
991  // in a Construct, C/C++, predetermined, p.4]
992  // Static data members are shared.
993  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
994  // in a Construct, C/C++, predetermined, p.7]
995  // Variables with static storage duration that are declared in a scope
996  // inside the construct are shared.
997  auto &&MatchesAlways = [](OpenMPDirectiveKind) -> bool { return true; };
998  if (VD && VD->isStaticDataMember()) {
999  DSAVarData DVarTemp = hasDSA(D, isOpenMPPrivate, MatchesAlways, FromParent);
1000  if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1001  return DVar;
1002 
1003  DVar.CKind = OMPC_shared;
1004  return DVar;
1005  }
1006 
1008  bool IsConstant = Type.isConstant(SemaRef.getASTContext());
1009  Type = SemaRef.getASTContext().getBaseElementType(Type);
1010  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1011  // in a Construct, C/C++, predetermined, p.6]
1012  // Variables with const qualified type having no mutable member are
1013  // shared.
1014  CXXRecordDecl *RD =
1015  SemaRef.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr;
1016  if (auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1017  if (auto *CTD = CTSD->getSpecializedTemplate())
1018  RD = CTD->getTemplatedDecl();
1019  if (IsConstant &&
1020  !(SemaRef.getLangOpts().CPlusPlus && RD && RD->hasDefinition() &&
1021  RD->hasMutableFields())) {
1022  // Variables with const-qualified type having no mutable member may be
1023  // listed in a firstprivate clause, even if they are static data members.
1024  DSAVarData DVarTemp = hasDSA(
1025  D, [](OpenMPClauseKind C) -> bool { return C == OMPC_firstprivate; },
1026  MatchesAlways, FromParent);
1027  if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr)
1028  return DVar;
1029 
1030  DVar.CKind = OMPC_shared;
1031  return DVar;
1032  }
1033 
1034  // Explicitly specified attributes and local variables with predetermined
1035  // attributes.
1036  auto I = Stack.back().first.rbegin();
1037  auto EndI = Stack.back().first.rend();
1038  if (FromParent && I != EndI)
1039  std::advance(I, 1);
1040  if (I->SharingMap.count(D)) {
1041  DVar.RefExpr = I->SharingMap[D].RefExpr.getPointer();
1042  DVar.PrivateCopy = I->SharingMap[D].PrivateCopy;
1043  DVar.CKind = I->SharingMap[D].Attributes;
1044  DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1045  DVar.DKind = I->Directive;
1046  }
1047 
1048  return DVar;
1049 }
1050 
1051 DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1052  bool FromParent) {
1053  if (isStackEmpty()) {
1054  StackTy::reverse_iterator I;
1055  return getDSA(I, D);
1056  }
1057  D = getCanonicalDecl(D);
1058  auto StartI = Stack.back().first.rbegin();
1059  auto EndI = Stack.back().first.rend();
1060  if (FromParent && StartI != EndI)
1061  std::advance(StartI, 1);
1062  return getDSA(StartI, D);
1063 }
1064 
1065 DSAStackTy::DSAVarData
1066 DSAStackTy::hasDSA(ValueDecl *D,
1067  const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
1068  const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
1069  bool FromParent) {
1070  if (isStackEmpty())
1071  return {};
1072  D = getCanonicalDecl(D);
1073  auto I = Stack.back().first.rbegin();
1074  auto EndI = Stack.back().first.rend();
1075  if (FromParent && I != EndI)
1076  std::advance(I, 1);
1077  for (; I != EndI; std::advance(I, 1)) {
1078  if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive))
1079  continue;
1080  auto NewI = I;
1081  DSAVarData DVar = getDSA(NewI, D);
1082  if (I == NewI && CPred(DVar.CKind))
1083  return DVar;
1084  }
1085  return {};
1086 }
1087 
1088 DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1089  ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
1090  const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
1091  bool FromParent) {
1092  if (isStackEmpty())
1093  return {};
1094  D = getCanonicalDecl(D);
1095  auto StartI = Stack.back().first.rbegin();
1096  auto EndI = Stack.back().first.rend();
1097  if (FromParent && StartI != EndI)
1098  std::advance(StartI, 1);
1099  if (StartI == EndI || !DPred(StartI->Directive))
1100  return {};
1101  auto NewI = StartI;
1102  DSAVarData DVar = getDSA(NewI, D);
1103  return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData();
1104 }
1105 
1106 bool DSAStackTy::hasExplicitDSA(
1107  ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
1108  unsigned Level, bool NotLastprivate) {
1109  if (isStackEmpty())
1110  return false;
1111  D = getCanonicalDecl(D);
1112  auto StartI = Stack.back().first.begin();
1113  auto EndI = Stack.back().first.end();
1114  if (std::distance(StartI, EndI) <= (int)Level)
1115  return false;
1116  std::advance(StartI, Level);
1117  return (StartI->SharingMap.count(D) > 0) &&
1118  StartI->SharingMap[D].RefExpr.getPointer() &&
1119  CPred(StartI->SharingMap[D].Attributes) &&
1120  (!NotLastprivate || !StartI->SharingMap[D].RefExpr.getInt());
1121 }
1122 
1123 bool DSAStackTy::hasExplicitDirective(
1124  const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
1125  unsigned Level) {
1126  if (isStackEmpty())
1127  return false;
1128  auto StartI = Stack.back().first.begin();
1129  auto EndI = Stack.back().first.end();
1130  if (std::distance(StartI, EndI) <= (int)Level)
1131  return false;
1132  std::advance(StartI, Level);
1133  return DPred(StartI->Directive);
1134 }
1135 
1136 bool DSAStackTy::hasDirective(
1137  const llvm::function_ref<bool(OpenMPDirectiveKind,
1139  &DPred,
1140  bool FromParent) {
1141  // We look only in the enclosing region.
1142  if (isStackEmpty())
1143  return false;
1144  auto StartI = std::next(Stack.back().first.rbegin());
1145  auto EndI = Stack.back().first.rend();
1146  if (FromParent && StartI != EndI)
1147  StartI = std::next(StartI);
1148  for (auto I = StartI, EE = EndI; I != EE; ++I) {
1149  if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1150  return true;
1151  }
1152  return false;
1153 }
1154 
1155 void Sema::InitDataSharingAttributesStack() {
1156  VarDataSharingAttributesStack = new DSAStackTy(*this);
1157 }
1158 
1159 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1160 
1161 void Sema::pushOpenMPFunctionRegion() {
1162  DSAStack->pushFunction();
1163 }
1164 
1165 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
1166  DSAStack->popFunction(OldFSI);
1167 }
1168 
1170  assert(LangOpts.OpenMP && "OpenMP is not allowed");
1171 
1172  auto &Ctx = getASTContext();
1173  bool IsByRef = true;
1174 
1175  // Find the directive that is associated with the provided scope.
1176  D = cast<ValueDecl>(D->getCanonicalDecl());
1177  auto Ty = D->getType();
1178 
1179  if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
1180  // This table summarizes how a given variable should be passed to the device
1181  // given its type and the clauses where it appears. This table is based on
1182  // the description in OpenMP 4.5 [2.10.4, target Construct] and
1183  // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
1184  //
1185  // =========================================================================
1186  // | type | defaultmap | pvt | first | is_device_ptr | map | res. |
1187  // | |(tofrom:scalar)| | pvt | | | |
1188  // =========================================================================
1189  // | scl | | | | - | | bycopy|
1190  // | scl | | - | x | - | - | bycopy|
1191  // | scl | | x | - | - | - | null |
1192  // | scl | x | | | - | | byref |
1193  // | scl | x | - | x | - | - | bycopy|
1194  // | scl | x | x | - | - | - | null |
1195  // | scl | | - | - | - | x | byref |
1196  // | scl | x | - | - | - | x | byref |
1197  //
1198  // | agg | n.a. | | | - | | byref |
1199  // | agg | n.a. | - | x | - | - | byref |
1200  // | agg | n.a. | x | - | - | - | null |
1201  // | agg | n.a. | - | - | - | x | byref |
1202  // | agg | n.a. | - | - | - | x[] | byref |
1203  //
1204  // | ptr | n.a. | | | - | | bycopy|
1205  // | ptr | n.a. | - | x | - | - | bycopy|
1206  // | ptr | n.a. | x | - | - | - | null |
1207  // | ptr | n.a. | - | - | - | x | byref |
1208  // | ptr | n.a. | - | - | - | x[] | bycopy|
1209  // | ptr | n.a. | - | - | x | | bycopy|
1210  // | ptr | n.a. | - | - | x | x | bycopy|
1211  // | ptr | n.a. | - | - | x | x[] | bycopy|
1212  // =========================================================================
1213  // Legend:
1214  // scl - scalar
1215  // ptr - pointer
1216  // agg - aggregate
1217  // x - applies
1218  // - - invalid in this combination
1219  // [] - mapped with an array section
1220  // byref - should be mapped by reference
1221  // byval - should be mapped by value
1222  // null - initialize a local variable to null on the device
1223  //
1224  // Observations:
1225  // - All scalar declarations that show up in a map clause have to be passed
1226  // by reference, because they may have been mapped in the enclosing data
1227  // environment.
1228  // - If the scalar value does not fit the size of uintptr, it has to be
1229  // passed by reference, regardless the result in the table above.
1230  // - For pointers mapped by value that have either an implicit map or an
1231  // array section, the runtime library may pass the NULL value to the
1232  // device instead of the value passed to it by the compiler.
1233 
1234  if (Ty->isReferenceType())
1235  Ty = Ty->castAs<ReferenceType>()->getPointeeType();
1236 
1237  // Locate map clauses and see if the variable being captured is referred to
1238  // in any of those clauses. Here we only care about variables, not fields,
1239  // because fields are part of aggregates.
1240  bool IsVariableUsedInMapClause = false;
1241  bool IsVariableAssociatedWithSection = false;
1242 
1243  DSAStack->checkMappableExprComponentListsForDeclAtLevel(
1245  MapExprComponents,
1246  OpenMPClauseKind WhereFoundClauseKind) {
1247  // Only the map clause information influences how a variable is
1248  // captured. E.g. is_device_ptr does not require changing the default
1249  // behavior.
1250  if (WhereFoundClauseKind != OMPC_map)
1251  return false;
1252 
1253  auto EI = MapExprComponents.rbegin();
1254  auto EE = MapExprComponents.rend();
1255 
1256  assert(EI != EE && "Invalid map expression!");
1257 
1258  if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
1259  IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
1260 
1261  ++EI;
1262  if (EI == EE)
1263  return false;
1264 
1265  if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
1266  isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
1267  isa<MemberExpr>(EI->getAssociatedExpression())) {
1268  IsVariableAssociatedWithSection = true;
1269  // There is nothing more we need to know about this variable.
1270  return true;
1271  }
1272 
1273  // Keep looking for more map info.
1274  return false;
1275  });
1276 
1277  if (IsVariableUsedInMapClause) {
1278  // If variable is identified in a map clause it is always captured by
1279  // reference except if it is a pointer that is dereferenced somehow.
1280  IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
1281  } else {
1282  // By default, all the data that has a scalar type is mapped by copy
1283  // (except for reduction variables).
1284  IsByRef =
1285  !Ty->isScalarType() ||
1286  DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar ||
1287  DSAStack->hasExplicitDSA(
1288  D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level);
1289  }
1290  }
1291 
1292  if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
1293  IsByRef = !DSAStack->hasExplicitDSA(
1294  D, [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; },
1295  Level, /*NotLastprivate=*/true);
1296  }
1297 
1298  // When passing data by copy, we need to make sure it fits the uintptr size
1299  // and alignment, because the runtime library only deals with uintptr types.
1300  // If it does not fit the uintptr size, we need to pass the data by reference
1301  // instead.
1302  if (!IsByRef &&
1303  (Ctx.getTypeSizeInChars(Ty) >
1304  Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
1305  Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
1306  IsByRef = true;
1307  }
1308 
1309  return IsByRef;
1310 }
1311 
1312 unsigned Sema::getOpenMPNestingLevel() const {
1313  assert(getLangOpts().OpenMP);
1314  return DSAStack->getNestingLevel();
1315 }
1316 
1318  return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) &&
1319  !DSAStack->isClauseParsingMode()) ||
1320  DSAStack->hasDirective(
1322  SourceLocation) -> bool {
1323  return isOpenMPTargetExecutionDirective(K);
1324  },
1325  false);
1326 }
1327 
1329  assert(LangOpts.OpenMP && "OpenMP is not allowed");
1330  D = getCanonicalDecl(D);
1331 
1332  // If we are attempting to capture a global variable in a directive with
1333  // 'target' we return true so that this global is also mapped to the device.
1334  //
1335  // FIXME: If the declaration is enclosed in a 'declare target' directive,
1336  // then it should not be captured. Therefore, an extra check has to be
1337  // inserted here once support for 'declare target' is added.
1338  //
1339  auto *VD = dyn_cast<VarDecl>(D);
1340  if (VD && !VD->hasLocalStorage() && isInOpenMPTargetExecutionDirective())
1341  return VD;
1342 
1343  if (DSAStack->getCurrentDirective() != OMPD_unknown &&
1344  (!DSAStack->isClauseParsingMode() ||
1345  DSAStack->getParentDirective() != OMPD_unknown)) {
1346  auto &&Info = DSAStack->isLoopControlVariable(D);
1347  if (Info.first ||
1348  (VD && VD->hasLocalStorage() &&
1349  isParallelOrTaskRegion(DSAStack->getCurrentDirective())) ||
1350  (VD && DSAStack->isForceVarCapturing()))
1351  return VD ? VD : Info.second;
1352  auto DVarPrivate = DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
1353  if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind))
1354  return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1355  DVarPrivate = DSAStack->hasDSA(
1356  D, isOpenMPPrivate, [](OpenMPDirectiveKind) -> bool { return true; },
1357  DSAStack->isClauseParsingMode());
1358  if (DVarPrivate.CKind != OMPC_unknown)
1359  return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1360  }
1361  return nullptr;
1362 }
1363 
1364 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
1365  unsigned Level) const {
1367  getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level));
1368  FunctionScopesIndex -= Regions.size();
1369 }
1370 
1372  assert(LangOpts.OpenMP && "OpenMP is not allowed");
1373  return DSAStack->hasExplicitDSA(
1374  D, [](OpenMPClauseKind K) -> bool { return K == OMPC_private; },
1375  Level) ||
1376  (DSAStack->isClauseParsingMode() &&
1377  DSAStack->getClauseParsingMode() == OMPC_private) ||
1378  // Consider taskgroup reduction descriptor variable a private to avoid
1379  // possible capture in the region.
1380  (DSAStack->hasExplicitDirective(
1381  [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; },
1382  Level) &&
1383  DSAStack->isTaskgroupReductionRef(D, Level));
1384 }
1385 
1387  assert(LangOpts.OpenMP && "OpenMP is not allowed");
1388  D = getCanonicalDecl(D);
1390  for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) {
1391  const unsigned NewLevel = I - 1;
1392  if (DSAStack->hasExplicitDSA(D,
1393  [&OMPC](const OpenMPClauseKind K) {
1394  if (isOpenMPPrivate(K)) {
1395  OMPC = K;
1396  return true;
1397  }
1398  return false;
1399  },
1400  NewLevel))
1401  break;
1402  if (DSAStack->checkMappableExprComponentListsForDeclAtLevel(
1403  D, NewLevel,
1405  OpenMPClauseKind) { return true; })) {
1406  OMPC = OMPC_map;
1407  break;
1408  }
1409  if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
1410  NewLevel)) {
1411  OMPC = OMPC_firstprivate;
1412  break;
1413  }
1414  }
1415  if (OMPC != OMPC_unknown)
1416  FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC));
1417 }
1418 
1420  assert(LangOpts.OpenMP && "OpenMP is not allowed");
1421  // Return true if the current level is no longer enclosed in a target region.
1422 
1423  auto *VD = dyn_cast<VarDecl>(D);
1424  return VD && !VD->hasLocalStorage() &&
1425  DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
1426  Level);
1427 }
1428 
1429 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
1430 
1432  const DeclarationNameInfo &DirName,
1433  Scope *CurScope, SourceLocation Loc) {
1434  DSAStack->push(DKind, DirName, CurScope, Loc);
1435  PushExpressionEvaluationContext(
1436  ExpressionEvaluationContext::PotentiallyEvaluated);
1437 }
1438 
1440  DSAStack->setClauseParsingMode(K);
1441 }
1442 
1444  DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
1445 }
1446 
1447 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
1448  // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
1449  // A variable of class type (or array thereof) that appears in a lastprivate
1450  // clause requires an accessible, unambiguous default constructor for the
1451  // class type, unless the list item is also specified in a firstprivate
1452  // clause.
1453  if (auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
1454  for (auto *C : D->clauses()) {
1455  if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
1456  SmallVector<Expr *, 8> PrivateCopies;
1457  for (auto *DE : Clause->varlists()) {
1458  if (DE->isValueDependent() || DE->isTypeDependent()) {
1459  PrivateCopies.push_back(nullptr);
1460  continue;
1461  }
1462  auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
1463  VarDecl *VD = cast<VarDecl>(DRE->getDecl());
1464  QualType Type = VD->getType().getNonReferenceType();
1465  auto DVar = DSAStack->getTopDSA(VD, false);
1466  if (DVar.CKind == OMPC_lastprivate) {
1467  // Generate helper private variable and initialize it with the
1468  // default value. The address of the original variable is replaced
1469  // by the address of the new private variable in CodeGen. This new
1470  // variable is not added to IdResolver, so the code in the OpenMP
1471  // region uses original variable for proper diagnostics.
1472  auto *VDPrivate = buildVarDecl(
1473  *this, DE->getExprLoc(), Type.getUnqualifiedType(),
1474  VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr);
1475  ActOnUninitializedDecl(VDPrivate);
1476  if (VDPrivate->isInvalidDecl())
1477  continue;
1478  PrivateCopies.push_back(buildDeclRefExpr(
1479  *this, VDPrivate, DE->getType(), DE->getExprLoc()));
1480  } else {
1481  // The variable is also a firstprivate, so initialization sequence
1482  // for private copy is generated already.
1483  PrivateCopies.push_back(nullptr);
1484  }
1485  }
1486  // Set initializers to private copies if no errors were found.
1487  if (PrivateCopies.size() == Clause->varlist_size())
1488  Clause->setPrivateCopies(PrivateCopies);
1489  }
1490  }
1491  }
1492 
1493  DSAStack->pop();
1494  DiscardCleanupsInEvaluationContext();
1495  PopExpressionEvaluationContext();
1496 }
1497 
1498 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
1499  Expr *NumIterations, Sema &SemaRef,
1500  Scope *S, DSAStackTy *Stack);
1501 
1502 namespace {
1503 
1504 class VarDeclFilterCCC : public CorrectionCandidateCallback {
1505 private:
1506  Sema &SemaRef;
1507 
1508 public:
1509  explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
1510  bool ValidateCandidate(const TypoCorrection &Candidate) override {
1511  NamedDecl *ND = Candidate.getCorrectionDecl();
1512  if (auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
1513  return VD->hasGlobalStorage() &&
1514  SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
1515  SemaRef.getCurScope());
1516  }
1517  return false;
1518  }
1519 };
1520 
1521 class VarOrFuncDeclFilterCCC : public CorrectionCandidateCallback {
1522 private:
1523  Sema &SemaRef;
1524 
1525 public:
1526  explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
1527  bool ValidateCandidate(const TypoCorrection &Candidate) override {
1528  NamedDecl *ND = Candidate.getCorrectionDecl();
1529  if (ND && (isa<VarDecl>(ND) || isa<FunctionDecl>(ND))) {
1530  return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
1531  SemaRef.getCurScope());
1532  }
1533  return false;
1534  }
1535 };
1536 
1537 } // namespace
1538 
1540  CXXScopeSpec &ScopeSpec,
1541  const DeclarationNameInfo &Id) {
1542  LookupResult Lookup(*this, Id, LookupOrdinaryName);
1543  LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
1544 
1545  if (Lookup.isAmbiguous())
1546  return ExprError();
1547 
1548  VarDecl *VD;
1549  if (!Lookup.isSingleResult()) {
1550  if (TypoCorrection Corrected = CorrectTypo(
1551  Id, LookupOrdinaryName, CurScope, nullptr,
1552  llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) {
1553  diagnoseTypo(Corrected,
1554  PDiag(Lookup.empty()
1555  ? diag::err_undeclared_var_use_suggest
1556  : diag::err_omp_expected_var_arg_suggest)
1557  << Id.getName());
1558  VD = Corrected.getCorrectionDeclAs<VarDecl>();
1559  } else {
1560  Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
1561  : diag::err_omp_expected_var_arg)
1562  << Id.getName();
1563  return ExprError();
1564  }
1565  } else {
1566  if (!(VD = Lookup.getAsSingle<VarDecl>())) {
1567  Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
1568  Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
1569  return ExprError();
1570  }
1571  }
1572  Lookup.suppressDiagnostics();
1573 
1574  // OpenMP [2.9.2, Syntax, C/C++]
1575  // Variables must be file-scope, namespace-scope, or static block-scope.
1576  if (!VD->hasGlobalStorage()) {
1577  Diag(Id.getLoc(), diag::err_omp_global_var_arg)
1578  << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal();
1579  bool IsDecl =
1581  Diag(VD->getLocation(),
1582  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1583  << VD;
1584  return ExprError();
1585  }
1586 
1587  VarDecl *CanonicalVD = VD->getCanonicalDecl();
1588  NamedDecl *ND = cast<NamedDecl>(CanonicalVD);
1589  // OpenMP [2.9.2, Restrictions, C/C++, p.2]
1590  // A threadprivate directive for file-scope variables must appear outside
1591  // any definition or declaration.
1592  if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
1593  !getCurLexicalContext()->isTranslationUnit()) {
1594  Diag(Id.getLoc(), diag::err_omp_var_scope)
1595  << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1596  bool IsDecl =
1598  Diag(VD->getLocation(),
1599  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1600  << VD;
1601  return ExprError();
1602  }
1603  // OpenMP [2.9.2, Restrictions, C/C++, p.3]
1604  // A threadprivate directive for static class member variables must appear
1605  // in the class definition, in the same scope in which the member
1606  // variables are declared.
1607  if (CanonicalVD->isStaticDataMember() &&
1608  !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
1609  Diag(Id.getLoc(), diag::err_omp_var_scope)
1610  << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1611  bool IsDecl =
1613  Diag(VD->getLocation(),
1614  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1615  << VD;
1616  return ExprError();
1617  }
1618  // OpenMP [2.9.2, Restrictions, C/C++, p.4]
1619  // A threadprivate directive for namespace-scope variables must appear
1620  // outside any definition or declaration other than the namespace
1621  // definition itself.
1622  if (CanonicalVD->getDeclContext()->isNamespace() &&
1623  (!getCurLexicalContext()->isFileContext() ||
1624  !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
1625  Diag(Id.getLoc(), diag::err_omp_var_scope)
1626  << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1627  bool IsDecl =
1629  Diag(VD->getLocation(),
1630  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1631  << VD;
1632  return ExprError();
1633  }
1634  // OpenMP [2.9.2, Restrictions, C/C++, p.6]
1635  // A threadprivate directive for static block-scope variables must appear
1636  // in the scope of the variable and not in a nested scope.
1637  if (CanonicalVD->isStaticLocal() && CurScope &&
1638  !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
1639  Diag(Id.getLoc(), diag::err_omp_var_scope)
1640  << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1641  bool IsDecl =
1643  Diag(VD->getLocation(),
1644  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1645  << VD;
1646  return ExprError();
1647  }
1648 
1649  // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
1650  // A threadprivate directive must lexically precede all references to any
1651  // of the variables in its list.
1652  if (VD->isUsed() && !DSAStack->isThreadPrivate(VD)) {
1653  Diag(Id.getLoc(), diag::err_omp_var_used)
1654  << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1655  return ExprError();
1656  }
1657 
1658  QualType ExprType = VD->getType().getNonReferenceType();
1659  return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
1660  SourceLocation(), VD,
1661  /*RefersToEnclosingVariableOrCapture=*/false,
1662  Id.getLoc(), ExprType, VK_LValue);
1663 }
1664 
1667  ArrayRef<Expr *> VarList) {
1668  if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
1669  CurContext->addDecl(D);
1670  return DeclGroupPtrTy::make(DeclGroupRef(D));
1671  }
1672  return nullptr;
1673 }
1674 
1675 namespace {
1676 class LocalVarRefChecker : public ConstStmtVisitor<LocalVarRefChecker, bool> {
1677  Sema &SemaRef;
1678 
1679 public:
1680  bool VisitDeclRefExpr(const DeclRefExpr *E) {
1681  if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
1682  if (VD->hasLocalStorage()) {
1683  SemaRef.Diag(E->getLocStart(),
1684  diag::err_omp_local_var_in_threadprivate_init)
1685  << E->getSourceRange();
1686  SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
1687  << VD << VD->getSourceRange();
1688  return true;
1689  }
1690  }
1691  return false;
1692  }
1693  bool VisitStmt(const Stmt *S) {
1694  for (auto Child : S->children()) {
1695  if (Child && Visit(Child))
1696  return true;
1697  }
1698  return false;
1699  }
1700  explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
1701 };
1702 } // namespace
1703 
1707  for (auto &RefExpr : VarList) {
1708  DeclRefExpr *DE = cast<DeclRefExpr>(RefExpr);
1709  VarDecl *VD = cast<VarDecl>(DE->getDecl());
1710  SourceLocation ILoc = DE->getExprLoc();
1711 
1712  // Mark variable as used.
1713  VD->setReferenced();
1714  VD->markUsed(Context);
1715 
1716  QualType QType = VD->getType();
1717  if (QType->isDependentType() || QType->isInstantiationDependentType()) {
1718  // It will be analyzed later.
1719  Vars.push_back(DE);
1720  continue;
1721  }
1722 
1723  // OpenMP [2.9.2, Restrictions, C/C++, p.10]
1724  // A threadprivate variable must not have an incomplete type.
1725  if (RequireCompleteType(ILoc, VD->getType(),
1726  diag::err_omp_threadprivate_incomplete_type)) {
1727  continue;
1728  }
1729 
1730  // OpenMP [2.9.2, Restrictions, C/C++, p.10]
1731  // A threadprivate variable must not have a reference type.
1732  if (VD->getType()->isReferenceType()) {
1733  Diag(ILoc, diag::err_omp_ref_type_arg)
1734  << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
1735  bool IsDecl =
1736  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1737  Diag(VD->getLocation(),
1738  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1739  << VD;
1740  continue;
1741  }
1742 
1743  // Check if this is a TLS variable. If TLS is not being supported, produce
1744  // the corresponding diagnostic.
1745  if ((VD->getTLSKind() != VarDecl::TLS_None &&
1746  !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1747  getLangOpts().OpenMPUseTLS &&
1748  getASTContext().getTargetInfo().isTLSSupported())) ||
1749  (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
1750  !VD->isLocalVarDecl())) {
1751  Diag(ILoc, diag::err_omp_var_thread_local)
1752  << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
1753  bool IsDecl =
1754  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1755  Diag(VD->getLocation(),
1756  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1757  << VD;
1758  continue;
1759  }
1760 
1761  // Check if initial value of threadprivate variable reference variable with
1762  // local storage (it is not supported by runtime).
1763  if (auto Init = VD->getAnyInitializer()) {
1764  LocalVarRefChecker Checker(*this);
1765  if (Checker.Visit(Init))
1766  continue;
1767  }
1768 
1769  Vars.push_back(RefExpr);
1770  DSAStack->addDSA(VD, DE, OMPC_threadprivate);
1771  VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
1772  Context, SourceRange(Loc, Loc)));
1773  if (auto *ML = Context.getASTMutationListener())
1774  ML->DeclarationMarkedOpenMPThreadPrivate(VD);
1775  }
1776  OMPThreadPrivateDecl *D = nullptr;
1777  if (!Vars.empty()) {
1778  D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
1779  Vars);
1780  D->setAccess(AS_public);
1781  }
1782  return D;
1783 }
1784 
1785 static void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack,
1786  const ValueDecl *D, DSAStackTy::DSAVarData DVar,
1787  bool IsLoopIterVar = false) {
1788  if (DVar.RefExpr) {
1789  SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
1790  << getOpenMPClauseName(DVar.CKind);
1791  return;
1792  }
1793  enum {
1794  PDSA_StaticMemberShared,
1795  PDSA_StaticLocalVarShared,
1796  PDSA_LoopIterVarPrivate,
1797  PDSA_LoopIterVarLinear,
1798  PDSA_LoopIterVarLastprivate,
1799  PDSA_ConstVarShared,
1800  PDSA_GlobalVarShared,
1801  PDSA_TaskVarFirstprivate,
1802  PDSA_LocalVarPrivate,
1803  PDSA_Implicit
1804  } Reason = PDSA_Implicit;
1805  bool ReportHint = false;
1806  auto ReportLoc = D->getLocation();
1807  auto *VD = dyn_cast<VarDecl>(D);
1808  if (IsLoopIterVar) {
1809  if (DVar.CKind == OMPC_private)
1810  Reason = PDSA_LoopIterVarPrivate;
1811  else if (DVar.CKind == OMPC_lastprivate)
1812  Reason = PDSA_LoopIterVarLastprivate;
1813  else
1814  Reason = PDSA_LoopIterVarLinear;
1815  } else if (isOpenMPTaskingDirective(DVar.DKind) &&
1816  DVar.CKind == OMPC_firstprivate) {
1817  Reason = PDSA_TaskVarFirstprivate;
1818  ReportLoc = DVar.ImplicitDSALoc;
1819  } else if (VD && VD->isStaticLocal())
1820  Reason = PDSA_StaticLocalVarShared;
1821  else if (VD && VD->isStaticDataMember())
1822  Reason = PDSA_StaticMemberShared;
1823  else if (VD && VD->isFileVarDecl())
1824  Reason = PDSA_GlobalVarShared;
1825  else if (D->getType().isConstant(SemaRef.getASTContext()))
1826  Reason = PDSA_ConstVarShared;
1827  else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
1828  ReportHint = true;
1829  Reason = PDSA_LocalVarPrivate;
1830  }
1831  if (Reason != PDSA_Implicit) {
1832  SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
1833  << Reason << ReportHint
1834  << getOpenMPDirectiveName(Stack->getCurrentDirective());
1835  } else if (DVar.ImplicitDSALoc.isValid()) {
1836  SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
1837  << getOpenMPClauseName(DVar.CKind);
1838  }
1839 }
1840 
1841 namespace {
1842 class DSAAttrChecker : public StmtVisitor<DSAAttrChecker, void> {
1843  DSAStackTy *Stack;
1844  Sema &SemaRef;
1845  bool ErrorFound;
1846  CapturedStmt *CS;
1847  llvm::SmallVector<Expr *, 8> ImplicitFirstprivate;
1848  llvm::SmallVector<Expr *, 8> ImplicitMap;
1849  llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA;
1850  llvm::DenseSet<ValueDecl *> ImplicitDeclarations;
1851 
1852 public:
1853  void VisitDeclRefExpr(DeclRefExpr *E) {
1854  if (E->isTypeDependent() || E->isValueDependent() ||
1856  return;
1857  if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
1858  VD = VD->getCanonicalDecl();
1859  // Skip internally declared variables.
1860  if (VD->hasLocalStorage() && !CS->capturesVariable(VD))
1861  return;
1862 
1863  auto DVar = Stack->getTopDSA(VD, false);
1864  // Check if the variable has explicit DSA set and stop analysis if it so.
1865  if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
1866  return;
1867 
1868  // Skip internally declared static variables.
1869  if (VD->hasGlobalStorage() && !CS->capturesVariable(VD))
1870  return;
1871 
1872  auto ELoc = E->getExprLoc();
1873  auto DKind = Stack->getCurrentDirective();
1874  // The default(none) clause requires that each variable that is referenced
1875  // in the construct, and does not have a predetermined data-sharing
1876  // attribute, must have its data-sharing attribute explicitly determined
1877  // by being listed in a data-sharing attribute clause.
1878  if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none &&
1879  isParallelOrTaskRegion(DKind) &&
1880  VarsWithInheritedDSA.count(VD) == 0) {
1881  VarsWithInheritedDSA[VD] = E;
1882  return;
1883  }
1884 
1885  if (isOpenMPTargetExecutionDirective(DKind) &&
1886  !Stack->isLoopControlVariable(VD).first) {
1887  if (!Stack->checkMappableExprComponentListsForDecl(
1888  VD, /*CurrentRegionOnly=*/true,
1890  StackComponents,
1891  OpenMPClauseKind) {
1892  // Variable is used if it has been marked as an array, array
1893  // section or the variable iself.
1894  return StackComponents.size() == 1 ||
1895  std::all_of(
1896  std::next(StackComponents.rbegin()),
1897  StackComponents.rend(),
1898  [](const OMPClauseMappableExprCommon::
1899  MappableComponent &MC) {
1900  return MC.getAssociatedDeclaration() ==
1901  nullptr &&
1902  (isa<OMPArraySectionExpr>(
1903  MC.getAssociatedExpression()) ||
1904  isa<ArraySubscriptExpr>(
1905  MC.getAssociatedExpression()));
1906  });
1907  })) {
1908  bool IsFirstprivate = false;
1909  // By default lambdas are captured as firstprivates.
1910  if (const auto *RD =
1911  VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
1912  IsFirstprivate = RD->isLambda();
1913  IsFirstprivate =
1914  IsFirstprivate ||
1915  (VD->getType().getNonReferenceType()->isScalarType() &&
1916  Stack->getDefaultDMA() != DMA_tofrom_scalar);
1917  if (IsFirstprivate)
1918  ImplicitFirstprivate.emplace_back(E);
1919  else
1920  ImplicitMap.emplace_back(E);
1921  return;
1922  }
1923  }
1924 
1925  // OpenMP [2.9.3.6, Restrictions, p.2]
1926  // A list item that appears in a reduction clause of the innermost
1927  // enclosing worksharing or parallel construct may not be accessed in an
1928  // explicit task.
1929  DVar = Stack->hasInnermostDSA(
1930  VD, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; },
1931  [](OpenMPDirectiveKind K) -> bool {
1932  return isOpenMPParallelDirective(K) ||
1934  },
1935  /*FromParent=*/true);
1936  if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
1937  ErrorFound = true;
1938  SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
1939  ReportOriginalDSA(SemaRef, Stack, VD, DVar);
1940  return;
1941  }
1942 
1943  // Define implicit data-sharing attributes for task.
1944  DVar = Stack->getImplicitDSA(VD, false);
1945  if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
1946  !Stack->isLoopControlVariable(VD).first)
1947  ImplicitFirstprivate.push_back(E);
1948  }
1949  }
1950  void VisitMemberExpr(MemberExpr *E) {
1951  if (E->isTypeDependent() || E->isValueDependent() ||
1953  return;
1954  auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
1955  OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
1956  if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
1957  if (!FD)
1958  return;
1959  auto DVar = Stack->getTopDSA(FD, false);
1960  // Check if the variable has explicit DSA set and stop analysis if it
1961  // so.
1962  if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
1963  return;
1964 
1965  if (isOpenMPTargetExecutionDirective(DKind) &&
1966  !Stack->isLoopControlVariable(FD).first &&
1967  !Stack->checkMappableExprComponentListsForDecl(
1968  FD, /*CurrentRegionOnly=*/true,
1970  StackComponents,
1971  OpenMPClauseKind) {
1972  return isa<CXXThisExpr>(
1973  cast<MemberExpr>(
1974  StackComponents.back().getAssociatedExpression())
1975  ->getBase()
1976  ->IgnoreParens());
1977  })) {
1978  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
1979  // A bit-field cannot appear in a map clause.
1980  //
1981  if (FD->isBitField())
1982  return;
1983  ImplicitMap.emplace_back(E);
1984  return;
1985  }
1986 
1987  auto ELoc = E->getExprLoc();
1988  // OpenMP [2.9.3.6, Restrictions, p.2]
1989  // A list item that appears in a reduction clause of the innermost
1990  // enclosing worksharing or parallel construct may not be accessed in
1991  // an explicit task.
1992  DVar = Stack->hasInnermostDSA(
1993  FD, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; },
1994  [](OpenMPDirectiveKind K) -> bool {
1995  return isOpenMPParallelDirective(K) ||
1997  },
1998  /*FromParent=*/true);
1999  if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
2000  ErrorFound = true;
2001  SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
2002  ReportOriginalDSA(SemaRef, Stack, FD, DVar);
2003  return;
2004  }
2005 
2006  // Define implicit data-sharing attributes for task.
2007  DVar = Stack->getImplicitDSA(FD, false);
2008  if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
2009  !Stack->isLoopControlVariable(FD).first)
2010  ImplicitFirstprivate.push_back(E);
2011  return;
2012  }
2013  if (isOpenMPTargetExecutionDirective(DKind)) {
2015  if (!CheckMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
2016  /*NoDiagnose=*/true))
2017  return;
2018  auto *VD = cast<ValueDecl>(
2019  CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
2020  if (!Stack->checkMappableExprComponentListsForDecl(
2021  VD, /*CurrentRegionOnly=*/true,
2022  [&CurComponents](
2024  StackComponents,
2025  OpenMPClauseKind) {
2026  auto CCI = CurComponents.rbegin();
2027  auto CCE = CurComponents.rend();
2028  for (const auto &SC : llvm::reverse(StackComponents)) {
2029  // Do both expressions have the same kind?
2030  if (CCI->getAssociatedExpression()->getStmtClass() !=
2031  SC.getAssociatedExpression()->getStmtClass())
2032  if (!(isa<OMPArraySectionExpr>(
2033  SC.getAssociatedExpression()) &&
2034  isa<ArraySubscriptExpr>(
2035  CCI->getAssociatedExpression())))
2036  return false;
2037 
2038  Decl *CCD = CCI->getAssociatedDeclaration();
2039  Decl *SCD = SC.getAssociatedDeclaration();
2040  CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
2041  SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
2042  if (SCD != CCD)
2043  return false;
2044  std::advance(CCI, 1);
2045  if (CCI == CCE)
2046  break;
2047  }
2048  return true;
2049  })) {
2050  Visit(E->getBase());
2051  }
2052  } else
2053  Visit(E->getBase());
2054  }
2055  void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
2056  for (auto *C : S->clauses()) {
2057  // Skip analysis of arguments of implicitly defined firstprivate clause
2058  // for task|target directives.
2059  // Skip analysis of arguments of implicitly defined map clause for target
2060  // directives.
2061  if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
2062  C->isImplicit())) {
2063  for (auto *CC : C->children()) {
2064  if (CC)
2065  Visit(CC);
2066  }
2067  }
2068  }
2069  }
2070  void VisitStmt(Stmt *S) {
2071  for (auto *C : S->children()) {
2072  if (C && !isa<OMPExecutableDirective>(C))
2073  Visit(C);
2074  }
2075  }
2076 
2077  bool isErrorFound() { return ErrorFound; }
2078  ArrayRef<Expr *> getImplicitFirstprivate() const {
2079  return ImplicitFirstprivate;
2080  }
2081  ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; }
2082  llvm::DenseMap<ValueDecl *, Expr *> &getVarsWithInheritedDSA() {
2083  return VarsWithInheritedDSA;
2084  }
2085 
2086  DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
2087  : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {}
2088 };
2089 } // namespace
2090 
2092  switch (DKind) {
2093  case OMPD_parallel:
2094  case OMPD_parallel_for:
2095  case OMPD_parallel_for_simd:
2096  case OMPD_parallel_sections:
2097  case OMPD_teams:
2098  case OMPD_teams_distribute:
2099  case OMPD_teams_distribute_simd: {
2100  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2101  QualType KmpInt32PtrTy =
2102  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2103  Sema::CapturedParamNameType Params[] = {
2104  std::make_pair(".global_tid.", KmpInt32PtrTy),
2105  std::make_pair(".bound_tid.", KmpInt32PtrTy),
2106  std::make_pair(StringRef(), QualType()) // __context with shared vars
2107  };
2108  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2109  Params);
2110  break;
2111  }
2112  case OMPD_target_teams:
2113  case OMPD_target_parallel:
2114  case OMPD_target_parallel_for:
2115  case OMPD_target_parallel_for_simd:
2116  case OMPD_target_teams_distribute:
2117  case OMPD_target_teams_distribute_simd: {
2118  Sema::CapturedParamNameType ParamsTarget[] = {
2119  std::make_pair(StringRef(), QualType()) // __context with shared vars
2120  };
2121  // Start a captured region for 'target' with no implicit parameters.
2122  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2123  ParamsTarget);
2124  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2125  QualType KmpInt32PtrTy =
2126  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2127  Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
2128  std::make_pair(".global_tid.", KmpInt32PtrTy),
2129  std::make_pair(".bound_tid.", KmpInt32PtrTy),
2130  std::make_pair(StringRef(), QualType()) // __context with shared vars
2131  };
2132  // Start a captured region for 'teams' or 'parallel'. Both regions have
2133  // the same implicit parameters.
2134  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2135  ParamsTeamsOrParallel);
2136  break;
2137  }
2138  case OMPD_simd:
2139  case OMPD_for:
2140  case OMPD_for_simd:
2141  case OMPD_sections:
2142  case OMPD_section:
2143  case OMPD_single:
2144  case OMPD_master:
2145  case OMPD_critical:
2146  case OMPD_taskgroup:
2147  case OMPD_distribute:
2148  case OMPD_distribute_simd:
2149  case OMPD_ordered:
2150  case OMPD_atomic:
2151  case OMPD_target_data:
2152  case OMPD_target:
2153  case OMPD_target_simd: {
2154  Sema::CapturedParamNameType Params[] = {
2155  std::make_pair(StringRef(), QualType()) // __context with shared vars
2156  };
2157  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2158  Params);
2159  break;
2160  }
2161  case OMPD_task: {
2162  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2163  QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()};
2165  EPI.Variadic = true;
2166  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2167  Sema::CapturedParamNameType Params[] = {
2168  std::make_pair(".global_tid.", KmpInt32Ty),
2169  std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)),
2170  std::make_pair(".privates.", Context.VoidPtrTy.withConst()),
2171  std::make_pair(".copy_fn.",
2172  Context.getPointerType(CopyFnType).withConst()),
2173  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2174  std::make_pair(StringRef(), QualType()) // __context with shared vars
2175  };
2176  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2177  Params);
2178  // Mark this captured region as inlined, because we don't use outlined
2179  // function directly.
2180  getCurCapturedRegion()->TheCapturedDecl->addAttr(
2181  AlwaysInlineAttr::CreateImplicit(
2182  Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange()));
2183  break;
2184  }
2185  case OMPD_taskloop:
2186  case OMPD_taskloop_simd: {
2187  QualType KmpInt32Ty =
2188  Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
2189  QualType KmpUInt64Ty =
2190  Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
2191  QualType KmpInt64Ty =
2192  Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
2193  QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()};
2195  EPI.Variadic = true;
2196  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2197  Sema::CapturedParamNameType Params[] = {
2198  std::make_pair(".global_tid.", KmpInt32Ty),
2199  std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)),
2200  std::make_pair(".privates.",
2201  Context.VoidPtrTy.withConst().withRestrict()),
2202  std::make_pair(
2203  ".copy_fn.",
2204  Context.getPointerType(CopyFnType).withConst().withRestrict()),
2205  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2206  std::make_pair(".lb.", KmpUInt64Ty),
2207  std::make_pair(".ub.", KmpUInt64Ty), std::make_pair(".st.", KmpInt64Ty),
2208  std::make_pair(".liter.", KmpInt32Ty),
2209  std::make_pair(".reductions.",
2210  Context.VoidPtrTy.withConst().withRestrict()),
2211  std::make_pair(StringRef(), QualType()) // __context with shared vars
2212  };
2213  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2214  Params);
2215  // Mark this captured region as inlined, because we don't use outlined
2216  // function directly.
2217  getCurCapturedRegion()->TheCapturedDecl->addAttr(
2218  AlwaysInlineAttr::CreateImplicit(
2219  Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange()));
2220  break;
2221  }
2222  case OMPD_distribute_parallel_for_simd:
2223  case OMPD_distribute_parallel_for:
2224  case OMPD_target_teams_distribute_parallel_for:
2225  case OMPD_target_teams_distribute_parallel_for_simd: {
2226  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2227  QualType KmpInt32PtrTy =
2228  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2229  Sema::CapturedParamNameType Params[] = {
2230  std::make_pair(".global_tid.", KmpInt32PtrTy),
2231  std::make_pair(".bound_tid.", KmpInt32PtrTy),
2232  std::make_pair(".previous.lb.", Context.getSizeType()),
2233  std::make_pair(".previous.ub.", Context.getSizeType()),
2234  std::make_pair(StringRef(), QualType()) // __context with shared vars
2235  };
2236  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2237  Params);
2238  break;
2239  }
2240  case OMPD_teams_distribute_parallel_for:
2241  case OMPD_teams_distribute_parallel_for_simd: {
2242  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2243  QualType KmpInt32PtrTy =
2244  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2245 
2246  Sema::CapturedParamNameType ParamsTeams[] = {
2247  std::make_pair(".global_tid.", KmpInt32PtrTy),
2248  std::make_pair(".bound_tid.", KmpInt32PtrTy),
2249  std::make_pair(StringRef(), QualType()) // __context with shared vars
2250  };
2251  // Start a captured region for 'target' with no implicit parameters.
2252  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2253  ParamsTeams);
2254 
2255  Sema::CapturedParamNameType ParamsParallel[] = {
2256  std::make_pair(".global_tid.", KmpInt32PtrTy),
2257  std::make_pair(".bound_tid.", KmpInt32PtrTy),
2258  std::make_pair(".previous.lb.", Context.getSizeType()),
2259  std::make_pair(".previous.ub.", Context.getSizeType()),
2260  std::make_pair(StringRef(), QualType()) // __context with shared vars
2261  };
2262  // Start a captured region for 'teams' or 'parallel'. Both regions have
2263  // the same implicit parameters.
2264  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2265  ParamsParallel);
2266  break;
2267  }
2268  case OMPD_target_update:
2269  case OMPD_target_enter_data:
2270  case OMPD_target_exit_data: {
2271  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2272  QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()};
2274  EPI.Variadic = true;
2275  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2276  Sema::CapturedParamNameType Params[] = {
2277  std::make_pair(".global_tid.", KmpInt32Ty),
2278  std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)),
2279  std::make_pair(".privates.", Context.VoidPtrTy.withConst()),
2280  std::make_pair(".copy_fn.",
2281  Context.getPointerType(CopyFnType).withConst()),
2282  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2283  std::make_pair(StringRef(), QualType()) // __context with shared vars
2284  };
2285  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2286  Params);
2287  // Mark this captured region as inlined, because we don't use outlined
2288  // function directly.
2289  getCurCapturedRegion()->TheCapturedDecl->addAttr(
2290  AlwaysInlineAttr::CreateImplicit(
2291  Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange()));
2292  break;
2293  }
2294  case OMPD_threadprivate:
2295  case OMPD_taskyield:
2296  case OMPD_barrier:
2297  case OMPD_taskwait:
2298  case OMPD_cancellation_point:
2299  case OMPD_cancel:
2300  case OMPD_flush:
2301  case OMPD_declare_reduction:
2302  case OMPD_declare_simd:
2303  case OMPD_declare_target:
2304  case OMPD_end_declare_target:
2305  llvm_unreachable("OpenMP Directive is not allowed");
2306  case OMPD_unknown:
2307  llvm_unreachable("Unknown OpenMP directive");
2308  }
2309 }
2310 
2312  SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2313  getOpenMPCaptureRegions(CaptureRegions, DKind);
2314  return CaptureRegions.size();
2315 }
2316 
2318  Expr *CaptureExpr, bool WithInit,
2319  bool AsExpression) {
2320  assert(CaptureExpr);
2321  ASTContext &C = S.getASTContext();
2322  Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
2323  QualType Ty = Init->getType();
2324  if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
2325  if (S.getLangOpts().CPlusPlus)
2326  Ty = C.getLValueReferenceType(Ty);
2327  else {
2328  Ty = C.getPointerType(Ty);
2329  ExprResult Res =
2330  S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
2331  if (!Res.isUsable())
2332  return nullptr;
2333  Init = Res.get();
2334  }
2335  WithInit = true;
2336  }
2337  auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
2338  CaptureExpr->getLocStart());
2339  if (!WithInit)
2340  CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C, SourceRange()));
2341  S.CurContext->addHiddenDecl(CED);
2342  S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
2343  return CED;
2344 }
2345 
2346 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2347  bool WithInit) {
2348  OMPCapturedExprDecl *CD;
2349  if (auto *VD = S.IsOpenMPCapturedDecl(D))
2350  CD = cast<OMPCapturedExprDecl>(VD);
2351  else
2352  CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
2353  /*AsExpression=*/false);
2354  return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
2355  CaptureExpr->getExprLoc());
2356 }
2357 
2358 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
2359  if (!Ref) {
2360  auto *CD =
2361  buildCaptureDecl(S, &S.getASTContext().Idents.get(".capture_expr."),
2362  CaptureExpr, /*WithInit=*/true, /*AsExpression=*/true);
2363  Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
2364  CaptureExpr->getExprLoc());
2365  }
2366  ExprResult Res = Ref;
2367  if (!S.getLangOpts().CPlusPlus &&
2368  CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
2369  Ref->getType()->isPointerType())
2370  Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
2371  if (!Res.isUsable())
2372  return ExprError();
2373  return CaptureExpr->isGLValue() ? Res : S.DefaultLvalueConversion(Res.get());
2374 }
2375 
2376 namespace {
2377 // OpenMP directives parsed in this section are represented as a
2378 // CapturedStatement with an associated statement. If a syntax error
2379 // is detected during the parsing of the associated statement, the
2380 // compiler must abort processing and close the CapturedStatement.
2381 //
2382 // Combined directives such as 'target parallel' have more than one
2383 // nested CapturedStatements. This RAII ensures that we unwind out
2384 // of all the nested CapturedStatements when an error is found.
2385 class CaptureRegionUnwinderRAII {
2386 private:
2387  Sema &S;
2388  bool &ErrorFound;
2389  OpenMPDirectiveKind DKind;
2390 
2391 public:
2392  CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
2393  OpenMPDirectiveKind DKind)
2394  : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
2395  ~CaptureRegionUnwinderRAII() {
2396  if (ErrorFound) {
2397  int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
2398  while (--ThisCaptureLevel >= 0)
2400  }
2401  }
2402 };
2403 } // namespace
2404 
2406  ArrayRef<OMPClause *> Clauses) {
2407  bool ErrorFound = false;
2408  CaptureRegionUnwinderRAII CaptureRegionUnwinder(
2409  *this, ErrorFound, DSAStack->getCurrentDirective());
2410  if (!S.isUsable()) {
2411  ErrorFound = true;
2412  return StmtError();
2413  }
2414 
2415  SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2416  getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective());
2417  OMPOrderedClause *OC = nullptr;
2418  OMPScheduleClause *SC = nullptr;
2421  // This is required for proper codegen.
2422  for (auto *Clause : Clauses) {
2423  if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
2424  Clause->getClauseKind() == OMPC_in_reduction) {
2425  // Capture taskgroup task_reduction descriptors inside the tasking regions
2426  // with the corresponding in_reduction items.
2427  auto *IRC = cast<OMPInReductionClause>(Clause);
2428  for (auto *E : IRC->taskgroup_descriptors())
2429  if (E)
2430  MarkDeclarationsReferencedInExpr(E);
2431  }
2432  if (isOpenMPPrivate(Clause->getClauseKind()) ||
2433  Clause->getClauseKind() == OMPC_copyprivate ||
2434  (getLangOpts().OpenMPUseTLS &&
2435  getASTContext().getTargetInfo().isTLSSupported() &&
2436  Clause->getClauseKind() == OMPC_copyin)) {
2437  DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
2438  // Mark all variables in private list clauses as used in inner region.
2439  for (auto *VarRef : Clause->children()) {
2440  if (auto *E = cast_or_null<Expr>(VarRef)) {
2441  MarkDeclarationsReferencedInExpr(E);
2442  }
2443  }
2444  DSAStack->setForceVarCapturing(/*V=*/false);
2445  } else if (CaptureRegions.size() > 1 ||
2446  CaptureRegions.back() != OMPD_unknown) {
2447  if (auto *C = OMPClauseWithPreInit::get(Clause))
2448  PICs.push_back(C);
2449  if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
2450  if (auto *E = C->getPostUpdateExpr())
2451  MarkDeclarationsReferencedInExpr(E);
2452  }
2453  }
2454  if (Clause->getClauseKind() == OMPC_schedule)
2455  SC = cast<OMPScheduleClause>(Clause);
2456  else if (Clause->getClauseKind() == OMPC_ordered)
2457  OC = cast<OMPOrderedClause>(Clause);
2458  else if (Clause->getClauseKind() == OMPC_linear)
2459  LCs.push_back(cast<OMPLinearClause>(Clause));
2460  }
2461  // OpenMP, 2.7.1 Loop Construct, Restrictions
2462  // The nonmonotonic modifier cannot be specified if an ordered clause is
2463  // specified.
2464  if (SC &&
2465  (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
2466  SC->getSecondScheduleModifier() ==
2467  OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
2468  OC) {
2469  Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
2472  diag::err_omp_schedule_nonmonotonic_ordered)
2473  << SourceRange(OC->getLocStart(), OC->getLocEnd());
2474  ErrorFound = true;
2475  }
2476  if (!LCs.empty() && OC && OC->getNumForLoops()) {
2477  for (auto *C : LCs) {
2478  Diag(C->getLocStart(), diag::err_omp_linear_ordered)
2479  << SourceRange(OC->getLocStart(), OC->getLocEnd());
2480  }
2481  ErrorFound = true;
2482  }
2483  if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
2484  isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
2485  OC->getNumForLoops()) {
2486  Diag(OC->getLocStart(), diag::err_omp_ordered_simd)
2487  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
2488  ErrorFound = true;
2489  }
2490  if (ErrorFound) {
2491  return StmtError();
2492  }
2493  StmtResult SR = S;
2494  for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
2495  // Mark all variables in private list clauses as used in inner region.
2496  // Required for proper codegen of combined directives.
2497  // TODO: add processing for other clauses.
2498  if (ThisCaptureRegion != OMPD_unknown) {
2499  for (auto *C : PICs) {
2500  OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
2501  // Find the particular capture region for the clause if the
2502  // directive is a combined one with multiple capture regions.
2503  // If the directive is not a combined one, the capture region
2504  // associated with the clause is OMPD_unknown and is generated
2505  // only once.
2506  if (CaptureRegion == ThisCaptureRegion ||
2507  CaptureRegion == OMPD_unknown) {
2508  if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
2509  for (auto *D : DS->decls())
2510  MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
2511  }
2512  }
2513  }
2514  }
2515  SR = ActOnCapturedRegionEnd(SR.get());
2516  }
2517  return SR;
2518 }
2519 
2520 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
2521  OpenMPDirectiveKind CancelRegion,
2522  SourceLocation StartLoc) {
2523  // CancelRegion is only needed for cancel and cancellation_point.
2524  if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
2525  return false;
2526 
2527  if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
2528  CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
2529  return false;
2530 
2531  SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
2532  << getOpenMPDirectiveName(CancelRegion);
2533  return true;
2534 }
2535 
2536 static bool checkNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
2537  OpenMPDirectiveKind CurrentRegion,
2538  const DeclarationNameInfo &CurrentName,
2539  OpenMPDirectiveKind CancelRegion,
2540  SourceLocation StartLoc) {
2541  if (Stack->getCurScope()) {
2542  auto ParentRegion = Stack->getParentDirective();
2543  auto OffendingRegion = ParentRegion;
2544  bool NestingProhibited = false;
2545  bool CloseNesting = true;
2546  bool OrphanSeen = false;
2547  enum {
2548  NoRecommend,
2549  ShouldBeInParallelRegion,
2550  ShouldBeInOrderedRegion,
2551  ShouldBeInTargetRegion,
2552  ShouldBeInTeamsRegion
2553  } Recommend = NoRecommend;
2554  if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) {
2555  // OpenMP [2.16, Nesting of Regions]
2556  // OpenMP constructs may not be nested inside a simd region.
2557  // OpenMP [2.8.1,simd Construct, Restrictions]
2558  // An ordered construct with the simd clause is the only OpenMP
2559  // construct that can appear in the simd region.
2560  // Allowing a SIMD construct nested in another SIMD construct is an
2561  // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
2562  // message.
2563  SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
2564  ? diag::err_omp_prohibited_region_simd
2565  : diag::warn_omp_nesting_simd);
2566  return CurrentRegion != OMPD_simd;
2567  }
2568  if (ParentRegion == OMPD_atomic) {
2569  // OpenMP [2.16, Nesting of Regions]
2570  // OpenMP constructs may not be nested inside an atomic region.
2571  SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
2572  return true;
2573  }
2574  if (CurrentRegion == OMPD_section) {
2575  // OpenMP [2.7.2, sections Construct, Restrictions]
2576  // Orphaned section directives are prohibited. That is, the section
2577  // directives must appear within the sections construct and must not be
2578  // encountered elsewhere in the sections region.
2579  if (ParentRegion != OMPD_sections &&
2580  ParentRegion != OMPD_parallel_sections) {
2581  SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
2582  << (ParentRegion != OMPD_unknown)
2583  << getOpenMPDirectiveName(ParentRegion);
2584  return true;
2585  }
2586  return false;
2587  }
2588  // Allow some constructs (except teams) to be orphaned (they could be
2589  // used in functions, called from OpenMP regions with the required
2590  // preconditions).
2591  if (ParentRegion == OMPD_unknown &&
2592  !isOpenMPNestingTeamsDirective(CurrentRegion))
2593  return false;
2594  if (CurrentRegion == OMPD_cancellation_point ||
2595  CurrentRegion == OMPD_cancel) {
2596  // OpenMP [2.16, Nesting of Regions]
2597  // A cancellation point construct for which construct-type-clause is
2598  // taskgroup must be nested inside a task construct. A cancellation
2599  // point construct for which construct-type-clause is not taskgroup must
2600  // be closely nested inside an OpenMP construct that matches the type
2601  // specified in construct-type-clause.
2602  // A cancel construct for which construct-type-clause is taskgroup must be
2603  // nested inside a task construct. A cancel construct for which
2604  // construct-type-clause is not taskgroup must be closely nested inside an
2605  // OpenMP construct that matches the type specified in
2606  // construct-type-clause.
2607  NestingProhibited =
2608  !((CancelRegion == OMPD_parallel &&
2609  (ParentRegion == OMPD_parallel ||
2610  ParentRegion == OMPD_target_parallel)) ||
2611  (CancelRegion == OMPD_for &&
2612  (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
2613  ParentRegion == OMPD_target_parallel_for ||
2614  ParentRegion == OMPD_distribute_parallel_for ||
2615  ParentRegion == OMPD_teams_distribute_parallel_for ||
2616  ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
2617  (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) ||
2618  (CancelRegion == OMPD_sections &&
2619  (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
2620  ParentRegion == OMPD_parallel_sections)));
2621  } else if (CurrentRegion == OMPD_master) {
2622  // OpenMP [2.16, Nesting of Regions]
2623  // A master region may not be closely nested inside a worksharing,
2624  // atomic, or explicit task region.
2625  NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
2626  isOpenMPTaskingDirective(ParentRegion);
2627  } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
2628  // OpenMP [2.16, Nesting of Regions]
2629  // A critical region may not be nested (closely or otherwise) inside a
2630  // critical region with the same name. Note that this restriction is not
2631  // sufficient to prevent deadlock.
2632  SourceLocation PreviousCriticalLoc;
2633  bool DeadLock = Stack->hasDirective(
2634  [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
2635  const DeclarationNameInfo &DNI,
2636  SourceLocation Loc) -> bool {
2637  if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
2638  PreviousCriticalLoc = Loc;
2639  return true;
2640  } else
2641  return false;
2642  },
2643  false /* skip top directive */);
2644  if (DeadLock) {
2645  SemaRef.Diag(StartLoc,
2646  diag::err_omp_prohibited_region_critical_same_name)
2647  << CurrentName.getName();
2648  if (PreviousCriticalLoc.isValid())
2649  SemaRef.Diag(PreviousCriticalLoc,
2650  diag::note_omp_previous_critical_region);
2651  return true;
2652  }
2653  } else if (CurrentRegion == OMPD_barrier) {
2654  // OpenMP [2.16, Nesting of Regions]
2655  // A barrier region may not be closely nested inside a worksharing,
2656  // explicit task, critical, ordered, atomic, or master region.
2657  NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
2658  isOpenMPTaskingDirective(ParentRegion) ||
2659  ParentRegion == OMPD_master ||
2660  ParentRegion == OMPD_critical ||
2661  ParentRegion == OMPD_ordered;
2662  } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
2663  !isOpenMPParallelDirective(CurrentRegion) &&
2664  !isOpenMPTeamsDirective(CurrentRegion)) {
2665  // OpenMP [2.16, Nesting of Regions]
2666  // A worksharing region may not be closely nested inside a worksharing,
2667  // explicit task, critical, ordered, atomic, or master region.
2668  NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
2669  isOpenMPTaskingDirective(ParentRegion) ||
2670  ParentRegion == OMPD_master ||
2671  ParentRegion == OMPD_critical ||
2672  ParentRegion == OMPD_ordered;
2673  Recommend = ShouldBeInParallelRegion;
2674  } else if (CurrentRegion == OMPD_ordered) {
2675  // OpenMP [2.16, Nesting of Regions]
2676  // An ordered region may not be closely nested inside a critical,
2677  // atomic, or explicit task region.
2678  // An ordered region must be closely nested inside a loop region (or
2679  // parallel loop region) with an ordered clause.
2680  // OpenMP [2.8.1,simd Construct, Restrictions]
2681  // An ordered construct with the simd clause is the only OpenMP construct
2682  // that can appear in the simd region.
2683  NestingProhibited = ParentRegion == OMPD_critical ||
2684  isOpenMPTaskingDirective(ParentRegion) ||
2685  !(isOpenMPSimdDirective(ParentRegion) ||
2686  Stack->isParentOrderedRegion());
2687  Recommend = ShouldBeInOrderedRegion;
2688  } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
2689  // OpenMP [2.16, Nesting of Regions]
2690  // If specified, a teams construct must be contained within a target
2691  // construct.
2692  NestingProhibited = ParentRegion != OMPD_target;
2693  OrphanSeen = ParentRegion == OMPD_unknown;
2694  Recommend = ShouldBeInTargetRegion;
2695  }
2696  if (!NestingProhibited &&
2697  !isOpenMPTargetExecutionDirective(CurrentRegion) &&
2698  !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
2699  (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
2700  // OpenMP [2.16, Nesting of Regions]
2701  // distribute, parallel, parallel sections, parallel workshare, and the
2702  // parallel loop and parallel loop SIMD constructs are the only OpenMP
2703  // constructs that can be closely nested in the teams region.
2704  NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
2705  !isOpenMPDistributeDirective(CurrentRegion);
2706  Recommend = ShouldBeInParallelRegion;
2707  }
2708  if (!NestingProhibited &&
2709  isOpenMPNestingDistributeDirective(CurrentRegion)) {
2710  // OpenMP 4.5 [2.17 Nesting of Regions]
2711  // The region associated with the distribute construct must be strictly
2712  // nested inside a teams region
2713  NestingProhibited =
2714  (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
2715  Recommend = ShouldBeInTeamsRegion;
2716  }
2717  if (!NestingProhibited &&
2718  (isOpenMPTargetExecutionDirective(CurrentRegion) ||
2719  isOpenMPTargetDataManagementDirective(CurrentRegion))) {
2720  // OpenMP 4.5 [2.17 Nesting of Regions]
2721  // If a target, target update, target data, target enter data, or
2722  // target exit data construct is encountered during execution of a
2723  // target region, the behavior is unspecified.
2724  NestingProhibited = Stack->hasDirective(
2725  [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2726  SourceLocation) -> bool {
2728  OffendingRegion = K;
2729  return true;
2730  } else
2731  return false;
2732  },
2733  false /* don't skip top directive */);
2734  CloseNesting = false;
2735  }
2736  if (NestingProhibited) {
2737  if (OrphanSeen) {
2738  SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
2739  << getOpenMPDirectiveName(CurrentRegion) << Recommend;
2740  } else {
2741  SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
2742  << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
2743  << Recommend << getOpenMPDirectiveName(CurrentRegion);
2744  }
2745  return true;
2746  }
2747  }
2748  return false;
2749 }
2750 
2752  ArrayRef<OMPClause *> Clauses,
2753  ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
2754  bool ErrorFound = false;
2755  unsigned NamedModifiersNumber = 0;
2757  OMPD_unknown + 1);
2758  SmallVector<SourceLocation, 4> NameModifierLoc;
2759  for (const auto *C : Clauses) {
2760  if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
2761  // At most one if clause without a directive-name-modifier can appear on
2762  // the directive.
2763  OpenMPDirectiveKind CurNM = IC->getNameModifier();
2764  if (FoundNameModifiers[CurNM]) {
2765  S.Diag(C->getLocStart(), diag::err_omp_more_one_clause)
2766  << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
2767  << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
2768  ErrorFound = true;
2769  } else if (CurNM != OMPD_unknown) {
2770  NameModifierLoc.push_back(IC->getNameModifierLoc());
2771  ++NamedModifiersNumber;
2772  }
2773  FoundNameModifiers[CurNM] = IC;
2774  if (CurNM == OMPD_unknown)
2775  continue;
2776  // Check if the specified name modifier is allowed for the current
2777  // directive.
2778  // At most one if clause with the particular directive-name-modifier can
2779  // appear on the directive.
2780  bool MatchFound = false;
2781  for (auto NM : AllowedNameModifiers) {
2782  if (CurNM == NM) {
2783  MatchFound = true;
2784  break;
2785  }
2786  }
2787  if (!MatchFound) {
2788  S.Diag(IC->getNameModifierLoc(),
2789  diag::err_omp_wrong_if_directive_name_modifier)
2791  ErrorFound = true;
2792  }
2793  }
2794  }
2795  // If any if clause on the directive includes a directive-name-modifier then
2796  // all if clauses on the directive must include a directive-name-modifier.
2797  if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
2798  if (NamedModifiersNumber == AllowedNameModifiers.size()) {
2799  S.Diag(FoundNameModifiers[OMPD_unknown]->getLocStart(),
2800  diag::err_omp_no_more_if_clause);
2801  } else {
2802  std::string Values;
2803  std::string Sep(", ");
2804  unsigned AllowedCnt = 0;
2805  unsigned TotalAllowedNum =
2806  AllowedNameModifiers.size() - NamedModifiersNumber;
2807  for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
2808  ++Cnt) {
2809  OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
2810  if (!FoundNameModifiers[NM]) {
2811  Values += "'";
2812  Values += getOpenMPDirectiveName(NM);
2813  Values += "'";
2814  if (AllowedCnt + 2 == TotalAllowedNum)
2815  Values += " or ";
2816  else if (AllowedCnt + 1 != TotalAllowedNum)
2817  Values += Sep;
2818  ++AllowedCnt;
2819  }
2820  }
2821  S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getLocStart(),
2822  diag::err_omp_unnamed_if_clause)
2823  << (TotalAllowedNum > 1) << Values;
2824  }
2825  for (auto Loc : NameModifierLoc) {
2826  S.Diag(Loc, diag::note_omp_previous_named_if_clause);
2827  }
2828  ErrorFound = true;
2829  }
2830  return ErrorFound;
2831 }
2832 
2835  OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
2836  Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
2837  StmtResult Res = StmtError();
2838  // First check CancelRegion which is then used in checkNestingOfRegions.
2839  if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
2840  checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
2841  StartLoc))
2842  return StmtError();
2843 
2844  llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
2845  llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA;
2846  bool ErrorFound = false;
2847  ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
2848  if (AStmt && !CurContext->isDependentContext()) {
2849  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
2850 
2851  // Check default data sharing attributes for referenced variables.
2852  DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
2853  int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
2854  Stmt *S = AStmt;
2855  while (--ThisCaptureLevel >= 0)
2856  S = cast<CapturedStmt>(S)->getCapturedStmt();
2857  DSAChecker.Visit(S);
2858  if (DSAChecker.isErrorFound())
2859  return StmtError();
2860  // Generate list of implicitly defined firstprivate variables.
2861  VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
2862 
2863  SmallVector<Expr *, 4> ImplicitFirstprivates(
2864  DSAChecker.getImplicitFirstprivate().begin(),
2865  DSAChecker.getImplicitFirstprivate().end());
2866  SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(),
2867  DSAChecker.getImplicitMap().end());
2868  // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
2869  for (auto *C : Clauses) {
2870  if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
2871  for (auto *E : IRC->taskgroup_descriptors())
2872  if (E)
2873  ImplicitFirstprivates.emplace_back(E);
2874  }
2875  }
2876  if (!ImplicitFirstprivates.empty()) {
2877  if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
2878  ImplicitFirstprivates, SourceLocation(), SourceLocation(),
2879  SourceLocation())) {
2880  ClausesWithImplicit.push_back(Implicit);
2881  ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
2882  ImplicitFirstprivates.size();
2883  } else
2884  ErrorFound = true;
2885  }
2886  if (!ImplicitMaps.empty()) {
2887  if (OMPClause *Implicit = ActOnOpenMPMapClause(
2888  OMPC_MAP_unknown, OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true,
2889  SourceLocation(), SourceLocation(), ImplicitMaps,
2891  ClausesWithImplicit.emplace_back(Implicit);
2892  ErrorFound |=
2893  cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size();
2894  } else
2895  ErrorFound = true;
2896  }
2897  }
2898 
2899  llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
2900  switch (Kind) {
2901  case OMPD_parallel:
2902  Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
2903  EndLoc);
2904  AllowedNameModifiers.push_back(OMPD_parallel);
2905  break;
2906  case OMPD_simd:
2907  Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
2908  VarsWithInheritedDSA);
2909  break;
2910  case OMPD_for:
2911  Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
2912  VarsWithInheritedDSA);
2913  break;
2914  case OMPD_for_simd:
2915  Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
2916  EndLoc, VarsWithInheritedDSA);
2917  break;
2918  case OMPD_sections:
2919  Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
2920  EndLoc);
2921  break;
2922  case OMPD_section:
2923  assert(ClausesWithImplicit.empty() &&
2924  "No clauses are allowed for 'omp section' directive");
2925  Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
2926  break;
2927  case OMPD_single:
2928  Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
2929  EndLoc);
2930  break;
2931  case OMPD_master:
2932  assert(ClausesWithImplicit.empty() &&
2933  "No clauses are allowed for 'omp master' directive");
2934  Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
2935  break;
2936  case OMPD_critical:
2937  Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
2938  StartLoc, EndLoc);
2939  break;
2940  case OMPD_parallel_for:
2941  Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
2942  EndLoc, VarsWithInheritedDSA);
2943  AllowedNameModifiers.push_back(OMPD_parallel);
2944  break;
2945  case OMPD_parallel_for_simd:
2946  Res = ActOnOpenMPParallelForSimdDirective(
2947  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
2948  AllowedNameModifiers.push_back(OMPD_parallel);
2949  break;
2950  case OMPD_parallel_sections:
2951  Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
2952  StartLoc, EndLoc);
2953  AllowedNameModifiers.push_back(OMPD_parallel);
2954  break;
2955  case OMPD_task:
2956  Res =
2957  ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
2958  AllowedNameModifiers.push_back(OMPD_task);
2959  break;
2960  case OMPD_taskyield:
2961  assert(ClausesWithImplicit.empty() &&
2962  "No clauses are allowed for 'omp taskyield' directive");
2963  assert(AStmt == nullptr &&
2964  "No associated statement allowed for 'omp taskyield' directive");
2965  Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
2966  break;
2967  case OMPD_barrier:
2968  assert(ClausesWithImplicit.empty() &&
2969  "No clauses are allowed for 'omp barrier' directive");
2970  assert(AStmt == nullptr &&
2971  "No associated statement allowed for 'omp barrier' directive");
2972  Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
2973  break;
2974  case OMPD_taskwait:
2975  assert(ClausesWithImplicit.empty() &&
2976  "No clauses are allowed for 'omp taskwait' directive");
2977  assert(AStmt == nullptr &&
2978  "No associated statement allowed for 'omp taskwait' directive");
2979  Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
2980  break;
2981  case OMPD_taskgroup:
2982  Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
2983  EndLoc);
2984  break;
2985  case OMPD_flush:
2986  assert(AStmt == nullptr &&
2987  "No associated statement allowed for 'omp flush' directive");
2988  Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
2989  break;
2990  case OMPD_ordered:
2991  Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
2992  EndLoc);
2993  break;
2994  case OMPD_atomic:
2995  Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
2996  EndLoc);
2997  break;
2998  case OMPD_teams:
2999  Res =
3000  ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
3001  break;
3002  case OMPD_target:
3003  Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
3004  EndLoc);
3005  AllowedNameModifiers.push_back(OMPD_target);
3006  break;
3007  case OMPD_target_parallel:
3008  Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
3009  StartLoc, EndLoc);
3010  AllowedNameModifiers.push_back(OMPD_target);
3011  AllowedNameModifiers.push_back(OMPD_parallel);
3012  break;
3013  case OMPD_target_parallel_for:
3014  Res = ActOnOpenMPTargetParallelForDirective(
3015  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3016  AllowedNameModifiers.push_back(OMPD_target);
3017  AllowedNameModifiers.push_back(OMPD_parallel);
3018  break;
3019  case OMPD_cancellation_point:
3020  assert(ClausesWithImplicit.empty() &&
3021  "No clauses are allowed for 'omp cancellation point' directive");
3022  assert(AStmt == nullptr && "No associated statement allowed for 'omp "
3023  "cancellation point' directive");
3024  Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
3025  break;
3026  case OMPD_cancel:
3027  assert(AStmt == nullptr &&
3028  "No associated statement allowed for 'omp cancel' directive");
3029  Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
3030  CancelRegion);
3031  AllowedNameModifiers.push_back(OMPD_cancel);
3032  break;
3033  case OMPD_target_data:
3034  Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
3035  EndLoc);
3036  AllowedNameModifiers.push_back(OMPD_target_data);
3037  break;
3038  case OMPD_target_enter_data:
3039  Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
3040  EndLoc, AStmt);
3041  AllowedNameModifiers.push_back(OMPD_target_enter_data);
3042  break;
3043  case OMPD_target_exit_data:
3044  Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
3045  EndLoc, AStmt);
3046  AllowedNameModifiers.push_back(OMPD_target_exit_data);
3047  break;
3048  case OMPD_taskloop:
3049  Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
3050  EndLoc, VarsWithInheritedDSA);
3051  AllowedNameModifiers.push_back(OMPD_taskloop);
3052  break;
3053  case OMPD_taskloop_simd:
3054  Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3055  EndLoc, VarsWithInheritedDSA);
3056  AllowedNameModifiers.push_back(OMPD_taskloop);
3057  break;
3058  case OMPD_distribute:
3059  Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
3060  EndLoc, VarsWithInheritedDSA);
3061  break;
3062  case OMPD_target_update:
3063  Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
3064  EndLoc, AStmt);
3065  AllowedNameModifiers.push_back(OMPD_target_update);
3066  break;
3067  case OMPD_distribute_parallel_for:
3068  Res = ActOnOpenMPDistributeParallelForDirective(
3069  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3070  AllowedNameModifiers.push_back(OMPD_parallel);
3071  break;
3072  case OMPD_distribute_parallel_for_simd:
3073  Res = ActOnOpenMPDistributeParallelForSimdDirective(
3074  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3075  AllowedNameModifiers.push_back(OMPD_parallel);
3076  break;
3077  case OMPD_distribute_simd:
3078  Res = ActOnOpenMPDistributeSimdDirective(
3079  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3080  break;
3081  case OMPD_target_parallel_for_simd:
3082  Res = ActOnOpenMPTargetParallelForSimdDirective(
3083  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3084  AllowedNameModifiers.push_back(OMPD_target);
3085  AllowedNameModifiers.push_back(OMPD_parallel);
3086  break;
3087  case OMPD_target_simd:
3088  Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3089  EndLoc, VarsWithInheritedDSA);
3090  AllowedNameModifiers.push_back(OMPD_target);
3091  break;
3092  case OMPD_teams_distribute:
3093  Res = ActOnOpenMPTeamsDistributeDirective(
3094  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3095  break;
3096  case OMPD_teams_distribute_simd:
3097  Res = ActOnOpenMPTeamsDistributeSimdDirective(
3098  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3099  break;
3100  case OMPD_teams_distribute_parallel_for_simd:
3101  Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
3102  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3103  AllowedNameModifiers.push_back(OMPD_parallel);
3104  break;
3105  case OMPD_teams_distribute_parallel_for:
3106  Res = ActOnOpenMPTeamsDistributeParallelForDirective(
3107  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3108  AllowedNameModifiers.push_back(OMPD_parallel);
3109  break;
3110  case OMPD_target_teams:
3111  Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
3112  EndLoc);
3113  AllowedNameModifiers.push_back(OMPD_target);
3114  break;
3115  case OMPD_target_teams_distribute:
3116  Res = ActOnOpenMPTargetTeamsDistributeDirective(
3117  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3118  AllowedNameModifiers.push_back(OMPD_target);
3119  break;
3120  case OMPD_target_teams_distribute_parallel_for:
3121  Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
3122  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3123  AllowedNameModifiers.push_back(OMPD_target);
3124  AllowedNameModifiers.push_back(OMPD_parallel);
3125  break;
3126  case OMPD_target_teams_distribute_parallel_for_simd:
3127  Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
3128  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3129  AllowedNameModifiers.push_back(OMPD_target);
3130  AllowedNameModifiers.push_back(OMPD_parallel);
3131  break;
3132  case OMPD_target_teams_distribute_simd:
3133  Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
3134  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3135  AllowedNameModifiers.push_back(OMPD_target);
3136  break;
3137  case OMPD_declare_target:
3138  case OMPD_end_declare_target:
3139  case OMPD_threadprivate:
3140  case OMPD_declare_reduction:
3141  case OMPD_declare_simd:
3142  llvm_unreachable("OpenMP Directive is not allowed");
3143  case OMPD_unknown:
3144  llvm_unreachable("Unknown OpenMP directive");
3145  }
3146 
3147  for (auto P : VarsWithInheritedDSA) {
3148  Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
3149  << P.first << P.second->getSourceRange();
3150  }
3151  ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound;
3152 
3153  if (!AllowedNameModifiers.empty())
3154  ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
3155  ErrorFound;
3156 
3157  if (ErrorFound)
3158  return StmtError();
3159  return Res;
3160 }
3161 
3163  DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
3164  ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
3165  ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
3166  ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
3167  assert(Aligneds.size() == Alignments.size());
3168  assert(Linears.size() == LinModifiers.size());
3169  assert(Linears.size() == Steps.size());
3170  if (!DG || DG.get().isNull())
3171  return DeclGroupPtrTy();
3172 
3173  if (!DG.get().isSingleDecl()) {
3174  Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd);
3175  return DG;
3176  }
3177  auto *ADecl = DG.get().getSingleDecl();
3178  if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
3179  ADecl = FTD->getTemplatedDecl();
3180 
3181  auto *FD = dyn_cast<FunctionDecl>(ADecl);
3182  if (!FD) {
3183  Diag(ADecl->getLocation(), diag::err_omp_function_expected);
3184  return DeclGroupPtrTy();
3185  }
3186 
3187  // OpenMP [2.8.2, declare simd construct, Description]
3188  // The parameter of the simdlen clause must be a constant positive integer
3189  // expression.
3190  ExprResult SL;
3191  if (Simdlen)
3192  SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
3193  // OpenMP [2.8.2, declare simd construct, Description]
3194  // The special this pointer can be used as if was one of the arguments to the
3195  // function in any of the linear, aligned, or uniform clauses.
3196  // The uniform clause declares one or more arguments to have an invariant
3197  // value for all concurrent invocations of the function in the execution of a
3198  // single SIMD loop.
3199  llvm::DenseMap<Decl *, Expr *> UniformedArgs;
3200  Expr *UniformedLinearThis = nullptr;
3201  for (auto *E : Uniforms) {
3202  E = E->IgnoreParenImpCasts();
3203  if (auto *DRE = dyn_cast<DeclRefExpr>(E))
3204  if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
3205  if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3206  FD->getParamDecl(PVD->getFunctionScopeIndex())
3207  ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
3208  UniformedArgs.insert(std::make_pair(PVD->getCanonicalDecl(), E));
3209  continue;
3210  }
3211  if (isa<CXXThisExpr>(E)) {
3212  UniformedLinearThis = E;
3213  continue;
3214  }
3215  Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3216  << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3217  }
3218  // OpenMP [2.8.2, declare simd construct, Description]
3219  // The aligned clause declares that the object to which each list item points
3220  // is aligned to the number of bytes expressed in the optional parameter of
3221  // the aligned clause.
3222  // The special this pointer can be used as if was one of the arguments to the
3223  // function in any of the linear, aligned, or uniform clauses.
3224  // The type of list items appearing in the aligned clause must be array,
3225  // pointer, reference to array, or reference to pointer.
3226  llvm::DenseMap<Decl *, Expr *> AlignedArgs;
3227  Expr *AlignedThis = nullptr;
3228  for (auto *E : Aligneds) {
3229  E = E->IgnoreParenImpCasts();
3230  if (auto *DRE = dyn_cast<DeclRefExpr>(E))
3231  if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3232  auto *CanonPVD = PVD->getCanonicalDecl();
3233  if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3234  FD->getParamDecl(PVD->getFunctionScopeIndex())
3235  ->getCanonicalDecl() == CanonPVD) {
3236  // OpenMP [2.8.1, simd construct, Restrictions]
3237  // A list-item cannot appear in more than one aligned clause.
3238  if (AlignedArgs.count(CanonPVD) > 0) {
3239  Diag(E->getExprLoc(), diag::err_omp_aligned_twice)
3240  << 1 << E->getSourceRange();
3241  Diag(AlignedArgs[CanonPVD]->getExprLoc(),
3242  diag::note_omp_explicit_dsa)
3243  << getOpenMPClauseName(OMPC_aligned);
3244  continue;
3245  }
3246  AlignedArgs[CanonPVD] = E;
3247  QualType QTy = PVD->getType()
3248  .getNonReferenceType()
3249  .getUnqualifiedType()
3250  .getCanonicalType();
3251  const Type *Ty = QTy.getTypePtrOrNull();
3252  if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
3253  Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
3254  << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
3255  Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
3256  }
3257  continue;
3258  }
3259  }
3260  if (isa<CXXThisExpr>(E)) {
3261  if (AlignedThis) {
3262  Diag(E->getExprLoc(), diag::err_omp_aligned_twice)
3263  << 2 << E->getSourceRange();
3264  Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
3265  << getOpenMPClauseName(OMPC_aligned);
3266  }
3267  AlignedThis = E;
3268  continue;
3269  }
3270  Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3271  << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3272  }
3273  // The optional parameter of the aligned clause, alignment, must be a constant
3274  // positive integer expression. If no optional parameter is specified,
3275  // implementation-defined default alignments for SIMD instructions on the
3276  // target platforms are assumed.
3277  SmallVector<Expr *, 4> NewAligns;
3278  for (auto *E : Alignments) {
3279  ExprResult Align;
3280  if (E)
3281  Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
3282  NewAligns.push_back(Align.get());
3283  }
3284  // OpenMP [2.8.2, declare simd construct, Description]
3285  // The linear clause declares one or more list items to be private to a SIMD
3286  // lane and to have a linear relationship with respect to the iteration space
3287  // of a loop.
3288  // The special this pointer can be used as if was one of the arguments to the
3289  // function in any of the linear, aligned, or uniform clauses.
3290  // When a linear-step expression is specified in a linear clause it must be
3291  // either a constant integer expression or an integer-typed parameter that is
3292  // specified in a uniform clause on the directive.
3293  llvm::DenseMap<Decl *, Expr *> LinearArgs;
3294  const bool IsUniformedThis = UniformedLinearThis != nullptr;
3295  auto MI = LinModifiers.begin();
3296  for (auto *E : Linears) {
3297  auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
3298  ++MI;
3299  E = E->IgnoreParenImpCasts();
3300  if (auto *DRE = dyn_cast<DeclRefExpr>(E))
3301  if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3302  auto *CanonPVD = PVD->getCanonicalDecl();
3303  if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3304  FD->getParamDecl(PVD->getFunctionScopeIndex())
3305  ->getCanonicalDecl() == CanonPVD) {
3306  // OpenMP [2.15.3.7, linear Clause, Restrictions]
3307  // A list-item cannot appear in more than one linear clause.
3308  if (LinearArgs.count(CanonPVD) > 0) {
3309  Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3310  << getOpenMPClauseName(OMPC_linear)
3311  << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
3312  Diag(LinearArgs[CanonPVD]->getExprLoc(),
3313  diag::note_omp_explicit_dsa)
3314  << getOpenMPClauseName(OMPC_linear);
3315  continue;
3316  }
3317  // Each argument can appear in at most one uniform or linear clause.
3318  if (UniformedArgs.count(CanonPVD) > 0) {
3319  Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3320  << getOpenMPClauseName(OMPC_linear)
3322  Diag(UniformedArgs[CanonPVD]->getExprLoc(),
3323  diag::note_omp_explicit_dsa)
3325  continue;
3326  }
3327  LinearArgs[CanonPVD] = E;
3328  if (E->isValueDependent() || E->isTypeDependent() ||
3329  E->isInstantiationDependent() ||
3331  continue;
3332  (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
3333  PVD->getOriginalType());
3334  continue;
3335  }
3336  }
3337  if (isa<CXXThisExpr>(E)) {
3338  if (UniformedLinearThis) {
3339  Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3340  << getOpenMPClauseName(OMPC_linear)
3341  << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
3342  << E->getSourceRange();
3343  Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
3344  << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
3345  : OMPC_linear);
3346  continue;
3347  }
3348  UniformedLinearThis = E;
3349  if (E->isValueDependent() || E->isTypeDependent() ||
3351  continue;
3352  (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
3353  E->getType());
3354  continue;
3355  }
3356  Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3357  << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3358  }
3359  Expr *Step = nullptr;
3360  Expr *NewStep = nullptr;
3361  SmallVector<Expr *, 4> NewSteps;
3362  for (auto *E : Steps) {
3363  // Skip the same step expression, it was checked already.
3364  if (Step == E || !E) {
3365  NewSteps.push_back(E ? NewStep : nullptr);
3366  continue;
3367  }
3368  Step = E;
3369  if (auto *DRE = dyn_cast<DeclRefExpr>(Step))
3370  if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3371  auto *CanonPVD = PVD->getCanonicalDecl();
3372  if (UniformedArgs.count(CanonPVD) == 0) {
3373  Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
3374  << Step->getSourceRange();
3375  } else if (E->isValueDependent() || E->isTypeDependent() ||
3376  E->isInstantiationDependent() ||
3378  CanonPVD->getType()->hasIntegerRepresentation())
3379  NewSteps.push_back(Step);
3380  else {
3381  Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
3382  << Step->getSourceRange();
3383  }
3384  continue;
3385  }
3386  NewStep = Step;
3387  if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
3388  !Step->isInstantiationDependent() &&
3390  NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
3391  .get();
3392  if (NewStep)
3393  NewStep = VerifyIntegerConstantExpression(NewStep).get();
3394  }
3395  NewSteps.push_back(NewStep);
3396  }
3397  auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
3398  Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
3399  Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
3400  const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
3401  const_cast<Expr **>(Linears.data()), Linears.size(),
3402  const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
3403  NewSteps.data(), NewSteps.size(), SR);
3404  ADecl->addAttr(NewAttr);
3405  return ConvertDeclToDeclGroup(ADecl);
3406 }
3407 
3409  Stmt *AStmt,
3410  SourceLocation StartLoc,
3411  SourceLocation EndLoc) {
3412  if (!AStmt)
3413  return StmtError();
3414 
3415  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
3416  // 1.2.2 OpenMP Language Terminology
3417  // Structured block - An executable statement with a single entry at the
3418  // top and a single exit at the bottom.
3419  // The point of exit cannot be a branch out of the structured block.
3420  // longjmp() and throw() must not violate the entry/exit criteria.
3421  CS->getCapturedDecl()->setNothrow();
3422 
3423  getCurFunction()->setHasBranchProtectedScope();
3424 
3425  return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
3426  DSAStack->isCancelRegion());
3427 }
3428 
3429 namespace {
3430 /// \brief Helper class for checking canonical form of the OpenMP loops and
3431 /// extracting iteration space of each loop in the loop nest, that will be used
3432 /// for IR generation.
3433 class OpenMPIterationSpaceChecker {
3434  /// \brief Reference to Sema.
3435  Sema &SemaRef;
3436  /// \brief A location for diagnostics (when there is no some better location).
3437  SourceLocation DefaultLoc;
3438  /// \brief A location for diagnostics (when increment is not compatible).
3439  SourceLocation ConditionLoc;
3440  /// \brief A source location for referring to loop init later.
3441  SourceRange InitSrcRange;
3442  /// \brief A source location for referring to condition later.
3443  SourceRange ConditionSrcRange;
3444  /// \brief A source location for referring to increment later.
3445  SourceRange IncrementSrcRange;
3446  /// \brief Loop variable.
3447  ValueDecl *LCDecl = nullptr;
3448  /// \brief Reference to loop variable.
3449  Expr *LCRef = nullptr;
3450  /// \brief Lower bound (initializer for the var).
3451  Expr *LB = nullptr;
3452  /// \brief Upper bound.
3453  Expr *UB = nullptr;
3454  /// \brief Loop step (increment).
3455  Expr *Step = nullptr;
3456  /// \brief This flag is true when condition is one of:
3457  /// Var < UB
3458  /// Var <= UB
3459  /// UB > Var
3460  /// UB >= Var
3461  bool TestIsLessOp = false;
3462  /// \brief This flag is true when condition is strict ( < or > ).
3463  bool TestIsStrictOp = false;
3464  /// \brief This flag is true when step is subtracted on each iteration.
3465  bool SubtractStep = false;
3466 
3467 public:
3468  OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc)
3469  : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
3470  /// \brief Check init-expr for canonical loop form and save loop counter
3471  /// variable - #Var and its initialization value - #LB.
3472  bool CheckInit(Stmt *S, bool EmitDiags = true);
3473  /// \brief Check test-expr for canonical form, save upper-bound (#UB), flags
3474  /// for less/greater and for strict/non-strict comparison.
3475  bool CheckCond(Expr *S);
3476  /// \brief Check incr-expr for canonical loop form and return true if it
3477  /// does not conform, otherwise save loop step (#Step).
3478  bool CheckInc(Expr *S);
3479  /// \brief Return the loop counter variable.
3480  ValueDecl *GetLoopDecl() const { return LCDecl; }
3481  /// \brief Return the reference expression to loop counter variable.
3482  Expr *GetLoopDeclRefExpr() const { return LCRef; }
3483  /// \brief Source range of the loop init.
3484  SourceRange GetInitSrcRange() const { return InitSrcRange; }
3485  /// \brief Source range of the loop condition.
3486  SourceRange GetConditionSrcRange() const { return ConditionSrcRange; }
3487  /// \brief Source range of the loop increment.
3488  SourceRange GetIncrementSrcRange() const { return IncrementSrcRange; }
3489  /// \brief True if the step should be subtracted.
3490  bool ShouldSubtractStep() const { return SubtractStep; }
3491  /// \brief Build the expression to calculate the number of iterations.
3492  Expr *
3493  BuildNumIterations(Scope *S, const bool LimitedType,
3494  llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const;
3495  /// \brief Build the precondition expression for the loops.
3496  Expr *BuildPreCond(Scope *S, Expr *Cond,
3497  llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const;
3498  /// \brief Build reference expression to the counter be used for codegen.
3499  DeclRefExpr *BuildCounterVar(llvm::MapVector<Expr *, DeclRefExpr *> &Captures,
3500  DSAStackTy &DSA) const;
3501  /// \brief Build reference expression to the private counter be used for
3502  /// codegen.
3503  Expr *BuildPrivateCounterVar() const;
3504  /// \brief Build initialization of the counter be used for codegen.
3505  Expr *BuildCounterInit() const;
3506  /// \brief Build step of the counter be used for codegen.
3507  Expr *BuildCounterStep() const;
3508  /// \brief Return true if any expression is dependent.
3509  bool Dependent() const;
3510 
3511 private:
3512  /// \brief Check the right-hand side of an assignment in the increment
3513  /// expression.
3514  bool CheckIncRHS(Expr *RHS);
3515  /// \brief Helper to set loop counter variable and its initializer.
3516  bool SetLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB);
3517  /// \brief Helper to set upper bound.
3518  bool SetUB(Expr *NewUB, bool LessOp, bool StrictOp, SourceRange SR,
3519  SourceLocation SL);
3520  /// \brief Helper to set loop increment.
3521  bool SetStep(Expr *NewStep, bool Subtract);
3522 };
3523 
3524 bool OpenMPIterationSpaceChecker::Dependent() const {
3525  if (!LCDecl) {
3526  assert(!LB && !UB && !Step);
3527  return false;
3528  }
3529  return LCDecl->getType()->isDependentType() ||
3530  (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
3531  (Step && Step->isValueDependent());
3532 }
3533 
3534 bool OpenMPIterationSpaceChecker::SetLCDeclAndLB(ValueDecl *NewLCDecl,
3535  Expr *NewLCRefExpr,
3536  Expr *NewLB) {
3537  // State consistency checking to ensure correct usage.
3538  assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
3539  UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
3540  if (!NewLCDecl || !NewLB)
3541  return true;
3542  LCDecl = getCanonicalDecl(NewLCDecl);
3543  LCRef = NewLCRefExpr;
3544  if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
3545  if (const CXXConstructorDecl *Ctor = CE->getConstructor())
3546  if ((Ctor->isCopyOrMoveConstructor() ||
3547  Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
3548  CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
3549  NewLB = CE->getArg(0)->IgnoreParenImpCasts();
3550  LB = NewLB;
3551  return false;
3552 }
3553 
3554 bool OpenMPIterationSpaceChecker::SetUB(Expr *NewUB, bool LessOp, bool StrictOp,
3555  SourceRange SR, SourceLocation SL) {
3556  // State consistency checking to ensure correct usage.
3557  assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&
3558  Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
3559  if (!NewUB)
3560  return true;
3561  UB = NewUB;
3562  TestIsLessOp = LessOp;
3563  TestIsStrictOp = StrictOp;
3564  ConditionSrcRange = SR;
3565  ConditionLoc = SL;
3566  return false;
3567 }
3568 
3569 bool OpenMPIterationSpaceChecker::SetStep(Expr *NewStep, bool Subtract) {
3570  // State consistency checking to ensure correct usage.
3571  assert(LCDecl != nullptr && LB != nullptr && Step == nullptr);
3572  if (!NewStep)
3573  return true;
3574  if (!NewStep->isValueDependent()) {
3575  // Check that the step is integer expression.
3576  SourceLocation StepLoc = NewStep->getLocStart();
3578  StepLoc, getExprAsWritten(NewStep));
3579  if (Val.isInvalid())
3580  return true;
3581  NewStep = Val.get();
3582 
3583  // OpenMP [2.6, Canonical Loop Form, Restrictions]
3584  // If test-expr is of form var relational-op b and relational-op is < or
3585  // <= then incr-expr must cause var to increase on each iteration of the
3586  // loop. If test-expr is of form var relational-op b and relational-op is
3587  // > or >= then incr-expr must cause var to decrease on each iteration of
3588  // the loop.
3589  // If test-expr is of form b relational-op var and relational-op is < or
3590  // <= then incr-expr must cause var to decrease on each iteration of the
3591  // loop. If test-expr is of form b relational-op var and relational-op is
3592  // > or >= then incr-expr must cause var to increase on each iteration of
3593  // the loop.
3594  llvm::APSInt Result;
3595  bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context);
3596  bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
3597  bool IsConstNeg =
3598  IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
3599  bool IsConstPos =
3600  IsConstant && Result.isSigned() && (Subtract == Result.isNegative());
3601  bool IsConstZero = IsConstant && !Result.getBoolValue();
3602  if (UB && (IsConstZero ||
3603  (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract))
3604  : (IsConstPos || (IsUnsigned && !Subtract))))) {
3605  SemaRef.Diag(NewStep->getExprLoc(),
3606  diag::err_omp_loop_incr_not_compatible)
3607  << LCDecl << TestIsLessOp << NewStep->getSourceRange();
3608  SemaRef.Diag(ConditionLoc,
3609  diag::note_omp_loop_cond_requres_compatible_incr)
3610  << TestIsLessOp << ConditionSrcRange;
3611  return true;
3612  }
3613  if (TestIsLessOp == Subtract) {
3614  NewStep =
3615  SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
3616  .get();
3617  Subtract = !Subtract;
3618  }
3619  }
3620 
3621  Step = NewStep;
3622  SubtractStep = Subtract;
3623  return false;
3624 }
3625 
3626 bool OpenMPIterationSpaceChecker::CheckInit(Stmt *S, bool EmitDiags) {
3627  // Check init-expr for canonical loop form and save loop counter
3628  // variable - #Var and its initialization value - #LB.
3629  // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
3630  // var = lb
3631  // integer-type var = lb
3632  // random-access-iterator-type var = lb
3633  // pointer-type var = lb
3634  //
3635  if (!S) {
3636  if (EmitDiags) {
3637  SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
3638  }
3639  return true;
3640  }
3641  if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
3642  if (!ExprTemp->cleanupsHaveSideEffects())
3643  S = ExprTemp->getSubExpr();
3644 
3645  InitSrcRange = S->getSourceRange();
3646  if (Expr *E = dyn_cast<Expr>(S))
3647  S = E->IgnoreParens();
3648  if (auto *BO = dyn_cast<BinaryOperator>(S)) {
3649  if (BO->getOpcode() == BO_Assign) {
3650  auto *LHS = BO->getLHS()->IgnoreParens();
3651  if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
3652  if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
3653  if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
3654  return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3655  return SetLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS());
3656  }
3657  if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
3658  if (ME->isArrow() &&
3659  isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3660  return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3661  }
3662  }
3663  } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
3664  if (DS->isSingleDecl()) {
3665  if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
3666  if (Var->hasInit() && !Var->getType()->isReferenceType()) {
3667  // Accept non-canonical init form here but emit ext. warning.
3668  if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
3669  SemaRef.Diag(S->getLocStart(),
3670  diag::ext_omp_loop_not_canonical_init)
3671  << S->getSourceRange();
3672  return SetLCDeclAndLB(Var, nullptr, Var->getInit());
3673  }
3674  }
3675  }
3676  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
3677  if (CE->getOperator() == OO_Equal) {
3678  auto *LHS = CE->getArg(0);
3679  if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
3680  if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
3681  if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
3682  return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3683  return SetLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1));
3684  }
3685  if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
3686  if (ME->isArrow() &&
3687  isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3688  return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3689  }
3690  }
3691  }
3692 
3693  if (Dependent() || SemaRef.CurContext->isDependentContext())
3694  return false;
3695  if (EmitDiags) {
3696  SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_init)
3697  << S->getSourceRange();
3698  }
3699  return true;
3700 }
3701 
3702 /// \brief Ignore parenthesizes, implicit casts, copy constructor and return the
3703 /// variable (which may be the loop variable) if possible.
3704 static const ValueDecl *GetInitLCDecl(Expr *E) {
3705  if (!E)
3706  return nullptr;
3707  E = getExprAsWritten(E);
3708  if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
3709  if (const CXXConstructorDecl *Ctor = CE->getConstructor())
3710  if ((Ctor->isCopyOrMoveConstructor() ||
3711  Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
3712  CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
3713  E = CE->getArg(0)->IgnoreParenImpCasts();
3714  if (auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
3715  if (auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
3716  return getCanonicalDecl(VD);
3717  }
3718  if (auto *ME = dyn_cast_or_null<MemberExpr>(E))
3719  if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3720  return getCanonicalDecl(ME->getMemberDecl());
3721  return nullptr;
3722 }
3723 
3724 bool OpenMPIterationSpaceChecker::CheckCond(Expr *S) {
3725  // Check test-expr for canonical form, save upper-bound UB, flags for
3726  // less/greater and for strict/non-strict comparison.
3727  // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
3728  // var relational-op b
3729  // b relational-op var
3730  //
3731  if (!S) {
3732  SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl;
3733  return true;
3734  }
3735  S = getExprAsWritten(S);
3736  SourceLocation CondLoc = S->getLocStart();
3737  if (auto *BO = dyn_cast<BinaryOperator>(S)) {
3738  if (BO->isRelationalOp()) {
3739  if (GetInitLCDecl(BO->getLHS()) == LCDecl)
3740  return SetUB(BO->getRHS(),
3741  (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
3742  (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
3743  BO->getSourceRange(), BO->getOperatorLoc());
3744  if (GetInitLCDecl(BO->getRHS()) == LCDecl)
3745  return SetUB(BO->getLHS(),
3746  (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
3747  (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
3748  BO->getSourceRange(), BO->getOperatorLoc());
3749  }
3750  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
3751  if (CE->getNumArgs() == 2) {
3752  auto Op = CE->getOperator();
3753  switch (Op) {
3754  case OO_Greater:
3755  case OO_GreaterEqual:
3756  case OO_Less:
3757  case OO_LessEqual:
3758  if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3759  return SetUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
3760  Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
3761  CE->getOperatorLoc());
3762  if (GetInitLCDecl(CE->getArg(1)) == LCDecl)
3763  return SetUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
3764  Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
3765  CE->getOperatorLoc());
3766  break;
3767  default:
3768  break;
3769  }
3770  }
3771  }
3772  if (Dependent() || SemaRef.CurContext->isDependentContext())
3773  return false;
3774  SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
3775  << S->getSourceRange() << LCDecl;
3776  return true;
3777 }
3778 
3779 bool OpenMPIterationSpaceChecker::CheckIncRHS(Expr *RHS) {
3780  // RHS of canonical loop form increment can be:
3781  // var + incr
3782  // incr + var
3783  // var - incr
3784  //
3785  RHS = RHS->IgnoreParenImpCasts();
3786  if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
3787  if (BO->isAdditiveOp()) {
3788  bool IsAdd = BO->getOpcode() == BO_Add;
3789  if (GetInitLCDecl(BO->getLHS()) == LCDecl)
3790  return SetStep(BO->getRHS(), !IsAdd);
3791  if (IsAdd && GetInitLCDecl(BO->getRHS()) == LCDecl)
3792  return SetStep(BO->getLHS(), false);
3793  }
3794  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
3795  bool IsAdd = CE->getOperator() == OO_Plus;
3796  if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
3797  if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3798  return SetStep(CE->getArg(1), !IsAdd);
3799  if (IsAdd && GetInitLCDecl(CE->getArg(1)) == LCDecl)
3800  return SetStep(CE->getArg(0), false);
3801  }
3802  }
3803  if (Dependent() || SemaRef.CurContext->isDependentContext())
3804  return false;
3805  SemaRef.Diag(RHS->getLocStart(), diag::err_omp_loop_not_canonical_incr)
3806  << RHS->getSourceRange() << LCDecl;
3807  return true;
3808 }
3809 
3810 bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) {
3811  // Check incr-expr for canonical loop form and return true if it
3812  // does not conform.
3813  // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
3814  // ++var
3815  // var++
3816  // --var
3817  // var--
3818  // var += incr
3819  // var -= incr
3820  // var = var + incr
3821  // var = incr + var
3822  // var = var - incr
3823  //
3824  if (!S) {
3825  SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
3826  return true;
3827  }
3828  if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
3829  if (!ExprTemp->cleanupsHaveSideEffects())
3830  S = ExprTemp->getSubExpr();
3831 
3832  IncrementSrcRange = S->getSourceRange();
3833  S = S->IgnoreParens();
3834  if (auto *UO = dyn_cast<UnaryOperator>(S)) {
3835  if (UO->isIncrementDecrementOp() &&
3836  GetInitLCDecl(UO->getSubExpr()) == LCDecl)
3837  return SetStep(SemaRef
3838  .ActOnIntegerConstant(UO->getLocStart(),
3839  (UO->isDecrementOp() ? -1 : 1))
3840  .get(),
3841  false);
3842  } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
3843  switch (BO->getOpcode()) {
3844  case BO_AddAssign:
3845  case BO_SubAssign:
3846  if (GetInitLCDecl(BO->getLHS()) == LCDecl)
3847  return SetStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
3848  break;
3849  case BO_Assign:
3850  if (GetInitLCDecl(BO->getLHS()) == LCDecl)
3851  return CheckIncRHS(BO->getRHS());
3852  break;
3853  default:
3854  break;
3855  }
3856  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
3857  switch (CE->getOperator()) {
3858  case OO_PlusPlus:
3859  case OO_MinusMinus:
3860  if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3861  return SetStep(SemaRef
3862  .ActOnIntegerConstant(
3863  CE->getLocStart(),
3864  ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
3865  .get(),
3866  false);
3867  break;
3868  case OO_PlusEqual:
3869  case OO_MinusEqual:
3870  if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3871  return SetStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
3872  break;
3873  case OO_Equal:
3874  if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3875  return CheckIncRHS(CE->getArg(1));
3876  break;
3877  default:
3878  break;
3879  }
3880  }
3881  if (Dependent() || SemaRef.CurContext->isDependentContext())
3882  return false;
3883  SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_incr)
3884  << S->getSourceRange() << LCDecl;
3885  return true;
3886 }
3887 
3888 static ExprResult
3889 tryBuildCapture(Sema &SemaRef, Expr *Capture,
3890  llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
3891  if (SemaRef.CurContext->isDependentContext())
3892  return ExprResult(Capture);
3893  if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
3894  return SemaRef.PerformImplicitConversion(
3895  Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
3896  /*AllowExplicit=*/true);
3897  auto I = Captures.find(Capture);
3898  if (I != Captures.end())
3899  return buildCapture(SemaRef, Capture, I->second);
3900  DeclRefExpr *Ref = nullptr;
3901  ExprResult Res = buildCapture(SemaRef, Capture, Ref);
3902  Captures[Capture] = Ref;
3903  return Res;
3904 }
3905 
3906 /// \brief Build the expression to calculate the number of iterations.
3907 Expr *OpenMPIterationSpaceChecker::BuildNumIterations(
3908  Scope *S, const bool LimitedType,
3909  llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const {
3910  ExprResult Diff;
3911  auto VarType = LCDecl->getType().getNonReferenceType();
3912  if (VarType->isIntegerType() || VarType->isPointerType() ||
3913  SemaRef.getLangOpts().CPlusPlus) {
3914  // Upper - Lower
3915  auto *UBExpr = TestIsLessOp ? UB : LB;
3916  auto *LBExpr = TestIsLessOp ? LB : UB;
3917  Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
3918  Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
3919  if (!Upper || !Lower)
3920  return nullptr;
3921 
3922  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
3923 
3924  if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) {
3925  // BuildBinOp already emitted error, this one is to point user to upper
3926  // and lower bound, and to tell what is passed to 'operator-'.
3927  SemaRef.Diag(Upper->getLocStart(), diag::err_omp_loop_diff_cxx)
3928  << Upper->getSourceRange() << Lower->getSourceRange();
3929  return nullptr;
3930  }
3931  }
3932 
3933  if (!Diff.isUsable())
3934  return nullptr;
3935 
3936  // Upper - Lower [- 1]
3937  if (TestIsStrictOp)
3938  Diff = SemaRef.BuildBinOp(
3939  S, DefaultLoc, BO_Sub, Diff.get(),
3940  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
3941  if (!Diff.isUsable())
3942  return nullptr;
3943 
3944  // Upper - Lower [- 1] + Step
3945  auto NewStep = tryBuildCapture(SemaRef, Step, Captures);
3946  if (!NewStep.isUsable())
3947  return nullptr;
3948  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
3949  if (!Diff.isUsable())
3950  return nullptr;
3951 
3952  // Parentheses (for dumping/debugging purposes only).
3953  Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
3954  if (!Diff.isUsable())
3955  return nullptr;
3956 
3957  // (Upper - Lower [- 1] + Step) / Step
3958  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
3959  if (!Diff.isUsable())
3960  return nullptr;
3961 
3962  // OpenMP runtime requires 32-bit or 64-bit loop variables.
3963  QualType Type = Diff.get()->getType();
3964  auto &C = SemaRef.Context;
3965  bool UseVarType = VarType->hasIntegerRepresentation() &&
3966  C.getTypeSize(Type) > C.getTypeSize(VarType);
3967  if (!Type->isIntegerType() || UseVarType) {
3968  unsigned NewSize =
3969  UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
3970  bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
3972  Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
3973  if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
3974  Diff = SemaRef.PerformImplicitConversion(
3975  Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
3976  if (!Diff.isUsable())
3977  return nullptr;
3978  }
3979  }
3980  if (LimitedType) {
3981  unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
3982  if (NewSize != C.getTypeSize(Type)) {
3983  if (NewSize < C.getTypeSize(Type)) {
3984  assert(NewSize == 64 && "incorrect loop var size");
3985  SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
3986  << InitSrcRange << ConditionSrcRange;
3987  }
3988  QualType NewType = C.getIntTypeForBitwidth(
3989  NewSize, Type->hasSignedIntegerRepresentation() ||
3990  C.getTypeSize(Type) < NewSize);
3991  if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
3992  Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
3993  Sema::AA_Converting, true);
3994  if (!Diff.isUsable())
3995  return nullptr;
3996  }
3997  }
3998  }
3999 
4000  return Diff.get();
4001 }
4002 
4003 Expr *OpenMPIterationSpaceChecker::BuildPreCond(
4004  Scope *S, Expr *Cond,
4005  llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const {
4006  // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
4007  bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
4008  SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
4009 
4010  auto NewLB = tryBuildCapture(SemaRef, LB, Captures);
4011  auto NewUB = tryBuildCapture(SemaRef, UB, Captures);
4012  if (!NewLB.isUsable() || !NewUB.isUsable())
4013  return nullptr;
4014 
4015  auto CondExpr = SemaRef.BuildBinOp(
4016  S, DefaultLoc, TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE)
4017  : (TestIsStrictOp ? BO_GT : BO_GE),
4018  NewLB.get(), NewUB.get());
4019  if (CondExpr.isUsable()) {
4020  if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
4021  SemaRef.Context.BoolTy))
4022  CondExpr = SemaRef.PerformImplicitConversion(
4023  CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
4024  /*AllowExplicit=*/true);
4025  }
4026  SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
4027  // Otherwise use original loop conditon and evaluate it in runtime.
4028  return CondExpr.isUsable() ? CondExpr.get() : Cond;
4029 }
4030 
4031 /// \brief Build reference expression to the counter be used for codegen.
4032 DeclRefExpr *OpenMPIterationSpaceChecker::BuildCounterVar(
4033  llvm::MapVector<Expr *, DeclRefExpr *> &Captures, DSAStackTy &DSA) const {
4034  auto *VD = dyn_cast<VarDecl>(LCDecl);
4035  if (!VD) {
4036  VD = SemaRef.IsOpenMPCapturedDecl(LCDecl);
4037  auto *Ref = buildDeclRefExpr(
4038  SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
4039  DSAStackTy::DSAVarData Data = DSA.getTopDSA(LCDecl, /*FromParent=*/false);
4040  // If the loop control decl is explicitly marked as private, do not mark it
4041  // as captured again.
4042  if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
4043  Captures.insert(std::make_pair(LCRef, Ref));
4044  return Ref;
4045  }
4046  return buildDeclRefExpr(SemaRef, VD, VD->getType().getNonReferenceType(),
4047  DefaultLoc);
4048 }
4049 
4050 Expr *OpenMPIterationSpaceChecker::BuildPrivateCounterVar() const {
4051  if (LCDecl && !LCDecl->isInvalidDecl()) {
4052  auto Type = LCDecl->getType().getNonReferenceType();
4053  auto *PrivateVar =
4054  buildVarDecl(SemaRef, DefaultLoc, Type, LCDecl->getName(),
4055  LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr);
4056  if (PrivateVar->isInvalidDecl())
4057  return nullptr;
4058  return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
4059  }
4060  return nullptr;
4061 }
4062 
4063 /// \brief Build initialization of the counter to be used for codegen.
4065 
4066 /// \brief Build step of the counter be used for codegen.
4067 Expr *OpenMPIterationSpaceChecker::BuildCounterStep() const { return Step; }
4068 
4069 /// \brief Iteration space of a single for loop.
4070 struct LoopIterationSpace final {
4071  /// \brief Condition of the loop.
4072  Expr *PreCond = nullptr;
4073  /// \brief This expression calculates the number of iterations in the loop.
4074  /// It is always possible to calculate it before starting the loop.
4075  Expr *NumIterations = nullptr;
4076  /// \brief The loop counter variable.
4077  Expr *CounterVar = nullptr;
4078  /// \brief Private loop counter variable.
4079  Expr *PrivateCounterVar = nullptr;
4080  /// \brief This is initializer for the initial value of #CounterVar.
4081  Expr *CounterInit = nullptr;
4082  /// \brief This is step for the #CounterVar used to generate its update:
4083  /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
4084  Expr *CounterStep = nullptr;
4085  /// \brief Should step be subtracted?
4086  bool Subtract = false;
4087  /// \brief Source range of the loop init.
4088  SourceRange InitSrcRange;
4089  /// \brief Source range of the loop condition.
4090  SourceRange CondSrcRange;
4091  /// \brief Source range of the loop increment.
4092  SourceRange IncSrcRange;
4093 };
4094 
4095 } // namespace
4096 
4098  assert(getLangOpts().OpenMP && "OpenMP is not active.");
4099  assert(Init && "Expected loop in canonical form.");
4100  unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
4101  if (AssociatedLoops > 0 &&
4102  isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
4103  OpenMPIterationSpaceChecker ISC(*this, ForLoc);
4104  if (!ISC.CheckInit(Init, /*EmitDiags=*/false)) {
4105  if (auto *D = ISC.GetLoopDecl()) {
4106  auto *VD = dyn_cast<VarDecl>(D);
4107  if (!VD) {
4108  if (auto *Private = IsOpenMPCapturedDecl(D))
4109  VD = Private;
4110  else {
4111  auto *Ref = buildCapture(*this, D, ISC.GetLoopDeclRefExpr(),
4112  /*WithInit=*/false);
4113  VD = cast<VarDecl>(Ref->getDecl());
4114  }
4115  }
4116  DSAStack->addLoopControlVariable(D, VD);
4117  }
4118  }
4119  DSAStack->setAssociatedLoops(AssociatedLoops - 1);
4120  }
4121 }
4122 
4123 /// \brief Called on a for stmt to check and extract its iteration space
4124 /// for further processing (such as collapsing).
4126  OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
4127  unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
4128  Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr,
4129  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA,
4130  LoopIterationSpace &ResultIterSpace,
4131  llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
4132  // OpenMP [2.6, Canonical Loop Form]
4133  // for (init-expr; test-expr; incr-expr) structured-block
4134  auto *For = dyn_cast_or_null<ForStmt>(S);
4135  if (!For) {
4136  SemaRef.Diag(S->getLocStart(), diag::err_omp_not_for)
4137  << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
4138  << getOpenMPDirectiveName(DKind) << NestedLoopCount
4139  << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
4140  if (NestedLoopCount > 1) {
4141  if (CollapseLoopCountExpr && OrderedLoopCountExpr)
4142  SemaRef.Diag(DSA.getConstructLoc(),
4143  diag::note_omp_collapse_ordered_expr)
4144  << 2 << CollapseLoopCountExpr->getSourceRange()
4145  << OrderedLoopCountExpr->getSourceRange();
4146  else if (CollapseLoopCountExpr)
4147  SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
4148  diag::note_omp_collapse_ordered_expr)
4149  << 0 << CollapseLoopCountExpr->getSourceRange();
4150  else
4151  SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
4152  diag::note_omp_collapse_ordered_expr)
4153  << 1 << OrderedLoopCountExpr->getSourceRange();
4154  }
4155  return true;
4156  }
4157  assert(For->getBody());
4158 
4159  OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc());
4160 
4161  // Check init.
4162  auto Init = For->getInit();
4163  if (ISC.CheckInit(Init))
4164  return true;
4165 
4166  bool HasErrors = false;
4167 
4168  // Check loop variable's type.
4169  if (auto *LCDecl = ISC.GetLoopDecl()) {
4170  auto *LoopDeclRefExpr = ISC.GetLoopDeclRefExpr();
4171 
4172  // OpenMP [2.6, Canonical Loop Form]
4173  // Var is one of the following:
4174  // A variable of signed or unsigned integer type.
4175  // For C++, a variable of a random access iterator type.
4176  // For C, a variable of a pointer type.
4177  auto VarType = LCDecl->getType().getNonReferenceType();
4178  if (!VarType->isDependentType() && !VarType->isIntegerType() &&
4179  !VarType->isPointerType() &&
4180  !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
4181  SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_variable_type)
4182  << SemaRef.getLangOpts().CPlusPlus;
4183  HasErrors = true;
4184  }
4185 
4186  // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
4187  // a Construct
4188  // The loop iteration variable(s) in the associated for-loop(s) of a for or
4189  // parallel for construct is (are) private.
4190  // The loop iteration variable in the associated for-loop of a simd
4191  // construct with just one associated for-loop is linear with a
4192  // constant-linear-step that is the increment of the associated for-loop.
4193  // Exclude loop var from the list of variables with implicitly defined data
4194  // sharing attributes.
4195  VarsWithImplicitDSA.erase(LCDecl);
4196 
4197  // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
4198  // in a Construct, C/C++].
4199  // The loop iteration variable in the associated for-loop of a simd
4200  // construct with just one associated for-loop may be listed in a linear
4201  // clause with a constant-linear-step that is the increment of the
4202  // associated for-loop.
4203  // The loop iteration variable(s) in the associated for-loop(s) of a for or
4204  // parallel for construct may be listed in a private or lastprivate clause.
4205  DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl, false);
4206  // If LoopVarRefExpr is nullptr it means the corresponding loop variable is
4207  // declared in the loop and it is predetermined as a private.
4208  auto PredeterminedCKind =
4209  isOpenMPSimdDirective(DKind)
4210  ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate)
4211  : OMPC_private;
4212  if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
4213  DVar.CKind != PredeterminedCKind) ||
4214  ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
4215  isOpenMPDistributeDirective(DKind)) &&
4216  !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
4217  DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
4218  (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
4219  SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa)
4220  << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind)
4221  << getOpenMPClauseName(PredeterminedCKind);
4222  if (DVar.RefExpr == nullptr)
4223  DVar.CKind = PredeterminedCKind;
4224  ReportOriginalDSA(SemaRef, &DSA, LCDecl, DVar, /*IsLoopIterVar=*/true);
4225  HasErrors = true;
4226  } else if (LoopDeclRefExpr != nullptr) {
4227  // Make the loop iteration variable private (for worksharing constructs),
4228  // linear (for simd directives with the only one associated loop) or
4229  // lastprivate (for simd directives with several collapsed or ordered
4230  // loops).
4231  if (DVar.CKind == OMPC_unknown)
4232  DVar = DSA.hasDSA(LCDecl, isOpenMPPrivate,
4233  [](OpenMPDirectiveKind) -> bool { return true; },
4234  /*FromParent=*/false);
4235  DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind);
4236  }
4237 
4238  assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
4239 
4240  // Check test-expr.
4241  HasErrors |= ISC.CheckCond(For->getCond());
4242 
4243  // Check incr-expr.
4244  HasErrors |= ISC.CheckInc(For->getInc());
4245  }
4246 
4247  if (ISC.Dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
4248  return HasErrors;
4249 
4250  // Build the loop's iteration space representation.
4251  ResultIterSpace.PreCond =
4252  ISC.BuildPreCond(DSA.getCurScope(), For->getCond(), Captures);
4253  ResultIterSpace.NumIterations = ISC.BuildNumIterations(
4254  DSA.getCurScope(),
4255  (isOpenMPWorksharingDirective(DKind) ||
4257  Captures);
4258  ResultIterSpace.CounterVar = ISC.BuildCounterVar(Captures, DSA);
4259  ResultIterSpace.PrivateCounterVar = ISC.BuildPrivateCounterVar();
4260  ResultIterSpace.CounterInit = ISC.BuildCounterInit();
4261  ResultIterSpace.CounterStep = ISC.BuildCounterStep();
4262  ResultIterSpace.InitSrcRange = ISC.GetInitSrcRange();
4263  ResultIterSpace.CondSrcRange = ISC.GetConditionSrcRange();
4264  ResultIterSpace.IncSrcRange = ISC.GetIncrementSrcRange();
4265  ResultIterSpace.Subtract = ISC.ShouldSubtractStep();
4266 
4267  HasErrors |= (ResultIterSpace.PreCond == nullptr ||
4268  ResultIterSpace.NumIterations == nullptr ||
4269  ResultIterSpace.CounterVar == nullptr ||
4270  ResultIterSpace.PrivateCounterVar == nullptr ||
4271  ResultIterSpace.CounterInit == nullptr ||
4272  ResultIterSpace.CounterStep == nullptr);
4273 
4274  return HasErrors;
4275 }
4276 
4277 /// \brief Build 'VarRef = Start.
4278 static ExprResult
4280  ExprResult Start,
4281  llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
4282  // Build 'VarRef = Start.
4283  auto NewStart = tryBuildCapture(SemaRef, Start.get(), Captures);
4284  if (!NewStart.isUsable())
4285  return ExprError();
4286  if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
4287  VarRef.get()->getType())) {
4288  NewStart = SemaRef.PerformImplicitConversion(
4289  NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
4290  /*AllowExplicit=*/true);
4291  if (!NewStart.isUsable())
4292  return ExprError();
4293  }
4294 
4295  auto Init =
4296  SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
4297  return Init;
4298 }
4299 
4300 /// \brief Build 'VarRef = Start + Iter * Step'.
4301 static ExprResult
4303  ExprResult VarRef, ExprResult Start, ExprResult Iter,
4304  ExprResult Step, bool Subtract,
4305  llvm::MapVector<Expr *, DeclRefExpr *> *Captures = nullptr) {
4306  // Add parentheses (for debugging purposes only).
4307  Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
4308  if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
4309  !Step.isUsable())
4310  return ExprError();
4311 
4312  ExprResult NewStep = Step;
4313  if (Captures)
4314  NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
4315  if (NewStep.isInvalid())
4316  return ExprError();
4317  ExprResult Update =
4318  SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
4319  if (!Update.isUsable())
4320  return ExprError();
4321 
4322  // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
4323  // 'VarRef = Start (+|-) Iter * Step'.
4324  ExprResult NewStart = Start;
4325  if (Captures)
4326  NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
4327  if (NewStart.isInvalid())
4328  return ExprError();
4329 
4330  // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
4331  ExprResult SavedUpdate = Update;
4332  ExprResult UpdateVal;
4333  if (VarRef.get()->getType()->isOverloadableType() ||
4334  NewStart.get()->getType()->isOverloadableType() ||
4335  Update.get()->getType()->isOverloadableType()) {
4336  bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
4337  SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
4338  Update =
4339  SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
4340  if (Update.isUsable()) {
4341  UpdateVal =
4342  SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
4343  VarRef.get(), SavedUpdate.get());
4344  if (UpdateVal.isUsable()) {
4345  Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
4346  UpdateVal.get());
4347  }
4348  }
4349  SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
4350  }
4351 
4352  // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
4353  if (!Update.isUsable() || !UpdateVal.isUsable()) {
4354  Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
4355  NewStart.get(), SavedUpdate.get());
4356  if (!Update.isUsable())
4357  return ExprError();
4358 
4359  if (!SemaRef.Context.hasSameType(Update.get()->getType(),
4360  VarRef.get()->getType())) {
4361  Update = SemaRef.PerformImplicitConversion(
4362  Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
4363  if (!Update.isUsable())
4364  return ExprError();
4365  }
4366 
4367  Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
4368  }
4369  return Update;
4370 }
4371 
4372 /// \brief Convert integer expression \a E to make it have at least \a Bits
4373 /// bits.
4374 static ExprResult WidenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
4375  if (E == nullptr)
4376  return ExprError();
4377  auto &C = SemaRef.Context;
4378  QualType OldType = E->getType();
4379  unsigned HasBits = C.getTypeSize(OldType);
4380  if (HasBits >= Bits)
4381  return ExprResult(E);
4382  // OK to convert to signed, because new type has more bits than old.
4383  QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
4384  return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
4385  true);
4386 }
4387 
4388 /// \brief Check if the given expression \a E is a constant integer that fits
4389 /// into \a Bits bits.
4390 static bool FitsInto(unsigned Bits, bool Signed, Expr *E, Sema &SemaRef) {
4391  if (E == nullptr)
4392  return false;
4393  llvm::APSInt Result;
4394  if (E->isIntegerConstantExpr(Result, SemaRef.Context))
4395  return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits);
4396  return false;
4397 }
4398 
4399 /// Build preinits statement for the given declarations.
4400 static Stmt *buildPreInits(ASTContext &Context,
4401  MutableArrayRef<Decl *> PreInits) {
4402  if (!PreInits.empty()) {
4403  return new (Context) DeclStmt(
4404  DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
4406  }
4407  return nullptr;
4408 }
4409 
4410 /// Build preinits statement for the given declarations.
4411 static Stmt *
4413  const llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
4414  if (!Captures.empty()) {
4415  SmallVector<Decl *, 16> PreInits;
4416  for (auto &Pair : Captures)
4417  PreInits.push_back(Pair.second->getDecl());
4418  return buildPreInits(Context, PreInits);
4419  }
4420  return nullptr;
4421 }
4422 
4423 /// Build postupdate expression for the given list of postupdates expressions.
4424 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
4425  Expr *PostUpdate = nullptr;
4426  if (!PostUpdates.empty()) {
4427  for (auto *E : PostUpdates) {
4428  Expr *ConvE = S.BuildCStyleCastExpr(
4429  E->getExprLoc(),
4431  E->getExprLoc(), E)
4432  .get();
4433  PostUpdate = PostUpdate
4434  ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
4435  PostUpdate, ConvE)
4436  .get()
4437  : ConvE;
4438  }
4439  }
4440  return PostUpdate;
4441 }
4442 
4443 /// \brief Called on a for stmt to check itself and nested loops (if any).
4444 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
4445 /// number of collapsed loops otherwise.
4446 static unsigned
4447 CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
4448  Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
4449  DSAStackTy &DSA,
4450  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA,
4452  unsigned NestedLoopCount = 1;
4453  if (CollapseLoopCountExpr) {
4454  // Found 'collapse' clause - calculate collapse number.
4455  llvm::APSInt Result;
4456  if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext()))
4457  NestedLoopCount = Result.getLimitedValue();
4458  }
4459  if (OrderedLoopCountExpr) {
4460  // Found 'ordered' clause - calculate collapse number.
4461  llvm::APSInt Result;
4462  if (OrderedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
4463  if (Result.getLimitedValue() < NestedLoopCount) {
4464  SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
4465  diag::err_omp_wrong_ordered_loop_count)
4466  << OrderedLoopCountExpr->getSourceRange();
4467  SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
4468  diag::note_collapse_loop_count)
4469  << CollapseLoopCountExpr->getSourceRange();
4470  }
4471  NestedLoopCount = Result.getLimitedValue();
4472  }
4473  }
4474  // This is helper routine for loop directives (e.g., 'for', 'simd',
4475  // 'for simd', etc.).
4476  llvm::MapVector<Expr *, DeclRefExpr *> Captures;
4478  IterSpaces.resize(NestedLoopCount);
4479  Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true);
4480  for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
4481  if (CheckOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA, Cnt,
4482  NestedLoopCount, CollapseLoopCountExpr,
4483  OrderedLoopCountExpr, VarsWithImplicitDSA,
4484  IterSpaces[Cnt], Captures))
4485  return 0;
4486  // Move on to the next nested for loop, or to the loop body.
4487  // OpenMP [2.8.1, simd construct, Restrictions]
4488  // All loops associated with the construct must be perfectly nested; that
4489  // is, there must be no intervening code nor any OpenMP directive between
4490  // any two loops.
4491  CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers();
4492  }
4493 
4494  Built.clear(/* size */ NestedLoopCount);
4495 
4496  if (SemaRef.CurContext->isDependentContext())
4497  return NestedLoopCount;
4498 
4499  // An example of what is generated for the following code:
4500  //
4501  // #pragma omp simd collapse(2) ordered(2)
4502  // for (i = 0; i < NI; ++i)
4503  // for (k = 0; k < NK; ++k)
4504  // for (j = J0; j < NJ; j+=2) {
4505  // <loop body>
4506  // }
4507  //
4508  // We generate the code below.
4509  // Note: the loop body may be outlined in CodeGen.
4510  // Note: some counters may be C++ classes, operator- is used to find number of
4511  // iterations and operator+= to calculate counter value.
4512  // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
4513  // or i64 is currently supported).
4514  //
4515  // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
4516  // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
4517  // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
4518  // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
4519  // // similar updates for vars in clauses (e.g. 'linear')
4520  // <loop body (using local i and j)>
4521  // }
4522  // i = NI; // assign final values of counters
4523  // j = NJ;
4524  //
4525 
4526  // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
4527  // the iteration counts of the collapsed for loops.
4528  // Precondition tests if there is at least one iteration (all conditions are
4529  // true).
4530  auto PreCond = ExprResult(IterSpaces[0].PreCond);
4531  auto N0 = IterSpaces[0].NumIterations;
4532  ExprResult LastIteration32 = WidenIterationCount(
4533  32 /* Bits */, SemaRef
4534  .PerformImplicitConversion(
4535  N0->IgnoreImpCasts(), N0->getType(),
4536  Sema::AA_Converting, /*AllowExplicit=*/true)
4537  .get(),
4538  SemaRef);
4539  ExprResult LastIteration64 = WidenIterationCount(
4540  64 /* Bits */, SemaRef
4541  .PerformImplicitConversion(
4542  N0->IgnoreImpCasts(), N0->getType(),
4543  Sema::AA_Converting, /*AllowExplicit=*/true)
4544  .get(),
4545  SemaRef);
4546 
4547  if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
4548  return NestedLoopCount;
4549 
4550  auto &C = SemaRef.Context;
4551  bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
4552 
4553  Scope *CurScope = DSA.getCurScope();
4554  for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
4555  if (PreCond.isUsable()) {
4556  PreCond =
4557  SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
4558  PreCond.get(), IterSpaces[Cnt].PreCond);
4559  }
4560  auto N = IterSpaces[Cnt].NumIterations;
4561  SourceLocation Loc = N->getExprLoc();
4562  AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
4563  if (LastIteration32.isUsable())
4564  LastIteration32 = SemaRef.BuildBinOp(
4565  CurScope, Loc, BO_Mul, LastIteration32.get(),
4566  SemaRef
4567  .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
4569  /*AllowExplicit=*/true)
4570  .get());
4571  if (LastIteration64.isUsable())
4572  LastIteration64 = SemaRef.BuildBinOp(
4573  CurScope, Loc, BO_Mul, LastIteration64.get(),
4574  SemaRef
4575  .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
4577  /*AllowExplicit=*/true)
4578  .get());
4579  }
4580 
4581  // Choose either the 32-bit or 64-bit version.
4582  ExprResult LastIteration = LastIteration64;
4583  if (LastIteration32.isUsable() &&
4584  C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
4585  (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
4586  FitsInto(
4587  32 /* Bits */,
4588  LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
4589  LastIteration64.get(), SemaRef)))
4590  LastIteration = LastIteration32;
4591  QualType VType = LastIteration.get()->getType();
4592  QualType RealVType = VType;
4593  QualType StrideVType = VType;
4594  if (isOpenMPTaskLoopDirective(DKind)) {
4595  VType =
4596  SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
4597  StrideVType =
4598  SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
4599  }
4600 
4601  if (!LastIteration.isUsable())
4602  return 0;
4603 
4604  // Save the number of iterations.
4605  ExprResult NumIterations = LastIteration;
4606  {
4607  LastIteration = SemaRef.BuildBinOp(
4608  CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
4609  LastIteration.get(),
4610  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
4611  if (!LastIteration.isUsable())
4612  return 0;
4613  }
4614 
4615  // Calculate the last iteration number beforehand instead of doing this on
4616  // each iteration. Do not do this if the number of iterations may be kfold-ed.
4617  llvm::APSInt Result;
4618  bool IsConstant =
4619  LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context);
4620  ExprResult CalcLastIteration;
4621  if (!IsConstant) {
4622  ExprResult SaveRef =
4623  tryBuildCapture(SemaRef, LastIteration.get(), Captures);
4624  LastIteration = SaveRef;
4625 
4626  // Prepare SaveRef + 1.
4627  NumIterations = SemaRef.BuildBinOp(
4628  CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
4629  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
4630  if (!NumIterations.isUsable())
4631  return 0;
4632  }
4633 
4634  SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
4635 
4636  // Build variables passed into runtime, necessary for worksharing directives.
4637  ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
4639  isOpenMPDistributeDirective(DKind)) {
4640  // Lower bound variable, initialized with zero.
4641  VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
4642  LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
4643  SemaRef.AddInitializerToDecl(LBDecl,
4644  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
4645  /*DirectInit*/ false);
4646 
4647  // Upper bound variable, initialized with last iteration number.
4648  VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
4649  UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
4650  SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
4651  /*DirectInit*/ false);
4652 
4653  // A 32-bit variable-flag where runtime returns 1 for the last iteration.
4654  // This will be used to implement clause 'lastprivate'.
4655  QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
4656  VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
4657  IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
4658  SemaRef.AddInitializerToDecl(ILDecl,
4659  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
4660  /*DirectInit*/ false);
4661 
4662  // Stride variable returned by runtime (we initialize it to 1 by default).
4663  VarDecl *STDecl =
4664  buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
4665  ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
4666  SemaRef.AddInitializerToDecl(STDecl,
4667  SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
4668  /*DirectInit*/ false);
4669 
4670  // Build expression: UB = min(UB, LastIteration)
4671  // It is necessary for CodeGen of directives with static scheduling.
4672  ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
4673  UB.get(), LastIteration.get());
4674  ExprResult CondOp = SemaRef.ActOnConditionalOp(
4675  InitLoc, InitLoc, IsUBGreater.get(), LastIteration.get(), UB.get());
4676  EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
4677  CondOp.get());
4678  EUB = SemaRef.ActOnFinishFullExpr(EUB.get());
4679 
4680  // If we have a combined directive that combines 'distribute', 'for' or
4681  // 'simd' we need to be able to access the bounds of the schedule of the
4682  // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
4683  // by scheduling 'distribute' have to be passed to the schedule of 'for'.
4684  if (isOpenMPLoopBoundSharingDirective(DKind)) {
4685 
4686  // Lower bound variable, initialized with zero.
4687  VarDecl *CombLBDecl =
4688  buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
4689  CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
4690  SemaRef.AddInitializerToDecl(
4691  CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
4692  /*DirectInit*/ false);
4693 
4694  // Upper bound variable, initialized with last iteration number.
4695  VarDecl *CombUBDecl =
4696  buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
4697  CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
4698  SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
4699  /*DirectInit*/ false);
4700 
4701  ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
4702  CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
4703  ExprResult CombCondOp =
4704  SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
4705  LastIteration.get(), CombUB.get());
4706  CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
4707  CombCondOp.get());
4708  CombEUB = SemaRef.ActOnFinishFullExpr(CombEUB.get());
4709 
4710  auto *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
4711  // We expect to have at least 2 more parameters than the 'parallel'
4712  // directive does - the lower and upper bounds of the previous schedule.
4713  assert(CD->getNumParams() >= 4 &&
4714  "Unexpected number of parameters in loop combined directive");
4715 
4716  // Set the proper type for the bounds given what we learned from the
4717  // enclosed loops.
4718  auto *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
4719  auto *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
4720 
4721  // Previous lower and upper bounds are obtained from the region
4722  // parameters.
4723  PrevLB =
4724  buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
4725  PrevUB =
4726  buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
4727  }
4728  }
4729 
4730  // Build the iteration variable and its initialization before loop.
4731  ExprResult IV;
4732  ExprResult Init, CombInit;
4733  {
4734  VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
4735  IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
4736  Expr *RHS =
4737  (isOpenMPWorksharingDirective(DKind) ||
4739  ? LB.get()
4740  : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
4741  Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
4742  Init = SemaRef.ActOnFinishFullExpr(Init.get());
4743 
4744  if (isOpenMPLoopBoundSharingDirective(DKind)) {
4745  Expr *CombRHS =
4746  (isOpenMPWorksharingDirective(DKind) ||
4747  isOpenMPTaskLoopDirective(DKind) ||
4749  ? CombLB.get()
4750  : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
4751  CombInit =
4752  SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
4753  CombInit = SemaRef.ActOnFinishFullExpr(CombInit.get());
4754  }
4755  }
4756 
4757  // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops.
4758  SourceLocation CondLoc;
4759  ExprResult Cond =
4760  (isOpenMPWorksharingDirective(DKind) ||
4762  ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get())
4763  : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
4764  NumIterations.get());
4765  ExprResult CombCond;
4766  if (isOpenMPLoopBoundSharingDirective(DKind)) {
4767  CombCond =
4768  SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), CombUB.get());
4769  }
4770  // Loop increment (IV = IV + 1)
4771  SourceLocation IncLoc;
4772  ExprResult Inc =
4773  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
4774  SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
4775  if (!Inc.isUsable())
4776  return 0;
4777  Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
4778  Inc = SemaRef.ActOnFinishFullExpr(Inc.get());
4779  if (!Inc.isUsable())
4780  return 0;
4781 
4782  // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
4783  // Used for directives with static scheduling.
4784  // In combined construct, add combined version that use CombLB and CombUB
4785  // base variables for the update
4786  ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
4788  isOpenMPDistributeDirective(DKind)) {
4789  // LB + ST
4790  NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
4791  if (!NextLB.isUsable())
4792  return 0;
4793  // LB = LB + ST
4794  NextLB =
4795  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
4796  NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get());
4797  if (!NextLB.isUsable())
4798  return 0;
4799  // UB + ST
4800  NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
4801  if (!NextUB.isUsable())
4802  return 0;
4803  // UB = UB + ST
4804  NextUB =
4805  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
4806  NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get());
4807  if (!NextUB.isUsable())
4808  return 0;
4809  if (isOpenMPLoopBoundSharingDirective(DKind)) {
4810  CombNextLB =
4811  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
4812  if (!NextLB.isUsable())
4813  return 0;
4814  // LB = LB + ST
4815  CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
4816  CombNextLB.get());
4817  CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get());
4818  if (!CombNextLB.isUsable())
4819  return 0;
4820  // UB + ST
4821  CombNextUB =
4822  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
4823  if (!CombNextUB.isUsable())
4824  return 0;
4825  // UB = UB + ST
4826  CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
4827  CombNextUB.get());
4828  CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get());
4829  if (!CombNextUB.isUsable())
4830  return 0;
4831  }
4832  }
4833 
4834  // Create increment expression for distribute loop when combined in a same
4835  // directive with for as IV = IV + ST; ensure upper bound expression based
4836  // on PrevUB instead of NumIterations - used to implement 'for' when found
4837  // in combination with 'distribute', like in 'distribute parallel for'
4838  SourceLocation DistIncLoc;
4839  ExprResult DistCond, DistInc, PrevEUB;
4840  if (isOpenMPLoopBoundSharingDirective(DKind)) {
4841  DistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get());
4842  assert(DistCond.isUsable() && "distribute cond expr was not built");
4843 
4844  DistInc =
4845  SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
4846  assert(DistInc.isUsable() && "distribute inc expr was not built");
4847  DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
4848  DistInc.get());
4849  DistInc = SemaRef.ActOnFinishFullExpr(DistInc.get());
4850  assert(DistInc.isUsable() && "distribute inc expr was not built");
4851 
4852  // Build expression: UB = min(UB, prevUB) for #for in composite or combined
4853  // construct
4854  SourceLocation DistEUBLoc;
4855  ExprResult IsUBGreater =
4856  SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get());
4857  ExprResult CondOp = SemaRef.ActOnConditionalOp(
4858  DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
4859  PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
4860  CondOp.get());
4861  PrevEUB = SemaRef.ActOnFinishFullExpr(PrevEUB.get());
4862  }
4863 
4864  // Build updates and final values of the loop counters.
4865  bool HasErrors = false;
4866  Built.Counters.resize(NestedLoopCount);
4867  Built.Inits.resize(NestedLoopCount);
4868  Built.Updates.resize(NestedLoopCount);
4869  Built.Finals.resize(NestedLoopCount);
4870  SmallVector<Expr *, 4> LoopMultipliers;
4871  {
4872  ExprResult Div;
4873  // Go from inner nested loop to outer.
4874  for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) {
4875  LoopIterationSpace &IS = IterSpaces[Cnt];
4876  SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
4877  // Build: Iter = (IV / Div) % IS.NumIters
4878  // where Div is product of previous iterations' IS.NumIters.
4879  ExprResult Iter;
4880  if (Div.isUsable()) {
4881  Iter =
4882  SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, IV.get(), Div.get());
4883  } else {
4884  Iter = IV;
4885  assert((Cnt == (int)NestedLoopCount - 1) &&
4886  "unusable div expected on first iteration only");
4887  }
4888 
4889  if (Cnt != 0 && Iter.isUsable())
4890  Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.get(),
4891  IS.NumIterations);
4892  if (!Iter.isUsable()) {
4893  HasErrors = true;
4894  break;
4895  }
4896 
4897  // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
4898  auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
4899  auto *CounterVar = buildDeclRefExpr(SemaRef, VD, IS.CounterVar->getType(),
4900  IS.CounterVar->getExprLoc(),
4901  /*RefersToCapture=*/true);
4902  ExprResult Init = BuildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
4903  IS.CounterInit, Captures);
4904  if (!Init.isUsable()) {
4905  HasErrors = true;
4906  break;
4907  }
4909  SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
4910  IS.CounterStep, IS.Subtract, &Captures);
4911  if (!Update.isUsable()) {
4912  HasErrors = true;
4913  break;
4914  }
4915 
4916  // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
4918  SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit,
4919  IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures);
4920  if (!Final.isUsable()) {
4921  HasErrors = true;
4922  break;
4923  }
4924 
4925  // Build Div for the next iteration: Div <- Div * IS.NumIters
4926  if (Cnt != 0) {
4927  if (Div.isUnset())
4928  Div = IS.NumIterations;
4929  else
4930  Div = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.get(),
4931  IS.NumIterations);
4932 
4933  // Add parentheses (for debugging purposes only).
4934  if (Div.isUsable())
4935  Div = tryBuildCapture(SemaRef, Div.get(), Captures);
4936  if (!Div.isUsable()) {
4937  HasErrors = true;
4938  break;
4939  }
4940  LoopMultipliers.push_back(Div.get());
4941  }
4942  if (!Update.isUsable() || !Final.isUsable()) {
4943  HasErrors = true;
4944  break;
4945  }
4946  // Save results
4947  Built.Counters[Cnt] = IS.CounterVar;
4948  Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
4949  Built.Inits[Cnt] = Init.get();
4950  Built.Updates[Cnt] = Update.get();
4951  Built.Finals[Cnt] = Final.get();
4952  }
4953  }
4954 
4955  if (HasErrors)
4956  return 0;
4957 
4958  // Save results
4959  Built.IterationVarRef = IV.get();
4960  Built.LastIteration = LastIteration.get();
4961  Built.NumIterations = NumIterations.get();
4962  Built.CalcLastIteration =
4963  SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get();
4964  Built.PreCond = PreCond.get();
4965  Built.PreInits = buildPreInits(C, Captures);
4966  Built.Cond = Cond.get();
4967  Built.Init = Init.get();
4968  Built.Inc = Inc.get();
4969  Built.LB = LB.get();
4970  Built.UB = UB.get();
4971  Built.IL = IL.get();
4972  Built.ST = ST.get();
4973  Built.EUB = EUB.get();
4974  Built.NLB = NextLB.get();
4975  Built.NUB = NextUB.get();
4976  Built.PrevLB = PrevLB.get();
4977  Built.PrevUB = PrevUB.get();
4978  Built.DistInc = DistInc.get();
4979  Built.PrevEUB = PrevEUB.get();
4980  Built.DistCombinedFields.LB = CombLB.get();
4981  Built.DistCombinedFields.UB = CombUB.get();
4982  Built.DistCombinedFields.EUB = CombEUB.get();
4983  Built.DistCombinedFields.Init = CombInit.get();
4984  Built.DistCombinedFields.Cond = CombCond.get();
4985  Built.DistCombinedFields.NLB = CombNextLB.get();
4986  Built.DistCombinedFields.NUB = CombNextUB.get();
4987 
4988  Expr *CounterVal = SemaRef.DefaultLvalueConversion(IV.get()).get();
4989  // Fill data for doacross depend clauses.
4990  for (auto Pair : DSA.getDoacrossDependClauses()) {
4991  if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
4992  Pair.first->setCounterValue(CounterVal);
4993  else {
4994  if (NestedLoopCount != Pair.second.size() ||
4995  NestedLoopCount != LoopMultipliers.size() + 1) {
4996  // Erroneous case - clause has some problems.
4997  Pair.first->setCounterValue(CounterVal);
4998  continue;
4999  }
5000  assert(Pair.first->getDependencyKind() == OMPC_DEPEND_sink);
5001  auto I = Pair.second.rbegin();
5002  auto IS = IterSpaces.rbegin();
5003  auto ILM = LoopMultipliers.rbegin();
5004  Expr *UpCounterVal = CounterVal;
5005  Expr *Multiplier = nullptr;
5006  for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) {
5007  if (I->first) {
5008  assert(IS->CounterStep);
5009  Expr *NormalizedOffset =
5010  SemaRef
5011  .BuildBinOp(CurScope, I->first->getExprLoc(), BO_Div,
5012  I->first, IS->CounterStep)
5013  .get();
5014  if (Multiplier) {
5015  NormalizedOffset =
5016  SemaRef
5017  .BuildBinOp(CurScope, I->first->getExprLoc(), BO_Mul,
5018  NormalizedOffset, Multiplier)
5019  .get();
5020  }
5021  assert(I->second == OO_Plus || I->second == OO_Minus);
5022  BinaryOperatorKind BOK = (I->second == OO_Plus) ? BO_Add : BO_Sub;
5023  UpCounterVal = SemaRef
5024  .BuildBinOp(CurScope, I->first->getExprLoc(), BOK,
5025  UpCounterVal, NormalizedOffset)
5026  .get();
5027  }
5028  Multiplier = *ILM;
5029  ++I;
5030  ++IS;
5031  ++ILM;
5032  }
5033  Pair.first->setCounterValue(UpCounterVal);
5034  }
5035  }
5036 
5037  return NestedLoopCount;
5038 }
5039 
5041  auto CollapseClauses =
5042  OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
5043  if (CollapseClauses.begin() != CollapseClauses.end())
5044  return (*CollapseClauses.begin())->getNumForLoops();
5045  return nullptr;
5046 }
5047 
5049  auto OrderedClauses =
5050  OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
5051  if (OrderedClauses.begin() != OrderedClauses.end())
5052  return (*OrderedClauses.begin())->getNumForLoops();
5053  return nullptr;
5054 }
5055 
5057  const ArrayRef<OMPClause *> Clauses) {
5058  OMPSafelenClause *Safelen = nullptr;
5059  OMPSimdlenClause *Simdlen = nullptr;
5060 
5061  for (auto *Clause : Clauses) {
5062  if (Clause->getClauseKind() == OMPC_safelen)
5063  Safelen = cast<OMPSafelenClause>(Clause);
5064  else if (Clause->getClauseKind() == OMPC_simdlen)
5065  Simdlen = cast<OMPSimdlenClause>(Clause);
5066  if (Safelen && Simdlen)
5067  break;
5068  }
5069 
5070  if (Simdlen && Safelen) {
5071  llvm::APSInt SimdlenRes, SafelenRes;
5072  auto SimdlenLength = Simdlen->getSimdlen();
5073  auto SafelenLength = Safelen->getSafelen();
5074  if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
5075  SimdlenLength->isInstantiationDependent() ||
5076  SimdlenLength->containsUnexpandedParameterPack())
5077  return false;
5078  if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
5079  SafelenLength->isInstantiationDependent() ||
5080  SafelenLength->containsUnexpandedParameterPack())
5081  return false;
5082  SimdlenLength->EvaluateAsInt(SimdlenRes, S.Context);
5083  SafelenLength->EvaluateAsInt(SafelenRes, S.Context);
5084  // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
5085  // If both simdlen and safelen clauses are specified, the value of the
5086  // simdlen parameter must be less than or equal to the value of the safelen
5087  // parameter.
5088  if (SimdlenRes > SafelenRes) {
5089  S.Diag(SimdlenLength->getExprLoc(),
5090  diag::err_omp_wrong_simdlen_safelen_values)
5091  << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
5092  return true;
5093  }
5094  }
5095  return false;
5096 }
5097 
5099  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5100  SourceLocation EndLoc,
5101  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5102  if (!AStmt)
5103  return StmtError();
5104 
5105  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5107  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5108  // define the nested loops number.
5109  unsigned NestedLoopCount = CheckOpenMPLoop(
5110  OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
5111  AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
5112  if (NestedLoopCount == 0)
5113  return StmtError();
5114 
5115  assert((CurContext->isDependentContext() || B.builtAll()) &&
5116  "omp simd loop exprs were not built");
5117 
5118  if (!CurContext->isDependentContext()) {
5119  // Finalize the clauses that need pre-built expressions for CodeGen.
5120  for (auto C : Clauses) {
5121  if (auto *LC = dyn_cast<OMPLinearClause>(C))
5122  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5123  B.NumIterations, *this, CurScope,
5124  DSAStack))
5125  return StmtError();
5126  }
5127  }
5128 
5129  if (checkSimdlenSafelenSpecified(*this, Clauses))
5130  return StmtError();
5131 
5132  getCurFunction()->setHasBranchProtectedScope();
5133  return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5134  Clauses, AStmt, B);
5135 }
5136 
5138  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5139  SourceLocation EndLoc,
5140  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5141  if (!AStmt)
5142  return StmtError();
5143 
5144  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5146  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5147  // define the nested loops number.
5148  unsigned NestedLoopCount = CheckOpenMPLoop(
5149  OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
5150  AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
5151  if (NestedLoopCount == 0)
5152  return StmtError();
5153 
5154  assert((CurContext->isDependentContext() || B.builtAll()) &&
5155  "omp for loop exprs were not built");
5156 
5157  if (!CurContext->isDependentContext()) {
5158  // Finalize the clauses that need pre-built expressions for CodeGen.
5159  for (auto C : Clauses) {
5160  if (auto *LC = dyn_cast<OMPLinearClause>(C))
5161  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5162  B.NumIterations, *this, CurScope,
5163  DSAStack))
5164  return StmtError();
5165  }
5166  }
5167 
5168  getCurFunction()->setHasBranchProtectedScope();
5169  return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5170  Clauses, AStmt, B, DSAStack->isCancelRegion());
5171 }
5172 
5174  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5175  SourceLocation EndLoc,
5176  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5177  if (!AStmt)
5178  return StmtError();
5179 
5180  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5182  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5183  // define the nested loops number.
5184  unsigned NestedLoopCount =
5185  CheckOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
5186  getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
5187  VarsWithImplicitDSA, B);
5188  if (NestedLoopCount == 0)
5189  return StmtError();
5190 
5191  assert((CurContext->isDependentContext() || B.builtAll()) &&
5192  "omp for simd loop exprs were not built");
5193 
5194  if (!CurContext->isDependentContext()) {
5195  // Finalize the clauses that need pre-built expressions for CodeGen.
5196  for (auto C : Clauses) {
5197  if (auto *LC = dyn_cast<OMPLinearClause>(C))
5198  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5199  B.NumIterations, *this, CurScope,
5200  DSAStack))
5201  return StmtError();
5202  }
5203  }
5204 
5205  if (checkSimdlenSafelenSpecified(*this, Clauses))
5206  return StmtError();
5207 
5208  getCurFunction()->setHasBranchProtectedScope();
5209  return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5210  Clauses, AStmt, B);
5211 }
5212 
5214  Stmt *AStmt,
5215  SourceLocation StartLoc,
5216  SourceLocation EndLoc) {
5217  if (!AStmt)
5218  return StmtError();
5219 
5220  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5221  auto BaseStmt = AStmt;
5222  while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
5223  BaseStmt = CS->getCapturedStmt();
5224  if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
5225  auto S = C->children();
5226  if (S.begin() == S.end())
5227  return StmtError();
5228  // All associated statements must be '#pragma omp section' except for
5229  // the first one.
5230  for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
5231  if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
5232  if (SectionStmt)
5233  Diag(SectionStmt->getLocStart(),
5234  diag::err_omp_sections_substmt_not_section);
5235  return StmtError();
5236  }
5237  cast<OMPSectionDirective>(SectionStmt)
5238  ->setHasCancel(DSAStack->isCancelRegion());
5239  }
5240  } else {
5241  Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt);
5242  return StmtError();
5243  }
5244 
5245  getCurFunction()->setHasBranchProtectedScope();
5246 
5247  return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
5248  DSAStack->isCancelRegion());
5249 }
5250 
5252  SourceLocation StartLoc,
5253  SourceLocation EndLoc) {
5254  if (!AStmt)
5255  return StmtError();
5256 
5257  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5258 
5259  getCurFunction()->setHasBranchProtectedScope();
5260  DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
5261 
5262  return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
5263  DSAStack->isCancelRegion());
5264 }
5265 
5267  Stmt *AStmt,
5268  SourceLocation StartLoc,
5269  SourceLocation EndLoc) {
5270  if (!AStmt)
5271  return StmtError();
5272 
5273  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5274 
5275  getCurFunction()->setHasBranchProtectedScope();
5276 
5277  // OpenMP [2.7.3, single Construct, Restrictions]
5278  // The copyprivate clause must not be used with the nowait clause.
5279  OMPClause *Nowait = nullptr;
5280  OMPClause *Copyprivate = nullptr;
5281  for (auto *Clause : Clauses) {
5282  if (Clause->getClauseKind() == OMPC_nowait)
5283  Nowait = Clause;
5284  else if (Clause->getClauseKind() == OMPC_copyprivate)
5285  Copyprivate = Clause;
5286  if (Copyprivate && Nowait) {
5287  Diag(Copyprivate->getLocStart(),
5288  diag::err_omp_single_copyprivate_with_nowait);
5289  Diag(Nowait->getLocStart(), diag::note_omp_nowait_clause_here);
5290  return StmtError();
5291  }
5292  }
5293 
5294  return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
5295 }
5296 
5298  SourceLocation StartLoc,
5299  SourceLocation EndLoc) {
5300  if (!AStmt)
5301  return StmtError();
5302 
5303  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5304 
5305  getCurFunction()->setHasBranchProtectedScope();
5306 
5307  return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
5308 }
5309 
5311  const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
5312  Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
5313  if (!AStmt)
5314  return StmtError();
5315 
5316  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5317 
5318  bool ErrorFound = false;
5319  llvm::APSInt Hint;
5320  SourceLocation HintLoc;
5321  bool DependentHint = false;
5322  for (auto *C : Clauses) {
5323  if (C->getClauseKind() == OMPC_hint) {
5324  if (!DirName.getName()) {
5325  Diag(C->getLocStart(), diag::err_omp_hint_clause_no_name);
5326  ErrorFound = true;
5327  }
5328  Expr *E = cast<OMPHintClause>(C)->getHint();
5329  if (E->isTypeDependent() || E->isValueDependent() ||
5331  DependentHint = true;
5332  else {
5333  Hint = E->EvaluateKnownConstInt(Context);
5334  HintLoc = C->getLocStart();
5335  }
5336  }
5337  }
5338  if (ErrorFound)
5339  return StmtError();
5340  auto Pair = DSAStack->getCriticalWithHint(DirName);
5341  if (Pair.first && DirName.getName() && !DependentHint) {
5342  if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
5343  Diag(StartLoc, diag::err_omp_critical_with_hint);
5344  if (HintLoc.isValid()) {
5345  Diag(HintLoc, diag::note_omp_critical_hint_here)
5346  << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false);
5347  } else
5348  Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
5349  if (auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
5350  Diag(C->getLocStart(), diag::note_omp_critical_hint_here)
5351  << 1
5352  << C->getHint()->EvaluateKnownConstInt(Context).toString(
5353  /*Radix=*/10, /*Signed=*/false);
5354  } else
5355  Diag(Pair.first->getLocStart(), diag::note_omp_critical_no_hint) << 1;
5356  }
5357  }
5358 
5359  getCurFunction()->setHasBranchProtectedScope();
5360 
5361  auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
5362  Clauses, AStmt);
5363  if (!Pair.first && DirName.getName() && !DependentHint)
5364  DSAStack->addCriticalWithHint(Dir, Hint);
5365  return Dir;
5366 }
5367 
5369  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5370  SourceLocation EndLoc,
5371  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5372  if (!AStmt)
5373  return StmtError();
5374 
5375  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
5376  // 1.2.2 OpenMP Language Terminology
5377  // Structured block - An executable statement with a single entry at the
5378  // top and a single exit at the bottom.
5379  // The point of exit cannot be a branch out of the structured block.
5380  // longjmp() and throw() must not violate the entry/exit criteria.
5381  CS->getCapturedDecl()->setNothrow();
5382 
5384  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5385  // define the nested loops number.
5386  unsigned NestedLoopCount =
5387  CheckOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
5388  getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
5389  VarsWithImplicitDSA, B);
5390  if (NestedLoopCount == 0)
5391  return StmtError();
5392 
5393  assert((CurContext->isDependentContext() || B.builtAll()) &&
5394  "omp parallel for loop exprs were not built");
5395 
5396  if (!CurContext->isDependentContext()) {
5397  // Finalize the clauses that need pre-built expressions for CodeGen.
5398  for (auto C : Clauses) {
5399  if (auto *LC = dyn_cast<OMPLinearClause>(C))
5400  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5401  B.NumIterations, *this, CurScope,
5402  DSAStack))
5403  return StmtError();
5404  }
5405  }
5406 
5407  getCurFunction()->setHasBranchProtectedScope();
5408  return OMPParallelForDirective::Create(Context, StartLoc, EndLoc,
5409  NestedLoopCount, Clauses, AStmt, B,
5410  DSAStack->isCancelRegion());
5411 }
5412 
5414  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5415  SourceLocation EndLoc,
5416  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5417  if (!AStmt)
5418  return StmtError();
5419 
5420  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
5421  // 1.2.2 OpenMP Language Terminology
5422  // Structured block - An executable statement with a single entry at the
5423  // top and a single exit at the bottom.
5424  // The point of exit cannot be a branch out of the structured block.
5425  // longjmp() and throw() must not violate the entry/exit criteria.
5426  CS->getCapturedDecl()->setNothrow();
5427 
5429  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5430  // define the nested loops number.
5431  unsigned NestedLoopCount =
5432  CheckOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
5433  getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
5434  VarsWithImplicitDSA, B);
5435  if (NestedLoopCount == 0)
5436  return StmtError();
5437 
5438  if (!CurContext->isDependentContext()) {
5439  // Finalize the clauses that need pre-built expressions for CodeGen.
5440  for (auto C : Clauses) {
5441  if (auto *LC = dyn_cast<OMPLinearClause>(C))
5442  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5443  B.NumIterations, *this, CurScope,
5444  DSAStack))
5445  return StmtError();
5446  }
5447  }
5448 
5449  if (checkSimdlenSafelenSpecified(*this, Clauses))
5450  return StmtError();
5451 
5452  getCurFunction()->setHasBranchProtectedScope();
5454  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
5455 }
5456 
5457 StmtResult
5459  Stmt *AStmt, SourceLocation StartLoc,
5460  SourceLocation EndLoc) {
5461  if (!AStmt)
5462  return StmtError();
5463 
5464  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5465  auto BaseStmt = AStmt;
5466  while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
5467  BaseStmt = CS->getCapturedStmt();
5468  if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
5469  auto S = C->children();
5470  if (S.begin() == S.end())
5471  return StmtError();
5472  // All associated statements must be '#pragma omp section' except for
5473  // the first one.
5474  for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
5475  if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
5476  if (SectionStmt)
5477  Diag(SectionStmt->getLocStart(),
5478  diag::err_omp_parallel_sections_substmt_not_section);
5479  return StmtError();
5480  }
5481  cast<OMPSectionDirective>(SectionStmt)
5482  ->setHasCancel(DSAStack->isCancelRegion());
5483  }
5484  } else {
5485  Diag(AStmt->getLocStart(),
5486  diag::err_omp_parallel_sections_not_compound_stmt);
5487  return StmtError();
5488  }
5489 
5490  getCurFunction()->setHasBranchProtectedScope();
5491 
5493  Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion());
5494 }
5495 
5497  Stmt *AStmt, SourceLocation StartLoc,
5498  SourceLocation EndLoc) {
5499  if (!AStmt)
5500  return StmtError();
5501 
5502  auto *CS = cast<CapturedStmt>(AStmt);
5503  // 1.2.2 OpenMP Language Terminology
5504  // Structured block - An executable statement with a single entry at the
5505  // top and a single exit at the bottom.
5506  // The point of exit cannot be a branch out of the structured block.
5507  // longjmp() and throw() must not violate the entry/exit criteria.
5508  CS->getCapturedDecl()->setNothrow();
5509 
5510  getCurFunction()->setHasBranchProtectedScope();
5511 
5512  return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
5513  DSAStack->isCancelRegion());
5514 }
5515 
5517  SourceLocation EndLoc) {
5518  return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
5519 }
5520 
5522  SourceLocation EndLoc) {
5523  return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
5524 }
5525 
5527  SourceLocation EndLoc) {
5528  return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
5529 }
5530 
5532  Stmt *AStmt,
5533  SourceLocation StartLoc,
5534  SourceLocation EndLoc) {
5535  if (!AStmt)
5536  return StmtError();
5537 
5538  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5539 
5540  getCurFunction()->setHasBranchProtectedScope();
5541 
5542  return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
5543  AStmt,
5544  DSAStack->getTaskgroupReductionRef());
5545 }
5546 
5548  SourceLocation StartLoc,
5549  SourceLocation EndLoc) {
5550  assert(Clauses.size() <= 1 && "Extra clauses in flush directive");
5551  return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
5552 }
5553 
5555  Stmt *AStmt,
5556  SourceLocation StartLoc,
5557  SourceLocation EndLoc) {
5558  OMPClause *DependFound = nullptr;
5559  OMPClause *DependSourceClause = nullptr;
5560  OMPClause *DependSinkClause = nullptr;
5561  bool ErrorFound = false;
5562  OMPThreadsClause *TC = nullptr;
5563  OMPSIMDClause *SC = nullptr;
5564  for (auto *C : Clauses) {
5565  if (auto *DC = dyn_cast<OMPDependClause>(C)) {
5566  DependFound = C;
5567  if (DC->getDependencyKind() == OMPC_DEPEND_source) {
5568  if (DependSourceClause) {
5569  Diag(C->getLocStart(), diag::err_omp_more_one_clause)
5570  << getOpenMPDirectiveName(OMPD_ordered)
5571  << getOpenMPClauseName(OMPC_depend) << 2;
5572  ErrorFound = true;
5573  } else
5574  DependSourceClause = C;
5575  if (DependSinkClause) {
5576  Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed)
5577  << 0;
5578  ErrorFound = true;
5579  }
5580  } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
5581  if (DependSourceClause) {
5582  Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed)
5583  << 1;
5584  ErrorFound = true;
5585  }
5586  DependSinkClause = C;
5587  }
5588  } else if (C->getClauseKind() == OMPC_threads)
5589  TC = cast<OMPThreadsClause>(C);
5590  else if (C->getClauseKind() == OMPC_simd)
5591  SC = cast<OMPSIMDClause>(C);
5592  }
5593  if (!ErrorFound && !SC &&
5594  isOpenMPSimdDirective(DSAStack->getParentDirective())) {
5595  // OpenMP [2.8.1,simd Construct, Restrictions]
5596  // An ordered construct with the simd clause is the only OpenMP construct
5597  // that can appear in the simd region.
5598  Diag(StartLoc, diag::err_omp_prohibited_region_simd);
5599  ErrorFound = true;
5600  } else if (DependFound && (TC || SC)) {
5601  Diag(DependFound->getLocStart(), diag::err_omp_depend_clause_thread_simd)
5602  << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
5603  ErrorFound = true;
5604  } else if (DependFound && !DSAStack->getParentOrderedRegionParam()) {
5605  Diag(DependFound->getLocStart(),
5606  diag::err_omp_ordered_directive_without_param);
5607  ErrorFound = true;
5608  } else if (TC || Clauses.empty()) {
5609  if (auto *Param = DSAStack->getParentOrderedRegionParam()) {
5610  SourceLocation ErrLoc = TC ? TC->getLocStart() : StartLoc;
5611  Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
5612  << (TC != nullptr);
5613  Diag(Param->getLocStart(), diag::note_omp_ordered_param);
5614  ErrorFound = true;
5615  }
5616  }
5617  if ((!AStmt && !DependFound) || ErrorFound)
5618  return StmtError();
5619 
5620  if (AStmt) {
5621  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5622 
5623  getCurFunction()->setHasBranchProtectedScope();
5624  }
5625 
5626  return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
5627 }
5628 
5629 namespace {
5630 /// \brief Helper class for checking expression in 'omp atomic [update]'
5631 /// construct.
5632 class OpenMPAtomicUpdateChecker {
5633  /// \brief Error results for atomic update expressions.
5634  enum ExprAnalysisErrorCode {
5635  /// \brief A statement is not an expression statement.
5636  NotAnExpression,
5637  /// \brief Expression is not builtin binary or unary operation.
5638  NotABinaryOrUnaryExpression,
5639  /// \brief Unary operation is not post-/pre- increment/decrement operation.
5640  NotAnUnaryIncDecExpression,
5641  /// \brief An expression is not of scalar type.
5642  NotAScalarType,
5643  /// \brief A binary operation is not an assignment operation.
5644  NotAnAssignmentOp,
5645  /// \brief RHS part of the binary operation is not a binary expression.
5646  NotABinaryExpression,
5647  /// \brief RHS part is not additive/multiplicative/shift/biwise binary
5648  /// expression.
5649  NotABinaryOperator,
5650  /// \brief RHS binary operation does not have reference to the updated LHS
5651  /// part.
5652  NotAnUpdateExpression,
5653  /// \brief No errors is found.
5654  NoError
5655  };
5656  /// \brief Reference to Sema.
5657  Sema &SemaRef;
5658  /// \brief A location for note diagnostics (when error is found).
5659  SourceLocation NoteLoc;
5660  /// \brief 'x' lvalue part of the source atomic expression.
5661  Expr *X;
5662  /// \brief 'expr' rvalue part of the source atomic expression.
5663  Expr *E;
5664  /// \brief Helper expression of the form
5665  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
5666  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
5667  Expr *UpdateExpr;
5668  /// \brief Is 'x' a LHS in a RHS part of full update expression. It is
5669  /// important for non-associative operations.
5670  bool IsXLHSInRHSPart;
5671  BinaryOperatorKind Op;
5672  SourceLocation OpLoc;
5673  /// \brief true if the source expression is a postfix unary operation, false
5674  /// if it is a prefix unary operation.
5675  bool IsPostfixUpdate;
5676 
5677 public:
5678  OpenMPAtomicUpdateChecker(Sema &SemaRef)
5679  : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
5680  IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
5681  /// \brief Check specified statement that it is suitable for 'atomic update'
5682  /// constructs and extract 'x', 'expr' and Operation from the original
5683  /// expression. If DiagId and NoteId == 0, then only check is performed
5684  /// without error notification.
5685  /// \param DiagId Diagnostic which should be emitted if error is found.
5686  /// \param NoteId Diagnostic note for the main error message.
5687  /// \return true if statement is not an update expression, false otherwise.
5688  bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
5689  /// \brief Return the 'x' lvalue part of the source atomic expression.
5690  Expr *getX() const { return X; }
5691  /// \brief Return the 'expr' rvalue part of the source atomic expression.
5692  Expr *getExpr() const { return E; }
5693  /// \brief Return the update expression used in calculation of the updated
5694  /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
5695  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
5696  Expr *getUpdateExpr() const { return UpdateExpr; }
5697  /// \brief Return true if 'x' is LHS in RHS part of full update expression,
5698  /// false otherwise.
5699  bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
5700 
5701  /// \brief true if the source expression is a postfix unary operation, false
5702  /// if it is a prefix unary operation.
5703  bool isPostfixUpdate() const { return IsPostfixUpdate; }
5704 
5705 private:
5706  bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
5707  unsigned NoteId = 0);
5708 };
5709 } // namespace
5710 
5711 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
5712  BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
5713  ExprAnalysisErrorCode ErrorFound = NoError;
5714  SourceLocation ErrorLoc, NoteLoc;
5715  SourceRange ErrorRange, NoteRange;
5716  // Allowed constructs are:
5717  // x = x binop expr;
5718  // x = expr binop x;
5719  if (AtomicBinOp->getOpcode() == BO_Assign) {
5720  X = AtomicBinOp->getLHS();
5721  if (auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
5722  AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
5723  if (AtomicInnerBinOp->isMultiplicativeOp() ||
5724  AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
5725  AtomicInnerBinOp->isBitwiseOp()) {
5726  Op = AtomicInnerBinOp->getOpcode();
5727  OpLoc = AtomicInnerBinOp->getOperatorLoc();
5728  auto *LHS = AtomicInnerBinOp->getLHS();
5729  auto *RHS = AtomicInnerBinOp->getRHS();
5730  llvm::FoldingSetNodeID XId, LHSId, RHSId;
5731  X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
5732  /*Canonical=*/true);
5733  LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
5734  /*Canonical=*/true);
5735  RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.