clang  6.0.0
SemaOpenMP.cpp
Go to the documentation of this file.
1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 /// \file
10 /// \brief This file implements semantic analysis for OpenMP directives and
11 /// clauses.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #include "TreeTransform.h"
16 #include "clang/AST/ASTContext.h"
19 #include "clang/AST/Decl.h"
20 #include "clang/AST/DeclCXX.h"
21 #include "clang/AST/DeclOpenMP.h"
22 #include "clang/AST/StmtCXX.h"
23 #include "clang/AST/StmtOpenMP.h"
24 #include "clang/AST/StmtVisitor.h"
27 #include "clang/Sema/Lookup.h"
28 #include "clang/Sema/Scope.h"
29 #include "clang/Sema/ScopeInfo.h"
31 #include "llvm/ADT/PointerEmbeddedInt.h"
32 using namespace clang;
33 
34 //===----------------------------------------------------------------------===//
35 // Stack of data-sharing attributes for variables
36 //===----------------------------------------------------------------------===//
37 
39  Sema &SemaRef, Expr *E,
41  OpenMPClauseKind CKind, bool NoDiagnose);
42 
43 namespace {
44 /// \brief Default data sharing attributes, which can be applied to directive.
46  DSA_unspecified = 0, /// \brief Data sharing attribute not specified.
47  DSA_none = 1 << 0, /// \brief Default data sharing attribute 'none'.
48  DSA_shared = 1 << 1, /// \brief Default data sharing attribute 'shared'.
49 };
50 
51 /// Attributes of the defaultmap clause.
53  DMA_unspecified, /// Default mapping is not specified.
54  DMA_tofrom_scalar, /// Default mapping is 'tofrom:scalar'.
55 };
56 
57 /// \brief Stack for tracking declarations used in OpenMP directives and
58 /// clauses and their data-sharing attributes.
59 class DSAStackTy final {
60 public:
61  struct DSAVarData final {
64  Expr *RefExpr = nullptr;
65  DeclRefExpr *PrivateCopy = nullptr;
66  SourceLocation ImplicitDSALoc;
67  DSAVarData() = default;
68  DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, Expr *RefExpr,
69  DeclRefExpr *PrivateCopy, SourceLocation ImplicitDSALoc)
70  : DKind(DKind), CKind(CKind), RefExpr(RefExpr),
71  PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {}
72  };
74  OperatorOffsetTy;
75 
76 private:
77  struct DSAInfo final {
78  OpenMPClauseKind Attributes = OMPC_unknown;
79  /// Pointer to a reference expression and a flag which shows that the
80  /// variable is marked as lastprivate(true) or not (false).
81  llvm::PointerIntPair<Expr *, 1, bool> RefExpr;
82  DeclRefExpr *PrivateCopy = nullptr;
83  };
84  typedef llvm::DenseMap<ValueDecl *, DSAInfo> DeclSAMapTy;
85  typedef llvm::DenseMap<ValueDecl *, Expr *> AlignedMapTy;
86  typedef std::pair<unsigned, VarDecl *> LCDeclInfo;
87  typedef llvm::DenseMap<ValueDecl *, LCDeclInfo> LoopControlVariablesMapTy;
88  /// Struct that associates a component with the clause kind where they are
89  /// found.
90  struct MappedExprComponentTy {
93  };
94  typedef llvm::DenseMap<ValueDecl *, MappedExprComponentTy>
95  MappedExprComponentsTy;
96  typedef llvm::StringMap<std::pair<OMPCriticalDirective *, llvm::APSInt>>
97  CriticalsWithHintsTy;
98  typedef llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>
99  DoacrossDependMapTy;
100  struct ReductionData {
101  typedef llvm::PointerEmbeddedInt<BinaryOperatorKind, 16> BOKPtrType;
102  SourceRange ReductionRange;
103  llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
104  ReductionData() = default;
105  void set(BinaryOperatorKind BO, SourceRange RR) {
106  ReductionRange = RR;
107  ReductionOp = BO;
108  }
109  void set(const Expr *RefExpr, SourceRange RR) {
110  ReductionRange = RR;
111  ReductionOp = RefExpr;
112  }
113  };
114  typedef llvm::DenseMap<ValueDecl *, ReductionData> DeclReductionMapTy;
115 
116  struct SharingMapTy final {
117  DeclSAMapTy SharingMap;
118  DeclReductionMapTy ReductionMap;
119  AlignedMapTy AlignedMap;
120  MappedExprComponentsTy MappedExprComponents;
121  LoopControlVariablesMapTy LCVMap;
122  DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
123  SourceLocation DefaultAttrLoc;
124  DefaultMapAttributes DefaultMapAttr = DMA_unspecified;
125  SourceLocation DefaultMapAttrLoc;
127  DeclarationNameInfo DirectiveName;
128  Scope *CurScope = nullptr;
129  SourceLocation ConstructLoc;
130  /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
131  /// get the data (loop counters etc.) about enclosing loop-based construct.
132  /// This data is required during codegen.
133  DoacrossDependMapTy DoacrossDepends;
134  /// \brief first argument (Expr *) contains optional argument of the
135  /// 'ordered' clause, the second one is true if the regions has 'ordered'
136  /// clause, false otherwise.
137  llvm::PointerIntPair<Expr *, 1, bool> OrderedRegion;
138  bool NowaitRegion = false;
139  bool CancelRegion = false;
140  unsigned AssociatedLoops = 1;
141  SourceLocation InnerTeamsRegionLoc;
142  /// Reference to the taskgroup task_reduction reference expression.
143  Expr *TaskgroupReductionRef = nullptr;
144  SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
145  Scope *CurScope, SourceLocation Loc)
146  : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
147  ConstructLoc(Loc) {}
148  SharingMapTy() = default;
149  };
150 
151  typedef SmallVector<SharingMapTy, 4> StackTy;
152 
153  /// \brief Stack of used declaration and their data-sharing attributes.
154  DeclSAMapTy Threadprivates;
155  const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
157  /// \brief true, if check for DSA must be from parent directive, false, if
158  /// from current directive.
159  OpenMPClauseKind ClauseKindMode = OMPC_unknown;
160  Sema &SemaRef;
161  bool ForceCapturing = false;
162  CriticalsWithHintsTy Criticals;
163 
164  typedef SmallVector<SharingMapTy, 8>::reverse_iterator reverse_iterator;
165 
166  DSAVarData getDSA(StackTy::reverse_iterator &Iter, ValueDecl *D);
167 
168  /// \brief Checks if the variable is a local for OpenMP region.
169  bool isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter);
170 
171  bool isStackEmpty() const {
172  return Stack.empty() ||
173  Stack.back().second != CurrentNonCapturingFunctionScope ||
174  Stack.back().first.empty();
175  }
176 
177 public:
178  explicit DSAStackTy(Sema &S) : SemaRef(S) {}
179 
180  bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
181  OpenMPClauseKind getClauseParsingMode() const {
182  assert(isClauseParsingMode() && "Must be in clause parsing mode.");
183  return ClauseKindMode;
184  }
185  void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
186 
187  bool isForceVarCapturing() const { return ForceCapturing; }
188  void setForceVarCapturing(bool V) { ForceCapturing = V; }
189 
190  void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
191  Scope *CurScope, SourceLocation Loc) {
192  if (Stack.empty() ||
193  Stack.back().second != CurrentNonCapturingFunctionScope)
194  Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
195  Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
196  Stack.back().first.back().DefaultAttrLoc = Loc;
197  }
198 
199  void pop() {
200  assert(!Stack.back().first.empty() &&
201  "Data-sharing attributes stack is empty!");
202  Stack.back().first.pop_back();
203  }
204 
205  /// Start new OpenMP region stack in new non-capturing function.
206  void pushFunction() {
207  const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
208  assert(!isa<CapturingScopeInfo>(CurFnScope));
209  CurrentNonCapturingFunctionScope = CurFnScope;
210  }
211  /// Pop region stack for non-capturing function.
212  void popFunction(const FunctionScopeInfo *OldFSI) {
213  if (!Stack.empty() && Stack.back().second == OldFSI) {
214  assert(Stack.back().first.empty());
215  Stack.pop_back();
216  }
217  CurrentNonCapturingFunctionScope = nullptr;
218  for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
219  if (!isa<CapturingScopeInfo>(FSI)) {
220  CurrentNonCapturingFunctionScope = FSI;
221  break;
222  }
223  }
224  }
225 
226  void addCriticalWithHint(OMPCriticalDirective *D, llvm::APSInt Hint) {
227  Criticals[D->getDirectiveName().getAsString()] = std::make_pair(D, Hint);
228  }
229  const std::pair<OMPCriticalDirective *, llvm::APSInt>
230  getCriticalWithHint(const DeclarationNameInfo &Name) const {
231  auto I = Criticals.find(Name.getAsString());
232  if (I != Criticals.end())
233  return I->second;
234  return std::make_pair(nullptr, llvm::APSInt());
235  }
236  /// \brief If 'aligned' declaration for given variable \a D was not seen yet,
237  /// add it and return NULL; otherwise return previous occurrence's expression
238  /// for diagnostics.
239  Expr *addUniqueAligned(ValueDecl *D, Expr *NewDE);
240 
241  /// \brief Register specified variable as loop control variable.
242  void addLoopControlVariable(ValueDecl *D, VarDecl *Capture);
243  /// \brief Check if the specified variable is a loop control variable for
244  /// current region.
245  /// \return The index of the loop control variable in the list of associated
246  /// for-loops (from outer to inner).
247  LCDeclInfo isLoopControlVariable(ValueDecl *D);
248  /// \brief Check if the specified variable is a loop control variable for
249  /// parent region.
250  /// \return The index of the loop control variable in the list of associated
251  /// for-loops (from outer to inner).
252  LCDeclInfo isParentLoopControlVariable(ValueDecl *D);
253  /// \brief Get the loop control variable for the I-th loop (or nullptr) in
254  /// parent directive.
255  ValueDecl *getParentLoopControlVariable(unsigned I);
256 
257  /// \brief Adds explicit data sharing attribute to the specified declaration.
258  void addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A,
259  DeclRefExpr *PrivateCopy = nullptr);
260 
261  /// Adds additional information for the reduction items with the reduction id
262  /// represented as an operator.
263  void addTaskgroupReductionData(ValueDecl *D, SourceRange SR,
264  BinaryOperatorKind BOK);
265  /// Adds additional information for the reduction items with the reduction id
266  /// represented as reduction identifier.
267  void addTaskgroupReductionData(ValueDecl *D, SourceRange SR,
268  const Expr *ReductionRef);
269  /// Returns the location and reduction operation from the innermost parent
270  /// region for the given \p D.
271  DSAVarData getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR,
272  BinaryOperatorKind &BOK,
273  Expr *&TaskgroupDescriptor);
274  /// Returns the location and reduction operation from the innermost parent
275  /// region for the given \p D.
276  DSAVarData getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR,
277  const Expr *&ReductionRef,
278  Expr *&TaskgroupDescriptor);
279  /// Return reduction reference expression for the current taskgroup.
280  Expr *getTaskgroupReductionRef() const {
281  assert(Stack.back().first.back().Directive == OMPD_taskgroup &&
282  "taskgroup reference expression requested for non taskgroup "
283  "directive.");
284  return Stack.back().first.back().TaskgroupReductionRef;
285  }
286  /// Checks if the given \p VD declaration is actually a taskgroup reduction
287  /// descriptor variable at the \p Level of OpenMP regions.
288  bool isTaskgroupReductionRef(ValueDecl *VD, unsigned Level) const {
289  return Stack.back().first[Level].TaskgroupReductionRef &&
290  cast<DeclRefExpr>(Stack.back().first[Level].TaskgroupReductionRef)
291  ->getDecl() == VD;
292  }
293 
294  /// \brief Returns data sharing attributes from top of the stack for the
295  /// specified declaration.
296  DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
297  /// \brief Returns data-sharing attributes for the specified declaration.
298  DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent);
299  /// \brief Checks if the specified variables has data-sharing attributes which
300  /// match specified \a CPred predicate in any directive which matches \a DPred
301  /// predicate.
302  DSAVarData hasDSA(ValueDecl *D,
303  const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
304  const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
305  bool FromParent);
306  /// \brief Checks if the specified variables has data-sharing attributes which
307  /// match specified \a CPred predicate in any innermost directive which
308  /// matches \a DPred predicate.
309  DSAVarData
310  hasInnermostDSA(ValueDecl *D,
311  const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
312  const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
313  bool FromParent);
314  /// \brief Checks if the specified variables has explicit data-sharing
315  /// attributes which match specified \a CPred predicate at the specified
316  /// OpenMP region.
317  bool hasExplicitDSA(ValueDecl *D,
318  const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
319  unsigned Level, bool NotLastprivate = false);
320 
321  /// \brief Returns true if the directive at level \Level matches in the
322  /// specified \a DPred predicate.
323  bool hasExplicitDirective(
324  const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
325  unsigned Level);
326 
327  /// \brief Finds a directive which matches specified \a DPred predicate.
328  bool hasDirective(const llvm::function_ref<bool(OpenMPDirectiveKind,
329  const DeclarationNameInfo &,
330  SourceLocation)> &DPred,
331  bool FromParent);
332 
333  /// \brief Returns currently analyzed directive.
334  OpenMPDirectiveKind getCurrentDirective() const {
335  return isStackEmpty() ? OMPD_unknown : Stack.back().first.back().Directive;
336  }
337  /// \brief Returns directive kind at specified level.
338  OpenMPDirectiveKind getDirective(unsigned Level) const {
339  assert(!isStackEmpty() && "No directive at specified level.");
340  return Stack.back().first[Level].Directive;
341  }
342  /// \brief Returns parent directive.
343  OpenMPDirectiveKind getParentDirective() const {
344  if (isStackEmpty() || Stack.back().first.size() == 1)
345  return OMPD_unknown;
346  return std::next(Stack.back().first.rbegin())->Directive;
347  }
348 
349  /// \brief Set default data sharing attribute to none.
350  void setDefaultDSANone(SourceLocation Loc) {
351  assert(!isStackEmpty());
352  Stack.back().first.back().DefaultAttr = DSA_none;
353  Stack.back().first.back().DefaultAttrLoc = Loc;
354  }
355  /// \brief Set default data sharing attribute to shared.
356  void setDefaultDSAShared(SourceLocation Loc) {
357  assert(!isStackEmpty());
358  Stack.back().first.back().DefaultAttr = DSA_shared;
359  Stack.back().first.back().DefaultAttrLoc = Loc;
360  }
361  /// Set default data mapping attribute to 'tofrom:scalar'.
362  void setDefaultDMAToFromScalar(SourceLocation Loc) {
363  assert(!isStackEmpty());
364  Stack.back().first.back().DefaultMapAttr = DMA_tofrom_scalar;
365  Stack.back().first.back().DefaultMapAttrLoc = Loc;
366  }
367 
368  DefaultDataSharingAttributes getDefaultDSA() const {
369  return isStackEmpty() ? DSA_unspecified
370  : Stack.back().first.back().DefaultAttr;
371  }
372  SourceLocation getDefaultDSALocation() const {
373  return isStackEmpty() ? SourceLocation()
374  : Stack.back().first.back().DefaultAttrLoc;
375  }
376  DefaultMapAttributes getDefaultDMA() const {
377  return isStackEmpty() ? DMA_unspecified
378  : Stack.back().first.back().DefaultMapAttr;
379  }
380  DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const {
381  return Stack.back().first[Level].DefaultMapAttr;
382  }
383  SourceLocation getDefaultDMALocation() const {
384  return isStackEmpty() ? SourceLocation()
385  : Stack.back().first.back().DefaultMapAttrLoc;
386  }
387 
388  /// \brief Checks if the specified variable is a threadprivate.
389  bool isThreadPrivate(VarDecl *D) {
390  DSAVarData DVar = getTopDSA(D, false);
391  return isOpenMPThreadPrivate(DVar.CKind);
392  }
393 
394  /// \brief Marks current region as ordered (it has an 'ordered' clause).
395  void setOrderedRegion(bool IsOrdered, Expr *Param) {
396  assert(!isStackEmpty());
397  Stack.back().first.back().OrderedRegion.setInt(IsOrdered);
398  Stack.back().first.back().OrderedRegion.setPointer(Param);
399  }
400  /// \brief Returns true, if parent region is ordered (has associated
401  /// 'ordered' clause), false - otherwise.
402  bool isParentOrderedRegion() const {
403  if (isStackEmpty() || Stack.back().first.size() == 1)
404  return false;
405  return std::next(Stack.back().first.rbegin())->OrderedRegion.getInt();
406  }
407  /// \brief Returns optional parameter for the ordered region.
408  Expr *getParentOrderedRegionParam() const {
409  if (isStackEmpty() || Stack.back().first.size() == 1)
410  return nullptr;
411  return std::next(Stack.back().first.rbegin())->OrderedRegion.getPointer();
412  }
413  /// \brief Marks current region as nowait (it has a 'nowait' clause).
414  void setNowaitRegion(bool IsNowait = true) {
415  assert(!isStackEmpty());
416  Stack.back().first.back().NowaitRegion = IsNowait;
417  }
418  /// \brief Returns true, if parent region is nowait (has associated
419  /// 'nowait' clause), false - otherwise.
420  bool isParentNowaitRegion() const {
421  if (isStackEmpty() || Stack.back().first.size() == 1)
422  return false;
423  return std::next(Stack.back().first.rbegin())->NowaitRegion;
424  }
425  /// \brief Marks parent region as cancel region.
426  void setParentCancelRegion(bool Cancel = true) {
427  if (!isStackEmpty() && Stack.back().first.size() > 1) {
428  auto &StackElemRef = *std::next(Stack.back().first.rbegin());
429  StackElemRef.CancelRegion |= StackElemRef.CancelRegion || Cancel;
430  }
431  }
432  /// \brief Return true if current region has inner cancel construct.
433  bool isCancelRegion() const {
434  return isStackEmpty() ? false : Stack.back().first.back().CancelRegion;
435  }
436 
437  /// \brief Set collapse value for the region.
438  void setAssociatedLoops(unsigned Val) {
439  assert(!isStackEmpty());
440  Stack.back().first.back().AssociatedLoops = Val;
441  }
442  /// \brief Return collapse value for region.
443  unsigned getAssociatedLoops() const {
444  return isStackEmpty() ? 0 : Stack.back().first.back().AssociatedLoops;
445  }
446 
447  /// \brief Marks current target region as one with closely nested teams
448  /// region.
449  void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
450  if (!isStackEmpty() && Stack.back().first.size() > 1) {
451  std::next(Stack.back().first.rbegin())->InnerTeamsRegionLoc =
452  TeamsRegionLoc;
453  }
454  }
455  /// \brief Returns true, if current region has closely nested teams region.
456  bool hasInnerTeamsRegion() const {
457  return getInnerTeamsRegionLoc().isValid();
458  }
459  /// \brief Returns location of the nested teams region (if any).
460  SourceLocation getInnerTeamsRegionLoc() const {
461  return isStackEmpty() ? SourceLocation()
462  : Stack.back().first.back().InnerTeamsRegionLoc;
463  }
464 
465  Scope *getCurScope() const {
466  return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope;
467  }
468  Scope *getCurScope() {
469  return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope;
470  }
471  SourceLocation getConstructLoc() {
472  return isStackEmpty() ? SourceLocation()
473  : Stack.back().first.back().ConstructLoc;
474  }
475 
476  /// Do the check specified in \a Check to all component lists and return true
477  /// if any issue is found.
478  bool checkMappableExprComponentListsForDecl(
479  ValueDecl *VD, bool CurrentRegionOnly,
480  const llvm::function_ref<
482  OpenMPClauseKind)> &Check) {
483  if (isStackEmpty())
484  return false;
485  auto SI = Stack.back().first.rbegin();
486  auto SE = Stack.back().first.rend();
487 
488  if (SI == SE)
489  return false;
490 
491  if (CurrentRegionOnly) {
492  SE = std::next(SI);
493  } else {
494  ++SI;
495  }
496 
497  for (; SI != SE; ++SI) {
498  auto MI = SI->MappedExprComponents.find(VD);
499  if (MI != SI->MappedExprComponents.end())
500  for (auto &L : MI->second.Components)
501  if (Check(L, MI->second.Kind))
502  return true;
503  }
504  return false;
505  }
506 
507  /// Do the check specified in \a Check to all component lists at a given level
508  /// and return true if any issue is found.
509  bool checkMappableExprComponentListsForDeclAtLevel(
510  ValueDecl *VD, unsigned Level,
511  const llvm::function_ref<
513  OpenMPClauseKind)> &Check) {
514  if (isStackEmpty())
515  return false;
516 
517  auto StartI = Stack.back().first.begin();
518  auto EndI = Stack.back().first.end();
519  if (std::distance(StartI, EndI) <= (int)Level)
520  return false;
521  std::advance(StartI, Level);
522 
523  auto MI = StartI->MappedExprComponents.find(VD);
524  if (MI != StartI->MappedExprComponents.end())
525  for (auto &L : MI->second.Components)
526  if (Check(L, MI->second.Kind))
527  return true;
528  return false;
529  }
530 
531  /// Create a new mappable expression component list associated with a given
532  /// declaration and initialize it with the provided list of components.
533  void addMappableExpressionComponents(
534  ValueDecl *VD,
536  OpenMPClauseKind WhereFoundClauseKind) {
537  assert(!isStackEmpty() &&
538  "Not expecting to retrieve components from a empty stack!");
539  auto &MEC = Stack.back().first.back().MappedExprComponents[VD];
540  // Create new entry and append the new components there.
541  MEC.Components.resize(MEC.Components.size() + 1);
542  MEC.Components.back().append(Components.begin(), Components.end());
543  MEC.Kind = WhereFoundClauseKind;
544  }
545 
546  unsigned getNestingLevel() const {
547  assert(!isStackEmpty());
548  return Stack.back().first.size() - 1;
549  }
550  void addDoacrossDependClause(OMPDependClause *C, OperatorOffsetTy &OpsOffs) {
551  assert(!isStackEmpty() && Stack.back().first.size() > 1);
552  auto &StackElem = *std::next(Stack.back().first.rbegin());
553  assert(isOpenMPWorksharingDirective(StackElem.Directive));
554  StackElem.DoacrossDepends.insert({C, OpsOffs});
555  }
556  llvm::iterator_range<DoacrossDependMapTy::const_iterator>
557  getDoacrossDependClauses() const {
558  assert(!isStackEmpty());
559  auto &StackElem = Stack.back().first.back();
560  if (isOpenMPWorksharingDirective(StackElem.Directive)) {
561  auto &Ref = StackElem.DoacrossDepends;
562  return llvm::make_range(Ref.begin(), Ref.end());
563  }
564  return llvm::make_range(StackElem.DoacrossDepends.end(),
565  StackElem.DoacrossDepends.end());
566  }
567 };
568 bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) {
569  return isOpenMPParallelDirective(DKind) || isOpenMPTaskingDirective(DKind) ||
570  isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown;
571 }
572 } // namespace
573 
575  if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(E))
576  E = ExprTemp->getSubExpr();
577 
578  if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
579  E = MTE->GetTemporaryExpr();
580 
581  while (auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
582  E = Binder->getSubExpr();
583 
584  if (auto *ICE = dyn_cast<ImplicitCastExpr>(E))
585  E = ICE->getSubExprAsWritten();
586  return E->IgnoreParens();
587 }
588 
590  if (auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
591  if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
592  D = ME->getMemberDecl();
593  auto *VD = dyn_cast<VarDecl>(D);
594  auto *FD = dyn_cast<FieldDecl>(D);
595  if (VD != nullptr) {
596  VD = VD->getCanonicalDecl();
597  D = VD;
598  } else {
599  assert(FD);
600  FD = FD->getCanonicalDecl();
601  D = FD;
602  }
603  return D;
604 }
605 
606 DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator &Iter,
607  ValueDecl *D) {
608  D = getCanonicalDecl(D);
609  auto *VD = dyn_cast<VarDecl>(D);
610  auto *FD = dyn_cast<FieldDecl>(D);
611  DSAVarData DVar;
612  if (isStackEmpty() || Iter == Stack.back().first.rend()) {
613  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
614  // in a region but not in construct]
615  // File-scope or namespace-scope variables referenced in called routines
616  // in the region are shared unless they appear in a threadprivate
617  // directive.
618  if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(D))
619  DVar.CKind = OMPC_shared;
620 
621  // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
622  // in a region but not in construct]
623  // Variables with static storage duration that are declared in called
624  // routines in the region are shared.
625  if (VD && VD->hasGlobalStorage())
626  DVar.CKind = OMPC_shared;
627 
628  // Non-static data members are shared by default.
629  if (FD)
630  DVar.CKind = OMPC_shared;
631 
632  return DVar;
633  }
634 
635  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
636  // in a Construct, C/C++, predetermined, p.1]
637  // Variables with automatic storage duration that are declared in a scope
638  // inside the construct are private.
639  if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
640  (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
641  DVar.CKind = OMPC_private;
642  return DVar;
643  }
644 
645  DVar.DKind = Iter->Directive;
646  // Explicitly specified attributes and local variables with predetermined
647  // attributes.
648  if (Iter->SharingMap.count(D)) {
649  DVar.RefExpr = Iter->SharingMap[D].RefExpr.getPointer();
650  DVar.PrivateCopy = Iter->SharingMap[D].PrivateCopy;
651  DVar.CKind = Iter->SharingMap[D].Attributes;
652  DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
653  return DVar;
654  }
655 
656  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
657  // in a Construct, C/C++, implicitly determined, p.1]
658  // In a parallel or task construct, the data-sharing attributes of these
659  // variables are determined by the default clause, if present.
660  switch (Iter->DefaultAttr) {
661  case DSA_shared:
662  DVar.CKind = OMPC_shared;
663  DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
664  return DVar;
665  case DSA_none:
666  return DVar;
667  case DSA_unspecified:
668  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
669  // in a Construct, implicitly determined, p.2]
670  // In a parallel construct, if no default clause is present, these
671  // variables are shared.
672  DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
673  if (isOpenMPParallelDirective(DVar.DKind) ||
674  isOpenMPTeamsDirective(DVar.DKind)) {
675  DVar.CKind = OMPC_shared;
676  return DVar;
677  }
678 
679  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
680  // in a Construct, implicitly determined, p.4]
681  // In a task construct, if no default clause is present, a variable that in
682  // the enclosing context is determined to be shared by all implicit tasks
683  // bound to the current team is shared.
684  if (isOpenMPTaskingDirective(DVar.DKind)) {
685  DSAVarData DVarTemp;
686  auto I = Iter, E = Stack.back().first.rend();
687  do {
688  ++I;
689  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
690  // Referenced in a Construct, implicitly determined, p.6]
691  // In a task construct, if no default clause is present, a variable
692  // whose data-sharing attribute is not determined by the rules above is
693  // firstprivate.
694  DVarTemp = getDSA(I, D);
695  if (DVarTemp.CKind != OMPC_shared) {
696  DVar.RefExpr = nullptr;
697  DVar.CKind = OMPC_firstprivate;
698  return DVar;
699  }
700  } while (I != E && !isParallelOrTaskRegion(I->Directive));
701  DVar.CKind =
702  (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
703  return DVar;
704  }
705  }
706  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
707  // in a Construct, implicitly determined, p.3]
708  // For constructs other than task, if no default clause is present, these
709  // variables inherit their data-sharing attributes from the enclosing
710  // context.
711  return getDSA(++Iter, D);
712 }
713 
714 Expr *DSAStackTy::addUniqueAligned(ValueDecl *D, Expr *NewDE) {
715  assert(!isStackEmpty() && "Data sharing attributes stack is empty");
716  D = getCanonicalDecl(D);
717  auto &StackElem = Stack.back().first.back();
718  auto It = StackElem.AlignedMap.find(D);
719  if (It == StackElem.AlignedMap.end()) {
720  assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
721  StackElem.AlignedMap[D] = NewDE;
722  return nullptr;
723  } else {
724  assert(It->second && "Unexpected nullptr expr in the aligned map");
725  return It->second;
726  }
727  return nullptr;
728 }
729 
730 void DSAStackTy::addLoopControlVariable(ValueDecl *D, VarDecl *Capture) {
731  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
732  D = getCanonicalDecl(D);
733  auto &StackElem = Stack.back().first.back();
734  StackElem.LCVMap.insert(
735  {D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)});
736 }
737 
738 DSAStackTy::LCDeclInfo DSAStackTy::isLoopControlVariable(ValueDecl *D) {
739  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
740  D = getCanonicalDecl(D);
741  auto &StackElem = Stack.back().first.back();
742  auto It = StackElem.LCVMap.find(D);
743  if (It != StackElem.LCVMap.end())
744  return It->second;
745  return {0, nullptr};
746 }
747 
748 DSAStackTy::LCDeclInfo DSAStackTy::isParentLoopControlVariable(ValueDecl *D) {
749  assert(!isStackEmpty() && Stack.back().first.size() > 1 &&
750  "Data-sharing attributes stack is empty");
751  D = getCanonicalDecl(D);
752  auto &StackElem = *std::next(Stack.back().first.rbegin());
753  auto It = StackElem.LCVMap.find(D);
754  if (It != StackElem.LCVMap.end())
755  return It->second;
756  return {0, nullptr};
757 }
758 
759 ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) {
760  assert(!isStackEmpty() && Stack.back().first.size() > 1 &&
761  "Data-sharing attributes stack is empty");
762  auto &StackElem = *std::next(Stack.back().first.rbegin());
763  if (StackElem.LCVMap.size() < I)
764  return nullptr;
765  for (auto &Pair : StackElem.LCVMap)
766  if (Pair.second.first == I)
767  return Pair.first;
768  return nullptr;
769 }
770 
771 void DSAStackTy::addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A,
772  DeclRefExpr *PrivateCopy) {
773  D = getCanonicalDecl(D);
774  if (A == OMPC_threadprivate) {
775  auto &Data = Threadprivates[D];
776  Data.Attributes = A;
777  Data.RefExpr.setPointer(E);
778  Data.PrivateCopy = nullptr;
779  } else {
780  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
781  auto &Data = Stack.back().first.back().SharingMap[D];
782  assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
783  (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
784  (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
785  (isLoopControlVariable(D).first && A == OMPC_private));
786  if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
787  Data.RefExpr.setInt(/*IntVal=*/true);
788  return;
789  }
790  const bool IsLastprivate =
791  A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
792  Data.Attributes = A;
793  Data.RefExpr.setPointerAndInt(E, IsLastprivate);
794  Data.PrivateCopy = PrivateCopy;
795  if (PrivateCopy) {
796  auto &Data = Stack.back().first.back().SharingMap[PrivateCopy->getDecl()];
797  Data.Attributes = A;
798  Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
799  Data.PrivateCopy = nullptr;
800  }
801  }
802 }
803 
804 /// \brief Build a variable declaration for OpenMP loop iteration variable.
806  StringRef Name, const AttrVec *Attrs = nullptr) {
807  DeclContext *DC = SemaRef.CurContext;
808  IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
809  TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
810  VarDecl *Decl =
811  VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
812  if (Attrs) {
813  for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
814  I != E; ++I)
815  Decl->addAttr(*I);
816  }
817  Decl->setImplicit();
818  return Decl;
819 }
820 
822  SourceLocation Loc,
823  bool RefersToCapture = false) {
824  D->setReferenced();
825  D->markUsed(S.Context);
827  SourceLocation(), D, RefersToCapture, Loc, Ty,
828  VK_LValue);
829 }
830 
831 void DSAStackTy::addTaskgroupReductionData(ValueDecl *D, SourceRange SR,
832  BinaryOperatorKind BOK) {
833  D = getCanonicalDecl(D);
834  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
835  assert(
836  Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction &&
837  "Additional reduction info may be specified only for reduction items.");
838  auto &ReductionData = Stack.back().first.back().ReductionMap[D];
839  assert(ReductionData.ReductionRange.isInvalid() &&
840  Stack.back().first.back().Directive == OMPD_taskgroup &&
841  "Additional reduction info may be specified only once for reduction "
842  "items.");
843  ReductionData.set(BOK, SR);
844  Expr *&TaskgroupReductionRef =
845  Stack.back().first.back().TaskgroupReductionRef;
846  if (!TaskgroupReductionRef) {
847  auto *VD = buildVarDecl(SemaRef, SR.getBegin(),
848  SemaRef.Context.VoidPtrTy, ".task_red.");
849  TaskgroupReductionRef =
850  buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
851  }
852 }
853 
854 void DSAStackTy::addTaskgroupReductionData(ValueDecl *D, SourceRange SR,
855  const Expr *ReductionRef) {
856  D = getCanonicalDecl(D);
857  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
858  assert(
859  Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction &&
860  "Additional reduction info may be specified only for reduction items.");
861  auto &ReductionData = Stack.back().first.back().ReductionMap[D];
862  assert(ReductionData.ReductionRange.isInvalid() &&
863  Stack.back().first.back().Directive == OMPD_taskgroup &&
864  "Additional reduction info may be specified only once for reduction "
865  "items.");
866  ReductionData.set(ReductionRef, SR);
867  Expr *&TaskgroupReductionRef =
868  Stack.back().first.back().TaskgroupReductionRef;
869  if (!TaskgroupReductionRef) {
870  auto *VD = buildVarDecl(SemaRef, SR.getBegin(), SemaRef.Context.VoidPtrTy,
871  ".task_red.");
872  TaskgroupReductionRef =
873  buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
874  }
875 }
876 
877 DSAStackTy::DSAVarData
878 DSAStackTy::getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR,
879  BinaryOperatorKind &BOK,
880  Expr *&TaskgroupDescriptor) {
881  D = getCanonicalDecl(D);
882  assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
883  if (Stack.back().first.empty())
884  return DSAVarData();
885  for (auto I = std::next(Stack.back().first.rbegin(), 1),
886  E = Stack.back().first.rend();
887  I != E; std::advance(I, 1)) {
888  auto &Data = I->SharingMap[D];
889  if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
890  continue;
891  auto &ReductionData = I->ReductionMap[D];
892  if (!ReductionData.ReductionOp ||
893  ReductionData.ReductionOp.is<const Expr *>())
894  return DSAVarData();
895  SR = ReductionData.ReductionRange;
896  BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
897  assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
898  "expression for the descriptor is not "
899  "set.");
900  TaskgroupDescriptor = I->TaskgroupReductionRef;
901  return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
902  Data.PrivateCopy, I->DefaultAttrLoc);
903  }
904  return DSAVarData();
905 }
906 
907 DSAStackTy::DSAVarData
908 DSAStackTy::getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR,
909  const Expr *&ReductionRef,
910  Expr *&TaskgroupDescriptor) {
911  D = getCanonicalDecl(D);
912  assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
913  if (Stack.back().first.empty())
914  return DSAVarData();
915  for (auto I = std::next(Stack.back().first.rbegin(), 1),
916  E = Stack.back().first.rend();
917  I != E; std::advance(I, 1)) {
918  auto &Data = I->SharingMap[D];
919  if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
920  continue;
921  auto &ReductionData = I->ReductionMap[D];
922  if (!ReductionData.ReductionOp ||
923  !ReductionData.ReductionOp.is<const Expr *>())
924  return DSAVarData();
925  SR = ReductionData.ReductionRange;
926  ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
927  assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
928  "expression for the descriptor is not "
929  "set.");
930  TaskgroupDescriptor = I->TaskgroupReductionRef;
931  return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
932  Data.PrivateCopy, I->DefaultAttrLoc);
933  }
934  return DSAVarData();
935 }
936 
937 bool DSAStackTy::isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter) {
938  D = D->getCanonicalDecl();
939  if (!isStackEmpty() && Stack.back().first.size() > 1) {
940  reverse_iterator I = Iter, E = Stack.back().first.rend();
941  Scope *TopScope = nullptr;
942  while (I != E && !isParallelOrTaskRegion(I->Directive))
943  ++I;
944  if (I == E)
945  return false;
946  TopScope = I->CurScope ? I->CurScope->getParent() : nullptr;
947  Scope *CurScope = getCurScope();
948  while (CurScope != TopScope && !CurScope->isDeclScope(D))
949  CurScope = CurScope->getParent();
950  return CurScope != TopScope;
951  }
952  return false;
953 }
954 
955 DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, bool FromParent) {
956  D = getCanonicalDecl(D);
957  DSAVarData DVar;
958 
959  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
960  // in a Construct, C/C++, predetermined, p.1]
961  // Variables appearing in threadprivate directives are threadprivate.
962  auto *VD = dyn_cast<VarDecl>(D);
963  if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
964  !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
965  SemaRef.getLangOpts().OpenMPUseTLS &&
966  SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
967  (VD && VD->getStorageClass() == SC_Register &&
968  VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
969  addDSA(D, buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
970  D->getLocation()),
972  }
973  auto TI = Threadprivates.find(D);
974  if (TI != Threadprivates.end()) {
975  DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
976  DVar.CKind = OMPC_threadprivate;
977  return DVar;
978  } else if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
979  DVar.RefExpr = buildDeclRefExpr(
980  SemaRef, VD, D->getType().getNonReferenceType(),
981  VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
982  DVar.CKind = OMPC_threadprivate;
983  addDSA(D, DVar.RefExpr, OMPC_threadprivate);
984  }
985 
986  if (isStackEmpty())
987  // Not in OpenMP execution region and top scope was already checked.
988  return DVar;
989 
990  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
991  // in a Construct, C/C++, predetermined, p.4]
992  // Static data members are shared.
993  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
994  // in a Construct, C/C++, predetermined, p.7]
995  // Variables with static storage duration that are declared in a scope
996  // inside the construct are shared.
997  auto &&MatchesAlways = [](OpenMPDirectiveKind) -> bool { return true; };
998  if (VD && VD->isStaticDataMember()) {
999  DSAVarData DVarTemp = hasDSA(D, isOpenMPPrivate, MatchesAlways, FromParent);
1000  if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1001  return DVar;
1002 
1003  DVar.CKind = OMPC_shared;
1004  return DVar;
1005  }
1006 
1008  bool IsConstant = Type.isConstant(SemaRef.getASTContext());
1009  Type = SemaRef.getASTContext().getBaseElementType(Type);
1010  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1011  // in a Construct, C/C++, predetermined, p.6]
1012  // Variables with const qualified type having no mutable member are
1013  // shared.
1014  CXXRecordDecl *RD =
1015  SemaRef.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr;
1016  if (auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1017  if (auto *CTD = CTSD->getSpecializedTemplate())
1018  RD = CTD->getTemplatedDecl();
1019  if (IsConstant &&
1020  !(SemaRef.getLangOpts().CPlusPlus && RD && RD->hasDefinition() &&
1021  RD->hasMutableFields())) {
1022  // Variables with const-qualified type having no mutable member may be
1023  // listed in a firstprivate clause, even if they are static data members.
1024  DSAVarData DVarTemp = hasDSA(
1025  D, [](OpenMPClauseKind C) -> bool { return C == OMPC_firstprivate; },
1026  MatchesAlways, FromParent);
1027  if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr)
1028  return DVar;
1029 
1030  DVar.CKind = OMPC_shared;
1031  return DVar;
1032  }
1033 
1034  // Explicitly specified attributes and local variables with predetermined
1035  // attributes.
1036  auto I = Stack.back().first.rbegin();
1037  auto EndI = Stack.back().first.rend();
1038  if (FromParent && I != EndI)
1039  std::advance(I, 1);
1040  if (I->SharingMap.count(D)) {
1041  DVar.RefExpr = I->SharingMap[D].RefExpr.getPointer();
1042  DVar.PrivateCopy = I->SharingMap[D].PrivateCopy;
1043  DVar.CKind = I->SharingMap[D].Attributes;
1044  DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1045  DVar.DKind = I->Directive;
1046  }
1047 
1048  return DVar;
1049 }
1050 
1051 DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1052  bool FromParent) {
1053  if (isStackEmpty()) {
1054  StackTy::reverse_iterator I;
1055  return getDSA(I, D);
1056  }
1057  D = getCanonicalDecl(D);
1058  auto StartI = Stack.back().first.rbegin();
1059  auto EndI = Stack.back().first.rend();
1060  if (FromParent && StartI != EndI)
1061  std::advance(StartI, 1);
1062  return getDSA(StartI, D);
1063 }
1064 
1065 DSAStackTy::DSAVarData
1066 DSAStackTy::hasDSA(ValueDecl *D,
1067  const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
1068  const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
1069  bool FromParent) {
1070  if (isStackEmpty())
1071  return {};
1072  D = getCanonicalDecl(D);
1073  auto I = Stack.back().first.rbegin();
1074  auto EndI = Stack.back().first.rend();
1075  if (FromParent && I != EndI)
1076  std::advance(I, 1);
1077  for (; I != EndI; std::advance(I, 1)) {
1078  if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive))
1079  continue;
1080  auto NewI = I;
1081  DSAVarData DVar = getDSA(NewI, D);
1082  if (I == NewI && CPred(DVar.CKind))
1083  return DVar;
1084  }
1085  return {};
1086 }
1087 
1088 DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1089  ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
1090  const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
1091  bool FromParent) {
1092  if (isStackEmpty())
1093  return {};
1094  D = getCanonicalDecl(D);
1095  auto StartI = Stack.back().first.rbegin();
1096  auto EndI = Stack.back().first.rend();
1097  if (FromParent && StartI != EndI)
1098  std::advance(StartI, 1);
1099  if (StartI == EndI || !DPred(StartI->Directive))
1100  return {};
1101  auto NewI = StartI;
1102  DSAVarData DVar = getDSA(NewI, D);
1103  return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData();
1104 }
1105 
1106 bool DSAStackTy::hasExplicitDSA(
1107  ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred,
1108  unsigned Level, bool NotLastprivate) {
1109  if (isStackEmpty())
1110  return false;
1111  D = getCanonicalDecl(D);
1112  auto StartI = Stack.back().first.begin();
1113  auto EndI = Stack.back().first.end();
1114  if (std::distance(StartI, EndI) <= (int)Level)
1115  return false;
1116  std::advance(StartI, Level);
1117  return (StartI->SharingMap.count(D) > 0) &&
1118  StartI->SharingMap[D].RefExpr.getPointer() &&
1119  CPred(StartI->SharingMap[D].Attributes) &&
1120  (!NotLastprivate || !StartI->SharingMap[D].RefExpr.getInt());
1121 }
1122 
1123 bool DSAStackTy::hasExplicitDirective(
1124  const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred,
1125  unsigned Level) {
1126  if (isStackEmpty())
1127  return false;
1128  auto StartI = Stack.back().first.begin();
1129  auto EndI = Stack.back().first.end();
1130  if (std::distance(StartI, EndI) <= (int)Level)
1131  return false;
1132  std::advance(StartI, Level);
1133  return DPred(StartI->Directive);
1134 }
1135 
1136 bool DSAStackTy::hasDirective(
1137  const llvm::function_ref<bool(OpenMPDirectiveKind,
1139  &DPred,
1140  bool FromParent) {
1141  // We look only in the enclosing region.
1142  if (isStackEmpty())
1143  return false;
1144  auto StartI = std::next(Stack.back().first.rbegin());
1145  auto EndI = Stack.back().first.rend();
1146  if (FromParent && StartI != EndI)
1147  StartI = std::next(StartI);
1148  for (auto I = StartI, EE = EndI; I != EE; ++I) {
1149  if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1150  return true;
1151  }
1152  return false;
1153 }
1154 
1155 void Sema::InitDataSharingAttributesStack() {
1156  VarDataSharingAttributesStack = new DSAStackTy(*this);
1157 }
1158 
1159 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1160 
1161 void Sema::pushOpenMPFunctionRegion() {
1162  DSAStack->pushFunction();
1163 }
1164 
1165 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
1166  DSAStack->popFunction(OldFSI);
1167 }
1168 
1170  assert(LangOpts.OpenMP && "OpenMP is not allowed");
1171 
1172  auto &Ctx = getASTContext();
1173  bool IsByRef = true;
1174 
1175  // Find the directive that is associated with the provided scope.
1176  D = cast<ValueDecl>(D->getCanonicalDecl());
1177  auto Ty = D->getType();
1178 
1179  if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
1180  // This table summarizes how a given variable should be passed to the device
1181  // given its type and the clauses where it appears. This table is based on
1182  // the description in OpenMP 4.5 [2.10.4, target Construct] and
1183  // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
1184  //
1185  // =========================================================================
1186  // | type | defaultmap | pvt | first | is_device_ptr | map | res. |
1187  // | |(tofrom:scalar)| | pvt | | | |
1188  // =========================================================================
1189  // | scl | | | | - | | bycopy|
1190  // | scl | | - | x | - | - | bycopy|
1191  // | scl | | x | - | - | - | null |
1192  // | scl | x | | | - | | byref |
1193  // | scl | x | - | x | - | - | bycopy|
1194  // | scl | x | x | - | - | - | null |
1195  // | scl | | - | - | - | x | byref |
1196  // | scl | x | - | - | - | x | byref |
1197  //
1198  // | agg | n.a. | | | - | | byref |
1199  // | agg | n.a. | - | x | - | - | byref |
1200  // | agg | n.a. | x | - | - | - | null |
1201  // | agg | n.a. | - | - | - | x | byref |
1202  // | agg | n.a. | - | - | - | x[] | byref |
1203  //
1204  // | ptr | n.a. | | | - | | bycopy|
1205  // | ptr | n.a. | - | x | - | - | bycopy|
1206  // | ptr | n.a. | x | - | - | - | null |
1207  // | ptr | n.a. | - | - | - | x | byref |
1208  // | ptr | n.a. | - | - | - | x[] | bycopy|
1209  // | ptr | n.a. | - | - | x | | bycopy|
1210  // | ptr | n.a. | - | - | x | x | bycopy|
1211  // | ptr | n.a. | - | - | x | x[] | bycopy|
1212  // =========================================================================
1213  // Legend:
1214  // scl - scalar
1215  // ptr - pointer
1216  // agg - aggregate
1217  // x - applies
1218  // - - invalid in this combination
1219  // [] - mapped with an array section
1220  // byref - should be mapped by reference
1221  // byval - should be mapped by value
1222  // null - initialize a local variable to null on the device
1223  //
1224  // Observations:
1225  // - All scalar declarations that show up in a map clause have to be passed
1226  // by reference, because they may have been mapped in the enclosing data
1227  // environment.
1228  // - If the scalar value does not fit the size of uintptr, it has to be
1229  // passed by reference, regardless the result in the table above.
1230  // - For pointers mapped by value that have either an implicit map or an
1231  // array section, the runtime library may pass the NULL value to the
1232  // device instead of the value passed to it by the compiler.
1233 
1234  if (Ty->isReferenceType())
1235  Ty = Ty->castAs<ReferenceType>()->getPointeeType();
1236 
1237  // Locate map clauses and see if the variable being captured is referred to
1238  // in any of those clauses. Here we only care about variables, not fields,
1239  // because fields are part of aggregates.
1240  bool IsVariableUsedInMapClause = false;
1241  bool IsVariableAssociatedWithSection = false;
1242 
1243  DSAStack->checkMappableExprComponentListsForDeclAtLevel(
1245  MapExprComponents,
1246  OpenMPClauseKind WhereFoundClauseKind) {
1247  // Only the map clause information influences how a variable is
1248  // captured. E.g. is_device_ptr does not require changing the default
1249  // behavior.
1250  if (WhereFoundClauseKind != OMPC_map)
1251  return false;
1252 
1253  auto EI = MapExprComponents.rbegin();
1254  auto EE = MapExprComponents.rend();
1255 
1256  assert(EI != EE && "Invalid map expression!");
1257 
1258  if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
1259  IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
1260 
1261  ++EI;
1262  if (EI == EE)
1263  return false;
1264 
1265  if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
1266  isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
1267  isa<MemberExpr>(EI->getAssociatedExpression())) {
1268  IsVariableAssociatedWithSection = true;
1269  // There is nothing more we need to know about this variable.
1270  return true;
1271  }
1272 
1273  // Keep looking for more map info.
1274  return false;
1275  });
1276 
1277  if (IsVariableUsedInMapClause) {
1278  // If variable is identified in a map clause it is always captured by
1279  // reference except if it is a pointer that is dereferenced somehow.
1280  IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
1281  } else {
1282  // By default, all the data that has a scalar type is mapped by copy
1283  // (except for reduction variables).
1284  IsByRef =
1285  !Ty->isScalarType() ||
1286  DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar ||
1287  DSAStack->hasExplicitDSA(
1288  D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level);
1289  }
1290  }
1291 
1292  if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
1293  IsByRef =
1294  !DSAStack->hasExplicitDSA(
1295  D,
1296  [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; },
1297  Level, /*NotLastprivate=*/true) &&
1298  // If the variable is artificial and must be captured by value - try to
1299  // capture by value.
1300  !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
1301  !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue());
1302  }
1303 
1304  // When passing data by copy, we need to make sure it fits the uintptr size
1305  // and alignment, because the runtime library only deals with uintptr types.
1306  // If it does not fit the uintptr size, we need to pass the data by reference
1307  // instead.
1308  if (!IsByRef &&
1309  (Ctx.getTypeSizeInChars(Ty) >
1310  Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
1311  Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
1312  IsByRef = true;
1313  }
1314 
1315  return IsByRef;
1316 }
1317 
1318 unsigned Sema::getOpenMPNestingLevel() const {
1319  assert(getLangOpts().OpenMP);
1320  return DSAStack->getNestingLevel();
1321 }
1322 
1324  return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) &&
1325  !DSAStack->isClauseParsingMode()) ||
1326  DSAStack->hasDirective(
1328  SourceLocation) -> bool {
1329  return isOpenMPTargetExecutionDirective(K);
1330  },
1331  false);
1332 }
1333 
1335  assert(LangOpts.OpenMP && "OpenMP is not allowed");
1336  D = getCanonicalDecl(D);
1337 
1338  // If we are attempting to capture a global variable in a directive with
1339  // 'target' we return true so that this global is also mapped to the device.
1340  //
1341  // FIXME: If the declaration is enclosed in a 'declare target' directive,
1342  // then it should not be captured. Therefore, an extra check has to be
1343  // inserted here once support for 'declare target' is added.
1344  //
1345  auto *VD = dyn_cast<VarDecl>(D);
1346  if (VD && !VD->hasLocalStorage() && isInOpenMPTargetExecutionDirective())
1347  return VD;
1348 
1349  if (DSAStack->getCurrentDirective() != OMPD_unknown &&
1350  (!DSAStack->isClauseParsingMode() ||
1351  DSAStack->getParentDirective() != OMPD_unknown)) {
1352  auto &&Info = DSAStack->isLoopControlVariable(D);
1353  if (Info.first ||
1354  (VD && VD->hasLocalStorage() &&
1355  isParallelOrTaskRegion(DSAStack->getCurrentDirective())) ||
1356  (VD && DSAStack->isForceVarCapturing()))
1357  return VD ? VD : Info.second;
1358  auto DVarPrivate = DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
1359  if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind))
1360  return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1361  DVarPrivate = DSAStack->hasDSA(
1362  D, isOpenMPPrivate, [](OpenMPDirectiveKind) -> bool { return true; },
1363  DSAStack->isClauseParsingMode());
1364  if (DVarPrivate.CKind != OMPC_unknown)
1365  return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1366  }
1367  return nullptr;
1368 }
1369 
1370 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
1371  unsigned Level) const {
1373  getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level));
1374  FunctionScopesIndex -= Regions.size();
1375 }
1376 
1378  assert(LangOpts.OpenMP && "OpenMP is not allowed");
1379  return DSAStack->hasExplicitDSA(
1380  D, [](OpenMPClauseKind K) -> bool { return K == OMPC_private; },
1381  Level) ||
1382  (DSAStack->isClauseParsingMode() &&
1383  DSAStack->getClauseParsingMode() == OMPC_private) ||
1384  // Consider taskgroup reduction descriptor variable a private to avoid
1385  // possible capture in the region.
1386  (DSAStack->hasExplicitDirective(
1387  [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; },
1388  Level) &&
1389  DSAStack->isTaskgroupReductionRef(D, Level));
1390 }
1391 
1393  assert(LangOpts.OpenMP && "OpenMP is not allowed");
1394  D = getCanonicalDecl(D);
1396  for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) {
1397  const unsigned NewLevel = I - 1;
1398  if (DSAStack->hasExplicitDSA(D,
1399  [&OMPC](const OpenMPClauseKind K) {
1400  if (isOpenMPPrivate(K)) {
1401  OMPC = K;
1402  return true;
1403  }
1404  return false;
1405  },
1406  NewLevel))
1407  break;
1408  if (DSAStack->checkMappableExprComponentListsForDeclAtLevel(
1409  D, NewLevel,
1411  OpenMPClauseKind) { return true; })) {
1412  OMPC = OMPC_map;
1413  break;
1414  }
1415  if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
1416  NewLevel)) {
1417  OMPC = OMPC_firstprivate;
1418  break;
1419  }
1420  }
1421  if (OMPC != OMPC_unknown)
1422  FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC));
1423 }
1424 
1426  assert(LangOpts.OpenMP && "OpenMP is not allowed");
1427  // Return true if the current level is no longer enclosed in a target region.
1428 
1429  auto *VD = dyn_cast<VarDecl>(D);
1430  return VD && !VD->hasLocalStorage() &&
1431  DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
1432  Level);
1433 }
1434 
1435 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
1436 
1438  const DeclarationNameInfo &DirName,
1439  Scope *CurScope, SourceLocation Loc) {
1440  DSAStack->push(DKind, DirName, CurScope, Loc);
1441  PushExpressionEvaluationContext(
1442  ExpressionEvaluationContext::PotentiallyEvaluated);
1443 }
1444 
1446  DSAStack->setClauseParsingMode(K);
1447 }
1448 
1450  DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
1451 }
1452 
1453 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
1454  // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
1455  // A variable of class type (or array thereof) that appears in a lastprivate
1456  // clause requires an accessible, unambiguous default constructor for the
1457  // class type, unless the list item is also specified in a firstprivate
1458  // clause.
1459  if (auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
1460  for (auto *C : D->clauses()) {
1461  if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
1462  SmallVector<Expr *, 8> PrivateCopies;
1463  for (auto *DE : Clause->varlists()) {
1464  if (DE->isValueDependent() || DE->isTypeDependent()) {
1465  PrivateCopies.push_back(nullptr);
1466  continue;
1467  }
1468  auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
1469  VarDecl *VD = cast<VarDecl>(DRE->getDecl());
1470  QualType Type = VD->getType().getNonReferenceType();
1471  auto DVar = DSAStack->getTopDSA(VD, false);
1472  if (DVar.CKind == OMPC_lastprivate) {
1473  // Generate helper private variable and initialize it with the
1474  // default value. The address of the original variable is replaced
1475  // by the address of the new private variable in CodeGen. This new
1476  // variable is not added to IdResolver, so the code in the OpenMP
1477  // region uses original variable for proper diagnostics.
1478  auto *VDPrivate = buildVarDecl(
1479  *this, DE->getExprLoc(), Type.getUnqualifiedType(),
1480  VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr);
1481  ActOnUninitializedDecl(VDPrivate);
1482  if (VDPrivate->isInvalidDecl())
1483  continue;
1484  PrivateCopies.push_back(buildDeclRefExpr(
1485  *this, VDPrivate, DE->getType(), DE->getExprLoc()));
1486  } else {
1487  // The variable is also a firstprivate, so initialization sequence
1488  // for private copy is generated already.
1489  PrivateCopies.push_back(nullptr);
1490  }
1491  }
1492  // Set initializers to private copies if no errors were found.
1493  if (PrivateCopies.size() == Clause->varlist_size())
1494  Clause->setPrivateCopies(PrivateCopies);
1495  }
1496  }
1497  }
1498 
1499  DSAStack->pop();
1500  DiscardCleanupsInEvaluationContext();
1501  PopExpressionEvaluationContext();
1502 }
1503 
1504 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
1505  Expr *NumIterations, Sema &SemaRef,
1506  Scope *S, DSAStackTy *Stack);
1507 
1508 namespace {
1509 
1510 class VarDeclFilterCCC : public CorrectionCandidateCallback {
1511 private:
1512  Sema &SemaRef;
1513 
1514 public:
1515  explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
1516  bool ValidateCandidate(const TypoCorrection &Candidate) override {
1517  NamedDecl *ND = Candidate.getCorrectionDecl();
1518  if (auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
1519  return VD->hasGlobalStorage() &&
1520  SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
1521  SemaRef.getCurScope());
1522  }
1523  return false;
1524  }
1525 };
1526 
1527 class VarOrFuncDeclFilterCCC : public CorrectionCandidateCallback {
1528 private:
1529  Sema &SemaRef;
1530 
1531 public:
1532  explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
1533  bool ValidateCandidate(const TypoCorrection &Candidate) override {
1534  NamedDecl *ND = Candidate.getCorrectionDecl();
1535  if (ND && (isa<VarDecl>(ND) || isa<FunctionDecl>(ND))) {
1536  return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
1537  SemaRef.getCurScope());
1538  }
1539  return false;
1540  }
1541 };
1542 
1543 } // namespace
1544 
1546  CXXScopeSpec &ScopeSpec,
1547  const DeclarationNameInfo &Id) {
1548  LookupResult Lookup(*this, Id, LookupOrdinaryName);
1549  LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
1550 
1551  if (Lookup.isAmbiguous())
1552  return ExprError();
1553 
1554  VarDecl *VD;
1555  if (!Lookup.isSingleResult()) {
1556  if (TypoCorrection Corrected = CorrectTypo(
1557  Id, LookupOrdinaryName, CurScope, nullptr,
1558  llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) {
1559  diagnoseTypo(Corrected,
1560  PDiag(Lookup.empty()
1561  ? diag::err_undeclared_var_use_suggest
1562  : diag::err_omp_expected_var_arg_suggest)
1563  << Id.getName());
1564  VD = Corrected.getCorrectionDeclAs<VarDecl>();
1565  } else {
1566  Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
1567  : diag::err_omp_expected_var_arg)
1568  << Id.getName();
1569  return ExprError();
1570  }
1571  } else {
1572  if (!(VD = Lookup.getAsSingle<VarDecl>())) {
1573  Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
1574  Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
1575  return ExprError();
1576  }
1577  }
1578  Lookup.suppressDiagnostics();
1579 
1580  // OpenMP [2.9.2, Syntax, C/C++]
1581  // Variables must be file-scope, namespace-scope, or static block-scope.
1582  if (!VD->hasGlobalStorage()) {
1583  Diag(Id.getLoc(), diag::err_omp_global_var_arg)
1584  << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal();
1585  bool IsDecl =
1587  Diag(VD->getLocation(),
1588  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1589  << VD;
1590  return ExprError();
1591  }
1592 
1593  VarDecl *CanonicalVD = VD->getCanonicalDecl();
1594  NamedDecl *ND = cast<NamedDecl>(CanonicalVD);
1595  // OpenMP [2.9.2, Restrictions, C/C++, p.2]
1596  // A threadprivate directive for file-scope variables must appear outside
1597  // any definition or declaration.
1598  if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
1599  !getCurLexicalContext()->isTranslationUnit()) {
1600  Diag(Id.getLoc(), diag::err_omp_var_scope)
1601  << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1602  bool IsDecl =
1604  Diag(VD->getLocation(),
1605  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1606  << VD;
1607  return ExprError();
1608  }
1609  // OpenMP [2.9.2, Restrictions, C/C++, p.3]
1610  // A threadprivate directive for static class member variables must appear
1611  // in the class definition, in the same scope in which the member
1612  // variables are declared.
1613  if (CanonicalVD->isStaticDataMember() &&
1614  !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
1615  Diag(Id.getLoc(), diag::err_omp_var_scope)
1616  << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1617  bool IsDecl =
1619  Diag(VD->getLocation(),
1620  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1621  << VD;
1622  return ExprError();
1623  }
1624  // OpenMP [2.9.2, Restrictions, C/C++, p.4]
1625  // A threadprivate directive for namespace-scope variables must appear
1626  // outside any definition or declaration other than the namespace
1627  // definition itself.
1628  if (CanonicalVD->getDeclContext()->isNamespace() &&
1629  (!getCurLexicalContext()->isFileContext() ||
1630  !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
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  // OpenMP [2.9.2, Restrictions, C/C++, p.6]
1641  // A threadprivate directive for static block-scope variables must appear
1642  // in the scope of the variable and not in a nested scope.
1643  if (CanonicalVD->isStaticLocal() && CurScope &&
1644  !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
1645  Diag(Id.getLoc(), diag::err_omp_var_scope)
1646  << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1647  bool IsDecl =
1649  Diag(VD->getLocation(),
1650  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1651  << VD;
1652  return ExprError();
1653  }
1654 
1655  // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
1656  // A threadprivate directive must lexically precede all references to any
1657  // of the variables in its list.
1658  if (VD->isUsed() && !DSAStack->isThreadPrivate(VD)) {
1659  Diag(Id.getLoc(), diag::err_omp_var_used)
1660  << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1661  return ExprError();
1662  }
1663 
1664  QualType ExprType = VD->getType().getNonReferenceType();
1665  return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
1666  SourceLocation(), VD,
1667  /*RefersToEnclosingVariableOrCapture=*/false,
1668  Id.getLoc(), ExprType, VK_LValue);
1669 }
1670 
1673  ArrayRef<Expr *> VarList) {
1674  if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
1675  CurContext->addDecl(D);
1676  return DeclGroupPtrTy::make(DeclGroupRef(D));
1677  }
1678  return nullptr;
1679 }
1680 
1681 namespace {
1682 class LocalVarRefChecker : public ConstStmtVisitor<LocalVarRefChecker, bool> {
1683  Sema &SemaRef;
1684 
1685 public:
1686  bool VisitDeclRefExpr(const DeclRefExpr *E) {
1687  if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
1688  if (VD->hasLocalStorage()) {
1689  SemaRef.Diag(E->getLocStart(),
1690  diag::err_omp_local_var_in_threadprivate_init)
1691  << E->getSourceRange();
1692  SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
1693  << VD << VD->getSourceRange();
1694  return true;
1695  }
1696  }
1697  return false;
1698  }
1699  bool VisitStmt(const Stmt *S) {
1700  for (auto Child : S->children()) {
1701  if (Child && Visit(Child))
1702  return true;
1703  }
1704  return false;
1705  }
1706  explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
1707 };
1708 } // namespace
1709 
1713  for (auto &RefExpr : VarList) {
1714  DeclRefExpr *DE = cast<DeclRefExpr>(RefExpr);
1715  VarDecl *VD = cast<VarDecl>(DE->getDecl());
1716  SourceLocation ILoc = DE->getExprLoc();
1717 
1718  // Mark variable as used.
1719  VD->setReferenced();
1720  VD->markUsed(Context);
1721 
1722  QualType QType = VD->getType();
1723  if (QType->isDependentType() || QType->isInstantiationDependentType()) {
1724  // It will be analyzed later.
1725  Vars.push_back(DE);
1726  continue;
1727  }
1728 
1729  // OpenMP [2.9.2, Restrictions, C/C++, p.10]
1730  // A threadprivate variable must not have an incomplete type.
1731  if (RequireCompleteType(ILoc, VD->getType(),
1732  diag::err_omp_threadprivate_incomplete_type)) {
1733  continue;
1734  }
1735 
1736  // OpenMP [2.9.2, Restrictions, C/C++, p.10]
1737  // A threadprivate variable must not have a reference type.
1738  if (VD->getType()->isReferenceType()) {
1739  Diag(ILoc, diag::err_omp_ref_type_arg)
1740  << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
1741  bool IsDecl =
1742  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1743  Diag(VD->getLocation(),
1744  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1745  << VD;
1746  continue;
1747  }
1748 
1749  // Check if this is a TLS variable. If TLS is not being supported, produce
1750  // the corresponding diagnostic.
1751  if ((VD->getTLSKind() != VarDecl::TLS_None &&
1752  !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1753  getLangOpts().OpenMPUseTLS &&
1754  getASTContext().getTargetInfo().isTLSSupported())) ||
1755  (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
1756  !VD->isLocalVarDecl())) {
1757  Diag(ILoc, diag::err_omp_var_thread_local)
1758  << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
1759  bool IsDecl =
1760  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
1761  Diag(VD->getLocation(),
1762  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1763  << VD;
1764  continue;
1765  }
1766 
1767  // Check if initial value of threadprivate variable reference variable with
1768  // local storage (it is not supported by runtime).
1769  if (auto Init = VD->getAnyInitializer()) {
1770  LocalVarRefChecker Checker(*this);
1771  if (Checker.Visit(Init))
1772  continue;
1773  }
1774 
1775  Vars.push_back(RefExpr);
1776  DSAStack->addDSA(VD, DE, OMPC_threadprivate);
1777  VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
1778  Context, SourceRange(Loc, Loc)));
1779  if (auto *ML = Context.getASTMutationListener())
1780  ML->DeclarationMarkedOpenMPThreadPrivate(VD);
1781  }
1782  OMPThreadPrivateDecl *D = nullptr;
1783  if (!Vars.empty()) {
1784  D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
1785  Vars);
1786  D->setAccess(AS_public);
1787  }
1788  return D;
1789 }
1790 
1791 static void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack,
1792  const ValueDecl *D, DSAStackTy::DSAVarData DVar,
1793  bool IsLoopIterVar = false) {
1794  if (DVar.RefExpr) {
1795  SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
1796  << getOpenMPClauseName(DVar.CKind);
1797  return;
1798  }
1799  enum {
1800  PDSA_StaticMemberShared,
1801  PDSA_StaticLocalVarShared,
1802  PDSA_LoopIterVarPrivate,
1803  PDSA_LoopIterVarLinear,
1804  PDSA_LoopIterVarLastprivate,
1805  PDSA_ConstVarShared,
1806  PDSA_GlobalVarShared,
1807  PDSA_TaskVarFirstprivate,
1808  PDSA_LocalVarPrivate,
1809  PDSA_Implicit
1810  } Reason = PDSA_Implicit;
1811  bool ReportHint = false;
1812  auto ReportLoc = D->getLocation();
1813  auto *VD = dyn_cast<VarDecl>(D);
1814  if (IsLoopIterVar) {
1815  if (DVar.CKind == OMPC_private)
1816  Reason = PDSA_LoopIterVarPrivate;
1817  else if (DVar.CKind == OMPC_lastprivate)
1818  Reason = PDSA_LoopIterVarLastprivate;
1819  else
1820  Reason = PDSA_LoopIterVarLinear;
1821  } else if (isOpenMPTaskingDirective(DVar.DKind) &&
1822  DVar.CKind == OMPC_firstprivate) {
1823  Reason = PDSA_TaskVarFirstprivate;
1824  ReportLoc = DVar.ImplicitDSALoc;
1825  } else if (VD && VD->isStaticLocal())
1826  Reason = PDSA_StaticLocalVarShared;
1827  else if (VD && VD->isStaticDataMember())
1828  Reason = PDSA_StaticMemberShared;
1829  else if (VD && VD->isFileVarDecl())
1830  Reason = PDSA_GlobalVarShared;
1831  else if (D->getType().isConstant(SemaRef.getASTContext()))
1832  Reason = PDSA_ConstVarShared;
1833  else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
1834  ReportHint = true;
1835  Reason = PDSA_LocalVarPrivate;
1836  }
1837  if (Reason != PDSA_Implicit) {
1838  SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
1839  << Reason << ReportHint
1840  << getOpenMPDirectiveName(Stack->getCurrentDirective());
1841  } else if (DVar.ImplicitDSALoc.isValid()) {
1842  SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
1843  << getOpenMPClauseName(DVar.CKind);
1844  }
1845 }
1846 
1847 namespace {
1848 class DSAAttrChecker : public StmtVisitor<DSAAttrChecker, void> {
1849  DSAStackTy *Stack;
1850  Sema &SemaRef;
1851  bool ErrorFound;
1852  CapturedStmt *CS;
1853  llvm::SmallVector<Expr *, 8> ImplicitFirstprivate;
1854  llvm::SmallVector<Expr *, 8> ImplicitMap;
1855  llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA;
1856  llvm::DenseSet<ValueDecl *> ImplicitDeclarations;
1857 
1858 public:
1859  void VisitDeclRefExpr(DeclRefExpr *E) {
1860  if (E->isTypeDependent() || E->isValueDependent() ||
1862  return;
1863  if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
1864  VD = VD->getCanonicalDecl();
1865  // Skip internally declared variables.
1866  if (VD->hasLocalStorage() && !CS->capturesVariable(VD))
1867  return;
1868 
1869  auto DVar = Stack->getTopDSA(VD, false);
1870  // Check if the variable has explicit DSA set and stop analysis if it so.
1871  if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
1872  return;
1873 
1874  // Skip internally declared static variables.
1875  if (VD->hasGlobalStorage() && !CS->capturesVariable(VD))
1876  return;
1877 
1878  auto ELoc = E->getExprLoc();
1879  auto DKind = Stack->getCurrentDirective();
1880  // The default(none) clause requires that each variable that is referenced
1881  // in the construct, and does not have a predetermined data-sharing
1882  // attribute, must have its data-sharing attribute explicitly determined
1883  // by being listed in a data-sharing attribute clause.
1884  if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none &&
1885  isParallelOrTaskRegion(DKind) &&
1886  VarsWithInheritedDSA.count(VD) == 0) {
1887  VarsWithInheritedDSA[VD] = E;
1888  return;
1889  }
1890 
1891  if (isOpenMPTargetExecutionDirective(DKind) &&
1892  !Stack->isLoopControlVariable(VD).first) {
1893  if (!Stack->checkMappableExprComponentListsForDecl(
1894  VD, /*CurrentRegionOnly=*/true,
1896  StackComponents,
1897  OpenMPClauseKind) {
1898  // Variable is used if it has been marked as an array, array
1899  // section or the variable iself.
1900  return StackComponents.size() == 1 ||
1901  std::all_of(
1902  std::next(StackComponents.rbegin()),
1903  StackComponents.rend(),
1904  [](const OMPClauseMappableExprCommon::
1905  MappableComponent &MC) {
1906  return MC.getAssociatedDeclaration() ==
1907  nullptr &&
1908  (isa<OMPArraySectionExpr>(
1909  MC.getAssociatedExpression()) ||
1910  isa<ArraySubscriptExpr>(
1911  MC.getAssociatedExpression()));
1912  });
1913  })) {
1914  bool IsFirstprivate = false;
1915  // By default lambdas are captured as firstprivates.
1916  if (const auto *RD =
1917  VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
1918  IsFirstprivate = RD->isLambda();
1919  IsFirstprivate =
1920  IsFirstprivate ||
1921  (VD->getType().getNonReferenceType()->isScalarType() &&
1922  Stack->getDefaultDMA() != DMA_tofrom_scalar);
1923  if (IsFirstprivate)
1924  ImplicitFirstprivate.emplace_back(E);
1925  else
1926  ImplicitMap.emplace_back(E);
1927  return;
1928  }
1929  }
1930 
1931  // OpenMP [2.9.3.6, Restrictions, p.2]
1932  // A list item that appears in a reduction clause of the innermost
1933  // enclosing worksharing or parallel construct may not be accessed in an
1934  // explicit task.
1935  DVar = Stack->hasInnermostDSA(
1936  VD, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; },
1937  [](OpenMPDirectiveKind K) -> bool {
1938  return isOpenMPParallelDirective(K) ||
1940  },
1941  /*FromParent=*/true);
1942  if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
1943  ErrorFound = true;
1944  SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
1945  ReportOriginalDSA(SemaRef, Stack, VD, DVar);
1946  return;
1947  }
1948 
1949  // Define implicit data-sharing attributes for task.
1950  DVar = Stack->getImplicitDSA(VD, false);
1951  if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
1952  !Stack->isLoopControlVariable(VD).first)
1953  ImplicitFirstprivate.push_back(E);
1954  }
1955  }
1956  void VisitMemberExpr(MemberExpr *E) {
1957  if (E->isTypeDependent() || E->isValueDependent() ||
1959  return;
1960  auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
1961  OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
1962  if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
1963  if (!FD)
1964  return;
1965  auto DVar = Stack->getTopDSA(FD, false);
1966  // Check if the variable has explicit DSA set and stop analysis if it
1967  // so.
1968  if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
1969  return;
1970 
1971  if (isOpenMPTargetExecutionDirective(DKind) &&
1972  !Stack->isLoopControlVariable(FD).first &&
1973  !Stack->checkMappableExprComponentListsForDecl(
1974  FD, /*CurrentRegionOnly=*/true,
1976  StackComponents,
1977  OpenMPClauseKind) {
1978  return isa<CXXThisExpr>(
1979  cast<MemberExpr>(
1980  StackComponents.back().getAssociatedExpression())
1981  ->getBase()
1982  ->IgnoreParens());
1983  })) {
1984  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
1985  // A bit-field cannot appear in a map clause.
1986  //
1987  if (FD->isBitField())
1988  return;
1989  ImplicitMap.emplace_back(E);
1990  return;
1991  }
1992 
1993  auto ELoc = E->getExprLoc();
1994  // OpenMP [2.9.3.6, Restrictions, p.2]
1995  // A list item that appears in a reduction clause of the innermost
1996  // enclosing worksharing or parallel construct may not be accessed in
1997  // an explicit task.
1998  DVar = Stack->hasInnermostDSA(
1999  FD, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; },
2000  [](OpenMPDirectiveKind K) -> bool {
2001  return isOpenMPParallelDirective(K) ||
2003  },
2004  /*FromParent=*/true);
2005  if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
2006  ErrorFound = true;
2007  SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
2008  ReportOriginalDSA(SemaRef, Stack, FD, DVar);
2009  return;
2010  }
2011 
2012  // Define implicit data-sharing attributes for task.
2013  DVar = Stack->getImplicitDSA(FD, false);
2014  if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
2015  !Stack->isLoopControlVariable(FD).first)
2016  ImplicitFirstprivate.push_back(E);
2017  return;
2018  }
2019  if (isOpenMPTargetExecutionDirective(DKind)) {
2021  if (!CheckMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
2022  /*NoDiagnose=*/true))
2023  return;
2024  auto *VD = cast<ValueDecl>(
2025  CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
2026  if (!Stack->checkMappableExprComponentListsForDecl(
2027  VD, /*CurrentRegionOnly=*/true,
2028  [&CurComponents](
2030  StackComponents,
2031  OpenMPClauseKind) {
2032  auto CCI = CurComponents.rbegin();
2033  auto CCE = CurComponents.rend();
2034  for (const auto &SC : llvm::reverse(StackComponents)) {
2035  // Do both expressions have the same kind?
2036  if (CCI->getAssociatedExpression()->getStmtClass() !=
2037  SC.getAssociatedExpression()->getStmtClass())
2038  if (!(isa<OMPArraySectionExpr>(
2039  SC.getAssociatedExpression()) &&
2040  isa<ArraySubscriptExpr>(
2041  CCI->getAssociatedExpression())))
2042  return false;
2043 
2044  Decl *CCD = CCI->getAssociatedDeclaration();
2045  Decl *SCD = SC.getAssociatedDeclaration();
2046  CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
2047  SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
2048  if (SCD != CCD)
2049  return false;
2050  std::advance(CCI, 1);
2051  if (CCI == CCE)
2052  break;
2053  }
2054  return true;
2055  })) {
2056  Visit(E->getBase());
2057  }
2058  } else
2059  Visit(E->getBase());
2060  }
2061  void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
2062  for (auto *C : S->clauses()) {
2063  // Skip analysis of arguments of implicitly defined firstprivate clause
2064  // for task|target directives.
2065  // Skip analysis of arguments of implicitly defined map clause for target
2066  // directives.
2067  if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
2068  C->isImplicit())) {
2069  for (auto *CC : C->children()) {
2070  if (CC)
2071  Visit(CC);
2072  }
2073  }
2074  }
2075  }
2076  void VisitStmt(Stmt *S) {
2077  for (auto *C : S->children()) {
2078  if (C && !isa<OMPExecutableDirective>(C))
2079  Visit(C);
2080  }
2081  }
2082 
2083  bool isErrorFound() { return ErrorFound; }
2084  ArrayRef<Expr *> getImplicitFirstprivate() const {
2085  return ImplicitFirstprivate;
2086  }
2087  ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; }
2088  llvm::DenseMap<ValueDecl *, Expr *> &getVarsWithInheritedDSA() {
2089  return VarsWithInheritedDSA;
2090  }
2091 
2092  DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
2093  : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {}
2094 };
2095 } // namespace
2096 
2098  switch (DKind) {
2099  case OMPD_parallel:
2100  case OMPD_parallel_for:
2101  case OMPD_parallel_for_simd:
2102  case OMPD_parallel_sections:
2103  case OMPD_teams:
2104  case OMPD_teams_distribute:
2105  case OMPD_teams_distribute_simd: {
2106  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2107  QualType KmpInt32PtrTy =
2108  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2109  Sema::CapturedParamNameType Params[] = {
2110  std::make_pair(".global_tid.", KmpInt32PtrTy),
2111  std::make_pair(".bound_tid.", KmpInt32PtrTy),
2112  std::make_pair(StringRef(), QualType()) // __context with shared vars
2113  };
2114  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2115  Params);
2116  break;
2117  }
2118  case OMPD_target_teams:
2119  case OMPD_target_parallel:
2120  case OMPD_target_parallel_for:
2121  case OMPD_target_parallel_for_simd:
2122  case OMPD_target_teams_distribute:
2123  case OMPD_target_teams_distribute_simd: {
2124  Sema::CapturedParamNameType ParamsTarget[] = {
2125  std::make_pair(StringRef(), QualType()) // __context with shared vars
2126  };
2127  // Start a captured region for 'target' with no implicit parameters.
2128  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2129  ParamsTarget);
2130  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2131  QualType KmpInt32PtrTy =
2132  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2133  Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
2134  std::make_pair(".global_tid.", KmpInt32PtrTy),
2135  std::make_pair(".bound_tid.", KmpInt32PtrTy),
2136  std::make_pair(StringRef(), QualType()) // __context with shared vars
2137  };
2138  // Start a captured region for 'teams' or 'parallel'. Both regions have
2139  // the same implicit parameters.
2140  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2141  ParamsTeamsOrParallel);
2142  break;
2143  }
2144  case OMPD_simd:
2145  case OMPD_for:
2146  case OMPD_for_simd:
2147  case OMPD_sections:
2148  case OMPD_section:
2149  case OMPD_single:
2150  case OMPD_master:
2151  case OMPD_critical:
2152  case OMPD_taskgroup:
2153  case OMPD_distribute:
2154  case OMPD_distribute_simd:
2155  case OMPD_ordered:
2156  case OMPD_atomic:
2157  case OMPD_target_data:
2158  case OMPD_target:
2159  case OMPD_target_simd: {
2160  Sema::CapturedParamNameType Params[] = {
2161  std::make_pair(StringRef(), QualType()) // __context with shared vars
2162  };
2163  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2164  Params);
2165  break;
2166  }
2167  case OMPD_task: {
2168  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2169  QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()};
2171  EPI.Variadic = true;
2172  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2173  Sema::CapturedParamNameType Params[] = {
2174  std::make_pair(".global_tid.", KmpInt32Ty),
2175  std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)),
2176  std::make_pair(".privates.", Context.VoidPtrTy.withConst()),
2177  std::make_pair(".copy_fn.",
2178  Context.getPointerType(CopyFnType).withConst()),
2179  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2180  std::make_pair(StringRef(), QualType()) // __context with shared vars
2181  };
2182  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2183  Params);
2184  // Mark this captured region as inlined, because we don't use outlined
2185  // function directly.
2186  getCurCapturedRegion()->TheCapturedDecl->addAttr(
2187  AlwaysInlineAttr::CreateImplicit(
2188  Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange()));
2189  break;
2190  }
2191  case OMPD_taskloop:
2192  case OMPD_taskloop_simd: {
2193  QualType KmpInt32Ty =
2194  Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1);
2195  QualType KmpUInt64Ty =
2196  Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
2197  QualType KmpInt64Ty =
2198  Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
2199  QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()};
2201  EPI.Variadic = true;
2202  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2203  Sema::CapturedParamNameType Params[] = {
2204  std::make_pair(".global_tid.", KmpInt32Ty),
2205  std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)),
2206  std::make_pair(".privates.",
2207  Context.VoidPtrTy.withConst().withRestrict()),
2208  std::make_pair(
2209  ".copy_fn.",
2210  Context.getPointerType(CopyFnType).withConst().withRestrict()),
2211  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2212  std::make_pair(".lb.", KmpUInt64Ty),
2213  std::make_pair(".ub.", KmpUInt64Ty), std::make_pair(".st.", KmpInt64Ty),
2214  std::make_pair(".liter.", KmpInt32Ty),
2215  std::make_pair(".reductions.",
2216  Context.VoidPtrTy.withConst().withRestrict()),
2217  std::make_pair(StringRef(), QualType()) // __context with shared vars
2218  };
2219  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2220  Params);
2221  // Mark this captured region as inlined, because we don't use outlined
2222  // function directly.
2223  getCurCapturedRegion()->TheCapturedDecl->addAttr(
2224  AlwaysInlineAttr::CreateImplicit(
2225  Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange()));
2226  break;
2227  }
2228  case OMPD_distribute_parallel_for_simd:
2229  case OMPD_distribute_parallel_for:
2230  case OMPD_target_teams_distribute_parallel_for:
2231  case OMPD_target_teams_distribute_parallel_for_simd: {
2232  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2233  QualType KmpInt32PtrTy =
2234  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2235  Sema::CapturedParamNameType Params[] = {
2236  std::make_pair(".global_tid.", KmpInt32PtrTy),
2237  std::make_pair(".bound_tid.", KmpInt32PtrTy),
2238  std::make_pair(".previous.lb.", Context.getSizeType()),
2239  std::make_pair(".previous.ub.", Context.getSizeType()),
2240  std::make_pair(StringRef(), QualType()) // __context with shared vars
2241  };
2242  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2243  Params);
2244  break;
2245  }
2246  case OMPD_teams_distribute_parallel_for:
2247  case OMPD_teams_distribute_parallel_for_simd: {
2248  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2249  QualType KmpInt32PtrTy =
2250  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2251 
2252  Sema::CapturedParamNameType ParamsTeams[] = {
2253  std::make_pair(".global_tid.", KmpInt32PtrTy),
2254  std::make_pair(".bound_tid.", KmpInt32PtrTy),
2255  std::make_pair(StringRef(), QualType()) // __context with shared vars
2256  };
2257  // Start a captured region for 'target' with no implicit parameters.
2258  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2259  ParamsTeams);
2260 
2261  Sema::CapturedParamNameType ParamsParallel[] = {
2262  std::make_pair(".global_tid.", KmpInt32PtrTy),
2263  std::make_pair(".bound_tid.", KmpInt32PtrTy),
2264  std::make_pair(".previous.lb.", Context.getSizeType()),
2265  std::make_pair(".previous.ub.", Context.getSizeType()),
2266  std::make_pair(StringRef(), QualType()) // __context with shared vars
2267  };
2268  // Start a captured region for 'teams' or 'parallel'. Both regions have
2269  // the same implicit parameters.
2270  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2271  ParamsParallel);
2272  break;
2273  }
2274  case OMPD_target_update:
2275  case OMPD_target_enter_data:
2276  case OMPD_target_exit_data: {
2277  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1);
2278  QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()};
2280  EPI.Variadic = true;
2281  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2282  Sema::CapturedParamNameType Params[] = {
2283  std::make_pair(".global_tid.", KmpInt32Ty),
2284  std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)),
2285  std::make_pair(".privates.", Context.VoidPtrTy.withConst()),
2286  std::make_pair(".copy_fn.",
2287  Context.getPointerType(CopyFnType).withConst()),
2288  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2289  std::make_pair(StringRef(), QualType()) // __context with shared vars
2290  };
2291  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2292  Params);
2293  // Mark this captured region as inlined, because we don't use outlined
2294  // function directly.
2295  getCurCapturedRegion()->TheCapturedDecl->addAttr(
2296  AlwaysInlineAttr::CreateImplicit(
2297  Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange()));
2298  break;
2299  }
2300  case OMPD_threadprivate:
2301  case OMPD_taskyield:
2302  case OMPD_barrier:
2303  case OMPD_taskwait:
2304  case OMPD_cancellation_point:
2305  case OMPD_cancel:
2306  case OMPD_flush:
2307  case OMPD_declare_reduction:
2308  case OMPD_declare_simd:
2309  case OMPD_declare_target:
2310  case OMPD_end_declare_target:
2311  llvm_unreachable("OpenMP Directive is not allowed");
2312  case OMPD_unknown:
2313  llvm_unreachable("Unknown OpenMP directive");
2314  }
2315 }
2316 
2318  SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2319  getOpenMPCaptureRegions(CaptureRegions, DKind);
2320  return CaptureRegions.size();
2321 }
2322 
2324  Expr *CaptureExpr, bool WithInit,
2325  bool AsExpression) {
2326  assert(CaptureExpr);
2327  ASTContext &C = S.getASTContext();
2328  Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
2329  QualType Ty = Init->getType();
2330  if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
2331  if (S.getLangOpts().CPlusPlus) {
2332  Ty = C.getLValueReferenceType(Ty);
2333  } else {
2334  Ty = C.getPointerType(Ty);
2335  ExprResult Res =
2336  S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
2337  if (!Res.isUsable())
2338  return nullptr;
2339  Init = Res.get();
2340  }
2341  WithInit = true;
2342  }
2343  auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
2344  CaptureExpr->getLocStart());
2345  if (!WithInit)
2346  CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C, SourceRange()));
2347  S.CurContext->addHiddenDecl(CED);
2348  S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
2349  return CED;
2350 }
2351 
2352 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2353  bool WithInit) {
2354  OMPCapturedExprDecl *CD;
2355  if (auto *VD = S.IsOpenMPCapturedDecl(D)) {
2356  CD = cast<OMPCapturedExprDecl>(VD);
2357  } else {
2358  CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
2359  /*AsExpression=*/false);
2360  }
2361  return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
2362  CaptureExpr->getExprLoc());
2363 }
2364 
2365 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
2366  CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
2367  if (!Ref) {
2369  S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
2370  /*WithInit=*/true, /*AsExpression=*/true);
2371  Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
2372  CaptureExpr->getExprLoc());
2373  }
2374  ExprResult Res = Ref;
2375  if (!S.getLangOpts().CPlusPlus &&
2376  CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
2377  Ref->getType()->isPointerType()) {
2378  Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
2379  if (!Res.isUsable())
2380  return ExprError();
2381  }
2382  return S.DefaultLvalueConversion(Res.get());
2383 }
2384 
2385 namespace {
2386 // OpenMP directives parsed in this section are represented as a
2387 // CapturedStatement with an associated statement. If a syntax error
2388 // is detected during the parsing of the associated statement, the
2389 // compiler must abort processing and close the CapturedStatement.
2390 //
2391 // Combined directives such as 'target parallel' have more than one
2392 // nested CapturedStatements. This RAII ensures that we unwind out
2393 // of all the nested CapturedStatements when an error is found.
2394 class CaptureRegionUnwinderRAII {
2395 private:
2396  Sema &S;
2397  bool &ErrorFound;
2398  OpenMPDirectiveKind DKind;
2399 
2400 public:
2401  CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
2402  OpenMPDirectiveKind DKind)
2403  : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
2404  ~CaptureRegionUnwinderRAII() {
2405  if (ErrorFound) {
2406  int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
2407  while (--ThisCaptureLevel >= 0)
2409  }
2410  }
2411 };
2412 } // namespace
2413 
2415  ArrayRef<OMPClause *> Clauses) {
2416  bool ErrorFound = false;
2417  CaptureRegionUnwinderRAII CaptureRegionUnwinder(
2418  *this, ErrorFound, DSAStack->getCurrentDirective());
2419  if (!S.isUsable()) {
2420  ErrorFound = true;
2421  return StmtError();
2422  }
2423 
2424  SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2425  getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective());
2426  OMPOrderedClause *OC = nullptr;
2427  OMPScheduleClause *SC = nullptr;
2430  // This is required for proper codegen.
2431  for (auto *Clause : Clauses) {
2432  if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
2433  Clause->getClauseKind() == OMPC_in_reduction) {
2434  // Capture taskgroup task_reduction descriptors inside the tasking regions
2435  // with the corresponding in_reduction items.
2436  auto *IRC = cast<OMPInReductionClause>(Clause);
2437  for (auto *E : IRC->taskgroup_descriptors())
2438  if (E)
2439  MarkDeclarationsReferencedInExpr(E);
2440  }
2441  if (isOpenMPPrivate(Clause->getClauseKind()) ||
2442  Clause->getClauseKind() == OMPC_copyprivate ||
2443  (getLangOpts().OpenMPUseTLS &&
2444  getASTContext().getTargetInfo().isTLSSupported() &&
2445  Clause->getClauseKind() == OMPC_copyin)) {
2446  DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
2447  // Mark all variables in private list clauses as used in inner region.
2448  for (auto *VarRef : Clause->children()) {
2449  if (auto *E = cast_or_null<Expr>(VarRef)) {
2450  MarkDeclarationsReferencedInExpr(E);
2451  }
2452  }
2453  DSAStack->setForceVarCapturing(/*V=*/false);
2454  } else if (CaptureRegions.size() > 1 ||
2455  CaptureRegions.back() != OMPD_unknown) {
2456  if (auto *C = OMPClauseWithPreInit::get(Clause))
2457  PICs.push_back(C);
2458  if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
2459  if (auto *E = C->getPostUpdateExpr())
2460  MarkDeclarationsReferencedInExpr(E);
2461  }
2462  }
2463  if (Clause->getClauseKind() == OMPC_schedule)
2464  SC = cast<OMPScheduleClause>(Clause);
2465  else if (Clause->getClauseKind() == OMPC_ordered)
2466  OC = cast<OMPOrderedClause>(Clause);
2467  else if (Clause->getClauseKind() == OMPC_linear)
2468  LCs.push_back(cast<OMPLinearClause>(Clause));
2469  }
2470  // OpenMP, 2.7.1 Loop Construct, Restrictions
2471  // The nonmonotonic modifier cannot be specified if an ordered clause is
2472  // specified.
2473  if (SC &&
2474  (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
2475  SC->getSecondScheduleModifier() ==
2476  OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
2477  OC) {
2478  Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
2481  diag::err_omp_schedule_nonmonotonic_ordered)
2482  << SourceRange(OC->getLocStart(), OC->getLocEnd());
2483  ErrorFound = true;
2484  }
2485  if (!LCs.empty() && OC && OC->getNumForLoops()) {
2486  for (auto *C : LCs) {
2487  Diag(C->getLocStart(), diag::err_omp_linear_ordered)
2488  << SourceRange(OC->getLocStart(), OC->getLocEnd());
2489  }
2490  ErrorFound = true;
2491  }
2492  if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
2493  isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
2494  OC->getNumForLoops()) {
2495  Diag(OC->getLocStart(), diag::err_omp_ordered_simd)
2496  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
2497  ErrorFound = true;
2498  }
2499  if (ErrorFound) {
2500  return StmtError();
2501  }
2502  StmtResult SR = S;
2503  for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
2504  // Mark all variables in private list clauses as used in inner region.
2505  // Required for proper codegen of combined directives.
2506  // TODO: add processing for other clauses.
2507  if (ThisCaptureRegion != OMPD_unknown) {
2508  for (auto *C : PICs) {
2509  OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
2510  // Find the particular capture region for the clause if the
2511  // directive is a combined one with multiple capture regions.
2512  // If the directive is not a combined one, the capture region
2513  // associated with the clause is OMPD_unknown and is generated
2514  // only once.
2515  if (CaptureRegion == ThisCaptureRegion ||
2516  CaptureRegion == OMPD_unknown) {
2517  if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
2518  for (auto *D : DS->decls())
2519  MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
2520  }
2521  }
2522  }
2523  }
2524  SR = ActOnCapturedRegionEnd(SR.get());
2525  }
2526  return SR;
2527 }
2528 
2529 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
2530  OpenMPDirectiveKind CancelRegion,
2531  SourceLocation StartLoc) {
2532  // CancelRegion is only needed for cancel and cancellation_point.
2533  if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
2534  return false;
2535 
2536  if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
2537  CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
2538  return false;
2539 
2540  SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
2541  << getOpenMPDirectiveName(CancelRegion);
2542  return true;
2543 }
2544 
2545 static bool checkNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack,
2546  OpenMPDirectiveKind CurrentRegion,
2547  const DeclarationNameInfo &CurrentName,
2548  OpenMPDirectiveKind CancelRegion,
2549  SourceLocation StartLoc) {
2550  if (Stack->getCurScope()) {
2551  auto ParentRegion = Stack->getParentDirective();
2552  auto OffendingRegion = ParentRegion;
2553  bool NestingProhibited = false;
2554  bool CloseNesting = true;
2555  bool OrphanSeen = false;
2556  enum {
2557  NoRecommend,
2558  ShouldBeInParallelRegion,
2559  ShouldBeInOrderedRegion,
2560  ShouldBeInTargetRegion,
2561  ShouldBeInTeamsRegion
2562  } Recommend = NoRecommend;
2563  if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) {
2564  // OpenMP [2.16, Nesting of Regions]
2565  // OpenMP constructs may not be nested inside a simd region.
2566  // OpenMP [2.8.1,simd Construct, Restrictions]
2567  // An ordered construct with the simd clause is the only OpenMP
2568  // construct that can appear in the simd region.
2569  // Allowing a SIMD construct nested in another SIMD construct is an
2570  // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
2571  // message.
2572  SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
2573  ? diag::err_omp_prohibited_region_simd
2574  : diag::warn_omp_nesting_simd);
2575  return CurrentRegion != OMPD_simd;
2576  }
2577  if (ParentRegion == OMPD_atomic) {
2578  // OpenMP [2.16, Nesting of Regions]
2579  // OpenMP constructs may not be nested inside an atomic region.
2580  SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
2581  return true;
2582  }
2583  if (CurrentRegion == OMPD_section) {
2584  // OpenMP [2.7.2, sections Construct, Restrictions]
2585  // Orphaned section directives are prohibited. That is, the section
2586  // directives must appear within the sections construct and must not be
2587  // encountered elsewhere in the sections region.
2588  if (ParentRegion != OMPD_sections &&
2589  ParentRegion != OMPD_parallel_sections) {
2590  SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
2591  << (ParentRegion != OMPD_unknown)
2592  << getOpenMPDirectiveName(ParentRegion);
2593  return true;
2594  }
2595  return false;
2596  }
2597  // Allow some constructs (except teams) to be orphaned (they could be
2598  // used in functions, called from OpenMP regions with the required
2599  // preconditions).
2600  if (ParentRegion == OMPD_unknown &&
2601  !isOpenMPNestingTeamsDirective(CurrentRegion))
2602  return false;
2603  if (CurrentRegion == OMPD_cancellation_point ||
2604  CurrentRegion == OMPD_cancel) {
2605  // OpenMP [2.16, Nesting of Regions]
2606  // A cancellation point construct for which construct-type-clause is
2607  // taskgroup must be nested inside a task construct. A cancellation
2608  // point construct for which construct-type-clause is not taskgroup must
2609  // be closely nested inside an OpenMP construct that matches the type
2610  // specified in construct-type-clause.
2611  // A cancel construct for which construct-type-clause is taskgroup must be
2612  // nested inside a task construct. A cancel construct for which
2613  // construct-type-clause is not taskgroup must be closely nested inside an
2614  // OpenMP construct that matches the type specified in
2615  // construct-type-clause.
2616  NestingProhibited =
2617  !((CancelRegion == OMPD_parallel &&
2618  (ParentRegion == OMPD_parallel ||
2619  ParentRegion == OMPD_target_parallel)) ||
2620  (CancelRegion == OMPD_for &&
2621  (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
2622  ParentRegion == OMPD_target_parallel_for ||
2623  ParentRegion == OMPD_distribute_parallel_for ||
2624  ParentRegion == OMPD_teams_distribute_parallel_for ||
2625  ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
2626  (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) ||
2627  (CancelRegion == OMPD_sections &&
2628  (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
2629  ParentRegion == OMPD_parallel_sections)));
2630  } else if (CurrentRegion == OMPD_master) {
2631  // OpenMP [2.16, Nesting of Regions]
2632  // A master region may not be closely nested inside a worksharing,
2633  // atomic, or explicit task region.
2634  NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
2635  isOpenMPTaskingDirective(ParentRegion);
2636  } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
2637  // OpenMP [2.16, Nesting of Regions]
2638  // A critical region may not be nested (closely or otherwise) inside a
2639  // critical region with the same name. Note that this restriction is not
2640  // sufficient to prevent deadlock.
2641  SourceLocation PreviousCriticalLoc;
2642  bool DeadLock = Stack->hasDirective(
2643  [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
2644  const DeclarationNameInfo &DNI,
2645  SourceLocation Loc) -> bool {
2646  if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
2647  PreviousCriticalLoc = Loc;
2648  return true;
2649  } else
2650  return false;
2651  },
2652  false /* skip top directive */);
2653  if (DeadLock) {
2654  SemaRef.Diag(StartLoc,
2655  diag::err_omp_prohibited_region_critical_same_name)
2656  << CurrentName.getName();
2657  if (PreviousCriticalLoc.isValid())
2658  SemaRef.Diag(PreviousCriticalLoc,
2659  diag::note_omp_previous_critical_region);
2660  return true;
2661  }
2662  } else if (CurrentRegion == OMPD_barrier) {
2663  // OpenMP [2.16, Nesting of Regions]
2664  // A barrier region may not be closely nested inside a worksharing,
2665  // explicit task, critical, ordered, atomic, or master region.
2666  NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
2667  isOpenMPTaskingDirective(ParentRegion) ||
2668  ParentRegion == OMPD_master ||
2669  ParentRegion == OMPD_critical ||
2670  ParentRegion == OMPD_ordered;
2671  } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
2672  !isOpenMPParallelDirective(CurrentRegion) &&
2673  !isOpenMPTeamsDirective(CurrentRegion)) {
2674  // OpenMP [2.16, Nesting of Regions]
2675  // A worksharing region may not be closely nested inside a worksharing,
2676  // explicit task, critical, ordered, atomic, or master region.
2677  NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
2678  isOpenMPTaskingDirective(ParentRegion) ||
2679  ParentRegion == OMPD_master ||
2680  ParentRegion == OMPD_critical ||
2681  ParentRegion == OMPD_ordered;
2682  Recommend = ShouldBeInParallelRegion;
2683  } else if (CurrentRegion == OMPD_ordered) {
2684  // OpenMP [2.16, Nesting of Regions]
2685  // An ordered region may not be closely nested inside a critical,
2686  // atomic, or explicit task region.
2687  // An ordered region must be closely nested inside a loop region (or
2688  // parallel loop region) with an ordered clause.
2689  // OpenMP [2.8.1,simd Construct, Restrictions]
2690  // An ordered construct with the simd clause is the only OpenMP construct
2691  // that can appear in the simd region.
2692  NestingProhibited = ParentRegion == OMPD_critical ||
2693  isOpenMPTaskingDirective(ParentRegion) ||
2694  !(isOpenMPSimdDirective(ParentRegion) ||
2695  Stack->isParentOrderedRegion());
2696  Recommend = ShouldBeInOrderedRegion;
2697  } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
2698  // OpenMP [2.16, Nesting of Regions]
2699  // If specified, a teams construct must be contained within a target
2700  // construct.
2701  NestingProhibited = ParentRegion != OMPD_target;
2702  OrphanSeen = ParentRegion == OMPD_unknown;
2703  Recommend = ShouldBeInTargetRegion;
2704  }
2705  if (!NestingProhibited &&
2706  !isOpenMPTargetExecutionDirective(CurrentRegion) &&
2707  !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
2708  (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
2709  // OpenMP [2.16, Nesting of Regions]
2710  // distribute, parallel, parallel sections, parallel workshare, and the
2711  // parallel loop and parallel loop SIMD constructs are the only OpenMP
2712  // constructs that can be closely nested in the teams region.
2713  NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
2714  !isOpenMPDistributeDirective(CurrentRegion);
2715  Recommend = ShouldBeInParallelRegion;
2716  }
2717  if (!NestingProhibited &&
2718  isOpenMPNestingDistributeDirective(CurrentRegion)) {
2719  // OpenMP 4.5 [2.17 Nesting of Regions]
2720  // The region associated with the distribute construct must be strictly
2721  // nested inside a teams region
2722  NestingProhibited =
2723  (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
2724  Recommend = ShouldBeInTeamsRegion;
2725  }
2726  if (!NestingProhibited &&
2727  (isOpenMPTargetExecutionDirective(CurrentRegion) ||
2728  isOpenMPTargetDataManagementDirective(CurrentRegion))) {
2729  // OpenMP 4.5 [2.17 Nesting of Regions]
2730  // If a target, target update, target data, target enter data, or
2731  // target exit data construct is encountered during execution of a
2732  // target region, the behavior is unspecified.
2733  NestingProhibited = Stack->hasDirective(
2734  [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2735  SourceLocation) -> bool {
2737  OffendingRegion = K;
2738  return true;
2739  } else
2740  return false;
2741  },
2742  false /* don't skip top directive */);
2743  CloseNesting = false;
2744  }
2745  if (NestingProhibited) {
2746  if (OrphanSeen) {
2747  SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
2748  << getOpenMPDirectiveName(CurrentRegion) << Recommend;
2749  } else {
2750  SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
2751  << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
2752  << Recommend << getOpenMPDirectiveName(CurrentRegion);
2753  }
2754  return true;
2755  }
2756  }
2757  return false;
2758 }
2759 
2761  ArrayRef<OMPClause *> Clauses,
2762  ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
2763  bool ErrorFound = false;
2764  unsigned NamedModifiersNumber = 0;
2766  OMPD_unknown + 1);
2767  SmallVector<SourceLocation, 4> NameModifierLoc;
2768  for (const auto *C : Clauses) {
2769  if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
2770  // At most one if clause without a directive-name-modifier can appear on
2771  // the directive.
2772  OpenMPDirectiveKind CurNM = IC->getNameModifier();
2773  if (FoundNameModifiers[CurNM]) {
2774  S.Diag(C->getLocStart(), diag::err_omp_more_one_clause)
2775  << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
2776  << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
2777  ErrorFound = true;
2778  } else if (CurNM != OMPD_unknown) {
2779  NameModifierLoc.push_back(IC->getNameModifierLoc());
2780  ++NamedModifiersNumber;
2781  }
2782  FoundNameModifiers[CurNM] = IC;
2783  if (CurNM == OMPD_unknown)
2784  continue;
2785  // Check if the specified name modifier is allowed for the current
2786  // directive.
2787  // At most one if clause with the particular directive-name-modifier can
2788  // appear on the directive.
2789  bool MatchFound = false;
2790  for (auto NM : AllowedNameModifiers) {
2791  if (CurNM == NM) {
2792  MatchFound = true;
2793  break;
2794  }
2795  }
2796  if (!MatchFound) {
2797  S.Diag(IC->getNameModifierLoc(),
2798  diag::err_omp_wrong_if_directive_name_modifier)
2800  ErrorFound = true;
2801  }
2802  }
2803  }
2804  // If any if clause on the directive includes a directive-name-modifier then
2805  // all if clauses on the directive must include a directive-name-modifier.
2806  if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
2807  if (NamedModifiersNumber == AllowedNameModifiers.size()) {
2808  S.Diag(FoundNameModifiers[OMPD_unknown]->getLocStart(),
2809  diag::err_omp_no_more_if_clause);
2810  } else {
2811  std::string Values;
2812  std::string Sep(", ");
2813  unsigned AllowedCnt = 0;
2814  unsigned TotalAllowedNum =
2815  AllowedNameModifiers.size() - NamedModifiersNumber;
2816  for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
2817  ++Cnt) {
2818  OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
2819  if (!FoundNameModifiers[NM]) {
2820  Values += "'";
2821  Values += getOpenMPDirectiveName(NM);
2822  Values += "'";
2823  if (AllowedCnt + 2 == TotalAllowedNum)
2824  Values += " or ";
2825  else if (AllowedCnt + 1 != TotalAllowedNum)
2826  Values += Sep;
2827  ++AllowedCnt;
2828  }
2829  }
2830  S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getLocStart(),
2831  diag::err_omp_unnamed_if_clause)
2832  << (TotalAllowedNum > 1) << Values;
2833  }
2834  for (auto Loc : NameModifierLoc) {
2835  S.Diag(Loc, diag::note_omp_previous_named_if_clause);
2836  }
2837  ErrorFound = true;
2838  }
2839  return ErrorFound;
2840 }
2841 
2844  OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
2845  Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
2846  StmtResult Res = StmtError();
2847  // First check CancelRegion which is then used in checkNestingOfRegions.
2848  if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
2849  checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
2850  StartLoc))
2851  return StmtError();
2852 
2853  llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
2854  llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA;
2855  bool ErrorFound = false;
2856  ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
2857  if (AStmt && !CurContext->isDependentContext()) {
2858  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
2859 
2860  // Check default data sharing attributes for referenced variables.
2861  DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
2862  int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
2863  Stmt *S = AStmt;
2864  while (--ThisCaptureLevel >= 0)
2865  S = cast<CapturedStmt>(S)->getCapturedStmt();
2866  DSAChecker.Visit(S);
2867  if (DSAChecker.isErrorFound())
2868  return StmtError();
2869  // Generate list of implicitly defined firstprivate variables.
2870  VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
2871 
2872  SmallVector<Expr *, 4> ImplicitFirstprivates(
2873  DSAChecker.getImplicitFirstprivate().begin(),
2874  DSAChecker.getImplicitFirstprivate().end());
2875  SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(),
2876  DSAChecker.getImplicitMap().end());
2877  // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
2878  for (auto *C : Clauses) {
2879  if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
2880  for (auto *E : IRC->taskgroup_descriptors())
2881  if (E)
2882  ImplicitFirstprivates.emplace_back(E);
2883  }
2884  }
2885  if (!ImplicitFirstprivates.empty()) {
2886  if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
2887  ImplicitFirstprivates, SourceLocation(), SourceLocation(),
2888  SourceLocation())) {
2889  ClausesWithImplicit.push_back(Implicit);
2890  ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
2891  ImplicitFirstprivates.size();
2892  } else
2893  ErrorFound = true;
2894  }
2895  if (!ImplicitMaps.empty()) {
2896  if (OMPClause *Implicit = ActOnOpenMPMapClause(
2897  OMPC_MAP_unknown, OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true,
2898  SourceLocation(), SourceLocation(), ImplicitMaps,
2900  ClausesWithImplicit.emplace_back(Implicit);
2901  ErrorFound |=
2902  cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size();
2903  } else
2904  ErrorFound = true;
2905  }
2906  }
2907 
2908  llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
2909  switch (Kind) {
2910  case OMPD_parallel:
2911  Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
2912  EndLoc);
2913  AllowedNameModifiers.push_back(OMPD_parallel);
2914  break;
2915  case OMPD_simd:
2916  Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
2917  VarsWithInheritedDSA);
2918  break;
2919  case OMPD_for:
2920  Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
2921  VarsWithInheritedDSA);
2922  break;
2923  case OMPD_for_simd:
2924  Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
2925  EndLoc, VarsWithInheritedDSA);
2926  break;
2927  case OMPD_sections:
2928  Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
2929  EndLoc);
2930  break;
2931  case OMPD_section:
2932  assert(ClausesWithImplicit.empty() &&
2933  "No clauses are allowed for 'omp section' directive");
2934  Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
2935  break;
2936  case OMPD_single:
2937  Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
2938  EndLoc);
2939  break;
2940  case OMPD_master:
2941  assert(ClausesWithImplicit.empty() &&
2942  "No clauses are allowed for 'omp master' directive");
2943  Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
2944  break;
2945  case OMPD_critical:
2946  Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
2947  StartLoc, EndLoc);
2948  break;
2949  case OMPD_parallel_for:
2950  Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
2951  EndLoc, VarsWithInheritedDSA);
2952  AllowedNameModifiers.push_back(OMPD_parallel);
2953  break;
2954  case OMPD_parallel_for_simd:
2955  Res = ActOnOpenMPParallelForSimdDirective(
2956  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
2957  AllowedNameModifiers.push_back(OMPD_parallel);
2958  break;
2959  case OMPD_parallel_sections:
2960  Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
2961  StartLoc, EndLoc);
2962  AllowedNameModifiers.push_back(OMPD_parallel);
2963  break;
2964  case OMPD_task:
2965  Res =
2966  ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
2967  AllowedNameModifiers.push_back(OMPD_task);
2968  break;
2969  case OMPD_taskyield:
2970  assert(ClausesWithImplicit.empty() &&
2971  "No clauses are allowed for 'omp taskyield' directive");
2972  assert(AStmt == nullptr &&
2973  "No associated statement allowed for 'omp taskyield' directive");
2974  Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
2975  break;
2976  case OMPD_barrier:
2977  assert(ClausesWithImplicit.empty() &&
2978  "No clauses are allowed for 'omp barrier' directive");
2979  assert(AStmt == nullptr &&
2980  "No associated statement allowed for 'omp barrier' directive");
2981  Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
2982  break;
2983  case OMPD_taskwait:
2984  assert(ClausesWithImplicit.empty() &&
2985  "No clauses are allowed for 'omp taskwait' directive");
2986  assert(AStmt == nullptr &&
2987  "No associated statement allowed for 'omp taskwait' directive");
2988  Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
2989  break;
2990  case OMPD_taskgroup:
2991  Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
2992  EndLoc);
2993  break;
2994  case OMPD_flush:
2995  assert(AStmt == nullptr &&
2996  "No associated statement allowed for 'omp flush' directive");
2997  Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
2998  break;
2999  case OMPD_ordered:
3000  Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
3001  EndLoc);
3002  break;
3003  case OMPD_atomic:
3004  Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
3005  EndLoc);
3006  break;
3007  case OMPD_teams:
3008  Res =
3009  ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
3010  break;
3011  case OMPD_target:
3012  Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
3013  EndLoc);
3014  AllowedNameModifiers.push_back(OMPD_target);
3015  break;
3016  case OMPD_target_parallel:
3017  Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
3018  StartLoc, EndLoc);
3019  AllowedNameModifiers.push_back(OMPD_target);
3020  AllowedNameModifiers.push_back(OMPD_parallel);
3021  break;
3022  case OMPD_target_parallel_for:
3023  Res = ActOnOpenMPTargetParallelForDirective(
3024  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3025  AllowedNameModifiers.push_back(OMPD_target);
3026  AllowedNameModifiers.push_back(OMPD_parallel);
3027  break;
3028  case OMPD_cancellation_point:
3029  assert(ClausesWithImplicit.empty() &&
3030  "No clauses are allowed for 'omp cancellation point' directive");
3031  assert(AStmt == nullptr && "No associated statement allowed for 'omp "
3032  "cancellation point' directive");
3033  Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
3034  break;
3035  case OMPD_cancel:
3036  assert(AStmt == nullptr &&
3037  "No associated statement allowed for 'omp cancel' directive");
3038  Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
3039  CancelRegion);
3040  AllowedNameModifiers.push_back(OMPD_cancel);
3041  break;
3042  case OMPD_target_data:
3043  Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
3044  EndLoc);
3045  AllowedNameModifiers.push_back(OMPD_target_data);
3046  break;
3047  case OMPD_target_enter_data:
3048  Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
3049  EndLoc, AStmt);
3050  AllowedNameModifiers.push_back(OMPD_target_enter_data);
3051  break;
3052  case OMPD_target_exit_data:
3053  Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
3054  EndLoc, AStmt);
3055  AllowedNameModifiers.push_back(OMPD_target_exit_data);
3056  break;
3057  case OMPD_taskloop:
3058  Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
3059  EndLoc, VarsWithInheritedDSA);
3060  AllowedNameModifiers.push_back(OMPD_taskloop);
3061  break;
3062  case OMPD_taskloop_simd:
3063  Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3064  EndLoc, VarsWithInheritedDSA);
3065  AllowedNameModifiers.push_back(OMPD_taskloop);
3066  break;
3067  case OMPD_distribute:
3068  Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
3069  EndLoc, VarsWithInheritedDSA);
3070  break;
3071  case OMPD_target_update:
3072  Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
3073  EndLoc, AStmt);
3074  AllowedNameModifiers.push_back(OMPD_target_update);
3075  break;
3076  case OMPD_distribute_parallel_for:
3077  Res = ActOnOpenMPDistributeParallelForDirective(
3078  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3079  AllowedNameModifiers.push_back(OMPD_parallel);
3080  break;
3081  case OMPD_distribute_parallel_for_simd:
3082  Res = ActOnOpenMPDistributeParallelForSimdDirective(
3083  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3084  AllowedNameModifiers.push_back(OMPD_parallel);
3085  break;
3086  case OMPD_distribute_simd:
3087  Res = ActOnOpenMPDistributeSimdDirective(
3088  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3089  break;
3090  case OMPD_target_parallel_for_simd:
3091  Res = ActOnOpenMPTargetParallelForSimdDirective(
3092  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3093  AllowedNameModifiers.push_back(OMPD_target);
3094  AllowedNameModifiers.push_back(OMPD_parallel);
3095  break;
3096  case OMPD_target_simd:
3097  Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3098  EndLoc, VarsWithInheritedDSA);
3099  AllowedNameModifiers.push_back(OMPD_target);
3100  break;
3101  case OMPD_teams_distribute:
3102  Res = ActOnOpenMPTeamsDistributeDirective(
3103  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3104  break;
3105  case OMPD_teams_distribute_simd:
3106  Res = ActOnOpenMPTeamsDistributeSimdDirective(
3107  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3108  break;
3109  case OMPD_teams_distribute_parallel_for_simd:
3110  Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
3111  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3112  AllowedNameModifiers.push_back(OMPD_parallel);
3113  break;
3114  case OMPD_teams_distribute_parallel_for:
3115  Res = ActOnOpenMPTeamsDistributeParallelForDirective(
3116  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3117  AllowedNameModifiers.push_back(OMPD_parallel);
3118  break;
3119  case OMPD_target_teams:
3120  Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
3121  EndLoc);
3122  AllowedNameModifiers.push_back(OMPD_target);
3123  break;
3124  case OMPD_target_teams_distribute:
3125  Res = ActOnOpenMPTargetTeamsDistributeDirective(
3126  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3127  AllowedNameModifiers.push_back(OMPD_target);
3128  break;
3129  case OMPD_target_teams_distribute_parallel_for:
3130  Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
3131  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3132  AllowedNameModifiers.push_back(OMPD_target);
3133  AllowedNameModifiers.push_back(OMPD_parallel);
3134  break;
3135  case OMPD_target_teams_distribute_parallel_for_simd:
3136  Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
3137  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3138  AllowedNameModifiers.push_back(OMPD_target);
3139  AllowedNameModifiers.push_back(OMPD_parallel);
3140  break;
3141  case OMPD_target_teams_distribute_simd:
3142  Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
3143  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3144  AllowedNameModifiers.push_back(OMPD_target);
3145  break;
3146  case OMPD_declare_target:
3147  case OMPD_end_declare_target:
3148  case OMPD_threadprivate:
3149  case OMPD_declare_reduction:
3150  case OMPD_declare_simd:
3151  llvm_unreachable("OpenMP Directive is not allowed");
3152  case OMPD_unknown:
3153  llvm_unreachable("Unknown OpenMP directive");
3154  }
3155 
3156  for (auto P : VarsWithInheritedDSA) {
3157  Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
3158  << P.first << P.second->getSourceRange();
3159  }
3160  ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound;
3161 
3162  if (!AllowedNameModifiers.empty())
3163  ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
3164  ErrorFound;
3165 
3166  if (ErrorFound)
3167  return StmtError();
3168  return Res;
3169 }
3170 
3172  DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
3173  ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
3174  ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
3175  ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
3176  assert(Aligneds.size() == Alignments.size());
3177  assert(Linears.size() == LinModifiers.size());
3178  assert(Linears.size() == Steps.size());
3179  if (!DG || DG.get().isNull())
3180  return DeclGroupPtrTy();
3181 
3182  if (!DG.get().isSingleDecl()) {
3183  Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd);
3184  return DG;
3185  }
3186  auto *ADecl = DG.get().getSingleDecl();
3187  if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
3188  ADecl = FTD->getTemplatedDecl();
3189 
3190  auto *FD = dyn_cast<FunctionDecl>(ADecl);
3191  if (!FD) {
3192  Diag(ADecl->getLocation(), diag::err_omp_function_expected);
3193  return DeclGroupPtrTy();
3194  }
3195 
3196  // OpenMP [2.8.2, declare simd construct, Description]
3197  // The parameter of the simdlen clause must be a constant positive integer
3198  // expression.
3199  ExprResult SL;
3200  if (Simdlen)
3201  SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
3202  // OpenMP [2.8.2, declare simd construct, Description]
3203  // The special this pointer can be used as if was one of the arguments to the
3204  // function in any of the linear, aligned, or uniform clauses.
3205  // The uniform clause declares one or more arguments to have an invariant
3206  // value for all concurrent invocations of the function in the execution of a
3207  // single SIMD loop.
3208  llvm::DenseMap<Decl *, Expr *> UniformedArgs;
3209  Expr *UniformedLinearThis = nullptr;
3210  for (auto *E : Uniforms) {
3211  E = E->IgnoreParenImpCasts();
3212  if (auto *DRE = dyn_cast<DeclRefExpr>(E))
3213  if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
3214  if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3215  FD->getParamDecl(PVD->getFunctionScopeIndex())
3216  ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
3217  UniformedArgs.insert(std::make_pair(PVD->getCanonicalDecl(), E));
3218  continue;
3219  }
3220  if (isa<CXXThisExpr>(E)) {
3221  UniformedLinearThis = E;
3222  continue;
3223  }
3224  Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3225  << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3226  }
3227  // OpenMP [2.8.2, declare simd construct, Description]
3228  // The aligned clause declares that the object to which each list item points
3229  // is aligned to the number of bytes expressed in the optional parameter of
3230  // the aligned clause.
3231  // The special this pointer can be used as if was one of the arguments to the
3232  // function in any of the linear, aligned, or uniform clauses.
3233  // The type of list items appearing in the aligned clause must be array,
3234  // pointer, reference to array, or reference to pointer.
3235  llvm::DenseMap<Decl *, Expr *> AlignedArgs;
3236  Expr *AlignedThis = nullptr;
3237  for (auto *E : Aligneds) {
3238  E = E->IgnoreParenImpCasts();
3239  if (auto *DRE = dyn_cast<DeclRefExpr>(E))
3240  if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3241  auto *CanonPVD = PVD->getCanonicalDecl();
3242  if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3243  FD->getParamDecl(PVD->getFunctionScopeIndex())
3244  ->getCanonicalDecl() == CanonPVD) {
3245  // OpenMP [2.8.1, simd construct, Restrictions]
3246  // A list-item cannot appear in more than one aligned clause.
3247  if (AlignedArgs.count(CanonPVD) > 0) {
3248  Diag(E->getExprLoc(), diag::err_omp_aligned_twice)
3249  << 1 << E->getSourceRange();
3250  Diag(AlignedArgs[CanonPVD]->getExprLoc(),
3251  diag::note_omp_explicit_dsa)
3252  << getOpenMPClauseName(OMPC_aligned);
3253  continue;
3254  }
3255  AlignedArgs[CanonPVD] = E;
3256  QualType QTy = PVD->getType()
3257  .getNonReferenceType()
3258  .getUnqualifiedType()
3259  .getCanonicalType();
3260  const Type *Ty = QTy.getTypePtrOrNull();
3261  if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
3262  Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
3263  << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
3264  Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
3265  }
3266  continue;
3267  }
3268  }
3269  if (isa<CXXThisExpr>(E)) {
3270  if (AlignedThis) {
3271  Diag(E->getExprLoc(), diag::err_omp_aligned_twice)
3272  << 2 << E->getSourceRange();
3273  Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
3274  << getOpenMPClauseName(OMPC_aligned);
3275  }
3276  AlignedThis = E;
3277  continue;
3278  }
3279  Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3280  << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3281  }
3282  // The optional parameter of the aligned clause, alignment, must be a constant
3283  // positive integer expression. If no optional parameter is specified,
3284  // implementation-defined default alignments for SIMD instructions on the
3285  // target platforms are assumed.
3286  SmallVector<Expr *, 4> NewAligns;
3287  for (auto *E : Alignments) {
3288  ExprResult Align;
3289  if (E)
3290  Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
3291  NewAligns.push_back(Align.get());
3292  }
3293  // OpenMP [2.8.2, declare simd construct, Description]
3294  // The linear clause declares one or more list items to be private to a SIMD
3295  // lane and to have a linear relationship with respect to the iteration space
3296  // of a loop.
3297  // The special this pointer can be used as if was one of the arguments to the
3298  // function in any of the linear, aligned, or uniform clauses.
3299  // When a linear-step expression is specified in a linear clause it must be
3300  // either a constant integer expression or an integer-typed parameter that is
3301  // specified in a uniform clause on the directive.
3302  llvm::DenseMap<Decl *, Expr *> LinearArgs;
3303  const bool IsUniformedThis = UniformedLinearThis != nullptr;
3304  auto MI = LinModifiers.begin();
3305  for (auto *E : Linears) {
3306  auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
3307  ++MI;
3308  E = E->IgnoreParenImpCasts();
3309  if (auto *DRE = dyn_cast<DeclRefExpr>(E))
3310  if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3311  auto *CanonPVD = PVD->getCanonicalDecl();
3312  if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3313  FD->getParamDecl(PVD->getFunctionScopeIndex())
3314  ->getCanonicalDecl() == CanonPVD) {
3315  // OpenMP [2.15.3.7, linear Clause, Restrictions]
3316  // A list-item cannot appear in more than one linear clause.
3317  if (LinearArgs.count(CanonPVD) > 0) {
3318  Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3319  << getOpenMPClauseName(OMPC_linear)
3320  << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
3321  Diag(LinearArgs[CanonPVD]->getExprLoc(),
3322  diag::note_omp_explicit_dsa)
3323  << getOpenMPClauseName(OMPC_linear);
3324  continue;
3325  }
3326  // Each argument can appear in at most one uniform or linear clause.
3327  if (UniformedArgs.count(CanonPVD) > 0) {
3328  Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3329  << getOpenMPClauseName(OMPC_linear)
3331  Diag(UniformedArgs[CanonPVD]->getExprLoc(),
3332  diag::note_omp_explicit_dsa)
3334  continue;
3335  }
3336  LinearArgs[CanonPVD] = E;
3337  if (E->isValueDependent() || E->isTypeDependent() ||
3338  E->isInstantiationDependent() ||
3340  continue;
3341  (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
3342  PVD->getOriginalType());
3343  continue;
3344  }
3345  }
3346  if (isa<CXXThisExpr>(E)) {
3347  if (UniformedLinearThis) {
3348  Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3349  << getOpenMPClauseName(OMPC_linear)
3350  << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
3351  << E->getSourceRange();
3352  Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
3353  << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
3354  : OMPC_linear);
3355  continue;
3356  }
3357  UniformedLinearThis = E;
3358  if (E->isValueDependent() || E->isTypeDependent() ||
3360  continue;
3361  (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
3362  E->getType());
3363  continue;
3364  }
3365  Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3366  << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3367  }
3368  Expr *Step = nullptr;
3369  Expr *NewStep = nullptr;
3370  SmallVector<Expr *, 4> NewSteps;
3371  for (auto *E : Steps) {
3372  // Skip the same step expression, it was checked already.
3373  if (Step == E || !E) {
3374  NewSteps.push_back(E ? NewStep : nullptr);
3375  continue;
3376  }
3377  Step = E;
3378  if (auto *DRE = dyn_cast<DeclRefExpr>(Step))
3379  if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3380  auto *CanonPVD = PVD->getCanonicalDecl();
3381  if (UniformedArgs.count(CanonPVD) == 0) {
3382  Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
3383  << Step->getSourceRange();
3384  } else if (E->isValueDependent() || E->isTypeDependent() ||
3385  E->isInstantiationDependent() ||
3387  CanonPVD->getType()->hasIntegerRepresentation())
3388  NewSteps.push_back(Step);
3389  else {
3390  Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
3391  << Step->getSourceRange();
3392  }
3393  continue;
3394  }
3395  NewStep = Step;
3396  if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
3397  !Step->isInstantiationDependent() &&
3399  NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
3400  .get();
3401  if (NewStep)
3402  NewStep = VerifyIntegerConstantExpression(NewStep).get();
3403  }
3404  NewSteps.push_back(NewStep);
3405  }
3406  auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
3407  Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
3408  Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
3409  const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
3410  const_cast<Expr **>(Linears.data()), Linears.size(),
3411  const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
3412  NewSteps.data(), NewSteps.size(), SR);
3413  ADecl->addAttr(NewAttr);
3414  return ConvertDeclToDeclGroup(ADecl);
3415 }
3416 
3418  Stmt *AStmt,
3419  SourceLocation StartLoc,
3420  SourceLocation EndLoc) {
3421  if (!AStmt)
3422  return StmtError();
3423 
3424  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
3425  // 1.2.2 OpenMP Language Terminology
3426  // Structured block - An executable statement with a single entry at the
3427  // top and a single exit at the bottom.
3428  // The point of exit cannot be a branch out of the structured block.
3429  // longjmp() and throw() must not violate the entry/exit criteria.
3430  CS->getCapturedDecl()->setNothrow();
3431 
3432  getCurFunction()->setHasBranchProtectedScope();
3433 
3434  return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
3435  DSAStack->isCancelRegion());
3436 }
3437 
3438 namespace {
3439 /// \brief Helper class for checking canonical form of the OpenMP loops and
3440 /// extracting iteration space of each loop in the loop nest, that will be used
3441 /// for IR generation.
3442 class OpenMPIterationSpaceChecker {
3443  /// \brief Reference to Sema.
3444  Sema &SemaRef;
3445  /// \brief A location for diagnostics (when there is no some better location).
3446  SourceLocation DefaultLoc;
3447  /// \brief A location for diagnostics (when increment is not compatible).
3448  SourceLocation ConditionLoc;
3449  /// \brief A source location for referring to loop init later.
3450  SourceRange InitSrcRange;
3451  /// \brief A source location for referring to condition later.
3452  SourceRange ConditionSrcRange;
3453  /// \brief A source location for referring to increment later.
3454  SourceRange IncrementSrcRange;
3455  /// \brief Loop variable.
3456  ValueDecl *LCDecl = nullptr;
3457  /// \brief Reference to loop variable.
3458  Expr *LCRef = nullptr;
3459  /// \brief Lower bound (initializer for the var).
3460  Expr *LB = nullptr;
3461  /// \brief Upper bound.
3462  Expr *UB = nullptr;
3463  /// \brief Loop step (increment).
3464  Expr *Step = nullptr;
3465  /// \brief This flag is true when condition is one of:
3466  /// Var < UB
3467  /// Var <= UB
3468  /// UB > Var
3469  /// UB >= Var
3470  bool TestIsLessOp = false;
3471  /// \brief This flag is true when condition is strict ( < or > ).
3472  bool TestIsStrictOp = false;
3473  /// \brief This flag is true when step is subtracted on each iteration.
3474  bool SubtractStep = false;
3475 
3476 public:
3477  OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc)
3478  : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
3479  /// \brief Check init-expr for canonical loop form and save loop counter
3480  /// variable - #Var and its initialization value - #LB.
3481  bool CheckInit(Stmt *S, bool EmitDiags = true);
3482  /// \brief Check test-expr for canonical form, save upper-bound (#UB), flags
3483  /// for less/greater and for strict/non-strict comparison.
3484  bool CheckCond(Expr *S);
3485  /// \brief Check incr-expr for canonical loop form and return true if it
3486  /// does not conform, otherwise save loop step (#Step).
3487  bool CheckInc(Expr *S);
3488  /// \brief Return the loop counter variable.
3489  ValueDecl *GetLoopDecl() const { return LCDecl; }
3490  /// \brief Return the reference expression to loop counter variable.
3491  Expr *GetLoopDeclRefExpr() const { return LCRef; }
3492  /// \brief Source range of the loop init.
3493  SourceRange GetInitSrcRange() const { return InitSrcRange; }
3494  /// \brief Source range of the loop condition.
3495  SourceRange GetConditionSrcRange() const { return ConditionSrcRange; }
3496  /// \brief Source range of the loop increment.
3497  SourceRange GetIncrementSrcRange() const { return IncrementSrcRange; }
3498  /// \brief True if the step should be subtracted.
3499  bool ShouldSubtractStep() const { return SubtractStep; }
3500  /// \brief Build the expression to calculate the number of iterations.
3501  Expr *
3502  BuildNumIterations(Scope *S, const bool LimitedType,
3503  llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const;
3504  /// \brief Build the precondition expression for the loops.
3505  Expr *BuildPreCond(Scope *S, Expr *Cond,
3506  llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const;
3507  /// \brief Build reference expression to the counter be used for codegen.
3508  DeclRefExpr *BuildCounterVar(llvm::MapVector<Expr *, DeclRefExpr *> &Captures,
3509  DSAStackTy &DSA) const;
3510  /// \brief Build reference expression to the private counter be used for
3511  /// codegen.
3512  Expr *BuildPrivateCounterVar() const;
3513  /// \brief Build initialization of the counter be used for codegen.
3514  Expr *BuildCounterInit() const;
3515  /// \brief Build step of the counter be used for codegen.
3516  Expr *BuildCounterStep() const;
3517  /// \brief Return true if any expression is dependent.
3518  bool Dependent() const;
3519 
3520 private:
3521  /// \brief Check the right-hand side of an assignment in the increment
3522  /// expression.
3523  bool CheckIncRHS(Expr *RHS);
3524  /// \brief Helper to set loop counter variable and its initializer.
3525  bool SetLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB);
3526  /// \brief Helper to set upper bound.
3527  bool SetUB(Expr *NewUB, bool LessOp, bool StrictOp, SourceRange SR,
3528  SourceLocation SL);
3529  /// \brief Helper to set loop increment.
3530  bool SetStep(Expr *NewStep, bool Subtract);
3531 };
3532 
3533 bool OpenMPIterationSpaceChecker::Dependent() const {
3534  if (!LCDecl) {
3535  assert(!LB && !UB && !Step);
3536  return false;
3537  }
3538  return LCDecl->getType()->isDependentType() ||
3539  (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
3540  (Step && Step->isValueDependent());
3541 }
3542 
3543 bool OpenMPIterationSpaceChecker::SetLCDeclAndLB(ValueDecl *NewLCDecl,
3544  Expr *NewLCRefExpr,
3545  Expr *NewLB) {
3546  // State consistency checking to ensure correct usage.
3547  assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
3548  UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
3549  if (!NewLCDecl || !NewLB)
3550  return true;
3551  LCDecl = getCanonicalDecl(NewLCDecl);
3552  LCRef = NewLCRefExpr;
3553  if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
3554  if (const CXXConstructorDecl *Ctor = CE->getConstructor())
3555  if ((Ctor->isCopyOrMoveConstructor() ||
3556  Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
3557  CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
3558  NewLB = CE->getArg(0)->IgnoreParenImpCasts();
3559  LB = NewLB;
3560  return false;
3561 }
3562 
3563 bool OpenMPIterationSpaceChecker::SetUB(Expr *NewUB, bool LessOp, bool StrictOp,
3564  SourceRange SR, SourceLocation SL) {
3565  // State consistency checking to ensure correct usage.
3566  assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&
3567  Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
3568  if (!NewUB)
3569  return true;
3570  UB = NewUB;
3571  TestIsLessOp = LessOp;
3572  TestIsStrictOp = StrictOp;
3573  ConditionSrcRange = SR;
3574  ConditionLoc = SL;
3575  return false;
3576 }
3577 
3578 bool OpenMPIterationSpaceChecker::SetStep(Expr *NewStep, bool Subtract) {
3579  // State consistency checking to ensure correct usage.
3580  assert(LCDecl != nullptr && LB != nullptr && Step == nullptr);
3581  if (!NewStep)
3582  return true;
3583  if (!NewStep->isValueDependent()) {
3584  // Check that the step is integer expression.
3585  SourceLocation StepLoc = NewStep->getLocStart();
3587  StepLoc, getExprAsWritten(NewStep));
3588  if (Val.isInvalid())
3589  return true;
3590  NewStep = Val.get();
3591 
3592  // OpenMP [2.6, Canonical Loop Form, Restrictions]
3593  // If test-expr is of form var relational-op b and relational-op is < or
3594  // <= then incr-expr must cause var to increase on each iteration of the
3595  // loop. If test-expr is of form var relational-op b and relational-op is
3596  // > or >= then incr-expr must cause var to decrease on each iteration of
3597  // the loop.
3598  // If test-expr is of form b relational-op var and relational-op is < or
3599  // <= then incr-expr must cause var to decrease on each iteration of the
3600  // loop. If test-expr is of form b relational-op var and relational-op is
3601  // > or >= then incr-expr must cause var to increase on each iteration of
3602  // the loop.
3603  llvm::APSInt Result;
3604  bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context);
3605  bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
3606  bool IsConstNeg =
3607  IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
3608  bool IsConstPos =
3609  IsConstant && Result.isSigned() && (Subtract == Result.isNegative());
3610  bool IsConstZero = IsConstant && !Result.getBoolValue();
3611  if (UB && (IsConstZero ||
3612  (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract))
3613  : (IsConstPos || (IsUnsigned && !Subtract))))) {
3614  SemaRef.Diag(NewStep->getExprLoc(),
3615  diag::err_omp_loop_incr_not_compatible)
3616  << LCDecl << TestIsLessOp << NewStep->getSourceRange();
3617  SemaRef.Diag(ConditionLoc,
3618  diag::note_omp_loop_cond_requres_compatible_incr)
3619  << TestIsLessOp << ConditionSrcRange;
3620  return true;
3621  }
3622  if (TestIsLessOp == Subtract) {
3623  NewStep =
3624  SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
3625  .get();
3626  Subtract = !Subtract;
3627  }
3628  }
3629 
3630  Step = NewStep;
3631  SubtractStep = Subtract;
3632  return false;
3633 }
3634 
3635 bool OpenMPIterationSpaceChecker::CheckInit(Stmt *S, bool EmitDiags) {
3636  // Check init-expr for canonical loop form and save loop counter
3637  // variable - #Var and its initialization value - #LB.
3638  // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
3639  // var = lb
3640  // integer-type var = lb
3641  // random-access-iterator-type var = lb
3642  // pointer-type var = lb
3643  //
3644  if (!S) {
3645  if (EmitDiags) {
3646  SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
3647  }
3648  return true;
3649  }
3650  if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
3651  if (!ExprTemp->cleanupsHaveSideEffects())
3652  S = ExprTemp->getSubExpr();
3653 
3654  InitSrcRange = S->getSourceRange();
3655  if (Expr *E = dyn_cast<Expr>(S))
3656  S = E->IgnoreParens();
3657  if (auto *BO = dyn_cast<BinaryOperator>(S)) {
3658  if (BO->getOpcode() == BO_Assign) {
3659  auto *LHS = BO->getLHS()->IgnoreParens();
3660  if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
3661  if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
3662  if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
3663  return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3664  return SetLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS());
3665  }
3666  if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
3667  if (ME->isArrow() &&
3668  isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3669  return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3670  }
3671  }
3672  } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
3673  if (DS->isSingleDecl()) {
3674  if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
3675  if (Var->hasInit() && !Var->getType()->isReferenceType()) {
3676  // Accept non-canonical init form here but emit ext. warning.
3677  if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
3678  SemaRef.Diag(S->getLocStart(),
3679  diag::ext_omp_loop_not_canonical_init)
3680  << S->getSourceRange();
3681  return SetLCDeclAndLB(Var, nullptr, Var->getInit());
3682  }
3683  }
3684  }
3685  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
3686  if (CE->getOperator() == OO_Equal) {
3687  auto *LHS = CE->getArg(0);
3688  if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
3689  if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
3690  if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
3691  return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3692  return SetLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1));
3693  }
3694  if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
3695  if (ME->isArrow() &&
3696  isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3697  return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
3698  }
3699  }
3700  }
3701 
3702  if (Dependent() || SemaRef.CurContext->isDependentContext())
3703  return false;
3704  if (EmitDiags) {
3705  SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_init)
3706  << S->getSourceRange();
3707  }
3708  return true;
3709 }
3710 
3711 /// \brief Ignore parenthesizes, implicit casts, copy constructor and return the
3712 /// variable (which may be the loop variable) if possible.
3713 static const ValueDecl *GetInitLCDecl(Expr *E) {
3714  if (!E)
3715  return nullptr;
3716  E = getExprAsWritten(E);
3717  if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
3718  if (const CXXConstructorDecl *Ctor = CE->getConstructor())
3719  if ((Ctor->isCopyOrMoveConstructor() ||
3720  Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
3721  CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
3722  E = CE->getArg(0)->IgnoreParenImpCasts();
3723  if (auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
3724  if (auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
3725  return getCanonicalDecl(VD);
3726  }
3727  if (auto *ME = dyn_cast_or_null<MemberExpr>(E))
3728  if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
3729  return getCanonicalDecl(ME->getMemberDecl());
3730  return nullptr;
3731 }
3732 
3733 bool OpenMPIterationSpaceChecker::CheckCond(Expr *S) {
3734  // Check test-expr for canonical form, save upper-bound UB, flags for
3735  // less/greater and for strict/non-strict comparison.
3736  // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
3737  // var relational-op b
3738  // b relational-op var
3739  //
3740  if (!S) {
3741  SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl;
3742  return true;
3743  }
3744  S = getExprAsWritten(S);
3745  SourceLocation CondLoc = S->getLocStart();
3746  if (auto *BO = dyn_cast<BinaryOperator>(S)) {
3747  if (BO->isRelationalOp()) {
3748  if (GetInitLCDecl(BO->getLHS()) == LCDecl)
3749  return SetUB(BO->getRHS(),
3750  (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
3751  (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
3752  BO->getSourceRange(), BO->getOperatorLoc());
3753  if (GetInitLCDecl(BO->getRHS()) == LCDecl)
3754  return SetUB(BO->getLHS(),
3755  (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
3756  (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
3757  BO->getSourceRange(), BO->getOperatorLoc());
3758  }
3759  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
3760  if (CE->getNumArgs() == 2) {
3761  auto Op = CE->getOperator();
3762  switch (Op) {
3763  case OO_Greater:
3764  case OO_GreaterEqual:
3765  case OO_Less:
3766  case OO_LessEqual:
3767  if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3768  return SetUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
3769  Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
3770  CE->getOperatorLoc());
3771  if (GetInitLCDecl(CE->getArg(1)) == LCDecl)
3772  return SetUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
3773  Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
3774  CE->getOperatorLoc());
3775  break;
3776  default:
3777  break;
3778  }
3779  }
3780  }
3781  if (Dependent() || SemaRef.CurContext->isDependentContext())
3782  return false;
3783  SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
3784  << S->getSourceRange() << LCDecl;
3785  return true;
3786 }
3787 
3788 bool OpenMPIterationSpaceChecker::CheckIncRHS(Expr *RHS) {
3789  // RHS of canonical loop form increment can be:
3790  // var + incr
3791  // incr + var
3792  // var - incr
3793  //
3794  RHS = RHS->IgnoreParenImpCasts();
3795  if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
3796  if (BO->isAdditiveOp()) {
3797  bool IsAdd = BO->getOpcode() == BO_Add;
3798  if (GetInitLCDecl(BO->getLHS()) == LCDecl)
3799  return SetStep(BO->getRHS(), !IsAdd);
3800  if (IsAdd && GetInitLCDecl(BO->getRHS()) == LCDecl)
3801  return SetStep(BO->getLHS(), false);
3802  }
3803  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
3804  bool IsAdd = CE->getOperator() == OO_Plus;
3805  if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
3806  if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3807  return SetStep(CE->getArg(1), !IsAdd);
3808  if (IsAdd && GetInitLCDecl(CE->getArg(1)) == LCDecl)
3809  return SetStep(CE->getArg(0), false);
3810  }
3811  }
3812  if (Dependent() || SemaRef.CurContext->isDependentContext())
3813  return false;
3814  SemaRef.Diag(RHS->getLocStart(), diag::err_omp_loop_not_canonical_incr)
3815  << RHS->getSourceRange() << LCDecl;
3816  return true;
3817 }
3818 
3819 bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) {
3820  // Check incr-expr for canonical loop form and return true if it
3821  // does not conform.
3822  // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
3823  // ++var
3824  // var++
3825  // --var
3826  // var--
3827  // var += incr
3828  // var -= incr
3829  // var = var + incr
3830  // var = incr + var
3831  // var = var - incr
3832  //
3833  if (!S) {
3834  SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
3835  return true;
3836  }
3837  if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
3838  if (!ExprTemp->cleanupsHaveSideEffects())
3839  S = ExprTemp->getSubExpr();
3840 
3841  IncrementSrcRange = S->getSourceRange();
3842  S = S->IgnoreParens();
3843  if (auto *UO = dyn_cast<UnaryOperator>(S)) {
3844  if (UO->isIncrementDecrementOp() &&
3845  GetInitLCDecl(UO->getSubExpr()) == LCDecl)
3846  return SetStep(SemaRef
3847  .ActOnIntegerConstant(UO->getLocStart(),
3848  (UO->isDecrementOp() ? -1 : 1))
3849  .get(),
3850  false);
3851  } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
3852  switch (BO->getOpcode()) {
3853  case BO_AddAssign:
3854  case BO_SubAssign:
3855  if (GetInitLCDecl(BO->getLHS()) == LCDecl)
3856  return SetStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
3857  break;
3858  case BO_Assign:
3859  if (GetInitLCDecl(BO->getLHS()) == LCDecl)
3860  return CheckIncRHS(BO->getRHS());
3861  break;
3862  default:
3863  break;
3864  }
3865  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
3866  switch (CE->getOperator()) {
3867  case OO_PlusPlus:
3868  case OO_MinusMinus:
3869  if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3870  return SetStep(SemaRef
3871  .ActOnIntegerConstant(
3872  CE->getLocStart(),
3873  ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
3874  .get(),
3875  false);
3876  break;
3877  case OO_PlusEqual:
3878  case OO_MinusEqual:
3879  if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3880  return SetStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
3881  break;
3882  case OO_Equal:
3883  if (GetInitLCDecl(CE->getArg(0)) == LCDecl)
3884  return CheckIncRHS(CE->getArg(1));
3885  break;
3886  default:
3887  break;
3888  }
3889  }
3890  if (Dependent() || SemaRef.CurContext->isDependentContext())
3891  return false;
3892  SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_incr)
3893  << S->getSourceRange() << LCDecl;
3894  return true;
3895 }
3896 
3897 static ExprResult
3898 tryBuildCapture(Sema &SemaRef, Expr *Capture,
3899  llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
3900  if (SemaRef.CurContext->isDependentContext())
3901  return ExprResult(Capture);
3902  if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
3903  return SemaRef.PerformImplicitConversion(
3904  Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
3905  /*AllowExplicit=*/true);
3906  auto I = Captures.find(Capture);
3907  if (I != Captures.end())
3908  return buildCapture(SemaRef, Capture, I->second);
3909  DeclRefExpr *Ref = nullptr;
3910  ExprResult Res = buildCapture(SemaRef, Capture, Ref);
3911  Captures[Capture] = Ref;
3912  return Res;
3913 }
3914 
3915 /// \brief Build the expression to calculate the number of iterations.
3916 Expr *OpenMPIterationSpaceChecker::BuildNumIterations(
3917  Scope *S, const bool LimitedType,
3918  llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const {
3919  ExprResult Diff;
3920  auto VarType = LCDecl->getType().getNonReferenceType();
3921  if (VarType->isIntegerType() || VarType->isPointerType() ||
3922  SemaRef.getLangOpts().CPlusPlus) {
3923  // Upper - Lower
3924  auto *UBExpr = TestIsLessOp ? UB : LB;
3925  auto *LBExpr = TestIsLessOp ? LB : UB;
3926  Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
3927  Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
3928  if (!Upper || !Lower)
3929  return nullptr;
3930 
3931  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
3932 
3933  if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) {
3934  // BuildBinOp already emitted error, this one is to point user to upper
3935  // and lower bound, and to tell what is passed to 'operator-'.
3936  SemaRef.Diag(Upper->getLocStart(), diag::err_omp_loop_diff_cxx)
3937  << Upper->getSourceRange() << Lower->getSourceRange();
3938  return nullptr;
3939  }
3940  }
3941 
3942  if (!Diff.isUsable())
3943  return nullptr;
3944 
3945  // Upper - Lower [- 1]
3946  if (TestIsStrictOp)
3947  Diff = SemaRef.BuildBinOp(
3948  S, DefaultLoc, BO_Sub, Diff.get(),
3949  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
3950  if (!Diff.isUsable())
3951  return nullptr;
3952 
3953  // Upper - Lower [- 1] + Step
3954  auto NewStep = tryBuildCapture(SemaRef, Step, Captures);
3955  if (!NewStep.isUsable())
3956  return nullptr;
3957  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
3958  if (!Diff.isUsable())
3959  return nullptr;
3960 
3961  // Parentheses (for dumping/debugging purposes only).
3962  Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
3963  if (!Diff.isUsable())
3964  return nullptr;
3965 
3966  // (Upper - Lower [- 1] + Step) / Step
3967  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
3968  if (!Diff.isUsable())
3969  return nullptr;
3970 
3971  // OpenMP runtime requires 32-bit or 64-bit loop variables.
3972  QualType Type = Diff.get()->getType();
3973  auto &C = SemaRef.Context;
3974  bool UseVarType = VarType->hasIntegerRepresentation() &&
3975  C.getTypeSize(Type) > C.getTypeSize(VarType);
3976  if (!Type->isIntegerType() || UseVarType) {
3977  unsigned NewSize =
3978  UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
3979  bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
3981  Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
3982  if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
3983  Diff = SemaRef.PerformImplicitConversion(
3984  Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
3985  if (!Diff.isUsable())
3986  return nullptr;
3987  }
3988  }
3989  if (LimitedType) {
3990  unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
3991  if (NewSize != C.getTypeSize(Type)) {
3992  if (NewSize < C.getTypeSize(Type)) {
3993  assert(NewSize == 64 && "incorrect loop var size");
3994  SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
3995  << InitSrcRange << ConditionSrcRange;
3996  }
3997  QualType NewType = C.getIntTypeForBitwidth(
3998  NewSize, Type->hasSignedIntegerRepresentation() ||
3999  C.getTypeSize(Type) < NewSize);
4000  if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
4001  Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
4002  Sema::AA_Converting, true);
4003  if (!Diff.isUsable())
4004  return nullptr;
4005  }
4006  }
4007  }
4008 
4009  return Diff.get();
4010 }
4011 
4012 Expr *OpenMPIterationSpaceChecker::BuildPreCond(
4013  Scope *S, Expr *Cond,
4014  llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const {
4015  // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
4016  bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
4017  SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
4018 
4019  auto NewLB = tryBuildCapture(SemaRef, LB, Captures);
4020  auto NewUB = tryBuildCapture(SemaRef, UB, Captures);
4021  if (!NewLB.isUsable() || !NewUB.isUsable())
4022  return nullptr;
4023 
4024  auto CondExpr = SemaRef.BuildBinOp(
4025  S, DefaultLoc, TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE)
4026  : (TestIsStrictOp ? BO_GT : BO_GE),
4027  NewLB.get(), NewUB.get());
4028  if (CondExpr.isUsable()) {
4029  if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
4030  SemaRef.Context.BoolTy))
4031  CondExpr = SemaRef.PerformImplicitConversion(
4032  CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
4033  /*AllowExplicit=*/true);
4034  }
4035  SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
4036  // Otherwise use original loop conditon and evaluate it in runtime.
4037  return CondExpr.isUsable() ? CondExpr.get() : Cond;
4038 }
4039 
4040 /// \brief Build reference expression to the counter be used for codegen.
4041 DeclRefExpr *OpenMPIterationSpaceChecker::BuildCounterVar(
4042  llvm::MapVector<Expr *, DeclRefExpr *> &Captures, DSAStackTy &DSA) const {
4043  auto *VD = dyn_cast<VarDecl>(LCDecl);
4044  if (!VD) {
4045  VD = SemaRef.IsOpenMPCapturedDecl(LCDecl);
4046  auto *Ref = buildDeclRefExpr(
4047  SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
4048  DSAStackTy::DSAVarData Data = DSA.getTopDSA(LCDecl, /*FromParent=*/false);
4049  // If the loop control decl is explicitly marked as private, do not mark it
4050  // as captured again.
4051  if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
4052  Captures.insert(std::make_pair(LCRef, Ref));
4053  return Ref;
4054  }
4055  return buildDeclRefExpr(SemaRef, VD, VD->getType().getNonReferenceType(),
4056  DefaultLoc);
4057 }
4058 
4059 Expr *OpenMPIterationSpaceChecker::BuildPrivateCounterVar() const {
4060  if (LCDecl && !LCDecl->isInvalidDecl()) {
4061  auto Type = LCDecl->getType().getNonReferenceType();
4062  auto *PrivateVar =
4063  buildVarDecl(SemaRef, DefaultLoc, Type, LCDecl->getName(),
4064  LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr);
4065  if (PrivateVar->isInvalidDecl())
4066  return nullptr;
4067  return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
4068  }
4069  return nullptr;
4070 }
4071 
4072 /// \brief Build initialization of the counter to be used for codegen.
4074 
4075 /// \brief Build step of the counter be used for codegen.
4076 Expr *OpenMPIterationSpaceChecker::BuildCounterStep() const { return Step; }
4077 
4078 /// \brief Iteration space of a single for loop.
4079 struct LoopIterationSpace final {
4080  /// \brief Condition of the loop.
4081  Expr *PreCond = nullptr;
4082  /// \brief This expression calculates the number of iterations in the loop.
4083  /// It is always possible to calculate it before starting the loop.
4084  Expr *NumIterations = nullptr;
4085  /// \brief The loop counter variable.
4086  Expr *CounterVar = nullptr;
4087  /// \brief Private loop counter variable.
4088  Expr *PrivateCounterVar = nullptr;
4089  /// \brief This is initializer for the initial value of #CounterVar.
4090  Expr *CounterInit = nullptr;
4091  /// \brief This is step for the #CounterVar used to generate its update:
4092  /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
4093  Expr *CounterStep = nullptr;
4094  /// \brief Should step be subtracted?
4095  bool Subtract = false;
4096  /// \brief Source range of the loop init.
4097  SourceRange InitSrcRange;
4098  /// \brief Source range of the loop condition.
4099  SourceRange CondSrcRange;
4100  /// \brief Source range of the loop increment.
4101  SourceRange IncSrcRange;
4102 };
4103 
4104 } // namespace
4105 
4107  assert(getLangOpts().OpenMP && "OpenMP is not active.");
4108  assert(Init && "Expected loop in canonical form.");
4109  unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
4110  if (AssociatedLoops > 0 &&
4111  isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
4112  OpenMPIterationSpaceChecker ISC(*this, ForLoc);
4113  if (!ISC.CheckInit(Init, /*EmitDiags=*/false)) {
4114  if (auto *D = ISC.GetLoopDecl()) {
4115  auto *VD = dyn_cast<VarDecl>(D);
4116  if (!VD) {
4117  if (auto *Private = IsOpenMPCapturedDecl(D))
4118  VD = Private;
4119  else {
4120  auto *Ref = buildCapture(*this, D, ISC.GetLoopDeclRefExpr(),
4121  /*WithInit=*/false);
4122  VD = cast<VarDecl>(Ref->getDecl());
4123  }
4124  }
4125  DSAStack->addLoopControlVariable(D, VD);
4126  }
4127  }
4128  DSAStack->setAssociatedLoops(AssociatedLoops - 1);
4129  }
4130 }
4131 
4132 /// \brief Called on a for stmt to check and extract its iteration space
4133 /// for further processing (such as collapsing).
4135  OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
4136  unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
4137  Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr,
4138  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA,
4139  LoopIterationSpace &ResultIterSpace,
4140  llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
4141  // OpenMP [2.6, Canonical Loop Form]
4142  // for (init-expr; test-expr; incr-expr) structured-block
4143  auto *For = dyn_cast_or_null<ForStmt>(S);
4144  if (!For) {
4145  SemaRef.Diag(S->getLocStart(), diag::err_omp_not_for)
4146  << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
4147  << getOpenMPDirectiveName(DKind) << NestedLoopCount
4148  << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
4149  if (NestedLoopCount > 1) {
4150  if (CollapseLoopCountExpr && OrderedLoopCountExpr)
4151  SemaRef.Diag(DSA.getConstructLoc(),
4152  diag::note_omp_collapse_ordered_expr)
4153  << 2 << CollapseLoopCountExpr->getSourceRange()
4154  << OrderedLoopCountExpr->getSourceRange();
4155  else if (CollapseLoopCountExpr)
4156  SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
4157  diag::note_omp_collapse_ordered_expr)
4158  << 0 << CollapseLoopCountExpr->getSourceRange();
4159  else
4160  SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
4161  diag::note_omp_collapse_ordered_expr)
4162  << 1 << OrderedLoopCountExpr->getSourceRange();
4163  }
4164  return true;
4165  }
4166  assert(For->getBody());
4167 
4168  OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc());
4169 
4170  // Check init.
4171  auto Init = For->getInit();
4172  if (ISC.CheckInit(Init))
4173  return true;
4174 
4175  bool HasErrors = false;
4176 
4177  // Check loop variable's type.
4178  if (auto *LCDecl = ISC.GetLoopDecl()) {
4179  auto *LoopDeclRefExpr = ISC.GetLoopDeclRefExpr();
4180 
4181  // OpenMP [2.6, Canonical Loop Form]
4182  // Var is one of the following:
4183  // A variable of signed or unsigned integer type.
4184  // For C++, a variable of a random access iterator type.
4185  // For C, a variable of a pointer type.
4186  auto VarType = LCDecl->getType().getNonReferenceType();
4187  if (!VarType->isDependentType() && !VarType->isIntegerType() &&
4188  !VarType->isPointerType() &&
4189  !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
4190  SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_variable_type)
4191  << SemaRef.getLangOpts().CPlusPlus;
4192  HasErrors = true;
4193  }
4194 
4195  // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
4196  // a Construct
4197  // The loop iteration variable(s) in the associated for-loop(s) of a for or
4198  // parallel for construct is (are) private.
4199  // The loop iteration variable in the associated for-loop of a simd
4200  // construct with just one associated for-loop is linear with a
4201  // constant-linear-step that is the increment of the associated for-loop.
4202  // Exclude loop var from the list of variables with implicitly defined data
4203  // sharing attributes.
4204  VarsWithImplicitDSA.erase(LCDecl);
4205 
4206  // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
4207  // in a Construct, C/C++].
4208  // The loop iteration variable in the associated for-loop of a simd
4209  // construct with just one associated for-loop may be listed in a linear
4210  // clause with a constant-linear-step that is the increment of the
4211  // associated for-loop.
4212  // The loop iteration variable(s) in the associated for-loop(s) of a for or
4213  // parallel for construct may be listed in a private or lastprivate clause.
4214  DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl, false);
4215  // If LoopVarRefExpr is nullptr it means the corresponding loop variable is
4216  // declared in the loop and it is predetermined as a private.
4217  auto PredeterminedCKind =
4218  isOpenMPSimdDirective(DKind)
4219  ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate)
4220  : OMPC_private;
4221  if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
4222  DVar.CKind != PredeterminedCKind) ||
4223  ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
4224  isOpenMPDistributeDirective(DKind)) &&
4225  !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
4226  DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
4227  (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
4228  SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa)
4229  << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind)
4230  << getOpenMPClauseName(PredeterminedCKind);
4231  if (DVar.RefExpr == nullptr)
4232  DVar.CKind = PredeterminedCKind;
4233  ReportOriginalDSA(SemaRef, &DSA, LCDecl, DVar, /*IsLoopIterVar=*/true);
4234  HasErrors = true;
4235  } else if (LoopDeclRefExpr != nullptr) {
4236  // Make the loop iteration variable private (for worksharing constructs),
4237  // linear (for simd directives with the only one associated loop) or
4238  // lastprivate (for simd directives with several collapsed or ordered
4239  // loops).
4240  if (DVar.CKind == OMPC_unknown)
4241  DVar = DSA.hasDSA(LCDecl, isOpenMPPrivate,
4242  [](OpenMPDirectiveKind) -> bool { return true; },
4243  /*FromParent=*/false);
4244  DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind);
4245  }
4246 
4247  assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
4248 
4249  // Check test-expr.
4250  HasErrors |= ISC.CheckCond(For->getCond());
4251 
4252  // Check incr-expr.
4253  HasErrors |= ISC.CheckInc(For->getInc());
4254  }
4255 
4256  if (ISC.Dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
4257  return HasErrors;
4258 
4259  // Build the loop's iteration space representation.
4260  ResultIterSpace.PreCond =
4261  ISC.BuildPreCond(DSA.getCurScope(), For->getCond(), Captures);
4262  ResultIterSpace.NumIterations = ISC.BuildNumIterations(
4263  DSA.getCurScope(),
4264  (isOpenMPWorksharingDirective(DKind) ||
4266  Captures);
4267  ResultIterSpace.CounterVar = ISC.BuildCounterVar(Captures, DSA);
4268  ResultIterSpace.PrivateCounterVar = ISC.BuildPrivateCounterVar();
4269  ResultIterSpace.CounterInit = ISC.BuildCounterInit();
4270  ResultIterSpace.CounterStep = ISC.BuildCounterStep();
4271  ResultIterSpace.InitSrcRange = ISC.GetInitSrcRange();
4272  ResultIterSpace.CondSrcRange = ISC.GetConditionSrcRange();
4273  ResultIterSpace.IncSrcRange = ISC.GetIncrementSrcRange();
4274  ResultIterSpace.Subtract = ISC.ShouldSubtractStep();
4275 
4276  HasErrors |= (ResultIterSpace.PreCond == nullptr ||
4277  ResultIterSpace.NumIterations == nullptr ||
4278  ResultIterSpace.CounterVar == nullptr ||
4279  ResultIterSpace.PrivateCounterVar == nullptr ||
4280  ResultIterSpace.CounterInit == nullptr ||
4281  ResultIterSpace.CounterStep == nullptr);
4282 
4283  return HasErrors;
4284 }
4285 
4286 /// \brief Build 'VarRef = Start.
4287 static ExprResult
4289  ExprResult Start,
4290  llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
4291  // Build 'VarRef = Start.
4292  auto NewStart = tryBuildCapture(SemaRef, Start.get(), Captures);
4293  if (!NewStart.isUsable())
4294  return ExprError();
4295  if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
4296  VarRef.get()->getType())) {
4297  NewStart = SemaRef.PerformImplicitConversion(
4298  NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
4299  /*AllowExplicit=*/true);
4300  if (!NewStart.isUsable())
4301  return ExprError();
4302  }
4303 
4304  auto Init =
4305  SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
4306  return Init;
4307 }
4308 
4309 /// \brief Build 'VarRef = Start + Iter * Step'.
4310 static ExprResult
4312  ExprResult VarRef, ExprResult Start, ExprResult Iter,
4313  ExprResult Step, bool Subtract,
4314  llvm::MapVector<Expr *, DeclRefExpr *> *Captures = nullptr) {
4315  // Add parentheses (for debugging purposes only).
4316  Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
4317  if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
4318  !Step.isUsable())
4319  return ExprError();
4320 
4321  ExprResult NewStep = Step;
4322  if (Captures)
4323  NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
4324  if (NewStep.isInvalid())
4325  return ExprError();
4326  ExprResult Update =
4327  SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
4328  if (!Update.isUsable())
4329  return ExprError();
4330 
4331  // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
4332  // 'VarRef = Start (+|-) Iter * Step'.
4333  ExprResult NewStart = Start;
4334  if (Captures)
4335  NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
4336  if (NewStart.isInvalid())
4337  return ExprError();
4338 
4339  // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
4340  ExprResult SavedUpdate = Update;
4341  ExprResult UpdateVal;
4342  if (VarRef.get()->getType()->isOverloadableType() ||
4343  NewStart.get()->getType()->isOverloadableType() ||
4344  Update.get()->getType()->isOverloadableType()) {
4345  bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
4346  SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
4347  Update =
4348  SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
4349  if (Update.isUsable()) {
4350  UpdateVal =
4351  SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
4352  VarRef.get(), SavedUpdate.get());
4353  if (UpdateVal.isUsable()) {
4354  Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
4355  UpdateVal.get());
4356  }
4357  }
4358  SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
4359  }
4360 
4361  // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
4362  if (!Update.isUsable() || !UpdateVal.isUsable()) {
4363  Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
4364  NewStart.get(), SavedUpdate.get());
4365  if (!Update.isUsable())
4366  return ExprError();
4367 
4368  if (!SemaRef.Context.hasSameType(Update.get()->getType(),
4369  VarRef.get()->getType())) {
4370  Update = SemaRef.PerformImplicitConversion(
4371  Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
4372  if (!Update.isUsable())
4373  return ExprError();
4374  }
4375 
4376  Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
4377  }
4378  return Update;
4379 }
4380 
4381 /// \brief Convert integer expression \a E to make it have at least \a Bits
4382 /// bits.
4383 static ExprResult WidenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
4384  if (E == nullptr)
4385  return ExprError();
4386  auto &C = SemaRef.Context;
4387  QualType OldType = E->getType();
4388  unsigned HasBits = C.getTypeSize(OldType);
4389  if (HasBits >= Bits)
4390  return ExprResult(E);
4391  // OK to convert to signed, because new type has more bits than old.
4392  QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
4393  return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
4394  true);
4395 }
4396 
4397 /// \brief Check if the given expression \a E is a constant integer that fits
4398 /// into \a Bits bits.
4399 static bool FitsInto(unsigned Bits, bool Signed, Expr *E, Sema &SemaRef) {
4400  if (E == nullptr)
4401  return false;
4402  llvm::APSInt Result;
4403  if (E->isIntegerConstantExpr(Result, SemaRef.Context))
4404  return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits);
4405  return false;
4406 }
4407 
4408 /// Build preinits statement for the given declarations.
4409 static Stmt *buildPreInits(ASTContext &Context,
4410  MutableArrayRef<Decl *> PreInits) {
4411  if (!PreInits.empty()) {
4412  return new (Context) DeclStmt(
4413  DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
4415  }
4416  return nullptr;
4417 }
4418 
4419 /// Build preinits statement for the given declarations.
4420 static Stmt *
4422  const llvm::MapVector<Expr *, DeclRefExpr *> &Captures) {
4423  if (!Captures.empty()) {
4424  SmallVector<Decl *, 16> PreInits;
4425  for (auto &Pair : Captures)
4426  PreInits.push_back(Pair.second->getDecl());
4427  return buildPreInits(Context, PreInits);
4428  }
4429  return nullptr;
4430 }
4431 
4432 /// Build postupdate expression for the given list of postupdates expressions.
4433 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
4434  Expr *PostUpdate = nullptr;
4435  if (!PostUpdates.empty()) {
4436  for (auto *E : PostUpdates) {
4437  Expr *ConvE = S.BuildCStyleCastExpr(
4438  E->getExprLoc(),
4440  E->getExprLoc(), E)
4441  .get();
4442  PostUpdate = PostUpdate
4443  ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
4444  PostUpdate, ConvE)
4445  .get()
4446  : ConvE;
4447  }
4448  }
4449  return PostUpdate;
4450 }
4451 
4452 /// \brief Called on a for stmt to check itself and nested loops (if any).
4453 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
4454 /// number of collapsed loops otherwise.
4455 static unsigned
4456 CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
4457  Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
4458  DSAStackTy &DSA,
4459  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA,
4461  unsigned NestedLoopCount = 1;
4462  if (CollapseLoopCountExpr) {
4463  // Found 'collapse' clause - calculate collapse number.
4464  llvm::APSInt Result;
4465  if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext()))
4466  NestedLoopCount = Result.getLimitedValue();
4467  }
4468  if (OrderedLoopCountExpr) {
4469  // Found 'ordered' clause - calculate collapse number.
4470  llvm::APSInt Result;
4471  if (OrderedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
4472  if (Result.getLimitedValue() < NestedLoopCount) {
4473  SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
4474  diag::err_omp_wrong_ordered_loop_count)
4475  << OrderedLoopCountExpr->getSourceRange();
4476  SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
4477  diag::note_collapse_loop_count)
4478  << CollapseLoopCountExpr->getSourceRange();
4479  }
4480  NestedLoopCount = Result.getLimitedValue();
4481  }
4482  }
4483  // This is helper routine for loop directives (e.g., 'for', 'simd',
4484  // 'for simd', etc.).
4485  llvm::MapVector<Expr *, DeclRefExpr *> Captures;
4487  IterSpaces.resize(NestedLoopCount);
4488  Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true);
4489  for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
4490  if (CheckOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA, Cnt,
4491  NestedLoopCount, CollapseLoopCountExpr,
4492  OrderedLoopCountExpr, VarsWithImplicitDSA,
4493  IterSpaces[Cnt], Captures))
4494  return 0;
4495  // Move on to the next nested for loop, or to the loop body.
4496  // OpenMP [2.8.1, simd construct, Restrictions]
4497  // All loops associated with the construct must be perfectly nested; that
4498  // is, there must be no intervening code nor any OpenMP directive between
4499  // any two loops.
4500  CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers();
4501  }
4502 
4503  Built.clear(/* size */ NestedLoopCount);
4504 
4505  if (SemaRef.CurContext->isDependentContext())
4506  return NestedLoopCount;
4507 
4508  // An example of what is generated for the following code:
4509  //
4510  // #pragma omp simd collapse(2) ordered(2)
4511  // for (i = 0; i < NI; ++i)
4512  // for (k = 0; k < NK; ++k)
4513  // for (j = J0; j < NJ; j+=2) {
4514  // <loop body>
4515  // }
4516  //
4517  // We generate the code below.
4518  // Note: the loop body may be outlined in CodeGen.
4519  // Note: some counters may be C++ classes, operator- is used to find number of
4520  // iterations and operator+= to calculate counter value.
4521  // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
4522  // or i64 is currently supported).
4523  //
4524  // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
4525  // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
4526  // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
4527  // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
4528  // // similar updates for vars in clauses (e.g. 'linear')
4529  // <loop body (using local i and j)>
4530  // }
4531  // i = NI; // assign final values of counters
4532  // j = NJ;
4533  //
4534 
4535  // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
4536  // the iteration counts of the collapsed for loops.
4537  // Precondition tests if there is at least one iteration (all conditions are
4538  // true).
4539  auto PreCond = ExprResult(IterSpaces[0].PreCond);
4540  auto N0 = IterSpaces[0].NumIterations;
4541  ExprResult LastIteration32 = WidenIterationCount(
4542  32 /* Bits */, SemaRef
4543  .PerformImplicitConversion(
4544  N0->IgnoreImpCasts(), N0->getType(),
4545  Sema::AA_Converting, /*AllowExplicit=*/true)
4546  .get(),
4547  SemaRef);
4548  ExprResult LastIteration64 = WidenIterationCount(
4549  64 /* Bits */, SemaRef
4550  .PerformImplicitConversion(
4551  N0->IgnoreImpCasts(), N0->getType(),
4552  Sema::AA_Converting, /*AllowExplicit=*/true)
4553  .get(),
4554  SemaRef);
4555 
4556  if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
4557  return NestedLoopCount;
4558 
4559  auto &C = SemaRef.Context;
4560  bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
4561 
4562  Scope *CurScope = DSA.getCurScope();
4563  for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
4564  if (PreCond.isUsable()) {
4565  PreCond =
4566  SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
4567  PreCond.get(), IterSpaces[Cnt].PreCond);
4568  }
4569  auto N = IterSpaces[Cnt].NumIterations;
4570  SourceLocation Loc = N->getExprLoc();
4571  AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
4572  if (LastIteration32.isUsable())
4573  LastIteration32 = SemaRef.BuildBinOp(
4574  CurScope, Loc, BO_Mul, LastIteration32.get(),
4575  SemaRef
4576  .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
4578  /*AllowExplicit=*/true)
4579  .get());
4580  if (LastIteration64.isUsable())
4581  LastIteration64 = SemaRef.BuildBinOp(
4582  CurScope, Loc, BO_Mul, LastIteration64.get(),
4583  SemaRef
4584  .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
4586  /*AllowExplicit=*/true)
4587  .get());
4588  }
4589 
4590  // Choose either the 32-bit or 64-bit version.
4591  ExprResult LastIteration = LastIteration64;
4592  if (LastIteration32.isUsable() &&
4593  C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
4594  (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
4595  FitsInto(
4596  32 /* Bits */,
4597  LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
4598  LastIteration64.get(), SemaRef)))
4599  LastIteration = LastIteration32;
4600  QualType VType = LastIteration.get()->getType();
4601  QualType RealVType = VType;
4602  QualType StrideVType = VType;
4603  if (isOpenMPTaskLoopDirective(DKind)) {
4604  VType =
4605  SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
4606  StrideVType =
4607  SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
4608  }
4609 
4610  if (!LastIteration.isUsable())
4611  return 0;
4612 
4613  // Save the number of iterations.
4614  ExprResult NumIterations = LastIteration;
4615  {
4616  LastIteration = SemaRef.BuildBinOp(
4617  CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
4618  LastIteration.get(),
4619  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
4620  if (!LastIteration.isUsable())
4621  return 0;
4622  }
4623 
4624  // Calculate the last iteration number beforehand instead of doing this on
4625  // each iteration. Do not do this if the number of iterations may be kfold-ed.
4626  llvm::APSInt Result;
4627  bool IsConstant =
4628  LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context);
4629  ExprResult CalcLastIteration;
4630  if (!IsConstant) {
4631  ExprResult SaveRef =
4632  tryBuildCapture(SemaRef, LastIteration.get(), Captures);
4633  LastIteration = SaveRef;
4634 
4635  // Prepare SaveRef + 1.
4636  NumIterations = SemaRef.BuildBinOp(
4637  CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
4638  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
4639  if (!NumIterations.isUsable())
4640  return 0;
4641  }
4642 
4643  SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
4644 
4645  // Build variables passed into runtime, necessary for worksharing directives.
4646  ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
4648  isOpenMPDistributeDirective(DKind)) {
4649  // Lower bound variable, initialized with zero.
4650  VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
4651  LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
4652  SemaRef.AddInitializerToDecl(LBDecl,
4653  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
4654  /*DirectInit*/ false);
4655 
4656  // Upper bound variable, initialized with last iteration number.
4657  VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
4658  UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
4659  SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
4660  /*DirectInit*/ false);
4661 
4662  // A 32-bit variable-flag where runtime returns 1 for the last iteration.
4663  // This will be used to implement clause 'lastprivate'.
4664  QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
4665  VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
4666  IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
4667  SemaRef.AddInitializerToDecl(ILDecl,
4668  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
4669  /*DirectInit*/ false);
4670 
4671  // Stride variable returned by runtime (we initialize it to 1 by default).
4672  VarDecl *STDecl =
4673  buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
4674  ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
4675  SemaRef.AddInitializerToDecl(STDecl,
4676  SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
4677  /*DirectInit*/ false);
4678 
4679  // Build expression: UB = min(UB, LastIteration)
4680  // It is necessary for CodeGen of directives with static scheduling.
4681  ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
4682  UB.get(), LastIteration.get());
4683  ExprResult CondOp = SemaRef.ActOnConditionalOp(
4684  InitLoc, InitLoc, IsUBGreater.get(), LastIteration.get(), UB.get());
4685  EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
4686  CondOp.get());
4687  EUB = SemaRef.ActOnFinishFullExpr(EUB.get());
4688 
4689  // If we have a combined directive that combines 'distribute', 'for' or
4690  // 'simd' we need to be able to access the bounds of the schedule of the
4691  // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
4692  // by scheduling 'distribute' have to be passed to the schedule of 'for'.
4693  if (isOpenMPLoopBoundSharingDirective(DKind)) {
4694 
4695  // Lower bound variable, initialized with zero.
4696  VarDecl *CombLBDecl =
4697  buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
4698  CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
4699  SemaRef.AddInitializerToDecl(
4700  CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
4701  /*DirectInit*/ false);
4702 
4703  // Upper bound variable, initialized with last iteration number.
4704  VarDecl *CombUBDecl =
4705  buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
4706  CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
4707  SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
4708  /*DirectInit*/ false);
4709 
4710  ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
4711  CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
4712  ExprResult CombCondOp =
4713  SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
4714  LastIteration.get(), CombUB.get());
4715  CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
4716  CombCondOp.get());
4717  CombEUB = SemaRef.ActOnFinishFullExpr(CombEUB.get());
4718 
4719  auto *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
4720  // We expect to have at least 2 more parameters than the 'parallel'
4721  // directive does - the lower and upper bounds of the previous schedule.
4722  assert(CD->getNumParams() >= 4 &&
4723  "Unexpected number of parameters in loop combined directive");
4724 
4725  // Set the proper type for the bounds given what we learned from the
4726  // enclosed loops.
4727  auto *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
4728  auto *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
4729 
4730  // Previous lower and upper bounds are obtained from the region
4731  // parameters.
4732  PrevLB =
4733  buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
4734  PrevUB =
4735  buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
4736  }
4737  }
4738 
4739  // Build the iteration variable and its initialization before loop.
4740  ExprResult IV;
4741  ExprResult Init, CombInit;
4742  {
4743  VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
4744  IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
4745  Expr *RHS =
4746  (isOpenMPWorksharingDirective(DKind) ||
4748  ? LB.get()
4749  : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
4750  Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
4751  Init = SemaRef.ActOnFinishFullExpr(Init.get());
4752 
4753  if (isOpenMPLoopBoundSharingDirective(DKind)) {
4754  Expr *CombRHS =
4755  (isOpenMPWorksharingDirective(DKind) ||
4756  isOpenMPTaskLoopDirective(DKind) ||
4758  ? CombLB.get()
4759  : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
4760  CombInit =
4761  SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
4762  CombInit = SemaRef.ActOnFinishFullExpr(CombInit.get());
4763  }
4764  }
4765 
4766  // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops.
4767  SourceLocation CondLoc;
4768  ExprResult Cond =
4769  (isOpenMPWorksharingDirective(DKind) ||
4771  ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get())
4772  : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
4773  NumIterations.get());
4774  ExprResult CombCond;
4775  if (isOpenMPLoopBoundSharingDirective(DKind)) {
4776  CombCond =
4777  SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), CombUB.get());
4778  }
4779  // Loop increment (IV = IV + 1)
4780  SourceLocation IncLoc;
4781  ExprResult Inc =
4782  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
4783  SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
4784  if (!Inc.isUsable())
4785  return 0;
4786  Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
4787  Inc = SemaRef.ActOnFinishFullExpr(Inc.get());
4788  if (!Inc.isUsable())
4789  return 0;
4790 
4791  // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
4792  // Used for directives with static scheduling.
4793  // In combined construct, add combined version that use CombLB and CombUB
4794  // base variables for the update
4795  ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
4797  isOpenMPDistributeDirective(DKind)) {
4798  // LB + ST
4799  NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
4800  if (!NextLB.isUsable())
4801  return 0;
4802  // LB = LB + ST
4803  NextLB =
4804  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
4805  NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get());
4806  if (!NextLB.isUsable())
4807  return 0;
4808  // UB + ST
4809  NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
4810  if (!NextUB.isUsable())
4811  return 0;
4812  // UB = UB + ST
4813  NextUB =
4814  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
4815  NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get());
4816  if (!NextUB.isUsable())
4817  return 0;
4818  if (isOpenMPLoopBoundSharingDirective(DKind)) {
4819  CombNextLB =
4820  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
4821  if (!NextLB.isUsable())
4822  return 0;
4823  // LB = LB + ST
4824  CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
4825  CombNextLB.get());
4826  CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get());
4827  if (!CombNextLB.isUsable())
4828  return 0;
4829  // UB + ST
4830  CombNextUB =
4831  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
4832  if (!CombNextUB.isUsable())
4833  return 0;
4834  // UB = UB + ST
4835  CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
4836  CombNextUB.get());
4837  CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get());
4838  if (!CombNextUB.isUsable())
4839  return 0;
4840  }
4841  }
4842 
4843  // Create increment expression for distribute loop when combined in a same
4844  // directive with for as IV = IV + ST; ensure upper bound expression based
4845  // on PrevUB instead of NumIterations - used to implement 'for' when found
4846  // in combination with 'distribute', like in 'distribute parallel for'
4847  SourceLocation DistIncLoc;
4848  ExprResult DistCond, DistInc, PrevEUB;
4849  if (isOpenMPLoopBoundSharingDirective(DKind)) {
4850  DistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get());
4851  assert(DistCond.isUsable() && "distribute cond expr was not built");
4852 
4853  DistInc =
4854  SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
4855  assert(DistInc.isUsable() && "distribute inc expr was not built");
4856  DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
4857  DistInc.get());
4858  DistInc = SemaRef.ActOnFinishFullExpr(DistInc.get());
4859  assert(DistInc.isUsable() && "distribute inc expr was not built");
4860 
4861  // Build expression: UB = min(UB, prevUB) for #for in composite or combined
4862  // construct
4863  SourceLocation DistEUBLoc;
4864  ExprResult IsUBGreater =
4865  SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get());
4866  ExprResult CondOp = SemaRef.ActOnConditionalOp(
4867  DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
4868  PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
4869  CondOp.get());
4870  PrevEUB = SemaRef.ActOnFinishFullExpr(PrevEUB.get());
4871  }
4872 
4873  // Build updates and final values of the loop counters.
4874  bool HasErrors = false;
4875  Built.Counters.resize(NestedLoopCount);
4876  Built.Inits.resize(NestedLoopCount);
4877  Built.Updates.resize(NestedLoopCount);
4878  Built.Finals.resize(NestedLoopCount);
4879  SmallVector<Expr *, 4> LoopMultipliers;
4880  {
4881  ExprResult Div;
4882  // Go from inner nested loop to outer.
4883  for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) {
4884  LoopIterationSpace &IS = IterSpaces[Cnt];
4885  SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
4886  // Build: Iter = (IV / Div) % IS.NumIters
4887  // where Div is product of previous iterations' IS.NumIters.
4888  ExprResult Iter;
4889  if (Div.isUsable()) {
4890  Iter =
4891  SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, IV.get(), Div.get());
4892  } else {
4893  Iter = IV;
4894  assert((Cnt == (int)NestedLoopCount - 1) &&
4895  "unusable div expected on first iteration only");
4896  }
4897 
4898  if (Cnt != 0 && Iter.isUsable())
4899  Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.get(),
4900  IS.NumIterations);
4901  if (!Iter.isUsable()) {
4902  HasErrors = true;
4903  break;
4904  }
4905 
4906  // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
4907  auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
4908  auto *CounterVar = buildDeclRefExpr(SemaRef, VD, IS.CounterVar->getType(),
4909  IS.CounterVar->getExprLoc(),
4910  /*RefersToCapture=*/true);
4911  ExprResult Init = BuildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
4912  IS.CounterInit, Captures);
4913  if (!Init.isUsable()) {
4914  HasErrors = true;
4915  break;
4916  }
4918  SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
4919  IS.CounterStep, IS.Subtract, &Captures);
4920  if (!Update.isUsable()) {
4921  HasErrors = true;
4922  break;
4923  }
4924 
4925  // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
4927  SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit,
4928  IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures);
4929  if (!Final.isUsable()) {
4930  HasErrors = true;
4931  break;
4932  }
4933 
4934  // Build Div for the next iteration: Div <- Div * IS.NumIters
4935  if (Cnt != 0) {
4936  if (Div.isUnset())
4937  Div = IS.NumIterations;
4938  else
4939  Div = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.get(),
4940  IS.NumIterations);
4941 
4942  // Add parentheses (for debugging purposes only).
4943  if (Div.isUsable())
4944  Div = tryBuildCapture(SemaRef, Div.get(), Captures);
4945  if (!Div.isUsable()) {
4946  HasErrors = true;
4947  break;
4948  }
4949  LoopMultipliers.push_back(Div.get());
4950  }
4951  if (!Update.isUsable() || !Final.isUsable()) {
4952  HasErrors = true;
4953  break;
4954  }
4955  // Save results
4956  Built.Counters[Cnt] = IS.CounterVar;
4957  Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
4958  Built.Inits[Cnt] = Init.get();
4959  Built.Updates[Cnt] = Update.get();
4960  Built.Finals[Cnt] = Final.get();
4961  }
4962  }
4963 
4964  if (HasErrors)
4965  return 0;
4966 
4967  // Save results
4968  Built.IterationVarRef = IV.get();
4969  Built.LastIteration = LastIteration.get();
4970  Built.NumIterations = NumIterations.get();
4971  Built.CalcLastIteration =
4972  SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get();
4973  Built.PreCond = PreCond.get();
4974  Built.PreInits = buildPreInits(C, Captures);
4975  Built.Cond = Cond.get();
4976  Built.Init = Init.get();
4977  Built.Inc = Inc.get();
4978  Built.LB = LB.get();
4979  Built.UB = UB.get();
4980  Built.IL = IL.get();
4981  Built.ST = ST.get();
4982  Built.EUB = EUB.get();
4983  Built.NLB = NextLB.get();
4984  Built.NUB = NextUB.get();
4985  Built.PrevLB = PrevLB.get();
4986  Built.PrevUB = PrevUB.get();
4987  Built.DistInc = DistInc.get();
4988  Built.PrevEUB = PrevEUB.get();
4989  Built.DistCombinedFields.LB = CombLB.get();
4990  Built.DistCombinedFields.UB = CombUB.get();
4991  Built.DistCombinedFields.EUB = CombEUB.get();
4992  Built.DistCombinedFields.Init = CombInit.get();
4993  Built.DistCombinedFields.Cond = CombCond.get();
4994  Built.DistCombinedFields.NLB = CombNextLB.get();
4995  Built.DistCombinedFields.NUB = CombNextUB.get();
4996 
4997  Expr *CounterVal = SemaRef.DefaultLvalueConversion(IV.get()).get();
4998  // Fill data for doacross depend clauses.
4999  for (auto Pair : DSA.getDoacrossDependClauses()) {
5000  if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
5001  Pair.first->setCounterValue(CounterVal);
5002  else {
5003  if (NestedLoopCount != Pair.second.size() ||
5004  NestedLoopCount != LoopMultipliers.size() + 1) {
5005  // Erroneous case - clause has some problems.
5006  Pair.first->setCounterValue(CounterVal);
5007  continue;
5008  }
5009  assert(Pair.first->getDependencyKind() == OMPC_DEPEND_sink);
5010  auto I = Pair.second.rbegin();
5011  auto IS = IterSpaces.rbegin();
5012  auto ILM = LoopMultipliers.rbegin();
5013  Expr *UpCounterVal = CounterVal;
5014  Expr *Multiplier = nullptr;
5015  for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) {
5016  if (I->first) {
5017  assert(IS->CounterStep);
5018  Expr *NormalizedOffset =
5019  SemaRef
5020  .BuildBinOp(CurScope, I->first->getExprLoc(), BO_Div,
5021  I->first, IS->CounterStep)
5022  .get();
5023  if (Multiplier) {
5024  NormalizedOffset =
5025  SemaRef
5026  .BuildBinOp(CurScope, I->first->getExprLoc(), BO_Mul,
5027  NormalizedOffset, Multiplier)
5028  .get();
5029  }
5030  assert(I->second == OO_Plus || I->second == OO_Minus);
5031  BinaryOperatorKind BOK = (I->second == OO_Plus) ? BO_Add : BO_Sub;
5032  UpCounterVal = SemaRef
5033  .BuildBinOp(CurScope, I->first->getExprLoc(), BOK,
5034  UpCounterVal, NormalizedOffset)
5035  .get();
5036  }
5037  Multiplier = *ILM;
5038  ++I;
5039  ++IS;
5040  ++ILM;
5041  }
5042  Pair.first->setCounterValue(UpCounterVal);
5043  }
5044  }
5045 
5046  return NestedLoopCount;
5047 }
5048 
5050  auto CollapseClauses =
5051  OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
5052  if (CollapseClauses.begin() != CollapseClauses.end())
5053  return (*CollapseClauses.begin())->getNumForLoops();
5054  return nullptr;
5055 }
5056 
5058  auto OrderedClauses =
5059  OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
5060  if (OrderedClauses.begin() != OrderedClauses.end())
5061  return (*OrderedClauses.begin())->getNumForLoops();
5062  return nullptr;
5063 }
5064 
5066  const ArrayRef<OMPClause *> Clauses) {
5067  OMPSafelenClause *Safelen = nullptr;
5068  OMPSimdlenClause *Simdlen = nullptr;
5069 
5070  for (auto *Clause : Clauses) {
5071  if (Clause->getClauseKind() == OMPC_safelen)
5072  Safelen = cast<OMPSafelenClause>(Clause);
5073  else if (Clause->getClauseKind() == OMPC_simdlen)
5074  Simdlen = cast<OMPSimdlenClause>(Clause);
5075  if (Safelen && Simdlen)
5076  break;
5077  }
5078 
5079  if (Simdlen && Safelen) {
5080  llvm::APSInt SimdlenRes, SafelenRes;
5081  auto SimdlenLength = Simdlen->getSimdlen();
5082  auto SafelenLength = Safelen->getSafelen();
5083  if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
5084  SimdlenLength->isInstantiationDependent() ||
5085  SimdlenLength->containsUnexpandedParameterPack())
5086  return false;
5087  if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
5088  SafelenLength->isInstantiationDependent() ||
5089  SafelenLength->containsUnexpandedParameterPack())
5090  return false;
5091  SimdlenLength->EvaluateAsInt(SimdlenRes, S.Context);
5092  SafelenLength->EvaluateAsInt(SafelenRes, S.Context);
5093  // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
5094  // If both simdlen and safelen clauses are specified, the value of the
5095  // simdlen parameter must be less than or equal to the value of the safelen
5096  // parameter.
5097  if (SimdlenRes > SafelenRes) {
5098  S.Diag(SimdlenLength->getExprLoc(),
5099  diag::err_omp_wrong_simdlen_safelen_values)
5100  << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
5101  return true;
5102  }
5103  }
5104  return false;
5105 }
5106 
5108  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5109  SourceLocation EndLoc,
5110  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5111  if (!AStmt)
5112  return StmtError();
5113 
5114  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5116  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5117  // define the nested loops number.
5118  unsigned NestedLoopCount = CheckOpenMPLoop(
5119  OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
5120  AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
5121  if (NestedLoopCount == 0)
5122  return StmtError();
5123 
5124  assert((CurContext->isDependentContext() || B.builtAll()) &&
5125  "omp simd loop exprs were not built");
5126 
5127  if (!CurContext->isDependentContext()) {
5128  // Finalize the clauses that need pre-built expressions for CodeGen.
5129  for (auto C : Clauses) {
5130  if (auto *LC = dyn_cast<OMPLinearClause>(C))
5131  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5132  B.NumIterations, *this, CurScope,
5133  DSAStack))
5134  return StmtError();
5135  }
5136  }
5137 
5138  if (checkSimdlenSafelenSpecified(*this, Clauses))
5139  return StmtError();
5140 
5141  getCurFunction()->setHasBranchProtectedScope();
5142  return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5143  Clauses, AStmt, B);
5144 }
5145 
5147  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5148  SourceLocation EndLoc,
5149  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5150  if (!AStmt)
5151  return StmtError();
5152 
5153  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5155  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5156  // define the nested loops number.
5157  unsigned NestedLoopCount = CheckOpenMPLoop(
5158  OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
5159  AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
5160  if (NestedLoopCount == 0)
5161  return StmtError();
5162 
5163  assert((CurContext->isDependentContext() || B.builtAll()) &&
5164  "omp for loop exprs were not built");
5165 
5166  if (!CurContext->isDependentContext()) {
5167  // Finalize the clauses that need pre-built expressions for CodeGen.
5168  for (auto C : Clauses) {
5169  if (auto *LC = dyn_cast<OMPLinearClause>(C))
5170  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5171  B.NumIterations, *this, CurScope,
5172  DSAStack))
5173  return StmtError();
5174  }
5175  }
5176 
5177  getCurFunction()->setHasBranchProtectedScope();
5178  return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5179  Clauses, AStmt, B, DSAStack->isCancelRegion());
5180 }
5181 
5183  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5184  SourceLocation EndLoc,
5185  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5186  if (!AStmt)
5187  return StmtError();
5188 
5189  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5191  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5192  // define the nested loops number.
5193  unsigned NestedLoopCount =
5194  CheckOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
5195  getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
5196  VarsWithImplicitDSA, B);
5197  if (NestedLoopCount == 0)
5198  return StmtError();
5199 
5200  assert((CurContext->isDependentContext() || B.builtAll()) &&
5201  "omp for simd loop exprs were not built");
5202 
5203  if (!CurContext->isDependentContext()) {
5204  // Finalize the clauses that need pre-built expressions for CodeGen.
5205  for (auto C : Clauses) {
5206  if (auto *LC = dyn_cast<OMPLinearClause>(C))
5207  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5208  B.NumIterations, *this, CurScope,
5209  DSAStack))
5210  return StmtError();
5211  }
5212  }
5213 
5214  if (checkSimdlenSafelenSpecified(*this, Clauses))
5215  return StmtError();
5216 
5217  getCurFunction()->setHasBranchProtectedScope();
5218  return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5219  Clauses, AStmt, B);
5220 }
5221 
5223  Stmt *AStmt,
5224  SourceLocation StartLoc,
5225  SourceLocation EndLoc) {
5226  if (!AStmt)
5227  return StmtError();
5228 
5229  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5230  auto BaseStmt = AStmt;
5231  while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
5232  BaseStmt = CS->getCapturedStmt();
5233  if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
5234  auto S = C->children();
5235  if (S.begin() == S.end())
5236  return StmtError();
5237  // All associated statements must be '#pragma omp section' except for
5238  // the first one.
5239  for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
5240  if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
5241  if (SectionStmt)
5242  Diag(SectionStmt->getLocStart(),
5243  diag::err_omp_sections_substmt_not_section);
5244  return StmtError();
5245  }
5246  cast<OMPSectionDirective>(SectionStmt)
5247  ->setHasCancel(DSAStack->isCancelRegion());
5248  }
5249  } else {
5250  Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt);
5251  return StmtError();
5252  }
5253 
5254  getCurFunction()->setHasBranchProtectedScope();
5255 
5256  return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
5257  DSAStack->isCancelRegion());
5258 }
5259 
5261  SourceLocation StartLoc,
5262  SourceLocation EndLoc) {
5263  if (!AStmt)
5264  return StmtError();
5265 
5266  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5267 
5268  getCurFunction()->setHasBranchProtectedScope();
5269  DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
5270 
5271  return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
5272  DSAStack->isCancelRegion());
5273 }
5274 
5276  Stmt *AStmt,
5277  SourceLocation StartLoc,
5278  SourceLocation EndLoc) {
5279  if (!AStmt)
5280  return StmtError();
5281 
5282  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5283 
5284  getCurFunction()->setHasBranchProtectedScope();
5285 
5286  // OpenMP [2.7.3, single Construct, Restrictions]
5287  // The copyprivate clause must not be used with the nowait clause.
5288  OMPClause *Nowait = nullptr;
5289  OMPClause *Copyprivate = nullptr;
5290  for (auto *Clause : Clauses) {
5291  if (Clause->getClauseKind() == OMPC_nowait)
5292  Nowait = Clause;
5293  else if (Clause->getClauseKind() == OMPC_copyprivate)
5294  Copyprivate = Clause;
5295  if (Copyprivate && Nowait) {
5296  Diag(Copyprivate->getLocStart(),
5297  diag::err_omp_single_copyprivate_with_nowait);
5298  Diag(Nowait->getLocStart(), diag::note_omp_nowait_clause_here);
5299  return StmtError();
5300  }
5301  }
5302 
5303  return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
5304 }
5305 
5307  SourceLocation StartLoc,
5308  SourceLocation EndLoc) {
5309  if (!AStmt)
5310  return StmtError();
5311 
5312  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5313 
5314  getCurFunction()->setHasBranchProtectedScope();
5315 
5316  return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
5317 }
5318 
5320  const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
5321  Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
5322  if (!AStmt)
5323  return StmtError();
5324 
5325  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5326 
5327  bool ErrorFound = false;
5328  llvm::APSInt Hint;
5329  SourceLocation HintLoc;
5330  bool DependentHint = false;
5331  for (auto *C : Clauses) {
5332  if (C->getClauseKind() == OMPC_hint) {
5333  if (!DirName.getName()) {
5334  Diag(C->getLocStart(), diag::err_omp_hint_clause_no_name);
5335  ErrorFound = true;
5336  }
5337  Expr *E = cast<OMPHintClause>(C)->getHint();
5338  if (E->isTypeDependent() || E->isValueDependent() ||
5340  DependentHint = true;
5341  else {
5342  Hint = E->EvaluateKnownConstInt(Context);
5343  HintLoc = C->getLocStart();
5344  }
5345  }
5346  }
5347  if (ErrorFound)
5348  return StmtError();
5349  auto Pair = DSAStack->getCriticalWithHint(DirName);
5350  if (Pair.first && DirName.getName() && !DependentHint) {
5351  if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
5352  Diag(StartLoc, diag::err_omp_critical_with_hint);
5353  if (HintLoc.isValid()) {
5354  Diag(HintLoc, diag::note_omp_critical_hint_here)
5355  << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false);
5356  } else
5357  Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
5358  if (auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
5359  Diag(C->getLocStart(), diag::note_omp_critical_hint_here)
5360  << 1
5361  << C->getHint()->EvaluateKnownConstInt(Context).toString(
5362  /*Radix=*/10, /*Signed=*/false);
5363  } else
5364  Diag(Pair.first->getLocStart(), diag::note_omp_critical_no_hint) << 1;
5365  }
5366  }
5367 
5368  getCurFunction()->setHasBranchProtectedScope();
5369 
5370  auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
5371  Clauses, AStmt);
5372  if (!Pair.first && DirName.getName() && !DependentHint)
5373  DSAStack->addCriticalWithHint(Dir, Hint);
5374  return Dir;
5375 }
5376 
5378  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5379  SourceLocation EndLoc,
5380  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5381  if (!AStmt)
5382  return StmtError();
5383 
5384  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
5385  // 1.2.2 OpenMP Language Terminology
5386  // Structured block - An executable statement with a single entry at the
5387  // top and a single exit at the bottom.
5388  // The point of exit cannot be a branch out of the structured block.
5389  // longjmp() and throw() must not violate the entry/exit criteria.
5390  CS->getCapturedDecl()->setNothrow();
5391 
5393  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5394  // define the nested loops number.
5395  unsigned NestedLoopCount =
5396  CheckOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
5397  getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
5398  VarsWithImplicitDSA, B);
5399  if (NestedLoopCount == 0)
5400  return StmtError();
5401 
5402  assert((CurContext->isDependentContext() || B.builtAll()) &&
5403  "omp parallel for loop exprs were not built");
5404 
5405  if (!CurContext->isDependentContext()) {
5406  // Finalize the clauses that need pre-built expressions for CodeGen.
5407  for (auto C : Clauses) {
5408  if (auto *LC = dyn_cast<OMPLinearClause>(C))
5409  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5410  B.NumIterations, *this, CurScope,
5411  DSAStack))
5412  return StmtError();
5413  }
5414  }
5415 
5416  getCurFunction()->setHasBranchProtectedScope();
5417  return OMPParallelForDirective::Create(Context, StartLoc, EndLoc,
5418  NestedLoopCount, Clauses, AStmt, B,
5419  DSAStack->isCancelRegion());
5420 }
5421 
5423  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5424  SourceLocation EndLoc,
5425  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
5426  if (!AStmt)
5427  return StmtError();
5428 
5429  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
5430  // 1.2.2 OpenMP Language Terminology
5431  // Structured block - An executable statement with a single entry at the
5432  // top and a single exit at the bottom.
5433  // The point of exit cannot be a branch out of the structured block.
5434  // longjmp() and throw() must not violate the entry/exit criteria.
5435  CS->getCapturedDecl()->setNothrow();
5436 
5438  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5439  // define the nested loops number.
5440  unsigned NestedLoopCount =
5441  CheckOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
5442  getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
5443  VarsWithImplicitDSA, B);
5444  if (NestedLoopCount == 0)
5445  return StmtError();
5446 
5447  if (!CurContext->isDependentContext()) {
5448  // Finalize the clauses that need pre-built expressions for CodeGen.
5449  for (auto C : Clauses) {
5450  if (auto *LC = dyn_cast<OMPLinearClause>(C))
5451  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5452  B.NumIterations, *this, CurScope,
5453  DSAStack))
5454  return StmtError();
5455  }
5456  }
5457 
5458  if (checkSimdlenSafelenSpecified(*this, Clauses))
5459  return StmtError();
5460 
5461  getCurFunction()->setHasBranchProtectedScope();
5463  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
5464 }
5465 
5466 StmtResult
5468  Stmt *AStmt, SourceLocation StartLoc,
5469  SourceLocation EndLoc) {
5470  if (!AStmt)
5471  return StmtError();
5472 
5473  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5474  auto BaseStmt = AStmt;
5475  while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
5476  BaseStmt = CS->getCapturedStmt();
5477  if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
5478  auto S = C->children();
5479  if (S.begin() == S.end())
5480  return StmtError();
5481  // All associated statements must be '#pragma omp section' except for
5482  // the first one.
5483  for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
5484  if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
5485  if (SectionStmt)
5486  Diag(SectionStmt->getLocStart(),
5487  diag::err_omp_parallel_sections_substmt_not_section);
5488  return StmtError();
5489  }
5490  cast<OMPSectionDirective>(SectionStmt)
5491  ->setHasCancel(DSAStack->isCancelRegion());
5492  }
5493  } else {
5494  Diag(AStmt->getLocStart(),
5495  diag::err_omp_parallel_sections_not_compound_stmt);
5496  return StmtError();
5497  }
5498 
5499  getCurFunction()->setHasBranchProtectedScope();
5500 
5502  Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion());
5503 }
5504 
5506  Stmt *AStmt, SourceLocation StartLoc,
5507  SourceLocation EndLoc) {
5508  if (!AStmt)
5509  return StmtError();
5510 
5511  auto *CS = cast<CapturedStmt>(AStmt);
5512  // 1.2.2 OpenMP Language Terminology
5513  // Structured block - An executable statement with a single entry at the
5514  // top and a single exit at the bottom.
5515  // The point of exit cannot be a branch out of the structured block.
5516  // longjmp() and throw() must not violate the entry/exit criteria.
5517  CS->getCapturedDecl()->setNothrow();
5518 
5519  getCurFunction()->setHasBranchProtectedScope();
5520 
5521  return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
5522  DSAStack->isCancelRegion());
5523 }
5524 
5526  SourceLocation EndLoc) {
5527  return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
5528 }
5529 
5531  SourceLocation EndLoc) {
5532  return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
5533 }
5534 
5536  SourceLocation EndLoc) {
5537  return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
5538 }
5539 
5541  Stmt *AStmt,
5542  SourceLocation StartLoc,
5543  SourceLocation EndLoc) {
5544  if (!AStmt)
5545  return StmtError();
5546 
5547  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5548 
5549  getCurFunction()->setHasBranchProtectedScope();
5550 
5551  return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
5552  AStmt,
5553  DSAStack->getTaskgroupReductionRef());
5554 }
5555 
5557  SourceLocation StartLoc,
5558  SourceLocation EndLoc) {
5559  assert(Clauses.size() <= 1 && "Extra clauses in flush directive");
5560  return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
5561 }
5562 
5564  Stmt *AStmt,
5565  SourceLocation StartLoc,
5566  SourceLocation EndLoc) {
5567  OMPClause *DependFound = nullptr;
5568  OMPClause *DependSourceClause = nullptr;
5569  OMPClause *DependSinkClause = nullptr;
5570  bool ErrorFound = false;
5571  OMPThreadsClause *TC = nullptr;
5572  OMPSIMDClause *SC = nullptr;
5573  for (auto *C : Clauses) {
5574  if (auto *DC = dyn_cast<OMPDependClause>(C)) {
5575  DependFound = C;
5576  if (DC->getDependencyKind() == OMPC_DEPEND_source) {
5577  if (DependSourceClause) {
5578  Diag(C->getLocStart(), diag::err_omp_more_one_clause)
5579  << getOpenMPDirectiveName(OMPD_ordered)
5580  << getOpenMPClauseName(OMPC_depend) << 2;
5581  ErrorFound = true;
5582  } else
5583  DependSourceClause = C;
5584  if (DependSinkClause) {
5585  Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed)
5586  << 0;
5587  ErrorFound = true;
5588  }
5589  } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
5590  if (DependSourceClause) {
5591  Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed)
5592  << 1;
5593  ErrorFound = true;
5594  }
5595  DependSinkClause = C;
5596  }
5597  } else if (C->getClauseKind() == OMPC_threads)
5598  TC = cast<OMPThreadsClause>(C);
5599  else if (C->getClauseKind() == OMPC_simd)
5600  SC = cast<OMPSIMDClause>(C);
5601  }
5602  if (!ErrorFound && !SC &&
5603  isOpenMPSimdDirective(DSAStack->getParentDirective())) {
5604  // OpenMP [2.8.1,simd Construct, Restrictions]
5605  // An ordered construct with the simd clause is the only OpenMP construct
5606  // that can appear in the simd region.
5607  Diag(StartLoc, diag::err_omp_prohibited_region_simd);
5608  ErrorFound = true;
5609  } else if (DependFound && (TC || SC)) {
5610  Diag(DependFound->getLocStart(), diag::err_omp_depend_clause_thread_simd)
5611  << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
5612  ErrorFound = true;
5613  } else if (DependFound && !DSAStack->getParentOrderedRegionParam()) {
5614  Diag(DependFound->getLocStart(),
5615  diag::err_omp_ordered_directive_without_param);
5616  ErrorFound = true;
5617  } else if (TC || Clauses.empty()) {
5618  if (auto *Param = DSAStack->getParentOrderedRegionParam()) {
5619  SourceLocation ErrLoc = TC ? TC->getLocStart() : StartLoc;
5620  Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
5621  << (TC != nullptr);
5622  Diag(Param->getLocStart(), diag::note_omp_ordered_param);
5623  ErrorFound = true;
5624  }
5625  }
5626  if ((!AStmt && !DependFound) || ErrorFound)
5627  return StmtError();
5628 
5629  if (AStmt) {
5630  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5631 
5632  getCurFunction()->setHasBranchProtectedScope();
5633  }
5634 
5635  return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
5636 }
5637 
5638 namespace {
5639 /// \brief Helper class for checking expression in 'omp atomic [update]'
5640 /// construct.
5641 class OpenMPAtomicUpdateChecker {
5642  /// \brief Error results for atomic update expressions.
5643  enum ExprAnalysisErrorCode {
5644  /// \brief A statement is not an expression statement.
5645  NotAnExpression,
5646  /// \brief Expression is not builtin binary or unary operation.
5647  NotABinaryOrUnaryExpression,
5648  /// \brief Unary operation is not post-/pre- increment/decrement operation.
5649  NotAnUnaryIncDecExpression,
5650  /// \brief An expression is not of scalar type.
5651  NotAScalarType,
5652  /// \brief A binary operation is not an assignment operation.
5653  NotAnAssignmentOp,
5654  /// \brief RHS part of the binary operation is not a binary expression.
5655  NotABinaryExpression,
5656  /// \brief RHS part is not additive/multiplicative/shift/biwise binary
5657  /// expression.
5658  NotABinaryOperator,
5659  /// \brief RHS binary operation does not have reference to the updated LHS
5660  /// part.
5661  NotAnUpdateExpression,
5662  /// \brief No errors is found.
5663  NoError
5664  };
5665  /// \brief Reference to Sema.
5666  Sema &SemaRef;
5667  /// \brief A location for note diagnostics (when error is found).
5668  SourceLocation NoteLoc;
5669  /// \brief 'x' lvalue part of the source atomic expression.
5670  Expr *X;
5671  /// \brief 'expr' rvalue part of the source atomic expression.
5672  Expr *E;
5673  /// \brief Helper expression of the form
5674  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
5675  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
5676  Expr *UpdateExpr;
5677  /// \brief Is 'x' a LHS in a RHS part of full update expression. It is
5678  /// important for non-associative operations.
5679  bool IsXLHSInRHSPart;
5680  BinaryOperatorKind Op;
5681  SourceLocation OpLoc;
5682  /// \brief true if the source expression is a postfix unary operation, false
5683  /// if it is a prefix unary operation.
5684  bool IsPostfixUpdate;
5685 
5686 public:
5687  OpenMPAtomicUpdateChecker(Sema &SemaRef)
5688  : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
5689  IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
5690  /// \brief Check specified statement that it is suitable for 'atomic update'
5691  /// constructs and extract 'x', 'expr' and Operation from the original
5692  /// expression. If DiagId and NoteId == 0, then only check is performed
5693  /// without error notification.
5694  /// \param DiagId Diagnostic which should be emitted if error is found.
5695  /// \param NoteId Diagnostic note for the main error message.
5696  /// \return true if statement is not an update expression, false otherwise.
5697  bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
5698  /// \brief Return the 'x' lvalue part of the source atomic expression.
5699  Expr *getX() const { return X; }
5700  /// \brief Return the 'expr' rvalue part of the source atomic expression.
5701  Expr *getExpr() const { return E; }
5702  /// \brief Return the update expression used in calculation of the updated
5703  /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
5704  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
5705  Expr *getUpdateExpr() const { return UpdateExpr; }
5706  /// \brief Return true if 'x' is LHS in RHS part of full update expression,
5707  /// false otherwise.
5708  bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
5709 
5710  /// \brief true if the source expression is a postfix unary operation, false
5711  /// if it is a prefix unary operation.
5712  bool isPostfixUpdate() const { return IsPostfixUpdate; }
5713 
5714 private:
5715  bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
5716  unsigned NoteId = 0);
5717 };
5718 } // namespace
5719 
5720 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
5721  BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
5722  ExprAnalysisErrorCode ErrorFound = NoError;
5723  SourceLocation ErrorLoc, NoteLoc;
5724  SourceRange ErrorRange, NoteRange;
5725  // Allowed constructs are:
5726  // x = x binop expr;
5727  // x = expr binop x;
5728  if (AtomicBinOp->getOpcode() == BO_Assign) {
5729  X = AtomicBinOp->getLHS();
5730  if (auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
5731  AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
5732  if (AtomicInnerBinOp->isMultiplicativeOp() ||
5733  AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
5734  AtomicInnerBinOp->isBitwiseOp()) {
5735  Op = AtomicInnerBinOp->getOpcode();
5736  OpLoc = AtomicInnerBinOp->getOperatorLoc();
5737  auto *LHS = AtomicInnerBinOp->getLHS();
5738  auto *RHS = AtomicInnerBinOp->getRHS();
5739  llvm::FoldingSetNodeID XId, LHSId, RHSId;
5740  X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
5741  /*Canonical=*/true);
5742  LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
5743  /*Canonical=*/true);
5744  RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
5745  /*Canonical=*/true);
5746  if (XId == LHSId) {
5747  E = RHS;
5748  IsXLHSInRHSPart = true;
5749  } else if (XId == RHSId) {
5750  E = LHS;
5751  IsXLHSInRHSPart = false;
5752  } else {
5753  ErrorLoc = AtomicInnerBinOp->getExprLoc();
5754  ErrorRange = AtomicInnerBinOp->getSourceRange();
5755  NoteLoc = X->getExprLoc();
5756  NoteRange = X->getSourceRange();
5757  ErrorFound = NotAnUpdateExpression;
5758  }
5759  } else {
5760  ErrorLoc = AtomicInnerBinOp->getExprLoc();
5761  ErrorRange = AtomicInnerBinOp->getSourceRange();
5762  NoteLoc = AtomicInnerBinOp->getOperatorLoc();
5763  NoteRange = SourceRange(NoteLoc, NoteLoc);
5764  ErrorFound = NotABinaryOperator;
5765  }
5766  } else {
5767  NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
5768  NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
5769  ErrorFound = NotABinaryExpression;
5770  }
5771  } else {
5772  ErrorLoc = AtomicBinOp->getExprLoc();
5773  ErrorRange = AtomicBinOp->getSourceRange();
5774  NoteLoc = AtomicBinOp->getOperatorLoc();
5775  NoteRange = SourceRange(NoteLoc, NoteLoc);
5776  ErrorFound = NotAnAssignmentOp;
5777  }
5778  if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
5779  SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
5780  SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
5781  return true;
5782  } else if (SemaRef.CurContext->isDependentContext())
5783  E = X = UpdateExpr = nullptr;
5784  return ErrorFound != NoError;
5785 }
5786 
5787 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
5788  unsigned NoteId) {
5789  ExprAnalysisErrorCode ErrorFound = NoError;
5790  SourceLocation ErrorLoc, NoteLoc;
5791  SourceRange ErrorRange, NoteRange;
5792  // Allowed constructs are:
5793  // x++;
5794  // x--;
5795  // ++x;
5796  // --x;
5797  // x binop= expr;
5798  // x = x binop expr;
5799  // x = expr binop x;
5800  if (auto *AtomicBody = dyn_cast<Expr>(S)) {
5801  AtomicBody = AtomicBody->IgnoreParenImpCasts();
5802  if (AtomicBody->getType()->isScalarType() ||
5803  AtomicBody->isInstantiationDependent()) {
5804  if (auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
5805  AtomicBody->IgnoreParenImpCasts())) {
5806  // Check for Compound Assignment Operation
5808  AtomicCompAssignOp->getOpcode());
5809  OpLoc = AtomicCompAssignOp->getOperatorLoc();
5810  E = AtomicCompAssignOp->getRHS();
5811  X = AtomicCompAssignOp->getLHS()->IgnoreParens();
5812  IsXLHSInRHSPart = true;
5813  } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
5814  AtomicBody->IgnoreParenImpCasts())) {
5815  // Check for Binary Operation
5816  if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
5817  return true;
5818  } else if (auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
5819  AtomicBody->IgnoreParenImpCasts())) {
5820  // Check for Unary Operation
5821  if (AtomicUnaryOp->isIncrementDecrementOp()) {
5822  IsPostfixUpdate = AtomicUnaryOp->isPostfix();
5823  Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
5824  OpLoc = AtomicUnaryOp->getOperatorLoc();
5825  X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
5826  E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
5827  IsXLHSInRHSPart = true;
5828  } else {
5829  ErrorFound = NotAnUnaryIncDecExpression;
5830  ErrorLoc = AtomicUnaryOp->getExprLoc();
5831  ErrorRange = AtomicUnaryOp->getSourceRange();
5832  NoteLoc = AtomicUnaryOp->getOperatorLoc();
5833  NoteRange = SourceRange(NoteLoc, NoteLoc);
5834  }
5835  } else if (!AtomicBody->isInstantiationDependent()) {
5836  ErrorFound = NotABinaryOrUnaryExpression;
5837  NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
5838  NoteRange = ErrorRange = AtomicBody->getSourceRange();
5839  }
5840  } else {
5841  ErrorFound = NotAScalarType;
5842  NoteLoc = ErrorLoc = AtomicBody->getLocStart();
5843  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
5844  }
5845  } else {
5846  ErrorFound = NotAnExpression;
5847  NoteLoc = ErrorLoc = S->getLocStart();
5848  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
5849  }
5850  if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
5851  SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
5852  SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
5853  return true;
5854  } else if (SemaRef.CurContext->isDependentContext())
5855  E = X = UpdateExpr = nullptr;
5856  if (ErrorFound == NoError && E && X) {
5857  // Build an update expression of form 'OpaqueValueExpr(x) binop
5858  // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
5859  // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
5860  auto *OVEX = new (SemaRef.getASTContext())
5861  OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue);
5862  auto *OVEExpr = new (SemaRef.getASTContext())
5864  auto Update =
5865  SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
5866  IsXLHSInRHSPart ? OVEExpr : OVEX);
5867  if (Update.isInvalid())
5868  return true;
5869  Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
5871  if (Update.isInvalid())
5872  return true;
5873  UpdateExpr = Update.get();
5874  }
5875  return ErrorFound != NoError;
5876 }
5877 
5879  Stmt *AStmt,
5880  SourceLocation StartLoc,
5881  SourceLocation EndLoc) {
5882  if (!AStmt)
5883  return StmtError();
5884 
5885  auto *CS = cast<CapturedStmt>(AStmt);
5886  // 1.2.2 OpenMP Language Terminology
5887  // Structured block - An executable statement with a single entry at the
5888  // top and a single exit at the bottom.
5889  // The point of exit cannot be a branch out of the structured block.
5890  // longjmp() and throw() must not violate the entry/exit criteria.
5891  OpenMPClauseKind AtomicKind = OMPC_unknown;
5892  SourceLocation AtomicKindLoc;
5893  for (auto *C : Clauses) {
5894  if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
5895  C->getClauseKind() == OMPC_update ||
5896  C->getClauseKind() == OMPC_capture) {
5897  if (AtomicKind != OMPC_unknown) {
5898  Diag(C->getLocStart(), diag::err_omp_atomic_several_clauses)
5899  << SourceRange(C->getLocStart(), C->getLocEnd());
5900  Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause)
5901  << getOpenMPClauseName(AtomicKind);
5902  } else {
5903  AtomicKind = C->getClauseKind();
5904  AtomicKindLoc = C->getLocStart();
5905  }
5906  }
5907  }
5908 
5909  auto Body = CS->getCapturedStmt();
5910  if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
5911  Body = EWC->getSubExpr();
5912 
5913  Expr *X = nullptr;
5914  Expr *V = nullptr;
5915  Expr *E = nullptr;
5916  Expr *UE = nullptr;
5917  bool IsXLHSInRHSPart = false;
5918  bool IsPostfixUpdate = false;
5919  // OpenMP [2.12.6, atomic Construct]
5920  // In the next expressions:
5921  // * x and v (as applicable) are both l-value expressions with scalar type.
5922  // * During the execution of an atomic region, multiple syntactic
5923  // occurrences of x must designate the same storage location.
5924  // * Neither of v and expr (as applicable) may access the storage location
5925  // designated by x.
5926  // * Neither of x and expr (as applicable) may access the storage location
5927  // designated by v.
5928  // * expr is an expression with scalar type.
5929  // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
5930  // * binop, binop=, ++, and -- are not overloaded operators.
5931  // * The expression x binop expr must be numerically equivalent to x binop
5932  // (expr). This requirement is satisfied if the operators in expr have
5933  // precedence greater than binop, or by using parentheses around expr or
5934  // subexpressions of expr.
5935  // * The expression expr binop x must be numerically equivalent to (expr)
5936  // binop x. This requirement is satisfied if the operators in expr have
5937  // precedence equal to or greater than binop, or by using parentheses around
5938  // expr or subexpressions of expr.
5939  // * For forms that allow multiple occurrences of x, the number of times
5940  // that x is evaluated is unspecified.
5941  if (AtomicKind == OMPC_read) {
5942  enum {
5943  NotAnExpression,
5944  NotAnAssignmentOp,
5945  NotAScalarType,
5946  NotAnLValue,
5947  NoError
5948  } ErrorFound = NoError;
5949  SourceLocation ErrorLoc, NoteLoc;
5950  SourceRange ErrorRange, NoteRange;
5951  // If clause is read:
5952  // v = x;
5953  if (auto *AtomicBody = dyn_cast<Expr>(Body)) {
5954  auto *AtomicBinOp =
5955  dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
5956  if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
5957  X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
5958  V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
5959  if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
5960  (V->isInstantiationDependent() || V->getType()->isScalarType())) {
5961  if (!X->isLValue() || !V->isLValue()) {
5962  auto NotLValueExpr = X->isLValue() ? V : X;
5963  ErrorFound = NotAnLValue;
5964  ErrorLoc = AtomicBinOp->getExprLoc();
5965  ErrorRange = AtomicBinOp->getSourceRange();
5966  NoteLoc = NotLValueExpr->getExprLoc();
5967  NoteRange = NotLValueExpr->getSourceRange();
5968  }
5969  } else if (!X->isInstantiationDependent() ||
5970  !V->isInstantiationDependent()) {
5971  auto NotScalarExpr =
5973  ? V
5974  : X;
5975  ErrorFound = NotAScalarType;
5976  ErrorLoc = AtomicBinOp->getExprLoc();
5977  ErrorRange = AtomicBinOp->getSourceRange();
5978  NoteLoc = NotScalarExpr->getExprLoc();
5979  NoteRange = NotScalarExpr->getSourceRange();
5980  }
5981  } else if (!AtomicBody->isInstantiationDependent()) {
5982  ErrorFound = NotAnAssignmentOp;
5983  ErrorLoc = AtomicBody->getExprLoc();
5984  ErrorRange = AtomicBody->getSourceRange();
5985  NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
5986  : AtomicBody->getExprLoc();
5987  NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
5988  : AtomicBody->getSourceRange();
5989  }
5990  } else {
5991  ErrorFound = NotAnExpression;
5992  NoteLoc = ErrorLoc = Body->getLocStart();
5993  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
5994  }
5995  if (ErrorFound != NoError) {
5996  Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
5997  << ErrorRange;
5998  Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
5999  << NoteRange;
6000  return StmtError();
6001  } else if (CurContext->isDependentContext())
6002  V = X = nullptr;
6003  } else if (AtomicKind == OMPC_write) {
6004  enum {
6005  NotAnExpression,
6006  NotAnAssignmentOp,
6007  NotAScalarType,
6008  NotAnLValue,
6009  NoError
6010  } ErrorFound = NoError;
6011  SourceLocation ErrorLoc, NoteLoc;
6012  SourceRange ErrorRange, NoteRange;
6013  // If clause is write:
6014  // x = expr;
6015  if (auto *AtomicBody = dyn_cast<Expr>(Body)) {
6016  auto *AtomicBinOp =
6017  dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
6018  if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
6019  X = AtomicBinOp->getLHS();
6020  E = AtomicBinOp->getRHS();
6021  if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
6022  (E->isInstantiationDependent() || E->getType()->isScalarType())) {
6023  if (!X->isLValue()) {
6024  ErrorFound = NotAnLValue;
6025  ErrorLoc = AtomicBinOp->getExprLoc();
6026  ErrorRange = AtomicBinOp->getSourceRange();
6027  NoteLoc = X->getExprLoc();
6028  NoteRange = X->getSourceRange();
6029  }
6030  } else if (!X->isInstantiationDependent() ||
6031  !E->isInstantiationDependent()) {
6032  auto NotScalarExpr =
6034  ? E
6035  : X;
6036  ErrorFound = NotAScalarType;
6037  ErrorLoc = AtomicBinOp->getExprLoc();
6038  ErrorRange = AtomicBinOp->getSourceRange();
6039  NoteLoc = NotScalarExpr->getExprLoc();
6040  NoteRange = NotScalarExpr->getSourceRange();
6041  }
6042  } else if (!AtomicBody->isInstantiationDependent()) {
6043  ErrorFound = NotAnAssignmentOp;
6044  ErrorLoc = AtomicBody->getExprLoc();
6045  ErrorRange = AtomicBody->getSourceRange();
6046  NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
6047  : AtomicBody->getExprLoc();
6048  NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
6049  : AtomicBody->getSourceRange();
6050  }
6051  } else {
6052  ErrorFound = NotAnExpression;
6053  NoteLoc = ErrorLoc = Body->getLocStart();
6054  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
6055  }
6056  if (ErrorFound != NoError) {
6057  Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
6058  << ErrorRange;
6059  Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
6060  << NoteRange;
6061  return StmtError();
6062  } else if (CurContext->isDependentContext())
6063  E = X = nullptr;
6064  } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
6065  // If clause is update:
6066  // x++;
6067  // x--;
6068  // ++x;
6069  // --x;
6070  // x binop= expr;
6071  // x = x binop expr;
6072  // x = expr binop x;
6073  OpenMPAtomicUpdateChecker Checker(*this);
6074  if (Checker.checkStatement(
6075  Body, (AtomicKind == OMPC_update)
6076  ? diag::err_omp_atomic_update_not_expression_statement
6077  : diag::err_omp_atomic_not_expression_statement,
6078  diag::note_omp_atomic_update))
6079  return StmtError();
6080  if (!CurContext->isDependentContext()) {
6081  E = Checker.getExpr();
6082  X = Checker.getX();
6083  UE = Checker.getUpdateExpr();
6084  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6085  }
6086  } else if (AtomicKind == OMPC_capture) {
6087  enum {
6088  NotAnAssignmentOp,
6089  NotACompoundStatement,
6090  NotTwoSubstatements,
6091  NotASpecificExpression,
6092  NoError
6093  } ErrorFound = NoError;
6094  SourceLocation ErrorLoc, NoteLoc;
6095  SourceRange ErrorRange, NoteRange;
6096  if (auto *AtomicBody = dyn_cast<Expr>(Body)) {
6097  // If clause is a capture:
6098  // v = x++;
6099  // v = x--;
6100  // v = ++x;
6101  // v = --x;
6102  // v = x binop= expr;
6103  // v = x = x binop expr;
6104  // v = x = expr binop x;
6105  auto *AtomicBinOp =
6106  dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
6107  if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
6108  V = AtomicBinOp->getLHS();
6109  Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
6110  OpenMPAtomicUpdateChecker Checker(*this);
6111  if (Checker.checkStatement(
6112  Body, diag::err_omp_atomic_capture_not_expression_statement,
6113  diag::note_omp_atomic_update))
6114  return StmtError();
6115  E = Checker.getExpr();
6116  X = Checker.getX();
6117  UE = Checker.getUpdateExpr();
6118  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6119  IsPostfixUpdate = Checker.isPostfixUpdate();
6120  } else if (!AtomicBody->isInstantiationDependent()) {
6121  ErrorLoc = AtomicBody->getExprLoc();
6122  ErrorRange = AtomicBody->getSourceRange();
6123  NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
6124  : AtomicBody->getExprLoc();
6125  NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
6126  : AtomicBody->getSourceRange();
6127  ErrorFound = NotAnAssignmentOp;
6128  }
6129  if (ErrorFound != NoError) {
6130  Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
6131  << ErrorRange;
6132  Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
6133  return StmtError();
6134  } else if (CurContext->isDependentContext()) {
6135  UE = V = E = X = nullptr;
6136  }
6137  } else {
6138  // If clause is a capture:
6139  // { v = x; x = expr; }
6140  // { v = x; x++; }
6141  // { v = x; x--; }
6142  // { v = x; ++x; }
6143  // { v = x; --x; }
6144  // { v = x; x binop= expr; }
6145  // { v = x; x = x binop expr; }
6146  // { v = x; x = expr binop x; }
6147  // { x++; v = x; }
6148  // { x--; v = x; }
6149  // { ++x; v = x; }
6150  // { --x; v = x; }
6151  // { x binop= expr; v = x; }
6152  // { x = x binop expr; v = x; }
6153  // { x = expr binop x; v = x; }
6154  if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
6155  // Check that this is { expr1; expr2; }
6156  if (CS->size() == 2) {
6157  auto *First = CS->body_front();
6158  auto *Second = CS->body_back();
6159  if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
6160  First = EWC->getSubExpr()->IgnoreParenImpCasts();
6161  if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
6162  Second = EWC->getSubExpr()->IgnoreParenImpCasts();
6163  // Need to find what subexpression is 'v' and what is 'x'.
6164  OpenMPAtomicUpdateChecker Checker(*this);
6165  bool IsUpdateExprFound = !Checker.checkStatement(Second);
6166  BinaryOperator *BinOp = nullptr;
6167  if (IsUpdateExprFound) {
6168  BinOp = dyn_cast<BinaryOperator>(First);
6169  IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
6170  }
6171  if (IsUpdateExprFound && !CurContext->isDependentContext()) {
6172  // { v = x; x++; }
6173  // { v = x; x--; }
6174  // { v = x; ++x; }
6175  // { v = x; --x; }
6176  // { v = x; x binop= expr; }
6177  // { v = x; x = x binop expr; }
6178  // { v = x; x = expr binop x; }
6179  // Check that the first expression has form v = x.
6180  auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
6181  llvm::FoldingSetNodeID XId, PossibleXId;
6182  Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
6183  PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
6184  IsUpdateExprFound = XId == PossibleXId;
6185  if (IsUpdateExprFound) {
6186  V = BinOp->getLHS();
6187  X = Checker.getX();
6188  E = Checker.getExpr();
6189  UE = Checker.getUpdateExpr();
6190  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6191  IsPostfixUpdate = true;
6192  }
6193  }
6194  if (!IsUpdateExprFound) {
6195  IsUpdateExprFound = !Checker.checkStatement(First);
6196  BinOp = nullptr;
6197  if (IsUpdateExprFound) {
6198  BinOp = dyn_cast<BinaryOperator>(Second);
6199  IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
6200  }
6201  if (IsUpdateExprFound && !CurContext->isDependentContext()) {
6202  // { x++; v = x; }
6203  // { x--; v = x; }
6204  // { ++x; v = x; }
6205  // { --x; v = x; }
6206  // { x binop= expr; v = x; }
6207  // { x = x binop expr; v = x; }
6208  // { x = expr binop x; v = x; }
6209  // Check that the second expression has form v = x.
6210  auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
6211  llvm::FoldingSetNodeID XId, PossibleXId;
6212  Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
6213  PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
6214  IsUpdateExprFound = XId == PossibleXId;
6215  if (IsUpdateExprFound) {
6216  V = BinOp->getLHS();
6217  X = Checker.getX();
6218  E = Checker.getExpr();
6219  UE = Checker.getUpdateExpr();
6220  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6221  IsPostfixUpdate = false;
6222  }
6223  }
6224  }
6225  if (!IsUpdateExprFound) {
6226  // { v = x; x = expr; }
6227  auto *FirstExpr = dyn_cast<Expr>(First);
6228  auto *SecondExpr = dyn_cast<Expr>(Second);
6229  if (!FirstExpr || !SecondExpr ||
6230  !(FirstExpr->isInstantiationDependent() ||
6231  SecondExpr->isInstantiationDependent())) {
6232  auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
6233  if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
6234  ErrorFound = NotAnAssignmentOp;
6235  NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
6236  : First->getLocStart();
6237  NoteRange = ErrorRange = FirstBinOp
6238  ? FirstBinOp->getSourceRange()
6239  : SourceRange(ErrorLoc, ErrorLoc);
6240  } else {
6241  auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
6242  if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
6243  ErrorFound = NotAnAssignmentOp;
6244  NoteLoc = ErrorLoc = SecondBinOp
6245  ? SecondBinOp->getOperatorLoc()
6246  : Second->getLocStart();
6247  NoteRange = ErrorRange =
6248  SecondBinOp ? SecondBinOp->getSourceRange()
6249  : SourceRange(ErrorLoc, ErrorLoc);
6250  } else {
6251  auto *PossibleXRHSInFirst =
6252  FirstBinOp->getRHS()->IgnoreParenImpCasts();
6253  auto *PossibleXLHSInSecond =
6254  SecondBinOp->getLHS()->IgnoreParenImpCasts();
6255  llvm::FoldingSetNodeID X1Id, X2Id;
6256  PossibleXRHSInFirst->Profile(X1Id, Context,
6257  /*Canonical=*/true);
6258  PossibleXLHSInSecond->Profile(X2Id, Context,
6259  /*Canonical=*/true);
6260  IsUpdateExprFound = X1Id == X2Id;
6261  if (IsUpdateExprFound) {
6262  V = FirstBinOp->getLHS();
6263  X = SecondBinOp->getLHS();
6264  E = SecondBinOp->getRHS();
6265  UE = nullptr;
6266  IsXLHSInRHSPart = false;
6267  IsPostfixUpdate = true;
6268  } else {
6269  ErrorFound = NotASpecificExpression;
6270  ErrorLoc = FirstBinOp->getExprLoc();
6271  ErrorRange = FirstBinOp->getSourceRange();
6272  NoteLoc = SecondBinOp->getLHS()->getExprLoc();
6273  NoteRange = SecondBinOp->getRHS()->getSourceRange();
6274  }
6275  }
6276  }
6277  }
6278  }
6279  } else {
6280  NoteLoc = ErrorLoc = Body->getLocStart();
6281  NoteRange = ErrorRange =
6282  SourceRange(Body->getLocStart(), Body->getLocStart());
6283  ErrorFound = NotTwoSubstatements;
6284  }
6285  } else {
6286  NoteLoc = ErrorLoc = Body->getLocStart();
6287  NoteRange = ErrorRange =
6288  SourceRange(Body->getLocStart(), Body->getLocStart());
6289  ErrorFound = NotACompoundStatement;
6290  }
6291  if (ErrorFound != NoError) {
6292  Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
6293  << ErrorRange;
6294  Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
6295  return StmtError();
6296  } else if (CurContext->isDependentContext()) {
6297  UE = V = E = X = nullptr;
6298  }
6299  }
6300  }
6301 
6302  getCurFunction()->setHasBranchProtectedScope();
6303 
6304  return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
6305  X, V, E, UE, IsXLHSInRHSPart,
6306  IsPostfixUpdate);
6307 }
6308 
6310  Stmt *AStmt,
6311  SourceLocation StartLoc,
6312  SourceLocation EndLoc) {
6313  if (!AStmt)
6314  return StmtError();
6315 
6316  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6317  // 1.2.2 OpenMP Language Terminology
6318  // Structured block - An executable statement with a single entry at the
6319  // top and a single exit at the bottom.
6320  // The point of exit cannot be a branch out of the structured block.
6321  // longjmp() and throw() must not violate the entry/exit criteria.
6322  CS->getCapturedDecl()->setNothrow();
6323 
6324  // OpenMP [2.16, Nesting of Regions]
6325  // If specified, a teams construct must be contained within a target
6326  // construct. That target construct must contain no statements or directives
6327  // outside of the teams construct.
6328  if (DSAStack->hasInnerTeamsRegion()) {
6329  auto S = AStmt->IgnoreContainers(/*IgnoreCaptured*/ true);
6330  bool OMPTeamsFound = true;
6331  if (auto *CS = dyn_cast<CompoundStmt>(S)) {
6332  auto I = CS->body_begin();
6333  while (I != CS->body_end()) {
6334  auto *OED = dyn_cast<OMPExecutableDirective>(*I);
6335  if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind())) {
6336  OMPTeamsFound = false;
6337  break;
6338  }
6339  ++I;
6340  }
6341  assert(I != CS->body_end() && "Not found statement");
6342  S = *I;
6343  } else {
6344  auto *OED = dyn_cast<OMPExecutableDirective>(S);
6345  OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
6346  }
6347  if (!OMPTeamsFound) {
6348  Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
6349  Diag(DSAStack->getInnerTeamsRegionLoc(),
6350  diag::note_omp_nested_teams_construct_here);
6351  Diag(S->getLocStart(), diag::note_omp_nested_statement_here)
6352  << isa<OMPExecutableDirective>(S);
6353  return StmtError();
6354  }
6355  }
6356 
6357  getCurFunction()->setHasBranchProtectedScope();
6358 
6359  return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
6360 }
6361 
6362 StmtResult
6364  Stmt *AStmt, SourceLocation StartLoc,
6365  SourceLocation EndLoc) {
6366  if (!AStmt)
6367  return StmtError();
6368 
6369  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6370  // 1.2.2 OpenMP Language Terminology
6371  // Structured block - An executable statement with a single entry at the
6372  // top and a single exit at the bottom.
6373  // The point of exit cannot be a branch out of the structured block.
6374  // longjmp() and throw() must not violate the entry/exit criteria.
6375  CS->getCapturedDecl()->setNothrow();
6376 
6377  getCurFunction()->setHasBranchProtectedScope();
6378 
6379  return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses,
6380  AStmt);
6381 }
6382 
6384  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6385  SourceLocation EndLoc,
6386  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6387  if (!AStmt)
6388  return StmtError();
6389 
6390  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6391  // 1.2.2 OpenMP Language Terminology
6392  // Structured block - An executable statement with a single entry at the
6393  // top and a single exit at the bottom.
6394  // The point of exit cannot be a branch out of the structured block.
6395  // longjmp() and throw() must not violate the entry/exit criteria.
6396  CS->getCapturedDecl()->setNothrow();
6397  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
6398  ThisCaptureLevel > 1; --ThisCaptureLevel) {
6399  CS = cast<CapturedStmt>(CS->getCapturedStmt());
6400  // 1.2.2 OpenMP Language Terminology
6401  // Structured block - An executable statement with a single entry at the
6402  // top and a single exit at the bottom.
6403  // The point of exit cannot be a branch out of the structured block.
6404  // longjmp() and throw() must not violate the entry/exit criteria.
6405  CS->getCapturedDecl()->setNothrow();
6406  }
6407 
6409  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6410  // define the nested loops number.
6411  unsigned NestedLoopCount =
6412  CheckOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
6413  getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
6414  VarsWithImplicitDSA, B);
6415  if (NestedLoopCount == 0)
6416  return StmtError();
6417 
6418  assert((CurContext->isDependentContext() || B.builtAll()) &&
6419  "omp target parallel for loop exprs were not built");
6420 
6421  if (!CurContext->isDependentContext()) {
6422  // Finalize the clauses that need pre-built expressions for CodeGen.
6423  for (auto C : Clauses) {
6424  if (auto *LC = dyn_cast<OMPLinearClause>(C))
6425  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
6426  B.NumIterations, *this, CurScope,
6427  DSAStack))
6428  return StmtError();
6429  }
6430  }
6431 
6432  getCurFunction()->setHasBranchProtectedScope();
6433  return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc,
6434  NestedLoopCount, Clauses, AStmt,
6435  B, DSAStack->isCancelRegion());
6436 }
6437 
6438 /// Check for existence of a map clause in the list of clauses.
6439 static bool hasClauses(ArrayRef<OMPClause *> Clauses,
6440  const OpenMPClauseKind K) {
6441  return llvm::any_of(
6442  Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
6443 }
6444 
6445 template <typename... Params>
6447  const Params... ClauseTypes) {
6448  return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
6449 }
6450 
6452  Stmt *AStmt,
6453  SourceLocation StartLoc,
6454  SourceLocation EndLoc) {
6455  if (!AStmt)
6456  return StmtError();
6457 
6458  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6459 
6460  // OpenMP [2.10.1, Restrictions, p. 97]
6461  // At least one map clause must appear on the directive.
6462  if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) {
6463  Diag(StartLoc, diag::err_omp_no_clause_for_directive)
6464  << "'map' or 'use_device_ptr'"
6465  << getOpenMPDirectiveName(OMPD_target_data);
6466  return StmtError();
6467  }
6468 
6469  getCurFunction()->setHasBranchProtectedScope();
6470 
6471  return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
6472  AStmt);
6473 }
6474 
6475 StmtResult
6477  SourceLocation StartLoc,
6478  SourceLocation EndLoc, Stmt *AStmt) {
6479  if (!AStmt)
6480  return StmtError();
6481 
6482  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6483  // 1.2.2 OpenMP Language Terminology
6484  // Structured block - An executable statement with a single entry at the
6485  // top and a single exit at the bottom.
6486  // The point of exit cannot be a branch out of the structured block.
6487  // longjmp() and throw() must not violate the entry/exit criteria.
6488  CS->getCapturedDecl()->setNothrow();
6489  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
6490  ThisCaptureLevel > 1; --ThisCaptureLevel) {
6491  CS = cast<CapturedStmt>(CS->getCapturedStmt());
6492  // 1.2.2 OpenMP Language Terminology
6493  // Structured block - An executable statement with a single entry at the
6494  // top and a single exit at the bottom.
6495  // The point of exit cannot be a branch out of the structured block.
6496  // longjmp() and throw() must not violate the entry/exit criteria.
6497  CS->getCapturedDecl()->setNothrow();
6498  }
6499 
6500  // OpenMP [2.10.2, Restrictions, p. 99]
6501  // At least one map clause must appear on the directive.
6502  if (!hasClauses(Clauses, OMPC_map)) {
6503  Diag(StartLoc, diag::err_omp_no_clause_for_directive)
6504  << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
6505  return StmtError();
6506  }
6507 
6508  return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
6509  AStmt);
6510 }
6511 
6512 StmtResult
6514  SourceLocation StartLoc,
6515  SourceLocation EndLoc, Stmt *AStmt) {
6516  if (!AStmt)
6517  return StmtError();
6518 
6519  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6520  // 1.2.2 OpenMP Language Terminology
6521  // Structured block - An executable statement with a single entry at the
6522  // top and a single exit at the bottom.
6523  // The point of exit cannot be a branch out of the structured block.
6524  // longjmp() and throw() must not violate the entry/exit criteria.
6525  CS->getCapturedDecl()->setNothrow();
6526  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
6527  ThisCaptureLevel > 1; --ThisCaptureLevel) {
6528  CS = cast<CapturedStmt>(CS->getCapturedStmt());
6529  // 1.2.2 OpenMP Language Terminology
6530  // Structured block - An executable statement with a single entry at the
6531  // top and a single exit at the bottom.
6532  // The point of exit cannot be a branch out of the structured block.
6533  // longjmp() and throw() must not violate the entry/exit criteria.
6534  CS->getCapturedDecl()->setNothrow();
6535  }
6536 
6537  // OpenMP [2.10.3, Restrictions, p. 102]
6538  // At least one map clause must appear on the directive.
6539  if (!hasClauses(Clauses, OMPC_map)) {
6540  Diag(StartLoc, diag::err_omp_no_clause_for_directive)
6541  << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
6542  return StmtError();
6543  }
6544 
6545  return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
6546  AStmt);
6547 }
6548 
6550  SourceLocation StartLoc,
6551  SourceLocation EndLoc,
6552  Stmt *AStmt) {
6553  if (!AStmt)
6554  return StmtError();
6555 
6556  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6557  // 1.2.2 OpenMP Language Terminology
6558  // Structured block - An executable statement with a single entry at the
6559  // top and a single exit at the bottom.
6560  // The point of exit cannot be a branch out of the structured block.
6561  // longjmp() and throw() must not violate the entry/exit criteria.
6562  CS->getCapturedDecl()->setNothrow();
6563  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
6564  ThisCaptureLevel > 1; --ThisCaptureLevel) {
6565  CS = cast<CapturedStmt>(CS->getCapturedStmt());
6566  // 1.2.2 OpenMP Language Terminology
6567  // Structured block - An executable statement with a single entry at the
6568  // top and a single exit at the bottom.
6569  // The point of exit cannot be a branch out of the structured block.
6570  // longjmp() and throw() must not violate the entry/exit criteria.
6571  CS->getCapturedDecl()->setNothrow();
6572  }
6573 
6574  if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
6575  Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
6576  return StmtError();
6577  }
6578  return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
6579  AStmt);
6580 }
6581 
6583  Stmt *AStmt, SourceLocation StartLoc,
6584  SourceLocation EndLoc) {
6585  if (!AStmt)
6586  return StmtError();
6587 
6588  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6589  // 1.2.2 OpenMP Language Terminology
6590  // Structured block - An executable statement with a single entry at the
6591  // top and a single exit at the bottom.
6592  // The point of exit cannot be a branch out of the structured block.
6593  // longjmp() and throw() must not violate the entry/exit criteria.
6594  CS->getCapturedDecl()->setNothrow();
6595 
6596  getCurFunction()->setHasBranchProtectedScope();
6597 
6598  DSAStack->setParentTeamsRegionLoc(StartLoc);
6599 
6600  return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
6601 }
6602 
6603 StmtResult
6605  SourceLocation EndLoc,
6606  OpenMPDirectiveKind CancelRegion) {
6607  if (DSAStack->isParentNowaitRegion()) {
6608  Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
6609  return StmtError();
6610  }
6611  if (DSAStack->isParentOrderedRegion()) {
6612  Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
6613  return StmtError();
6614  }
6615  return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
6616  CancelRegion);
6617 }
6618 
6620  SourceLocation StartLoc,
6621  SourceLocation EndLoc,
6622  OpenMPDirectiveKind CancelRegion) {
6623  if (DSAStack->isParentNowaitRegion()) {
6624  Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
6625  return StmtError();
6626  }
6627  if (DSAStack->isParentOrderedRegion()) {
6628  Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
6629  return StmtError();
6630  }
6631  DSAStack->setParentCancelRegion(/*Cancel=*/true);
6632  return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
6633  CancelRegion);
6634 }
6635 
6637  ArrayRef<OMPClause *> Clauses) {
6638  OMPClause *PrevClause = nullptr;
6639  bool ErrorFound = false;
6640  for (auto *C : Clauses) {
6641  if (C->getClauseKind() == OMPC_grainsize ||
6642  C->getClauseKind() == OMPC_num_tasks) {
6643  if (!PrevClause)
6644  PrevClause = C;
6645  else if (PrevClause->getClauseKind() != C->getClauseKind()) {
6646  S.Diag(C->getLocStart(),
6647  diag::err_omp_grainsize_num_tasks_mutually_exclusive)
6648  << getOpenMPClauseName(C->getClauseKind())
6649  << getOpenMPClauseName(PrevClause->getClauseKind());
6650  S.Diag(PrevClause->getLocStart(),
6651  diag::note_omp_previous_grainsize_num_tasks)
6652  << getOpenMPClauseName(PrevClause->getClauseKind());
6653  ErrorFound = true;
6654  }
6655  }
6656  }
6657  return ErrorFound;
6658 }
6659 
6661  ArrayRef<OMPClause *> Clauses) {
6662  OMPClause *ReductionClause = nullptr;
6663  OMPClause *NogroupClause = nullptr;
6664  for (auto *C : Clauses) {
6665  if (C->getClauseKind() == OMPC_reduction) {
6666  ReductionClause = C;
6667  if (NogroupClause)
6668  break;
6669  continue;
6670  }
6671  if (C->getClauseKind() == OMPC_nogroup) {
6672  NogroupClause = C;
6673  if (ReductionClause)
6674  break;
6675  continue;
6676  }
6677  }
6678  if (ReductionClause && NogroupClause) {
6679  S.Diag(ReductionClause->getLocStart(), diag::err_omp_reduction_with_nogroup)
6680  << SourceRange(NogroupClause->getLocStart(),
6681  NogroupClause->getLocEnd());
6682  return true;
6683  }
6684  return false;
6685 }
6686 
6688  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6689  SourceLocation EndLoc,
6690  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6691  if (!AStmt)
6692  return StmtError();
6693 
6694  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6696  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6697  // define the nested loops number.
6698  unsigned NestedLoopCount =
6699  CheckOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
6700  /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
6701  VarsWithImplicitDSA, B);
6702  if (NestedLoopCount == 0)
6703  return StmtError();
6704 
6705  assert((CurContext->isDependentContext() || B.builtAll()) &&
6706  "omp for loop exprs were not built");
6707 
6708  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
6709  // The grainsize clause and num_tasks clause are mutually exclusive and may
6710  // not appear on the same taskloop directive.
6711  if (checkGrainsizeNumTasksClauses(*this, Clauses))
6712  return StmtError();
6713  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
6714  // If a reduction clause is present on the taskloop directive, the nogroup
6715  // clause must not be specified.
6716  if (checkReductionClauseWithNogroup(*this, Clauses))
6717  return StmtError();
6718 
6719  getCurFunction()->setHasBranchProtectedScope();
6720  return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
6721  NestedLoopCount, Clauses, AStmt, B);
6722 }
6723 
6725  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6726  SourceLocation EndLoc,
6727  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6728  if (!AStmt)
6729  return StmtError();
6730 
6731  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6733  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6734  // define the nested loops number.
6735  unsigned NestedLoopCount =
6736  CheckOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
6737  /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
6738  VarsWithImplicitDSA, B);
6739  if (NestedLoopCount == 0)
6740  return StmtError();
6741 
6742  assert((CurContext->isDependentContext() || B.builtAll()) &&
6743  "omp for loop exprs were not built");
6744 
6745  if (!CurContext->isDependentContext()) {
6746  // Finalize the clauses that need pre-built expressions for CodeGen.
6747  for (auto C : Clauses) {
6748  if (auto *LC = dyn_cast<OMPLinearClause>(C))
6749  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
6750  B.NumIterations, *this, CurScope,
6751  DSAStack))
6752  return StmtError();
6753  }
6754  }
6755 
6756  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
6757  // The grainsize clause and num_tasks clause are mutually exclusive and may
6758  // not appear on the same taskloop directive.
6759  if (checkGrainsizeNumTasksClauses(*this, Clauses))
6760  return StmtError();
6761  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
6762  // If a reduction clause is present on the taskloop directive, the nogroup
6763  // clause must not be specified.
6764  if (checkReductionClauseWithNogroup(*this, Clauses))
6765  return StmtError();
6766  if (checkSimdlenSafelenSpecified(*this, Clauses))
6767  return StmtError();
6768 
6769  getCurFunction()->setHasBranchProtectedScope();
6770  return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
6771  NestedLoopCount, Clauses, AStmt, B);
6772 }
6773 
6775  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6776  SourceLocation EndLoc,
6777  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6778  if (!AStmt)
6779  return StmtError();
6780 
6781  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6783  // In presence of clause 'collapse' with number of loops, it will
6784  // define the nested loops number.
6785  unsigned NestedLoopCount =
6786  CheckOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
6787  nullptr /*ordered not a clause on distribute*/, AStmt,
6788  *this, *DSAStack, VarsWithImplicitDSA, B);
6789  if (NestedLoopCount == 0)
6790  return StmtError();
6791 
6792  assert((CurContext->isDependentContext() || B.builtAll()) &&
6793  "omp for loop exprs were not built");
6794 
6795  getCurFunction()->setHasBranchProtectedScope();
6796  return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
6797  NestedLoopCount, Clauses, AStmt, B);
6798 }
6799 
6801  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6802  SourceLocation EndLoc,
6803  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6804  if (!AStmt)
6805  return StmtError();
6806 
6807  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6808  // 1.2.2 OpenMP Language Terminology
6809  // Structured block - An executable statement with a single entry at the
6810  // top and a single exit at the bottom.
6811  // The point of exit cannot be a branch out of the structured block.
6812  // longjmp() and throw() must not violate the entry/exit criteria.
6813  CS->getCapturedDecl()->setNothrow();
6814  for (int ThisCaptureLevel =
6815  getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
6816  ThisCaptureLevel > 1; --ThisCaptureLevel) {
6817  CS = cast<CapturedStmt>(CS->getCapturedStmt());
6818  // 1.2.2 OpenMP Language Terminology
6819  // Structured block - An executable statement with a single entry at the
6820  // top and a single exit at the bottom.
6821  // The point of exit cannot be a branch out of the structured block.
6822  // longjmp() and throw() must not violate the entry/exit criteria.
6823  CS->getCapturedDecl()->setNothrow();
6824  }
6825 
6827  // In presence of clause 'collapse' with number of loops, it will
6828  // define the nested loops number.
6829  unsigned NestedLoopCount = CheckOpenMPLoop(
6830  OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
6831  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
6832  VarsWithImplicitDSA, B);
6833  if (NestedLoopCount == 0)
6834  return StmtError();
6835 
6836  assert((CurContext->isDependentContext() || B.builtAll()) &&
6837  "omp for loop exprs were not built");
6838 
6839  getCurFunction()->setHasBranchProtectedScope();
6841  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
6842  DSAStack->isCancelRegion());
6843 }
6844 
6846  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6847  SourceLocation EndLoc,
6848  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6849  if (!AStmt)
6850  return StmtError();
6851 
6852  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6853  // 1.2.2 OpenMP Language Terminology
6854  // Structured block - An executable statement with a single entry at the
6855  // top and a single exit at the bottom.
6856  // The point of exit cannot be a branch out of the structured block.
6857  // longjmp() and throw() must not violate the entry/exit criteria.
6858  CS->getCapturedDecl()->setNothrow();
6859  for (int ThisCaptureLevel =
6860  getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
6861  ThisCaptureLevel > 1; --ThisCaptureLevel) {
6862  CS = cast<CapturedStmt>(CS->getCapturedStmt());
6863  // 1.2.2 OpenMP Language Terminology
6864  // Structured block - An executable statement with a single entry at the
6865  // top and a single exit at the bottom.
6866  // The point of exit cannot be a branch out of the structured block.
6867  // longjmp() and throw() must not violate the entry/exit criteria.
6868  CS->getCapturedDecl()->setNothrow();
6869  }
6870 
6872  // In presence of clause 'collapse' with number of loops, it will
6873  // define the nested loops number.
6874  unsigned NestedLoopCount = CheckOpenMPLoop(
6875  OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
6876  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
6877  VarsWithImplicitDSA, B);
6878  if (NestedLoopCount == 0)
6879  return StmtError();
6880 
6881  assert((CurContext->isDependentContext() || B.builtAll()) &&
6882  "omp for loop exprs were not built");
6883 
6884  if (!CurContext->isDependentContext()) {
6885  // Finalize the clauses that need pre-built expressions for CodeGen.
6886  for (auto C : Clauses) {
6887  if (auto *LC = dyn_cast<OMPLinearClause>(C))
6888  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
6889  B.NumIterations, *this, CurScope,
6890  DSAStack))
6891  return StmtError();
6892  }
6893  }
6894 
6895  if (checkSimdlenSafelenSpecified(*this, Clauses))
6896  return StmtError();
6897 
6898  getCurFunction()->setHasBranchProtectedScope();
6900  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
6901 }
6902 
6904  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6905  SourceLocation EndLoc,
6906  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6907  if (!AStmt)
6908  return StmtError();
6909 
6910  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6911  // 1.2.2 OpenMP Language Terminology
6912  // Structured block - An executable statement with a single entry at the
6913  // top and a single exit at the bottom.
6914  // The point of exit cannot be a branch out of the structured block.
6915  // longjmp() and throw() must not violate the entry/exit criteria.
6916  CS->getCapturedDecl()->setNothrow();
6917  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
6918  ThisCaptureLevel > 1; --ThisCaptureLevel) {
6919  CS = cast<CapturedStmt>(CS->getCapturedStmt());
6920  // 1.2.2 OpenMP Language Terminology
6921  // Structured block - An executable statement with a single entry at the
6922  // top and a single exit at the bottom.
6923  // The point of exit cannot be a branch out of the structured block.
6924  // longjmp() and throw() must not violate the entry/exit criteria.
6925  CS->getCapturedDecl()->setNothrow();
6926  }
6927 
6929  // In presence of clause 'collapse' with number of loops, it will
6930  // define the nested loops number.
6931  unsigned NestedLoopCount =
6932  CheckOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
6933  nullptr /*ordered not a clause on distribute*/, CS, *this,
6934  *DSAStack, VarsWithImplicitDSA, B);
6935  if (NestedLoopCount == 0)
6936  return StmtError();
6937 
6938  assert((CurContext->isDependentContext() || B.builtAll()) &&
6939  "omp for loop exprs were not built");
6940 
6941  if (!CurContext->isDependentContext()) {
6942  // Finalize the clauses that need pre-built expressions for CodeGen.
6943  for (auto C : Clauses) {
6944  if (auto *LC = dyn_cast<OMPLinearClause>(C))
6945  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
6946  B.NumIterations, *this, CurScope,
6947  DSAStack))
6948  return StmtError();
6949  }
6950  }
6951 
6952  if (checkSimdlenSafelenSpecified(*this, Clauses))
6953  return StmtError();
6954 
6955  getCurFunction()->setHasBranchProtectedScope();
6956  return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
6957  NestedLoopCount, Clauses, AStmt, B);
6958 }
6959 
6961  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6962  SourceLocation EndLoc,
6963  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
6964  if (!AStmt)
6965  return StmtError();
6966 
6967  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
6968  // 1.2.2 OpenMP Language Terminology
6969  // Structured block - An executable statement with a single entry at the
6970  // top and a single exit at the bottom.
6971  // The point of exit cannot be a branch out of the structured block.
6972  // longjmp() and throw() must not violate the entry/exit criteria.
6973  CS->getCapturedDecl()->setNothrow();
6974  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
6975  ThisCaptureLevel > 1; --ThisCaptureLevel) {
6976  CS = cast<CapturedStmt>(CS->getCapturedStmt());
6977  // 1.2.2 OpenMP Language Terminology
6978  // Structured block - An executable statement with a single entry at the
6979  // top and a single exit at the bottom.
6980  // The point of exit cannot be a branch out of the structured block.
6981  // longjmp() and throw() must not violate the entry/exit criteria.
6982  CS->getCapturedDecl()->setNothrow();
6983  }
6984 
6986  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6987  // define the nested loops number.
6988  unsigned NestedLoopCount = CheckOpenMPLoop(
6989  OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
6990  getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
6991  VarsWithImplicitDSA, B);
6992  if (NestedLoopCount == 0)
6993  return StmtError();
6994 
6995  assert((CurContext->isDependentContext() || B.builtAll()) &&
6996  "omp target parallel for simd loop exprs were not built");
6997 
6998  if (!CurContext->isDependentContext()) {
6999  // Finalize the clauses that need pre-built expressions for CodeGen.
7000  for (auto C : Clauses) {
7001  if (auto *LC = dyn_cast<OMPLinearClause>(C))
7002  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7003  B.NumIterations, *this, CurScope,
7004  DSAStack))
7005  return StmtError();
7006  }
7007  }
7008  if (checkSimdlenSafelenSpecified(*this, Clauses))
7009  return StmtError();
7010 
7011  getCurFunction()->setHasBranchProtectedScope();
7013  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7014 }
7015 
7017  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7018  SourceLocation EndLoc,
7019  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7020  if (!AStmt)
7021  return StmtError();
7022 
7023  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7024  // 1.2.2 OpenMP Language Terminology
7025  // Structured block - An executable statement with a single entry at the
7026  // top and a single exit at the bottom.
7027  // The point of exit cannot be a branch out of the structured block.
7028  // longjmp() and throw() must not violate the entry/exit criteria.
7029  CS->getCapturedDecl()->setNothrow();
7030  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
7031  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7032  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7033  // 1.2.2 OpenMP Language Terminology
7034  // Structured block - An executable statement with a single entry at the
7035  // top and a single exit at the bottom.
7036  // The point of exit cannot be a branch out of the structured block.
7037  // longjmp() and throw() must not violate the entry/exit criteria.
7038  CS->getCapturedDecl()->setNothrow();
7039  }
7040 
7042  // In presence of clause 'collapse' with number of loops, it will define the
7043  // nested loops number.
7044  unsigned NestedLoopCount =
7045  CheckOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
7046  getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
7047  VarsWithImplicitDSA, B);
7048  if (NestedLoopCount == 0)
7049  return StmtError();
7050 
7051  assert((CurContext->isDependentContext() || B.builtAll()) &&
7052  "omp target simd loop exprs were not built");
7053 
7054  if (!CurContext->isDependentContext()) {
7055  // Finalize the clauses that need pre-built expressions for CodeGen.
7056  for (auto C : Clauses) {
7057  if (auto *LC = dyn_cast<OMPLinearClause>(C))
7058  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7059  B.NumIterations, *this, CurScope,
7060  DSAStack))
7061  return StmtError();
7062  }
7063  }
7064 
7065  if (checkSimdlenSafelenSpecified(*this, Clauses))
7066  return StmtError();
7067 
7068  getCurFunction()->setHasBranchProtectedScope();
7069  return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
7070  NestedLoopCount, Clauses, AStmt, B);
7071 }
7072 
7074  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7075  SourceLocation EndLoc,
7076  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7077  if (!AStmt)
7078  return StmtError();
7079 
7080  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7081  // 1.2.2 OpenMP Language Terminology
7082  // Structured block - An executable statement with a single entry at the
7083  // top and a single exit at the bottom.
7084  // The point of exit cannot be a branch out of the structured block.
7085  // longjmp() and throw() must not violate the entry/exit criteria.
7086  CS->getCapturedDecl()->setNothrow();
7087  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
7088  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7089  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7090  // 1.2.2 OpenMP Language Terminology
7091  // Structured block - An executable statement with a single entry at the
7092  // top and a single exit at the bottom.
7093  // The point of exit cannot be a branch out of the structured block.
7094  // longjmp() and throw() must not violate the entry/exit criteria.
7095  CS->getCapturedDecl()->setNothrow();
7096  }
7097 
7099  // In presence of clause 'collapse' with number of loops, it will
7100  // define the nested loops number.
7101  unsigned NestedLoopCount =
7102  CheckOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
7103  nullptr /*ordered not a clause on distribute*/, CS, *this,
7104  *DSAStack, VarsWithImplicitDSA, B);
7105  if (NestedLoopCount == 0)
7106  return StmtError();
7107 
7108  assert((CurContext->isDependentContext() || B.builtAll()) &&
7109  "omp teams distribute loop exprs were not built");
7110 
7111  getCurFunction()->setHasBranchProtectedScope();
7112 
7113  DSAStack->setParentTeamsRegionLoc(StartLoc);
7114 
7116  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7117 }
7118 
7120  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7121  SourceLocation EndLoc,
7122  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7123  if (!AStmt)
7124  return StmtError();
7125 
7126  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7127  // 1.2.2 OpenMP Language Terminology
7128  // Structured block - An executable statement with a single entry at the
7129  // top and a single exit at the bottom.
7130  // The point of exit cannot be a branch out of the structured block.
7131  // longjmp() and throw() must not violate the entry/exit criteria.
7132  CS->getCapturedDecl()->setNothrow();
7133  for (int ThisCaptureLevel =
7134  getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
7135  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7136  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7137  // 1.2.2 OpenMP Language Terminology
7138  // Structured block - An executable statement with a single entry at the
7139  // top and a single exit at the bottom.
7140  // The point of exit cannot be a branch out of the structured block.
7141  // longjmp() and throw() must not violate the entry/exit criteria.
7142  CS->getCapturedDecl()->setNothrow();
7143  }
7144 
7145 
7147  // In presence of clause 'collapse' with number of loops, it will
7148  // define the nested loops number.
7149  unsigned NestedLoopCount = CheckOpenMPLoop(
7150  OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
7151  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7152  VarsWithImplicitDSA, B);
7153 
7154  if (NestedLoopCount == 0)
7155  return StmtError();
7156 
7157  assert((CurContext->isDependentContext() || B.builtAll()) &&
7158  "omp teams distribute simd loop exprs were not built");
7159 
7160  if (!CurContext->isDependentContext()) {
7161  // Finalize the clauses that need pre-built expressions for CodeGen.
7162  for (auto C : Clauses) {
7163  if (auto *LC = dyn_cast<OMPLinearClause>(C))
7164  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7165  B.NumIterations, *this, CurScope,
7166  DSAStack))
7167  return StmtError();
7168  }
7169  }
7170 
7171  if (checkSimdlenSafelenSpecified(*this, Clauses))
7172  return StmtError();
7173 
7174  getCurFunction()->setHasBranchProtectedScope();
7175 
7176  DSAStack->setParentTeamsRegionLoc(StartLoc);
7177 
7179  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7180 }
7181 
7183  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7184  SourceLocation EndLoc,
7185  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7186  if (!AStmt)
7187  return StmtError();
7188 
7189  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7190  // 1.2.2 OpenMP Language Terminology
7191  // Structured block - An executable statement with a single entry at the
7192  // top and a single exit at the bottom.
7193  // The point of exit cannot be a branch out of the structured block.
7194  // longjmp() and throw() must not violate the entry/exit criteria.
7195  CS->getCapturedDecl()->setNothrow();
7196 
7197  for (int ThisCaptureLevel =
7198  getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
7199  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7200  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7201  // 1.2.2 OpenMP Language Terminology
7202  // Structured block - An executable statement with a single entry at the
7203  // top and a single exit at the bottom.
7204  // The point of exit cannot be a branch out of the structured block.
7205  // longjmp() and throw() must not violate the entry/exit criteria.
7206  CS->getCapturedDecl()->setNothrow();
7207  }
7208 
7210  // In presence of clause 'collapse' with number of loops, it will
7211  // define the nested loops number.
7212  auto NestedLoopCount = CheckOpenMPLoop(
7213  OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
7214  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7215  VarsWithImplicitDSA, B);
7216 
7217  if (NestedLoopCount == 0)
7218  return StmtError();
7219 
7220  assert((CurContext->isDependentContext() || B.builtAll()) &&
7221  "omp for loop exprs were not built");
7222 
7223  if (!CurContext->isDependentContext()) {
7224  // Finalize the clauses that need pre-built expressions for CodeGen.
7225  for (auto C : Clauses) {
7226  if (auto *LC = dyn_cast<OMPLinearClause>(C))
7227  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7228  B.NumIterations, *this, CurScope,
7229  DSAStack))
7230  return StmtError();
7231  }
7232  }
7233 
7234  if (checkSimdlenSafelenSpecified(*this, Clauses))
7235  return StmtError();
7236 
7237  getCurFunction()->setHasBranchProtectedScope();
7238 
7239  DSAStack->setParentTeamsRegionLoc(StartLoc);
7240 
7242  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7243 }
7244 
7246  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7247  SourceLocation EndLoc,
7248  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7249  if (!AStmt)
7250  return StmtError();
7251 
7252  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7253  // 1.2.2 OpenMP Language Terminology
7254  // Structured block - An executable statement with a single entry at the
7255  // top and a single exit at the bottom.
7256  // The point of exit cannot be a branch out of the structured block.
7257  // longjmp() and throw() must not violate the entry/exit criteria.
7258  CS->getCapturedDecl()->setNothrow();
7259 
7260  for (int ThisCaptureLevel =
7261  getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
7262  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7263  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7264  // 1.2.2 OpenMP Language Terminology
7265  // Structured block - An executable statement with a single entry at the
7266  // top and a single exit at the bottom.
7267  // The point of exit cannot be a branch out of the structured block.
7268  // longjmp() and throw() must not violate the entry/exit criteria.
7269  CS->getCapturedDecl()->setNothrow();
7270  }
7271 
7273  // In presence of clause 'collapse' with number of loops, it will
7274  // define the nested loops number.
7275  unsigned NestedLoopCount = CheckOpenMPLoop(
7276  OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
7277  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7278  VarsWithImplicitDSA, B);
7279 
7280  if (NestedLoopCount == 0)
7281  return StmtError();
7282 
7283  assert((CurContext->isDependentContext() || B.builtAll()) &&
7284  "omp for loop exprs were not built");
7285 
7286  getCurFunction()->setHasBranchProtectedScope();
7287 
7288  DSAStack->setParentTeamsRegionLoc(StartLoc);
7289 
7291  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
7292  DSAStack->isCancelRegion());
7293 }
7294 
7296  Stmt *AStmt,
7297  SourceLocation StartLoc,
7298  SourceLocation EndLoc) {
7299  if (!AStmt)
7300  return StmtError();
7301 
7302  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7303  // 1.2.2 OpenMP Language Terminology
7304  // Structured block - An executable statement with a single entry at the
7305  // top and a single exit at the bottom.
7306  // The point of exit cannot be a branch out of the structured block.
7307  // longjmp() and throw() must not violate the entry/exit criteria.
7308  CS->getCapturedDecl()->setNothrow();
7309 
7310  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
7311  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7312  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7313  // 1.2.2 OpenMP Language Terminology
7314  // Structured block - An executable statement with a single entry at the
7315  // top and a single exit at the bottom.
7316  // The point of exit cannot be a branch out of the structured block.
7317  // longjmp() and throw() must not violate the entry/exit criteria.
7318  CS->getCapturedDecl()->setNothrow();
7319  }
7320  getCurFunction()->setHasBranchProtectedScope();
7321 
7322  return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
7323  AStmt);
7324 }
7325 
7327  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7328  SourceLocation EndLoc,
7329  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7330  if (!AStmt)
7331  return StmtError();
7332 
7333  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7334  // 1.2.2 OpenMP Language Terminology
7335  // Structured block - An executable statement with a single entry at the
7336  // top and a single exit at the bottom.
7337  // The point of exit cannot be a branch out of the structured block.
7338  // longjmp() and throw() must not violate the entry/exit criteria.
7339  CS->getCapturedDecl()->setNothrow();
7340  for (int ThisCaptureLevel =
7341  getOpenMPCaptureLevels(OMPD_target_teams_distribute);
7342  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7343  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7344  // 1.2.2 OpenMP Language Terminology
7345  // Structured block - An executable statement with a single entry at the
7346  // top and a single exit at the bottom.
7347  // The point of exit cannot be a branch out of the structured block.
7348  // longjmp() and throw() must not violate the entry/exit criteria.
7349  CS->getCapturedDecl()->setNothrow();
7350  }
7351 
7353  // In presence of clause 'collapse' with number of loops, it will
7354  // define the nested loops number.
7355  auto NestedLoopCount = CheckOpenMPLoop(
7356  OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
7357  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7358  VarsWithImplicitDSA, B);
7359  if (NestedLoopCount == 0)
7360  return StmtError();
7361 
7362  assert((CurContext->isDependentContext() || B.builtAll()) &&
7363  "omp target teams distribute loop exprs were not built");
7364 
7365  getCurFunction()->setHasBranchProtectedScope();
7367  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7368 }
7369 
7371  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7372  SourceLocation EndLoc,
7373  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7374  if (!AStmt)
7375  return StmtError();
7376 
7377  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7378  // 1.2.2 OpenMP Language Terminology
7379  // Structured block - An executable statement with a single entry at the
7380  // top and a single exit at the bottom.
7381  // The point of exit cannot be a branch out of the structured block.
7382  // longjmp() and throw() must not violate the entry/exit criteria.
7383  CS->getCapturedDecl()->setNothrow();
7384 
7386  // In presence of clause 'collapse' with number of loops, it will
7387  // define the nested loops number.
7388  auto NestedLoopCount = CheckOpenMPLoop(
7389  OMPD_target_teams_distribute_parallel_for,
7390  getCollapseNumberExpr(Clauses),
7391  nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack,
7392  VarsWithImplicitDSA, B);
7393  if (NestedLoopCount == 0)
7394  return StmtError();
7395 
7396  assert((CurContext->isDependentContext() || B.builtAll()) &&
7397  "omp target teams distribute parallel for loop exprs were not built");
7398 
7399  getCurFunction()->setHasBranchProtectedScope();
7401  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
7402  DSAStack->isCancelRegion());
7403 }
7404 
7406  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7407  SourceLocation EndLoc,
7408  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7409  if (!AStmt)
7410  return StmtError();
7411 
7412  CapturedStmt *CS = cast<CapturedStmt>(AStmt);
7413  // 1.2.2 OpenMP Language Terminology
7414  // Structured block - An executable statement with a single entry at the
7415  // top and a single exit at the bottom.
7416  // The point of exit cannot be a branch out of the structured block.
7417  // longjmp() and throw() must not violate the entry/exit criteria.
7418  CS->getCapturedDecl()->setNothrow();
7419 
7421  // In presence of clause 'collapse' with number of loops, it will
7422  // define the nested loops number.
7423  auto NestedLoopCount = CheckOpenMPLoop(
7424  OMPD_target_teams_distribute_parallel_for_simd,
7425  getCollapseNumberExpr(Clauses),
7426  nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack,
7427  VarsWithImplicitDSA, B);
7428  if (NestedLoopCount == 0)
7429  return StmtError();
7430 
7431  assert((CurContext->isDependentContext() || B.builtAll()) &&
7432  "omp target teams distribute parallel for simd loop exprs were not "
7433  "built");
7434 
7435  if (!CurContext->isDependentContext()) {
7436  // Finalize the clauses that need pre-built expressions for CodeGen.
7437  for (auto C : Clauses) {
7438  if (auto *LC = dyn_cast<OMPLinearClause>(C))
7439  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7440  B.NumIterations, *this, CurScope,
7441  DSAStack))
7442  return StmtError();
7443  }
7444  }
7445 
7446  if (checkSimdlenSafelenSpecified(*this, Clauses))
7447  return StmtError();
7448 
7449  getCurFunction()->setHasBranchProtectedScope();
7451  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7452 }
7453 
7455  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7456  SourceLocation EndLoc,
7457  llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) {
7458  if (!AStmt)
7459  return StmtError();
7460 
7461  auto *CS = cast<CapturedStmt>(AStmt);
7462  // 1.2.2 OpenMP Language Terminology
7463  // Structured block - An executable statement with a single entry at the
7464  // top and a single exit at the bottom.
7465  // The point of exit cannot be a branch out of the structured block.
7466  // longjmp() and throw() must not violate the entry/exit criteria.
7467  CS->getCapturedDecl()->setNothrow();
7468  for (int ThisCaptureLevel =
7469  getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
7470  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7471  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7472  // 1.2.2 OpenMP Language Terminology
7473  // Structured block - An executable statement with a single entry at the
7474  // top and a single exit at the bottom.
7475  // The point of exit cannot be a branch out of the structured block.
7476  // longjmp() and throw() must not violate the entry/exit criteria.
7477  CS->getCapturedDecl()->setNothrow();
7478  }
7479 
7481  // In presence of clause 'collapse' with number of loops, it will
7482  // define the nested loops number.
7483  auto NestedLoopCount = CheckOpenMPLoop(
7484  OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
7485  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7486  VarsWithImplicitDSA, B);
7487  if (NestedLoopCount == 0)
7488  return StmtError();
7489 
7490  assert((CurContext->isDependentContext() || B.builtAll()) &&
7491  "omp target teams distribute simd loop exprs were not built");
7492 
7493  if (!CurContext->isDependentContext()) {
7494  // Finalize the clauses that need pre-built expressions for CodeGen.
7495  for (auto C : Clauses) {
7496  if (auto *LC = dyn_cast<OMPLinearClause>(C))
7497  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7498  B.NumIterations, *this, CurScope,
7499  DSAStack))
7500  return StmtError();
7501  }
7502  }
7503 
7504  if (checkSimdlenSafelenSpecified(*this, Clauses))
7505  return StmtError();
7506 
7507  getCurFunction()->setHasBranchProtectedScope();
7509  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7510 }
7511 
7513  SourceLocation StartLoc,
7514  SourceLocation LParenLoc,
7515  SourceLocation EndLoc) {
7516  OMPClause *Res = nullptr;
7517  switch (Kind) {
7518  case OMPC_final:
7519  Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
7520  break;
7521  case OMPC_num_threads:
7522  Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
7523  break;
7524  case OMPC_safelen:
7525  Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
7526  break;
7527  case OMPC_simdlen:
7528  Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
7529  break;
7530  case OMPC_collapse:
7531  Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
7532  break;
7533  case OMPC_ordered:
7534  Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
7535  break;
7536  case OMPC_device:
7537  Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc);
7538  break;
7539  case OMPC_num_teams:
7540  Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
7541  break;
7542  case OMPC_thread_limit:
7543  Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
7544  break;
7545  case OMPC_priority:
7546  Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
7547  break;
7548  case OMPC_grainsize:
7549  Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
7550  break;
7551  case OMPC_num_tasks:
7552  Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
7553  break;
7554  case OMPC_hint:
7555  Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
7556  break;
7557  case OMPC_if:
7558  case OMPC_default:
7559  case OMPC_proc_bind:
7560  case OMPC_schedule:
7561  case OMPC_private:
7562  case OMPC_firstprivate:
7563  case OMPC_lastprivate:
7564  case OMPC_shared:
7565  case OMPC_reduction:
7566  case OMPC_task_reduction:
7567  case OMPC_in_reduction:
7568  case OMPC_linear:
7569  case OMPC_aligned:
7570  case OMPC_copyin:
7571  case OMPC_copyprivate:
7572  case OMPC_nowait:
7573  case OMPC_untied:
7574  case OMPC_mergeable:
7575  case OMPC_threadprivate:
7576  case OMPC_flush:
7577  case OMPC_read:
7578  case OMPC_write:
7579  case OMPC_update:
7580  case OMPC_capture:
7581  case OMPC_seq_cst:
7582  case OMPC_depend:
7583  case OMPC_threads:
7584  case OMPC_simd:
7585  case OMPC_map:
7586  case OMPC_nogroup:
7587  case OMPC_dist_schedule:
7588  case OMPC_defaultmap:
7589  case OMPC_unknown:
7590  case OMPC_uniform:
7591  case OMPC_to:
7592  case OMPC_from:
7593  case OMPC_use_device_ptr:
7594  case OMPC_is_device_ptr:
7595  llvm_unreachable("Clause is not allowed.");
7596  }
7597  return Res;
7598 }
7599 
7600 // An OpenMP directive such as 'target parallel' has two captured regions:
7601 // for the 'target' and 'parallel' respectively. This function returns
7602 // the region in which to capture expressions associated with a clause.
7603 // A return value of OMPD_unknown signifies that the expression should not
7604 // be captured.
7607  OpenMPDirectiveKind NameModifier = OMPD_unknown) {
7608  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
7609  switch (CKind) {
7610  case OMPC_if:
7611  switch (DKind) {
7612  case OMPD_target_parallel:
7613  case OMPD_target_parallel_for:
7614  case OMPD_target_parallel_for_simd:
7615  case OMPD_target_teams_distribute_parallel_for:
7616  case OMPD_target_teams_distribute_parallel_for_simd:
7617  // If this clause applies to the nested 'parallel' region, capture within
7618  // the 'target' region, otherwise do not capture.
7619  if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
7620  CaptureRegion = OMPD_target;
7621  break;
7622  case OMPD_teams_distribute_parallel_for:
7623  case OMPD_teams_distribute_parallel_for_simd:
7624  CaptureRegion = OMPD_teams;
7625  break;
7626  case OMPD_target_update:
7627  case OMPD_target_enter_data:
7628  case OMPD_target_exit_data:
7629  CaptureRegion = OMPD_task;
7630  break;
7631  case OMPD_cancel:
7632  case OMPD_parallel:
7633  case OMPD_parallel_sections:
7634  case OMPD_parallel_for:
7635  case OMPD_parallel_for_simd:
7636  case OMPD_target:
7637  case OMPD_target_simd:
7638  case OMPD_target_teams:
7639  case OMPD_target_teams_distribute:
7640  case OMPD_target_teams_distribute_simd:
7641  case OMPD_distribute_parallel_for:
7642  case OMPD_distribute_parallel_for_simd:
7643  case OMPD_task:
7644  case OMPD_taskloop:
7645  case OMPD_taskloop_simd:
7646  case OMPD_target_data:
7647  // Do not capture if-clause expressions.
7648  break;
7649  case OMPD_threadprivate:
7650  case OMPD_taskyield:
7651  case OMPD_barrier:
7652  case OMPD_taskwait:
7653  case OMPD_cancellation_point:
7654  case OMPD_flush:
7655  case OMPD_declare_reduction:
7656  case OMPD_declare_simd:
7657  case OMPD_declare_target:
7658  case OMPD_end_declare_target:
7659  case OMPD_teams:
7660  case OMPD_simd:
7661  case OMPD_for:
7662  case OMPD_for_simd:
7663  case OMPD_sections:
7664  case OMPD_section:
7665  case OMPD_single:
7666  case OMPD_master:
7667  case OMPD_critical:
7668  case OMPD_taskgroup:
7669  case OMPD_distribute:
7670  case OMPD_ordered:
7671  case OMPD_atomic:
7672  case OMPD_distribute_simd:
7673  case OMPD_teams_distribute:
7674  case OMPD_teams_distribute_simd:
7675  llvm_unreachable("Unexpected OpenMP directive with if-clause");
7676  case OMPD_unknown:
7677  llvm_unreachable("Unknown OpenMP directive");
7678  }
7679  break;
7680  case OMPC_num_threads:
7681  switch (DKind) {
7682  case OMPD_target_parallel:
7683  case OMPD_target_parallel_for:
7684  case OMPD_target_parallel_for_simd:
7685  case OMPD_target_teams_distribute_parallel_for:
7686  case OMPD_target_teams_distribute_parallel_for_simd:
7687  CaptureRegion = OMPD_target;
7688  break;
7689  case OMPD_teams_distribute_parallel_for:
7690  case OMPD_teams_distribute_parallel_for_simd:
7691  CaptureRegion = OMPD_teams;
7692  break;
7693  case OMPD_parallel:
7694  case OMPD_parallel_sections:
7695  case OMPD_parallel_for:
7696  case OMPD_parallel_for_simd:
7697  case OMPD_distribute_parallel_for:
7698  case OMPD_distribute_parallel_for_simd:
7699  // Do not capture num_threads-clause expressions.
7700  break;
7701  case OMPD_target_data:
7702  case OMPD_target_enter_data:
7703  case OMPD_target_exit_data:
7704  case OMPD_target_update:
7705  case OMPD_target:
7706  case OMPD_target_simd:
7707  case OMPD_target_teams:
7708  case OMPD_target_teams_distribute:
7709  case OMPD_target_teams_distribute_simd:
7710  case OMPD_cancel:
7711  case OMPD_task:
7712  case OMPD_taskloop:
7713  case OMPD_taskloop_simd:
7714  case OMPD_threadprivate:
7715  case OMPD_taskyield:
7716  case OMPD_barrier:
7717  case OMPD_taskwait:
7718  case OMPD_cancellation_point:
7719  case OMPD_flush:
7720  case OMPD_declare_reduction:
7721  case OMPD_declare_simd:
7722  case OMPD_declare_target:
7723  case OMPD_end_declare_target:
7724  case OMPD_teams:
7725  case OMPD_simd:
7726  case OMPD_for:
7727  case OMPD_for_simd:
7728  case OMPD_sections:
7729  case OMPD_section:
7730  case OMPD_single:
7731  case OMPD_master:
7732  case OMPD_critical:
7733  case OMPD_taskgroup:
7734  case OMPD_distribute:
7735  case OMPD_ordered:
7736  case OMPD_atomic:
7737  case OMPD_distribute_simd:
7738  case OMPD_teams_distribute:
7739  case OMPD_teams_distribute_simd:
7740  llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
7741  case OMPD_unknown:
7742  llvm_unreachable("Unknown OpenMP directive");
7743  }
7744  break;
7745  case OMPC_num_teams:
7746  switch (DKind) {
7747  case OMPD_target_teams:
7748  case OMPD_target_teams_distribute:
7749  case OMPD_target_teams_distribute_simd:
7750  case OMPD_target_teams_distribute_parallel_for:
7751  case OMPD_target_teams_distribute_parallel_for_simd:
7752  CaptureRegion = OMPD_target;
7753  break;
7754  case OMPD_teams_distribute_parallel_for:
7755  case OMPD_teams_distribute_parallel_for_simd:
7756  case OMPD_teams:
7757  case OMPD_teams_distribute:
7758  case OMPD_teams_distribute_simd:
7759  // Do not capture num_teams-clause expressions.
7760  break;
7761  case OMPD_distribute_parallel_for:
7762  case OMPD_distribute_parallel_for_simd:
7763  case OMPD_task:
7764  case OMPD_taskloop:
7765  case OMPD_taskloop_simd:
7766  case OMPD_target_data:
7767  case OMPD_target_enter_data:
7768  case OMPD_target_exit_data:
7769  case OMPD_target_update:
7770  case OMPD_cancel:
7771  case OMPD_parallel:
7772  case OMPD_parallel_sections:
7773  case OMPD_parallel_for:
7774  case OMPD_parallel_for_simd:
7775  case OMPD_target:
7776  case OMPD_target_simd:
7777  case OMPD_target_parallel:
7778  case OMPD_target_parallel_for:
7779  case OMPD_target_parallel_for_simd:
7780  case OMPD_threadprivate:
7781  case OMPD_taskyield:
7782  case OMPD_barrier:
7783  case OMPD_taskwait:
7784  case OMPD_cancellation_point:
7785  case OMPD_flush:
7786  case OMPD_declare_reduction:
7787  case OMPD_declare_simd:
7788  case OMPD_declare_target:
7789  case OMPD_end_declare_target:
7790  case OMPD_simd:
7791  case OMPD_for:
7792  case OMPD_for_simd:
7793  case OMPD_sections:
7794  case OMPD_section:
7795  case OMPD_single:
7796  case OMPD_master:
7797  case OMPD_critical:
7798  case OMPD_taskgroup:
7799  case OMPD_distribute:
7800  case OMPD_ordered:
7801  case OMPD_atomic:
7802  case OMPD_distribute_simd:
7803  llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
7804  case OMPD_unknown:
7805  llvm_unreachable("Unknown OpenMP directive");
7806  }
7807  break;
7808  case OMPC_thread_limit:
7809  switch (DKind) {
7810  case OMPD_target_teams:
7811  case OMPD_target_teams_distribute:
7812  case OMPD_target_teams_distribute_simd:
7813  case OMPD_target_teams_distribute_parallel_for:
7814  case OMPD_target_teams_distribute_parallel_for_simd:
7815  CaptureRegion = OMPD_target;
7816  break;
7817  case OMPD_teams_distribute_parallel_for:
7818  case OMPD_teams_distribute_parallel_for_simd:
7819  case OMPD_teams:
7820  case OMPD_teams_distribute:
7821  case OMPD_teams_distribute_simd:
7822  // Do not capture thread_limit-clause expressions.
7823  break;
7824  case OMPD_distribute_parallel_for:
7825  case OMPD_distribute_parallel_for_simd:
7826  case OMPD_task:
7827  case OMPD_taskloop:
7828  case OMPD_taskloop_simd:
7829  case OMPD_target_data:
7830  case OMPD_target_enter_data:
7831  case OMPD_target_exit_data:
7832  case OMPD_target_update:
7833  case OMPD_cancel:
7834  case OMPD_parallel:
7835  case OMPD_parallel_sections:
7836  case OMPD_parallel_for:
7837  case OMPD_parallel_for_simd:
7838  case OMPD_target:
7839  case OMPD_target_simd:
7840  case OMPD_target_parallel:
7841  case OMPD_target_parallel_for:
7842  case OMPD_target_parallel_for_simd:
7843  case OMPD_threadprivate:
7844  case OMPD_taskyield:
7845  case OMPD_barrier:
7846  case OMPD_taskwait:
7847  case OMPD_cancellation_point:
7848  case OMPD_flush:
7849  case OMPD_declare_reduction:
7850  case OMPD_declare_simd:
7851  case OMPD_declare_target:
7852  case OMPD_end_declare_target:
7853  case OMPD_simd:
7854  case OMPD_for:
7855  case OMPD_for_simd:
7856  case OMPD_sections:
7857  case OMPD_section:
7858  case OMPD_single:
7859  case OMPD_master:
7860  case OMPD_critical:
7861  case OMPD_taskgroup:
7862  case OMPD_distribute:
7863  case OMPD_ordered:
7864  case OMPD_atomic:
7865  case OMPD_distribute_simd:
7866  llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
7867  case OMPD_unknown:
7868  llvm_unreachable("Unknown OpenMP directive");
7869  }
7870  break;
7871  case OMPC_schedule:
7872  switch (DKind) {
7873  case OMPD_target_parallel_for:
7874  case OMPD_target_parallel_for_simd:
7875  case OMPD_target_teams_distribute_parallel_for:
7876  case OMPD_target_teams_distribute_parallel_for_simd:
7877  CaptureRegion = OMPD_target;
7878  break;
7879  case OMPD_teams_distribute_parallel_for:
7880  case OMPD_teams_distribute_parallel_for_simd:
7881  CaptureRegion = OMPD_teams;
7882  break;
7883  case OMPD_parallel_for:
7884  case OMPD_parallel_for_simd:
7885  case OMPD_distribute_parallel_for:
7886  case OMPD_distribute_parallel_for_simd:
7887  CaptureRegion = OMPD_parallel;
7888  break;
7889  case OMPD_for:
7890  case OMPD_for_simd:
7891  // Do not capture schedule-clause expressions.
7892  break;
7893  case OMPD_task:
7894  case OMPD_taskloop:
7895  case OMPD_taskloop_simd:
7896  case OMPD_target_data:
7897  case OMPD_target_enter_data:
7898  case OMPD_target_exit_data:
7899  case OMPD_target_update:
7900  case OMPD_teams:
7901  case OMPD_teams_distribute:
7902  case OMPD_teams_distribute_simd:
7903  case OMPD_target_teams_distribute:
7904  case OMPD_target_teams_distribute_simd:
7905  case OMPD_target:
7906  case OMPD_target_simd:
7907  case OMPD_target_parallel:
7908  case OMPD_cancel:
7909  case OMPD_parallel:
7910  case OMPD_parallel_sections:
7911  case OMPD_threadprivate:
7912  case OMPD_taskyield:
7913  case OMPD_barrier:
7914  case OMPD_taskwait:
7915  case OMPD_cancellation_point:
7916  case OMPD_flush:
7917  case OMPD_declare_reduction:
7918  case OMPD_declare_simd:
7919  case OMPD_declare_target:
7920  case OMPD_end_declare_target:
7921  case OMPD_simd:
7922  case OMPD_sections:
7923  case OMPD_section:
7924  case OMPD_single:
7925  case OMPD_master:
7926  case OMPD_critical:
7927  case OMPD_taskgroup:
7928  case OMPD_distribute:
7929  case OMPD_ordered:
7930  case OMPD_atomic:
7931  case OMPD_distribute_simd:
7932  case OMPD_target_teams:
7933  llvm_unreachable("Unexpected OpenMP directive with schedule clause");
7934  case OMPD_unknown:
7935  llvm_unreachable("Unknown OpenMP directive");
7936  }
7937  break;
7938  case OMPC_dist_schedule:
7939  switch (DKind) {
7940  case OMPD_teams_distribute_parallel_for:
7941  case OMPD_teams_distribute_parallel_for_simd:
7942  case OMPD_teams_distribute:
7943  case OMPD_teams_distribute_simd:
7944  CaptureRegion = OMPD_teams;
7945  break;
7946  case OMPD_target_teams_distribute_parallel_for:
7947  case OMPD_target_teams_distribute_parallel_for_simd:
7948  case OMPD_target_teams_distribute:
7949  case OMPD_target_teams_distribute_simd:
7950  CaptureRegion = OMPD_target;
7951  break;
7952  case OMPD_distribute_parallel_for:
7953  case OMPD_distribute_parallel_for_simd:
7954  CaptureRegion = OMPD_parallel;
7955  break;
7956  case OMPD_distribute:
7957  case OMPD_distribute_simd:
7958  // Do not capture thread_limit-clause expressions.
7959  break;
7960  case OMPD_parallel_for:
7961  case OMPD_parallel_for_simd:
7962  case OMPD_target_parallel_for_simd:
7963  case OMPD_target_parallel_for:
7964  case OMPD_task:
7965  case OMPD_taskloop:
7966  case OMPD_taskloop_simd:
7967  case OMPD_target_data:
7968  case OMPD_target_enter_data:
7969  case OMPD_target_exit_data:
7970  case OMPD_target_update:
7971  case OMPD_teams:
7972  case OMPD_target:
7973  case OMPD_target_simd:
7974  case OMPD_target_parallel:
7975  case OMPD_cancel:
7976  case OMPD_parallel:
7977  case OMPD_parallel_sections:
7978  case OMPD_threadprivate:
7979  case OMPD_taskyield:
7980  case OMPD_barrier:
7981  case OMPD_taskwait:
7982  case OMPD_cancellation_point:
7983  case OMPD_flush:
7984  case OMPD_declare_reduction:
7985  case OMPD_declare_simd:
7986  case OMPD_declare_target:
7987  case OMPD_end_declare_target:
7988  case OMPD_simd:
7989  case OMPD_for:
7990  case OMPD_for_simd:
7991  case OMPD_sections:
7992  case OMPD_section:
7993  case OMPD_single:
7994  case OMPD_master:
7995  case OMPD_critical:
7996  case OMPD_taskgroup:
7997  case OMPD_ordered:
7998  case OMPD_atomic:
7999  case OMPD_target_teams:
8000  llvm_unreachable("Unexpected OpenMP directive with schedule clause");
8001  case OMPD_unknown:
8002  llvm_unreachable("Unknown OpenMP directive");
8003  }
8004  break;
8005  case OMPC_device:
8006  switch (DKind) {
8007  case OMPD_target_update:
8008  case OMPD_target_enter_data:
8009  case OMPD_target_exit_data:
8010  CaptureRegion = OMPD_task;
8011  break;
8012  case OMPD_target_teams:
8013  case OMPD_target_teams_distribute:
8014  case OMPD_target_teams_distribute_simd:
8015  case OMPD_target_teams_distribute_parallel_for:
8016  case OMPD_target_teams_distribute_parallel_for_simd:
8017  case OMPD_target_data:
8018  case OMPD_target:
8019  case OMPD_target_simd:
8020  case OMPD_target_parallel:
8021  case OMPD_target_parallel_for:
8022  case OMPD_target_parallel_for_simd:
8023  // Do not capture device-clause expressions.
8024  break;
8025  case OMPD_teams_distribute_parallel_for:
8026  case OMPD_teams_distribute_parallel_for_simd:
8027  case OMPD_teams:
8028  case OMPD_teams_distribute:
8029  case OMPD_teams_distribute_simd:
8030  case OMPD_distribute_parallel_for:
8031  case OMPD_distribute_parallel_for_simd:
8032  case OMPD_task:
8033  case OMPD_taskloop:
8034  case OMPD_taskloop_simd:
8035  case OMPD_cancel:
8036  case OMPD_parallel:
8037  case OMPD_parallel_sections:
8038  case OMPD_parallel_for:
8039  case OMPD_parallel_for_simd:
8040  case OMPD_threadprivate:
8041  case OMPD_taskyield:
8042  case OMPD_barrier:
8043  case OMPD_taskwait:
8044  case OMPD_cancellation_point:
8045  case OMPD_flush:
8046  case OMPD_declare_reduction:
8047  case OMPD_declare_simd:
8048  case OMPD_declare_target:
8049  case OMPD_end_declare_target:
8050  case OMPD_simd:
8051  case OMPD_for:
8052  case OMPD_for_simd:
8053  case OMPD_sections:
8054  case OMPD_section:
8055  case OMPD_single:
8056  case OMPD_master:
8057  case OMPD_critical:
8058  case OMPD_taskgroup:
8059  case OMPD_distribute:
8060  case OMPD_ordered:
8061  case OMPD_atomic:
8062  case OMPD_distribute_simd:
8063  llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
8064  case OMPD_unknown:
8065  llvm_unreachable("Unknown OpenMP directive");
8066  }
8067  break;
8068  case OMPC_firstprivate:
8069  case OMPC_lastprivate:
8070  case OMPC_reduction:
8071  case OMPC_task_reduction:
8072  case OMPC_in_reduction:
8073  case OMPC_linear:
8074  case OMPC_default:
8075  case OMPC_proc_bind:
8076  case OMPC_final:
8077  case OMPC_safelen:
8078  case OMPC_simdlen:
8079  case OMPC_collapse:
8080  case OMPC_private:
8081  case OMPC_shared:
8082  case OMPC_aligned:
8083  case OMPC_copyin:
8084  case OMPC_copyprivate:
8085  case OMPC_ordered:
8086  case OMPC_nowait:
8087  case OMPC_untied:
8088  case OMPC_mergeable:
8089  case OMPC_threadprivate:
8090  case OMPC_flush:
8091  case OMPC_read:
8092  case OMPC_write:
8093  case OMPC_update:
8094  case OMPC_capture:
8095  case OMPC_seq_cst:
8096  case OMPC_depend:
8097  case OMPC_threads:
8098  case OMPC_simd:
8099  case OMPC_map:
8100  case OMPC_priority:
8101  case OMPC_grainsize:
8102  case OMPC_nogroup:
8103  case OMPC_num_tasks:
8104  case OMPC_hint:
8105  case OMPC_defaultmap:
8106  case OMPC_unknown:
8107  case OMPC_uniform:
8108  case OMPC_to:
8109  case OMPC_from:
8110  case OMPC_use_device_ptr:
8111  case OMPC_is_device_ptr:
8112  llvm_unreachable("Unexpected OpenMP clause.");
8113  }
8114  return CaptureRegion;
8115 }
8116 
8118  Expr *Condition, SourceLocation StartLoc,
8119  SourceLocation LParenLoc,
8120  SourceLocation NameModifierLoc,
8122  SourceLocation EndLoc) {
8123  Expr *ValExpr = Condition;
8124  Stmt *HelperValStmt = nullptr;
8125  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
8126  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
8127  !Condition->isInstantiationDependent() &&
8128  !Condition->containsUnexpandedParameterPack()) {
8129  ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
8130  if (Val.isInvalid())
8131  return nullptr;
8132 
8133  ValExpr = Val.get();
8134 
8135  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
8136  CaptureRegion =
8137  getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier);
8138  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
8139  ValExpr = MakeFullExpr(ValExpr).get();
8140  llvm::MapVector<Expr *, DeclRefExpr *> Captures;
8141  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
8142  HelperValStmt = buildPreInits(Context, Captures);
8143  }
8144  }
8145 
8146  return new (Context)
8147  OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
8148  LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
8149 }
8150 
8152  SourceLocation StartLoc,
8153  SourceLocation LParenLoc,
8154  SourceLocation EndLoc) {
8155  Expr *ValExpr = Condition;
8156  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
8157  !Condition->isInstantiationDependent() &&
8158  !Condition->containsUnexpandedParameterPack()) {
8159  ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
8160  if (Val.isInvalid())
8161  return nullptr;
8162 
8163  ValExpr = MakeFullExpr(Val.get()).get();
8164  }
8165 
8166  return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc);
8167 }
8169  Expr *Op) {
8170  if (!Op)
8171  return ExprError();
8172 
8173  class IntConvertDiagnoser : public ICEConvertDiagnoser {
8174  public:
8175  IntConvertDiagnoser()
8176  : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
8177  SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
8178  QualType T) override {
8179  return S.Diag(Loc, diag::err_omp_not_integral) << T;
8180  }
8181  SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
8182  QualType T) override {
8183  return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
8184  }
8185  SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
8186  QualType T,
8187  QualType ConvTy) override {
8188  return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
8189  }
8190  SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
8191  QualType ConvTy) override {
8192  return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
8193  << ConvTy->isEnumeralType() << ConvTy;
8194  }
8195  SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
8196  QualType T) override {
8197  return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
8198  }
8199  SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
8200  QualType ConvTy) override {
8201  return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
8202  << ConvTy->isEnumeralType() << ConvTy;
8203  }
8204  SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
8205  QualType) override {
8206  llvm_unreachable("conversion functions are permitted");
8207  }
8208  } ConvertDiagnoser;
8209  return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
8210 }
8211 
8212 static bool IsNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef,
8213  OpenMPClauseKind CKind,
8214  bool StrictlyPositive) {
8215  if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
8216  !ValExpr->isInstantiationDependent()) {
8217  SourceLocation Loc = ValExpr->getExprLoc();
8218  ExprResult Value =
8219  SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
8220  if (Value.isInvalid())
8221  return false;
8222 
8223  ValExpr = Value.get();
8224  // The expression must evaluate to a non-negative integer value.
8225  llvm::APSInt Result;
8226  if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) &&
8227  Result.isSigned() &&
8228  !((!StrictlyPositive && Result.isNonNegative()) ||
8229  (StrictlyPositive && Result.isStrictlyPositive()))) {
8230  SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
8231  << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
8232  << ValExpr->getSourceRange();
8233  return false;
8234  }
8235  }
8236  return true;
8237 }
8238 
8240  SourceLocation StartLoc,
8241  SourceLocation LParenLoc,
8242  SourceLocation EndLoc) {
8243  Expr *ValExpr = NumThreads;
8244  Stmt *HelperValStmt = nullptr;
8245 
8246  // OpenMP [2.5, Restrictions]
8247  // The num_threads expression must evaluate to a positive integer value.
8248  if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
8249  /*StrictlyPositive=*/true))
8250  return nullptr;
8251 
8252  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
8253  OpenMPDirectiveKind CaptureRegion =
8254  getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads);
8255  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
8256  ValExpr = MakeFullExpr(ValExpr).get();
8257  llvm::MapVector<Expr *, DeclRefExpr *> Captures;
8258  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
8259  HelperValStmt = buildPreInits(Context, Captures);
8260  }
8261 
8262  return new (Context) OMPNumThreadsClause(
8263  ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
8264 }
8265 
8266 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
8267  OpenMPClauseKind CKind,
8268  bool StrictlyPositive) {
8269  if (!E)
8270  return ExprError();
8271  if (E->isValueDependent() || E->isTypeDependent() ||
8273  return E;
8274  llvm::APSInt Result;
8275  ExprResult ICE = VerifyIntegerConstantExpression(E, &Result);
8276  if (ICE.isInvalid())
8277  return ExprError();
8278  if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
8279  (!StrictlyPositive && !Result.isNonNegative())) {
8280  Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
8281  << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
8282  << E->getSourceRange();
8283  return ExprError();
8284  }
8285  if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
8286  Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
8287  << E->getSourceRange();
8288  return ExprError();
8289  }
8290  if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
8291  DSAStack->setAssociatedLoops(Result.getExtValue());
8292  else if (CKind == OMPC_ordered)
8293  DSAStack->setAssociatedLoops(Result.getExtValue());
8294  return ICE;
8295 }
8296 
8298  SourceLocation LParenLoc,
8299  SourceLocation EndLoc) {
8300  // OpenMP [2.8.1, simd construct, Description]
8301  // The parameter of the safelen clause must be a constant
8302  // positive integer expression.
8303  ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
8304  if (Safelen.isInvalid())
8305  return nullptr;
8306  return new (Context)
8307  OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
8308 }
8309 
8311  SourceLocation LParenLoc,
8312  SourceLocation EndLoc) {
8313  // OpenMP [2.8.1, simd construct, Description]
8314  // The parameter of the simdlen clause must be a constant
8315  // positive integer expression.
8316  ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
8317  if (Simdlen.isInvalid())
8318  return nullptr;
8319  return new (Context)
8320  OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
8321 }
8322 
8324  SourceLocation StartLoc,
8325  SourceLocation LParenLoc,
8326  SourceLocation EndLoc) {
8327  // OpenMP [2.7.1, loop construct, Description]
8328  // OpenMP [2.8.1, simd construct, Description]
8329  // OpenMP [2.9.6, distribute construct, Description]
8330  // The parameter of the collapse clause must be a constant
8331  // positive integer expression.
8332  ExprResult NumForLoopsResult =
8333  VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
8334  if (NumForLoopsResult.isInvalid())
8335  return nullptr;
8336  return new (Context)
8337  OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
8338 }
8339 
8341  SourceLocation EndLoc,
8342  SourceLocation LParenLoc,
8343  Expr *NumForLoops) {
8344  // OpenMP [2.7.1, loop construct, Description]
8345  // OpenMP [2.8.1, simd construct, Description]
8346  // OpenMP [2.9.6, distribute construct, Description]
8347  // The parameter of the ordered clause must be a constant
8348  // positive integer expression if any.
8349  if (NumForLoops && LParenLoc.isValid()) {
8350  ExprResult NumForLoopsResult =
8351  VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
8352  if (NumForLoopsResult.isInvalid())
8353  return nullptr;
8354  NumForLoops = NumForLoopsResult.get();
8355  } else
8356  NumForLoops = nullptr;
8357  DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops);
8358  return new (Context)
8359  OMPOrderedClause(NumForLoops, StartLoc, LParenLoc, EndLoc);
8360 }
8361 
8363  OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
8364  SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
8365  OMPClause *Res = nullptr;
8366  switch (Kind) {
8367  case OMPC_default:
8368  Res =
8369  ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument),
8370  ArgumentLoc, StartLoc, LParenLoc, EndLoc);
8371  break;
8372  case OMPC_proc_bind:
8373  Res = ActOnOpenMPProcBindClause(
8374  static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc,
8375  LParenLoc, EndLoc);
8376  break;
8377  case OMPC_if:
8378  case OMPC_final:
8379  case OMPC_num_threads:
8380  case OMPC_safelen:
8381  case OMPC_simdlen:
8382  case OMPC_collapse:
8383  case OMPC_schedule:
8384  case OMPC_private:
8385  case OMPC_firstprivate:
8386  case OMPC_lastprivate:
8387  case OMPC_shared:
8388  case OMPC_reduction:
8389  case OMPC_task_reduction:
8390  case OMPC_in_reduction:
8391  case OMPC_linear:
8392  case OMPC_aligned:
8393  case OMPC_copyin:
8394  case OMPC_copyprivate:
8395  case OMPC_ordered:
8396  case OMPC_nowait:
8397  case OMPC_untied:
8398  case OMPC_mergeable:
8399  case OMPC_threadprivate:
8400  case OMPC_flush:
8401  case OMPC_read:
8402  case OMPC_write:
8403  case OMPC_update:
8404  case OMPC_capture:
8405  case OMPC_seq_cst:
8406  case OMPC_depend:
8407  case OMPC_device:
8408  case OMPC_threads:
8409  case OMPC_simd:
8410  case OMPC_map:
8411  case OMPC_num_teams:
8412  case OMPC_thread_limit:
8413  case OMPC_priority:
8414  case OMPC_grainsize:
8415  case OMPC_nogroup:
8416  case OMPC_num_tasks:
8417  case OMPC_hint:
8418  case OMPC_dist_schedule:
8419  case OMPC_defaultmap:
8420  case OMPC_unknown:
8421  case OMPC_uniform:
8422  case OMPC_to:
8423  case OMPC_from:
8424  case OMPC_use_device_ptr:
8425  case OMPC_is_device_ptr:
8426  llvm_unreachable("Clause is not allowed.");
8427  }
8428  return Res;
8429 }
8430 
8431 static std::string
8432 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
8433  ArrayRef<unsigned> Exclude = llvm::None) {
8434  std::string Values;
8435  unsigned Bound = Last >= 2 ? Last - 2 : 0;
8436  unsigned Skipped = Exclude.size();
8437  auto S = Exclude.begin(), E = Exclude.end();
8438  for (unsigned i = First; i < Last; ++i) {
8439  if (std::find(S, E, i) != E) {
8440  --Skipped;
8441  continue;
8442  }
8443  Values += "'";
8444  Values += getOpenMPSimpleClauseTypeName(K, i);
8445  Values += "'";
8446  if (i == Bound - Skipped)
8447  Values += " or ";
8448  else if (i != Bound + 1 - Skipped)
8449  Values += ", ";
8450  }
8451  return Values;
8452 }
8453 
8455  SourceLocation KindKwLoc,
8456  SourceLocation StartLoc,
8457  SourceLocation LParenLoc,
8458  SourceLocation EndLoc) {
8459  if (Kind == OMPC_DEFAULT_unknown) {
8460  static_assert(OMPC_DEFAULT_unknown > 0,
8461  "OMPC_DEFAULT_unknown not greater than 0");
8462  Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
8463  << getListOfPossibleValues(OMPC_default, /*First=*/0,
8464  /*Last=*/OMPC_DEFAULT_unknown)
8465  << getOpenMPClauseName(OMPC_default);
8466  return nullptr;
8467  }
8468  switch (Kind) {
8469  case OMPC_DEFAULT_none:
8470  DSAStack->setDefaultDSANone(KindKwLoc);
8471  break;
8472  case OMPC_DEFAULT_shared:
8473  DSAStack->setDefaultDSAShared(KindKwLoc);
8474  break;
8475  case OMPC_DEFAULT_unknown:
8476  llvm_unreachable("Clause kind is not allowed.");
8477  break;
8478  }
8479  return new (Context)
8480  OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
8481 }
8482 
8484  SourceLocation KindKwLoc,
8485  SourceLocation StartLoc,
8486  SourceLocation LParenLoc,
8487  SourceLocation EndLoc) {
8488  if (Kind == OMPC_PROC_BIND_unknown) {
8489  Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
8490  << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0,
8491  /*Last=*/OMPC_PROC_BIND_unknown)
8492  << getOpenMPClauseName(OMPC_proc_bind);
8493  return nullptr;
8494  }
8495  return new (Context)
8496  OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
8497 }
8498 
8501  SourceLocation StartLoc, SourceLocation LParenLoc,
8502  ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
8503  SourceLocation EndLoc) {
8504  OMPClause *Res = nullptr;
8505  switch (Kind) {
8506  case OMPC_schedule:
8507  enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
8508  assert(Argument.size() == NumberOfElements &&
8509  ArgumentLoc.size() == NumberOfElements);
8510  Res = ActOnOpenMPScheduleClause(
8511  static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
8512  static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
8513  static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
8514  StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
8515  ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
8516  break;
8517  case OMPC_if:
8518  assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
8519  Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
8520  Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
8521  DelimLoc, EndLoc);
8522  break;
8523  case OMPC_dist_schedule:
8524  Res = ActOnOpenMPDistScheduleClause(
8525  static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
8526  StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
8527  break;
8528  case OMPC_defaultmap:
8529  enum { Modifier, DefaultmapKind };
8530  Res = ActOnOpenMPDefaultmapClause(
8531  static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
8532  static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
8533  StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
8534  EndLoc);
8535  break;
8536  case OMPC_final:
8537  case OMPC_num_threads:
8538  case OMPC_safelen:
8539  case OMPC_simdlen:
8540  case OMPC_collapse:
8541  case OMPC_default:
8542  case OMPC_proc_bind:
8543  case OMPC_private:
8544  case OMPC_firstprivate:
8545  case OMPC_lastprivate:
8546  case OMPC_shared:
8547  case OMPC_reduction:
8548  case OMPC_task_reduction:
8549  case OMPC_in_reduction:
8550  case OMPC_linear:
8551  case OMPC_aligned:
8552  case OMPC_copyin:
8553  case OMPC_copyprivate:
8554  case OMPC_ordered:
8555  case OMPC_nowait:
8556  case OMPC_untied:
8557  case OMPC_mergeable:
8558  case OMPC_threadprivate:
8559  case OMPC_flush:
8560  case OMPC_read:
8561  case OMPC_write:
8562  case OMPC_update:
8563  case OMPC_capture:
8564  case OMPC_seq_cst:
8565  case OMPC_depend:
8566  case OMPC_device:
8567  case OMPC_threads:
8568  case OMPC_simd:
8569  case OMPC_map:
8570  case OMPC_num_teams:
8571  case OMPC_thread_limit:
8572  case OMPC_priority:
8573  case OMPC_grainsize:
8574  case OMPC_nogroup:
8575  case OMPC_num_tasks:
8576  case OMPC_hint:
8577  case OMPC_unknown:
8578  case OMPC_uniform:
8579  case OMPC_to:
8580  case OMPC_from:
8581  case OMPC_use_device_ptr:
8582  case OMPC_is_device_ptr:
8583  llvm_unreachable("Clause is not allowed.");
8584  }
8585  return Res;
8586 }
8587 
8590  SourceLocation M1Loc, SourceLocation M2Loc) {
8591  if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
8592  SmallVector<unsigned, 2> Excluded;
8594  Excluded.push_back(M2);
8595  if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
8596  Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
8597  if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
8598  Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
8599  S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
8600  << getListOfPossibleValues(OMPC_schedule,
8601  /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
8602  /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
8603  Excluded)
8604  << getOpenMPClauseName(OMPC_schedule);
8605  return true;
8606  }
8607  return false;
8608 }
8609 
8612  OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
8613  SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
8614  SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
8615  if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
8616  checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
8617  return nullptr;
8618  // OpenMP, 2.7.1, Loop Construct, Restrictions
8619  // Either the monotonic modifier or the nonmonotonic modifier can be specified
8620  // but not both.
8621  if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
8622  (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
8623  M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
8624  (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
8625  M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
8626  Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
8627  << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
8628  << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
8629  return nullptr;
8630  }
8631  if (Kind == OMPC_SCHEDULE_unknown) {
8632  std::string Values;
8633  if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
8634  unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
8635  Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
8636  /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
8637  Exclude);
8638  } else {
8639  Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
8640  /*Last=*/OMPC_SCHEDULE_unknown);
8641  }
8642  Diag(KindLoc, diag::err_omp_unexpected_clause_value)
8643  << Values << getOpenMPClauseName(OMPC_schedule);
8644  return nullptr;
8645  }
8646  // OpenMP, 2.7.1, Loop Construct, Restrictions
8647  // The nonmonotonic modifier can only be specified with schedule(dynamic) or
8648  // schedule(guided).
8649  if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
8650  M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
8651  Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
8652  Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
8653  diag::err_omp_schedule_nonmonotonic_static);
8654  return nullptr;
8655  }
8656  Expr *ValExpr = ChunkSize;
8657  Stmt *HelperValStmt = nullptr;
8658  if (ChunkSize) {
8659  if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
8660  !ChunkSize->isInstantiationDependent() &&
8661  !ChunkSize->containsUnexpandedParameterPack()) {
8662  SourceLocation ChunkSizeLoc = ChunkSize->getLocStart();
8663  ExprResult Val =
8664  PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
8665  if (Val.isInvalid())
8666  return nullptr;
8667 
8668  ValExpr = Val.get();
8669 
8670  // OpenMP [2.7.1, Restrictions]
8671  // chunk_size must be a loop invariant integer expression with a positive
8672  // value.
8673  llvm::APSInt Result;
8674  if (ValExpr->isIntegerConstantExpr(Result, Context)) {
8675  if (Result.isSigned() && !Result.isStrictlyPositive()) {
8676  Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
8677  << "schedule" << 1 << ChunkSize->getSourceRange();
8678  return nullptr;
8679  }
8681  DSAStack->getCurrentDirective(), OMPC_schedule) !=
8682  OMPD_unknown &&
8683  !CurContext->isDependentContext()) {
8684  ValExpr = MakeFullExpr(ValExpr).get();
8685  llvm::MapVector<Expr *, DeclRefExpr *> Captures;
8686  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
8687  HelperValStmt = buildPreInits(Context, Captures);
8688  }
8689  }
8690  }
8691 
8692  return new (Context)
8693  OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
8694  ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
8695 }
8696 
8698  SourceLocation StartLoc,
8699  SourceLocation EndLoc) {
8700  OMPClause *Res = nullptr;
8701  switch (Kind) {
8702  case OMPC_ordered:
8703  Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
8704  break;
8705  case OMPC_nowait:
8706  Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
8707  break;
8708  case OMPC_untied:
8709  Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
8710  break;
8711  case OMPC_mergeable:
8712  Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
8713  break;
8714  case OMPC_read:
8715  Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
8716  break;
8717  case OMPC_write:
8718  Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
8719  break;
8720  case OMPC_update:
8721  Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
8722  break;
8723  case OMPC_capture:
8724  Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
8725  break;
8726  case OMPC_seq_cst:
8727  Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
8728  break;
8729  case OMPC_threads:
8730  Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
8731  break;
8732  case OMPC_simd:
8733  Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
8734  break;
8735  case OMPC_nogroup:
8736  Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
8737  break;
8738  case OMPC_if:
8739  case OMPC_final:
8740  case OMPC_num_threads:
8741  case OMPC_safelen:
8742  case OMPC_simdlen:
8743  case OMPC_collapse:
8744  case OMPC_schedule:
8745  case OMPC_private:
8746  case OMPC_firstprivate:
8747  case OMPC_lastprivate:
8748  case OMPC_shared:
8749  case OMPC_reduction:
8750  case OMPC_task_reduction:
8751  case OMPC_in_reduction:
8752  case OMPC_linear:
8753  case OMPC_aligned:
8754  case OMPC_copyin:
8755  case OMPC_copyprivate:
8756  case OMPC_default:
8757  case OMPC_proc_bind:
8758  case OMPC_threadprivate:
8759  case OMPC_flush:
8760  case OMPC_depend:
8761  case OMPC_device:
8762  case OMPC_map:
8763  case OMPC_num_teams:
8764  case OMPC_thread_limit:
8765  case OMPC_priority:
8766  case OMPC_grainsize:
8767  case OMPC_num_tasks:
8768  case OMPC_hint:
8769  case OMPC_dist_schedule:
8770  case OMPC_defaultmap:
8771  case OMPC_unknown:
8772  case OMPC_uniform:
8773  case OMPC_to:
8774  case OMPC_from:
8775  case OMPC_use_device_ptr:
8776  case OMPC_is_device_ptr:
8777  llvm_unreachable("Clause is not allowed.");
8778  }
8779  return Res;
8780 }
8781 
8783  SourceLocation EndLoc) {
8784  DSAStack->setNowaitRegion();
8785  return new (Context) OMPNowaitClause(StartLoc, EndLoc);
8786 }
8787 
8789  SourceLocation EndLoc) {
8790  return new (Context) OMPUntiedClause(StartLoc, EndLoc);
8791 }
8792 
8794  SourceLocation EndLoc) {
8795  return new (Context) OMPMergeableClause(StartLoc, EndLoc);
8796 }
8797 
8799  SourceLocation EndLoc) {
8800  return new (Context) OMPReadClause(StartLoc, EndLoc);
8801 }
8802 
8804  SourceLocation EndLoc) {
8805  return new (Context) OMPWriteClause(StartLoc, EndLoc);
8806 }
8807 
8809  SourceLocation EndLoc) {
8810  return new (Context) OMPUpdateClause(StartLoc, EndLoc);
8811 }
8812 
8814  SourceLocation EndLoc) {
8815  return new (Context) OMPCaptureClause(StartLoc, EndLoc);
8816 }
8817 
8819  SourceLocation EndLoc) {
8820  return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
8821 }
8822 
8824  SourceLocation EndLoc) {
8825  return new (Context) OMPThreadsClause(StartLoc, EndLoc);
8826 }
8827 
8829  SourceLocation EndLoc) {
8830  return new (Context) OMPSIMDClause(StartLoc, EndLoc);
8831 }
8832 
8834  SourceLocation EndLoc) {
8835  return new (Context) OMPNogroupClause(StartLoc, EndLoc);
8836 }
8837 
8839  OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr,
8841  SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
8842  const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind,
8843  OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier,
8844  OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
8845  SourceLocation DepLinMapLoc) {
8846  OMPClause *Res = nullptr;
8847  switch (Kind) {
8848  case OMPC_private:
8849  Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
8850  break;
8851  case OMPC_firstprivate:
8852  Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
8853  break;
8854  case OMPC_lastprivate:
8855  Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
8856  break;
8857  case OMPC_shared:
8858  Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
8859  break;
8860  case OMPC_reduction:
8861  Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
8862  EndLoc, ReductionIdScopeSpec, ReductionId);
8863  break;
8864  case OMPC_task_reduction:
8865  Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
8866  EndLoc, ReductionIdScopeSpec,
8867  ReductionId);
8868  break;
8869  case OMPC_in_reduction:
8870  Res =
8871  ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
8872  EndLoc, ReductionIdScopeSpec, ReductionId);
8873  break;
8874  case OMPC_linear:
8875  Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc,
8876  LinKind, DepLinMapLoc, ColonLoc, EndLoc);
8877  break;
8878  case OMPC_aligned:
8879  Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc,
8880  ColonLoc, EndLoc);
8881  break;
8882  case OMPC_copyin:
8883  Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
8884  break;
8885  case OMPC_copyprivate:
8886  Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
8887  break;
8888  case OMPC_flush:
8889  Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
8890  break;
8891  case OMPC_depend:
8892  Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList,
8893  StartLoc, LParenLoc, EndLoc);
8894  break;
8895  case OMPC_map:
8896  Res = ActOnOpenMPMapClause(MapTypeModifier, MapType, IsMapTypeImplicit,
8897  DepLinMapLoc, ColonLoc, VarList, StartLoc,
8898  LParenLoc, EndLoc);
8899  break;
8900  case OMPC_to:
8901  Res = ActOnOpenMPToClause(VarList, StartLoc, LParenLoc, EndLoc);
8902  break;
8903  case OMPC_from:
8904  Res = ActOnOpenMPFromClause(VarList, StartLoc, LParenLoc, EndLoc);
8905  break;
8906  case OMPC_use_device_ptr:
8907  Res = ActOnOpenMPUseDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc);
8908  break;
8909  case OMPC_is_device_ptr:
8910  Res = ActOnOpenMPIsDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc);
8911  break;
8912  case OMPC_if:
8913  case OMPC_final:
8914  case OMPC_num_threads:
8915  case OMPC_safelen:
8916  case OMPC_simdlen:
8917  case OMPC_collapse:
8918  case OMPC_default:
8919  case OMPC_proc_bind:
8920  case OMPC_schedule:
8921  case OMPC_ordered:
8922  case OMPC_nowait:
8923  case OMPC_untied:
8924  case OMPC_mergeable:
8925  case OMPC_threadprivate:
8926  case OMPC_read:
8927  case OMPC_write:
8928  case OMPC_update:
8929  case OMPC_capture:
8930  case OMPC_seq_cst:
8931  case OMPC_device:
8932  case OMPC_threads:
8933  case OMPC_simd:
8934  case OMPC_num_teams:
8935  case OMPC_thread_limit:
8936  case OMPC_priority:
8937  case OMPC_grainsize:
8938  case OMPC_nogroup:
8939  case OMPC_num_tasks:
8940  case OMPC_hint:
8941  case OMPC_dist_schedule:
8942  case OMPC_defaultmap:
8943  case OMPC_unknown:
8944  case OMPC_uniform:
8945  llvm_unreachable("Clause is not allowed.");
8946  }
8947  return Res;
8948 }
8949 
8951  ExprObjectKind OK, SourceLocation Loc) {
8952  ExprResult Res = BuildDeclRefExpr(
8953  Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
8954  if (!Res.isUsable())
8955  return ExprError();
8956  if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
8957  Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
8958  if (!Res.isUsable())
8959  return ExprError();
8960  }
8961  if (VK != VK_LValue && Res.get()->isGLValue()) {
8962  Res = DefaultLvalueConversion(Res.get());
8963  if (!Res.isUsable())
8964  return ExprError();
8965  }
8966  return Res;
8967 }
8968 
8969 static std::pair<ValueDecl *, bool>
8971  SourceRange &ERange, bool AllowArraySection = false) {
8972  if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
8974  return std::make_pair(nullptr, true);
8975 
8976  // OpenMP [3.1, C/C++]
8977  // A list item is a variable name.
8978  // OpenMP [2.9.3.3, Restrictions, p.1]
8979  // A variable that is part of another variable (as an array or
8980  // structure element) cannot appear in a private clause.
8981  RefExpr = RefExpr->IgnoreParens();
8982  enum {
8983  NoArrayExpr = -1,
8984  ArraySubscript = 0,
8985  OMPArraySection = 1
8986  } IsArrayExpr = NoArrayExpr;
8987  if (AllowArraySection) {
8988  if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
8989  auto *Base = ASE->getBase()->IgnoreParenImpCasts();
8990  while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
8991  Base = TempASE->getBase()->IgnoreParenImpCasts();
8992  RefExpr = Base;
8993  IsArrayExpr = ArraySubscript;
8994  } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
8995  auto *Base = OASE->getBase()->IgnoreParenImpCasts();
8996  while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
8997  Base = TempOASE->getBase()->IgnoreParenImpCasts();
8998  while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
8999  Base = TempASE->getBase()->IgnoreParenImpCasts();
9000  RefExpr = Base;
9001  IsArrayExpr = OMPArraySection;
9002  }
9003  }
9004  ELoc = RefExpr->getExprLoc();
9005  ERange = RefExpr->getSourceRange();
9006  RefExpr = RefExpr->IgnoreParenImpCasts();
9007  auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
9008  auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
9009  if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
9010  (S.getCurrentThisType().isNull() || !ME ||
9011  !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
9012  !isa<FieldDecl>(ME->getMemberDecl()))) {
9013  if (IsArrayExpr != NoArrayExpr)
9014  S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
9015  << ERange;
9016  else {
9017  S.Diag(ELoc,
9018  AllowArraySection
9019  ? diag::err_omp_expected_var_name_member_expr_or_array_item
9020  : diag::err_omp_expected_var_name_member_expr)
9021  << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
9022  }
9023  return std::make_pair(nullptr, false);
9024  }
9025  return std::make_pair(
9026  getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
9027 }
9028 
9030  SourceLocation StartLoc,
9031  SourceLocation LParenLoc,
9032  SourceLocation EndLoc) {
9034  SmallVector<Expr *, 8> PrivateCopies;
9035  for (auto &RefExpr : VarList) {
9036  assert(RefExpr && "NULL expr in OpenMP private clause.");
9037  SourceLocation ELoc;
9038  SourceRange ERange;
9039  Expr *SimpleRefExpr = RefExpr;
9040  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
9041  if (Res.second) {
9042  // It will be analyzed later.
9043  Vars.push_back(RefExpr);
9044  PrivateCopies.push_back(nullptr);
9045  }
9046  ValueDecl *D = Res.first;
9047  if (!D)
9048  continue;
9049 
9050  QualType Type = D->getType();
9051  auto *VD = dyn_cast<VarDecl>(D);
9052 
9053  // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
9054  // A variable that appears in a private clause must not have an incomplete
9055  // type or a reference type.
9056  if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
9057  continue;
9058  Type = Type.getNonReferenceType();
9059 
9060  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
9061  // in a Construct]
9062  // Variables with the predetermined data-sharing attributes may not be
9063  // listed in data-sharing attributes clauses, except for the cases
9064  // listed below. For these exceptions only, listing a predetermined
9065  // variable in a data-sharing attribute clause is allowed and overrides
9066  // the variable's predetermined data-sharing attributes.
9067  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false);
9068  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
9069  Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
9070  << getOpenMPClauseName(OMPC_private);
9071  ReportOriginalDSA(*this, DSAStack, D, DVar);
9072  continue;
9073  }
9074 
9075  auto CurrDir = DSAStack->getCurrentDirective();
9076  // Variably modified types are not supported for tasks.
9077  if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
9078  isOpenMPTaskingDirective(CurrDir)) {
9079  Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
9080  << getOpenMPClauseName(OMPC_private) << Type
9081  << getOpenMPDirectiveName(CurrDir);
9082  bool IsDecl =
9083  !VD ||
9084  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
9085  Diag(D->getLocation(),
9086  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9087  << D;
9088  continue;
9089  }
9090 
9091  // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
9092  // A list item cannot appear in both a map clause and a data-sharing
9093  // attribute clause on the same construct
9094  if (CurrDir == OMPD_target || CurrDir == OMPD_target_parallel ||
9095  CurrDir == OMPD_target_teams ||
9096  CurrDir == OMPD_target_teams_distribute ||
9097  CurrDir == OMPD_target_teams_distribute_parallel_for ||
9098  CurrDir == OMPD_target_teams_distribute_parallel_for_simd ||
9099  CurrDir == OMPD_target_teams_distribute_simd ||
9100  CurrDir == OMPD_target_parallel_for_simd ||
9101  CurrDir == OMPD_target_parallel_for) {
9102  OpenMPClauseKind ConflictKind;
9103  if (DSAStack->checkMappableExprComponentListsForDecl(
9104  VD, /*CurrentRegionOnly=*/true,
9106  OpenMPClauseKind WhereFoundClauseKind) -> bool {
9107  ConflictKind = WhereFoundClauseKind;
9108  return true;
9109  })) {
9110  Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
9111  << getOpenMPClauseName(OMPC_private)
9112  << getOpenMPClauseName(ConflictKind)
9113  << getOpenMPDirectiveName(CurrDir);
9114  ReportOriginalDSA(*this, DSAStack, D, DVar);
9115  continue;
9116  }
9117  }
9118 
9119  // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
9120  // A variable of class type (or array thereof) that appears in a private
9121  // clause requires an accessible, unambiguous default constructor for the
9122  // class type.
9123  // Generate helper private variable and initialize it with the default
9124  // value. The address of the original variable is replaced by the address of
9125  // the new private variable in CodeGen. This new variable is not added to
9126  // IdResolver, so the code in the OpenMP region uses original variable for
9127  // proper diagnostics.
9128  Type = Type.getUnqualifiedType();
9129  auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(),
9130  D->hasAttrs() ? &D->getAttrs() : nullptr);
9131  ActOnUninitializedDecl(VDPrivate);
9132  if (VDPrivate->isInvalidDecl())
9133  continue;
9134  auto VDPrivateRefExpr = buildDeclRefExpr(
9135  *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
9136 
9137  DeclRefExpr *Ref = nullptr;
9138  if (!VD && !CurContext->isDependentContext())
9139  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
9140  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
9141  Vars.push_back((VD || CurContext->isDependentContext())
9142  ? RefExpr->IgnoreParens()
9143  : Ref);
9144  PrivateCopies.push_back(VDPrivateRefExpr);
9145  }
9146 
9147  if (Vars.empty())
9148  return nullptr;
9149 
9150  return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
9151  PrivateCopies);
9152 }
9153 
9154 namespace {
9155 class DiagsUninitializedSeveretyRAII {
9156 private:
9157  DiagnosticsEngine &Diags;
9158  SourceLocation SavedLoc;
9159  bool IsIgnored;
9160 
9161 public:
9162  DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
9163  bool IsIgnored)
9164  : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
9165  if (!IsIgnored) {
9166  Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
9167  /*Map*/ diag::Severity::Ignored, Loc);
9168  }
9169  }
9170  ~DiagsUninitializedSeveretyRAII() {
9171  if (!IsIgnored)
9172  Diags.popMappings(SavedLoc);
9173  }
9174 };
9175 }
9176 
9178  SourceLocation StartLoc,
9179  SourceLocation LParenLoc,
9180  SourceLocation EndLoc) {
9182  SmallVector<Expr *, 8> PrivateCopies;
9184  SmallVector<Decl *, 4> ExprCaptures;
9185  bool IsImplicitClause =
9186  StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
9187  auto ImplicitClauseLoc = DSAStack->getConstructLoc();
9188 
9189  for (auto &RefExpr : VarList) {
9190  assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
9191  SourceLocation ELoc;
9192  SourceRange ERange;
9193  Expr *SimpleRefExpr = RefExpr;
9194  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
9195  if (Res.second) {
9196  // It will be analyzed later.
9197  Vars.push_back(RefExpr);
9198  PrivateCopies.push_back(nullptr);
9199  Inits.push_back(nullptr);
9200  }
9201  ValueDecl *D = Res.first;
9202  if (!D)
9203  continue;
9204 
9205  ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
9206  QualType Type = D->getType();
9207  auto *VD = dyn_cast<VarDecl>(D);
9208 
9209  // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
9210  // A variable that appears in a private clause must not have an incomplete
9211  // type or a reference type.
9212  if (RequireCompleteType(ELoc, Type,
9213  diag::err_omp_firstprivate_incomplete_type))
9214  continue;
9215  Type = Type.getNonReferenceType();
9216 
9217  // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
9218  // A variable of class type (or array thereof) that appears in a private
9219  // clause requires an accessible, unambiguous copy constructor for the
9220  // class type.
9221  auto ElemType = Context.getBaseElementType(Type).getNonReferenceType();
9222 
9223  // If an implicit firstprivate variable found it was checked already.
9224  DSAStackTy::DSAVarData TopDVar;
9225  if (!IsImplicitClause) {
9226  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false);
9227  TopDVar = DVar;
9228  OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
9229  bool IsConstant = ElemType.isConstant(Context);
9230  // OpenMP [2.4.13, Data-sharing Attribute Clauses]
9231  // A list item that specifies a given variable may not appear in more
9232  // than one clause on the same directive, except that a variable may be
9233  // specified in both firstprivate and lastprivate clauses.
9234  // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
9235  // A list item may appear in a firstprivate or lastprivate clause but not
9236  // both.
9237  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
9238  (isOpenMPDistributeDirective(CurrDir) ||
9239  DVar.CKind != OMPC_lastprivate) &&
9240  DVar.RefExpr) {
9241  Diag(ELoc, diag::err_omp_wrong_dsa)
9242  << getOpenMPClauseName(DVar.CKind)
9243  << getOpenMPClauseName(OMPC_firstprivate);
9244  ReportOriginalDSA(*this, DSAStack, D, DVar);
9245  continue;
9246  }
9247 
9248  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
9249  // in a Construct]
9250  // Variables with the predetermined data-sharing attributes may not be
9251  // listed in data-sharing attributes clauses, except for the cases
9252  // listed below. For these exceptions only, listing a predetermined
9253  // variable in a data-sharing attribute clause is allowed and overrides
9254  // the variable's predetermined data-sharing attributes.
9255  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
9256  // in a Construct, C/C++, p.2]
9257  // Variables with const-qualified type having no mutable member may be
9258  // listed in a firstprivate clause, even if they are static data members.
9259  if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
9260  DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
9261  Diag(ELoc, diag::err_omp_wrong_dsa)
9262  << getOpenMPClauseName(DVar.CKind)
9263  << getOpenMPClauseName(OMPC_firstprivate);
9264  ReportOriginalDSA(*this, DSAStack, D, DVar);
9265  continue;
9266  }
9267 
9268  // OpenMP [2.9.3.4, Restrictions, p.2]
9269  // A list item that is private within a parallel region must not appear
9270  // in a firstprivate clause on a worksharing construct if any of the
9271  // worksharing regions arising from the worksharing construct ever bind
9272  // to any of the parallel regions arising from the parallel construct.
9273  // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
9274  // A list item that is private within a teams region must not appear in a
9275  // firstprivate clause on a distribute construct if any of the distribute
9276  // regions arising from the distribute construct ever bind to any of the
9277  // teams regions arising from the teams construct.
9278  // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
9279  // A list item that appears in a reduction clause of a teams construct
9280  // must not appear in a firstprivate clause on a distribute construct if
9281  // any of the distribute regions arising from the distribute construct
9282  // ever bind to any of the teams regions arising from the teams construct.
9283  if ((isOpenMPWorksharingDirective(CurrDir) ||
9284  isOpenMPDistributeDirective(CurrDir)) &&
9285  !isOpenMPParallelDirective(CurrDir) &&
9286  !isOpenMPTeamsDirective(CurrDir)) {
9287  DVar = DSAStack->getImplicitDSA(D, true);
9288  if (DVar.CKind != OMPC_shared &&
9289  (isOpenMPParallelDirective(DVar.DKind) ||
9290  isOpenMPTeamsDirective(DVar.DKind) ||
9291  DVar.DKind == OMPD_unknown)) {
9292  Diag(ELoc, diag::err_omp_required_access)
9293  << getOpenMPClauseName(OMPC_firstprivate)
9294  << getOpenMPClauseName(OMPC_shared);
9295  ReportOriginalDSA(*this, DSAStack, D, DVar);
9296  continue;
9297  }
9298  }
9299  // OpenMP [2.9.3.4, Restrictions, p.3]
9300  // A list item that appears in a reduction clause of a parallel construct
9301  // must not appear in a firstprivate clause on a worksharing or task
9302  // construct if any of the worksharing or task regions arising from the
9303  // worksharing or task construct ever bind to any of the parallel regions
9304  // arising from the parallel construct.
9305  // OpenMP [2.9.3.4, Restrictions, p.4]
9306  // A list item that appears in a reduction clause in worksharing
9307  // construct must not appear in a firstprivate clause in a task construct
9308  // encountered during execution of any of the worksharing regions arising
9309  // from the worksharing construct.
9310  if (isOpenMPTaskingDirective(CurrDir)) {
9311  DVar = DSAStack->hasInnermostDSA(
9312  D, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; },
9313  [](OpenMPDirectiveKind K) -> bool {
9314  return isOpenMPParallelDirective(K) ||
9317  },
9318  /*FromParent=*/true);
9319  if (DVar.CKind == OMPC_reduction &&
9320  (isOpenMPParallelDirective(DVar.DKind) ||
9321  isOpenMPWorksharingDirective(DVar.DKind) ||
9322  isOpenMPTeamsDirective(DVar.DKind))) {
9323  Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
9324  << getOpenMPDirectiveName(DVar.DKind);
9325  ReportOriginalDSA(*this, DSAStack, D, DVar);
9326  continue;
9327  }
9328  }
9329 
9330  // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
9331  // A list item cannot appear in both a map clause and a data-sharing
9332  // attribute clause on the same construct
9333  if (isOpenMPTargetExecutionDirective(CurrDir)) {
9334  OpenMPClauseKind ConflictKind;
9335  if (DSAStack->checkMappableExprComponentListsForDecl(
9336  VD, /*CurrentRegionOnly=*/true,
9338  OpenMPClauseKind WhereFoundClauseKind) -> bool {
9339  ConflictKind = WhereFoundClauseKind;
9340  return true;
9341  })) {
9342  Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
9343  << getOpenMPClauseName(OMPC_firstprivate)
9344  << getOpenMPClauseName(ConflictKind)
9345  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
9346  ReportOriginalDSA(*this, DSAStack, D, DVar);
9347  continue;
9348  }
9349  }
9350  }
9351 
9352  // Variably modified types are not supported for tasks.
9353  if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
9354  isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
9355  Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
9356  << getOpenMPClauseName(OMPC_firstprivate) << Type
9357  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
9358  bool IsDecl =
9359  !VD ||
9360  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
9361  Diag(D->getLocation(),
9362  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9363  << D;
9364  continue;
9365  }
9366 
9367  Type = Type.getUnqualifiedType();
9368  auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(),
9369  D->hasAttrs() ? &D->getAttrs() : nullptr);
9370  // Generate helper private variable and initialize it with the value of the
9371  // original variable. The address of the original variable is replaced by
9372  // the address of the new private variable in the CodeGen. This new variable
9373  // is not added to IdResolver, so the code in the OpenMP region uses
9374  // original variable for proper diagnostics and variable capturing.
9375  Expr *VDInitRefExpr = nullptr;
9376  // For arrays generate initializer for single element and replace it by the
9377  // original array element in CodeGen.
9378  if (Type->isArrayType()) {
9379  auto VDInit =
9380  buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
9381  VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
9382  auto Init = DefaultLvalueConversion(VDInitRefExpr).get();
9383  ElemType = ElemType.getUnqualifiedType();
9384  auto *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
9385  ".firstprivate.temp");
9386  InitializedEntity Entity =
9389 
9390  InitializationSequence InitSeq(*this, Entity, Kind, Init);
9391  ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
9392  if (Result.isInvalid())
9393  VDPrivate->setInvalidDecl();
9394  else
9395  VDPrivate->setInit(Result.getAs<Expr>());
9396  // Remove temp variable declaration.
9397  Context.Deallocate(VDInitTemp);
9398  } else {
9399  auto *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
9400  ".firstprivate.temp");
9401  VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
9402  RefExpr->getExprLoc());
9403  AddInitializerToDecl(VDPrivate,
9404  DefaultLvalueConversion(VDInitRefExpr).get(),
9405  /*DirectInit=*/false);
9406  }
9407  if (VDPrivate->isInvalidDecl()) {
9408  if (IsImplicitClause) {
9409  Diag(RefExpr->getExprLoc(),
9410  diag::note_omp_task_predetermined_firstprivate_here);
9411  }
9412  continue;
9413  }
9414  CurContext->addDecl(VDPrivate);
9415  auto VDPrivateRefExpr = buildDeclRefExpr(
9416  *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
9417  RefExpr->getExprLoc());
9418  DeclRefExpr *Ref = nullptr;
9419  if (!VD && !CurContext->isDependentContext()) {
9420  if (TopDVar.CKind == OMPC_lastprivate)
9421  Ref = TopDVar.PrivateCopy;
9422  else {
9423  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
9424  if (!IsOpenMPCapturedDecl(D))
9425  ExprCaptures.push_back(Ref->getDecl());
9426  }
9427  }
9428  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
9429  Vars.push_back((VD || CurContext->isDependentContext())
9430  ? RefExpr->IgnoreParens()
9431  : Ref);
9432  PrivateCopies.push_back(VDPrivateRefExpr);
9433  Inits.push_back(VDInitRefExpr);
9434  }
9435 
9436  if (Vars.empty())
9437  return nullptr;
9438 
9439  return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
9440  Vars, PrivateCopies, Inits,
9441  buildPreInits(Context, ExprCaptures));
9442 }
9443 
9445  SourceLocation StartLoc,
9446  SourceLocation LParenLoc,
9447  SourceLocation EndLoc) {
9449  SmallVector<Expr *, 8> SrcExprs;
9450  SmallVector<Expr *, 8> DstExprs;
9451  SmallVector<Expr *, 8> AssignmentOps;
9452  SmallVector<Decl *, 4> ExprCaptures;
9453  SmallVector<Expr *, 4> ExprPostUpdates;
9454  for (auto &RefExpr : VarList) {
9455  assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
9456  SourceLocation ELoc;
9457  SourceRange ERange;
9458  Expr *SimpleRefExpr = RefExpr;
9459  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
9460  if (Res.second) {
9461  // It will be analyzed later.
9462  Vars.push_back(RefExpr);
9463  SrcExprs.push_back(nullptr);
9464  DstExprs.push_back(nullptr);
9465  AssignmentOps.push_back(nullptr);
9466  }
9467  ValueDecl *D = Res.first;
9468  if (!D)
9469  continue;
9470 
9471  QualType Type = D->getType();
9472  auto *VD = dyn_cast<VarDecl>(D);
9473 
9474  // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
9475  // A variable that appears in a lastprivate clause must not have an
9476  // incomplete type or a reference type.
9477  if (RequireCompleteType(ELoc, Type,
9478  diag::err_omp_lastprivate_incomplete_type))
9479  continue;
9480  Type = Type.getNonReferenceType();
9481 
9482  OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
9483  // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
9484  // in a Construct]
9485  // Variables with the predetermined data-sharing attributes may not be
9486  // listed in data-sharing attributes clauses, except for the cases
9487  // listed below.
9488  // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
9489  // A list item may appear in a firstprivate or lastprivate clause but not
9490  // both.
9491  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false);
9492  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
9493  (isOpenMPDistributeDirective(CurrDir) ||
9494  DVar.CKind != OMPC_firstprivate) &&
9495  (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
9496  Diag(ELoc, diag::err_omp_wrong_dsa)
9497  << getOpenMPClauseName(DVar.CKind)
9498  << getOpenMPClauseName(OMPC_lastprivate);
9499  ReportOriginalDSA(*this, DSAStack, D, DVar);
9500  continue;
9501  }
9502 
9503  // OpenMP [2.14.3.5, Restrictions, p.2]
9504  // A list item that is private within a parallel region, or that appears in
9505  // the reduction clause of a parallel construct, must not appear in a
9506  // lastprivate clause on a worksharing construct if any of the corresponding
9507  // worksharing regions ever binds to any of the corresponding parallel
9508  // regions.
9509  DSAStackTy::DSAVarData TopDVar = DVar;
9510  if (isOpenMPWorksharingDirective(CurrDir) &&
9511  !isOpenMPParallelDirective(CurrDir) &&
9512  !isOpenMPTeamsDirective(CurrDir)) {
9513  DVar = DSAStack->getImplicitDSA(D, true);
9514  if (DVar.CKind != OMPC_shared) {
9515  Diag(ELoc, diag::err_omp_required_access)
9516  << getOpenMPClauseName(OMPC_lastprivate)
9517  << getOpenMPClauseName(OMPC_shared);
9518  ReportOriginalDSA(*this, DSAStack, D, DVar);
9519  continue;
9520  }
9521  }
9522 
9523  // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
9524  // A variable of class type (or array thereof) that appears in a
9525  // lastprivate clause requires an accessible, unambiguous default
9526  // constructor for the class type, unless the list item is also specified
9527  // in a firstprivate clause.
9528  // A variable of class type (or array thereof) that appears in a
9529  // lastprivate clause requires an accessible, unambiguous copy assignment
9530  // operator for the class type.
9531  Type = Context.getBaseElementType(Type).getNonReferenceType();
9532  auto *SrcVD = buildVarDecl(*this, ERange.getBegin(),
9533  Type.getUnqualifiedType(), ".lastprivate.src",
9534  D->hasAttrs() ? &D->getAttrs() : nullptr);
9535  auto *PseudoSrcExpr =
9536  buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
9537  auto *DstVD =
9538  buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
9539  D->hasAttrs() ? &D->getAttrs() : nullptr);
9540  auto *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
9541  // For arrays generate assignment operation for single element and replace
9542  // it by the original array element in CodeGen.
9543  auto AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
9544  PseudoDstExpr, PseudoSrcExpr);
9545  if (AssignmentOp.isInvalid())
9546  continue;
9547  AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc,
9548  /*DiscardedValue=*/true);
9549  if (AssignmentOp.isInvalid())
9550  continue;
9551 
9552  DeclRefExpr *Ref = nullptr;
9553  if (!VD && !CurContext->isDependentContext()) {
9554  if (TopDVar.CKind == OMPC_firstprivate)
9555  Ref = TopDVar.PrivateCopy;
9556  else {
9557  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
9558  if (!IsOpenMPCapturedDecl(D))
9559  ExprCaptures.push_back(Ref->getDecl());
9560  }
9561  if (TopDVar.CKind == OMPC_firstprivate ||
9562  (!IsOpenMPCapturedDecl(D) &&
9563  Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
9564  ExprResult RefRes = DefaultLvalueConversion(Ref);
9565  if (!RefRes.isUsable())
9566  continue;
9567  ExprResult PostUpdateRes =
9568  BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
9569  RefRes.get());
9570  if (!PostUpdateRes.isUsable())
9571  continue;
9572  ExprPostUpdates.push_back(
9573  IgnoredValueConversions(PostUpdateRes.get()).get());
9574  }
9575  }
9576  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
9577  Vars.push_back((VD || CurContext->isDependentContext())
9578  ? RefExpr->IgnoreParens()
9579  : Ref);
9580  SrcExprs.push_back(PseudoSrcExpr);
9581  DstExprs.push_back(PseudoDstExpr);
9582  AssignmentOps.push_back(AssignmentOp.get());
9583  }
9584 
9585  if (Vars.empty())
9586  return nullptr;
9587 
9588  return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
9589  Vars, SrcExprs, DstExprs, AssignmentOps,
9590  buildPreInits(Context, ExprCaptures),
9591  buildPostUpdate(*this, ExprPostUpdates));
9592 }
9593 
9595  SourceLocation StartLoc,
9596  SourceLocation LParenLoc,
9597  SourceLocation EndLoc) {
9599  for (auto &RefExpr : VarList) {
9600  assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
9601  SourceLocation ELoc;
9602  SourceRange ERange;
9603  Expr *SimpleRefExpr = RefExpr;
9604  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
9605  if (Res.second) {
9606  // It will be analyzed later.
9607  Vars.push_back(RefExpr);
9608  }
9609  ValueDecl *D = Res.first;
9610  if (!D)
9611  continue;
9612 
9613  auto *VD = dyn_cast<VarDecl>(D);
9614  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
9615  // in a Construct]
9616  // Variables with the predetermined data-sharing attributes may not be
9617  // listed in data-sharing attributes clauses, except for the cases
9618  // listed below. For these exceptions only, listing a predetermined
9619  // variable in a data-sharing attribute clause is allowed and overrides
9620  // the variable's predetermined data-sharing attributes.
9621  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false);
9622  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
9623  DVar.RefExpr) {
9624  Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
9625  << getOpenMPClauseName(OMPC_shared);
9626  ReportOriginalDSA(*this, DSAStack, D, DVar);
9627  continue;
9628  }
9629 
9630  DeclRefExpr *Ref = nullptr;
9631  if (!VD && IsOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
9632  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
9633  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
9634  Vars.push_back((VD || !Ref || CurContext->isDependentContext())
9635  ? RefExpr->IgnoreParens()
9636  : Ref);
9637  }
9638 
9639  if (Vars.empty())
9640  return nullptr;
9641 
9642  return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
9643 }
9644 
9645 namespace {
9646 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
9647  DSAStackTy *Stack;
9648 
9649 public:
9650  bool VisitDeclRefExpr(DeclRefExpr *E) {
9651  if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) {
9652  DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, false);
9653  if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
9654  return false;
9655  if (DVar.CKind != OMPC_unknown)
9656  return true;
9657  DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
9658  VD, isOpenMPPrivate, [](OpenMPDirectiveKind) -> bool { return true; },
9659  /*FromParent=*/true);
9660  if (DVarPrivate.CKind != OMPC_unknown)
9661  return true;
9662  return false;
9663  }
9664  return false;
9665  }
9666  bool VisitStmt(Stmt *S) {
9667  for (auto Child : S->children()) {
9668  if (Child && Visit(Child))
9669  return true;
9670  }
9671  return false;
9672  }
9673  explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
9674 };
9675 } // namespace
9676 
9677 namespace {
9678 // Transform MemberExpression for specified FieldDecl of current class to
9679 // DeclRefExpr to specified OMPCapturedExprDecl.
9680 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
9681  typedef TreeTransform<TransformExprToCaptures> BaseTransform;
9682  ValueDecl *Field;
9683  DeclRefExpr *CapturedExpr;
9684 
9685 public:
9686  TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
9687  : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
9688 
9689  ExprResult TransformMemberExpr(MemberExpr *E) {
9690  if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
9691  E->getMemberDecl() == Field) {
9692  CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
9693  return CapturedExpr;
9694  }
9695  return BaseTransform::TransformMemberExpr(E);
9696  }
9697  DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
9698 };
9699 } // namespace
9700 
9701 template <typename T>
9703  const llvm::function_ref<T(ValueDecl *)> &Gen) {
9704  for (auto &Set : Lookups) {
9705  for (auto *D : Set) {
9706  if (auto Res = Gen(cast<ValueDecl>(D)))
9707  return Res;
9708  }
9709  }
9710  return T();
9711 }
9712 
9713 static ExprResult
9715  Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
9716  const DeclarationNameInfo &ReductionId, QualType Ty,
9717  CXXCastPath &BasePath, Expr *UnresolvedReduction) {
9718  if (ReductionIdScopeSpec.isInvalid())
9719  return ExprError();
9720  SmallVector<UnresolvedSet<8>, 4> Lookups;
9721  if (S) {
9722  LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
9723  Lookup.suppressDiagnostics();
9724  while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
9725  auto *D = Lookup.getRepresentativeDecl();
9726  do {
9727  S = S->getParent();
9728  } while (S && !S->isDeclScope(D));
9729  if (S)
9730  S = S->getParent();
9731  Lookups.push_back(UnresolvedSet<8>());
9732  Lookups.back().append(Lookup.begin(), Lookup.end());
9733  Lookup.clear();
9734  }
9735  } else if (auto *ULE =
9736  cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
9737  Lookups.push_back(UnresolvedSet<8>());
9738  Decl *PrevD = nullptr;
9739  for (auto *D : ULE->decls()) {
9740  if (D == PrevD)
9741  Lookups.push_back(UnresolvedSet<8>());
9742  else if (auto *DRD = cast<OMPDeclareReductionDecl>(D))
9743  Lookups.back().addDecl(DRD);
9744  PrevD = D;
9745  }
9746  }
9747  if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
9750  filterLookupForUDR<bool>(Lookups, [](ValueDecl *D) -> bool {
9751  return !D->isInvalidDecl() &&
9752  (D->getType()->isDependentType() ||
9755  })) {
9756  UnresolvedSet<8> ResSet;
9757  for (auto &Set : Lookups) {
9758  ResSet.append(Set.begin(), Set.end());
9759  // The last item marks the end of all declarations at the specified scope.
9760  ResSet.addDecl(Set[Set.size() - 1]);
9761  }
9763  SemaRef.Context, /*NamingClass=*/nullptr,
9764  ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
9765  /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
9766  }
9767  if (auto *VD = filterLookupForUDR<ValueDecl *>(
9768  Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
9769  if (!D->isInvalidDecl() &&
9770  SemaRef.Context.hasSameType(D->getType(), Ty))
9771  return D;
9772  return nullptr;
9773  }))
9774  return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc);
9775  if (auto *VD = filterLookupForUDR<ValueDecl *>(
9776  Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
9777  if (!D->isInvalidDecl() &&
9778  SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
9779  !Ty.isMoreQualifiedThan(D->getType()))
9780  return D;
9781  return nullptr;
9782  })) {
9783  CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
9784  /*DetectVirtual=*/false);
9785  if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
9786  if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
9787  VD->getType().getUnqualifiedType()))) {
9788  if (SemaRef.CheckBaseClassAccess(Loc, VD->getType(), Ty, Paths.front(),
9789  /*DiagID=*/0) !=
9791  SemaRef.BuildBasePathArray(Paths, BasePath);
9792  return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc);
9793  }
9794  }
9795  }
9796  }
9797  if (ReductionIdScopeSpec.isSet()) {
9798  SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range;
9799  return ExprError();
9800  }
9801  return ExprEmpty();
9802 }
9803 
9804 namespace {
9805 /// Data for the reduction-based clauses.
9806 struct ReductionData {
9807  /// List of original reduction items.
9809  /// List of private copies of the reduction items.
9811  /// LHS expressions for the reduction_op expressions.
9813  /// RHS expressions for the reduction_op expressions.
9815  /// Reduction operation expression.
9816  SmallVector<Expr *, 8> ReductionOps;
9817  /// Taskgroup descriptors for the corresponding reduction items in
9818  /// in_reduction clauses.
9819  SmallVector<Expr *, 8> TaskgroupDescriptors;
9820  /// List of captures for clause.
9821  SmallVector<Decl *, 4> ExprCaptures;
9822  /// List of postupdate expressions.
9823  SmallVector<Expr *, 4> ExprPostUpdates;
9824  ReductionData() = delete;
9825  /// Reserves required memory for the reduction data.
9826  ReductionData(unsigned Size) {
9827  Vars.reserve(Size);
9828  Privates.reserve(Size);
9829  LHSs.reserve(Size);
9830  RHSs.reserve(Size);
9831  ReductionOps.reserve(Size);
9832  TaskgroupDescriptors.reserve(Size);
9833  ExprCaptures.reserve(Size);
9834  ExprPostUpdates.reserve(Size);
9835  }
9836  /// Stores reduction item and reduction operation only (required for dependent
9837  /// reduction item).
9838  void push(Expr *Item, Expr *ReductionOp) {
9839  Vars.emplace_back(Item);
9840  Privates.emplace_back(nullptr);
9841  LHSs.emplace_back(nullptr);
9842  RHSs.emplace_back(nullptr);
9843  ReductionOps.emplace_back(ReductionOp);
9844  TaskgroupDescriptors.emplace_back(nullptr);
9845  }
9846  /// Stores reduction data.
9847  void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
9848  Expr *TaskgroupDescriptor) {
9849  Vars.emplace_back(Item);
9850  Privates.emplace_back(Private);
9851  LHSs.emplace_back(LHS);
9852  RHSs.emplace_back(RHS);
9853  ReductionOps.emplace_back(ReductionOp);
9854  TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
9855  }
9856 };
9857 } // namespace
9858 
9860  ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
9861  SmallVectorImpl<llvm::APSInt> &ArraySizes) {
9862  const Expr *Length = OASE->getLength();
9863  if (Length == nullptr) {
9864  // For array sections of the form [1:] or [:], we would need to analyze
9865  // the lower bound...
9866  if (OASE->getColonLoc().isValid())
9867  return false;
9868 
9869  // This is an array subscript which has implicit length 1!
9870  SingleElement = true;
9871  ArraySizes.push_back(llvm::APSInt::get(1));
9872  } else {
9873  llvm::APSInt ConstantLengthValue;
9874  if (!Length->EvaluateAsInt(ConstantLengthValue, Context))
9875  return false;
9876 
9877  SingleElement = (ConstantLengthValue.getSExtValue() == 1);
9878  ArraySizes.push_back(ConstantLengthValue);
9879  }
9880 
9881  // Get the base of this array section and walk up from there.
9882  const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
9883 
9884  // We require length = 1 for all array sections except the right-most to
9885  // guarantee that the memory region is contiguous and has no holes in it.
9886  while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
9887  Length = TempOASE->getLength();
9888  if (Length == nullptr) {
9889  // For array sections of the form [1:] or [:], we would need to analyze
9890  // the lower bound...
9891  if (OASE->getColonLoc().isValid())
9892  return false;
9893 
9894  // This is an array subscript which has implicit length 1!
9895  ArraySizes.push_back(llvm::APSInt::get(1));
9896  } else {
9897  llvm::APSInt ConstantLengthValue;
9898  if (!Length->EvaluateAsInt(ConstantLengthValue, Context) ||
9899  ConstantLengthValue.getSExtValue() != 1)
9900  return false;
9901 
9902  ArraySizes.push_back(ConstantLengthValue);
9903  }
9904  Base = TempOASE->getBase()->IgnoreParenImpCasts();
9905  }
9906 
9907  // If we have a single element, we don't need to add the implicit lengths.
9908  if (!SingleElement) {
9909  while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
9910  // Has implicit length 1!
9911  ArraySizes.push_back(llvm::APSInt::get(1));
9912  Base = TempASE->getBase()->IgnoreParenImpCasts();
9913  }
9914  }
9915 
9916  // This array section can be privatized as a single value or as a constant
9917  // sized array.
9918  return true;
9919 }
9920 
9922  Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
9923  ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
9925  CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
9926  ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
9927  auto DN = ReductionId.getName();
9928  auto OOK = DN.getCXXOverloadedOperator();
9929  BinaryOperatorKind BOK = BO_Comma;
9930 
9931  ASTContext &Context = S.Context;
9932  // OpenMP [2.14.3.6, reduction clause]
9933  // C
9934  // reduction-identifier is either an identifier or one of the following
9935  // operators: +, -, *, &, |, ^, && and ||
9936  // C++
9937  // reduction-identifier is either an id-expression or one of the following
9938  // operators: +, -, *, &, |, ^, && and ||
9939  switch (OOK) {
9940  case OO_Plus:
9941  case OO_Minus:
9942  BOK = BO_Add;
9943  break;
9944  case OO_Star:
9945  BOK = BO_Mul;
9946  break;
9947  case OO_Amp:
9948  BOK = BO_And;
9949  break;
9950  case OO_Pipe:
9951  BOK = BO_Or;
9952  break;
9953  case OO_Caret:
9954  BOK = BO_Xor;
9955  break;
9956  case OO_AmpAmp:
9957  BOK = BO_LAnd;
9958  break;
9959  case OO_PipePipe:
9960  BOK = BO_LOr;
9961  break;
9962  case OO_New:
9963  case OO_Delete:
9964  case OO_Array_New:
9965  case OO_Array_Delete:
9966  case OO_Slash:
9967  case OO_Percent:
9968  case OO_Tilde:
9969  case OO_Exclaim:
9970  case OO_Equal:
9971  case OO_Less:
9972  case OO_Greater:
9973  case OO_LessEqual:
9974  case OO_GreaterEqual:
9975  case OO_PlusEqual:
9976  case OO_MinusEqual:
9977  case OO_StarEqual:
9978  case OO_SlashEqual:
9979  case OO_PercentEqual:
9980  case OO_CaretEqual:
9981  case OO_AmpEqual:
9982  case OO_PipeEqual:
9983  case OO_LessLess:
9984  case OO_GreaterGreater:
9985  case OO_LessLessEqual:
9986  case OO_GreaterGreaterEqual:
9987  case OO_EqualEqual:
9988  case OO_ExclaimEqual:
9989  case OO_Spaceship:
9990  case OO_PlusPlus:
9991  case OO_MinusMinus:
9992  case OO_Comma:
9993  case OO_ArrowStar:
9994  case OO_Arrow:
9995  case OO_Call:
9996  case OO_Subscript:
9997  case OO_Conditional:
9998  case OO_Coawait:
10000  llvm_unreachable("Unexpected reduction identifier");
10001  case OO_None:
10002  if (auto *II = DN.getAsIdentifierInfo()) {
10003  if (II->isStr("max"))
10004  BOK = BO_GT;
10005  else if (II->isStr("min"))
10006  BOK = BO_LT;
10007  }
10008  break;
10009  }
10010  SourceRange ReductionIdRange;
10011  if (ReductionIdScopeSpec.isValid())
10012  ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
10013  else
10014  ReductionIdRange.setBegin(ReductionId.getBeginLoc());
10015  ReductionIdRange.setEnd(ReductionId.getEndLoc());
10016 
10017  auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
10018  bool FirstIter = true;
10019  for (auto RefExpr : VarList) {
10020  assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
10021  // OpenMP [2.1, C/C++]
10022  // A list item is a variable or array section, subject to the restrictions
10023  // specified in Section 2.4 on page 42 and in each of the sections
10024  // describing clauses and directives for which a list appears.
10025  // OpenMP [2.14.3.3, Restrictions, p.1]
10026  // A variable that is part of another variable (as an array or
10027  // structure element) cannot appear in a private clause.
10028  if (!FirstIter && IR != ER)
10029  ++IR;
10030  FirstIter = false;
10031  SourceLocation ELoc;
10032  SourceRange ERange;
10033  Expr *SimpleRefExpr = RefExpr;
10034  auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
10035  /*AllowArraySection=*/true);
10036  if (Res.second) {
10037  // Try to find 'declare reduction' corresponding construct before using
10038  // builtin/overloaded operators.
10039  QualType Type = Context.DependentTy;
10040  CXXCastPath BasePath;
10041  ExprResult DeclareReductionRef = buildDeclareReductionRef(
10042  S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
10043  ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
10044  Expr *ReductionOp = nullptr;
10045  if (S.CurContext->isDependentContext() &&
10046  (DeclareReductionRef.isUnset() ||
10047  isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
10048  ReductionOp = DeclareReductionRef.get();
10049  // It will be analyzed later.
10050  RD.push(RefExpr, ReductionOp);
10051  }
10052  ValueDecl *D = Res.first;
10053  if (!D)
10054  continue;
10055 
10056  Expr *TaskgroupDescriptor = nullptr;
10057  QualType Type;
10058  auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
10059  auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
10060  if (ASE)
10061  Type = ASE->getType().getNonReferenceType();
10062  else if (OASE) {
10063  auto BaseType = OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
10064  if (auto *ATy = BaseType->getAsArrayTypeUnsafe())
10065  Type = ATy->getElementType();
10066  else
10067  Type = BaseType->getPointeeType();
10068  Type = Type.getNonReferenceType();
10069  } else
10070  Type = Context.getBaseElementType(D->getType().getNonReferenceType());
10071  auto *VD = dyn_cast<VarDecl>(D);
10072 
10073  // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
10074  // A variable that appears in a private clause must not have an incomplete
10075  // type or a reference type.
10076  if (S.RequireCompleteType(ELoc, Type,
10077  diag::err_omp_reduction_incomplete_type))
10078  continue;
10079  // OpenMP [2.14.3.6, reduction clause, Restrictions]
10080  // A list item that appears in a reduction clause must not be
10081  // const-qualified.
10082  if (Type.getNonReferenceType().isConstant(Context)) {
10083  S.Diag(ELoc, diag::err_omp_const_reduction_list_item) << ERange;
10084  if (!ASE && !OASE) {
10085  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
10087  S.Diag(D->getLocation(),
10088  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10089  << D;
10090  }
10091  continue;
10092  }
10093  // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
10094  // If a list-item is a reference type then it must bind to the same object
10095  // for all threads of the team.
10096  if (!ASE && !OASE && VD) {
10097  VarDecl *VDDef = VD->getDefinition();
10098  if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
10099  DSARefChecker Check(Stack);
10100  if (Check.Visit(VDDef->getInit())) {
10101  S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
10102  << getOpenMPClauseName(ClauseKind) << ERange;
10103  S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
10104  continue;
10105  }
10106  }
10107  }
10108 
10109  // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
10110  // in a Construct]
10111  // Variables with the predetermined data-sharing attributes may not be
10112  // listed in data-sharing attributes clauses, except for the cases
10113  // listed below. For these exceptions only, listing a predetermined
10114  // variable in a data-sharing attribute clause is allowed and overrides
10115  // the variable's predetermined data-sharing attributes.
10116  // OpenMP [2.14.3.6, Restrictions, p.3]
10117  // Any number of reduction clauses can be specified on the directive,
10118  // but a list item can appear only once in the reduction clauses for that
10119  // directive.
10120  DSAStackTy::DSAVarData DVar;
10121  DVar = Stack->getTopDSA(D, false);
10122  if (DVar.CKind == OMPC_reduction) {
10123  S.Diag(ELoc, diag::err_omp_once_referenced)
10124  << getOpenMPClauseName(ClauseKind);
10125  if (DVar.RefExpr)
10126  S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
10127  continue;
10128  } else if (DVar.CKind != OMPC_unknown) {
10129  S.Diag(ELoc, diag::err_omp_wrong_dsa)
10130  << getOpenMPClauseName(DVar.CKind)
10131  << getOpenMPClauseName(OMPC_reduction);
10132  ReportOriginalDSA(S, Stack, D, DVar);
10133  continue;
10134  }
10135 
10136  // OpenMP [2.14.3.6, Restrictions, p.1]
10137  // A list item that appears in a reduction clause of a worksharing
10138  // construct must be shared in the parallel regions to which any of the
10139  // worksharing regions arising from the worksharing construct bind.
10140  OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
10141  if (isOpenMPWorksharingDirective(CurrDir) &&
10142  !isOpenMPParallelDirective(CurrDir) &&
10143  !isOpenMPTeamsDirective(CurrDir)) {
10144  DVar = Stack->getImplicitDSA(D, true);
10145  if (DVar.CKind != OMPC_shared) {
10146  S.Diag(ELoc, diag::err_omp_required_access)
10147  << getOpenMPClauseName(OMPC_reduction)
10148  << getOpenMPClauseName(OMPC_shared);
10149  ReportOriginalDSA(S, Stack, D, DVar);
10150  continue;
10151  }
10152  }
10153 
10154  // Try to find 'declare reduction' corresponding construct before using
10155  // builtin/overloaded operators.
10156  CXXCastPath BasePath;
10157  ExprResult DeclareReductionRef = buildDeclareReductionRef(
10158  S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
10159  ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
10160  if (DeclareReductionRef.isInvalid())
10161  continue;
10162  if (S.CurContext->isDependentContext() &&
10163  (DeclareReductionRef.isUnset() ||
10164  isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
10165  RD.push(RefExpr, DeclareReductionRef.get());
10166  continue;
10167  }
10168  if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
10169  // Not allowed reduction identifier is found.
10170  S.Diag(ReductionId.getLocStart(),
10171  diag::err_omp_unknown_reduction_identifier)
10172  << Type << ReductionIdRange;
10173  continue;
10174  }
10175 
10176  // OpenMP [2.14.3.6, reduction clause, Restrictions]
10177  // The type of a list item that appears in a reduction clause must be valid
10178  // for the reduction-identifier. For a max or min reduction in C, the type
10179  // of the list item must be an allowed arithmetic data type: char, int,
10180  // float, double, or _Bool, possibly modified with long, short, signed, or
10181  // unsigned. For a max or min reduction in C++, the type of the list item
10182  // must be an allowed arithmetic data type: char, wchar_t, int, float,
10183  // double, or bool, possibly modified with long, short, signed, or unsigned.
10184  if (DeclareReductionRef.isUnset()) {
10185  if ((BOK == BO_GT || BOK == BO_LT) &&
10186  !(Type->isScalarType() ||
10187  (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
10188  S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
10189  << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
10190  if (!ASE && !OASE) {
10191  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
10193  S.Diag(D->getLocation(),
10194  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10195  << D;
10196  }
10197  continue;
10198  }
10199  if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
10200  !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
10201  S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
10202  << getOpenMPClauseName(ClauseKind);
10203  if (!ASE && !OASE) {
10204  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
10206  S.Diag(D->getLocation(),
10207  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10208  << D;
10209  }
10210  continue;
10211  }
10212  }
10213 
10214  Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
10215  auto *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
10216  D->hasAttrs() ? &D->getAttrs() : nullptr);
10217  auto *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
10218  D->hasAttrs() ? &D->getAttrs() : nullptr);
10219  auto PrivateTy = Type;
10220 
10221  // Try if we can determine constant lengths for all array sections and avoid
10222  // the VLA.
10223  bool ConstantLengthOASE = false;
10224  if (OASE) {
10225  bool SingleElement;
10227  ConstantLengthOASE = CheckOMPArraySectionConstantForReduction(
10228  Context, OASE, SingleElement, ArraySizes);
10229 
10230  // If we don't have a single element, we must emit a constant array type.
10231  if (ConstantLengthOASE && !SingleElement) {
10232  for (auto &Size : ArraySizes) {
10233  PrivateTy = Context.getConstantArrayType(
10234  PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0);
10235  }
10236  }
10237  }
10238 
10239  if ((OASE && !ConstantLengthOASE) ||
10240  (!OASE && !ASE &&
10242  if (!Context.getTargetInfo().isVLASupported() &&
10244  S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
10245  S.Diag(ELoc, diag::note_vla_unsupported);
10246  continue;
10247  }
10248  // For arrays/array sections only:
10249  // Create pseudo array type for private copy. The size for this array will
10250  // be generated during codegen.
10251  // For array subscripts or single variables Private Ty is the same as Type
10252  // (type of the variable or single array element).
10253  PrivateTy = Context.getVariableArrayType(
10254  Type,
10255  new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue),
10256  ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
10257  } else if (!ASE && !OASE &&
10258  Context.getAsArrayType(D->getType().getNonReferenceType()))
10259  PrivateTy = D->getType().getNonReferenceType();
10260  // Private copy.
10261  auto *PrivateVD = buildVarDecl(S, ELoc, PrivateTy, D->getName(),
10262  D->hasAttrs() ? &D->getAttrs() : nullptr);
10263  // Add initializer for private variable.
10264  Expr *Init = nullptr;
10265  auto *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
10266  auto *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
10267  if (DeclareReductionRef.isUsable()) {
10268  auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
10269  auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
10270  if (DRD->getInitializer()) {
10271  Init = DRDRef;
10272  RHSVD->setInit(DRDRef);
10273  RHSVD->setInitStyle(VarDecl::CallInit);
10274  }
10275  } else {
10276  switch (BOK) {
10277  case BO_Add:
10278  case BO_Xor:
10279  case BO_Or:
10280  case BO_LOr:
10281  // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
10282  if (Type->isScalarType() || Type->isAnyComplexType())
10283  Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
10284  break;
10285  case BO_Mul:
10286  case BO_LAnd:
10287  if (Type->isScalarType() || Type->isAnyComplexType()) {
10288  // '*' and '&&' reduction ops - initializer is '1'.
10289  Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
10290  }
10291  break;
10292  case BO_And: {
10293  // '&' reduction op - initializer is '~0'.
10294  QualType OrigType = Type;
10295  if (auto *ComplexTy = OrigType->getAs<ComplexType>())
10296  Type = ComplexTy->getElementType();
10297  if (Type->isRealFloatingType()) {
10298  llvm::APFloat InitValue =
10299  llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type),
10300  /*isIEEE=*/true);
10301  Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
10302  Type, ELoc);
10303  } else if (Type->isScalarType()) {
10304  auto Size = Context.getTypeSize(Type);
10305  QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
10306  llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
10307  Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
10308  }
10309  if (Init && OrigType->isAnyComplexType()) {
10310  // Init = 0xFFFF + 0xFFFFi;
10311  auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
10312  Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
10313  }
10314  Type = OrigType;
10315  break;
10316  }
10317  case BO_LT:
10318  case BO_GT: {
10319  // 'min' reduction op - initializer is 'Largest representable number in
10320  // the reduction list item type'.
10321  // 'max' reduction op - initializer is 'Least representable number in
10322  // the reduction list item type'.
10323  if (Type->isIntegerType() || Type->isPointerType()) {
10324  bool IsSigned = Type->hasSignedIntegerRepresentation();
10325  auto Size = Context.getTypeSize(Type);
10326  QualType IntTy =
10327  Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
10328  llvm::APInt InitValue =
10329  (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
10330  : llvm::APInt::getMinValue(Size)
10331  : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
10332  : llvm::APInt::getMaxValue(Size);
10333  Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
10334  if (Type->isPointerType()) {
10335  // Cast to pointer type.
10336  auto CastExpr = S.BuildCStyleCastExpr(
10337  ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
10338  if (CastExpr.isInvalid())
10339  continue;
10340  Init = CastExpr.get();
10341  }
10342  } else if (Type->isRealFloatingType()) {
10343  llvm::APFloat InitValue = llvm::APFloat::getLargest(
10344  Context.getFloatTypeSemantics(Type), BOK != BO_LT);
10345  Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
10346  Type, ELoc);
10347  }
10348  break;
10349  }
10350  case BO_PtrMemD:
10351  case BO_PtrMemI:
10352  case BO_MulAssign:
10353  case BO_Div:
10354  case BO_Rem:
10355  case BO_Sub:
10356  case BO_Shl:
10357  case BO_Shr:
10358  case BO_LE:
10359  case BO_GE:
10360  case BO_EQ:
10361  case BO_NE:
10362  case BO_Cmp:
10363  case BO_AndAssign:
10364  case BO_XorAssign:
10365  case BO_OrAssign:
10366  case BO_Assign:
10367  case BO_AddAssign:
10368  case BO_SubAssign:
10369  case BO_DivAssign:
10370  case BO_RemAssign:
10371  case BO_ShlAssign:
10372  case BO_ShrAssign:
10373  case BO_Comma:
10374  llvm_unreachable("Unexpected reduction operation");
10375  }
10376  }
10377  if (Init && DeclareReductionRef.isUnset())
10378  S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
10379  else if (!Init)
10380  S.ActOnUninitializedDecl(RHSVD);
10381  if (RHSVD->isInvalidDecl())
10382  continue;
10383  if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) {
10384  S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
10385  << Type << ReductionIdRange;
10386  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
10388  S.Diag(D->getLocation(),
10389  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10390  << D;
10391  continue;
10392  }
10393  // Store initializer for single element in private copy. Will be used during
10394  // codegen.
10395  PrivateVD->setInit(RHSVD->getInit());
10396  PrivateVD->setInitStyle(RHSVD->getInitStyle());
10397  auto *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
10398  ExprResult ReductionOp;
10399  if (DeclareReductionRef.isUsable()) {
10400  QualType RedTy = DeclareReductionRef.get()->getType();
10401  QualType PtrRedTy = Context.getPointerType(RedTy);
10402  ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
10403  ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
10404  if (!BasePath.empty()) {
10405  LHS = S.DefaultLvalueConversion(LHS.get());
10406  RHS = S.DefaultLvalueConversion(RHS.get());
10407  LHS = ImplicitCastExpr::Create(Context, PtrRedTy,
10408  CK_UncheckedDerivedToBase, LHS.get(),
10409  &BasePath, LHS.get()->getValueKind());
10410  RHS = ImplicitCastExpr::Create(Context, PtrRedTy,
10411  CK_UncheckedDerivedToBase, RHS.get(),
10412  &BasePath, RHS.get()->getValueKind());
10413  }
10415  QualType Params[] = {PtrRedTy, PtrRedTy};
10416  QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
10417  auto *OVE = new (Context) OpaqueValueExpr(
10418  ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary,
10419  S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
10420  Expr *Args[] = {LHS.get(), RHS.get()};
10421  ReductionOp = new (Context)
10422  CallExpr(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc);
10423  } else {
10424  ReductionOp = S.BuildBinOp(
10425  Stack->getCurScope(), ReductionId.getLocStart(), BOK, LHSDRE, RHSDRE);
10426  if (ReductionOp.isUsable()) {
10427  if (BOK != BO_LT && BOK != BO_GT) {
10428  ReductionOp =
10429  S.BuildBinOp(Stack->getCurScope(), ReductionId.getLocStart(),
10430  BO_Assign, LHSDRE, ReductionOp.get());
10431  } else {
10432  auto *ConditionalOp = new (Context)
10433  ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE,
10434  Type, VK_LValue, OK_Ordinary);
10435  ReductionOp =
10436  S.BuildBinOp(Stack->getCurScope(), ReductionId.getLocStart(),
10437  BO_Assign, LHSDRE, ConditionalOp);
10438  }
10439  if (ReductionOp.isUsable())
10440  ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get());
10441  }
10442  if (!ReductionOp.isUsable())
10443  continue;
10444  }
10445 
10446  // OpenMP [2.15.4.6, Restrictions, p.2]
10447  // A list item that appears in an in_reduction clause of a task construct
10448  // must appear in a task_reduction clause of a construct associated with a
10449  // taskgroup region that includes the participating task in its taskgroup
10450  // set. The construct associated with the innermost region that meets this
10451  // condition must specify the same reduction-identifier as the in_reduction
10452  // clause.
10453  if (ClauseKind == OMPC_in_reduction) {
10454  SourceRange ParentSR;
10455  BinaryOperatorKind ParentBOK;
10456  const Expr *ParentReductionOp;
10457  Expr *ParentBOKTD, *ParentReductionOpTD;
10458  DSAStackTy::DSAVarData ParentBOKDSA =
10459  Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
10460  ParentBOKTD);
10461  DSAStackTy::DSAVarData ParentReductionOpDSA =
10462  Stack->getTopMostTaskgroupReductionData(
10463  D, ParentSR, ParentReductionOp, ParentReductionOpTD);
10464  bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
10465  bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
10466  if (!IsParentBOK && !IsParentReductionOp) {
10467  S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction);
10468  continue;
10469  }
10470  if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
10471  (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK ||
10472  IsParentReductionOp) {
10473  bool EmitError = true;
10474  if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
10475  llvm::FoldingSetNodeID RedId, ParentRedId;
10476  ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
10477  DeclareReductionRef.get()->Profile(RedId, Context,
10478  /*Canonical=*/true);
10479  EmitError = RedId != ParentRedId;
10480  }
10481  if (EmitError) {
10482  S.Diag(ReductionId.getLocStart(),
10483  diag::err_omp_reduction_identifier_mismatch)
10484  << ReductionIdRange << RefExpr->getSourceRange();
10485  S.Diag(ParentSR.getBegin(),
10486  diag::note_omp_previous_reduction_identifier)
10487  << ParentSR
10488  << (IsParentBOK ? ParentBOKDSA.RefExpr
10489  : ParentReductionOpDSA.RefExpr)
10490  ->getSourceRange();
10491  continue;
10492  }
10493  }
10494  TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
10495  assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined.");
10496  }
10497 
10498  DeclRefExpr *Ref = nullptr;
10499  Expr *VarsExpr = RefExpr->IgnoreParens();
10500  if (!VD && !S.CurContext->isDependentContext()) {
10501  if (ASE || OASE) {
10502  TransformExprToCaptures RebuildToCapture(S, D);
10503  VarsExpr =
10504  RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
10505  Ref = RebuildToCapture.getCapturedExpr();
10506  } else {
10507  VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
10508  }
10509  if (!S.IsOpenMPCapturedDecl(D)) {
10510  RD.ExprCaptures.emplace_back(Ref->getDecl());
10511  if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
10512  ExprResult RefRes = S.DefaultLvalueConversion(Ref);
10513  if (!RefRes.isUsable())
10514  continue;
10515  ExprResult PostUpdateRes =
10516  S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
10517  RefRes.get());
10518  if (!PostUpdateRes.isUsable())
10519  continue;
10520  if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
10521  Stack->getCurrentDirective() == OMPD_taskgroup) {
10522  S.Diag(RefExpr->getExprLoc(),
10523  diag::err_omp_reduction_non_addressable_expression)
10524  << RefExpr->getSourceRange();
10525  continue;
10526  }
10527  RD.ExprPostUpdates.emplace_back(
10528  S.IgnoredValueConversions(PostUpdateRes.get()).get());
10529  }
10530  }
10531  }
10532  // All reduction items are still marked as reduction (to do not increase
10533  // code base size).
10534  Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref);
10535  if (CurrDir == OMPD_taskgroup) {
10536  if (DeclareReductionRef.isUsable())
10537  Stack->addTaskgroupReductionData(D, ReductionIdRange,
10538  DeclareReductionRef.get());
10539  else
10540  Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
10541  }
10542  RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
10543  TaskgroupDescriptor);
10544  }
10545  return RD.Vars.empty();
10546 }
10547 
10549  ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
10551  CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
10552  ArrayRef<Expr *> UnresolvedReductions) {
10553  ReductionData RD(VarList.size());
10554 
10555  if (ActOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList,
10556  StartLoc, LParenLoc, ColonLoc, EndLoc,
10557  ReductionIdScopeSpec, ReductionId,
10558  UnresolvedReductions, RD))
10559  return nullptr;
10560 
10562  Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
10563  ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
10564  RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
10565  buildPreInits(Context, RD.ExprCaptures),
10566  buildPostUpdate(*this, RD.ExprPostUpdates));
10567 }
10568 
10570  ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
10572  CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
10573  ArrayRef<Expr *> UnresolvedReductions) {
10574  ReductionData RD(VarList.size());
10575 
10576  if (ActOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction,
10577  VarList, StartLoc, LParenLoc, ColonLoc,
10578  EndLoc, ReductionIdScopeSpec, ReductionId,
10579  UnresolvedReductions, RD))
10580  return nullptr;
10581 
10583  Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
10584  ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
10585  RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
10586  buildPreInits(Context, RD.ExprCaptures),
10587  buildPostUpdate(*this, RD.ExprPostUpdates));
10588 }
10589 
10591  ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
10593  CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
10594  ArrayRef<Expr *> UnresolvedReductions) {
10595  ReductionData RD(VarList.size());
10596 
10597  if (ActOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList,
10598  StartLoc, LParenLoc, ColonLoc, EndLoc,
10599  ReductionIdScopeSpec, ReductionId,
10600  UnresolvedReductions, RD))
10601  return nullptr;
10602 
10604  Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
10605  ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
10606  RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
10607  buildPreInits(Context, RD.ExprCaptures),
10608  buildPostUpdate(*this, RD.ExprPostUpdates));
10609 }
10610 
10612  SourceLocation LinLoc) {
10613  if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
10614  LinKind == OMPC_LINEAR_unknown) {
10615  Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
10616  return true;
10617  }
10618  return false;
10619 }
10620 
10622  OpenMPLinearClauseKind LinKind,
10623  QualType Type) {
10624  auto *VD = dyn_cast_or_null<VarDecl>(D);
10625  // A variable must not have an incomplete type or a reference type.
10626  if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
10627  return true;
10628  if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
10629  !Type->isReferenceType()) {
10630  Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
10631  << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
10632  return true;
10633  }
10634  Type = Type.getNonReferenceType();
10635 
10636  // A list item must not be const-qualified.
10637  if (Type.isConstant(Context)) {
10638  Diag(ELoc, diag::err_omp_const_variable)
10639  << getOpenMPClauseName(OMPC_linear);
10640  if (D) {
10641  bool IsDecl =
10642  !VD ||
10643  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
10644  Diag(D->getLocation(),
10645  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10646  << D;
10647  }
10648  return true;
10649  }
10650 
10651  // A list item must be of integral or pointer type.
10652  Type = Type.getUnqualifiedType().getCanonicalType();
10653  const auto *Ty = Type.getTypePtrOrNull();
10654  if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
10655  !Ty->isPointerType())) {
10656  Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
10657  if (D) {
10658  bool IsDecl =
10659  !VD ||
10660  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
10661  Diag(D->getLocation(),
10662  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10663  << D;
10664  }
10665  return true;
10666  }
10667  return false;
10668 }
10669 
10671  ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
10672  SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
10677  SmallVector<Decl *, 4> ExprCaptures;
10678  SmallVector<Expr *, 4> ExprPostUpdates;
10679  if (CheckOpenMPLinearModifier(LinKind, LinLoc))
10680  LinKind = OMPC_LINEAR_val;
10681  for (auto &RefExpr : VarList) {
10682  assert(RefExpr && "NULL expr in OpenMP linear clause.");
10683  SourceLocation ELoc;
10684  SourceRange ERange;
10685  Expr *SimpleRefExpr = RefExpr;
10686  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
10687  /*AllowArraySection=*/false);
10688  if (Res.second) {
10689  // It will be analyzed later.
10690  Vars.push_back(RefExpr);
10691  Privates.push_back(nullptr);
10692  Inits.push_back(nullptr);
10693  }
10694  ValueDecl *D = Res.first;
10695  if (!D)
10696  continue;
10697 
10698  QualType Type = D->getType();
10699  auto *VD = dyn_cast<VarDecl>(D);
10700 
10701  // OpenMP [2.14.3.7, linear clause]
10702  // A list-item cannot appear in more than one linear clause.
10703  // A list-item that appears in a linear clause cannot appear in any
10704  // other data-sharing attribute clause.
10705  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false);
10706  if (DVar.RefExpr) {
10707  Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
10708  << getOpenMPClauseName(OMPC_linear);
10709  ReportOriginalDSA(*this, DSAStack, D, DVar);
10710  continue;
10711  }
10712 
10713  if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
10714  continue;
10716 
10717  // Build private copy of original var.
10718  auto *Private = buildVarDecl(*this, ELoc, Type, D->getName(),
10719  D->hasAttrs() ? &D->getAttrs() : nullptr);
10720  auto *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
10721  // Build var to save initial value.
10722  VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
10723  Expr *InitExpr;
10724  DeclRefExpr *Ref = nullptr;
10725  if (!VD && !CurContext->isDependentContext()) {
10726  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
10727  if (!IsOpenMPCapturedDecl(D)) {
10728  ExprCaptures.push_back(Ref->getDecl());
10729  if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
10730  ExprResult RefRes = DefaultLvalueConversion(Ref);
10731  if (!RefRes.isUsable())
10732  continue;
10733  ExprResult PostUpdateRes =
10734  BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
10735  SimpleRefExpr, RefRes.get());
10736  if (!PostUpdateRes.isUsable())
10737  continue;
10738  ExprPostUpdates.push_back(
10739  IgnoredValueConversions(PostUpdateRes.get()).get());
10740  }
10741  }
10742  }
10743  if (LinKind == OMPC_LINEAR_uval)
10744  InitExpr = VD ? VD->getInit() : SimpleRefExpr;
10745  else
10746  InitExpr = VD ? SimpleRefExpr : Ref;
10747  AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
10748  /*DirectInit=*/false);
10749  auto InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
10750 
10751  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
10752  Vars.push_back((VD || CurContext->isDependentContext())
10753  ? RefExpr->IgnoreParens()
10754  : Ref);
10755  Privates.push_back(PrivateRef);
10756  Inits.push_back(InitRef);
10757  }
10758 
10759  if (Vars.empty())
10760  return nullptr;
10761 
10762  Expr *StepExpr = Step;
10763  Expr *CalcStepExpr = nullptr;
10764  if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
10765  !Step->isInstantiationDependent() &&
10767  SourceLocation StepLoc = Step->getLocStart();
10768  ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
10769  if (Val.isInvalid())
10770  return nullptr;
10771  StepExpr = Val.get();
10772 
10773  // Build var to save the step value.
10774  VarDecl *SaveVar =
10775  buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
10776  ExprResult SaveRef =
10777  buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
10779  BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
10780  CalcStep = ActOnFinishFullExpr(CalcStep.get());
10781 
10782  // Warn about zero linear step (it would be probably better specified as
10783  // making corresponding variables 'const').
10784  llvm::APSInt Result;
10785  bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context);
10786  if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive())
10787  Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0]
10788  << (Vars.size() > 1);
10789  if (!IsConstant && CalcStep.isUsable()) {
10790  // Calculate the step beforehand instead of doing this on each iteration.
10791  // (This is not used if the number of iterations may be kfold-ed).
10792  CalcStepExpr = CalcStep.get();
10793  }
10794  }
10795 
10796  return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
10797  ColonLoc, EndLoc, Vars, Privates, Inits,
10798  StepExpr, CalcStepExpr,
10799  buildPreInits(Context, ExprCaptures),
10800  buildPostUpdate(*this, ExprPostUpdates));
10801 }
10802 
10804  Expr *NumIterations, Sema &SemaRef,
10805  Scope *S, DSAStackTy *Stack) {
10806  // Walk the vars and build update/final expressions for the CodeGen.
10809  Expr *Step = Clause.getStep();
10810  Expr *CalcStep = Clause.getCalcStep();
10811  // OpenMP [2.14.3.7, linear clause]
10812  // If linear-step is not specified it is assumed to be 1.
10813  if (Step == nullptr)
10814  Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
10815  else if (CalcStep) {
10816  Step = cast<BinaryOperator>(CalcStep)->getLHS();
10817  }
10818  bool HasErrors = false;
10819  auto CurInit = Clause.inits().begin();
10820  auto CurPrivate = Clause.privates().begin();
10821  auto LinKind = Clause.getModifier();
10822  for (auto &RefExpr : Clause.varlists()) {
10823  SourceLocation ELoc;
10824  SourceRange ERange;
10825  Expr *SimpleRefExpr = RefExpr;
10826  auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange,
10827  /*AllowArraySection=*/false);
10828  ValueDecl *D = Res.first;
10829  if (Res.second || !D) {
10830  Updates.push_back(nullptr);
10831  Finals.push_back(nullptr);
10832  HasErrors = true;
10833  continue;
10834  }
10835  auto &&Info = Stack->isLoopControlVariable(D);
10836  // OpenMP [2.15.11, distribute simd Construct]
10837  // A list item may not appear in a linear clause, unless it is the loop
10838  // iteration variable.
10839  if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
10840  isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
10841  SemaRef.Diag(ELoc,
10842  diag::err_omp_linear_distribute_var_non_loop_iteration);
10843  Updates.push_back(nullptr);
10844  Finals.push_back(nullptr);
10845  HasErrors = true;
10846  continue;
10847  }
10848  Expr *InitExpr = *CurInit;
10849 
10850  // Build privatized reference to the current linear var.
10851  auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
10852  Expr *CapturedRef;
10853  if (LinKind == OMPC_LINEAR_uval)
10854  CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
10855  else
10856  CapturedRef =
10857  buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
10858  DE->getType().getUnqualifiedType(), DE->getExprLoc(),
10859  /*RefersToCapture=*/true);
10860 
10861  // Build update: Var = InitExpr + IV * Step
10863  if (!Info.first) {
10864  Update =
10865  BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate,
10866  InitExpr, IV, Step, /* Subtract */ false);
10867  } else
10868  Update = *CurPrivate;
10869  Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getLocStart(),
10870  /*DiscardedValue=*/true);
10871 
10872  // Build final: Var = InitExpr + NumIterations * Step
10873  ExprResult Final;
10874  if (!Info.first) {
10875  Final = BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
10876  InitExpr, NumIterations, Step,
10877  /* Subtract */ false);
10878  } else
10879  Final = *CurPrivate;
10880  Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getLocStart(),
10881  /*DiscardedValue=*/true);
10882 
10883  if (!Update.isUsable() || !Final.isUsable()) {
10884  Updates.push_back(nullptr);
10885  Finals.push_back(nullptr);
10886  HasErrors = true;
10887  } else {
10888  Updates.push_back(Update.get());
10889  Finals.push_back(Final.get());
10890  }
10891  ++CurInit;
10892  ++CurPrivate;
10893  }
10894  Clause.setUpdates(Updates);
10895  Clause.setFinals(Finals);
10896  return HasErrors;
10897 }
10898 
10900  ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
10902 
10904  for (auto &RefExpr : VarList) {
10905  assert(RefExpr && "NULL expr in OpenMP linear clause.");
10906  SourceLocation ELoc;
10907  SourceRange ERange;
10908  Expr *SimpleRefExpr = RefExpr;
10909  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
10910  /*AllowArraySection=*/false);
10911  if (Res.second) {
10912  // It will be analyzed later.
10913  Vars.push_back(RefExpr);
10914  }
10915  ValueDecl *D = Res.first;
10916  if (!D)
10917  continue;
10918 
10919  QualType QType = D->getType();
10920  auto *VD = dyn_cast<VarDecl>(D);
10921 
10922  // OpenMP [2.8.1, simd construct, Restrictions]
10923  // The type of list items appearing in the aligned clause must be
10924  // array, pointer, reference to array, or reference to pointer.
10926  const Type *Ty = QType.getTypePtrOrNull();
10927  if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
10928  Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
10929  << QType << getLangOpts().CPlusPlus << ERange;
10930  bool IsDecl =
10931  !VD ||
10932  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
10933  Diag(D->getLocation(),
10934  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10935  << D;
10936  continue;
10937  }
10938 
10939  // OpenMP [2.8.1, simd construct, Restrictions]
10940  // A list-item cannot appear in more than one aligned clause.
10941  if (Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
10942  Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange;
10943  Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
10944  << getOpenMPClauseName(OMPC_aligned);
10945  continue;
10946  }
10947 
10948  DeclRefExpr *Ref = nullptr;
10949  if (!VD && IsOpenMPCapturedDecl(D))
10950  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
10951  Vars.push_back(DefaultFunctionArrayConversion(
10952  (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
10953  .get());
10954  }
10955 
10956  // OpenMP [2.8.1, simd construct, Description]
10957  // The parameter of the aligned clause, alignment, must be a constant
10958  // positive integer expression.
10959  // If no optional parameter is specified, implementation-defined default
10960  // alignments for SIMD instructions on the target platforms are assumed.
10961  if (Alignment != nullptr) {
10962  ExprResult AlignResult =
10963  VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
10964  if (AlignResult.isInvalid())
10965  return nullptr;
10966  Alignment = AlignResult.get();
10967  }
10968  if (Vars.empty())
10969  return nullptr;
10970 
10971  return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
10972  EndLoc, Vars, Alignment);
10973 }
10974 
10976  SourceLocation StartLoc,
10977  SourceLocation LParenLoc,
10978  SourceLocation EndLoc) {
10980  SmallVector<Expr *, 8> SrcExprs;
10981  SmallVector<Expr *, 8> DstExprs;
10982  SmallVector<Expr *, 8> AssignmentOps;
10983  for (auto &RefExpr : VarList) {
10984  assert(RefExpr && "NULL expr in OpenMP copyin clause.");
10985  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
10986  // It will be analyzed later.
10987  Vars.push_back(RefExpr);
10988  SrcExprs.push_back(nullptr);
10989  DstExprs.push_back(nullptr);
10990  AssignmentOps.push_back(nullptr);
10991  continue;
10992  }
10993 
10994  SourceLocation ELoc = RefExpr->getExprLoc();
10995  // OpenMP [2.1, C/C++]
10996  // A list item is a variable name.
10997  // OpenMP [2.14.4.1, Restrictions, p.1]
10998  // A list item that appears in a copyin clause must be threadprivate.
10999  DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr);
11000  if (!DE || !isa<VarDecl>(DE->getDecl())) {
11001  Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
11002  << 0 << RefExpr->getSourceRange();
11003  continue;
11004  }
11005 
11006  Decl *D = DE->getDecl();
11007  VarDecl *VD = cast<VarDecl>(D);
11008 
11009  QualType Type = VD->getType();
11010  if (Type->isDependentType() || Type->isInstantiationDependentType()) {
11011  // It will be analyzed later.
11012  Vars.push_back(DE);
11013  SrcExprs.push_back(nullptr);
11014  DstExprs.push_back(nullptr);
11015  AssignmentOps.push_back(nullptr);
11016  continue;
11017  }
11018 
11019  // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
11020  // A list item that appears in a copyin clause must be threadprivate.
11021  if (!DSAStack->isThreadPrivate(VD)) {
11022  Diag(ELoc, diag::err_omp_required_access)
11023  << getOpenMPClauseName(OMPC_copyin)
11024  << getOpenMPDirectiveName(OMPD_threadprivate);
11025  continue;
11026  }
11027 
11028  // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
11029  // A variable of class type (or array thereof) that appears in a
11030  // copyin clause requires an accessible, unambiguous copy assignment
11031  // operator for the class type.
11032  auto ElemType = Context.getBaseElementType(Type).getNonReferenceType();
11033  auto *SrcVD =
11034  buildVarDecl(*this, DE->getLocStart(), ElemType.getUnqualifiedType(),
11035  ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
11036  auto *PseudoSrcExpr = buildDeclRefExpr(
11037  *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
11038  auto *DstVD =
11039  buildVarDecl(*this, DE->getLocStart(), ElemType, ".copyin.dst",
11040  VD->hasAttrs() ? &VD->getAttrs() : nullptr);
11041  auto *PseudoDstExpr =
11042  buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
11043  // For arrays generate assignment operation for single element and replace
11044  // it by the original array element in CodeGen.
11045  auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign,
11046  PseudoDstExpr, PseudoSrcExpr);
11047  if (AssignmentOp.isInvalid())
11048  continue;
11049  AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
11050  /*DiscardedValue=*/true);
11051  if (AssignmentOp.isInvalid())
11052  continue;
11053 
11054  DSAStack->addDSA(VD, DE, OMPC_copyin);
11055  Vars.push_back(DE);
11056  SrcExprs.push_back(PseudoSrcExpr);
11057  DstExprs.push_back(PseudoDstExpr);
11058  AssignmentOps.push_back(AssignmentOp.get());
11059  }
11060 
11061  if (Vars.empty())
11062  return nullptr;
11063 
11064  return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
11065  SrcExprs, DstExprs, AssignmentOps);
11066 }
11067 
11069  SourceLocation StartLoc,
11070  SourceLocation LParenLoc,
11071  SourceLocation EndLoc) {
11073  SmallVector<Expr *, 8> SrcExprs;
11074  SmallVector<Expr *, 8> DstExprs;
11075  SmallVector<Expr *, 8> AssignmentOps;
11076  for (auto &RefExpr : VarList) {
11077  assert(RefExpr && "NULL expr in OpenMP linear clause.");
11078  SourceLocation ELoc;
11079  SourceRange ERange;
11080  Expr *SimpleRefExpr = RefExpr;
11081  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
11082  /*AllowArraySection=*/false);
11083  if (Res.second) {
11084  // It will be analyzed later.
11085  Vars.push_back(RefExpr);
11086  SrcExprs.push_back(nullptr);
11087  DstExprs.push_back(nullptr);
11088  AssignmentOps.push_back(nullptr);
11089  }
11090  ValueDecl *D = Res.first;
11091  if (!D)
11092  continue;
11093 
11094  QualType Type = D->getType();
11095  auto *VD = dyn_cast<VarDecl>(D);
11096 
11097  // OpenMP [2.14.4.2, Restrictions, p.2]
11098  // A list item that appears in a copyprivate clause may not appear in a
11099  // private or firstprivate clause on the single construct.
11100  if (!VD || !DSAStack->isThreadPrivate(VD)) {
11101  auto DVar = DSAStack->getTopDSA(D, false);
11102  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
11103  DVar.RefExpr) {
11104  Diag(ELoc, diag::err_omp_wrong_dsa)
11105  << getOpenMPClauseName(DVar.CKind)
11106  << getOpenMPClauseName(OMPC_copyprivate);
11107  ReportOriginalDSA(*this, DSAStack, D, DVar);
11108  continue;
11109  }
11110 
11111  // OpenMP [2.11.4.2, Restrictions, p.1]
11112  // All list items that appear in a copyprivate clause must be either
11113  // threadprivate or private in the enclosing context.
11114  if (DVar.CKind == OMPC_unknown) {
11115  DVar = DSAStack->getImplicitDSA(D, false);
11116  if (DVar.CKind == OMPC_shared) {
11117  Diag(ELoc, diag::err_omp_required_access)
11118  << getOpenMPClauseName(OMPC_copyprivate)
11119  << "threadprivate or private in the enclosing context";
11120  ReportOriginalDSA(*this, DSAStack, D, DVar);
11121  continue;
11122  }
11123  }
11124  }
11125 
11126  // Variably modified types are not supported.
11127  if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
11128  Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
11129  << getOpenMPClauseName(OMPC_copyprivate) << Type
11130  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
11131  bool IsDecl =
11132  !VD ||
11133  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
11134  Diag(D->getLocation(),
11135  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11136  << D;
11137  continue;
11138  }
11139 
11140  // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
11141  // A variable of class type (or array thereof) that appears in a
11142  // copyin clause requires an accessible, unambiguous copy assignment
11143  // operator for the class type.
11144  Type = Context.getBaseElementType(Type.getNonReferenceType())
11145  .getUnqualifiedType();
11146  auto *SrcVD =
11147  buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.src",
11148  D->hasAttrs() ? &D->getAttrs() : nullptr);
11149  auto *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
11150  auto *DstVD =
11151  buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.dst",
11152  D->hasAttrs() ? &D->getAttrs() : nullptr);
11153  auto *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
11154  auto AssignmentOp = BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
11155  PseudoDstExpr, PseudoSrcExpr);
11156  if (AssignmentOp.isInvalid())
11157  continue;
11158  AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc,
11159  /*DiscardedValue=*/true);
11160  if (AssignmentOp.isInvalid())
11161  continue;
11162 
11163  // No need to mark vars as copyprivate, they are already threadprivate or
11164  // implicitly private.
11165  assert(VD || IsOpenMPCapturedDecl(D));
11166  Vars.push_back(
11167  VD ? RefExpr->IgnoreParens()
11168  : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
11169  SrcExprs.push_back(PseudoSrcExpr);
11170  DstExprs.push_back(PseudoDstExpr);
11171  AssignmentOps.push_back(AssignmentOp.get());
11172  }
11173 
11174  if (Vars.empty())
11175  return nullptr;
11176 
11177  return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
11178  Vars, SrcExprs, DstExprs, AssignmentOps);
11179 }
11180 
11182  SourceLocation StartLoc,
11183  SourceLocation LParenLoc,
11184  SourceLocation EndLoc) {
11185  if (VarList.empty())
11186  return nullptr;
11187 
11188  return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
11189 }
11190 
11191 OMPClause *
11194  ArrayRef<Expr *> VarList, SourceLocation StartLoc,
11195  SourceLocation LParenLoc, SourceLocation EndLoc) {
11196  if (DSAStack->getCurrentDirective() == OMPD_ordered &&
11197  DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
11198  Diag(DepLoc, diag::err_omp_unexpected_clause_value)
11199  << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
11200  return nullptr;
11201  }
11202  if (DSAStack->getCurrentDirective() != OMPD_ordered &&
11203  (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
11204  DepKind == OMPC_DEPEND_sink)) {
11205  unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink};
11206  Diag(DepLoc, diag::err_omp_unexpected_clause_value)
11207  << getListOfPossibleValues(OMPC_depend, /*First=*/0,
11208  /*Last=*/OMPC_DEPEND_unknown, Except)
11209  << getOpenMPClauseName(OMPC_depend);
11210  return nullptr;
11211  }
11214  llvm::APSInt DepCounter(/*BitWidth=*/32);
11215  llvm::APSInt TotalDepCount(/*BitWidth=*/32);
11216  if (DepKind == OMPC_DEPEND_sink) {
11217  if (auto *OrderedCountExpr = DSAStack->getParentOrderedRegionParam()) {
11218  TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
11219  TotalDepCount.setIsUnsigned(/*Val=*/true);
11220  }
11221  }
11222  if ((DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) ||
11223  DSAStack->getParentOrderedRegionParam()) {
11224  for (auto &RefExpr : VarList) {
11225  assert(RefExpr && "NULL expr in OpenMP shared clause.");
11226  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
11227  // It will be analyzed later.
11228  Vars.push_back(RefExpr);
11229  continue;
11230  }
11231 
11232  SourceLocation ELoc = RefExpr->getExprLoc();
11233  auto *SimpleExpr = RefExpr->IgnoreParenCasts();
11234  if (DepKind == OMPC_DEPEND_sink) {
11235  if (DepCounter >= TotalDepCount) {
11236  Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
11237  continue;
11238  }
11239  ++DepCounter;
11240  // OpenMP [2.13.9, Summary]
11241  // depend(dependence-type : vec), where dependence-type is:
11242  // 'sink' and where vec is the iteration vector, which has the form:
11243  // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
11244  // where n is the value specified by the ordered clause in the loop
11245  // directive, xi denotes the loop iteration variable of the i-th nested
11246  // loop associated with the loop directive, and di is a constant
11247  // non-negative integer.
11248  if (CurContext->isDependentContext()) {
11249  // It will be analyzed later.
11250  Vars.push_back(RefExpr);
11251  continue;
11252  }
11253  SimpleExpr = SimpleExpr->IgnoreImplicit();
11255  SourceLocation OOLoc;
11256  Expr *LHS = SimpleExpr;
11257  Expr *RHS = nullptr;
11258  if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
11259  OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
11260  OOLoc = BO->getOperatorLoc();
11261  LHS = BO->getLHS()->IgnoreParenImpCasts();
11262  RHS = BO->getRHS()->IgnoreParenImpCasts();
11263  } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
11264  OOK = OCE->getOperator();
11265  OOLoc = OCE->getOperatorLoc();
11266  LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
11267  RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
11268  } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
11269  OOK = MCE->getMethodDecl()
11270  ->getNameInfo()
11271  .getName()
11272  .getCXXOverloadedOperator();
11273  OOLoc = MCE->getCallee()->getExprLoc();
11274  LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
11275  RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
11276  }
11277  SourceLocation ELoc;
11278  SourceRange ERange;
11279  auto Res = getPrivateItem(*this, LHS, ELoc, ERange,
11280  /*AllowArraySection=*/false);
11281  if (Res.second) {
11282  // It will be analyzed later.
11283  Vars.push_back(RefExpr);
11284  }
11285  ValueDecl *D = Res.first;
11286  if (!D)
11287  continue;
11288 
11289  if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
11290  Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
11291  continue;
11292  }
11293  if (RHS) {
11294  ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
11295  RHS, OMPC_depend, /*StrictlyPositive=*/false);
11296  if (RHSRes.isInvalid())
11297  continue;
11298  }
11299  if (!CurContext->isDependentContext() &&
11300  DSAStack->getParentOrderedRegionParam() &&
11301  DepCounter != DSAStack->isParentLoopControlVariable(D).first) {
11302  ValueDecl* VD = DSAStack->getParentLoopControlVariable(
11303  DepCounter.getZExtValue());
11304  if (VD) {
11305  Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
11306  << 1 << VD;
11307  } else {
11308  Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
11309  }
11310  continue;
11311  }
11312  OpsOffs.push_back({RHS, OOK});
11313  } else {
11314  auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
11315  if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
11316  (ASE &&
11317  !ASE->getBase()
11318  ->getType()
11319  .getNonReferenceType()
11320  ->isPointerType() &&
11321  !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
11322  Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
11323  << RefExpr->getSourceRange();
11324  continue;
11325  }
11326  bool Suppress = getDiagnostics().getSuppressAllDiagnostics();
11327  getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
11328  ExprResult Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
11329  RefExpr->IgnoreParenImpCasts());
11330  getDiagnostics().setSuppressAllDiagnostics(Suppress);
11331  if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) {
11332  Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
11333  << RefExpr->getSourceRange();
11334  continue;
11335  }
11336  }
11337  Vars.push_back(RefExpr->IgnoreParenImpCasts());
11338  }
11339 
11340  if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
11341  TotalDepCount > VarList.size() &&
11342  DSAStack->getParentOrderedRegionParam() &&
11343  DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
11344  Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) << 1
11345  << DSAStack->getParentLoopControlVariable(VarList.size() + 1);
11346  }
11347  if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
11348  Vars.empty())
11349  return nullptr;
11350  }
11351  auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
11352  DepKind, DepLoc, ColonLoc, Vars);
11353  if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source)
11354  DSAStack->addDoacrossDependClause(C, OpsOffs);
11355  return C;
11356 }
11357 
11359  SourceLocation LParenLoc,
11360  SourceLocation EndLoc) {
11361  Expr *ValExpr = Device;
11362  Stmt *HelperValStmt = nullptr;
11363 
11364  // OpenMP [2.9.1, Restrictions]
11365  // The device expression must evaluate to a non-negative integer value.
11366  if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
11367  /*StrictlyPositive=*/false))
11368  return nullptr;
11369 
11370  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
11371  OpenMPDirectiveKind CaptureRegion =
11372  getOpenMPCaptureRegionForClause(DKind, OMPC_device);
11373  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
11374  ValExpr = MakeFullExpr(ValExpr).get();
11375  llvm::MapVector<Expr *, DeclRefExpr *> Captures;
11376  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
11377  HelperValStmt = buildPreInits(Context, Captures);
11378  }
11379 
11380  return new (Context)
11381  OMPDeviceClause(ValExpr, HelperValStmt, StartLoc, LParenLoc, EndLoc);
11382 }
11383 
11384 static bool CheckTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
11385  DSAStackTy *Stack, QualType QTy) {
11386  NamedDecl *ND;
11387  if (QTy->isIncompleteType(&ND)) {
11388  SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR;
11389  return false;
11390  }
11391  return true;
11392 }
11393 
11394 /// \brief Return true if it can be proven that the provided array expression
11395 /// (array section or array subscript) does NOT specify the whole size of the
11396 /// array whose base type is \a BaseQTy.
11398  const Expr *E,
11399  QualType BaseQTy) {
11400  auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
11401 
11402  // If this is an array subscript, it refers to the whole size if the size of
11403  // the dimension is constant and equals 1. Also, an array section assumes the
11404  // format of an array subscript if no colon is used.
11405  if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) {
11406  if (auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
11407  return ATy->getSize().getSExtValue() != 1;
11408  // Size can't be evaluated statically.
11409  return false;
11410  }
11411 
11412  assert(OASE && "Expecting array section if not an array subscript.");
11413  auto *LowerBound = OASE->getLowerBound();
11414  auto *Length = OASE->getLength();
11415 
11416  // If there is a lower bound that does not evaluates to zero, we are not
11417  // covering the whole dimension.
11418  if (LowerBound) {
11419  llvm::APSInt ConstLowerBound;
11420  if (!LowerBound->EvaluateAsInt(ConstLowerBound, SemaRef.getASTContext()))
11421  return false; // Can't get the integer value as a constant.
11422  if (ConstLowerBound.getSExtValue())
11423  return true;
11424  }
11425 
11426  // If we don't have a length we covering the whole dimension.
11427  if (!Length)
11428  return false;
11429 
11430  // If the base is a pointer, we don't have a way to get the size of the
11431  // pointee.
11432  if (BaseQTy->isPointerType())
11433  return false;
11434 
11435  // We can only check if the length is the same as the size of the dimension
11436  // if we have a constant array.
11437  auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
11438  if (!CATy)
11439  return false;
11440 
11441  llvm::APSInt ConstLength;
11442  if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext()))
11443  return false; // Can't get the integer value as a constant.
11444 
11445  return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
11446 }
11447 
11448 // Return true if it can be proven that the provided array expression (array
11449 // section or array subscript) does NOT specify a single element of the array
11450 // whose base type is \a BaseQTy.
11452  const Expr *E,
11453  QualType BaseQTy) {
11454  auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
11455 
11456  // An array subscript always refer to a single element. Also, an array section
11457  // assumes the format of an array subscript if no colon is used.
11458  if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid()))
11459  return false;
11460 
11461  assert(OASE && "Expecting array section if not an array subscript.");
11462  auto *Length = OASE->getLength();
11463 
11464  // If we don't have a length we have to check if the array has unitary size
11465  // for this dimension. Also, we should always expect a length if the base type
11466  // is pointer.
11467  if (!Length) {
11468  if (auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
11469  return ATy->getSize().getSExtValue() != 1;
11470  // We cannot assume anything.
11471  return false;
11472  }
11473 
11474  // Check if the length evaluates to 1.
11475  llvm::APSInt ConstLength;
11476  if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext()))
11477  return false; // Can't get the integer value as a constant.
11478 
11479  return ConstLength.getSExtValue() != 1;
11480 }
11481 
11482 // Return the expression of the base of the mappable expression or null if it
11483 // cannot be determined and do all the necessary checks to see if the expression
11484 // is valid as a standalone mappable expression. In the process, record all the
11485 // components of the expression.
11487  Sema &SemaRef, Expr *E,
11489  OpenMPClauseKind CKind, bool NoDiagnose) {
11490  SourceLocation ELoc = E->getExprLoc();
11491  SourceRange ERange = E->getSourceRange();
11492 
11493  // The base of elements of list in a map clause have to be either:
11494  // - a reference to variable or field.
11495  // - a member expression.
11496  // - an array expression.
11497  //
11498  // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
11499  // reference to 'r'.
11500  //
11501  // If we have:
11502  //
11503  // struct SS {
11504  // Bla S;
11505  // foo() {
11506  // #pragma omp target map (S.Arr[:12]);
11507  // }
11508  // }
11509  //
11510  // We want to retrieve the member expression 'this->S';
11511 
11512  Expr *RelevantExpr = nullptr;
11513 
11514  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2]
11515  // If a list item is an array section, it must specify contiguous storage.
11516  //
11517  // For this restriction it is sufficient that we make sure only references
11518  // to variables or fields and array expressions, and that no array sections
11519  // exist except in the rightmost expression (unless they cover the whole
11520  // dimension of the array). E.g. these would be invalid:
11521  //
11522  // r.ArrS[3:5].Arr[6:7]
11523  //
11524  // r.ArrS[3:5].x
11525  //
11526  // but these would be valid:
11527  // r.ArrS[3].Arr[6:7]
11528  //
11529  // r.ArrS[3].x
11530 
11531  bool AllowUnitySizeArraySection = true;
11532  bool AllowWholeSizeArraySection = true;
11533 
11534  while (!RelevantExpr) {
11535  E = E->IgnoreParenImpCasts();
11536 
11537  if (auto *CurE = dyn_cast<DeclRefExpr>(E)) {
11538  if (!isa<VarDecl>(CurE->getDecl()))
11539  return nullptr;
11540 
11541  RelevantExpr = CurE;
11542 
11543  // If we got a reference to a declaration, we should not expect any array
11544  // section before that.
11545  AllowUnitySizeArraySection = false;
11546  AllowWholeSizeArraySection = false;
11547 
11548  // Record the component.
11549  CurComponents.emplace_back(CurE, CurE->getDecl());
11550  } else if (auto *CurE = dyn_cast<MemberExpr>(E)) {
11551  auto *BaseE = CurE->getBase()->IgnoreParenImpCasts();
11552 
11553  if (isa<CXXThisExpr>(BaseE))
11554  // We found a base expression: this->Val.
11555  RelevantExpr = CurE;
11556  else
11557  E = BaseE;
11558 
11559  if (!isa<FieldDecl>(CurE->getMemberDecl())) {
11560  if (!NoDiagnose) {
11561  SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
11562  << CurE->getSourceRange();
11563  return nullptr;
11564  }
11565  if (RelevantExpr)
11566  return nullptr;
11567  continue;
11568  }
11569 
11570  auto *FD = cast<FieldDecl>(CurE->getMemberDecl());
11571 
11572  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
11573  // A bit-field cannot appear in a map clause.
11574  //
11575  if (FD->isBitField()) {
11576  if (!NoDiagnose) {
11577  SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
11578  << CurE->getSourceRange() << getOpenMPClauseName(CKind);
11579  return nullptr;
11580  }
11581  if (RelevantExpr)
11582  return nullptr;
11583  continue;
11584  }
11585 
11586  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
11587  // If the type of a list item is a reference to a type T then the type
11588  // will be considered to be T for all purposes of this clause.
11589  QualType CurType = BaseE->getType().getNonReferenceType();
11590 
11591  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
11592  // A list item cannot be a variable that is a member of a structure with
11593  // a union type.
11594  //
11595  if (auto *RT = CurType->getAs<RecordType>()) {
11596  if (RT->isUnionType()) {
11597  if (!NoDiagnose) {
11598  SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
11599  << CurE->getSourceRange();
11600  return nullptr;
11601  }
11602  continue;
11603  }
11604  }
11605 
11606  // If we got a member expression, we should not expect any array section
11607  // before that:
11608  //
11609  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
11610  // If a list item is an element of a structure, only the rightmost symbol
11611  // of the variable reference can be an array section.
11612  //
11613  AllowUnitySizeArraySection = false;
11614  AllowWholeSizeArraySection = false;
11615 
11616  // Record the component.
11617  CurComponents.emplace_back(CurE, FD);
11618  } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) {
11619  E = CurE->getBase()->IgnoreParenImpCasts();
11620 
11621  if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
11622  if (!NoDiagnose) {
11623  SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
11624  << 0 << CurE->getSourceRange();
11625  return nullptr;
11626  }
11627  continue;
11628  }
11629 
11630  // If we got an array subscript that express the whole dimension we
11631  // can have any array expressions before. If it only expressing part of
11632  // the dimension, we can only have unitary-size array expressions.
11634  E->getType()))
11635  AllowWholeSizeArraySection = false;
11636 
11637  // Record the component - we don't have any declaration associated.
11638  CurComponents.emplace_back(CurE, nullptr);
11639  } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) {
11640  assert(!NoDiagnose && "Array sections cannot be implicitly mapped.");
11641  E = CurE->getBase()->IgnoreParenImpCasts();
11642 
11643  QualType CurType =
11645 
11646  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
11647  // If the type of a list item is a reference to a type T then the type
11648  // will be considered to be T for all purposes of this clause.
11649  if (CurType->isReferenceType())
11650  CurType = CurType->getPointeeType();
11651 
11652  bool IsPointer = CurType->isAnyPointerType();
11653 
11654  if (!IsPointer && !CurType->isArrayType()) {
11655  SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
11656  << 0 << CurE->getSourceRange();
11657  return nullptr;
11658  }
11659 
11660  bool NotWhole =
11661  CheckArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType);
11662  bool NotUnity =
11663  CheckArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType);
11664 
11665  if (AllowWholeSizeArraySection) {
11666  // Any array section is currently allowed. Allowing a whole size array
11667  // section implies allowing a unity array section as well.
11668  //
11669  // If this array section refers to the whole dimension we can still
11670  // accept other array sections before this one, except if the base is a
11671  // pointer. Otherwise, only unitary sections are accepted.
11672  if (NotWhole || IsPointer)
11673  AllowWholeSizeArraySection = false;
11674  } else if (AllowUnitySizeArraySection && NotUnity) {
11675  // A unity or whole array section is not allowed and that is not
11676  // compatible with the properties of the current array section.
11677  SemaRef.Diag(
11678  ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
11679  << CurE->getSourceRange();
11680  return nullptr;
11681  }
11682 
11683  // Record the component - we don't have any declaration associated.
11684  CurComponents.emplace_back(CurE, nullptr);
11685  } else {
11686  if (!NoDiagnose) {
11687  // If nothing else worked, this is not a valid map clause expression.
11688  SemaRef.Diag(
11689  ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
11690  << ERange;
11691  }
11692  return nullptr;
11693  }
11694  }
11695 
11696  return RelevantExpr;
11697 }
11698 
11699 // Return true if expression E associated with value VD has conflicts with other
11700 // map information.
11701 static bool CheckMapConflicts(
11702  Sema &SemaRef, DSAStackTy *DSAS, ValueDecl *VD, Expr *E,
11703  bool CurrentRegionOnly,
11705  OpenMPClauseKind CKind) {
11706  assert(VD && E);
11707  SourceLocation ELoc = E->getExprLoc();
11708  SourceRange ERange = E->getSourceRange();
11709 
11710  // In order to easily check the conflicts we need to match each component of
11711  // the expression under test with the components of the expressions that are
11712  // already in the stack.
11713 
11714  assert(!CurComponents.empty() && "Map clause expression with no components!");
11715  assert(CurComponents.back().getAssociatedDeclaration() == VD &&
11716  "Map clause expression with unexpected base!");
11717 
11718  // Variables to help detecting enclosing problems in data environment nests.
11719  bool IsEnclosedByDataEnvironmentExpr = false;
11720  const Expr *EnclosingExpr = nullptr;
11721 
11722  bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
11723  VD, CurrentRegionOnly,
11725  StackComponents,
11726  OpenMPClauseKind) -> bool {
11727 
11728  assert(!StackComponents.empty() &&
11729  "Map clause expression with no components!");
11730  assert(StackComponents.back().getAssociatedDeclaration() == VD &&
11731  "Map clause expression with unexpected base!");
11732 
11733  // The whole expression in the stack.
11734  auto *RE = StackComponents.front().getAssociatedExpression();
11735 
11736  // Expressions must start from the same base. Here we detect at which
11737  // point both expressions diverge from each other and see if we can
11738  // detect if the memory referred to both expressions is contiguous and
11739  // do not overlap.
11740  auto CI = CurComponents.rbegin();
11741  auto CE = CurComponents.rend();
11742  auto SI = StackComponents.rbegin();
11743  auto SE = StackComponents.rend();
11744  for (; CI != CE && SI != SE; ++CI, ++SI) {
11745 
11746  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
11747  // At most one list item can be an array item derived from a given
11748  // variable in map clauses of the same construct.
11749  if (CurrentRegionOnly &&
11750  (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
11751  isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) &&
11752  (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
11753  isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) {
11754  SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
11755  diag::err_omp_multiple_array_items_in_map_clause)
11756  << CI->getAssociatedExpression()->getSourceRange();
11757  SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
11758  diag::note_used_here)
11759  << SI->getAssociatedExpression()->getSourceRange();
11760  return true;
11761  }
11762 
11763  // Do both expressions have the same kind?
11764  if (CI->getAssociatedExpression()->getStmtClass() !=
11765  SI->getAssociatedExpression()->getStmtClass())
11766  break;
11767 
11768  // Are we dealing with different variables/fields?
11769  if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
11770  break;
11771  }
11772  // Check if the extra components of the expressions in the enclosing
11773  // data environment are redundant for the current base declaration.
11774  // If they are, the maps completely overlap, which is legal.
11775  for (; SI != SE; ++SI) {
11776  QualType Type;
11777  if (auto *ASE =
11778  dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
11779  Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
11780  } else if (auto *OASE = dyn_cast<OMPArraySectionExpr>(
11781  SI->getAssociatedExpression())) {
11782  auto *E = OASE->getBase()->IgnoreParenImpCasts();
11783  Type =
11785  }
11786  if (Type.isNull() || Type->isAnyPointerType() ||
11788  SemaRef, SI->getAssociatedExpression(), Type))
11789  break;
11790  }
11791 
11792  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
11793  // List items of map clauses in the same construct must not share
11794  // original storage.
11795  //
11796  // If the expressions are exactly the same or one is a subset of the
11797  // other, it means they are sharing storage.
11798  if (CI == CE && SI == SE) {
11799  if (CurrentRegionOnly) {
11800  if (CKind == OMPC_map)
11801  SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
11802  else {
11803  assert(CKind == OMPC_to || CKind == OMPC_from);
11804  SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
11805  << ERange;
11806  }
11807  SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
11808  << RE->getSourceRange();
11809  return true;
11810  } else {
11811  // If we find the same expression in the enclosing data environment,
11812  // that is legal.
11813  IsEnclosedByDataEnvironmentExpr = true;
11814  return false;
11815  }
11816  }
11817 
11818  QualType DerivedType =
11819  std::prev(CI)->getAssociatedDeclaration()->getType();
11820  SourceLocation DerivedLoc =
11821  std::prev(CI)->getAssociatedExpression()->getExprLoc();
11822 
11823  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
11824  // If the type of a list item is a reference to a type T then the type
11825  // will be considered to be T for all purposes of this clause.
11826  DerivedType = DerivedType.getNonReferenceType();
11827 
11828  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
11829  // A variable for which the type is pointer and an array section
11830  // derived from that variable must not appear as list items of map
11831  // clauses of the same construct.
11832  //
11833  // Also, cover one of the cases in:
11834  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
11835  // If any part of the original storage of a list item has corresponding
11836  // storage in the device data environment, all of the original storage
11837  // must have corresponding storage in the device data environment.
11838  //
11839  if (DerivedType->isAnyPointerType()) {
11840  if (CI == CE || SI == SE) {
11841  SemaRef.Diag(
11842  DerivedLoc,
11843  diag::err_omp_pointer_mapped_along_with_derived_section)
11844  << DerivedLoc;
11845  } else {
11846  assert(CI != CE && SI != SE);
11847  SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_derreferenced)
11848  << DerivedLoc;
11849  }
11850  SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
11851  << RE->getSourceRange();
11852  return true;
11853  }
11854 
11855  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
11856  // List items of map clauses in the same construct must not share
11857  // original storage.
11858  //
11859  // An expression is a subset of the other.
11860  if (CurrentRegionOnly && (CI == CE || SI == SE)) {
11861  if (CKind == OMPC_map)
11862  SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
11863  else {
11864  assert(CKind == OMPC_to || CKind == OMPC_from);
11865  SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
11866  << ERange;
11867  }
11868  SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
11869  << RE->getSourceRange();
11870  return true;
11871  }
11872 
11873  // The current expression uses the same base as other expression in the
11874  // data environment but does not contain it completely.
11875  if (!CurrentRegionOnly && SI != SE)
11876  EnclosingExpr = RE;
11877 
11878  // The current expression is a subset of the expression in the data
11879  // environment.
11880  IsEnclosedByDataEnvironmentExpr |=
11881  (!CurrentRegionOnly && CI != CE && SI == SE);
11882 
11883  return false;
11884  });
11885 
11886  if (CurrentRegionOnly)
11887  return FoundError;
11888 
11889  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
11890  // If any part of the original storage of a list item has corresponding
11891  // storage in the device data environment, all of the original storage must
11892  // have corresponding storage in the device data environment.
11893  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
11894  // If a list item is an element of a structure, and a different element of
11895  // the structure has a corresponding list item in the device data environment
11896  // prior to a task encountering the construct associated with the map clause,
11897  // then the list item must also have a corresponding list item in the device
11898  // data environment prior to the task encountering the construct.
11899  //
11900  if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
11901  SemaRef.Diag(ELoc,
11902  diag::err_omp_original_storage_is_shared_and_does_not_contain)
11903  << ERange;
11904  SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
11905  << EnclosingExpr->getSourceRange();
11906  return true;
11907  }
11908 
11909  return FoundError;
11910 }
11911 
11912 namespace {
11913 // Utility struct that gathers all the related lists associated with a mappable
11914 // expression.
11915 struct MappableVarListInfo final {
11916  // The list of expressions.
11917  ArrayRef<Expr *> VarList;
11918  // The list of processed expressions.
11919  SmallVector<Expr *, 16> ProcessedVarList;
11920  // The mappble components for each expression.
11922  // The base declaration of the variable.
11923  SmallVector<ValueDecl *, 16> VarBaseDeclarations;
11924 
11925  MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
11926  // We have a list of components and base declarations for each entry in the
11927  // variable list.
11928  VarComponents.reserve(VarList.size());
11929  VarBaseDeclarations.reserve(VarList.size());
11930  }
11931 };
11932 }
11933 
11934 // Check the validity of the provided variable list for the provided clause kind
11935 // \a CKind. In the check process the valid expressions, and mappable expression
11936 // components and variables are extracted and used to fill \a Vars,
11937 // \a ClauseComponents, and \a ClauseBaseDeclarations. \a MapType and
11938 // \a IsMapTypeImplicit are expected to be valid if the clause kind is 'map'.
11939 static void
11940 checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS,
11941  OpenMPClauseKind CKind, MappableVarListInfo &MVLI,
11942  SourceLocation StartLoc,
11944  bool IsMapTypeImplicit = false) {
11945  // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
11946  assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
11947  "Unexpected clause kind with mappable expressions!");
11948 
11949  // Keep track of the mappable components and base declarations in this clause.
11950  // Each entry in the list is going to have a list of components associated. We
11951  // record each set of the components so that we can build the clause later on.
11952  // In the end we should have the same amount of declarations and component
11953  // lists.
11954 
11955  for (auto &RE : MVLI.VarList) {
11956  assert(RE && "Null expr in omp to/from/map clause");
11957  SourceLocation ELoc = RE->getExprLoc();
11958 
11959  auto *VE = RE->IgnoreParenLValueCasts();
11960 
11961  if (VE->isValueDependent() || VE->isTypeDependent() ||
11962  VE->isInstantiationDependent() ||
11963  VE->containsUnexpandedParameterPack()) {
11964  // We can only analyze this information once the missing information is
11965  // resolved.
11966  MVLI.ProcessedVarList.push_back(RE);
11967  continue;
11968  }
11969 
11970  auto *SimpleExpr = RE->IgnoreParenCasts();
11971 
11972  if (!RE->IgnoreParenImpCasts()->isLValue()) {
11973  SemaRef.Diag(ELoc,
11974  diag::err_omp_expected_named_var_member_or_array_expression)
11975  << RE->getSourceRange();
11976  continue;
11977  }
11978 
11980  ValueDecl *CurDeclaration = nullptr;
11981 
11982  // Obtain the array or member expression bases if required. Also, fill the
11983  // components array with all the components identified in the process.
11984  auto *BE = CheckMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents,
11985  CKind, /*NoDiagnose=*/false);
11986  if (!BE)
11987  continue;
11988 
11989  assert(!CurComponents.empty() &&
11990  "Invalid mappable expression information.");
11991 
11992  // For the following checks, we rely on the base declaration which is
11993  // expected to be associated with the last component. The declaration is
11994  // expected to be a variable or a field (if 'this' is being mapped).
11995  CurDeclaration = CurComponents.back().getAssociatedDeclaration();
11996  assert(CurDeclaration && "Null decl on map clause.");
11997  assert(
11998  CurDeclaration->isCanonicalDecl() &&
11999  "Expecting components to have associated only canonical declarations.");
12000 
12001  auto *VD = dyn_cast<VarDecl>(CurDeclaration);
12002  auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
12003 
12004  assert((VD || FD) && "Only variables or fields are expected here!");
12005  (void)FD;
12006 
12007  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
12008  // threadprivate variables cannot appear in a map clause.
12009  // OpenMP 4.5 [2.10.5, target update Construct]
12010  // threadprivate variables cannot appear in a from clause.
12011  if (VD && DSAS->isThreadPrivate(VD)) {
12012  auto DVar = DSAS->getTopDSA(VD, false);
12013  SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
12014  << getOpenMPClauseName(CKind);
12015  ReportOriginalDSA(SemaRef, DSAS, VD, DVar);
12016  continue;
12017  }
12018 
12019  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
12020  // A list item cannot appear in both a map clause and a data-sharing
12021  // attribute clause on the same construct.
12022 
12023  // Check conflicts with other map clause expressions. We check the conflicts
12024  // with the current construct separately from the enclosing data
12025  // environment, because the restrictions are different. We only have to
12026  // check conflicts across regions for the map clauses.
12027  if (CheckMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
12028  /*CurrentRegionOnly=*/true, CurComponents, CKind))
12029  break;
12030  if (CKind == OMPC_map &&
12031  CheckMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
12032  /*CurrentRegionOnly=*/false, CurComponents, CKind))
12033  break;
12034 
12035  // OpenMP 4.5 [2.10.5, target update Construct]
12036  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
12037  // If the type of a list item is a reference to a type T then the type will
12038  // be considered to be T for all purposes of this clause.
12039  QualType Type = CurDeclaration->getType().getNonReferenceType();
12040 
12041  // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
12042  // A list item in a to or from clause must have a mappable type.
12043  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
12044  // A list item must have a mappable type.
12045  if (!CheckTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
12046  DSAS, Type))
12047  continue;
12048 
12049  if (CKind == OMPC_map) {
12050  // target enter data
12051  // OpenMP [2.10.2, Restrictions, p. 99]
12052  // A map-type must be specified in all map clauses and must be either
12053  // to or alloc.
12054  OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
12055  if (DKind == OMPD_target_enter_data &&
12056  !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
12057  SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
12058  << (IsMapTypeImplicit ? 1 : 0)
12059  << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
12060  << getOpenMPDirectiveName(DKind);
12061  continue;
12062  }
12063 
12064  // target exit_data
12065  // OpenMP [2.10.3, Restrictions, p. 102]
12066  // A map-type must be specified in all map clauses and must be either
12067  // from, release, or delete.
12068  if (DKind == OMPD_target_exit_data &&
12069  !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
12070  MapType == OMPC_MAP_delete)) {
12071  SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
12072  << (IsMapTypeImplicit ? 1 : 0)
12073  << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
12074  << getOpenMPDirectiveName(DKind);
12075  continue;
12076  }
12077 
12078  // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
12079  // A list item cannot appear in both a map clause and a data-sharing
12080  // attribute clause on the same construct
12081  if ((DKind == OMPD_target || DKind == OMPD_target_teams ||
12082  DKind == OMPD_target_teams_distribute ||
12083  DKind == OMPD_target_teams_distribute_parallel_for ||
12084  DKind == OMPD_target_teams_distribute_parallel_for_simd ||
12085  DKind == OMPD_target_teams_distribute_simd) && VD) {
12086  auto DVar = DSAS->getTopDSA(VD, false);
12087  if (isOpenMPPrivate(DVar.CKind)) {
12088  SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
12089  << getOpenMPClauseName(DVar.CKind)
12090  << getOpenMPClauseName(OMPC_map)
12091  << getOpenMPDirectiveName(DSAS->getCurrentDirective());
12092  ReportOriginalDSA(SemaRef, DSAS, CurDeclaration, DVar);
12093  continue;
12094  }
12095  }
12096  }
12097 
12098  // Save the current expression.
12099  MVLI.ProcessedVarList.push_back(RE);
12100 
12101  // Store the components in the stack so that they can be used to check
12102  // against other clauses later on.
12103  DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
12104  /*WhereFoundClauseKind=*/OMPC_map);
12105 
12106  // Save the components and declaration to create the clause. For purposes of
12107  // the clause creation, any component list that has has base 'this' uses
12108  // null as base declaration.
12109  MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
12110  MVLI.VarComponents.back().append(CurComponents.begin(),
12111  CurComponents.end());
12112  MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
12113  : CurDeclaration);
12114  }
12115 }
12116 
12117 OMPClause *
12119  OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
12121  ArrayRef<Expr *> VarList, SourceLocation StartLoc,
12122  SourceLocation LParenLoc, SourceLocation EndLoc) {
12123  MappableVarListInfo MVLI(VarList);
12124  checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, StartLoc,
12125  MapType, IsMapTypeImplicit);
12126 
12127  // We need to produce a map clause even if we don't have variables so that
12128  // other diagnostics related with non-existing map clauses are accurate.
12129  return OMPMapClause::Create(Context, StartLoc, LParenLoc, EndLoc,
12130  MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
12131  MVLI.VarComponents, MapTypeModifier, MapType,
12132  IsMapTypeImplicit, MapLoc);
12133 }
12134 
12137  assert(ParsedType.isUsable());
12138 
12139  QualType ReductionType = GetTypeFromParser(ParsedType.get());
12140  if (ReductionType.isNull())
12141  return QualType();
12142 
12143  // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
12144  // A type name in a declare reduction directive cannot be a function type, an
12145  // array type, a reference type, or a type qualified with const, volatile or
12146  // restrict.
12147  if (ReductionType.hasQualifiers()) {
12148  Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
12149  return QualType();
12150  }
12151 
12152  if (ReductionType->isFunctionType()) {
12153  Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
12154  return QualType();
12155  }
12156  if (ReductionType->isReferenceType()) {
12157  Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
12158  return QualType();
12159  }
12160  if (ReductionType->isArrayType()) {
12161  Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
12162  return QualType();
12163  }
12164  return ReductionType;
12165 }
12166 
12168  Scope *S, DeclContext *DC, DeclarationName Name,
12169  ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
12170  AccessSpecifier AS, Decl *PrevDeclInScope) {
12171  SmallVector<Decl *, 8> Decls;
12172  Decls.reserve(ReductionTypes.size());
12173 
12174  LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
12175  forRedeclarationInCurContext());
12176  // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
12177  // A reduction-identifier may not be re-declared in the current scope for the
12178  // same type or for a type that is compatible according to the base language
12179  // rules.
12180  llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
12181  OMPDeclareReductionDecl *PrevDRD = nullptr;
12182  bool InCompoundScope = true;
12183  if (S != nullptr) {
12184  // Find previous declaration with the same name not referenced in other
12185  // declarations.
12186  FunctionScopeInfo *ParentFn = getEnclosingFunction();
12187  InCompoundScope =
12188  (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
12189  LookupName(Lookup, S);
12190  FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
12191  /*AllowInlineNamespace=*/false);
12192  llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
12193  auto Filter = Lookup.makeFilter();
12194  while (Filter.hasNext()) {
12195  auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
12196  if (InCompoundScope) {
12197  auto I = UsedAsPrevious.find(PrevDecl);
12198  if (I == UsedAsPrevious.end())
12199  UsedAsPrevious[PrevDecl] = false;
12200  if (auto *D = PrevDecl->getPrevDeclInScope())
12201  UsedAsPrevious[D] = true;
12202  }
12203  PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
12204  PrevDecl->getLocation();
12205  }
12206  Filter.done();
12207  if (InCompoundScope) {
12208  for (auto &PrevData : UsedAsPrevious) {
12209  if (!PrevData.second) {
12210  PrevDRD = PrevData.first;
12211  break;
12212  }
12213  }
12214  }
12215  } else if (PrevDeclInScope != nullptr) {
12216  auto *PrevDRDInScope = PrevDRD =
12217  cast<OMPDeclareReductionDecl>(PrevDeclInScope);
12218  do {
12219  PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
12220  PrevDRDInScope->getLocation();
12221  PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
12222  } while (PrevDRDInScope != nullptr);
12223  }
12224  for (auto &TyData : ReductionTypes) {
12225  auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
12226  bool Invalid = false;
12227  if (I != PreviousRedeclTypes.end()) {
12228  Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
12229  << TyData.first;
12230  Diag(I->second, diag::note_previous_definition);
12231  Invalid = true;
12232  }
12233  PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
12234  auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
12235  Name, TyData.first, PrevDRD);
12236  DC->addDecl(DRD);
12237  DRD->setAccess(AS);
12238  Decls.push_back(DRD);
12239  if (Invalid)
12240  DRD->setInvalidDecl();
12241  else
12242  PrevDRD = DRD;
12243  }
12244 
12245  return DeclGroupPtrTy::make(
12246  DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
12247 }
12248 
12250  auto *DRD = cast<OMPDeclareReductionDecl>(D);
12251 
12252  // Enter new function scope.
12253  PushFunctionScope();
12254  getCurFunction()->setHasBranchProtectedScope();
12255  getCurFunction()->setHasOMPDeclareReductionCombiner();
12256 
12257  if (S != nullptr)
12258  PushDeclContext(S, DRD);
12259  else
12260  CurContext = DRD;
12261 
12262  PushExpressionEvaluationContext(
12263  ExpressionEvaluationContext::PotentiallyEvaluated);
12264 
12265  QualType ReductionType = DRD->getType();
12266  // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
12267  // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
12268  // uses semantics of argument handles by value, but it should be passed by
12269  // reference. C lang does not support references, so pass all parameters as
12270  // pointers.
12271  // Create 'T omp_in;' variable.
12272  auto *OmpInParm =
12273  buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
12274  // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
12275  // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
12276  // uses semantics of argument handles by value, but it should be passed by
12277  // reference. C lang does not support references, so pass all parameters as
12278  // pointers.
12279  // Create 'T omp_out;' variable.
12280  auto *OmpOutParm =
12281  buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
12282  if (S != nullptr) {
12283  PushOnScopeChains(OmpInParm, S);
12284  PushOnScopeChains(OmpOutParm, S);
12285  } else {
12286  DRD->addDecl(OmpInParm);
12287  DRD->addDecl(OmpOutParm);
12288  }
12289 }
12290 
12292  auto *DRD = cast<OMPDeclareReductionDecl>(D);
12293  DiscardCleanupsInEvaluationContext();
12294  PopExpressionEvaluationContext();
12295 
12296  PopDeclContext();
12297  PopFunctionScopeInfo();
12298 
12299  if (Combiner != nullptr)
12300  DRD->setCombiner(Combiner);
12301  else
12302  DRD->setInvalidDecl();
12303 }
12304 
12306  auto *DRD = cast<OMPDeclareReductionDecl>(D);
12307 
12308  // Enter new function scope.
12309  PushFunctionScope();
12310  getCurFunction()->setHasBranchProtectedScope();
12311 
12312  if (S != nullptr)
12313  PushDeclContext(S, DRD);
12314  else
12315  CurContext = DRD;
12316 
12317  PushExpressionEvaluationContext(
12318  ExpressionEvaluationContext::PotentiallyEvaluated);
12319 
12320  QualType ReductionType = DRD->getType();
12321  // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
12322  // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
12323  // uses semantics of argument handles by value, but it should be passed by
12324  // reference. C lang does not support references, so pass all parameters as
12325  // pointers.
12326  // Create 'T omp_priv;' variable.
12327  auto *OmpPrivParm =
12328  buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
12329  // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
12330  // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
12331  // uses semantics of argument handles by value, but it should be passed by
12332  // reference. C lang does not support references, so pass all parameters as
12333  // pointers.
12334  // Create 'T omp_orig;' variable.
12335  auto *OmpOrigParm =
12336  buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
12337  if (S != nullptr) {
12338  PushOnScopeChains(OmpPrivParm, S);
12339  PushOnScopeChains(OmpOrigParm, S);
12340  } else {
12341  DRD->addDecl(OmpPrivParm);
12342  DRD->addDecl(OmpOrigParm);
12343  }
12344  return OmpPrivParm;
12345 }
12346 
12348  VarDecl *OmpPrivParm) {
12349  auto *DRD = cast<OMPDeclareReductionDecl>(D);
12350  DiscardCleanupsInEvaluationContext();
12351  PopExpressionEvaluationContext();
12352 
12353  PopDeclContext();
12354  PopFunctionScopeInfo();
12355 
12356  if (Initializer != nullptr) {
12357  DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
12358  } else if (OmpPrivParm->hasInit()) {
12359  DRD->setInitializer(OmpPrivParm->getInit(),
12360  OmpPrivParm->isDirectInit()
12363  } else {
12364  DRD->setInvalidDecl();
12365  }
12366 }
12367 
12369  Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
12370  for (auto *D : DeclReductions.get()) {
12371  if (IsValid) {
12372  auto *DRD = cast<OMPDeclareReductionDecl>(D);
12373  if (S != nullptr)
12374  PushOnScopeChains(DRD, S, /*AddToContext=*/false);
12375  } else
12376  D->setInvalidDecl();
12377  }
12378  return DeclReductions;
12379 }
12380 
12382  SourceLocation StartLoc,
12383  SourceLocation LParenLoc,
12384  SourceLocation EndLoc) {
12385  Expr *ValExpr = NumTeams;
12386  Stmt *HelperValStmt = nullptr;
12387 
12388  // OpenMP [teams Constrcut, Restrictions]
12389  // The num_teams expression must evaluate to a positive integer value.
12390  if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
12391  /*StrictlyPositive=*/true))
12392  return nullptr;
12393 
12394  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
12395  OpenMPDirectiveKind CaptureRegion =
12396  getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams);
12397  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12398  ValExpr = MakeFullExpr(ValExpr).get();
12399  llvm::MapVector<Expr *, DeclRefExpr *> Captures;
12400  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12401  HelperValStmt = buildPreInits(Context, Captures);
12402  }
12403 
12404  return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
12405  StartLoc, LParenLoc, EndLoc);
12406 }
12407 
12409  SourceLocation StartLoc,
12410  SourceLocation LParenLoc,
12411  SourceLocation EndLoc) {
12412  Expr *ValExpr = ThreadLimit;
12413  Stmt *HelperValStmt = nullptr;
12414 
12415  // OpenMP [teams Constrcut, Restrictions]
12416  // The thread_limit expression must evaluate to a positive integer value.
12417  if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
12418  /*StrictlyPositive=*/true))
12419  return nullptr;
12420 
12421  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
12422  OpenMPDirectiveKind CaptureRegion =
12423  getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit);
12424  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12425  ValExpr = MakeFullExpr(ValExpr).get();
12426  llvm::MapVector<Expr *, DeclRefExpr *> Captures;
12427  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12428  HelperValStmt = buildPreInits(Context, Captures);
12429  }
12430 
12431  return new (Context) OMPThreadLimitClause(
12432  ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
12433 }
12434 
12436  SourceLocation StartLoc,
12437  SourceLocation LParenLoc,
12438  SourceLocation EndLoc) {
12439  Expr *ValExpr = Priority;
12440 
12441  // OpenMP [2.9.1, task Constrcut]
12442  // The priority-value is a non-negative numerical scalar expression.
12443  if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_priority,
12444  /*StrictlyPositive=*/false))
12445  return nullptr;
12446 
12447  return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc);
12448 }
12449 
12451  SourceLocation StartLoc,
12452  SourceLocation LParenLoc,
12453  SourceLocation EndLoc) {
12454  Expr *ValExpr = Grainsize;
12455 
12456  // OpenMP [2.9.2, taskloop Constrcut]
12457  // The parameter of the grainsize clause must be a positive integer
12458  // expression.
12459  if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize,
12460  /*StrictlyPositive=*/true))
12461  return nullptr;
12462 
12463  return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc);
12464 }
12465 
12467  SourceLocation StartLoc,
12468  SourceLocation LParenLoc,
12469  SourceLocation EndLoc) {
12470  Expr *ValExpr = NumTasks;
12471 
12472  // OpenMP [2.9.2, taskloop Constrcut]
12473  // The parameter of the num_tasks clause must be a positive integer
12474  // expression.
12475  if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks,
12476  /*StrictlyPositive=*/true))
12477  return nullptr;
12478 
12479  return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc);
12480 }
12481 
12483  SourceLocation LParenLoc,
12484  SourceLocation EndLoc) {
12485  // OpenMP [2.13.2, critical construct, Description]
12486  // ... where hint-expression is an integer constant expression that evaluates
12487  // to a valid lock hint.
12488  ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
12489  if (HintExpr.isInvalid())
12490  return nullptr;
12491  return new (Context)
12492  OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
12493 }
12494 
12496  OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
12497  SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
12498  SourceLocation EndLoc) {
12499  if (Kind == OMPC_DIST_SCHEDULE_unknown) {
12500  std::string Values;
12501  Values += "'";
12502  Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
12503  Values += "'";
12504  Diag(KindLoc, diag::err_omp_unexpected_clause_value)
12505  << Values << getOpenMPClauseName(OMPC_dist_schedule);
12506  return nullptr;
12507  }
12508  Expr *ValExpr = ChunkSize;
12509  Stmt *HelperValStmt = nullptr;
12510  if (ChunkSize) {
12511  if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
12512  !ChunkSize->isInstantiationDependent() &&
12513  !ChunkSize->containsUnexpandedParameterPack()) {
12514  SourceLocation ChunkSizeLoc = ChunkSize->getLocStart();
12515  ExprResult Val =
12516  PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
12517  if (Val.isInvalid())
12518  return nullptr;
12519 
12520  ValExpr = Val.get();
12521 
12522  // OpenMP [2.7.1, Restrictions]
12523  // chunk_size must be a loop invariant integer expression with a positive
12524  // value.
12525  llvm::APSInt Result;
12526  if (ValExpr->isIntegerConstantExpr(Result, Context)) {
12527  if (Result.isSigned() && !Result.isStrictlyPositive()) {
12528  Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
12529  << "dist_schedule" << ChunkSize->getSourceRange();
12530  return nullptr;
12531  }
12533  DSAStack->getCurrentDirective(), OMPC_dist_schedule) !=
12534  OMPD_unknown &&
12535  !CurContext->isDependentContext()) {
12536  ValExpr = MakeFullExpr(ValExpr).get();
12537  llvm::MapVector<Expr *, DeclRefExpr *> Captures;
12538  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12539  HelperValStmt = buildPreInits(Context, Captures);
12540  }
12541  }
12542  }
12543 
12544  return new (Context)
12545  OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
12546  Kind, ValExpr, HelperValStmt);
12547 }
12548 
12551  SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
12552  SourceLocation KindLoc, SourceLocation EndLoc) {
12553  // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)'
12554  if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) {
12555  std::string Value;
12556  SourceLocation Loc;
12557  Value += "'";
12558  if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
12559  Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
12560  OMPC_DEFAULTMAP_MODIFIER_tofrom);
12561  Loc = MLoc;
12562  } else {
12563  Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
12564  OMPC_DEFAULTMAP_scalar);
12565  Loc = KindLoc;
12566  }
12567  Value += "'";
12568  Diag(Loc, diag::err_omp_unexpected_clause_value)
12569  << Value << getOpenMPClauseName(OMPC_defaultmap);
12570  return nullptr;
12571  }
12572  DSAStack->setDefaultDMAToFromScalar(StartLoc);
12573 
12574  return new (Context)
12575  OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
12576 }
12577 
12579  DeclContext *CurLexicalContext = getCurLexicalContext();
12580  if (!CurLexicalContext->isFileContext() &&
12581  !CurLexicalContext->isExternCContext() &&
12582  !CurLexicalContext->isExternCXXContext() &&
12583  !isa<CXXRecordDecl>(CurLexicalContext) &&
12584  !isa<ClassTemplateDecl>(CurLexicalContext) &&
12585  !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
12586  !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
12587  Diag(Loc, diag::err_omp_region_not_file_context);
12588  return false;
12589  }
12590  if (IsInOpenMPDeclareTargetContext) {
12591  Diag(Loc, diag::err_omp_enclosed_declare_target);
12592  return false;
12593  }
12594 
12595  IsInOpenMPDeclareTargetContext = true;
12596  return true;
12597 }
12598 
12600  assert(IsInOpenMPDeclareTargetContext &&
12601  "Unexpected ActOnFinishOpenMPDeclareTargetDirective");
12602 
12603  IsInOpenMPDeclareTargetContext = false;
12604 }
12605 
12607  CXXScopeSpec &ScopeSpec,
12608  const DeclarationNameInfo &Id,
12609  OMPDeclareTargetDeclAttr::MapTypeTy MT,
12610  NamedDeclSetType &SameDirectiveDecls) {
12611  LookupResult Lookup(*this, Id, LookupOrdinaryName);
12612  LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
12613 
12614  if (Lookup.isAmbiguous())
12615  return;
12616  Lookup.suppressDiagnostics();
12617 
12618  if (!Lookup.isSingleResult()) {
12619  if (TypoCorrection Corrected =
12620  CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr,
12621  llvm::make_unique<VarOrFuncDeclFilterCCC>(*this),
12622  CTK_ErrorRecovery)) {
12623  diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
12624  << Id.getName());
12625  checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
12626  return;
12627  }
12628 
12629  Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
12630  return;
12631  }
12632 
12633  NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
12634  if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND)) {
12635  if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl())))
12636  Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName();
12637 
12638  if (!ND->hasAttr<OMPDeclareTargetDeclAttr>()) {
12639  Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT);
12640  ND->addAttr(A);
12641  if (ASTMutationListener *ML = Context.getASTMutationListener())
12642  ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
12643  checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Id.getLoc());
12644  } else if (ND->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() != MT) {
12645  Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link)
12646  << Id.getName();
12647  }
12648  } else
12649  Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
12650 }
12651 
12653  Sema &SemaRef, Decl *D) {
12654  if (!D)
12655  return;
12656  Decl *LD = nullptr;
12657  if (isa<TagDecl>(D)) {
12658  LD = cast<TagDecl>(D)->getDefinition();
12659  } else if (isa<VarDecl>(D)) {
12660  LD = cast<VarDecl>(D)->getDefinition();
12661 
12662  // If this is an implicit variable that is legal and we do not need to do
12663  // anything.
12664  if (cast<VarDecl>(D)->isImplicit()) {
12665  Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
12666  SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To);
12667  D->addAttr(A);
12669  ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
12670  return;
12671  }
12672 
12673  } else if (isa<FunctionDecl>(D)) {
12674  const FunctionDecl *FD = nullptr;
12675  if (cast<FunctionDecl>(D)->hasBody(FD))
12676  LD = const_cast<FunctionDecl *>(FD);
12677 
12678  // If the definition is associated with the current declaration in the
12679  // target region (it can be e.g. a lambda) that is legal and we do not need
12680  // to do anything else.
12681  if (LD == D) {
12682  Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
12683  SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To);
12684  D->addAttr(A);
12686  ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
12687  return;
12688  }
12689  }
12690  if (!LD)
12691  LD = D;
12692  if (LD && !LD->hasAttr<OMPDeclareTargetDeclAttr>() &&
12693  (isa<VarDecl>(LD) || isa<FunctionDecl>(LD))) {
12694  // Outlined declaration is not declared target.
12695  if (LD->isOutOfLine()) {
12696  SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context);
12697  SemaRef.Diag(SL, diag::note_used_here) << SR;
12698  } else {
12699  DeclContext *DC = LD->getDeclContext();
12700  while (DC) {
12701  if (isa<FunctionDecl>(DC) &&
12702  cast<FunctionDecl>(DC)->hasAttr<OMPDeclareTargetDeclAttr>())
12703  break;
12704  DC = DC->getParent();
12705  }
12706  if (DC)
12707  return;
12708 
12709  // Is not declared in target context.
12710  SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context);
12711  SemaRef.Diag(SL, diag::note_used_here) << SR;
12712  }
12713  // Mark decl as declared target to prevent further diagnostic.
12714  Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
12715  SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To);
12716  D->addAttr(A);
12718  ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
12719  }
12720 }
12721 
12723  Sema &SemaRef, DSAStackTy *Stack,
12724  ValueDecl *VD) {
12725  if (VD->hasAttr<OMPDeclareTargetDeclAttr>())
12726  return true;
12727  if (!CheckTypeMappable(SL, SR, SemaRef, Stack, VD->getType()))
12728  return false;
12729  return true;
12730 }
12731 
12733  SourceLocation IdLoc) {
12734  if (!D || D->isInvalidDecl())
12735  return;
12736  SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
12737  SourceLocation SL = E ? E->getLocStart() : D->getLocation();
12738  // 2.10.6: threadprivate variable cannot appear in a declare target directive.
12739  if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
12740  if (DSAStack->isThreadPrivate(VD)) {
12741  Diag(SL, diag::err_omp_threadprivate_in_target);
12742  ReportOriginalDSA(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false));
12743  return;
12744  }
12745  }
12746  if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) {
12747  // Problem if any with var declared with incomplete type will be reported
12748  // as normal, so no need to check it here.
12749  if ((E || !VD->getType()->isIncompleteType()) &&
12750  !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) {
12751  // Mark decl as declared target to prevent further diagnostic.
12752  if (isa<VarDecl>(VD) || isa<FunctionDecl>(VD)) {
12753  Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
12754  Context, OMPDeclareTargetDeclAttr::MT_To);
12755  VD->addAttr(A);
12756  if (ASTMutationListener *ML = Context.getASTMutationListener())
12757  ML->DeclarationMarkedOpenMPDeclareTarget(VD, A);
12758  }
12759  return;
12760  }
12761  }
12762  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
12763  if (FD->hasAttr<OMPDeclareTargetDeclAttr>() &&
12764  (FD->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() ==
12765  OMPDeclareTargetDeclAttr::MT_Link)) {
12766  assert(IdLoc.isValid() && "Source location is expected");
12767  Diag(IdLoc, diag::err_omp_function_in_link_clause);
12768  Diag(FD->getLocation(), diag::note_defined_here) << FD;
12769  return;
12770  }
12771  }
12772  if (!E) {
12773  // Checking declaration inside declare target region.
12774  if (!D->hasAttr<OMPDeclareTargetDeclAttr>() &&
12775  (isa<VarDecl>(D) || isa<FunctionDecl>(D))) {
12776  Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(
12777  Context, OMPDeclareTargetDeclAttr::MT_To);
12778  D->addAttr(A);
12779  if (ASTMutationListener *ML = Context.getASTMutationListener())
12780  ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
12781  }
12782  return;
12783  }
12784  checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
12785 }
12786 
12788  SourceLocation StartLoc,
12789  SourceLocation LParenLoc,
12790  SourceLocation EndLoc) {
12791  MappableVarListInfo MVLI(VarList);
12792  checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, StartLoc);
12793  if (MVLI.ProcessedVarList.empty())
12794  return nullptr;
12795 
12796  return OMPToClause::Create(Context, StartLoc, LParenLoc, EndLoc,
12797  MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
12798  MVLI.VarComponents);
12799 }
12800 
12802  SourceLocation StartLoc,
12803  SourceLocation LParenLoc,
12804  SourceLocation EndLoc) {
12805  MappableVarListInfo MVLI(VarList);
12806  checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, StartLoc);
12807  if (MVLI.ProcessedVarList.empty())
12808  return nullptr;
12809 
12810  return OMPFromClause::Create(Context, StartLoc, LParenLoc, EndLoc,
12811  MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
12812  MVLI.VarComponents);
12813 }
12814 
12816  SourceLocation StartLoc,
12817  SourceLocation LParenLoc,
12818  SourceLocation EndLoc) {
12819  MappableVarListInfo MVLI(VarList);
12820  SmallVector<Expr *, 8> PrivateCopies;
12822 
12823  for (auto &RefExpr : VarList) {
12824  assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
12825  SourceLocation ELoc;
12826  SourceRange ERange;
12827  Expr *SimpleRefExpr = RefExpr;
12828  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
12829  if (Res.second) {
12830  // It will be analyzed later.
12831  MVLI.ProcessedVarList.push_back(RefExpr);
12832  PrivateCopies.push_back(nullptr);
12833  Inits.push_back(nullptr);
12834  }
12835  ValueDecl *D = Res.first;
12836  if (!D)
12837  continue;
12838 
12839  QualType Type = D->getType();
12840  Type = Type.getNonReferenceType().getUnqualifiedType();
12841 
12842  auto *VD = dyn_cast<VarDecl>(D);
12843 
12844  // Item should be a pointer or reference to pointer.
12845  if (!Type->isPointerType()) {
12846  Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
12847  << 0 << RefExpr->getSourceRange();
12848  continue;
12849  }
12850 
12851  // Build the private variable and the expression that refers to it.
12852  auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(),
12853  D->hasAttrs() ? &D->getAttrs() : nullptr);
12854  if (VDPrivate->isInvalidDecl())
12855  continue;
12856 
12857  CurContext->addDecl(VDPrivate);
12858  auto VDPrivateRefExpr = buildDeclRefExpr(
12859  *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
12860 
12861  // Add temporary variable to initialize the private copy of the pointer.
12862  auto *VDInit =
12863  buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
12864  auto *VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
12865  RefExpr->getExprLoc());
12866  AddInitializerToDecl(VDPrivate,
12867  DefaultLvalueConversion(VDInitRefExpr).get(),
12868  /*DirectInit=*/false);
12869 
12870  // If required, build a capture to implement the privatization initialized
12871  // with the current list item value.
12872  DeclRefExpr *Ref = nullptr;
12873  if (!VD)
12874  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
12875  MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
12876  PrivateCopies.push_back(VDPrivateRefExpr);
12877  Inits.push_back(VDInitRefExpr);
12878 
12879  // We need to add a data sharing attribute for this variable to make sure it
12880  // is correctly captured. A variable that shows up in a use_device_ptr has
12881  // similar properties of a first private variable.
12882  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
12883 
12884  // Create a mappable component for the list item. List items in this clause
12885  // only need a component.
12886  MVLI.VarBaseDeclarations.push_back(D);
12887  MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
12888  MVLI.VarComponents.back().push_back(
12890  }
12891 
12892  if (MVLI.ProcessedVarList.empty())
12893  return nullptr;
12894 
12896  Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList,
12897  PrivateCopies, Inits, MVLI.VarBaseDeclarations, MVLI.VarComponents);
12898 }
12899 
12901  SourceLocation StartLoc,
12902  SourceLocation LParenLoc,
12903  SourceLocation EndLoc) {
12904  MappableVarListInfo MVLI(VarList);
12905  for (auto &RefExpr : VarList) {
12906  assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
12907  SourceLocation ELoc;
12908  SourceRange ERange;
12909  Expr *SimpleRefExpr = RefExpr;
12910  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
12911  if (Res.second) {
12912  // It will be analyzed later.
12913  MVLI.ProcessedVarList.push_back(RefExpr);
12914  }
12915  ValueDecl *D = Res.first;
12916  if (!D)
12917  continue;
12918 
12919  QualType Type = D->getType();
12920  // item should be a pointer or array or reference to pointer or array
12921  if (!Type.getNonReferenceType()->isPointerType() &&
12922  !Type.getNonReferenceType()->isArrayType()) {
12923  Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
12924  << 0 << RefExpr->getSourceRange();
12925  continue;
12926  }
12927 
12928  // Check if the declaration in the clause does not show up in any data
12929  // sharing attribute.
12930  auto DVar = DSAStack->getTopDSA(D, false);
12931  if (isOpenMPPrivate(DVar.CKind)) {
12932  Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
12933  << getOpenMPClauseName(DVar.CKind)
12934  << getOpenMPClauseName(OMPC_is_device_ptr)
12935  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
12936  ReportOriginalDSA(*this, DSAStack, D, DVar);
12937  continue;
12938  }
12939 
12940  Expr *ConflictExpr;
12941  if (DSAStack->checkMappableExprComponentListsForDecl(
12942  D, /*CurrentRegionOnly=*/true,
12943  [&ConflictExpr](
12945  OpenMPClauseKind) -> bool {
12946  ConflictExpr = R.front().getAssociatedExpression();
12947  return true;
12948  })) {
12949  Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
12950  Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
12951  << ConflictExpr->getSourceRange();
12952  continue;
12953  }
12954 
12955  // Store the components in the stack so that they can be used to check
12956  // against other clauses later on.
12958  DSAStack->addMappableExpressionComponents(
12959  D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
12960 
12961  // Record the expression we've just processed.
12962  MVLI.ProcessedVarList.push_back(SimpleRefExpr);
12963 
12964  // Create a mappable component for the list item. List items in this clause
12965  // only need a component. We use a null declaration to signal fields in
12966  // 'this'.
12967  assert((isa<DeclRefExpr>(SimpleRefExpr) ||
12968  isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
12969  "Unexpected device pointer expression!");
12970  MVLI.VarBaseDeclarations.push_back(
12971  isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
12972  MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
12973  MVLI.VarComponents.back().push_back(MC);
12974  }
12975 
12976  if (MVLI.ProcessedVarList.empty())
12977  return nullptr;
12978 
12980  Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList,
12981  MVLI.VarBaseDeclarations, MVLI.VarComponents);
12982 }
static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, SourceLocation M1Loc, SourceLocation M2Loc)
static OMPTaskReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef< Expr *> Privates, ArrayRef< Expr *> LHSExprs, ArrayRef< Expr *> RHSExprs, ArrayRef< Expr *> ReductionOps, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
Expr * NLB
Update of LowerBound for statically sheduled &#39;omp for&#39; loops.
Definition: StmtOpenMP.h:651
SourceLocation getLoc() const
getLoc - Returns the main location of the declaration name.
Defines the clang::ASTContext interface.
SmallVector< Expr *, 4 > Finals
Final loop counter values for GodeGen.
Definition: StmtOpenMP.h:679
Expr * NUB
Update of UpperBound for statically sheduled omp loops for outer loop in combined constructs (e...
Definition: StmtOpenMP.h:618
QualType getCurrentThisType()
Try to retrieve the type of the &#39;this&#39; pointer.
SmallVector< Expr *, 4 > Updates
Expressions for loop counters update for CodeGen.
Definition: StmtOpenMP.h:677
StmtResult ActOnOpenMPMasterDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp master&#39; after parsing of the associated statement.
QualType withConst() const
Retrieves a version of this type with const applied.
ExprResult ActOnOpenMPIdExpression(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id)
Called on correct id-expression from the &#39;#pragma omp threadprivate&#39;.
StmtResult ActOnOpenMPFlushDirective(ArrayRef< OMPClause *> Clauses, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp flush&#39;.
void setImplicit(bool I=true)
Definition: DeclBase.h:552
An instance of this class is created to represent a function declaration or definition.
Definition: Decl.h:1697
OMPClause * ActOnOpenMPSimdlenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;simdlen&#39; clause.
This represents &#39;thread_limit&#39; clause in the &#39;#pragma omp ...&#39; directive.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
StmtResult ActOnOpenMPSectionDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp section&#39; after parsing of the associated statement.
OMPClause * ActOnOpenMPTaskReductionClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr *> UnresolvedReductions=llvm::None)
Called on well-formed &#39;task_reduction&#39; clause.
static OMPDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
PtrTy get() const
Definition: Ownership.h:74
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
CanQualType VoidPtrTy
Definition: ASTContext.h:1012
bool ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc)
Called on the start of target region i.e. &#39;#pragma omp declare target&#39;.
A (possibly-)qualified type.
Definition: Type.h:653
void ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D)
Initialize declare reduction construct initializer.
Simple class containing the result of Sema::CorrectTypo.
static OMPAtomicDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *X, Expr *V, Expr *E, Expr *UE, bool IsXLHSInRHSPart, bool IsPostfixUpdate)
Creates directive with a list of Clauses and &#39;x&#39;, &#39;v&#39; and &#39;expr&#39; parts of the atomic construct (see S...
Definition: StmtOpenMP.cpp:643
bool isArrayType() const
Definition: Type.h:5991
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
Definition: Expr.h:2483
ArrayRef< OMPClause * > clauses()
Definition: StmtOpenMP.h:239
StmtResult ActOnOpenMPTargetUpdateDirective(ArrayRef< OMPClause *> Clauses, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AStmt)
Called on well-formed &#39;#pragma omp target update&#39;.
static Opcode getOpForCompoundAssignment(Opcode Opc)
Definition: Expr.h:3119
ExprResult ActOnConditionalOp(SourceLocation QuestionLoc, SourceLocation ColonLoc, Expr *CondExpr, Expr *LHSExpr, Expr *RHSExpr)
ActOnConditionalOp - Parse a ?: operation.
Definition: SemaExpr.cpp:7189
StmtResult ActOnOpenMPCancelDirective(ArrayRef< OMPClause *> Clauses, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Called on well-formed &#39;#pragma omp cancel&#39;.
ExprResult ActOnIntegerConstant(SourceLocation Loc, uint64_t Val)
Definition: SemaExpr.cpp:3129
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:195
void EndOpenMPDSABlock(Stmt *CurDirective)
Called on end of data sharing attribute block.
OpenMPDefaultmapClauseKind
OpenMP attributes for &#39;defaultmap&#39; clause.
Definition: OpenMPKinds.h:107
static OMPCopyprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> SrcExprs, ArrayRef< Expr *> DstExprs, ArrayRef< Expr *> AssignmentOps)
Creates clause with a list of variables VL.
static OMPTeamsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:840
StmtResult ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName, ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp critical&#39; after parsing of the associated statement.
static UnresolvedLookupExpr * Create(const ASTContext &C, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, bool ADL, bool Overloaded, UnresolvedSetIterator Begin, UnresolvedSetIterator End)
Definition: ExprCXX.h:2781
OMPClause * ActOnOpenMPUntiedClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;untied&#39; clause.
static OMPClauseWithPreInit * get(OMPClause *C)
Stmt - This represents one statement.
Definition: Stmt.h:66
Filter makeFilter()
Create a filter for this result set.
Definition: Lookup.h:685
static OMPTaskgroupDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *ReductionRef)
Creates directive.
Definition: StmtOpenMP.cpp:525
static bool CheckTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, DSAStackTy *Stack, QualType QTy)
StmtResult ActOnOpenMPTargetDataDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp target data&#39; after parsing of the associated statement.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
Definition: Type.cpp:456
static OMPTargetTeamsDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
ActionResult< Expr * > ExprResult
Definition: Ownership.h:251
bool isOpenMPNestingDistributeDirective(OpenMPDirectiveKind DKind)
Checks if the specified composite/combined directive constitutes a distribute directive in the outerm...
static bool hasClauses(ArrayRef< OMPClause *> Clauses, const OpenMPClauseKind K)
Check for existence of a map clause in the list of clauses.
Expr * EUB
EnsureUpperBound – expression UB = min(UB, NumIterations).
Definition: StmtOpenMP.h:649
Expr * DistInc
DistInc - increment expression for distribute loop when found combined with a further loop level (e...
Definition: StmtOpenMP.h:663
Expr * getBase() const
Definition: Expr.h:2477
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type...
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
Definition: Sema.h:1270
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
static OMPUseDevicePtrClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> Vars, ArrayRef< Expr *> PrivateVars, ArrayRef< Expr *> Inits, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
specific_attr_iterator - Iterates over a subrange of an AttrVec, only providing attributes that are o...
Definition: AttrIterator.h:54
This represents &#39;grainsize&#39; clause in the &#39;#pragma omp ...&#39; directive.
static OMPSectionDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt, bool HasCancel)
Creates directive.
Definition: StmtOpenMP.cpp:246
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
Definition: Decl.cpp:2083
static Expr * getOrderedNumberExpr(ArrayRef< OMPClause *> Clauses)
This represents &#39;if&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:240
OMPClause * ActOnOpenMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;threads&#39; clause.
bool isOpenMPTargetCapturedDecl(ValueDecl *D, unsigned Level)
Check if the specified variable is captured by &#39;target&#39; directive.
StmtResult ActOnOpenMPTargetParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp target parallel for&#39; after parsing of the associated statement...
Opcode getOpcode() const
Definition: Expr.h:3026
bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS, bool AllowBuiltinCreation=false, bool EnteringContext=false)
Performs name lookup for a name that was parsed in the source code, and may contain a C++ scope speci...
StringRef P
StmtResult ActOnOpenMPTaskLoopSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp taskloop simd&#39; after parsing of the associated statement...
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
Definition: Type.h:5891
This represents &#39;priority&#39; clause in the &#39;#pragma omp ...&#39; directive.
bool isOpenMPTargetDataManagementDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target data offload directive.
The base class of the type hierarchy.
Definition: Type.h:1351
StmtResult ActOnOpenMPTargetTeamsDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp target teams&#39; after parsing of the associated statement.
bool CheckOpenMPLinearDecl(ValueDecl *D, SourceLocation ELoc, OpenMPLinearClauseKind LinKind, QualType Type)
Checks that the specified declaration matches requirements for the linear decls.
OMPClause * ActOnOpenMPGrainsizeClause(Expr *Size, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;grainsize&#39; clause.
SourceLocation getBeginLoc() const
getBeginLoc - Retrieve the location of the first token.
const char * getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type)
static OMPDeclareReductionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, QualType T, OMPDeclareReductionDecl *PrevDeclInScope)
Create declare reduction node.
Definition: DeclOpenMP.cpp:62
QualType withConst() const
Definition: Type.h:818
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:671
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
Definition: Specifiers.h:95
A container of type source information.
Definition: Decl.h:86
This represents &#39;update&#39; clause in the &#39;#pragma omp atomic&#39; directive.
Wrapper for void* pointer.
Definition: Ownership.h:45
bool CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, SourceLocation LinLoc)
Checks correctness of linear modifiers.
OMPClause * ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;proc_bind&#39; clause.
static bool FitsInto(unsigned Bits, bool Signed, Expr *E, Sema &SemaRef)
Check if the given expression E is a constant integer that fits into Bits bits.
OMPClause * ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;hint&#39; clause.
StmtResult ActOnOpenMPTaskDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp task&#39; after parsing of the associated statement.
StmtResult ActOnOpenMPTeamsDistributeParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp teams distribute parallel for&#39; after parsing of the associated sta...
StmtResult ActOnOpenMPParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp parallel for simd&#39; after parsing of the associated statement...
static OMPTeamsDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2397
static std::pair< ValueDecl *, bool > getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, SourceRange &ERange, bool AllowArraySection=false)
OpenMPDefaultmapClauseModifier
OpenMP modifiers for &#39;defaultmap&#39; clause.
Definition: OpenMPKinds.h:115
static bool checkReductionClauseWithNogroup(Sema &S, ArrayRef< OMPClause *> Clauses)
float __ovld __cnfn distance(float p0, float p1)
Returns the distance between p0 and p1.
OMPClause * ActOnOpenMPPriorityClause(Expr *Priority, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;priority&#39; clause.
static unsigned CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, DSAStackTy &DSA, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA, OMPLoopDirective::HelperExprs &Built)
Called on a for stmt to check itself and nested loops (if any).
static int getOpenMPCaptureLevels(OpenMPDirectiveKind Kind)
Return the number of captured regions created for an OpenMP directive.
SourceLocation getSecondScheduleModifierLoc() const
Get the second modifier location.
Definition: OpenMPClause.h:895
bool capturesVariable(const VarDecl *Var) const
True if this variable has been captured.
Definition: Stmt.cpp:1124
Expr * PrevLB
PreviousLowerBound - local variable passed to runtime in the enclosing schedule or null if that does ...
Definition: StmtOpenMP.h:656
Retains information about a function, method, or block that is currently being parsed.
Definition: ScopeInfo.h:82
void setNothrow(bool Nothrow=true)
Definition: Decl.cpp:4276
bool EvaluateAsInt(llvm::APSInt &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer...
This represents &#39;read&#39; clause in the &#39;#pragma omp atomic&#39; directive.
static OMPTeamsDistributeDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
VarDecl - An instance of this class is created to represent a variable declaration or definition...
Definition: Decl.h:806
static OMPToClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> Vars, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
This represents &#39;num_threads&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:382
bool isEnumeralType() const
Definition: Type.h:6019
OMPClause * ActOnOpenMPFinalClause(Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;final&#39; clause.
const T * getAs() const
Member-template getAs<specific type>&#39;.
Definition: Type.h:6305
varlist_range varlists()
Definition: OpenMPClause.h:207
Extra information about a function prototype.
Definition: Type.h:3387
This represents &#39;defaultmap&#39; clause in the &#39;#pragma omp ...&#39; directive.
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context, bool Canonical) const
Produce a unique representation of the given statement.
bool isExternCContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
Definition: DeclBase.cpp:1092
bool isAmbiguous() const
Definition: Lookup.h:304
static OMPTeamsDistributeParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
bool isInvalidDecl() const
Definition: DeclBase.h:546
void setBegin(SourceLocation b)
Not a TLS variable.
Definition: Decl.h:823
OMPClause * ActOnOpenMPLastprivateClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;lastprivate&#39; clause.
StmtResult ActOnOpenMPBarrierDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp barrier&#39;.
bool hasDefinition() const
Definition: DeclCXX.h:738
static const NamedDecl * getDefinition(const Decl *D)
Definition: SemaDecl.cpp:2512
OMPClause * ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;depend&#39; clause.
bool isUnset() const
Definition: Ownership.h:160
This represents &#39;nogroup&#39; clause in the &#39;#pragma omp ...&#39; directive.
static Expr * CheckMapClauseExpressionBase(Sema &SemaRef, Expr *E, OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, OpenMPClauseKind CKind, bool NoDiagnose)
This represents &#39;safelen&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:447
Expr * LastIteration
Loop last iteration number.
Definition: StmtOpenMP.h:627
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveStart(Scope *S, DeclContext *DC, DeclarationName Name, ArrayRef< std::pair< QualType, SourceLocation >> ReductionTypes, AccessSpecifier AS, Decl *PrevDeclInScope=nullptr)
Called on start of &#39;#pragma omp declare reduction&#39;.
ExprResult PerformImplicitConversion(Expr *From, QualType ToType, AssignmentAction Action, bool AllowExplicit=false)
PerformImplicitConversion - Perform an implicit conversion of the expression From to the type ToType...
DeclGroupPtrTy ActOnOpenMPDeclareSimdDirective(DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, ArrayRef< Expr *> Uniforms, ArrayRef< Expr *> Aligneds, ArrayRef< Expr *> Alignments, ArrayRef< Expr *> Linears, ArrayRef< unsigned > LinModifiers, ArrayRef< Expr *> Steps, SourceRange SR)
Called on well-formed &#39;#pragma omp declare simd&#39; after parsing of the associated method/function.
IdentifierInfo * getIdentifier() const
getIdentifier - Get the identifier that names this declaration, if there is one.
Definition: Decl.h:265
void ActOnUninitializedDecl(Decl *dcl)
Definition: SemaDecl.cpp:10611
Expr * IgnoreImpCasts() LLVM_READONLY
IgnoreImpCasts - Skip past any implicit casts which might surround this expression.
Definition: Expr.h:2865
static OMPReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef< Expr *> Privates, ArrayRef< Expr *> LHSExprs, ArrayRef< Expr *> RHSExprs, ArrayRef< Expr *> ReductionOps, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
A semantic tree transformation that allows one to transform one abstract syntax tree into another...
Definition: TreeTransform.h:96
const char * getOpenMPClauseName(OpenMPClauseKind Kind)
Definition: OpenMPKinds.cpp:62
static OMPTargetParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
One of these records is kept for each identifier that is lexed.
CalcStep
Definition: OpenMPClause.h:141
static OMPIsDevicePtrClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> Vars, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
FieldDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
Definition: Decl.h:2659
Step
Definition: OpenMPClause.h:141
StmtResult ActOnOpenMPForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp for simd&#39; after parsing of the associated statement.
static OMPInReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef< Expr *> Privates, ArrayRef< Expr *> LHSExprs, ArrayRef< Expr *> RHSExprs, ArrayRef< Expr *> ReductionOps, ArrayRef< Expr *> TaskgroupDescriptors, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
OMPClause * ActOnOpenMPFirstprivateClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;firstprivate&#39; clause.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:149
A C++ nested-name-specifier augmented with source location information.
ExprResult ExprEmpty()
Definition: Ownership.h:273
This represents &#39;simd&#39; clause in the &#39;#pragma omp ...&#39; directive.
static OMPTargetEnterDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:796
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
bool IsDerivedFrom(SourceLocation Loc, QualType Derived, QualType Base)
Determine whether the type Derived is a C++ class that is derived from the type Base.
bool isOpenMPTaskingDirective(OpenMPDirectiveKind Kind)
Checks if the specified directive kind is one of tasking directives - task, taskloop or taksloop simd...
OpenMPLinearClauseKind
OpenMP attributes for &#39;linear&#39; clause.
Definition: OpenMPKinds.h:84
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
Definition: Decl.h:2467
OMPClause * ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation NameModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed &#39;if&#39; clause.
bool isNamespace() const
Definition: DeclBase.h:1413
static OMPTargetUpdateDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
StmtResult ActOnOpenMPRegionEnd(StmtResult S, ArrayRef< OMPClause *> Clauses)
End of OpenMP region.
void StartOpenMPDSABlock(OpenMPDirectiveKind K, const DeclarationNameInfo &DirName, Scope *CurScope, SourceLocation Loc)
Called on start of new data sharing attribute block.
SourceLocation getExprLoc() const LLVM_READONLY
Definition: Expr.h:2593
bool isReferenceType() const
Definition: Type.h:5954
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Definition: DeclBase.h:404
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr)
Definition: Expr.cpp:391
static OMPTaskDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:459
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC...
Definition: DeclBase.h:1455
Defines some OpenMP-specific enums and functions.
StmtResult ActOnOpenMPTargetExitDataDirective(ArrayRef< OMPClause *> Clauses, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AStmt)
Called on well-formed &#39;#pragma omp target exit data&#39; after parsing of the associated statement...
Expr * getSafelen() const
Return safe iteration space distance.
Definition: OpenMPClause.h:481
static Stmt * buildPreInits(ASTContext &Context, MutableArrayRef< Decl *> PreInits)
Build preinits statement for the given declarations.
static OMPDistributeDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:963
This represents &#39;#pragma omp critical&#39; directive.
Definition: StmtOpenMP.h:1424
void EndOpenMPClause()
End analysis of clauses.
IdentifierTable & Idents
Definition: ASTContext.h:537
StmtResult ActOnOpenMPTargetEnterDataDirective(ArrayRef< OMPClause *> Clauses, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AStmt)
Called on well-formed &#39;#pragma omp target enter data&#39; after parsing of the associated statement...
static bool IsNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, bool StrictlyPositive)
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
Definition: Specifiers.h:107
VerifyDiagnosticConsumer::Directive Directive
DeclClass * getAsSingle() const
Definition: Lookup.h:510
OpenMPDistScheduleClauseKind
OpenMP attributes for &#39;dist_schedule&#39; clause.
Definition: OpenMPKinds.h:100
bool isGLValue() const
Definition: Expr.h:252
static void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack, const ValueDecl *D, DSAStackTy::DSAVarData DVar, bool IsLoopIterVar=false)
BinaryOperatorKind
OMPClause * ActOnOpenMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;num_teams&#39; clause.
Represents the results of name lookup.
Definition: Lookup.h:32
PtrTy get() const
Definition: Ownership.h:162
bool IsOpenMPCapturedByRef(ValueDecl *D, unsigned Level)
Return true if the provided declaration VD should be captured by reference.
StmtResult ActOnOpenMPDistributeDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp distribute&#39; after parsing of the associated statement.
Expr * LB
DistributeLowerBound - used when composing &#39;omp distribute&#39; with &#39;omp for&#39; in a same construct...
Definition: StmtOpenMP.h:599
Expr * EUB
DistributeEnsureUpperBound - used when composing &#39;omp distribute&#39; with &#39;omp for&#39; in a same construct...
Definition: StmtOpenMP.h:605
bool isOpenMPTeamsDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a teams-kind directive.
OMPClause * ActOnOpenMPNogroupClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;nogroup&#39; clause.
OMPClause * ActOnOpenMPReadClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;read&#39; clause.
OMPClause * ActOnOpenMPScheduleClause(OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Called on well-formed &#39;schedule&#39; clause.
static OMPTeamsDistributeSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPLastprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> SrcExprs, ArrayRef< Expr *> DstExprs, ArrayRef< Expr *> AssignmentOps, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
static ValueDecl * getCanonicalDecl(ValueDecl *D)
Definition: SemaOpenMP.cpp:589
SourceLocation getLocStart() const
Returns the starting location of the clause.
Definition: OpenMPClause.h:67
static DeclRefExpr * buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, SourceLocation Loc, bool RefersToCapture=false)
Definition: SemaOpenMP.cpp:821
static ExprResult buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, Scope *S, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, QualType Ty, CXXCastPath &BasePath, Expr *UnresolvedReduction)
child_range children()
Definition: Stmt.cpp:226
SourceLocation getEndLoc() const
getEndLoc - Retrieve the location of the last token.
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:147
StmtResult StmtError()
Definition: Ownership.h:268
bool containsUnexpandedParameterPack() const
Whether this type is or contains an unexpanded parameter pack, used to support C++0x variadic templat...
Definition: Type.h:1633
OMPClause * ActOnOpenMPCaptureClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;capture&#39; clause.
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:2985
Look up the name of an OpenMP user-defined reduction operation.
Definition: Sema.h:3032
OMPClause * ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc, SourceLocation EndLoc)
std::pair< StringRef, QualType > CapturedParamNameType
Definition: Sema.h:3791
SmallVector< MappableComponent, 8 > MappableExprComponentList
This represents &#39;default&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:606
Scope - A scope is a transient data structure that is used while parsing the program.
Definition: Scope.h:39
ExprResult Perform(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, MultiExprArg Args, QualType *ResultType=nullptr)
Perform the actual initialization of the given entity based on the computed initialization sequence...
Definition: SemaInit.cpp:6555
static bool CheckOpenMPIterationSpace(OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA, LoopIterationSpace &ResultIterSpace, llvm::MapVector< Expr *, DeclRefExpr *> &Captures)
Called on a for stmt to check and extract its iteration space for further processing (such as collaps...
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:5718
OMPClause * ActOnOpenMPLinearClause(ArrayRef< Expr *> VarList, Expr *Step, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed &#39;linear&#39; clause.
This represents &#39;final&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:330
This represents &#39;mergeable&#39; clause in the &#39;#pragma omp ...&#39; directive.
bool isOpenMPTargetExecutionDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a target code offload directive.
static OMPFlushDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:595
void append(iterator I, iterator E)
Expr * CalcLastIteration
Calculation of last iteration.
Definition: StmtOpenMP.h:631
Represents a C++ nested-name-specifier or a global scope specifier.
Definition: DeclSpec.h:63
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
Definition: Expr.h:2710
static OMPTargetTeamsDistributeDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static DeclRefExpr * buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, bool WithInit)
bool isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a worksharing directive.
Preprocessor & PP
Definition: Sema.h:315
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
Definition: Decl.cpp:1869
const LangOptions & getLangOpts() const
Definition: Sema.h:1193
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value &#39;V&#39; and type &#39;type&#39;.
Definition: Expr.cpp:748
bool isTypeDependent() const
isTypeDependent - Determines whether this expression is type-dependent (C++ [temp.dep.expr]), which means that its type could change from one template instantiation to the next.
Definition: Expr.h:167
bool isScalarType() const
Definition: Type.h:6204
An ordinary object is located at an address in memory.
Definition: Specifiers.h:123
static OMPParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:384
static T filterLookupForUDR(SmallVectorImpl< UnresolvedSet< 8 >> &Lookups, const llvm::function_ref< T(ValueDecl *)> &Gen)
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const
Retrieve a nested-name-specifier with location information, copied into the given AST context...
Definition: DeclSpec.cpp:143
OMPClause * ActOnOpenMPSafelenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;safelen&#39; clause.
OMPClause * ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;default&#39; clause.
static bool ActOnOMPReductionKindClause(Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr *> UnresolvedReductions, ReductionData &RD)
StmtResult ActOnOpenMPTargetParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp target parallel for simd&#39; after parsing of the associated statemen...
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclBase.h:869
static OMPCopyinClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> SrcExprs, ArrayRef< Expr *> DstExprs, ArrayRef< Expr *> AssignmentOps)
Creates clause with a list of variables VL.
Expr * NUB
Update of UpperBound for statically sheduled &#39;omp for&#39; loops.
Definition: StmtOpenMP.h:653
static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, ArrayRef< OMPClause *> Clauses, ArrayRef< OpenMPDirectiveKind > AllowedNameModifiers)
Expr * Cond
Loop condition.
Definition: StmtOpenMP.h:635
VarDecl * ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D)
Initialize declare reduction construct initializer.
static OMPDistributeSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPTargetParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:724
DiagnosticsEngine & getDiagnostics() const
Definition: Sema.h:1197
static OMPTargetParallelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:700
Expr * PreCond
Loop pre-condition.
Definition: StmtOpenMP.h:633
child_range children()
OpenMP 4.0 [2.4, Array Sections].
Definition: ExprOpenMP.h:45
The expressions built for the OpenMP loop CodeGen for the whole collapsed loop nest.
Definition: StmtOpenMP.h:623
OMPClause * ActOnOpenMPWriteClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;write&#39; clause.
static bool checkSimdlenSafelenSpecified(Sema &S, const ArrayRef< OMPClause *> Clauses)
bool hasAttr() const
Definition: DeclBase.h:535
ConditionalOperator - The ?: ternary operator.
Definition: Expr.h:3269
static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, Expr *NumIterations, Sema &SemaRef, Scope *S, DSAStackTy *Stack)
Sema - This implements semantic analysis and AST building for C.
Definition: Sema.h:274
static bool checkNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, OpenMPDirectiveKind CurrentRegion, const DeclarationNameInfo &CurrentName, OpenMPDirectiveKind CancelRegion, SourceLocation StartLoc)
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1590
This represents &#39;threads&#39; clause in the &#39;#pragma omp ...&#39; directive.
ExprResult CreateBuiltinBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
CreateBuiltinBinOp - Creates a new built-in binary operation with operator Opc at location TokLoc...
Definition: SemaExpr.cpp:11577
Expr * getSimdlen() const
Return safe iteration space distance.
Definition: OpenMPClause.h:535
OMPClause * ActOnOpenMPNowaitClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;nowait&#39; clause.
StmtResult ActOnOpenMPSectionsDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp sections&#39; after parsing of the associated statement.
bool isMoreQualifiedThan(QualType Other) const
Determine whether this type is more qualified than the other given type, requiring exact equality for...
Definition: Type.h:5862
bool isOpenMPPrivate(OpenMPClauseKind Kind)
Checks if the specified clause is one of private clauses like &#39;private&#39;, &#39;firstprivate&#39;, &#39;reduction&#39; etc.
OpenMPClauseKind getClauseKind() const
Returns kind of OpenMP clause (private, shared, reduction, etc.).
Definition: OpenMPClause.h:79
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat)
Definition: Expr.cpp:1718
OverloadedOperatorKind getCXXOverloadedOperator() const
getCXXOverloadedOperator - If this name is the name of an overloadable operator in C++ (e...
static OMPCriticalDirective * Create(const ASTContext &C, const DeclarationNameInfo &Name, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive.
Definition: StmtOpenMP.cpp:310
static OMPDependClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, OpenMPDependClauseKind DepKind, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef< Expr *> VL)
Creates clause with a list of variables VL.
StmtResult ActOnOpenMPTeamsDistributeParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp teams distribute parallel for simd&#39; after parsing of the associate...
static bool checkGrainsizeNumTasksClauses(Sema &S, ArrayRef< OMPClause *> Clauses)
Expr * IterationVarRef
Loop iteration variable.
Definition: StmtOpenMP.h:625
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location, which defaults to the empty location.
static OMPDistributeParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Expr * Init
Distribute loop iteration variable init used when composing &#39;omp distribute&#39; with &#39;omp for&#39; in a same...
Definition: StmtOpenMP.h:609
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
StmtResult ActOnOpenMPDistributeParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp distribute parallel for simd&#39; after parsing of the associated stat...
Scope * getCurScope() const
Retrieve the parser&#39;s current scope.
Definition: Sema.h:10524
This represents implicit clause &#39;depend&#39; for the &#39;#pragma omp task&#39; directive.
This represents &#39;proc_bind&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:675
This represents &#39;capture&#39; clause in the &#39;#pragma omp atomic&#39; directive.
ValueDecl - Represent the declaration of a variable (in which case it is an lvalue) a function (in wh...
Definition: Decl.h:627
Expr - This represents one expression.
Definition: Expr.h:106
void StartOpenMPClause(OpenMPClauseKind K)
Start analysis of clauses.
QualType getPointeeType() const
Definition: Type.h:2440
Allow any unmodeled side effect.
Definition: Expr.h:598
SourceLocation End
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
Definition: Specifiers.h:104
bool isDeclScope(Decl *D)
isDeclScope - Return true if this is the scope that the specified decl is declared in...
Definition: Scope.h:315
int Id
Definition: ASTDiff.cpp:191
bool hasLocalStorage() const
hasLocalStorage - Returns true if a variable with function scope is a non-static local variable...
Definition: Decl.h:1025
void ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner)
Finish current declare reduction construct initializer.
static OMPTargetTeamsDistributeParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
const FunctionProtoType * T
void BuildBasePathArray(const CXXBasePaths &Paths, CXXCastPath &BasePath)
This represents &#39;simdlen&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:501
Stmt * IgnoreContainers(bool IgnoreCaptured=false)
Skip no-op (attributed, compound) container stmts and skip captured stmt at the top, if IgnoreCaptured is true.
Definition: Stmt.cpp:132
OMPThreadPrivateDecl * CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef< Expr *> VarList)
Builds a new OpenMPThreadPrivateDecl and checks its correctness.
bool isOpenMPPrivateDecl(ValueDecl *D, unsigned Level)
Check if the specified variable is used in &#39;private&#39; clause.
bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a parallel-kind directive.
OMPClause * ActOnOpenMPCopyinClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;copyin&#39; clause.
StmtResult ActOnOpenMPDistributeParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp distribute parallel for&#39; after parsing of the associated statement...
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:6368
OMPClause * ActOnOpenMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;mergeable&#39; clause.
Inits[]
Definition: OpenMPClause.h:140
static InitializedEntity InitializeVariable(VarDecl *Var)
Create the initialization entity for a variable.
static OMPMasterDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt)
Creates directive.
Definition: StmtOpenMP.cpp:292
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
Definition: DeclBase.cpp:132
static OMPTargetSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
OpenMPClauseKind
OpenMP clauses.
Definition: OpenMPKinds.h:33
bool isFileContext() const
Definition: DeclBase.h:1401
StmtResult ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp taskyield&#39;.
SourceLocation getBeginLoc() const
Definition: DeclSpec.h:72
DeclContext * getDeclContext()
Definition: DeclBase.h:425
void setOpenMPCaptureKind(FieldDecl *FD, ValueDecl *D, unsigned Level)
Sets OpenMP capture kind (OMPC_private, OMPC_firstprivate, OMPC_map etc.) for FD based on DSA for the...
bool isAnyComplexType() const
Definition: Type.h:6023
static OMPTargetDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:674
An abstract interface that should be implemented by listeners that want to be notified when an AST en...
static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, Sema &SemaRef, DSAStackTy *Stack, ValueDecl *VD)
OMPClause * ActOnOpenMPDefaultmapClause(OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, SourceLocation KindLoc, SourceLocation EndLoc)
Called on well-formed &#39;defaultmap&#39; clause.
static FloatingLiteral * Create(const ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L)
Definition: Expr.cpp:774
bool RequireCompleteType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Definition: SemaType.cpp:7394
OMPClause * ActOnOpenMPPrivateClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;private&#39; clause.
bool builtAll()
Check if all the expressions are built (does not check the worksharing ones).
Definition: StmtOpenMP.h:688
This represents &#39;ordered&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:925
Expr * PrevUB
PreviousUpperBound - local variable passed to runtime in the enclosing schedule or null if that does ...
Definition: StmtOpenMP.h:659
static OMPOrderedDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive.
Definition: StmtOpenMP.cpp:617
QualType getType() const
Definition: Expr.h:128
SmallVector< sema::FunctionScopeInfo *, 4 > FunctionScopes
Stack containing information about each of the nested function, block, and method scopes that are cur...
Definition: Sema.h:537
StmtResult ActOnOpenMPTargetTeamsDistributeSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp target teams distribute simd&#39; after parsing of the associated stat...
bool isSingleResult() const
Determines if this names a single result which is not an unresolved value using decl.
Definition: Lookup.h:311
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:1335
bool isInvalid() const
Definition: Ownership.h:158
OMPClause * ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind, ArrayRef< unsigned > Arguments, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, ArrayRef< SourceLocation > ArgumentsLoc, SourceLocation DelimLoc, SourceLocation EndLoc)
OMPClause * ActOnOpenMPInReductionClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr *> UnresolvedReductions=llvm::None)
Called on well-formed &#39;in_reduction&#39; clause.
bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a taskloop directive.
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
Definition: ASTContext.h:1333
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
Definition: DeclBase.cpp:1041
OMPClause * ActOnOpenMPNumTasksClause(Expr *NumTasks, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;num_tasks&#39; clause.
This represents &#39;collapse&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:555
ValueDecl * getDecl()
Definition: Expr.h:1041
bool isUsable() const
Definition: Ownership.h:159
Represents a C++ conversion function within a class.
Definition: DeclCXX.h:2682
Expr * NLB
Update of LowerBound for statically sheduled omp loops for outer loop in combined constructs (e...
Definition: StmtOpenMP.h:615
StmtResult ActOnOpenMPTaskLoopDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp taskloop&#39; after parsing of the associated statement.
The result type of a method or function.
bool isNull() const
Return true if this QualType doesn&#39;t point to a type yet.
Definition: Type.h:719
OpenMPProcBindClauseKind
OpenMP attributes for &#39;proc_bind&#39; clause.
Definition: OpenMPKinds.h:51
StmtResult ActOnOpenMPParallelDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp parallel&#39; after parsing of the associated statement.
void checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, SourceLocation IdLoc=SourceLocation())
Check declaration inside target region.
OMPClause * ActOnOpenMPFlushClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;flush&#39; pseudo clause.
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition: Decl.cpp:1977
DefaultDataSharingAttributes
Default data sharing attributes, which can be applied to directive.
Definition: SemaOpenMP.cpp:45
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1...
Definition: Expr.h:1463
bool isDirectInit() const
Whether the initializer is a direct-initializer (list or call).
Definition: Decl.h:1276
OMPClause * ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;device&#39; clause.
StmtResult ActOnOpenMPTeamsDistributeSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp teams distribute simd&#39; after parsing of the associated statement...
Expr * NumIterations
Loop number of iterations.
Definition: StmtOpenMP.h:629
static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)
Create a copy initialization.
ExprResult ActOnFinishFullExpr(Expr *Expr)
Definition: Sema.h:5244
static ExprResult WidenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef)
Convert integer expression E to make it have at least Bits bits.
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
Definition: Expr.h:412
This represents &#39;seq_cst&#39; clause in the &#39;#pragma omp atomic&#39; directive.
AttrVec & getAttrs()
Definition: DeclBase.h:477
This represents &#39;untied&#39; clause in the &#39;#pragma omp ...&#39; directive.
bool hasAttrs() const
Definition: DeclBase.h:471
ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)
Definition: SemaCast.cpp:2652
ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E)
Definition: SemaExpr.cpp:3489
static OMPForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:123
Expr * ST
Stride - local variable passed to runtime.
Definition: StmtOpenMP.h:647
void addAttr(Attr *A)
Definition: DeclBase.h:484
SmallVector< Expr *, 4 > PrivateCounters
PrivateCounters Loop counters.
Definition: StmtOpenMP.h:673
This represents &#39;num_teams&#39; clause in the &#39;#pragma omp ...&#39; directive.
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class...
Definition: Expr.h:868
static bool CheckArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, const Expr *E, QualType BaseQTy)
Return true if it can be proven that the provided array expression (array section or array subscript)...
static ExprResult BuildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, llvm::MapVector< Expr *, DeclRefExpr *> &Captures)
Build &#39;VarRef = Start.
#define false
Definition: stdbool.h:33
Kind
This captures a statement into a function.
Definition: Stmt.h:2058
OMPClause * ActOnOpenMPSharedClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;shared&#39; clause.
QualType getCanonicalType() const
Definition: Type.h:5757
OMPClause * ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef< Expr *> Vars, Expr *TailExpr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation DepLinMapLoc)
ActionResult - This structure is used while parsing/acting on expressions, stmts, etc...
Definition: Ownership.h:144
SmallVector< Expr *, 4 > Counters
Counters Loop counters.
Definition: StmtOpenMP.h:671
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on a template...
Definition: Expr.h:191
StmtResult ActOnOpenMPTargetTeamsDistributeDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp target teams distribute&#39; after parsing of the associated statement...
ASTContext & getASTContext() const
Definition: Sema.h:1200
StmtResult ActOnOpenMPDistributeSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp distribute simd&#39; after parsing of the associated statement...
Encodes a location in the source.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
This represents &#39;hint&#39; clause in the &#39;#pragma omp ...&#39; directive.
OpenMPDependClauseKind
OpenMP attributes for &#39;depend&#39; clause.
Definition: OpenMPKinds.h:76
SourceLocation getOperatorLoc() const
Definition: Expr.h:3023
This represents &#39;#pragma omp declare reduction ...&#39; directive.
Definition: DeclOpenMP.h:102
Pseudo declaration for capturing expressions.
Definition: DeclOpenMP.h:187
StmtResult ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, OpenMPDirectiveKind CancelRegion, ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
Definition: Type.h:1874
This is a basic class for representing single OpenMP executable directive.
Definition: StmtOpenMP.h:33
static OMPMapClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> Vars, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists, OpenMPMapClauseKind TypeModifier, OpenMPMapClauseKind Type, bool TypeIsImplicit, SourceLocation TypeLoc)
Creates clause with a list of variables VL.
VarDecl * IsOpenMPCapturedDecl(ValueDecl *D)
Check if the specified variable is used in one of the private clauses (private, firstprivate, lastprivate, reduction etc.) in OpenMP constructs.
DeclarationName getName() const
getName - Returns the embedded declaration name.
This represents &#39;schedule&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:744
static OMPParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:335
static Expr * buildPostUpdate(Sema &S, ArrayRef< Expr *> PostUpdates)
Build postupdate expression for the given list of postupdates expressions.
DeclStmt - Adaptor class for mixing declarations with statements and expressions. ...
Definition: Stmt.h:487
void setReferenced(bool R=true)
Definition: DeclBase.h:581
OpenMPDirectiveKind
OpenMP directives.
Definition: OpenMPKinds.h:23
IdentifierTable & getIdentifierTable()
Definition: Preprocessor.h:823
ExprObjectKind
A further classification of the kind of object referenced by an l-value or x-value.
Definition: Specifiers.h:121
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
DeclarationNameInfo getDirectiveName() const
Return name of the directive.
Definition: StmtOpenMP.h:1482
static OMPParallelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:57
static OMPTargetExitDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:818
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:186
static ExprResult BuildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, llvm::MapVector< Expr *, DeclRefExpr *> *Captures=nullptr)
Build &#39;VarRef = Start + Iter * Step&#39;.
SourceLocation getColonLoc() const
Definition: ExprOpenMP.h:109
StmtResult ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Called on well-formed &#39;#pragma omp cancellation point&#39;.
OpenMPLinearClauseKind Modifier
Modifier of &#39;linear&#39; clause.
Definition: OpenMPClause.h:91
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
Definition: Decl.h:1067
ExprResult DefaultLvalueConversion(Expr *E)
Definition: SemaExpr.cpp:530
C-style initialization with assignment.
Definition: Decl.h:811
Expr * PrevEUB
PrevEUB - expression similar to EUB but to be used when loop scheduling uses PrevLB and PrevUB (e...
Definition: StmtOpenMP.h:669
This file defines OpenMP nodes for declarative directives.
static OMPSharedClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL)
Creates clause with a list of variables VL.
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
This is a basic class for representing single OpenMP clause.
Definition: OpenMPClause.h:51
OMPClause * ActOnOpenMPUpdateClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;update&#39; clause.
CanQualType VoidTy
Definition: ASTContext.h:996
bool isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind)
Checks if the specified directive kind is one of the composite or combined directives that need loop ...
void addDecl(NamedDecl *D)
Definition: UnresolvedSet.h:89
OMPClause * ActOnOpenMPCopyprivateClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;copyprivate&#39; clause.
Describes the kind of initialization being performed, along with location information for tokens rela...
bool isValueDependent() const
isValueDependent - Determines whether this expression is value-dependent (C++ [temp.dep.constexpr]).
Definition: Expr.h:149
StmtResult ActOnOpenMPOrderedDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp ordered&#39; after parsing of the associated statement.
bool isAnyPointerType() const
Definition: Type.h:5946
static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, OpenMPDirectiveKind CancelRegion, SourceLocation StartLoc)
This declaration is only a declaration.
Definition: Decl.h:1138
StmtResult ActOnOpenMPTargetDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp target&#39; after parsing of the associated statement.
Stmt * getCapturedStmt()
Retrieve the statement being captured.
Definition: Stmt.h:2159
OMPClause * ActOnOpenMPSeqCstClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;seq_cst&#39; clause.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language...
Definition: Expr.h:249
StmtResult ActOnOpenMPTeamsDistributeDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp teams distribute&#39; after parsing of the associated statement...
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required...
Definition: DeclBase.cpp:399
Updates[]
Definition: OpenMPClause.h:140
static void checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, MappableVarListInfo &MVLI, SourceLocation StartLoc, OpenMPMapClauseKind MapType=OMPC_MAP_unknown, bool IsMapTypeImplicit=false)
DistCombinedHelperExprs DistCombinedFields
Expressions used when combining OpenMP loop pragmas.
Definition: StmtOpenMP.h:684
static OMPForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:172
Expr * LB
LowerBound - local variable passed to runtime.
Definition: StmtOpenMP.h:643
void clear(unsigned Size)
Initialize all the fields to null.
Definition: StmtOpenMP.h:696
DefaultMapAttributes
Attributes of the defaultmap clause.
Definition: SemaOpenMP.cpp:52
Expr * Init
Loop iteration variable init.
Definition: StmtOpenMP.h:637
ExprResult PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc, Expr *Op)
#define DSAStack
SourceLocation getLocStart() const LLVM_READONLY
Definition: Expr.cpp:450
static OMPAlignedClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, Expr *A)
Creates clause with a list of variables VL and alignment A.
bool isVLASupported() const
Whether target supports variable-length arrays.
Definition: TargetInfo.h:951
bool isInvalid() const
An error occurred during parsing of the scope specifier.
Definition: DeclSpec.h:194
StmtResult ActOnOpenMPTargetParallelDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp target parallel&#39; after parsing of the associated statement...
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
Definition: ASTContext.h:2214
virtual bool isOutOfLine() const
Determine whether this declaration is declared out of line (outside its semantic context).
Definition: Decl.cpp:80
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
Definition: Type.h:1864
static OMPSingleDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:266
static OMPPrivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> PrivateVL)
Creates clause with a list of variables VL.
OMPClause * ActOnOpenMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Called on well-formed &#39;dist_schedule&#39; clause.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Definition: Expr.cpp:216
OMPClause * ActOnOpenMPSIMDClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;simd&#39; clause.
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat &#39;semantics&#39; for the specified scalar floating point type.
Expr * getLHS() const
Definition: Expr.h:3029
SourceLocation getLocEnd() const
Returns the ending location of the clause.
Definition: OpenMPClause.h:70
static Expr * getCollapseNumberExpr(ArrayRef< OMPClause *> Clauses)
OMPClause * ActOnOpenMPNumThreadsClause(Expr *NumThreads, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;num_threads&#39; clause.
static DeclGroupRef Create(ASTContext &C, Decl **Decls, unsigned NumDecls)
Definition: DeclGroup.h:69
* Finals[]
Definition: OpenMPClause.h:141
QualType withRestrict() const
Definition: Type.h:834
static OMPCapturedExprDecl * Create(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, QualType T, SourceLocation StartLoc)
Definition: DeclOpenMP.cpp:92
StmtResult ActOnOpenMPParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp parallel for&#39; after parsing of the associated statement.
OpenMPScheduleClauseModifier
OpenMP modifiers for &#39;schedule&#39; clause.
Definition: OpenMPKinds.h:67
Dataflow Directional Tag Classes.
std::string getAsString() const
getAsString - Retrieve the human-readable string for this name.
StmtResult ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp target teams distribute parallel for simd&#39; after parsing of the as...
This represents &#39;device&#39; clause in the &#39;#pragma omp ...&#39; directive.
bool isValid() const
Return true if this is a valid SourceLocation object.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1256
static bool CheckOMPArraySectionConstantForReduction(ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, SmallVectorImpl< llvm::APSInt > &ArraySizes)
SmallVector< Expr *, 4 > Inits
Expressions for loop counters inits for CodeGen.
Definition: StmtOpenMP.h:675
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
Definition: OperatorKinds.h:22
static OMPThreadPrivateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef< Expr *> VL)
Definition: DeclOpenMP.cpp:29
const Scope * getParent() const
getParent - Return the scope that this is nested in.
Definition: Scope.h:224
void ActOnCapturedRegionError()
Definition: SemaStmt.cpp:4153
static std::string getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, ArrayRef< unsigned > Exclude=llvm::None)
static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, OpenMPDirectiveKind NameModifier=OMPD_unknown)
static OMPParallelSectionsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:433
OMPClause * ActOnOpenMPSimpleClause(OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
const Expr * getInit() const
Definition: Decl.h:1212
void ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope)
Initialization of captured region for OpenMP region.
NamedDecl * getCorrectionDecl() const
Gets the pointer to the declaration of the typo correction.
DeclarationName - The name of a declaration.
bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a simd directive.
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup.
Definition: Lookup.h:520
static OMPCapturedExprDecl * buildCaptureDecl(Sema &S, IdentifierInfo *Id, Expr *CaptureExpr, bool WithInit, bool AsExpression)
OMPClause * ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;map&#39; clause.
bool shouldDiagnoseTargetSupportFromOpenMP() const
Return true if (un)supported features for the current target should be diagnosed if OpenMP (offloadin...
Definition: Sema.h:8677
OMPClause * ActOnOpenMPUseDevicePtrClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;use_device_ptr&#39; clause.
This represents clause &#39;linear&#39; in the &#39;#pragma omp ...&#39; directives.
bool isAmbiguous(CanQualType BaseType)
Determine whether the path from the most-derived type to the given base type is ambiguous (i...
bool isIntegerConstantExpr(llvm::APSInt &Result, const ASTContext &Ctx, SourceLocation *Loc=nullptr, bool isEvaluated=true) const
isIntegerConstantExpr - Return true if this expression is a valid integer constant expression...
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveEnd(Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid)
Called at the end of &#39;#pragma omp declare reduction&#39;.
bool isOpenMPThreadPrivate(OpenMPClauseKind Kind)
Checks if the specified clause is one of threadprivate clauses like &#39;threadprivate&#39;, &#39;copyin&#39; or &#39;copyprivate&#39;.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspnd...
static OMPFirstprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> PrivateVL, ArrayRef< Expr *> InitVL, Stmt *PreInit)
Creates clause with a list of variables VL.
static bool CheckArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, const Expr *E, QualType BaseQTy)
static OMPFromClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> Vars, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit)
AddInitializerToDecl - Adds the initializer Init to the declaration dcl.
Definition: SemaDecl.cpp:10156
bool isValid() const
A scope specifier is present, and it refers to a real scope.
Definition: DeclSpec.h:196
Expr * IgnoreParenImpCasts() LLVM_READONLY
IgnoreParenImpCasts - Ignore parentheses and implicit casts.
Definition: Expr.cpp:2552
ExprResult IgnoredValueConversions(Expr *E)
IgnoredValueConversions - Given that an expression&#39;s result is syntactically ignored, perform any conversions that are required.
Not an overloaded operator.
Definition: OperatorKinds.h:23
void getOpenMPCaptureRegions(llvm::SmallVectorImpl< OpenMPDirectiveKind > &CaptureRegions, OpenMPDirectiveKind DKind)
Return the captured regions of an OpenMP directive.
void ActOnFinishOpenMPDeclareTargetDirective()
Called at the end of target region i.e. &#39;#pragme omp end declare target&#39;.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:3976
Complex values, per C99 6.2.5p11.
Definition: Type.h:2223
bool isInOpenMPTargetExecutionDirective() const
Return true inside OpenMP target region.
bool isOpenMPDistributeDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a distribute directive.
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Definition: Expr.h:2121
This file defines OpenMP AST classes for executable directives and clauses.
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
Definition: Type.h:6191
T * getAttr() const
Definition: DeclBase.h:531
void setSeverity(diag::kind Diag, diag::Severity Map, SourceLocation Loc)
This allows the client to specify that certain warnings are ignored.
Definition: Diagnostic.cpp:245
static OMPSectionsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:221
const llvm::APInt & getSize() const
Definition: Type.h:2636
CanQualType DependentTy
Definition: ASTContext.h:1013
bool isDeclInScope(NamedDecl *D, DeclContext *Ctx, Scope *S=nullptr, bool AllowInlineNamespace=false)
isDeclInScope - If &#39;Ctx&#39; is a function/method, isDeclInScope returns true if &#39;D&#39; is in Scope &#39;S&#39;...
Definition: SemaDecl.cpp:1410
OMPClause * ActOnOpenMPIsDevicePtrClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;is_device_ptr&#39; clause.
void ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, VarDecl *OmpPrivParm)
Finish current declare reduction construct initializer.
static Expr * getExprAsWritten(Expr *E)
Definition: SemaOpenMP.cpp:574
bool isStaticLocal() const
isStaticLocal - Returns true if a variable with function scope is a static local variable.
Definition: Decl.h:1049
Expr * Inc
Loop increment.
Definition: StmtOpenMP.h:639
DeclContext * getCurLexicalContext() const
Definition: Sema.h:10535
OMPClause * ActOnOpenMPToClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;to&#39; clause.
OpenMPScheduleClauseKind
OpenMP attributes for &#39;schedule&#39; clause.
Definition: OpenMPKinds.h:59
bool popMappings(SourceLocation Loc)
Pops the current DiagMappings off the top of the stack, causing the new top of the stack to be the ac...
Definition: Diagnostic.cpp:101
CXXBasePath & front()
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:2419
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
Definition: ASTContext.h:2190
OMPClause * ActOnOpenMPReductionClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr *> UnresolvedReductions=llvm::None)
Called on well-formed &#39;reduction&#39; clause.
QualType ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, TypeResult ParsedType)
Check if the specified type is allowed to be used in &#39;omp declare reduction&#39; construct.
ExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *InputExpr)
Definition: SemaExpr.cpp:12164
OpenMPDefaultClauseKind
OpenMP attributes for &#39;default&#39; clause.
Definition: OpenMPKinds.h:43
void addDecl(Decl *D)
Add the declaration D into this context.
Definition: DeclBase.cpp:1425
static OMPTargetTeamsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
SourceLocation getExprLoc() const LLVM_READONLY
Definition: Expr.h:3022
This represents &#39;write&#39; clause in the &#39;#pragma omp atomic&#39; directive.
const char * getOpenMPDirectiveName(OpenMPDirectiveKind Kind)
Definition: OpenMPKinds.cpp:31
StmtResult ActOnOpenMPTargetTeamsDistributeParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp target teams distribute parallel for&#39; after parsing of the associa...
const Type * getTypePtrOrNull() const
Definition: Type.h:5722
void markUsed(ASTContext &C)
Mark the declaration used, in the sense of odr-use.
Definition: DeclBase.cpp:414
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
Definition: ASTContext.h:2007
static OMPTaskLoopDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:866
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types...
Definition: Type.cpp:1986
ASTMutationListener * getASTMutationListener() const
Retrieve a pointer to the AST mutation listener associated with this AST context, if any...
Definition: ASTContext.h:1063
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Definition: ASTContext.h:2174
bool isSet() const
Deprecated.
Definition: DeclSpec.h:209
Expr * UB
DistributeUpperBound - used when composing &#39;omp distribute&#39; with &#39;omp for&#39; in a same construct...
Definition: StmtOpenMP.h:602
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
Definition: SemaDecl.cpp:13020
bool hasMutableFields() const
Determine whether this class, or any of its class subobjects, contains a mutable field.
Definition: DeclCXX.h:1304
StmtResult ActOnOpenMPTeamsDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp teams&#39; after parsing of the associated statement.
CapturedDecl * getCapturedDecl()
Retrieve the outlined function declaration.
Definition: Stmt.cpp:1100
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
Call-style initialization (C++98)
Definition: Decl.h:814
static OMPTaskyieldDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
Definition: StmtOpenMP.cpp:482
ExprResult BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, SourceLocation Loc, const CXXScopeSpec *SS=nullptr)
Definition: SemaExpr.cpp:1637
OpenMPScheduleClauseModifier getSecondScheduleModifier() const
Get the second modifier of the clause.
Definition: OpenMPClause.h:879
void Deallocate(void *Ptr) const
Definition: ASTContext.h:656
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition: Expr.h:2387
static OMPTargetDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:774
StmtResult ActOnOpenMPTaskgroupDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp taskgroup&#39;.
void setSuppressAllDiagnostics(bool Val=true)
Suppress all diagnostics, to silence the front end when we know that we don&#39;t want any more diagnosti...
Definition: Diagnostic.h:548
Expr * UB
UpperBound - local variable passed to runtime.
Definition: StmtOpenMP.h:645
static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, Sema &SemaRef, Decl *D)
Describes the sequence of initializations required to initialize a given object or reference with a s...
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition: Type.h:5798
This represents &#39;nowait&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:975
void setEnd(SourceLocation e)
void ActOnOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id, OMPDeclareTargetDeclAttr::MapTypeTy MT, NamedDeclSetType &SameDirectiveDecls)
Called on correct id-expression from the &#39;#pragma omp declare target&#39;.
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g., it is an signed integer type or a vector.
Definition: Type.cpp:1830
Represents a C++ struct/union/class.
Definition: DeclCXX.h:299
OpenMPScheduleClauseModifier getFirstScheduleModifier() const
Get the first modifier of the clause.
Definition: OpenMPClause.h:874
This represents &#39;num_tasks&#39; clause in the &#39;#pragma omp ...&#39; directive.
StmtResult ActOnOpenMPTargetSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp target simd&#39; after parsing of the associated statement.
sema::FunctionScopeInfo * getCurFunction() const
Definition: Sema.h:1320
static QualType getBaseOriginalType(const Expr *Base)
Return original type of the base expression for array section.
Definition: Expr.cpp:4071
StmtResult ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp taskwait&#39;.
static OMPBarrierDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
Definition: StmtOpenMP.cpp:497
Privates[]
Gets the list of initial values for linear variables.
Definition: OpenMPClause.h:140
OpenMPMapClauseKind
OpenMP mapping kind for &#39;map&#39; clause.
Definition: OpenMPKinds.h:92
void addHiddenDecl(Decl *D)
Add the declaration D to this context without modifying any lookup tables.
Definition: DeclBase.cpp:1399
SourceLocation getFirstScheduleModifierLoc() const
Get the first modifier location.
Definition: OpenMPClause.h:890
Do not present this diagnostic, ignore it.
AccessResult CheckBaseClassAccess(SourceLocation AccessLoc, QualType Base, QualType Derived, const CXXBasePath &Path, unsigned DiagID, bool ForceCheck=false, bool ForceUnprivileged=false)
Checks access for a hierarchy conversion.
StmtResult ActOnOpenMPForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp for&#39; after parsing of the associated statement.
OMPClause * ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;thread_limit&#39; clause.
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
Definition: Sema.h:328
bool containsUnexpandedParameterPack() const
Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates)...
Definition: Expr.h:214
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
StmtResult ActOnOpenMPAtomicDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp atomic&#39; after parsing of the associated statement.
static OMPSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:83
StmtResult ActOnOpenMPSingleDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp single&#39; after parsing of the associated statement.
iterator end() const
Definition: Lookup.h:339
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:265
StmtResult ActOnOpenMPSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, llvm::DenseMap< ValueDecl *, Expr *> &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp simd&#39; after parsing of the associated statement.
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition: Expr.h:2209
DeclGroupPtrTy ActOnOpenMPThreadprivateDirective(SourceLocation Loc, ArrayRef< Expr *> VarList)
Called on well-formed &#39;#pragma omp threadprivate&#39;.
StringRef getName() const
getName - Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:270
ExprResult ExprError()
Definition: Ownership.h:267
This represents &#39;dist_schedule&#39; clause in the &#39;#pragma omp ...&#39; directive.
static VarDecl * buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, StringRef Name, const AttrVec *Attrs=nullptr)
Build a variable declaration for OpenMP loop iteration variable.
Definition: SemaOpenMP.cpp:805
static OMPTaskwaitDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
Definition: StmtOpenMP.cpp:511
Expr * Cond
Distribute Loop condition used when composing &#39;omp distribute&#39; with &#39;omp for&#39; in a same construct...
Definition: StmtOpenMP.h:612
Stmt * PreInits
Init statement for all captured expressions.
Definition: StmtOpenMP.h:681
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:1858
bool isEvaluatable(const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects) const
isEvaluatable - Call EvaluateAsRValue to see if this expression can be constant folded without side-e...
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:956
Expr * getRHS() const
Definition: Expr.h:3031
void ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init)
Check if the current region is an OpenMP loop region and if it is, mark loop control variable...
static OMPTargetTeamsDistributeSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
bool isPointerType() const
Definition: Type.h:5942
static OverloadedOperatorKind getOverloadedOperator(Opcode Opc)
Retrieve the overloaded operator kind that corresponds to the given binary opcode.
Definition: Expr.cpp:1809
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
static OMPFlushClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL)
Creates clause with a list of variables VL.
OMPClause * ActOnOpenMPAlignedClause(ArrayRef< Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed &#39;aligned&#39; clause.
DefinitionKind isThisDeclarationADefinition(ASTContext &) const
Check whether this declaration is a definition.
Definition: Decl.cpp:1980
bool isStaticDataMember() const
Determines whether this is a static data member.
Definition: Decl.h:1126
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
Definition: Lookup.h:586
SmallVector< CompoundScopeInfo, 4 > CompoundScopes
The stack of currently active compound stamement scopes in the function.
Definition: ScopeInfo.h:180
QualType getType() const
Definition: Decl.h:638
bool empty() const
Return true if no decls were found.
Definition: Lookup.h:342
An l-value expression is a reference to an object with independent storage.
Definition: Specifiers.h:111
StmtResult ActOnOpenMPParallelSectionsDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp parallel sections&#39; after parsing of the associated statement...
static OMPCancelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion)
Creates directive.
Definition: StmtOpenMP.cpp:571
bool isOpenMPLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a directive with an associated loop construct.
OMPClause * ActOnOpenMPFromClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;from&#39; clause.
Expr * IL
IsLastIteration - local flag variable passed to runtime.
Definition: StmtOpenMP.h:641
A trivial tuple used to represent a source range.
ASTContext & Context
Definition: Sema.h:316
NamedDecl - This represents a decl with a name.
Definition: Decl.h:245
static bool CheckMapConflicts(Sema &SemaRef, DSAStackTy *DSAS, ValueDecl *VD, Expr *E, bool CurrentRegionOnly, OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, OpenMPClauseKind CKind)
static OMPCancellationPointDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Creates directive.
Definition: StmtOpenMP.cpp:550
bool isTranslationUnit() const
Definition: DeclBase.h:1405
void setAccess(AccessSpecifier AS)
Definition: DeclBase.h:455
CanQualType BoolTy
Definition: ASTContext.h:997
OMPClause * ActOnOpenMPOrderedClause(SourceLocation StartLoc, SourceLocation EndLoc, SourceLocation LParenLoc=SourceLocation(), Expr *NumForLoops=nullptr)
Called on well-formed &#39;ordered&#39; clause.
Directive - Abstract class representing a parsed verify directive.
QualType getVariableArrayType(QualType EltTy, Expr *NumElts, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals, SourceRange Brackets) const
Return a non-unique reference to the type for a variable array of the specified element type...
OMPClause * ActOnOpenMPCollapseClause(Expr *NumForLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;collapse&#39; clause.
bool isConstant(const ASTContext &Ctx) const
Definition: Type.h:789
ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
Definition: SemaExpr.cpp:12058
static OMPClauseWithPostUpdate * get(OMPClause *C)
iterator begin() const
Definition: Lookup.h:338
Describes an entity that is being initialized.
NamedDecl * getRepresentativeDecl() const
Fetches a representative decl. Useful for lazy diagnostics.
Definition: Lookup.h:527
SourceLocation getLocStart() const LLVM_READONLY
Definition: Stmt.cpp:277
bool hasInit() const
Definition: Decl.cpp:2115
SourceLocation getBegin() const
SourceLocation ColonLoc
Location of &#39;:&#39;.
Definition: OpenMPClause.h:97
static OMPTaskLoopSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:915
This represents &#39;#pragma omp threadprivate ...&#39; directive.
Definition: DeclOpenMP.h:39
bool isExternCXXContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
Definition: DeclBase.cpp:1107
Represents the canonical version of C arrays with a specified constant size.
Definition: Type.h:2618
bool getSuppressAllDiagnostics() const
Definition: Diagnostic.h:551
void clear()
Clears out any current state.
Definition: Lookup.h:557
OMPClause * ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Attr - This represents one attribute.
Definition: Attr.h:43
SourceLocation getLocation() const
Definition: DeclBase.h:416
Expr * getLength()
Get length of array section.
Definition: ExprOpenMP.h:99
QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const
getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth, signed/unsigned.
bool isOpenMPNestingTeamsDirective(OpenMPDirectiveKind DKind)
Checks if the specified composite/combined directive constitutes a teams directive in the outermost n...
Helper class that creates diagnostics with optional template instantiation stacks.
Definition: Sema.h:1223
Expr * IgnoreParens() LLVM_READONLY
IgnoreParens - Ignore parentheses.
Definition: Expr.cpp:2434
static OMPLinearClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, OpenMPLinearClauseKind Modifier, SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> PL, ArrayRef< Expr *> IL, Expr *Step, Expr *CalcStep, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL and a linear step Step.
ExprResult getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, ExprObjectKind OK, SourceLocation Loc)
CanQualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
Expr * getBase()
An array section can be written only as Base[LowerBound:Length].
Definition: ExprOpenMP.h:82