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