clang  8.0.0
SemaOpenMP.cpp
Go to the documentation of this file.
1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 /// \file
10 /// This file implements semantic analysis for OpenMP directives and
11 /// clauses.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #include "TreeTransform.h"
16 #include "clang/AST/ASTContext.h"
19 #include "clang/AST/Decl.h"
20 #include "clang/AST/DeclCXX.h"
21 #include "clang/AST/DeclOpenMP.h"
22 #include "clang/AST/StmtCXX.h"
23 #include "clang/AST/StmtOpenMP.h"
24 #include "clang/AST/StmtVisitor.h"
25 #include "clang/AST/TypeOrdering.h"
28 #include "clang/Sema/Lookup.h"
29 #include "clang/Sema/Scope.h"
30 #include "clang/Sema/ScopeInfo.h"
32 #include "llvm/ADT/PointerEmbeddedInt.h"
33 using namespace clang;
34 
35 //===----------------------------------------------------------------------===//
36 // Stack of data-sharing attributes for variables
37 //===----------------------------------------------------------------------===//
38 
40  Sema &SemaRef, Expr *E,
42  OpenMPClauseKind CKind, bool NoDiagnose);
43 
44 namespace {
45 /// Default data sharing attributes, which can be applied to directive.
47  DSA_unspecified = 0, /// Data sharing attribute not specified.
48  DSA_none = 1 << 0, /// Default data sharing attribute 'none'.
49  DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'.
50 };
51 
52 /// Attributes of the defaultmap clause.
54  DMA_unspecified, /// Default mapping is not specified.
55  DMA_tofrom_scalar, /// Default mapping is 'tofrom:scalar'.
56 };
57 
58 /// Stack for tracking declarations used in OpenMP directives and
59 /// clauses and their data-sharing attributes.
60 class DSAStackTy {
61 public:
62  struct DSAVarData {
65  const Expr *RefExpr = nullptr;
66  DeclRefExpr *PrivateCopy = nullptr;
67  SourceLocation ImplicitDSALoc;
68  DSAVarData() = default;
69  DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
70  const Expr *RefExpr, DeclRefExpr *PrivateCopy,
71  SourceLocation ImplicitDSALoc)
72  : DKind(DKind), CKind(CKind), RefExpr(RefExpr),
73  PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {}
74  };
75  using OperatorOffsetTy =
77  using DoacrossDependMapTy =
78  llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
79 
80 private:
81  struct DSAInfo {
82  OpenMPClauseKind Attributes = OMPC_unknown;
83  /// Pointer to a reference expression and a flag which shows that the
84  /// variable is marked as lastprivate(true) or not (false).
85  llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
86  DeclRefExpr *PrivateCopy = nullptr;
87  };
88  using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
89  using AlignedMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
90  using LCDeclInfo = std::pair<unsigned, VarDecl *>;
91  using LoopControlVariablesMapTy =
92  llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
93  /// Struct that associates a component with the clause kind where they are
94  /// found.
95  struct MappedExprComponentTy {
98  };
99  using MappedExprComponentsTy =
100  llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
101  using CriticalsWithHintsTy =
102  llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
103  struct ReductionData {
104  using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
105  SourceRange ReductionRange;
106  llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
107  ReductionData() = default;
108  void set(BinaryOperatorKind BO, SourceRange RR) {
109  ReductionRange = RR;
110  ReductionOp = BO;
111  }
112  void set(const Expr *RefExpr, SourceRange RR) {
113  ReductionRange = RR;
114  ReductionOp = RefExpr;
115  }
116  };
117  using DeclReductionMapTy =
118  llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
119 
120  struct SharingMapTy {
121  DeclSAMapTy SharingMap;
122  DeclReductionMapTy ReductionMap;
123  AlignedMapTy AlignedMap;
124  MappedExprComponentsTy MappedExprComponents;
125  LoopControlVariablesMapTy LCVMap;
126  DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
127  SourceLocation DefaultAttrLoc;
128  DefaultMapAttributes DefaultMapAttr = DMA_unspecified;
129  SourceLocation DefaultMapAttrLoc;
131  DeclarationNameInfo DirectiveName;
132  Scope *CurScope = nullptr;
133  SourceLocation ConstructLoc;
134  /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
135  /// get the data (loop counters etc.) about enclosing loop-based construct.
136  /// This data is required during codegen.
137  DoacrossDependMapTy DoacrossDepends;
138  /// first argument (Expr *) contains optional argument of the
139  /// 'ordered' clause, the second one is true if the regions has 'ordered'
140  /// clause, false otherwise.
142  unsigned AssociatedLoops = 1;
143  const Decl *PossiblyLoopCounter = nullptr;
144  bool NowaitRegion = false;
145  bool CancelRegion = false;
146  bool LoopStart = false;
147  SourceLocation InnerTeamsRegionLoc;
148  /// Reference to the taskgroup task_reduction reference expression.
149  Expr *TaskgroupReductionRef = nullptr;
150  llvm::DenseSet<QualType> MappedClassesQualTypes;
151  SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
152  Scope *CurScope, SourceLocation Loc)
153  : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
154  ConstructLoc(Loc) {}
155  SharingMapTy() = default;
156  };
157 
158  using StackTy = SmallVector<SharingMapTy, 4>;
159 
160  /// Stack of used declaration and their data-sharing attributes.
161  DeclSAMapTy Threadprivates;
162  const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
164  /// true, if check for DSA must be from parent directive, false, if
165  /// from current directive.
166  OpenMPClauseKind ClauseKindMode = OMPC_unknown;
167  Sema &SemaRef;
168  bool ForceCapturing = false;
169  /// true if all the vaiables in the target executable directives must be
170  /// captured by reference.
171  bool ForceCaptureByReferenceInTargetExecutable = false;
172  CriticalsWithHintsTy Criticals;
173 
174  using iterator = StackTy::const_reverse_iterator;
175 
176  DSAVarData getDSA(iterator &Iter, ValueDecl *D) const;
177 
178  /// Checks if the variable is a local for OpenMP region.
179  bool isOpenMPLocal(VarDecl *D, iterator Iter) const;
180 
181  bool isStackEmpty() const {
182  return Stack.empty() ||
183  Stack.back().second != CurrentNonCapturingFunctionScope ||
184  Stack.back().first.empty();
185  }
186 
187  /// Vector of previously declared requires directives
189 
190 public:
191  explicit DSAStackTy(Sema &S) : SemaRef(S) {}
192 
193  bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
194  OpenMPClauseKind getClauseParsingMode() const {
195  assert(isClauseParsingMode() && "Must be in clause parsing mode.");
196  return ClauseKindMode;
197  }
198  void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
199 
200  bool isForceVarCapturing() const { return ForceCapturing; }
201  void setForceVarCapturing(bool V) { ForceCapturing = V; }
202 
203  void setForceCaptureByReferenceInTargetExecutable(bool V) {
204  ForceCaptureByReferenceInTargetExecutable = V;
205  }
206  bool isForceCaptureByReferenceInTargetExecutable() const {
207  return ForceCaptureByReferenceInTargetExecutable;
208  }
209 
210  void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
211  Scope *CurScope, SourceLocation Loc) {
212  if (Stack.empty() ||
213  Stack.back().second != CurrentNonCapturingFunctionScope)
214  Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
215  Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
216  Stack.back().first.back().DefaultAttrLoc = Loc;
217  }
218 
219  void pop() {
220  assert(!Stack.back().first.empty() &&
221  "Data-sharing attributes stack is empty!");
222  Stack.back().first.pop_back();
223  }
224 
225  /// Marks that we're started loop parsing.
226  void loopInit() {
227  assert(isOpenMPLoopDirective(getCurrentDirective()) &&
228  "Expected loop-based directive.");
229  Stack.back().first.back().LoopStart = true;
230  }
231  /// Start capturing of the variables in the loop context.
232  void loopStart() {
233  assert(isOpenMPLoopDirective(getCurrentDirective()) &&
234  "Expected loop-based directive.");
235  Stack.back().first.back().LoopStart = false;
236  }
237  /// true, if variables are captured, false otherwise.
238  bool isLoopStarted() const {
239  assert(isOpenMPLoopDirective(getCurrentDirective()) &&
240  "Expected loop-based directive.");
241  return !Stack.back().first.back().LoopStart;
242  }
243  /// Marks (or clears) declaration as possibly loop counter.
244  void resetPossibleLoopCounter(const Decl *D = nullptr) {
245  Stack.back().first.back().PossiblyLoopCounter =
246  D ? D->getCanonicalDecl() : D;
247  }
248  /// Gets the possible loop counter decl.
249  const Decl *getPossiblyLoopCunter() const {
250  return Stack.back().first.back().PossiblyLoopCounter;
251  }
252  /// Start new OpenMP region stack in new non-capturing function.
253  void pushFunction() {
254  const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
255  assert(!isa<CapturingScopeInfo>(CurFnScope));
256  CurrentNonCapturingFunctionScope = CurFnScope;
257  }
258  /// Pop region stack for non-capturing function.
259  void popFunction(const FunctionScopeInfo *OldFSI) {
260  if (!Stack.empty() && Stack.back().second == OldFSI) {
261  assert(Stack.back().first.empty());
262  Stack.pop_back();
263  }
264  CurrentNonCapturingFunctionScope = nullptr;
265  for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
266  if (!isa<CapturingScopeInfo>(FSI)) {
267  CurrentNonCapturingFunctionScope = FSI;
268  break;
269  }
270  }
271  }
272 
273  void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) {
274  Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
275  }
276  const std::pair<const OMPCriticalDirective *, llvm::APSInt>
277  getCriticalWithHint(const DeclarationNameInfo &Name) const {
278  auto I = Criticals.find(Name.getAsString());
279  if (I != Criticals.end())
280  return I->second;
281  return std::make_pair(nullptr, llvm::APSInt());
282  }
283  /// If 'aligned' declaration for given variable \a D was not seen yet,
284  /// add it and return NULL; otherwise return previous occurrence's expression
285  /// for diagnostics.
286  const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE);
287 
288  /// Register specified variable as loop control variable.
289  void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture);
290  /// Check if the specified variable is a loop control variable for
291  /// current region.
292  /// \return The index of the loop control variable in the list of associated
293  /// for-loops (from outer to inner).
294  const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const;
295  /// Check if the specified variable is a loop control variable for
296  /// parent region.
297  /// \return The index of the loop control variable in the list of associated
298  /// for-loops (from outer to inner).
299  const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const;
300  /// Get the loop control variable for the I-th loop (or nullptr) in
301  /// parent directive.
302  const ValueDecl *getParentLoopControlVariable(unsigned I) const;
303 
304  /// Adds explicit data sharing attribute to the specified declaration.
305  void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
306  DeclRefExpr *PrivateCopy = nullptr);
307 
308  /// Adds additional information for the reduction items with the reduction id
309  /// represented as an operator.
310  void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
311  BinaryOperatorKind BOK);
312  /// Adds additional information for the reduction items with the reduction id
313  /// represented as reduction identifier.
314  void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
315  const Expr *ReductionRef);
316  /// Returns the location and reduction operation from the innermost parent
317  /// region for the given \p D.
318  const DSAVarData
319  getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
320  BinaryOperatorKind &BOK,
321  Expr *&TaskgroupDescriptor) const;
322  /// Returns the location and reduction operation from the innermost parent
323  /// region for the given \p D.
324  const DSAVarData
325  getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
326  const Expr *&ReductionRef,
327  Expr *&TaskgroupDescriptor) const;
328  /// Return reduction reference expression for the current taskgroup.
329  Expr *getTaskgroupReductionRef() const {
330  assert(Stack.back().first.back().Directive == OMPD_taskgroup &&
331  "taskgroup reference expression requested for non taskgroup "
332  "directive.");
333  return Stack.back().first.back().TaskgroupReductionRef;
334  }
335  /// Checks if the given \p VD declaration is actually a taskgroup reduction
336  /// descriptor variable at the \p Level of OpenMP regions.
337  bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
338  return Stack.back().first[Level].TaskgroupReductionRef &&
339  cast<DeclRefExpr>(Stack.back().first[Level].TaskgroupReductionRef)
340  ->getDecl() == VD;
341  }
342 
343  /// Returns data sharing attributes from top of the stack for the
344  /// specified declaration.
345  const DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
346  /// Returns data-sharing attributes for the specified declaration.
347  const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const;
348  /// Checks if the specified variables has data-sharing attributes which
349  /// match specified \a CPred predicate in any directive which matches \a DPred
350  /// predicate.
351  const DSAVarData
352  hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
353  const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
354  bool FromParent) const;
355  /// Checks if the specified variables has data-sharing attributes which
356  /// match specified \a CPred predicate in any innermost directive which
357  /// matches \a DPred predicate.
358  const DSAVarData
359  hasInnermostDSA(ValueDecl *D,
360  const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
361  const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
362  bool FromParent) const;
363  /// Checks if the specified variables has explicit data-sharing
364  /// attributes which match specified \a CPred predicate at the specified
365  /// OpenMP region.
366  bool hasExplicitDSA(const ValueDecl *D,
367  const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
368  unsigned Level, bool NotLastprivate = false) const;
369 
370  /// Returns true if the directive at level \Level matches in the
371  /// specified \a DPred predicate.
372  bool hasExplicitDirective(
373  const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
374  unsigned Level) const;
375 
376  /// Finds a directive which matches specified \a DPred predicate.
377  bool hasDirective(
378  const llvm::function_ref<bool(
380  DPred,
381  bool FromParent) const;
382 
383  /// Returns currently analyzed directive.
384  OpenMPDirectiveKind getCurrentDirective() const {
385  return isStackEmpty() ? OMPD_unknown : Stack.back().first.back().Directive;
386  }
387  /// Returns directive kind at specified level.
388  OpenMPDirectiveKind getDirective(unsigned Level) const {
389  assert(!isStackEmpty() && "No directive at specified level.");
390  return Stack.back().first[Level].Directive;
391  }
392  /// Returns parent directive.
393  OpenMPDirectiveKind getParentDirective() const {
394  if (isStackEmpty() || Stack.back().first.size() == 1)
395  return OMPD_unknown;
396  return std::next(Stack.back().first.rbegin())->Directive;
397  }
398 
399  /// Add requires decl to internal vector
400  void addRequiresDecl(OMPRequiresDecl *RD) {
401  RequiresDecls.push_back(RD);
402  }
403 
404  /// Checks for a duplicate clause amongst previously declared requires
405  /// directives
406  bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const {
407  bool IsDuplicate = false;
408  for (OMPClause *CNew : ClauseList) {
409  for (const OMPRequiresDecl *D : RequiresDecls) {
410  for (const OMPClause *CPrev : D->clauselists()) {
411  if (CNew->getClauseKind() == CPrev->getClauseKind()) {
412  SemaRef.Diag(CNew->getBeginLoc(),
413  diag::err_omp_requires_clause_redeclaration)
414  << getOpenMPClauseName(CNew->getClauseKind());
415  SemaRef.Diag(CPrev->getBeginLoc(),
416  diag::note_omp_requires_previous_clause)
417  << getOpenMPClauseName(CPrev->getClauseKind());
418  IsDuplicate = true;
419  }
420  }
421  }
422  }
423  return IsDuplicate;
424  }
425 
426  /// Set default data sharing attribute to none.
427  void setDefaultDSANone(SourceLocation Loc) {
428  assert(!isStackEmpty());
429  Stack.back().first.back().DefaultAttr = DSA_none;
430  Stack.back().first.back().DefaultAttrLoc = Loc;
431  }
432  /// Set default data sharing attribute to shared.
433  void setDefaultDSAShared(SourceLocation Loc) {
434  assert(!isStackEmpty());
435  Stack.back().first.back().DefaultAttr = DSA_shared;
436  Stack.back().first.back().DefaultAttrLoc = Loc;
437  }
438  /// Set default data mapping attribute to 'tofrom:scalar'.
439  void setDefaultDMAToFromScalar(SourceLocation Loc) {
440  assert(!isStackEmpty());
441  Stack.back().first.back().DefaultMapAttr = DMA_tofrom_scalar;
442  Stack.back().first.back().DefaultMapAttrLoc = Loc;
443  }
444 
445  DefaultDataSharingAttributes getDefaultDSA() const {
446  return isStackEmpty() ? DSA_unspecified
447  : Stack.back().first.back().DefaultAttr;
448  }
449  SourceLocation getDefaultDSALocation() const {
450  return isStackEmpty() ? SourceLocation()
451  : Stack.back().first.back().DefaultAttrLoc;
452  }
453  DefaultMapAttributes getDefaultDMA() const {
454  return isStackEmpty() ? DMA_unspecified
455  : Stack.back().first.back().DefaultMapAttr;
456  }
457  DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const {
458  return Stack.back().first[Level].DefaultMapAttr;
459  }
460  SourceLocation getDefaultDMALocation() const {
461  return isStackEmpty() ? SourceLocation()
462  : Stack.back().first.back().DefaultMapAttrLoc;
463  }
464 
465  /// Checks if the specified variable is a threadprivate.
466  bool isThreadPrivate(VarDecl *D) {
467  const DSAVarData DVar = getTopDSA(D, false);
468  return isOpenMPThreadPrivate(DVar.CKind);
469  }
470 
471  /// Marks current region as ordered (it has an 'ordered' clause).
472  void setOrderedRegion(bool IsOrdered, const Expr *Param,
473  OMPOrderedClause *Clause) {
474  assert(!isStackEmpty());
475  if (IsOrdered)
476  Stack.back().first.back().OrderedRegion.emplace(Param, Clause);
477  else
478  Stack.back().first.back().OrderedRegion.reset();
479  }
480  /// Returns true, if region is ordered (has associated 'ordered' clause),
481  /// false - otherwise.
482  bool isOrderedRegion() const {
483  if (isStackEmpty())
484  return false;
485  return Stack.back().first.rbegin()->OrderedRegion.hasValue();
486  }
487  /// Returns optional parameter for the ordered region.
488  std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
489  if (isStackEmpty() ||
490  !Stack.back().first.rbegin()->OrderedRegion.hasValue())
491  return std::make_pair(nullptr, nullptr);
492  return Stack.back().first.rbegin()->OrderedRegion.getValue();
493  }
494  /// Returns true, if parent region is ordered (has associated
495  /// 'ordered' clause), false - otherwise.
496  bool isParentOrderedRegion() const {
497  if (isStackEmpty() || Stack.back().first.size() == 1)
498  return false;
499  return std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue();
500  }
501  /// Returns optional parameter for the ordered region.
502  std::pair<const Expr *, OMPOrderedClause *>
503  getParentOrderedRegionParam() const {
504  if (isStackEmpty() || Stack.back().first.size() == 1 ||
505  !std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue())
506  return std::make_pair(nullptr, nullptr);
507  return std::next(Stack.back().first.rbegin())->OrderedRegion.getValue();
508  }
509  /// Marks current region as nowait (it has a 'nowait' clause).
510  void setNowaitRegion(bool IsNowait = true) {
511  assert(!isStackEmpty());
512  Stack.back().first.back().NowaitRegion = IsNowait;
513  }
514  /// Returns true, if parent region is nowait (has associated
515  /// 'nowait' clause), false - otherwise.
516  bool isParentNowaitRegion() const {
517  if (isStackEmpty() || Stack.back().first.size() == 1)
518  return false;
519  return std::next(Stack.back().first.rbegin())->NowaitRegion;
520  }
521  /// Marks parent region as cancel region.
522  void setParentCancelRegion(bool Cancel = true) {
523  if (!isStackEmpty() && Stack.back().first.size() > 1) {
524  auto &StackElemRef = *std::next(Stack.back().first.rbegin());
525  StackElemRef.CancelRegion |= StackElemRef.CancelRegion || Cancel;
526  }
527  }
528  /// Return true if current region has inner cancel construct.
529  bool isCancelRegion() const {
530  return isStackEmpty() ? false : Stack.back().first.back().CancelRegion;
531  }
532 
533  /// Set collapse value for the region.
534  void setAssociatedLoops(unsigned Val) {
535  assert(!isStackEmpty());
536  Stack.back().first.back().AssociatedLoops = Val;
537  }
538  /// Return collapse value for region.
539  unsigned getAssociatedLoops() const {
540  return isStackEmpty() ? 0 : Stack.back().first.back().AssociatedLoops;
541  }
542 
543  /// Marks current target region as one with closely nested teams
544  /// region.
545  void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
546  if (!isStackEmpty() && Stack.back().first.size() > 1) {
547  std::next(Stack.back().first.rbegin())->InnerTeamsRegionLoc =
548  TeamsRegionLoc;
549  }
550  }
551  /// Returns true, if current region has closely nested teams region.
552  bool hasInnerTeamsRegion() const {
553  return getInnerTeamsRegionLoc().isValid();
554  }
555  /// Returns location of the nested teams region (if any).
556  SourceLocation getInnerTeamsRegionLoc() const {
557  return isStackEmpty() ? SourceLocation()
558  : Stack.back().first.back().InnerTeamsRegionLoc;
559  }
560 
561  Scope *getCurScope() const {
562  return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope;
563  }
564  SourceLocation getConstructLoc() const {
565  return isStackEmpty() ? SourceLocation()
566  : Stack.back().first.back().ConstructLoc;
567  }
568 
569  /// Do the check specified in \a Check to all component lists and return true
570  /// if any issue is found.
571  bool checkMappableExprComponentListsForDecl(
572  const ValueDecl *VD, bool CurrentRegionOnly,
573  const llvm::function_ref<
576  Check) const {
577  if (isStackEmpty())
578  return false;
579  auto SI = Stack.back().first.rbegin();
580  auto SE = Stack.back().first.rend();
581 
582  if (SI == SE)
583  return false;
584 
585  if (CurrentRegionOnly)
586  SE = std::next(SI);
587  else
588  std::advance(SI, 1);
589 
590  for (; SI != SE; ++SI) {
591  auto MI = SI->MappedExprComponents.find(VD);
592  if (MI != SI->MappedExprComponents.end())
594  MI->second.Components)
595  if (Check(L, MI->second.Kind))
596  return true;
597  }
598  return false;
599  }
600 
601  /// Do the check specified in \a Check to all component lists at a given level
602  /// and return true if any issue is found.
603  bool checkMappableExprComponentListsForDeclAtLevel(
604  const ValueDecl *VD, unsigned Level,
605  const llvm::function_ref<
608  Check) const {
609  if (isStackEmpty())
610  return false;
611 
612  auto StartI = Stack.back().first.begin();
613  auto EndI = Stack.back().first.end();
614  if (std::distance(StartI, EndI) <= (int)Level)
615  return false;
616  std::advance(StartI, Level);
617 
618  auto MI = StartI->MappedExprComponents.find(VD);
619  if (MI != StartI->MappedExprComponents.end())
621  MI->second.Components)
622  if (Check(L, MI->second.Kind))
623  return true;
624  return false;
625  }
626 
627  /// Create a new mappable expression component list associated with a given
628  /// declaration and initialize it with the provided list of components.
629  void addMappableExpressionComponents(
630  const ValueDecl *VD,
632  OpenMPClauseKind WhereFoundClauseKind) {
633  assert(!isStackEmpty() &&
634  "Not expecting to retrieve components from a empty stack!");
635  MappedExprComponentTy &MEC =
636  Stack.back().first.back().MappedExprComponents[VD];
637  // Create new entry and append the new components there.
638  MEC.Components.resize(MEC.Components.size() + 1);
639  MEC.Components.back().append(Components.begin(), Components.end());
640  MEC.Kind = WhereFoundClauseKind;
641  }
642 
643  unsigned getNestingLevel() const {
644  assert(!isStackEmpty());
645  return Stack.back().first.size() - 1;
646  }
647  void addDoacrossDependClause(OMPDependClause *C,
648  const OperatorOffsetTy &OpsOffs) {
649  assert(!isStackEmpty() && Stack.back().first.size() > 1);
650  SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin());
651  assert(isOpenMPWorksharingDirective(StackElem.Directive));
652  StackElem.DoacrossDepends.try_emplace(C, OpsOffs);
653  }
654  llvm::iterator_range<DoacrossDependMapTy::const_iterator>
655  getDoacrossDependClauses() const {
656  assert(!isStackEmpty());
657  const SharingMapTy &StackElem = Stack.back().first.back();
658  if (isOpenMPWorksharingDirective(StackElem.Directive)) {
659  const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
660  return llvm::make_range(Ref.begin(), Ref.end());
661  }
662  return llvm::make_range(StackElem.DoacrossDepends.end(),
663  StackElem.DoacrossDepends.end());
664  }
665 
666  // Store types of classes which have been explicitly mapped
667  void addMappedClassesQualTypes(QualType QT) {
668  SharingMapTy &StackElem = Stack.back().first.back();
669  StackElem.MappedClassesQualTypes.insert(QT);
670  }
671 
672  // Return set of mapped classes types
673  bool isClassPreviouslyMapped(QualType QT) const {
674  const SharingMapTy &StackElem = Stack.back().first.back();
675  return StackElem.MappedClassesQualTypes.count(QT) != 0;
676  }
677 
678 };
679 
680 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
681  return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
682 }
683 
684 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
685  return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || DKind == OMPD_unknown;
686 }
687 
688 } // namespace
689 
690 static const Expr *getExprAsWritten(const Expr *E) {
691  if (const auto *FE = dyn_cast<FullExpr>(E))
692  E = FE->getSubExpr();
693 
694  if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
695  E = MTE->GetTemporaryExpr();
696 
697  while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
698  E = Binder->getSubExpr();
699 
700  if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
701  E = ICE->getSubExprAsWritten();
702  return E->IgnoreParens();
703 }
704 
706  return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
707 }
708 
709 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
710  if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
711  if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
712  D = ME->getMemberDecl();
713  const auto *VD = dyn_cast<VarDecl>(D);
714  const auto *FD = dyn_cast<FieldDecl>(D);
715  if (VD != nullptr) {
716  VD = VD->getCanonicalDecl();
717  D = VD;
718  } else {
719  assert(FD);
720  FD = FD->getCanonicalDecl();
721  D = FD;
722  }
723  return D;
724 }
725 
727  return const_cast<ValueDecl *>(
728  getCanonicalDecl(const_cast<const ValueDecl *>(D)));
729 }
730 
731 DSAStackTy::DSAVarData DSAStackTy::getDSA(iterator &Iter,
732  ValueDecl *D) const {
733  D = getCanonicalDecl(D);
734  auto *VD = dyn_cast<VarDecl>(D);
735  const auto *FD = dyn_cast<FieldDecl>(D);
736  DSAVarData DVar;
737  if (isStackEmpty() || Iter == Stack.back().first.rend()) {
738  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
739  // in a region but not in construct]
740  // File-scope or namespace-scope variables referenced in called routines
741  // in the region are shared unless they appear in a threadprivate
742  // directive.
743  if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
744  DVar.CKind = OMPC_shared;
745 
746  // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
747  // in a region but not in construct]
748  // Variables with static storage duration that are declared in called
749  // routines in the region are shared.
750  if (VD && VD->hasGlobalStorage())
751  DVar.CKind = OMPC_shared;
752 
753  // Non-static data members are shared by default.
754  if (FD)
755  DVar.CKind = OMPC_shared;
756 
757  return DVar;
758  }
759 
760  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
761  // in a Construct, C/C++, predetermined, p.1]
762  // Variables with automatic storage duration that are declared in a scope
763  // inside the construct are private.
764  if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
765  (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
766  DVar.CKind = OMPC_private;
767  return DVar;
768  }
769 
770  DVar.DKind = Iter->Directive;
771  // Explicitly specified attributes and local variables with predetermined
772  // attributes.
773  if (Iter->SharingMap.count(D)) {
774  const DSAInfo &Data = Iter->SharingMap.lookup(D);
775  DVar.RefExpr = Data.RefExpr.getPointer();
776  DVar.PrivateCopy = Data.PrivateCopy;
777  DVar.CKind = Data.Attributes;
778  DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
779  return DVar;
780  }
781 
782  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
783  // in a Construct, C/C++, implicitly determined, p.1]
784  // In a parallel or task construct, the data-sharing attributes of these
785  // variables are determined by the default clause, if present.
786  switch (Iter->DefaultAttr) {
787  case DSA_shared:
788  DVar.CKind = OMPC_shared;
789  DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
790  return DVar;
791  case DSA_none:
792  return DVar;
793  case DSA_unspecified:
794  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
795  // in a Construct, implicitly determined, p.2]
796  // In a parallel construct, if no default clause is present, these
797  // variables are shared.
798  DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
799  if (isOpenMPParallelDirective(DVar.DKind) ||
800  isOpenMPTeamsDirective(DVar.DKind)) {
801  DVar.CKind = OMPC_shared;
802  return DVar;
803  }
804 
805  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
806  // in a Construct, implicitly determined, p.4]
807  // In a task construct, if no default clause is present, a variable that in
808  // the enclosing context is determined to be shared by all implicit tasks
809  // bound to the current team is shared.
810  if (isOpenMPTaskingDirective(DVar.DKind)) {
811  DSAVarData DVarTemp;
812  iterator I = Iter, E = Stack.back().first.rend();
813  do {
814  ++I;
815  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
816  // Referenced in a Construct, implicitly determined, p.6]
817  // In a task construct, if no default clause is present, a variable
818  // whose data-sharing attribute is not determined by the rules above is
819  // firstprivate.
820  DVarTemp = getDSA(I, D);
821  if (DVarTemp.CKind != OMPC_shared) {
822  DVar.RefExpr = nullptr;
823  DVar.CKind = OMPC_firstprivate;
824  return DVar;
825  }
826  } while (I != E && !isImplicitTaskingRegion(I->Directive));
827  DVar.CKind =
828  (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
829  return DVar;
830  }
831  }
832  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
833  // in a Construct, implicitly determined, p.3]
834  // For constructs other than task, if no default clause is present, these
835  // variables inherit their data-sharing attributes from the enclosing
836  // context.
837  return getDSA(++Iter, D);
838 }
839 
840 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
841  const Expr *NewDE) {
842  assert(!isStackEmpty() && "Data sharing attributes stack is empty");
843  D = getCanonicalDecl(D);
844  SharingMapTy &StackElem = Stack.back().first.back();
845  auto It = StackElem.AlignedMap.find(D);
846  if (It == StackElem.AlignedMap.end()) {
847  assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
848  StackElem.AlignedMap[D] = NewDE;
849  return nullptr;
850  }
851  assert(It->second && "Unexpected nullptr expr in the aligned map");
852  return It->second;
853 }
854 
855 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
856  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
857  D = getCanonicalDecl(D);
858  SharingMapTy &StackElem = Stack.back().first.back();
859  StackElem.LCVMap.try_emplace(
860  D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
861 }
862 
863 const DSAStackTy::LCDeclInfo
864 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
865  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
866  D = getCanonicalDecl(D);
867  const SharingMapTy &StackElem = Stack.back().first.back();
868  auto It = StackElem.LCVMap.find(D);
869  if (It != StackElem.LCVMap.end())
870  return It->second;
871  return {0, nullptr};
872 }
873 
874 const DSAStackTy::LCDeclInfo
875 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
876  assert(!isStackEmpty() && Stack.back().first.size() > 1 &&
877  "Data-sharing attributes stack is empty");
878  D = getCanonicalDecl(D);
879  const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin());
880  auto It = StackElem.LCVMap.find(D);
881  if (It != StackElem.LCVMap.end())
882  return It->second;
883  return {0, nullptr};
884 }
885 
886 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
887  assert(!isStackEmpty() && Stack.back().first.size() > 1 &&
888  "Data-sharing attributes stack is empty");
889  const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin());
890  if (StackElem.LCVMap.size() < I)
891  return nullptr;
892  for (const auto &Pair : StackElem.LCVMap)
893  if (Pair.second.first == I)
894  return Pair.first;
895  return nullptr;
896 }
897 
898 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
899  DeclRefExpr *PrivateCopy) {
900  D = getCanonicalDecl(D);
901  if (A == OMPC_threadprivate) {
902  DSAInfo &Data = Threadprivates[D];
903  Data.Attributes = A;
904  Data.RefExpr.setPointer(E);
905  Data.PrivateCopy = nullptr;
906  } else {
907  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
908  DSAInfo &Data = Stack.back().first.back().SharingMap[D];
909  assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
910  (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
911  (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
912  (isLoopControlVariable(D).first && A == OMPC_private));
913  if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
914  Data.RefExpr.setInt(/*IntVal=*/true);
915  return;
916  }
917  const bool IsLastprivate =
918  A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
919  Data.Attributes = A;
920  Data.RefExpr.setPointerAndInt(E, IsLastprivate);
921  Data.PrivateCopy = PrivateCopy;
922  if (PrivateCopy) {
923  DSAInfo &Data =
924  Stack.back().first.back().SharingMap[PrivateCopy->getDecl()];
925  Data.Attributes = A;
926  Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
927  Data.PrivateCopy = nullptr;
928  }
929  }
930 }
931 
932 /// Build a variable declaration for OpenMP loop iteration variable.
934  StringRef Name, const AttrVec *Attrs = nullptr,
935  DeclRefExpr *OrigRef = nullptr) {
936  DeclContext *DC = SemaRef.CurContext;
937  IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
938  TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
939  auto *Decl =
940  VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
941  if (Attrs) {
942  for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
943  I != E; ++I)
944  Decl->addAttr(*I);
945  }
946  Decl->setImplicit();
947  if (OrigRef) {
948  Decl->addAttr(
949  OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
950  }
951  return Decl;
952 }
953 
955  SourceLocation Loc,
956  bool RefersToCapture = false) {
957  D->setReferenced();
958  D->markUsed(S.Context);
960  SourceLocation(), D, RefersToCapture, Loc, Ty,
961  VK_LValue);
962 }
963 
964 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
965  BinaryOperatorKind BOK) {
966  D = getCanonicalDecl(D);
967  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
968  assert(
969  Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction &&
970  "Additional reduction info may be specified only for reduction items.");
971  ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D];
972  assert(ReductionData.ReductionRange.isInvalid() &&
973  Stack.back().first.back().Directive == OMPD_taskgroup &&
974  "Additional reduction info may be specified only once for reduction "
975  "items.");
976  ReductionData.set(BOK, SR);
977  Expr *&TaskgroupReductionRef =
978  Stack.back().first.back().TaskgroupReductionRef;
979  if (!TaskgroupReductionRef) {
980  VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
981  SemaRef.Context.VoidPtrTy, ".task_red.");
982  TaskgroupReductionRef =
983  buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
984  }
985 }
986 
987 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
988  const Expr *ReductionRef) {
989  D = getCanonicalDecl(D);
990  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
991  assert(
992  Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction &&
993  "Additional reduction info may be specified only for reduction items.");
994  ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D];
995  assert(ReductionData.ReductionRange.isInvalid() &&
996  Stack.back().first.back().Directive == OMPD_taskgroup &&
997  "Additional reduction info may be specified only once for reduction "
998  "items.");
999  ReductionData.set(ReductionRef, SR);
1000  Expr *&TaskgroupReductionRef =
1001  Stack.back().first.back().TaskgroupReductionRef;
1002  if (!TaskgroupReductionRef) {
1003  VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1004  SemaRef.Context.VoidPtrTy, ".task_red.");
1005  TaskgroupReductionRef =
1006  buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1007  }
1008 }
1009 
1010 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1011  const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
1012  Expr *&TaskgroupDescriptor) const {
1013  D = getCanonicalDecl(D);
1014  assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1015  if (Stack.back().first.empty())
1016  return DSAVarData();
1017  for (iterator I = std::next(Stack.back().first.rbegin(), 1),
1018  E = Stack.back().first.rend();
1019  I != E; std::advance(I, 1)) {
1020  const DSAInfo &Data = I->SharingMap.lookup(D);
1021  if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
1022  continue;
1023  const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1024  if (!ReductionData.ReductionOp ||
1025  ReductionData.ReductionOp.is<const Expr *>())
1026  return DSAVarData();
1027  SR = ReductionData.ReductionRange;
1028  BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1029  assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1030  "expression for the descriptor is not "
1031  "set.");
1032  TaskgroupDescriptor = I->TaskgroupReductionRef;
1033  return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
1034  Data.PrivateCopy, I->DefaultAttrLoc);
1035  }
1036  return DSAVarData();
1037 }
1038 
1039 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1040  const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
1041  Expr *&TaskgroupDescriptor) const {
1042  D = getCanonicalDecl(D);
1043  assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1044  if (Stack.back().first.empty())
1045  return DSAVarData();
1046  for (iterator I = std::next(Stack.back().first.rbegin(), 1),
1047  E = Stack.back().first.rend();
1048  I != E; std::advance(I, 1)) {
1049  const DSAInfo &Data = I->SharingMap.lookup(D);
1050  if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
1051  continue;
1052  const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1053  if (!ReductionData.ReductionOp ||
1054  !ReductionData.ReductionOp.is<const Expr *>())
1055  return DSAVarData();
1056  SR = ReductionData.ReductionRange;
1057  ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
1058  assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1059  "expression for the descriptor is not "
1060  "set.");
1061  TaskgroupDescriptor = I->TaskgroupReductionRef;
1062  return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
1063  Data.PrivateCopy, I->DefaultAttrLoc);
1064  }
1065  return DSAVarData();
1066 }
1067 
1068 bool DSAStackTy::isOpenMPLocal(VarDecl *D, iterator Iter) const {
1069  D = D->getCanonicalDecl();
1070  if (!isStackEmpty()) {
1071  iterator I = Iter, E = Stack.back().first.rend();
1072  Scope *TopScope = nullptr;
1073  while (I != E && !isImplicitOrExplicitTaskingRegion(I->Directive) &&
1074  !isOpenMPTargetExecutionDirective(I->Directive))
1075  ++I;
1076  if (I == E)
1077  return false;
1078  TopScope = I->CurScope ? I->CurScope->getParent() : nullptr;
1079  Scope *CurScope = getCurScope();
1080  while (CurScope != TopScope && !CurScope->isDeclScope(D))
1081  CurScope = CurScope->getParent();
1082  return CurScope != TopScope;
1083  }
1084  return false;
1085 }
1086 
1087 static bool isConstNotMutableType(Sema &SemaRef, QualType Type,
1088  bool AcceptIfMutable = true,
1089  bool *IsClassType = nullptr) {
1090  ASTContext &Context = SemaRef.getASTContext();
1091  Type = Type.getNonReferenceType().getCanonicalType();
1092  bool IsConstant = Type.isConstant(Context);
1093  Type = Context.getBaseElementType(Type);
1094  const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus
1095  ? Type->getAsCXXRecordDecl()
1096  : nullptr;
1097  if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1098  if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1099  RD = CTD->getTemplatedDecl();
1100  if (IsClassType)
1101  *IsClassType = RD;
1102  return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD &&
1103  RD->hasDefinition() && RD->hasMutableFields());
1104 }
1105 
1106 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D,
1108  SourceLocation ELoc,
1109  bool AcceptIfMutable = true,
1110  bool ListItemNotVar = false) {
1111  ASTContext &Context = SemaRef.getASTContext();
1112  bool IsClassType;
1113  if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) {
1114  unsigned Diag = ListItemNotVar
1115  ? diag::err_omp_const_list_item
1116  : IsClassType ? diag::err_omp_const_not_mutable_variable
1117  : diag::err_omp_const_variable;
1118  SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind);
1119  if (!ListItemNotVar && D) {
1120  const VarDecl *VD = dyn_cast<VarDecl>(D);
1121  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
1123  SemaRef.Diag(D->getLocation(),
1124  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1125  << D;
1126  }
1127  return true;
1128  }
1129  return false;
1130 }
1131 
1132 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1133  bool FromParent) {
1134  D = getCanonicalDecl(D);
1135  DSAVarData DVar;
1136 
1137  auto *VD = dyn_cast<VarDecl>(D);
1138  auto TI = Threadprivates.find(D);
1139  if (TI != Threadprivates.end()) {
1140  DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1141  DVar.CKind = OMPC_threadprivate;
1142  return DVar;
1143  }
1144  if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1145  DVar.RefExpr = buildDeclRefExpr(
1146  SemaRef, VD, D->getType().getNonReferenceType(),
1147  VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1148  DVar.CKind = OMPC_threadprivate;
1149  addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1150  return DVar;
1151  }
1152  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1153  // in a Construct, C/C++, predetermined, p.1]
1154  // Variables appearing in threadprivate directives are threadprivate.
1155  if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1156  !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1157  SemaRef.getLangOpts().OpenMPUseTLS &&
1158  SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1159  (VD && VD->getStorageClass() == SC_Register &&
1160  VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1161  DVar.RefExpr = buildDeclRefExpr(
1162  SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1163  DVar.CKind = OMPC_threadprivate;
1164  addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1165  return DVar;
1166  }
1167  if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1168  VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1169  !isLoopControlVariable(D).first) {
1170  iterator IterTarget =
1171  std::find_if(Stack.back().first.rbegin(), Stack.back().first.rend(),
1172  [](const SharingMapTy &Data) {
1173  return isOpenMPTargetExecutionDirective(Data.Directive);
1174  });
1175  if (IterTarget != Stack.back().first.rend()) {
1176  iterator ParentIterTarget = std::next(IterTarget, 1);
1177  for (iterator Iter = Stack.back().first.rbegin();
1178  Iter != ParentIterTarget; std::advance(Iter, 1)) {
1179  if (isOpenMPLocal(VD, Iter)) {
1180  DVar.RefExpr =
1181  buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1182  D->getLocation());
1183  DVar.CKind = OMPC_threadprivate;
1184  return DVar;
1185  }
1186  }
1187  if (!isClauseParsingMode() || IterTarget != Stack.back().first.rbegin()) {
1188  auto DSAIter = IterTarget->SharingMap.find(D);
1189  if (DSAIter != IterTarget->SharingMap.end() &&
1190  isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1191  DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1192  DVar.CKind = OMPC_threadprivate;
1193  return DVar;
1194  }
1195  iterator End = Stack.back().first.rend();
1196  if (!SemaRef.isOpenMPCapturedByRef(
1197  D, std::distance(ParentIterTarget, End))) {
1198  DVar.RefExpr =
1199  buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1200  IterTarget->ConstructLoc);
1201  DVar.CKind = OMPC_threadprivate;
1202  return DVar;
1203  }
1204  }
1205  }
1206  }
1207 
1208  if (isStackEmpty())
1209  // Not in OpenMP execution region and top scope was already checked.
1210  return DVar;
1211 
1212  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1213  // in a Construct, C/C++, predetermined, p.4]
1214  // Static data members are shared.
1215  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1216  // in a Construct, C/C++, predetermined, p.7]
1217  // Variables with static storage duration that are declared in a scope
1218  // inside the construct are shared.
1219  auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
1220  if (VD && VD->isStaticDataMember()) {
1221  DSAVarData DVarTemp = hasDSA(D, isOpenMPPrivate, MatchesAlways, FromParent);
1222  if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1223  return DVar;
1224 
1225  DVar.CKind = OMPC_shared;
1226  return DVar;
1227  }
1228 
1229  // The predetermined shared attribute for const-qualified types having no
1230  // mutable members was removed after OpenMP 3.1.
1231  if (SemaRef.LangOpts.OpenMP <= 31) {
1232  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1233  // in a Construct, C/C++, predetermined, p.6]
1234  // Variables with const qualified type having no mutable member are
1235  // shared.
1236  if (isConstNotMutableType(SemaRef, D->getType())) {
1237  // Variables with const-qualified type having no mutable member may be
1238  // listed in a firstprivate clause, even if they are static data members.
1239  DSAVarData DVarTemp = hasInnermostDSA(
1240  D,
1241  [](OpenMPClauseKind C) {
1242  return C == OMPC_firstprivate || C == OMPC_shared;
1243  },
1244  MatchesAlways, FromParent);
1245  if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1246  return DVarTemp;
1247 
1248  DVar.CKind = OMPC_shared;
1249  return DVar;
1250  }
1251  }
1252 
1253  // Explicitly specified attributes and local variables with predetermined
1254  // attributes.
1255  iterator I = Stack.back().first.rbegin();
1256  iterator EndI = Stack.back().first.rend();
1257  if (FromParent && I != EndI)
1258  std::advance(I, 1);
1259  auto It = I->SharingMap.find(D);
1260  if (It != I->SharingMap.end()) {
1261  const DSAInfo &Data = It->getSecond();
1262  DVar.RefExpr = Data.RefExpr.getPointer();
1263  DVar.PrivateCopy = Data.PrivateCopy;
1264  DVar.CKind = Data.Attributes;
1265  DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1266  DVar.DKind = I->Directive;
1267  }
1268 
1269  return DVar;
1270 }
1271 
1272 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1273  bool FromParent) const {
1274  if (isStackEmpty()) {
1275  iterator I;
1276  return getDSA(I, D);
1277  }
1278  D = getCanonicalDecl(D);
1279  iterator StartI = Stack.back().first.rbegin();
1280  iterator EndI = Stack.back().first.rend();
1281  if (FromParent && StartI != EndI)
1282  std::advance(StartI, 1);
1283  return getDSA(StartI, D);
1284 }
1285 
1286 const DSAStackTy::DSAVarData
1287 DSAStackTy::hasDSA(ValueDecl *D,
1288  const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1289  const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1290  bool FromParent) const {
1291  if (isStackEmpty())
1292  return {};
1293  D = getCanonicalDecl(D);
1294  iterator I = Stack.back().first.rbegin();
1295  iterator EndI = Stack.back().first.rend();
1296  if (FromParent && I != EndI)
1297  std::advance(I, 1);
1298  for (; I != EndI; std::advance(I, 1)) {
1299  if (!DPred(I->Directive) && !isImplicitOrExplicitTaskingRegion(I->Directive))
1300  continue;
1301  iterator NewI = I;
1302  DSAVarData DVar = getDSA(NewI, D);
1303  if (I == NewI && CPred(DVar.CKind))
1304  return DVar;
1305  }
1306  return {};
1307 }
1308 
1309 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1310  ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1311  const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1312  bool FromParent) const {
1313  if (isStackEmpty())
1314  return {};
1315  D = getCanonicalDecl(D);
1316  iterator StartI = Stack.back().first.rbegin();
1317  iterator EndI = Stack.back().first.rend();
1318  if (FromParent && StartI != EndI)
1319  std::advance(StartI, 1);
1320  if (StartI == EndI || !DPred(StartI->Directive))
1321  return {};
1322  iterator NewI = StartI;
1323  DSAVarData DVar = getDSA(NewI, D);
1324  return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData();
1325 }
1326 
1327 bool DSAStackTy::hasExplicitDSA(
1328  const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1329  unsigned Level, bool NotLastprivate) const {
1330  if (isStackEmpty())
1331  return false;
1332  D = getCanonicalDecl(D);
1333  auto StartI = Stack.back().first.begin();
1334  auto EndI = Stack.back().first.end();
1335  if (std::distance(StartI, EndI) <= (int)Level)
1336  return false;
1337  std::advance(StartI, Level);
1338  auto I = StartI->SharingMap.find(D);
1339  if ((I != StartI->SharingMap.end()) &&
1340  I->getSecond().RefExpr.getPointer() &&
1341  CPred(I->getSecond().Attributes) &&
1342  (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1343  return true;
1344  // Check predetermined rules for the loop control variables.
1345  auto LI = StartI->LCVMap.find(D);
1346  if (LI != StartI->LCVMap.end())
1347  return CPred(OMPC_private);
1348  return false;
1349 }
1350 
1351 bool DSAStackTy::hasExplicitDirective(
1352  const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1353  unsigned Level) const {
1354  if (isStackEmpty())
1355  return false;
1356  auto StartI = Stack.back().first.begin();
1357  auto EndI = Stack.back().first.end();
1358  if (std::distance(StartI, EndI) <= (int)Level)
1359  return false;
1360  std::advance(StartI, Level);
1361  return DPred(StartI->Directive);
1362 }
1363 
1364 bool DSAStackTy::hasDirective(
1365  const llvm::function_ref<bool(OpenMPDirectiveKind,
1367  DPred,
1368  bool FromParent) const {
1369  // We look only in the enclosing region.
1370  if (isStackEmpty())
1371  return false;
1372  auto StartI = std::next(Stack.back().first.rbegin());
1373  auto EndI = Stack.back().first.rend();
1374  if (FromParent && StartI != EndI)
1375  StartI = std::next(StartI);
1376  for (auto I = StartI, EE = EndI; I != EE; ++I) {
1377  if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1378  return true;
1379  }
1380  return false;
1381 }
1382 
1383 void Sema::InitDataSharingAttributesStack() {
1384  VarDataSharingAttributesStack = new DSAStackTy(*this);
1385 }
1386 
1387 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1388 
1389 void Sema::pushOpenMPFunctionRegion() {
1390  DSAStack->pushFunction();
1391 }
1392 
1393 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
1394  DSAStack->popFunction(OldFSI);
1395 }
1396 
1397 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level) const {
1398  assert(LangOpts.OpenMP && "OpenMP is not allowed");
1399 
1400  ASTContext &Ctx = getASTContext();
1401  bool IsByRef = true;
1402 
1403  // Find the directive that is associated with the provided scope.
1404  D = cast<ValueDecl>(D->getCanonicalDecl());
1405  QualType Ty = D->getType();
1406 
1407  if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
1408  // This table summarizes how a given variable should be passed to the device
1409  // given its type and the clauses where it appears. This table is based on
1410  // the description in OpenMP 4.5 [2.10.4, target Construct] and
1411  // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
1412  //
1413  // =========================================================================
1414  // | type | defaultmap | pvt | first | is_device_ptr | map | res. |
1415  // | |(tofrom:scalar)| | pvt | | | |
1416  // =========================================================================
1417  // | scl | | | | - | | bycopy|
1418  // | scl | | - | x | - | - | bycopy|
1419  // | scl | | x | - | - | - | null |
1420  // | scl | x | | | - | | byref |
1421  // | scl | x | - | x | - | - | bycopy|
1422  // | scl | x | x | - | - | - | null |
1423  // | scl | | - | - | - | x | byref |
1424  // | scl | x | - | - | - | x | byref |
1425  //
1426  // | agg | n.a. | | | - | | byref |
1427  // | agg | n.a. | - | x | - | - | byref |
1428  // | agg | n.a. | x | - | - | - | null |
1429  // | agg | n.a. | - | - | - | x | byref |
1430  // | agg | n.a. | - | - | - | x[] | byref |
1431  //
1432  // | ptr | n.a. | | | - | | bycopy|
1433  // | ptr | n.a. | - | x | - | - | bycopy|
1434  // | ptr | n.a. | x | - | - | - | null |
1435  // | ptr | n.a. | - | - | - | x | byref |
1436  // | ptr | n.a. | - | - | - | x[] | bycopy|
1437  // | ptr | n.a. | - | - | x | | bycopy|
1438  // | ptr | n.a. | - | - | x | x | bycopy|
1439  // | ptr | n.a. | - | - | x | x[] | bycopy|
1440  // =========================================================================
1441  // Legend:
1442  // scl - scalar
1443  // ptr - pointer
1444  // agg - aggregate
1445  // x - applies
1446  // - - invalid in this combination
1447  // [] - mapped with an array section
1448  // byref - should be mapped by reference
1449  // byval - should be mapped by value
1450  // null - initialize a local variable to null on the device
1451  //
1452  // Observations:
1453  // - All scalar declarations that show up in a map clause have to be passed
1454  // by reference, because they may have been mapped in the enclosing data
1455  // environment.
1456  // - If the scalar value does not fit the size of uintptr, it has to be
1457  // passed by reference, regardless the result in the table above.
1458  // - For pointers mapped by value that have either an implicit map or an
1459  // array section, the runtime library may pass the NULL value to the
1460  // device instead of the value passed to it by the compiler.
1461 
1462  if (Ty->isReferenceType())
1463  Ty = Ty->castAs<ReferenceType>()->getPointeeType();
1464 
1465  // Locate map clauses and see if the variable being captured is referred to
1466  // in any of those clauses. Here we only care about variables, not fields,
1467  // because fields are part of aggregates.
1468  bool IsVariableUsedInMapClause = false;
1469  bool IsVariableAssociatedWithSection = false;
1470 
1471  DSAStack->checkMappableExprComponentListsForDeclAtLevel(
1472  D, Level,
1473  [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D](
1475  MapExprComponents,
1476  OpenMPClauseKind WhereFoundClauseKind) {
1477  // Only the map clause information influences how a variable is
1478  // captured. E.g. is_device_ptr does not require changing the default
1479  // behavior.
1480  if (WhereFoundClauseKind != OMPC_map)
1481  return false;
1482 
1483  auto EI = MapExprComponents.rbegin();
1484  auto EE = MapExprComponents.rend();
1485 
1486  assert(EI != EE && "Invalid map expression!");
1487 
1488  if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
1489  IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
1490 
1491  ++EI;
1492  if (EI == EE)
1493  return false;
1494 
1495  if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
1496  isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
1497  isa<MemberExpr>(EI->getAssociatedExpression())) {
1498  IsVariableAssociatedWithSection = true;
1499  // There is nothing more we need to know about this variable.
1500  return true;
1501  }
1502 
1503  // Keep looking for more map info.
1504  return false;
1505  });
1506 
1507  if (IsVariableUsedInMapClause) {
1508  // If variable is identified in a map clause it is always captured by
1509  // reference except if it is a pointer that is dereferenced somehow.
1510  IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
1511  } else {
1512  // By default, all the data that has a scalar type is mapped by copy
1513  // (except for reduction variables).
1514  IsByRef =
1515  (DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
1516  !Ty->isAnyPointerType()) ||
1517  !Ty->isScalarType() ||
1518  DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar ||
1519  DSAStack->hasExplicitDSA(
1520  D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level);
1521  }
1522  }
1523 
1524  if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
1525  IsByRef =
1526  ((DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
1527  !Ty->isAnyPointerType()) ||
1528  !DSAStack->hasExplicitDSA(
1529  D,
1530  [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; },
1531  Level, /*NotLastprivate=*/true)) &&
1532  // If the variable is artificial and must be captured by value - try to
1533  // capture by value.
1534  !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
1535  !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue());
1536  }
1537 
1538  // When passing data by copy, we need to make sure it fits the uintptr size
1539  // and alignment, because the runtime library only deals with uintptr types.
1540  // If it does not fit the uintptr size, we need to pass the data by reference
1541  // instead.
1542  if (!IsByRef &&
1543  (Ctx.getTypeSizeInChars(Ty) >
1544  Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
1545  Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
1546  IsByRef = true;
1547  }
1548 
1549  return IsByRef;
1550 }
1551 
1552 unsigned Sema::getOpenMPNestingLevel() const {
1553  assert(getLangOpts().OpenMP);
1554  return DSAStack->getNestingLevel();
1555 }
1556 
1558  return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) &&
1559  !DSAStack->isClauseParsingMode()) ||
1560  DSAStack->hasDirective(
1562  SourceLocation) -> bool {
1563  return isOpenMPTargetExecutionDirective(K);
1564  },
1565  false);
1566 }
1567 
1569  assert(LangOpts.OpenMP && "OpenMP is not allowed");
1570  D = getCanonicalDecl(D);
1571 
1572  // If we are attempting to capture a global variable in a directive with
1573  // 'target' we return true so that this global is also mapped to the device.
1574  //
1575  auto *VD = dyn_cast<VarDecl>(D);
1576  if (VD && !VD->hasLocalStorage()) {
1577  if (isInOpenMPDeclareTargetContext() &&
1578  (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
1579  // Try to mark variable as declare target if it is used in capturing
1580  // regions.
1581  if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
1582  checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
1583  return nullptr;
1584  } else if (isInOpenMPTargetExecutionDirective()) {
1585  // If the declaration is enclosed in a 'declare target' directive,
1586  // then it should not be captured.
1587  //
1588  if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
1589  return nullptr;
1590  return VD;
1591  }
1592  }
1593  // Capture variables captured by reference in lambdas for target-based
1594  // directives.
1595  if (VD && !DSAStack->isClauseParsingMode()) {
1596  if (const auto *RD = VD->getType()
1597  .getCanonicalType()
1598  .getNonReferenceType()
1599  ->getAsCXXRecordDecl()) {
1600  bool SavedForceCaptureByReferenceInTargetExecutable =
1601  DSAStack->isForceCaptureByReferenceInTargetExecutable();
1602  DSAStack->setForceCaptureByReferenceInTargetExecutable(/*V=*/true);
1603  if (RD->isLambda()) {
1604  llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
1605  FieldDecl *ThisCapture;
1606  RD->getCaptureFields(Captures, ThisCapture);
1607  for (const LambdaCapture &LC : RD->captures()) {
1608  if (LC.getCaptureKind() == LCK_ByRef) {
1609  VarDecl *VD = LC.getCapturedVar();
1610  DeclContext *VDC = VD->getDeclContext();
1611  if (!VDC->Encloses(CurContext))
1612  continue;
1613  DSAStackTy::DSAVarData DVarPrivate =
1614  DSAStack->getTopDSA(VD, /*FromParent=*/false);
1615  // Do not capture already captured variables.
1616  if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) &&
1617  DVarPrivate.CKind == OMPC_unknown &&
1618  !DSAStack->checkMappableExprComponentListsForDecl(
1619  D, /*CurrentRegionOnly=*/true,
1621  MappableExprComponentListRef,
1622  OpenMPClauseKind) { return true; }))
1623  MarkVariableReferenced(LC.getLocation(), LC.getCapturedVar());
1624  } else if (LC.getCaptureKind() == LCK_This) {
1625  QualType ThisTy = getCurrentThisType();
1626  if (!ThisTy.isNull() &&
1627  Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
1628  CheckCXXThisCapture(LC.getLocation());
1629  }
1630  }
1631  }
1632  DSAStack->setForceCaptureByReferenceInTargetExecutable(
1633  SavedForceCaptureByReferenceInTargetExecutable);
1634  }
1635  }
1636 
1637  if (DSAStack->getCurrentDirective() != OMPD_unknown &&
1638  (!DSAStack->isClauseParsingMode() ||
1639  DSAStack->getParentDirective() != OMPD_unknown)) {
1640  auto &&Info = DSAStack->isLoopControlVariable(D);
1641  if (Info.first ||
1642  (VD && VD->hasLocalStorage() &&
1643  isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) ||
1644  (VD && DSAStack->isForceVarCapturing()))
1645  return VD ? VD : Info.second;
1646  DSAStackTy::DSAVarData DVarPrivate =
1647  DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
1648  if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind))
1649  return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1650  DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate,
1651  [](OpenMPDirectiveKind) { return true; },
1652  DSAStack->isClauseParsingMode());
1653  if (DVarPrivate.CKind != OMPC_unknown)
1654  return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
1655  }
1656  return nullptr;
1657 }
1658 
1659 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
1660  unsigned Level) const {
1662  getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level));
1663  FunctionScopesIndex -= Regions.size();
1664 }
1665 
1667  assert(LangOpts.OpenMP && "OpenMP must be enabled.");
1668  if (isOpenMPLoopDirective(DSAStack->getCurrentDirective()))
1669  DSAStack->loopInit();
1670 }
1671 
1672 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const {
1673  assert(LangOpts.OpenMP && "OpenMP is not allowed");
1674  if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
1675  if (DSAStack->getAssociatedLoops() > 0 &&
1676  !DSAStack->isLoopStarted()) {
1677  DSAStack->resetPossibleLoopCounter(D);
1678  DSAStack->loopStart();
1679  return true;
1680  }
1681  if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
1682  DSAStack->isLoopControlVariable(D).first) &&
1683  !DSAStack->hasExplicitDSA(
1684  D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) &&
1685  !isOpenMPSimdDirective(DSAStack->getCurrentDirective()))
1686  return true;
1687  }
1688  return DSAStack->hasExplicitDSA(
1689  D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) ||
1690  (DSAStack->isClauseParsingMode() &&
1691  DSAStack->getClauseParsingMode() == OMPC_private) ||
1692  // Consider taskgroup reduction descriptor variable a private to avoid
1693  // possible capture in the region.
1694  (DSAStack->hasExplicitDirective(
1695  [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; },
1696  Level) &&
1697  DSAStack->isTaskgroupReductionRef(D, Level));
1698 }
1699 
1701  unsigned Level) {
1702  assert(LangOpts.OpenMP && "OpenMP is not allowed");
1703  D = getCanonicalDecl(D);
1705  for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) {
1706  const unsigned NewLevel = I - 1;
1707  if (DSAStack->hasExplicitDSA(D,
1708  [&OMPC](const OpenMPClauseKind K) {
1709  if (isOpenMPPrivate(K)) {
1710  OMPC = K;
1711  return true;
1712  }
1713  return false;
1714  },
1715  NewLevel))
1716  break;
1717  if (DSAStack->checkMappableExprComponentListsForDeclAtLevel(
1718  D, NewLevel,
1720  OpenMPClauseKind) { return true; })) {
1721  OMPC = OMPC_map;
1722  break;
1723  }
1724  if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
1725  NewLevel)) {
1726  OMPC = OMPC_map;
1727  if (D->getType()->isScalarType() &&
1728  DSAStack->getDefaultDMAAtLevel(NewLevel) !=
1729  DefaultMapAttributes::DMA_tofrom_scalar)
1730  OMPC = OMPC_firstprivate;
1731  break;
1732  }
1733  }
1734  if (OMPC != OMPC_unknown)
1735  FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC));
1736 }
1737 
1739  unsigned Level) const {
1740  assert(LangOpts.OpenMP && "OpenMP is not allowed");
1741  // Return true if the current level is no longer enclosed in a target region.
1742 
1743  const auto *VD = dyn_cast<VarDecl>(D);
1744  return VD && !VD->hasLocalStorage() &&
1745  DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
1746  Level);
1747 }
1748 
1749 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
1750 
1752  const DeclarationNameInfo &DirName,
1753  Scope *CurScope, SourceLocation Loc) {
1754  DSAStack->push(DKind, DirName, CurScope, Loc);
1755  PushExpressionEvaluationContext(
1756  ExpressionEvaluationContext::PotentiallyEvaluated);
1757 }
1758 
1760  DSAStack->setClauseParsingMode(K);
1761 }
1762 
1764  DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
1765 }
1766 
1767 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
1768  // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
1769  // A variable of class type (or array thereof) that appears in a lastprivate
1770  // clause requires an accessible, unambiguous default constructor for the
1771  // class type, unless the list item is also specified in a firstprivate
1772  // clause.
1773  if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
1774  for (OMPClause *C : D->clauses()) {
1775  if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
1776  SmallVector<Expr *, 8> PrivateCopies;
1777  for (Expr *DE : Clause->varlists()) {
1778  if (DE->isValueDependent() || DE->isTypeDependent()) {
1779  PrivateCopies.push_back(nullptr);
1780  continue;
1781  }
1782  auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
1783  auto *VD = cast<VarDecl>(DRE->getDecl());
1784  QualType Type = VD->getType().getNonReferenceType();
1785  const DSAStackTy::DSAVarData DVar =
1786  DSAStack->getTopDSA(VD, /*FromParent=*/false);
1787  if (DVar.CKind == OMPC_lastprivate) {
1788  // Generate helper private variable and initialize it with the
1789  // default value. The address of the original variable is replaced
1790  // by the address of the new private variable in CodeGen. This new
1791  // variable is not added to IdResolver, so the code in the OpenMP
1792  // region uses original variable for proper diagnostics.
1793  VarDecl *VDPrivate = buildVarDecl(
1794  *this, DE->getExprLoc(), Type.getUnqualifiedType(),
1795  VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
1796  ActOnUninitializedDecl(VDPrivate);
1797  if (VDPrivate->isInvalidDecl())
1798  continue;
1799  PrivateCopies.push_back(buildDeclRefExpr(
1800  *this, VDPrivate, DE->getType(), DE->getExprLoc()));
1801  } else {
1802  // The variable is also a firstprivate, so initialization sequence
1803  // for private copy is generated already.
1804  PrivateCopies.push_back(nullptr);
1805  }
1806  }
1807  // Set initializers to private copies if no errors were found.
1808  if (PrivateCopies.size() == Clause->varlist_size())
1809  Clause->setPrivateCopies(PrivateCopies);
1810  }
1811  }
1812  }
1813 
1814  DSAStack->pop();
1815  DiscardCleanupsInEvaluationContext();
1816  PopExpressionEvaluationContext();
1817 }
1818 
1819 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
1820  Expr *NumIterations, Sema &SemaRef,
1821  Scope *S, DSAStackTy *Stack);
1822 
1823 namespace {
1824 
1825 class VarDeclFilterCCC final : public CorrectionCandidateCallback {
1826 private:
1827  Sema &SemaRef;
1828 
1829 public:
1830  explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
1831  bool ValidateCandidate(const TypoCorrection &Candidate) override {
1832  NamedDecl *ND = Candidate.getCorrectionDecl();
1833  if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
1834  return VD->hasGlobalStorage() &&
1835  SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
1836  SemaRef.getCurScope());
1837  }
1838  return false;
1839  }
1840 };
1841 
1842 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
1843 private:
1844  Sema &SemaRef;
1845 
1846 public:
1847  explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
1848  bool ValidateCandidate(const TypoCorrection &Candidate) override {
1849  NamedDecl *ND = Candidate.getCorrectionDecl();
1850  if (ND && (isa<VarDecl>(ND) || isa<FunctionDecl>(ND))) {
1851  return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
1852  SemaRef.getCurScope());
1853  }
1854  return false;
1855  }
1856 };
1857 
1858 } // namespace
1859 
1861  CXXScopeSpec &ScopeSpec,
1862  const DeclarationNameInfo &Id) {
1863  LookupResult Lookup(*this, Id, LookupOrdinaryName);
1864  LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
1865 
1866  if (Lookup.isAmbiguous())
1867  return ExprError();
1868 
1869  VarDecl *VD;
1870  if (!Lookup.isSingleResult()) {
1871  if (TypoCorrection Corrected = CorrectTypo(
1872  Id, LookupOrdinaryName, CurScope, nullptr,
1873  llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) {
1874  diagnoseTypo(Corrected,
1875  PDiag(Lookup.empty()
1876  ? diag::err_undeclared_var_use_suggest
1877  : diag::err_omp_expected_var_arg_suggest)
1878  << Id.getName());
1879  VD = Corrected.getCorrectionDeclAs<VarDecl>();
1880  } else {
1881  Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
1882  : diag::err_omp_expected_var_arg)
1883  << Id.getName();
1884  return ExprError();
1885  }
1886  } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
1887  Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
1888  Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
1889  return ExprError();
1890  }
1891  Lookup.suppressDiagnostics();
1892 
1893  // OpenMP [2.9.2, Syntax, C/C++]
1894  // Variables must be file-scope, namespace-scope, or static block-scope.
1895  if (!VD->hasGlobalStorage()) {
1896  Diag(Id.getLoc(), diag::err_omp_global_var_arg)
1897  << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal();
1898  bool IsDecl =
1900  Diag(VD->getLocation(),
1901  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1902  << VD;
1903  return ExprError();
1904  }
1905 
1906  VarDecl *CanonicalVD = VD->getCanonicalDecl();
1907  NamedDecl *ND = CanonicalVD;
1908  // OpenMP [2.9.2, Restrictions, C/C++, p.2]
1909  // A threadprivate directive for file-scope variables must appear outside
1910  // any definition or declaration.
1911  if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
1912  !getCurLexicalContext()->isTranslationUnit()) {
1913  Diag(Id.getLoc(), diag::err_omp_var_scope)
1914  << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1915  bool IsDecl =
1917  Diag(VD->getLocation(),
1918  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1919  << VD;
1920  return ExprError();
1921  }
1922  // OpenMP [2.9.2, Restrictions, C/C++, p.3]
1923  // A threadprivate directive for static class member variables must appear
1924  // in the class definition, in the same scope in which the member
1925  // variables are declared.
1926  if (CanonicalVD->isStaticDataMember() &&
1927  !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
1928  Diag(Id.getLoc(), diag::err_omp_var_scope)
1929  << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1930  bool IsDecl =
1932  Diag(VD->getLocation(),
1933  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1934  << VD;
1935  return ExprError();
1936  }
1937  // OpenMP [2.9.2, Restrictions, C/C++, p.4]
1938  // A threadprivate directive for namespace-scope variables must appear
1939  // outside any definition or declaration other than the namespace
1940  // definition itself.
1941  if (CanonicalVD->getDeclContext()->isNamespace() &&
1942  (!getCurLexicalContext()->isFileContext() ||
1943  !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
1944  Diag(Id.getLoc(), diag::err_omp_var_scope)
1945  << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1946  bool IsDecl =
1948  Diag(VD->getLocation(),
1949  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1950  << VD;
1951  return ExprError();
1952  }
1953  // OpenMP [2.9.2, Restrictions, C/C++, p.6]
1954  // A threadprivate directive for static block-scope variables must appear
1955  // in the scope of the variable and not in a nested scope.
1956  if (CanonicalVD->isStaticLocal() && CurScope &&
1957  !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
1958  Diag(Id.getLoc(), diag::err_omp_var_scope)
1959  << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1960  bool IsDecl =
1962  Diag(VD->getLocation(),
1963  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1964  << VD;
1965  return ExprError();
1966  }
1967 
1968  // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
1969  // A threadprivate directive must lexically precede all references to any
1970  // of the variables in its list.
1971  if (VD->isUsed() && !DSAStack->isThreadPrivate(VD)) {
1972  Diag(Id.getLoc(), diag::err_omp_var_used)
1973  << getOpenMPDirectiveName(OMPD_threadprivate) << VD;
1974  return ExprError();
1975  }
1976 
1977  QualType ExprType = VD->getType().getNonReferenceType();
1978  return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
1979  SourceLocation(), VD,
1980  /*RefersToEnclosingVariableOrCapture=*/false,
1981  Id.getLoc(), ExprType, VK_LValue);
1982 }
1983 
1986  ArrayRef<Expr *> VarList) {
1987  if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
1988  CurContext->addDecl(D);
1989  return DeclGroupPtrTy::make(DeclGroupRef(D));
1990  }
1991  return nullptr;
1992 }
1993 
1994 namespace {
1995 class LocalVarRefChecker final
1996  : public ConstStmtVisitor<LocalVarRefChecker, bool> {
1997  Sema &SemaRef;
1998 
1999 public:
2000  bool VisitDeclRefExpr(const DeclRefExpr *E) {
2001  if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
2002  if (VD->hasLocalStorage()) {
2003  SemaRef.Diag(E->getBeginLoc(),
2004  diag::err_omp_local_var_in_threadprivate_init)
2005  << E->getSourceRange();
2006  SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
2007  << VD << VD->getSourceRange();
2008  return true;
2009  }
2010  }
2011  return false;
2012  }
2013  bool VisitStmt(const Stmt *S) {
2014  for (const Stmt *Child : S->children()) {
2015  if (Child && Visit(Child))
2016  return true;
2017  }
2018  return false;
2019  }
2020  explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
2021 };
2022 } // namespace
2023 
2027  for (Expr *RefExpr : VarList) {
2028  auto *DE = cast<DeclRefExpr>(RefExpr);
2029  auto *VD = cast<VarDecl>(DE->getDecl());
2030  SourceLocation ILoc = DE->getExprLoc();
2031 
2032  // Mark variable as used.
2033  VD->setReferenced();
2034  VD->markUsed(Context);
2035 
2036  QualType QType = VD->getType();
2037  if (QType->isDependentType() || QType->isInstantiationDependentType()) {
2038  // It will be analyzed later.
2039  Vars.push_back(DE);
2040  continue;
2041  }
2042 
2043  // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2044  // A threadprivate variable must not have an incomplete type.
2045  if (RequireCompleteType(ILoc, VD->getType(),
2046  diag::err_omp_threadprivate_incomplete_type)) {
2047  continue;
2048  }
2049 
2050  // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2051  // A threadprivate variable must not have a reference type.
2052  if (VD->getType()->isReferenceType()) {
2053  Diag(ILoc, diag::err_omp_ref_type_arg)
2054  << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
2055  bool IsDecl =
2056  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2057  Diag(VD->getLocation(),
2058  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2059  << VD;
2060  continue;
2061  }
2062 
2063  // Check if this is a TLS variable. If TLS is not being supported, produce
2064  // the corresponding diagnostic.
2065  if ((VD->getTLSKind() != VarDecl::TLS_None &&
2066  !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
2067  getLangOpts().OpenMPUseTLS &&
2068  getASTContext().getTargetInfo().isTLSSupported())) ||
2069  (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
2070  !VD->isLocalVarDecl())) {
2071  Diag(ILoc, diag::err_omp_var_thread_local)
2072  << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
2073  bool IsDecl =
2074  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2075  Diag(VD->getLocation(),
2076  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2077  << VD;
2078  continue;
2079  }
2080 
2081  // Check if initial value of threadprivate variable reference variable with
2082  // local storage (it is not supported by runtime).
2083  if (const Expr *Init = VD->getAnyInitializer()) {
2084  LocalVarRefChecker Checker(*this);
2085  if (Checker.Visit(Init))
2086  continue;
2087  }
2088 
2089  Vars.push_back(RefExpr);
2090  DSAStack->addDSA(VD, DE, OMPC_threadprivate);
2091  VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
2092  Context, SourceRange(Loc, Loc)));
2093  if (ASTMutationListener *ML = Context.getASTMutationListener())
2094  ML->DeclarationMarkedOpenMPThreadPrivate(VD);
2095  }
2096  OMPThreadPrivateDecl *D = nullptr;
2097  if (!Vars.empty()) {
2098  D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
2099  Vars);
2100  D->setAccess(AS_public);
2101  }
2102  return D;
2103 }
2104 
2107  ArrayRef<OMPClause *> ClauseList) {
2108  OMPRequiresDecl *D = nullptr;
2109  if (!CurContext->isFileContext()) {
2110  Diag(Loc, diag::err_omp_invalid_scope) << "requires";
2111  } else {
2112  D = CheckOMPRequiresDecl(Loc, ClauseList);
2113  if (D) {
2114  CurContext->addDecl(D);
2115  DSAStack->addRequiresDecl(D);
2116  }
2117  }
2118  return DeclGroupPtrTy::make(DeclGroupRef(D));
2119 }
2120 
2122  ArrayRef<OMPClause *> ClauseList) {
2123  if (!DSAStack->hasDuplicateRequiresClause(ClauseList))
2124  return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
2125  ClauseList);
2126  return nullptr;
2127 }
2128 
2129 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2130  const ValueDecl *D,
2131  const DSAStackTy::DSAVarData &DVar,
2132  bool IsLoopIterVar = false) {
2133  if (DVar.RefExpr) {
2134  SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
2135  << getOpenMPClauseName(DVar.CKind);
2136  return;
2137  }
2138  enum {
2139  PDSA_StaticMemberShared,
2140  PDSA_StaticLocalVarShared,
2141  PDSA_LoopIterVarPrivate,
2142  PDSA_LoopIterVarLinear,
2143  PDSA_LoopIterVarLastprivate,
2144  PDSA_ConstVarShared,
2145  PDSA_GlobalVarShared,
2146  PDSA_TaskVarFirstprivate,
2147  PDSA_LocalVarPrivate,
2148  PDSA_Implicit
2149  } Reason = PDSA_Implicit;
2150  bool ReportHint = false;
2151  auto ReportLoc = D->getLocation();
2152  auto *VD = dyn_cast<VarDecl>(D);
2153  if (IsLoopIterVar) {
2154  if (DVar.CKind == OMPC_private)
2155  Reason = PDSA_LoopIterVarPrivate;
2156  else if (DVar.CKind == OMPC_lastprivate)
2157  Reason = PDSA_LoopIterVarLastprivate;
2158  else
2159  Reason = PDSA_LoopIterVarLinear;
2160  } else if (isOpenMPTaskingDirective(DVar.DKind) &&
2161  DVar.CKind == OMPC_firstprivate) {
2162  Reason = PDSA_TaskVarFirstprivate;
2163  ReportLoc = DVar.ImplicitDSALoc;
2164  } else if (VD && VD->isStaticLocal())
2165  Reason = PDSA_StaticLocalVarShared;
2166  else if (VD && VD->isStaticDataMember())
2167  Reason = PDSA_StaticMemberShared;
2168  else if (VD && VD->isFileVarDecl())
2169  Reason = PDSA_GlobalVarShared;
2170  else if (D->getType().isConstant(SemaRef.getASTContext()))
2171  Reason = PDSA_ConstVarShared;
2172  else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
2173  ReportHint = true;
2174  Reason = PDSA_LocalVarPrivate;
2175  }
2176  if (Reason != PDSA_Implicit) {
2177  SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
2178  << Reason << ReportHint
2179  << getOpenMPDirectiveName(Stack->getCurrentDirective());
2180  } else if (DVar.ImplicitDSALoc.isValid()) {
2181  SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
2182  << getOpenMPClauseName(DVar.CKind);
2183  }
2184 }
2185 
2186 namespace {
2187 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
2188  DSAStackTy *Stack;
2189  Sema &SemaRef;
2190  bool ErrorFound = false;
2191  CapturedStmt *CS = nullptr;
2192  llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
2193  llvm::SmallVector<Expr *, 4> ImplicitMap;
2194  Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
2195  llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
2196 
2197  void VisitSubCaptures(OMPExecutableDirective *S) {
2198  // Check implicitly captured variables.
2199  if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
2200  return;
2201  for (const CapturedStmt::Capture &Cap :
2203  if (!Cap.capturesVariable())
2204  continue;
2205  VarDecl *VD = Cap.getCapturedVar();
2206  // Do not try to map the variable if it or its sub-component was mapped
2207  // already.
2208  if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
2209  Stack->checkMappableExprComponentListsForDecl(
2210  VD, /*CurrentRegionOnly=*/true,
2212  OpenMPClauseKind) { return true; }))
2213  continue;
2215  SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
2216  Cap.getLocation(), /*RefersToCapture=*/true);
2217  Visit(DRE);
2218  }
2219  }
2220 
2221 public:
2222  void VisitDeclRefExpr(DeclRefExpr *E) {
2223  if (E->isTypeDependent() || E->isValueDependent() ||
2225  return;
2226  if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
2227  VD = VD->getCanonicalDecl();
2228  // Skip internally declared variables.
2229  if (VD->hasLocalStorage() && !CS->capturesVariable(VD))
2230  return;
2231 
2232  DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
2233  // Check if the variable has explicit DSA set and stop analysis if it so.
2234  if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
2235  return;
2236 
2237  // Skip internally declared static variables.
2239  OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
2240  if (VD->hasGlobalStorage() && !CS->capturesVariable(VD) &&
2241  (!Res || *Res != OMPDeclareTargetDeclAttr::MT_Link))
2242  return;
2243 
2244  SourceLocation ELoc = E->getExprLoc();
2245  OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
2246  // The default(none) clause requires that each variable that is referenced
2247  // in the construct, and does not have a predetermined data-sharing
2248  // attribute, must have its data-sharing attribute explicitly determined
2249  // by being listed in a data-sharing attribute clause.
2250  if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none &&
2251  isImplicitOrExplicitTaskingRegion(DKind) &&
2252  VarsWithInheritedDSA.count(VD) == 0) {
2253  VarsWithInheritedDSA[VD] = E;
2254  return;
2255  }
2256 
2257  if (isOpenMPTargetExecutionDirective(DKind) &&
2258  !Stack->isLoopControlVariable(VD).first) {
2259  if (!Stack->checkMappableExprComponentListsForDecl(
2260  VD, /*CurrentRegionOnly=*/true,
2262  StackComponents,
2263  OpenMPClauseKind) {
2264  // Variable is used if it has been marked as an array, array
2265  // section or the variable iself.
2266  return StackComponents.size() == 1 ||
2267  std::all_of(
2268  std::next(StackComponents.rbegin()),
2269  StackComponents.rend(),
2270  [](const OMPClauseMappableExprCommon::
2271  MappableComponent &MC) {
2272  return MC.getAssociatedDeclaration() ==
2273  nullptr &&
2274  (isa<OMPArraySectionExpr>(
2275  MC.getAssociatedExpression()) ||
2276  isa<ArraySubscriptExpr>(
2277  MC.getAssociatedExpression()));
2278  });
2279  })) {
2280  bool IsFirstprivate = false;
2281  // By default lambdas are captured as firstprivates.
2282  if (const auto *RD =
2283  VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
2284  IsFirstprivate = RD->isLambda();
2285  IsFirstprivate =
2286  IsFirstprivate ||
2287  (VD->getType().getNonReferenceType()->isScalarType() &&
2288  Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res);
2289  if (IsFirstprivate)
2290  ImplicitFirstprivate.emplace_back(E);
2291  else
2292  ImplicitMap.emplace_back(E);
2293  return;
2294  }
2295  }
2296 
2297  // OpenMP [2.9.3.6, Restrictions, p.2]
2298  // A list item that appears in a reduction clause of the innermost
2299  // enclosing worksharing or parallel construct may not be accessed in an
2300  // explicit task.
2301  DVar = Stack->hasInnermostDSA(
2302  VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
2303  [](OpenMPDirectiveKind K) {
2304  return isOpenMPParallelDirective(K) ||
2306  },
2307  /*FromParent=*/true);
2308  if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
2309  ErrorFound = true;
2310  SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
2311  reportOriginalDsa(SemaRef, Stack, VD, DVar);
2312  return;
2313  }
2314 
2315  // Define implicit data-sharing attributes for task.
2316  DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
2317  if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
2318  !Stack->isLoopControlVariable(VD).first)
2319  ImplicitFirstprivate.push_back(E);
2320  }
2321  }
2322  void VisitMemberExpr(MemberExpr *E) {
2323  if (E->isTypeDependent() || E->isValueDependent() ||
2325  return;
2326  auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
2327  OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
2328  if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) {
2329  if (!FD)
2330  return;
2331  DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
2332  // Check if the variable has explicit DSA set and stop analysis if it
2333  // so.
2334  if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
2335  return;
2336 
2337  if (isOpenMPTargetExecutionDirective(DKind) &&
2338  !Stack->isLoopControlVariable(FD).first &&
2339  !Stack->checkMappableExprComponentListsForDecl(
2340  FD, /*CurrentRegionOnly=*/true,
2342  StackComponents,
2343  OpenMPClauseKind) {
2344  return isa<CXXThisExpr>(
2345  cast<MemberExpr>(
2346  StackComponents.back().getAssociatedExpression())
2347  ->getBase()
2348  ->IgnoreParens());
2349  })) {
2350  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
2351  // A bit-field cannot appear in a map clause.
2352  //
2353  if (FD->isBitField())
2354  return;
2355 
2356  // Check to see if the member expression is referencing a class that
2357  // has already been explicitly mapped
2358  if (Stack->isClassPreviouslyMapped(TE->getType()))
2359  return;
2360 
2361  ImplicitMap.emplace_back(E);
2362  return;
2363  }
2364 
2365  SourceLocation ELoc = E->getExprLoc();
2366  // OpenMP [2.9.3.6, Restrictions, p.2]
2367  // A list item that appears in a reduction clause of the innermost
2368  // enclosing worksharing or parallel construct may not be accessed in
2369  // an explicit task.
2370  DVar = Stack->hasInnermostDSA(
2371  FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
2372  [](OpenMPDirectiveKind K) {
2373  return isOpenMPParallelDirective(K) ||
2375  },
2376  /*FromParent=*/true);
2377  if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
2378  ErrorFound = true;
2379  SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
2380  reportOriginalDsa(SemaRef, Stack, FD, DVar);
2381  return;
2382  }
2383 
2384  // Define implicit data-sharing attributes for task.
2385  DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
2386  if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
2387  !Stack->isLoopControlVariable(FD).first) {
2388  // Check if there is a captured expression for the current field in the
2389  // region. Do not mark it as firstprivate unless there is no captured
2390  // expression.
2391  // TODO: try to make it firstprivate.
2392  if (DVar.CKind != OMPC_unknown)
2393  ImplicitFirstprivate.push_back(E);
2394  }
2395  return;
2396  }
2397  if (isOpenMPTargetExecutionDirective(DKind)) {
2399  if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
2400  /*NoDiagnose=*/true))
2401  return;
2402  const auto *VD = cast<ValueDecl>(
2403  CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
2404  if (!Stack->checkMappableExprComponentListsForDecl(
2405  VD, /*CurrentRegionOnly=*/true,
2406  [&CurComponents](
2408  StackComponents,
2409  OpenMPClauseKind) {
2410  auto CCI = CurComponents.rbegin();
2411  auto CCE = CurComponents.rend();
2412  for (const auto &SC : llvm::reverse(StackComponents)) {
2413  // Do both expressions have the same kind?
2414  if (CCI->getAssociatedExpression()->getStmtClass() !=
2415  SC.getAssociatedExpression()->getStmtClass())
2416  if (!(isa<OMPArraySectionExpr>(
2417  SC.getAssociatedExpression()) &&
2418  isa<ArraySubscriptExpr>(
2419  CCI->getAssociatedExpression())))
2420  return false;
2421 
2422  const Decl *CCD = CCI->getAssociatedDeclaration();
2423  const Decl *SCD = SC.getAssociatedDeclaration();
2424  CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
2425  SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
2426  if (SCD != CCD)
2427  return false;
2428  std::advance(CCI, 1);
2429  if (CCI == CCE)
2430  break;
2431  }
2432  return true;
2433  })) {
2434  Visit(E->getBase());
2435  }
2436  } else {
2437  Visit(E->getBase());
2438  }
2439  }
2440  void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
2441  for (OMPClause *C : S->clauses()) {
2442  // Skip analysis of arguments of implicitly defined firstprivate clause
2443  // for task|target directives.
2444  // Skip analysis of arguments of implicitly defined map clause for target
2445  // directives.
2446  if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
2447  C->isImplicit())) {
2448  for (Stmt *CC : C->children()) {
2449  if (CC)
2450  Visit(CC);
2451  }
2452  }
2453  }
2454  // Check implicitly captured variables.
2455  VisitSubCaptures(S);
2456  }
2457  void VisitStmt(Stmt *S) {
2458  for (Stmt *C : S->children()) {
2459  if (C) {
2460  // Check implicitly captured variables in the task-based directives to
2461  // check if they must be firstprivatized.
2462  Visit(C);
2463  }
2464  }
2465  }
2466 
2467  bool isErrorFound() const { return ErrorFound; }
2468  ArrayRef<Expr *> getImplicitFirstprivate() const {
2469  return ImplicitFirstprivate;
2470  }
2471  ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; }
2472  const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
2473  return VarsWithInheritedDSA;
2474  }
2475 
2476  DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
2477  : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {}
2478 };
2479 } // namespace
2480 
2482  switch (DKind) {
2483  case OMPD_parallel:
2484  case OMPD_parallel_for:
2485  case OMPD_parallel_for_simd:
2486  case OMPD_parallel_sections:
2487  case OMPD_teams:
2488  case OMPD_teams_distribute:
2489  case OMPD_teams_distribute_simd: {
2490  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2491  QualType KmpInt32PtrTy =
2492  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2493  Sema::CapturedParamNameType Params[] = {
2494  std::make_pair(".global_tid.", KmpInt32PtrTy),
2495  std::make_pair(".bound_tid.", KmpInt32PtrTy),
2496  std::make_pair(StringRef(), QualType()) // __context with shared vars
2497  };
2498  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2499  Params);
2500  break;
2501  }
2502  case OMPD_target_teams:
2503  case OMPD_target_parallel:
2504  case OMPD_target_parallel_for:
2505  case OMPD_target_parallel_for_simd:
2506  case OMPD_target_teams_distribute:
2507  case OMPD_target_teams_distribute_simd: {
2508  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2509  QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2510  QualType KmpInt32PtrTy =
2511  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2512  QualType Args[] = {VoidPtrTy};
2514  EPI.Variadic = true;
2515  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2516  Sema::CapturedParamNameType Params[] = {
2517  std::make_pair(".global_tid.", KmpInt32Ty),
2518  std::make_pair(".part_id.", KmpInt32PtrTy),
2519  std::make_pair(".privates.", VoidPtrTy),
2520  std::make_pair(
2521  ".copy_fn.",
2522  Context.getPointerType(CopyFnType).withConst().withRestrict()),
2523  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2524  std::make_pair(StringRef(), QualType()) // __context with shared vars
2525  };
2526  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2527  Params);
2528  // Mark this captured region as inlined, because we don't use outlined
2529  // function directly.
2530  getCurCapturedRegion()->TheCapturedDecl->addAttr(
2531  AlwaysInlineAttr::CreateImplicit(
2532  Context, AlwaysInlineAttr::Keyword_forceinline));
2533  Sema::CapturedParamNameType ParamsTarget[] = {
2534  std::make_pair(StringRef(), QualType()) // __context with shared vars
2535  };
2536  // Start a captured region for 'target' with no implicit parameters.
2537  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2538  ParamsTarget);
2539  Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
2540  std::make_pair(".global_tid.", KmpInt32PtrTy),
2541  std::make_pair(".bound_tid.", KmpInt32PtrTy),
2542  std::make_pair(StringRef(), QualType()) // __context with shared vars
2543  };
2544  // Start a captured region for 'teams' or 'parallel'. Both regions have
2545  // the same implicit parameters.
2546  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2547  ParamsTeamsOrParallel);
2548  break;
2549  }
2550  case OMPD_target:
2551  case OMPD_target_simd: {
2552  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2553  QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2554  QualType KmpInt32PtrTy =
2555  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2556  QualType Args[] = {VoidPtrTy};
2558  EPI.Variadic = true;
2559  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2560  Sema::CapturedParamNameType Params[] = {
2561  std::make_pair(".global_tid.", KmpInt32Ty),
2562  std::make_pair(".part_id.", KmpInt32PtrTy),
2563  std::make_pair(".privates.", VoidPtrTy),
2564  std::make_pair(
2565  ".copy_fn.",
2566  Context.getPointerType(CopyFnType).withConst().withRestrict()),
2567  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2568  std::make_pair(StringRef(), QualType()) // __context with shared vars
2569  };
2570  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2571  Params);
2572  // Mark this captured region as inlined, because we don't use outlined
2573  // function directly.
2574  getCurCapturedRegion()->TheCapturedDecl->addAttr(
2575  AlwaysInlineAttr::CreateImplicit(
2576  Context, AlwaysInlineAttr::Keyword_forceinline));
2577  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2578  std::make_pair(StringRef(), QualType()));
2579  break;
2580  }
2581  case OMPD_simd:
2582  case OMPD_for:
2583  case OMPD_for_simd:
2584  case OMPD_sections:
2585  case OMPD_section:
2586  case OMPD_single:
2587  case OMPD_master:
2588  case OMPD_critical:
2589  case OMPD_taskgroup:
2590  case OMPD_distribute:
2591  case OMPD_distribute_simd:
2592  case OMPD_ordered:
2593  case OMPD_atomic:
2594  case OMPD_target_data: {
2595  Sema::CapturedParamNameType Params[] = {
2596  std::make_pair(StringRef(), QualType()) // __context with shared vars
2597  };
2598  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2599  Params);
2600  break;
2601  }
2602  case OMPD_task: {
2603  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2604  QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2605  QualType KmpInt32PtrTy =
2606  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2607  QualType Args[] = {VoidPtrTy};
2609  EPI.Variadic = true;
2610  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2611  Sema::CapturedParamNameType Params[] = {
2612  std::make_pair(".global_tid.", KmpInt32Ty),
2613  std::make_pair(".part_id.", KmpInt32PtrTy),
2614  std::make_pair(".privates.", VoidPtrTy),
2615  std::make_pair(
2616  ".copy_fn.",
2617  Context.getPointerType(CopyFnType).withConst().withRestrict()),
2618  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2619  std::make_pair(StringRef(), QualType()) // __context with shared vars
2620  };
2621  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2622  Params);
2623  // Mark this captured region as inlined, because we don't use outlined
2624  // function directly.
2625  getCurCapturedRegion()->TheCapturedDecl->addAttr(
2626  AlwaysInlineAttr::CreateImplicit(
2627  Context, AlwaysInlineAttr::Keyword_forceinline));
2628  break;
2629  }
2630  case OMPD_taskloop:
2631  case OMPD_taskloop_simd: {
2632  QualType KmpInt32Ty =
2633  Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
2634  .withConst();
2635  QualType KmpUInt64Ty =
2636  Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
2637  .withConst();
2638  QualType KmpInt64Ty =
2639  Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
2640  .withConst();
2641  QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2642  QualType KmpInt32PtrTy =
2643  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2644  QualType Args[] = {VoidPtrTy};
2646  EPI.Variadic = true;
2647  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2648  Sema::CapturedParamNameType Params[] = {
2649  std::make_pair(".global_tid.", KmpInt32Ty),
2650  std::make_pair(".part_id.", KmpInt32PtrTy),
2651  std::make_pair(".privates.", VoidPtrTy),
2652  std::make_pair(
2653  ".copy_fn.",
2654  Context.getPointerType(CopyFnType).withConst().withRestrict()),
2655  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2656  std::make_pair(".lb.", KmpUInt64Ty),
2657  std::make_pair(".ub.", KmpUInt64Ty),
2658  std::make_pair(".st.", KmpInt64Ty),
2659  std::make_pair(".liter.", KmpInt32Ty),
2660  std::make_pair(".reductions.", VoidPtrTy),
2661  std::make_pair(StringRef(), QualType()) // __context with shared vars
2662  };
2663  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2664  Params);
2665  // Mark this captured region as inlined, because we don't use outlined
2666  // function directly.
2667  getCurCapturedRegion()->TheCapturedDecl->addAttr(
2668  AlwaysInlineAttr::CreateImplicit(
2669  Context, AlwaysInlineAttr::Keyword_forceinline));
2670  break;
2671  }
2672  case OMPD_distribute_parallel_for_simd:
2673  case OMPD_distribute_parallel_for: {
2674  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2675  QualType KmpInt32PtrTy =
2676  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2677  Sema::CapturedParamNameType Params[] = {
2678  std::make_pair(".global_tid.", KmpInt32PtrTy),
2679  std::make_pair(".bound_tid.", KmpInt32PtrTy),
2680  std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
2681  std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
2682  std::make_pair(StringRef(), QualType()) // __context with shared vars
2683  };
2684  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2685  Params);
2686  break;
2687  }
2688  case OMPD_target_teams_distribute_parallel_for:
2689  case OMPD_target_teams_distribute_parallel_for_simd: {
2690  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2691  QualType KmpInt32PtrTy =
2692  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2693  QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2694 
2695  QualType Args[] = {VoidPtrTy};
2697  EPI.Variadic = true;
2698  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2699  Sema::CapturedParamNameType Params[] = {
2700  std::make_pair(".global_tid.", KmpInt32Ty),
2701  std::make_pair(".part_id.", KmpInt32PtrTy),
2702  std::make_pair(".privates.", VoidPtrTy),
2703  std::make_pair(
2704  ".copy_fn.",
2705  Context.getPointerType(CopyFnType).withConst().withRestrict()),
2706  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2707  std::make_pair(StringRef(), QualType()) // __context with shared vars
2708  };
2709  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2710  Params);
2711  // Mark this captured region as inlined, because we don't use outlined
2712  // function directly.
2713  getCurCapturedRegion()->TheCapturedDecl->addAttr(
2714  AlwaysInlineAttr::CreateImplicit(
2715  Context, AlwaysInlineAttr::Keyword_forceinline));
2716  Sema::CapturedParamNameType ParamsTarget[] = {
2717  std::make_pair(StringRef(), QualType()) // __context with shared vars
2718  };
2719  // Start a captured region for 'target' with no implicit parameters.
2720  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2721  ParamsTarget);
2722 
2723  Sema::CapturedParamNameType ParamsTeams[] = {
2724  std::make_pair(".global_tid.", KmpInt32PtrTy),
2725  std::make_pair(".bound_tid.", KmpInt32PtrTy),
2726  std::make_pair(StringRef(), QualType()) // __context with shared vars
2727  };
2728  // Start a captured region for 'target' with no implicit parameters.
2729  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2730  ParamsTeams);
2731 
2732  Sema::CapturedParamNameType ParamsParallel[] = {
2733  std::make_pair(".global_tid.", KmpInt32PtrTy),
2734  std::make_pair(".bound_tid.", KmpInt32PtrTy),
2735  std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
2736  std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
2737  std::make_pair(StringRef(), QualType()) // __context with shared vars
2738  };
2739  // Start a captured region for 'teams' or 'parallel'. Both regions have
2740  // the same implicit parameters.
2741  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2742  ParamsParallel);
2743  break;
2744  }
2745 
2746  case OMPD_teams_distribute_parallel_for:
2747  case OMPD_teams_distribute_parallel_for_simd: {
2748  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2749  QualType KmpInt32PtrTy =
2750  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2751 
2752  Sema::CapturedParamNameType ParamsTeams[] = {
2753  std::make_pair(".global_tid.", KmpInt32PtrTy),
2754  std::make_pair(".bound_tid.", KmpInt32PtrTy),
2755  std::make_pair(StringRef(), QualType()) // __context with shared vars
2756  };
2757  // Start a captured region for 'target' with no implicit parameters.
2758  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2759  ParamsTeams);
2760 
2761  Sema::CapturedParamNameType ParamsParallel[] = {
2762  std::make_pair(".global_tid.", KmpInt32PtrTy),
2763  std::make_pair(".bound_tid.", KmpInt32PtrTy),
2764  std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
2765  std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
2766  std::make_pair(StringRef(), QualType()) // __context with shared vars
2767  };
2768  // Start a captured region for 'teams' or 'parallel'. Both regions have
2769  // the same implicit parameters.
2770  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2771  ParamsParallel);
2772  break;
2773  }
2774  case OMPD_target_update:
2775  case OMPD_target_enter_data:
2776  case OMPD_target_exit_data: {
2777  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
2778  QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
2779  QualType KmpInt32PtrTy =
2780  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
2781  QualType Args[] = {VoidPtrTy};
2783  EPI.Variadic = true;
2784  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
2785  Sema::CapturedParamNameType Params[] = {
2786  std::make_pair(".global_tid.", KmpInt32Ty),
2787  std::make_pair(".part_id.", KmpInt32PtrTy),
2788  std::make_pair(".privates.", VoidPtrTy),
2789  std::make_pair(
2790  ".copy_fn.",
2791  Context.getPointerType(CopyFnType).withConst().withRestrict()),
2792  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
2793  std::make_pair(StringRef(), QualType()) // __context with shared vars
2794  };
2795  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
2796  Params);
2797  // Mark this captured region as inlined, because we don't use outlined
2798  // function directly.
2799  getCurCapturedRegion()->TheCapturedDecl->addAttr(
2800  AlwaysInlineAttr::CreateImplicit(
2801  Context, AlwaysInlineAttr::Keyword_forceinline));
2802  break;
2803  }
2804  case OMPD_threadprivate:
2805  case OMPD_taskyield:
2806  case OMPD_barrier:
2807  case OMPD_taskwait:
2808  case OMPD_cancellation_point:
2809  case OMPD_cancel:
2810  case OMPD_flush:
2811  case OMPD_declare_reduction:
2812  case OMPD_declare_simd:
2813  case OMPD_declare_target:
2814  case OMPD_end_declare_target:
2815  case OMPD_requires:
2816  llvm_unreachable("OpenMP Directive is not allowed");
2817  case OMPD_unknown:
2818  llvm_unreachable("Unknown OpenMP directive");
2819  }
2820 }
2821 
2823  SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2824  getOpenMPCaptureRegions(CaptureRegions, DKind);
2825  return CaptureRegions.size();
2826 }
2827 
2829  Expr *CaptureExpr, bool WithInit,
2830  bool AsExpression) {
2831  assert(CaptureExpr);
2832  ASTContext &C = S.getASTContext();
2833  Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
2834  QualType Ty = Init->getType();
2835  if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
2836  if (S.getLangOpts().CPlusPlus) {
2837  Ty = C.getLValueReferenceType(Ty);
2838  } else {
2839  Ty = C.getPointerType(Ty);
2840  ExprResult Res =
2841  S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
2842  if (!Res.isUsable())
2843  return nullptr;
2844  Init = Res.get();
2845  }
2846  WithInit = true;
2847  }
2848  auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
2849  CaptureExpr->getBeginLoc());
2850  if (!WithInit)
2851  CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
2852  S.CurContext->addHiddenDecl(CED);
2853  S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
2854  return CED;
2855 }
2856 
2857 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2858  bool WithInit) {
2859  OMPCapturedExprDecl *CD;
2860  if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
2861  CD = cast<OMPCapturedExprDecl>(VD);
2862  else
2863  CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
2864  /*AsExpression=*/false);
2865  return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
2866  CaptureExpr->getExprLoc());
2867 }
2868 
2869 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
2870  CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
2871  if (!Ref) {
2873  S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
2874  /*WithInit=*/true, /*AsExpression=*/true);
2875  Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
2876  CaptureExpr->getExprLoc());
2877  }
2878  ExprResult Res = Ref;
2879  if (!S.getLangOpts().CPlusPlus &&
2880  CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
2881  Ref->getType()->isPointerType()) {
2882  Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
2883  if (!Res.isUsable())
2884  return ExprError();
2885  }
2886  return S.DefaultLvalueConversion(Res.get());
2887 }
2888 
2889 namespace {
2890 // OpenMP directives parsed in this section are represented as a
2891 // CapturedStatement with an associated statement. If a syntax error
2892 // is detected during the parsing of the associated statement, the
2893 // compiler must abort processing and close the CapturedStatement.
2894 //
2895 // Combined directives such as 'target parallel' have more than one
2896 // nested CapturedStatements. This RAII ensures that we unwind out
2897 // of all the nested CapturedStatements when an error is found.
2898 class CaptureRegionUnwinderRAII {
2899 private:
2900  Sema &S;
2901  bool &ErrorFound;
2903 
2904 public:
2905  CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
2906  OpenMPDirectiveKind DKind)
2907  : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
2908  ~CaptureRegionUnwinderRAII() {
2909  if (ErrorFound) {
2910  int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
2911  while (--ThisCaptureLevel >= 0)
2913  }
2914  }
2915 };
2916 } // namespace
2917 
2919  ArrayRef<OMPClause *> Clauses) {
2920  bool ErrorFound = false;
2921  CaptureRegionUnwinderRAII CaptureRegionUnwinder(
2922  *this, ErrorFound, DSAStack->getCurrentDirective());
2923  if (!S.isUsable()) {
2924  ErrorFound = true;
2925  return StmtError();
2926  }
2927 
2928  SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2929  getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective());
2930  OMPOrderedClause *OC = nullptr;
2931  OMPScheduleClause *SC = nullptr;
2934  // This is required for proper codegen.
2935  for (OMPClause *Clause : Clauses) {
2936  if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
2937  Clause->getClauseKind() == OMPC_in_reduction) {
2938  // Capture taskgroup task_reduction descriptors inside the tasking regions
2939  // with the corresponding in_reduction items.
2940  auto *IRC = cast<OMPInReductionClause>(Clause);
2941  for (Expr *E : IRC->taskgroup_descriptors())
2942  if (E)
2943  MarkDeclarationsReferencedInExpr(E);
2944  }
2945  if (isOpenMPPrivate(Clause->getClauseKind()) ||
2946  Clause->getClauseKind() == OMPC_copyprivate ||
2947  (getLangOpts().OpenMPUseTLS &&
2948  getASTContext().getTargetInfo().isTLSSupported() &&
2949  Clause->getClauseKind() == OMPC_copyin)) {
2950  DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
2951  // Mark all variables in private list clauses as used in inner region.
2952  for (Stmt *VarRef : Clause->children()) {
2953  if (auto *E = cast_or_null<Expr>(VarRef)) {
2954  MarkDeclarationsReferencedInExpr(E);
2955  }
2956  }
2957  DSAStack->setForceVarCapturing(/*V=*/false);
2958  } else if (CaptureRegions.size() > 1 ||
2959  CaptureRegions.back() != OMPD_unknown) {
2960  if (auto *C = OMPClauseWithPreInit::get(Clause))
2961  PICs.push_back(C);
2962  if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
2963  if (Expr *E = C->getPostUpdateExpr())
2964  MarkDeclarationsReferencedInExpr(E);
2965  }
2966  }
2967  if (Clause->getClauseKind() == OMPC_schedule)
2968  SC = cast<OMPScheduleClause>(Clause);
2969  else if (Clause->getClauseKind() == OMPC_ordered)
2970  OC = cast<OMPOrderedClause>(Clause);
2971  else if (Clause->getClauseKind() == OMPC_linear)
2972  LCs.push_back(cast<OMPLinearClause>(Clause));
2973  }
2974  // OpenMP, 2.7.1 Loop Construct, Restrictions
2975  // The nonmonotonic modifier cannot be specified if an ordered clause is
2976  // specified.
2977  if (SC &&
2978  (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
2979  SC->getSecondScheduleModifier() ==
2980  OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
2981  OC) {
2982  Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
2985  diag::err_omp_schedule_nonmonotonic_ordered)
2986  << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
2987  ErrorFound = true;
2988  }
2989  if (!LCs.empty() && OC && OC->getNumForLoops()) {
2990  for (const OMPLinearClause *C : LCs) {
2991  Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
2992  << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
2993  }
2994  ErrorFound = true;
2995  }
2996  if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
2997  isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
2998  OC->getNumForLoops()) {
2999  Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
3000  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
3001  ErrorFound = true;
3002  }
3003  if (ErrorFound) {
3004  return StmtError();
3005  }
3006  StmtResult SR = S;
3007  for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
3008  // Mark all variables in private list clauses as used in inner region.
3009  // Required for proper codegen of combined directives.
3010  // TODO: add processing for other clauses.
3011  if (ThisCaptureRegion != OMPD_unknown) {
3012  for (const clang::OMPClauseWithPreInit *C : PICs) {
3013  OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
3014  // Find the particular capture region for the clause if the
3015  // directive is a combined one with multiple capture regions.
3016  // If the directive is not a combined one, the capture region
3017  // associated with the clause is OMPD_unknown and is generated
3018  // only once.
3019  if (CaptureRegion == ThisCaptureRegion ||
3020  CaptureRegion == OMPD_unknown) {
3021  if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
3022  for (Decl *D : DS->decls())
3023  MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
3024  }
3025  }
3026  }
3027  }
3028  SR = ActOnCapturedRegionEnd(SR.get());
3029  }
3030  return SR;
3031 }
3032 
3033 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
3034  OpenMPDirectiveKind CancelRegion,
3035  SourceLocation StartLoc) {
3036  // CancelRegion is only needed for cancel and cancellation_point.
3037  if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
3038  return false;
3039 
3040  if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
3041  CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
3042  return false;
3043 
3044  SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
3045  << getOpenMPDirectiveName(CancelRegion);
3046  return true;
3047 }
3048 
3049 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
3050  OpenMPDirectiveKind CurrentRegion,
3051  const DeclarationNameInfo &CurrentName,
3052  OpenMPDirectiveKind CancelRegion,
3053  SourceLocation StartLoc) {
3054  if (Stack->getCurScope()) {
3055  OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
3056  OpenMPDirectiveKind OffendingRegion = ParentRegion;
3057  bool NestingProhibited = false;
3058  bool CloseNesting = true;
3059  bool OrphanSeen = false;
3060  enum {
3061  NoRecommend,
3062  ShouldBeInParallelRegion,
3063  ShouldBeInOrderedRegion,
3064  ShouldBeInTargetRegion,
3065  ShouldBeInTeamsRegion
3066  } Recommend = NoRecommend;
3067  if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) {
3068  // OpenMP [2.16, Nesting of Regions]
3069  // OpenMP constructs may not be nested inside a simd region.
3070  // OpenMP [2.8.1,simd Construct, Restrictions]
3071  // An ordered construct with the simd clause is the only OpenMP
3072  // construct that can appear in the simd region.
3073  // Allowing a SIMD construct nested in another SIMD construct is an
3074  // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
3075  // message.
3076  SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
3077  ? diag::err_omp_prohibited_region_simd
3078  : diag::warn_omp_nesting_simd);
3079  return CurrentRegion != OMPD_simd;
3080  }
3081  if (ParentRegion == OMPD_atomic) {
3082  // OpenMP [2.16, Nesting of Regions]
3083  // OpenMP constructs may not be nested inside an atomic region.
3084  SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
3085  return true;
3086  }
3087  if (CurrentRegion == OMPD_section) {
3088  // OpenMP [2.7.2, sections Construct, Restrictions]
3089  // Orphaned section directives are prohibited. That is, the section
3090  // directives must appear within the sections construct and must not be
3091  // encountered elsewhere in the sections region.
3092  if (ParentRegion != OMPD_sections &&
3093  ParentRegion != OMPD_parallel_sections) {
3094  SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
3095  << (ParentRegion != OMPD_unknown)
3096  << getOpenMPDirectiveName(ParentRegion);
3097  return true;
3098  }
3099  return false;
3100  }
3101  // Allow some constructs (except teams and cancellation constructs) to be
3102  // orphaned (they could be used in functions, called from OpenMP regions
3103  // with the required preconditions).
3104  if (ParentRegion == OMPD_unknown &&
3105  !isOpenMPNestingTeamsDirective(CurrentRegion) &&
3106  CurrentRegion != OMPD_cancellation_point &&
3107  CurrentRegion != OMPD_cancel)
3108  return false;
3109  if (CurrentRegion == OMPD_cancellation_point ||
3110  CurrentRegion == OMPD_cancel) {
3111  // OpenMP [2.16, Nesting of Regions]
3112  // A cancellation point construct for which construct-type-clause is
3113  // taskgroup must be nested inside a task construct. A cancellation
3114  // point construct for which construct-type-clause is not taskgroup must
3115  // be closely nested inside an OpenMP construct that matches the type
3116  // specified in construct-type-clause.
3117  // A cancel construct for which construct-type-clause is taskgroup must be
3118  // nested inside a task construct. A cancel construct for which
3119  // construct-type-clause is not taskgroup must be closely nested inside an
3120  // OpenMP construct that matches the type specified in
3121  // construct-type-clause.
3122  NestingProhibited =
3123  !((CancelRegion == OMPD_parallel &&
3124  (ParentRegion == OMPD_parallel ||
3125  ParentRegion == OMPD_target_parallel)) ||
3126  (CancelRegion == OMPD_for &&
3127  (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
3128  ParentRegion == OMPD_target_parallel_for ||
3129  ParentRegion == OMPD_distribute_parallel_for ||
3130  ParentRegion == OMPD_teams_distribute_parallel_for ||
3131  ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
3132  (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) ||
3133  (CancelRegion == OMPD_sections &&
3134  (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
3135  ParentRegion == OMPD_parallel_sections)));
3136  OrphanSeen = ParentRegion == OMPD_unknown;
3137  } else if (CurrentRegion == OMPD_master) {
3138  // OpenMP [2.16, Nesting of Regions]
3139  // A master region may not be closely nested inside a worksharing,
3140  // atomic, or explicit task region.
3141  NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
3142  isOpenMPTaskingDirective(ParentRegion);
3143  } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
3144  // OpenMP [2.16, Nesting of Regions]
3145  // A critical region may not be nested (closely or otherwise) inside a
3146  // critical region with the same name. Note that this restriction is not
3147  // sufficient to prevent deadlock.
3148  SourceLocation PreviousCriticalLoc;
3149  bool DeadLock = Stack->hasDirective(
3150  [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
3151  const DeclarationNameInfo &DNI,
3152  SourceLocation Loc) {
3153  if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
3154  PreviousCriticalLoc = Loc;
3155  return true;
3156  }
3157  return false;
3158  },
3159  false /* skip top directive */);
3160  if (DeadLock) {
3161  SemaRef.Diag(StartLoc,
3162  diag::err_omp_prohibited_region_critical_same_name)
3163  << CurrentName.getName();
3164  if (PreviousCriticalLoc.isValid())
3165  SemaRef.Diag(PreviousCriticalLoc,
3166  diag::note_omp_previous_critical_region);
3167  return true;
3168  }
3169  } else if (CurrentRegion == OMPD_barrier) {
3170  // OpenMP [2.16, Nesting of Regions]
3171  // A barrier region may not be closely nested inside a worksharing,
3172  // explicit task, critical, ordered, atomic, or master region.
3173  NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
3174  isOpenMPTaskingDirective(ParentRegion) ||
3175  ParentRegion == OMPD_master ||
3176  ParentRegion == OMPD_critical ||
3177  ParentRegion == OMPD_ordered;
3178  } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
3179  !isOpenMPParallelDirective(CurrentRegion) &&
3180  !isOpenMPTeamsDirective(CurrentRegion)) {
3181  // OpenMP [2.16, Nesting of Regions]
3182  // A worksharing region may not be closely nested inside a worksharing,
3183  // explicit task, critical, ordered, atomic, or master region.
3184  NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
3185  isOpenMPTaskingDirective(ParentRegion) ||
3186  ParentRegion == OMPD_master ||
3187  ParentRegion == OMPD_critical ||
3188  ParentRegion == OMPD_ordered;
3189  Recommend = ShouldBeInParallelRegion;
3190  } else if (CurrentRegion == OMPD_ordered) {
3191  // OpenMP [2.16, Nesting of Regions]
3192  // An ordered region may not be closely nested inside a critical,
3193  // atomic, or explicit task region.
3194  // An ordered region must be closely nested inside a loop region (or
3195  // parallel loop region) with an ordered clause.
3196  // OpenMP [2.8.1,simd Construct, Restrictions]
3197  // An ordered construct with the simd clause is the only OpenMP construct
3198  // that can appear in the simd region.
3199  NestingProhibited = ParentRegion == OMPD_critical ||
3200  isOpenMPTaskingDirective(ParentRegion) ||
3201  !(isOpenMPSimdDirective(ParentRegion) ||
3202  Stack->isParentOrderedRegion());
3203  Recommend = ShouldBeInOrderedRegion;
3204  } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
3205  // OpenMP [2.16, Nesting of Regions]
3206  // If specified, a teams construct must be contained within a target
3207  // construct.
3208  NestingProhibited = ParentRegion != OMPD_target;
3209  OrphanSeen = ParentRegion == OMPD_unknown;
3210  Recommend = ShouldBeInTargetRegion;
3211  }
3212  if (!NestingProhibited &&
3213  !isOpenMPTargetExecutionDirective(CurrentRegion) &&
3214  !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
3215  (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
3216  // OpenMP [2.16, Nesting of Regions]
3217  // distribute, parallel, parallel sections, parallel workshare, and the
3218  // parallel loop and parallel loop SIMD constructs are the only OpenMP
3219  // constructs that can be closely nested in the teams region.
3220  NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
3221  !isOpenMPDistributeDirective(CurrentRegion);
3222  Recommend = ShouldBeInParallelRegion;
3223  }
3224  if (!NestingProhibited &&
3225  isOpenMPNestingDistributeDirective(CurrentRegion)) {
3226  // OpenMP 4.5 [2.17 Nesting of Regions]
3227  // The region associated with the distribute construct must be strictly
3228  // nested inside a teams region
3229  NestingProhibited =
3230  (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
3231  Recommend = ShouldBeInTeamsRegion;
3232  }
3233  if (!NestingProhibited &&
3234  (isOpenMPTargetExecutionDirective(CurrentRegion) ||
3235  isOpenMPTargetDataManagementDirective(CurrentRegion))) {
3236  // OpenMP 4.5 [2.17 Nesting of Regions]
3237  // If a target, target update, target data, target enter data, or
3238  // target exit data construct is encountered during execution of a
3239  // target region, the behavior is unspecified.
3240  NestingProhibited = Stack->hasDirective(
3241  [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
3242  SourceLocation) {
3244  OffendingRegion = K;
3245  return true;
3246  }
3247  return false;
3248  },
3249  false /* don't skip top directive */);
3250  CloseNesting = false;
3251  }
3252  if (NestingProhibited) {
3253  if (OrphanSeen) {
3254  SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
3255  << getOpenMPDirectiveName(CurrentRegion) << Recommend;
3256  } else {
3257  SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
3258  << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
3259  << Recommend << getOpenMPDirectiveName(CurrentRegion);
3260  }
3261  return true;
3262  }
3263  }
3264  return false;
3265 }
3266 
3268  ArrayRef<OMPClause *> Clauses,
3269  ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
3270  bool ErrorFound = false;
3271  unsigned NamedModifiersNumber = 0;
3273  OMPD_unknown + 1);
3274  SmallVector<SourceLocation, 4> NameModifierLoc;
3275  for (const OMPClause *C : Clauses) {
3276  if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
3277  // At most one if clause without a directive-name-modifier can appear on
3278  // the directive.
3279  OpenMPDirectiveKind CurNM = IC->getNameModifier();
3280  if (FoundNameModifiers[CurNM]) {
3281  S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
3282  << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
3283  << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
3284  ErrorFound = true;
3285  } else if (CurNM != OMPD_unknown) {
3286  NameModifierLoc.push_back(IC->getNameModifierLoc());
3287  ++NamedModifiersNumber;
3288  }
3289  FoundNameModifiers[CurNM] = IC;
3290  if (CurNM == OMPD_unknown)
3291  continue;
3292  // Check if the specified name modifier is allowed for the current
3293  // directive.
3294  // At most one if clause with the particular directive-name-modifier can
3295  // appear on the directive.
3296  bool MatchFound = false;
3297  for (auto NM : AllowedNameModifiers) {
3298  if (CurNM == NM) {
3299  MatchFound = true;
3300  break;
3301  }
3302  }
3303  if (!MatchFound) {
3304  S.Diag(IC->getNameModifierLoc(),
3305  diag::err_omp_wrong_if_directive_name_modifier)
3307  ErrorFound = true;
3308  }
3309  }
3310  }
3311  // If any if clause on the directive includes a directive-name-modifier then
3312  // all if clauses on the directive must include a directive-name-modifier.
3313  if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
3314  if (NamedModifiersNumber == AllowedNameModifiers.size()) {
3315  S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
3316  diag::err_omp_no_more_if_clause);
3317  } else {
3318  std::string Values;
3319  std::string Sep(", ");
3320  unsigned AllowedCnt = 0;
3321  unsigned TotalAllowedNum =
3322  AllowedNameModifiers.size() - NamedModifiersNumber;
3323  for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
3324  ++Cnt) {
3325  OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
3326  if (!FoundNameModifiers[NM]) {
3327  Values += "'";
3328  Values += getOpenMPDirectiveName(NM);
3329  Values += "'";
3330  if (AllowedCnt + 2 == TotalAllowedNum)
3331  Values += " or ";
3332  else if (AllowedCnt + 1 != TotalAllowedNum)
3333  Values += Sep;
3334  ++AllowedCnt;
3335  }
3336  }
3337  S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
3338  diag::err_omp_unnamed_if_clause)
3339  << (TotalAllowedNum > 1) << Values;
3340  }
3341  for (SourceLocation Loc : NameModifierLoc) {
3342  S.Diag(Loc, diag::note_omp_previous_named_if_clause);
3343  }
3344  ErrorFound = true;
3345  }
3346  return ErrorFound;
3347 }
3348 
3351  OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
3352  Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
3353  StmtResult Res = StmtError();
3354  // First check CancelRegion which is then used in checkNestingOfRegions.
3355  if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
3356  checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
3357  StartLoc))
3358  return StmtError();
3359 
3360  llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
3361  VarsWithInheritedDSAType VarsWithInheritedDSA;
3362  bool ErrorFound = false;
3363  ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
3364  if (AStmt && !CurContext->isDependentContext()) {
3365  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
3366 
3367  // Check default data sharing attributes for referenced variables.
3368  DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
3369  int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
3370  Stmt *S = AStmt;
3371  while (--ThisCaptureLevel >= 0)
3372  S = cast<CapturedStmt>(S)->getCapturedStmt();
3373  DSAChecker.Visit(S);
3374  if (DSAChecker.isErrorFound())
3375  return StmtError();
3376  // Generate list of implicitly defined firstprivate variables.
3377  VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
3378 
3379  SmallVector<Expr *, 4> ImplicitFirstprivates(
3380  DSAChecker.getImplicitFirstprivate().begin(),
3381  DSAChecker.getImplicitFirstprivate().end());
3382  SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(),
3383  DSAChecker.getImplicitMap().end());
3384  // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
3385  for (OMPClause *C : Clauses) {
3386  if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
3387  for (Expr *E : IRC->taskgroup_descriptors())
3388  if (E)
3389  ImplicitFirstprivates.emplace_back(E);
3390  }
3391  }
3392  if (!ImplicitFirstprivates.empty()) {
3393  if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
3394  ImplicitFirstprivates, SourceLocation(), SourceLocation(),
3395  SourceLocation())) {
3396  ClausesWithImplicit.push_back(Implicit);
3397  ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
3398  ImplicitFirstprivates.size();
3399  } else {
3400  ErrorFound = true;
3401  }
3402  }
3403  if (!ImplicitMaps.empty()) {
3404  if (OMPClause *Implicit = ActOnOpenMPMapClause(
3405  llvm::None, llvm::None, OMPC_MAP_tofrom,
3406  /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
3407  ImplicitMaps, SourceLocation(), SourceLocation(),
3408  SourceLocation())) {
3409  ClausesWithImplicit.emplace_back(Implicit);
3410  ErrorFound |=
3411  cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size();
3412  } else {
3413  ErrorFound = true;
3414  }
3415  }
3416  }
3417 
3418  llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
3419  switch (Kind) {
3420  case OMPD_parallel:
3421  Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
3422  EndLoc);
3423  AllowedNameModifiers.push_back(OMPD_parallel);
3424  break;
3425  case OMPD_simd:
3426  Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
3427  VarsWithInheritedDSA);
3428  break;
3429  case OMPD_for:
3430  Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
3431  VarsWithInheritedDSA);
3432  break;
3433  case OMPD_for_simd:
3434  Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3435  EndLoc, VarsWithInheritedDSA);
3436  break;
3437  case OMPD_sections:
3438  Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
3439  EndLoc);
3440  break;
3441  case OMPD_section:
3442  assert(ClausesWithImplicit.empty() &&
3443  "No clauses are allowed for 'omp section' directive");
3444  Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
3445  break;
3446  case OMPD_single:
3447  Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
3448  EndLoc);
3449  break;
3450  case OMPD_master:
3451  assert(ClausesWithImplicit.empty() &&
3452  "No clauses are allowed for 'omp master' directive");
3453  Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
3454  break;
3455  case OMPD_critical:
3456  Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
3457  StartLoc, EndLoc);
3458  break;
3459  case OMPD_parallel_for:
3460  Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
3461  EndLoc, VarsWithInheritedDSA);
3462  AllowedNameModifiers.push_back(OMPD_parallel);
3463  break;
3464  case OMPD_parallel_for_simd:
3465  Res = ActOnOpenMPParallelForSimdDirective(
3466  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3467  AllowedNameModifiers.push_back(OMPD_parallel);
3468  break;
3469  case OMPD_parallel_sections:
3470  Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
3471  StartLoc, EndLoc);
3472  AllowedNameModifiers.push_back(OMPD_parallel);
3473  break;
3474  case OMPD_task:
3475  Res =
3476  ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
3477  AllowedNameModifiers.push_back(OMPD_task);
3478  break;
3479  case OMPD_taskyield:
3480  assert(ClausesWithImplicit.empty() &&
3481  "No clauses are allowed for 'omp taskyield' directive");
3482  assert(AStmt == nullptr &&
3483  "No associated statement allowed for 'omp taskyield' directive");
3484  Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
3485  break;
3486  case OMPD_barrier:
3487  assert(ClausesWithImplicit.empty() &&
3488  "No clauses are allowed for 'omp barrier' directive");
3489  assert(AStmt == nullptr &&
3490  "No associated statement allowed for 'omp barrier' directive");
3491  Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
3492  break;
3493  case OMPD_taskwait:
3494  assert(ClausesWithImplicit.empty() &&
3495  "No clauses are allowed for 'omp taskwait' directive");
3496  assert(AStmt == nullptr &&
3497  "No associated statement allowed for 'omp taskwait' directive");
3498  Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
3499  break;
3500  case OMPD_taskgroup:
3501  Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
3502  EndLoc);
3503  break;
3504  case OMPD_flush:
3505  assert(AStmt == nullptr &&
3506  "No associated statement allowed for 'omp flush' directive");
3507  Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
3508  break;
3509  case OMPD_ordered:
3510  Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
3511  EndLoc);
3512  break;
3513  case OMPD_atomic:
3514  Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
3515  EndLoc);
3516  break;
3517  case OMPD_teams:
3518  Res =
3519  ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
3520  break;
3521  case OMPD_target:
3522  Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
3523  EndLoc);
3524  AllowedNameModifiers.push_back(OMPD_target);
3525  break;
3526  case OMPD_target_parallel:
3527  Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
3528  StartLoc, EndLoc);
3529  AllowedNameModifiers.push_back(OMPD_target);
3530  AllowedNameModifiers.push_back(OMPD_parallel);
3531  break;
3532  case OMPD_target_parallel_for:
3533  Res = ActOnOpenMPTargetParallelForDirective(
3534  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3535  AllowedNameModifiers.push_back(OMPD_target);
3536  AllowedNameModifiers.push_back(OMPD_parallel);
3537  break;
3538  case OMPD_cancellation_point:
3539  assert(ClausesWithImplicit.empty() &&
3540  "No clauses are allowed for 'omp cancellation point' directive");
3541  assert(AStmt == nullptr && "No associated statement allowed for 'omp "
3542  "cancellation point' directive");
3543  Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
3544  break;
3545  case OMPD_cancel:
3546  assert(AStmt == nullptr &&
3547  "No associated statement allowed for 'omp cancel' directive");
3548  Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
3549  CancelRegion);
3550  AllowedNameModifiers.push_back(OMPD_cancel);
3551  break;
3552  case OMPD_target_data:
3553  Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
3554  EndLoc);
3555  AllowedNameModifiers.push_back(OMPD_target_data);
3556  break;
3557  case OMPD_target_enter_data:
3558  Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
3559  EndLoc, AStmt);
3560  AllowedNameModifiers.push_back(OMPD_target_enter_data);
3561  break;
3562  case OMPD_target_exit_data:
3563  Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
3564  EndLoc, AStmt);
3565  AllowedNameModifiers.push_back(OMPD_target_exit_data);
3566  break;
3567  case OMPD_taskloop:
3568  Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
3569  EndLoc, VarsWithInheritedDSA);
3570  AllowedNameModifiers.push_back(OMPD_taskloop);
3571  break;
3572  case OMPD_taskloop_simd:
3573  Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3574  EndLoc, VarsWithInheritedDSA);
3575  AllowedNameModifiers.push_back(OMPD_taskloop);
3576  break;
3577  case OMPD_distribute:
3578  Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
3579  EndLoc, VarsWithInheritedDSA);
3580  break;
3581  case OMPD_target_update:
3582  Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
3583  EndLoc, AStmt);
3584  AllowedNameModifiers.push_back(OMPD_target_update);
3585  break;
3586  case OMPD_distribute_parallel_for:
3587  Res = ActOnOpenMPDistributeParallelForDirective(
3588  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3589  AllowedNameModifiers.push_back(OMPD_parallel);
3590  break;
3591  case OMPD_distribute_parallel_for_simd:
3592  Res = ActOnOpenMPDistributeParallelForSimdDirective(
3593  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3594  AllowedNameModifiers.push_back(OMPD_parallel);
3595  break;
3596  case OMPD_distribute_simd:
3597  Res = ActOnOpenMPDistributeSimdDirective(
3598  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3599  break;
3600  case OMPD_target_parallel_for_simd:
3601  Res = ActOnOpenMPTargetParallelForSimdDirective(
3602  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3603  AllowedNameModifiers.push_back(OMPD_target);
3604  AllowedNameModifiers.push_back(OMPD_parallel);
3605  break;
3606  case OMPD_target_simd:
3607  Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
3608  EndLoc, VarsWithInheritedDSA);
3609  AllowedNameModifiers.push_back(OMPD_target);
3610  break;
3611  case OMPD_teams_distribute:
3612  Res = ActOnOpenMPTeamsDistributeDirective(
3613  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3614  break;
3615  case OMPD_teams_distribute_simd:
3616  Res = ActOnOpenMPTeamsDistributeSimdDirective(
3617  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3618  break;
3619  case OMPD_teams_distribute_parallel_for_simd:
3620  Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
3621  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3622  AllowedNameModifiers.push_back(OMPD_parallel);
3623  break;
3624  case OMPD_teams_distribute_parallel_for:
3625  Res = ActOnOpenMPTeamsDistributeParallelForDirective(
3626  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3627  AllowedNameModifiers.push_back(OMPD_parallel);
3628  break;
3629  case OMPD_target_teams:
3630  Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
3631  EndLoc);
3632  AllowedNameModifiers.push_back(OMPD_target);
3633  break;
3634  case OMPD_target_teams_distribute:
3635  Res = ActOnOpenMPTargetTeamsDistributeDirective(
3636  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3637  AllowedNameModifiers.push_back(OMPD_target);
3638  break;
3639  case OMPD_target_teams_distribute_parallel_for:
3640  Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
3641  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3642  AllowedNameModifiers.push_back(OMPD_target);
3643  AllowedNameModifiers.push_back(OMPD_parallel);
3644  break;
3645  case OMPD_target_teams_distribute_parallel_for_simd:
3646  Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
3647  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3648  AllowedNameModifiers.push_back(OMPD_target);
3649  AllowedNameModifiers.push_back(OMPD_parallel);
3650  break;
3651  case OMPD_target_teams_distribute_simd:
3652  Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
3653  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
3654  AllowedNameModifiers.push_back(OMPD_target);
3655  break;
3656  case OMPD_declare_target:
3657  case OMPD_end_declare_target:
3658  case OMPD_threadprivate:
3659  case OMPD_declare_reduction:
3660  case OMPD_declare_simd:
3661  case OMPD_requires:
3662  llvm_unreachable("OpenMP Directive is not allowed");
3663  case OMPD_unknown:
3664  llvm_unreachable("Unknown OpenMP directive");
3665  }
3666 
3667  for (const auto &P : VarsWithInheritedDSA) {
3668  Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
3669  << P.first << P.second->getSourceRange();
3670  }
3671  ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound;
3672 
3673  if (!AllowedNameModifiers.empty())
3674  ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
3675  ErrorFound;
3676 
3677  if (ErrorFound)
3678  return StmtError();
3679  return Res;
3680 }
3681 
3683  DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
3684  ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
3685  ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
3686  ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
3687  assert(Aligneds.size() == Alignments.size());
3688  assert(Linears.size() == LinModifiers.size());
3689  assert(Linears.size() == Steps.size());
3690  if (!DG || DG.get().isNull())
3691  return DeclGroupPtrTy();
3692 
3693  if (!DG.get().isSingleDecl()) {
3694  Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd);
3695  return DG;
3696  }
3697  Decl *ADecl = DG.get().getSingleDecl();
3698  if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
3699  ADecl = FTD->getTemplatedDecl();
3700 
3701  auto *FD = dyn_cast<FunctionDecl>(ADecl);
3702  if (!FD) {
3703  Diag(ADecl->getLocation(), diag::err_omp_function_expected);
3704  return DeclGroupPtrTy();
3705  }
3706 
3707  // OpenMP [2.8.2, declare simd construct, Description]
3708  // The parameter of the simdlen clause must be a constant positive integer
3709  // expression.
3710  ExprResult SL;
3711  if (Simdlen)
3712  SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
3713  // OpenMP [2.8.2, declare simd construct, Description]
3714  // The special this pointer can be used as if was one of the arguments to the
3715  // function in any of the linear, aligned, or uniform clauses.
3716  // The uniform clause declares one or more arguments to have an invariant
3717  // value for all concurrent invocations of the function in the execution of a
3718  // single SIMD loop.
3719  llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
3720  const Expr *UniformedLinearThis = nullptr;
3721  for (const Expr *E : Uniforms) {
3722  E = E->IgnoreParenImpCasts();
3723  if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
3724  if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
3725  if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3726  FD->getParamDecl(PVD->getFunctionScopeIndex())
3727  ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
3728  UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
3729  continue;
3730  }
3731  if (isa<CXXThisExpr>(E)) {
3732  UniformedLinearThis = E;
3733  continue;
3734  }
3735  Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3736  << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3737  }
3738  // OpenMP [2.8.2, declare simd construct, Description]
3739  // The aligned clause declares that the object to which each list item points
3740  // is aligned to the number of bytes expressed in the optional parameter of
3741  // the aligned clause.
3742  // The special this pointer can be used as if was one of the arguments to the
3743  // function in any of the linear, aligned, or uniform clauses.
3744  // The type of list items appearing in the aligned clause must be array,
3745  // pointer, reference to array, or reference to pointer.
3746  llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
3747  const Expr *AlignedThis = nullptr;
3748  for (const Expr *E : Aligneds) {
3749  E = E->IgnoreParenImpCasts();
3750  if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
3751  if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3752  const VarDecl *CanonPVD = PVD->getCanonicalDecl();
3753  if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3754  FD->getParamDecl(PVD->getFunctionScopeIndex())
3755  ->getCanonicalDecl() == CanonPVD) {
3756  // OpenMP [2.8.1, simd construct, Restrictions]
3757  // A list-item cannot appear in more than one aligned clause.
3758  if (AlignedArgs.count(CanonPVD) > 0) {
3759  Diag(E->getExprLoc(), diag::err_omp_aligned_twice)
3760  << 1 << E->getSourceRange();
3761  Diag(AlignedArgs[CanonPVD]->getExprLoc(),
3762  diag::note_omp_explicit_dsa)
3763  << getOpenMPClauseName(OMPC_aligned);
3764  continue;
3765  }
3766  AlignedArgs[CanonPVD] = E;
3767  QualType QTy = PVD->getType()
3768  .getNonReferenceType()
3769  .getUnqualifiedType()
3770  .getCanonicalType();
3771  const Type *Ty = QTy.getTypePtrOrNull();
3772  if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
3773  Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
3774  << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
3775  Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
3776  }
3777  continue;
3778  }
3779  }
3780  if (isa<CXXThisExpr>(E)) {
3781  if (AlignedThis) {
3782  Diag(E->getExprLoc(), diag::err_omp_aligned_twice)
3783  << 2 << E->getSourceRange();
3784  Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
3785  << getOpenMPClauseName(OMPC_aligned);
3786  }
3787  AlignedThis = E;
3788  continue;
3789  }
3790  Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3791  << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3792  }
3793  // The optional parameter of the aligned clause, alignment, must be a constant
3794  // positive integer expression. If no optional parameter is specified,
3795  // implementation-defined default alignments for SIMD instructions on the
3796  // target platforms are assumed.
3797  SmallVector<const Expr *, 4> NewAligns;
3798  for (Expr *E : Alignments) {
3799  ExprResult Align;
3800  if (E)
3801  Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
3802  NewAligns.push_back(Align.get());
3803  }
3804  // OpenMP [2.8.2, declare simd construct, Description]
3805  // The linear clause declares one or more list items to be private to a SIMD
3806  // lane and to have a linear relationship with respect to the iteration space
3807  // of a loop.
3808  // The special this pointer can be used as if was one of the arguments to the
3809  // function in any of the linear, aligned, or uniform clauses.
3810  // When a linear-step expression is specified in a linear clause it must be
3811  // either a constant integer expression or an integer-typed parameter that is
3812  // specified in a uniform clause on the directive.
3813  llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
3814  const bool IsUniformedThis = UniformedLinearThis != nullptr;
3815  auto MI = LinModifiers.begin();
3816  for (const Expr *E : Linears) {
3817  auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
3818  ++MI;
3819  E = E->IgnoreParenImpCasts();
3820  if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
3821  if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3822  const VarDecl *CanonPVD = PVD->getCanonicalDecl();
3823  if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
3824  FD->getParamDecl(PVD->getFunctionScopeIndex())
3825  ->getCanonicalDecl() == CanonPVD) {
3826  // OpenMP [2.15.3.7, linear Clause, Restrictions]
3827  // A list-item cannot appear in more than one linear clause.
3828  if (LinearArgs.count(CanonPVD) > 0) {
3829  Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3830  << getOpenMPClauseName(OMPC_linear)
3831  << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
3832  Diag(LinearArgs[CanonPVD]->getExprLoc(),
3833  diag::note_omp_explicit_dsa)
3834  << getOpenMPClauseName(OMPC_linear);
3835  continue;
3836  }
3837  // Each argument can appear in at most one uniform or linear clause.
3838  if (UniformedArgs.count(CanonPVD) > 0) {
3839  Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3840  << getOpenMPClauseName(OMPC_linear)
3842  Diag(UniformedArgs[CanonPVD]->getExprLoc(),
3843  diag::note_omp_explicit_dsa)
3845  continue;
3846  }
3847  LinearArgs[CanonPVD] = E;
3848  if (E->isValueDependent() || E->isTypeDependent() ||
3849  E->isInstantiationDependent() ||
3851  continue;
3852  (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
3853  PVD->getOriginalType());
3854  continue;
3855  }
3856  }
3857  if (isa<CXXThisExpr>(E)) {
3858  if (UniformedLinearThis) {
3859  Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
3860  << getOpenMPClauseName(OMPC_linear)
3861  << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
3862  << E->getSourceRange();
3863  Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
3864  << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
3865  : OMPC_linear);
3866  continue;
3867  }
3868  UniformedLinearThis = E;
3869  if (E->isValueDependent() || E->isTypeDependent() ||
3871  continue;
3872  (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
3873  E->getType());
3874  continue;
3875  }
3876  Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
3877  << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
3878  }
3879  Expr *Step = nullptr;
3880  Expr *NewStep = nullptr;
3881  SmallVector<Expr *, 4> NewSteps;
3882  for (Expr *E : Steps) {
3883  // Skip the same step expression, it was checked already.
3884  if (Step == E || !E) {
3885  NewSteps.push_back(E ? NewStep : nullptr);
3886  continue;
3887  }
3888  Step = E;
3889  if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
3890  if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
3891  const VarDecl *CanonPVD = PVD->getCanonicalDecl();
3892  if (UniformedArgs.count(CanonPVD) == 0) {
3893  Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
3894  << Step->getSourceRange();
3895  } else if (E->isValueDependent() || E->isTypeDependent() ||
3896  E->isInstantiationDependent() ||
3898  CanonPVD->getType()->hasIntegerRepresentation()) {
3899  NewSteps.push_back(Step);
3900  } else {
3901  Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
3902  << Step->getSourceRange();
3903  }
3904  continue;
3905  }
3906  NewStep = Step;
3907  if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
3908  !Step->isInstantiationDependent() &&
3910  NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
3911  .get();
3912  if (NewStep)
3913  NewStep = VerifyIntegerConstantExpression(NewStep).get();
3914  }
3915  NewSteps.push_back(NewStep);
3916  }
3917  auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
3918  Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
3919  Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
3920  const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
3921  const_cast<Expr **>(Linears.data()), Linears.size(),
3922  const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
3923  NewSteps.data(), NewSteps.size(), SR);
3924  ADecl->addAttr(NewAttr);
3925  return ConvertDeclToDeclGroup(ADecl);
3926 }
3927 
3929  Stmt *AStmt,
3930  SourceLocation StartLoc,
3931  SourceLocation EndLoc) {
3932  if (!AStmt)
3933  return StmtError();
3934 
3935  auto *CS = cast<CapturedStmt>(AStmt);
3936  // 1.2.2 OpenMP Language Terminology
3937  // Structured block - An executable statement with a single entry at the
3938  // top and a single exit at the bottom.
3939  // The point of exit cannot be a branch out of the structured block.
3940  // longjmp() and throw() must not violate the entry/exit criteria.
3941  CS->getCapturedDecl()->setNothrow();
3942 
3943  setFunctionHasBranchProtectedScope();
3944 
3945  return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
3946  DSAStack->isCancelRegion());
3947 }
3948 
3949 namespace {
3950 /// Helper class for checking canonical form of the OpenMP loops and
3951 /// extracting iteration space of each loop in the loop nest, that will be used
3952 /// for IR generation.
3953 class OpenMPIterationSpaceChecker {
3954  /// Reference to Sema.
3955  Sema &SemaRef;
3956  /// A location for diagnostics (when there is no some better location).
3957  SourceLocation DefaultLoc;
3958  /// A location for diagnostics (when increment is not compatible).
3959  SourceLocation ConditionLoc;
3960  /// A source location for referring to loop init later.
3961  SourceRange InitSrcRange;
3962  /// A source location for referring to condition later.
3963  SourceRange ConditionSrcRange;
3964  /// A source location for referring to increment later.
3965  SourceRange IncrementSrcRange;
3966  /// Loop variable.
3967  ValueDecl *LCDecl = nullptr;
3968  /// Reference to loop variable.
3969  Expr *LCRef = nullptr;
3970  /// Lower bound (initializer for the var).
3971  Expr *LB = nullptr;
3972  /// Upper bound.
3973  Expr *UB = nullptr;
3974  /// Loop step (increment).
3975  Expr *Step = nullptr;
3976  /// This flag is true when condition is one of:
3977  /// Var < UB
3978  /// Var <= UB
3979  /// UB > Var
3980  /// UB >= Var
3981  /// This will have no value when the condition is !=
3982  llvm::Optional<bool> TestIsLessOp;
3983  /// This flag is true when condition is strict ( < or > ).
3984  bool TestIsStrictOp = false;
3985  /// This flag is true when step is subtracted on each iteration.
3986  bool SubtractStep = false;
3987 
3988 public:
3989  OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc)
3990  : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
3991  /// Check init-expr for canonical loop form and save loop counter
3992  /// variable - #Var and its initialization value - #LB.
3993  bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
3994  /// Check test-expr for canonical form, save upper-bound (#UB), flags
3995  /// for less/greater and for strict/non-strict comparison.
3996  bool checkAndSetCond(Expr *S);
3997  /// Check incr-expr for canonical loop form and return true if it
3998  /// does not conform, otherwise save loop step (#Step).
3999  bool checkAndSetInc(Expr *S);
4000  /// Return the loop counter variable.
4001  ValueDecl *getLoopDecl() const { return LCDecl; }
4002  /// Return the reference expression to loop counter variable.
4003  Expr *getLoopDeclRefExpr() const { return LCRef; }
4004  /// Source range of the loop init.
4005  SourceRange getInitSrcRange() const { return InitSrcRange; }
4006  /// Source range of the loop condition.
4007  SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
4008  /// Source range of the loop increment.
4009  SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
4010  /// True if the step should be subtracted.
4011  bool shouldSubtractStep() const { return SubtractStep; }
4012  /// Build the expression to calculate the number of iterations.
4013  Expr *buildNumIterations(
4014  Scope *S, const bool LimitedType,
4015  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
4016  /// Build the precondition expression for the loops.
4017  Expr *
4018  buildPreCond(Scope *S, Expr *Cond,
4019  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
4020  /// Build reference expression to the counter be used for codegen.
4021  DeclRefExpr *
4022  buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
4023  DSAStackTy &DSA) const;
4024  /// Build reference expression to the private counter be used for
4025  /// codegen.
4026  Expr *buildPrivateCounterVar() const;
4027  /// Build initialization of the counter be used for codegen.
4028  Expr *buildCounterInit() const;
4029  /// Build step of the counter be used for codegen.
4030  Expr *buildCounterStep() const;
4031  /// Build loop data with counter value for depend clauses in ordered
4032  /// directives.
4033  Expr *
4034  buildOrderedLoopData(Scope *S, Expr *Counter,
4035  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
4036  SourceLocation Loc, Expr *Inc = nullptr,
4037  OverloadedOperatorKind OOK = OO_Amp);
4038  /// Return true if any expression is dependent.
4039  bool dependent() const;
4040 
4041 private:
4042  /// Check the right-hand side of an assignment in the increment
4043  /// expression.
4044  bool checkAndSetIncRHS(Expr *RHS);
4045  /// Helper to set loop counter variable and its initializer.
4046  bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB);
4047  /// Helper to set upper bound.
4048  bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp,
4049  SourceRange SR, SourceLocation SL);
4050  /// Helper to set loop increment.
4051  bool setStep(Expr *NewStep, bool Subtract);
4052 };
4053 
4054 bool OpenMPIterationSpaceChecker::dependent() const {
4055  if (!LCDecl) {
4056  assert(!LB && !UB && !Step);
4057  return false;
4058  }
4059  return LCDecl->getType()->isDependentType() ||
4060  (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
4061  (Step && Step->isValueDependent());
4062 }
4063 
4064 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
4065  Expr *NewLCRefExpr,
4066  Expr *NewLB) {
4067  // State consistency checking to ensure correct usage.
4068  assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
4069  UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
4070  if (!NewLCDecl || !NewLB)
4071  return true;
4072  LCDecl = getCanonicalDecl(NewLCDecl);
4073  LCRef = NewLCRefExpr;
4074  if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
4075  if (const CXXConstructorDecl *Ctor = CE->getConstructor())
4076  if ((Ctor->isCopyOrMoveConstructor() ||
4077  Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
4078  CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
4079  NewLB = CE->getArg(0)->IgnoreParenImpCasts();
4080  LB = NewLB;
4081  return false;
4082 }
4083 
4084 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, llvm::Optional<bool> LessOp,
4085  bool StrictOp, SourceRange SR,
4086  SourceLocation SL) {
4087  // State consistency checking to ensure correct usage.
4088  assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&
4089  Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
4090  if (!NewUB)
4091  return true;
4092  UB = NewUB;
4093  if (LessOp)
4094  TestIsLessOp = LessOp;
4095  TestIsStrictOp = StrictOp;
4096  ConditionSrcRange = SR;
4097  ConditionLoc = SL;
4098  return false;
4099 }
4100 
4101 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
4102  // State consistency checking to ensure correct usage.
4103  assert(LCDecl != nullptr && LB != nullptr && Step == nullptr);
4104  if (!NewStep)
4105  return true;
4106  if (!NewStep->isValueDependent()) {
4107  // Check that the step is integer expression.
4108  SourceLocation StepLoc = NewStep->getBeginLoc();
4110  StepLoc, getExprAsWritten(NewStep));
4111  if (Val.isInvalid())
4112  return true;
4113  NewStep = Val.get();
4114 
4115  // OpenMP [2.6, Canonical Loop Form, Restrictions]
4116  // If test-expr is of form var relational-op b and relational-op is < or
4117  // <= then incr-expr must cause var to increase on each iteration of the
4118  // loop. If test-expr is of form var relational-op b and relational-op is
4119  // > or >= then incr-expr must cause var to decrease on each iteration of
4120  // the loop.
4121  // If test-expr is of form b relational-op var and relational-op is < or
4122  // <= then incr-expr must cause var to decrease on each iteration of the
4123  // loop. If test-expr is of form b relational-op var and relational-op is
4124  // > or >= then incr-expr must cause var to increase on each iteration of
4125  // the loop.
4126  llvm::APSInt Result;
4127  bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context);
4128  bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
4129  bool IsConstNeg =
4130  IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
4131  bool IsConstPos =
4132  IsConstant && Result.isSigned() && (Subtract == Result.isNegative());
4133  bool IsConstZero = IsConstant && !Result.getBoolValue();
4134 
4135  // != with increment is treated as <; != with decrement is treated as >
4136  if (!TestIsLessOp.hasValue())
4137  TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
4138  if (UB && (IsConstZero ||
4139  (TestIsLessOp.getValue() ?
4140  (IsConstNeg || (IsUnsigned && Subtract)) :
4141  (IsConstPos || (IsUnsigned && !Subtract))))) {
4142  SemaRef.Diag(NewStep->getExprLoc(),
4143  diag::err_omp_loop_incr_not_compatible)
4144  << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange();
4145  SemaRef.Diag(ConditionLoc,
4146  diag::note_omp_loop_cond_requres_compatible_incr)
4147  << TestIsLessOp.getValue() << ConditionSrcRange;
4148  return true;
4149  }
4150  if (TestIsLessOp.getValue() == Subtract) {
4151  NewStep =
4152  SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
4153  .get();
4154  Subtract = !Subtract;
4155  }
4156  }
4157 
4158  Step = NewStep;
4159  SubtractStep = Subtract;
4160  return false;
4161 }
4162 
4163 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
4164  // Check init-expr for canonical loop form and save loop counter
4165  // variable - #Var and its initialization value - #LB.
4166  // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
4167  // var = lb
4168  // integer-type var = lb
4169  // random-access-iterator-type var = lb
4170  // pointer-type var = lb
4171  //
4172  if (!S) {
4173  if (EmitDiags) {
4174  SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
4175  }
4176  return true;
4177  }
4178  if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
4179  if (!ExprTemp->cleanupsHaveSideEffects())
4180  S = ExprTemp->getSubExpr();
4181 
4182  InitSrcRange = S->getSourceRange();
4183  if (Expr *E = dyn_cast<Expr>(S))
4184  S = E->IgnoreParens();
4185  if (auto *BO = dyn_cast<BinaryOperator>(S)) {
4186  if (BO->getOpcode() == BO_Assign) {
4187  Expr *LHS = BO->getLHS()->IgnoreParens();
4188  if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
4189  if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
4190  if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
4191  return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
4192  return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS());
4193  }
4194  if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
4195  if (ME->isArrow() &&
4196  isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
4197  return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
4198  }
4199  }
4200  } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
4201  if (DS->isSingleDecl()) {
4202  if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
4203  if (Var->hasInit() && !Var->getType()->isReferenceType()) {
4204  // Accept non-canonical init form here but emit ext. warning.
4205  if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
4206  SemaRef.Diag(S->getBeginLoc(),
4207  diag::ext_omp_loop_not_canonical_init)
4208  << S->getSourceRange();
4209  return setLCDeclAndLB(
4210  Var,
4211  buildDeclRefExpr(SemaRef, Var,
4212  Var->getType().getNonReferenceType(),
4213  DS->getBeginLoc()),
4214  Var->getInit());
4215  }
4216  }
4217  }
4218  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
4219  if (CE->getOperator() == OO_Equal) {
4220  Expr *LHS = CE->getArg(0);
4221  if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
4222  if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
4223  if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
4224  return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
4225  return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1));
4226  }
4227  if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
4228  if (ME->isArrow() &&
4229  isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
4230  return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS());
4231  }
4232  }
4233  }
4234 
4235  if (dependent() || SemaRef.CurContext->isDependentContext())
4236  return false;
4237  if (EmitDiags) {
4238  SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
4239  << S->getSourceRange();
4240  }
4241  return true;
4242 }
4243 
4244 /// Ignore parenthesizes, implicit casts, copy constructor and return the
4245 /// variable (which may be the loop variable) if possible.
4246 static const ValueDecl *getInitLCDecl(const Expr *E) {
4247  if (!E)
4248  return nullptr;
4249  E = getExprAsWritten(E);
4250  if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
4251  if (const CXXConstructorDecl *Ctor = CE->getConstructor())
4252  if ((Ctor->isCopyOrMoveConstructor() ||
4253  Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
4254  CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
4255  E = CE->getArg(0)->IgnoreParenImpCasts();
4256  if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
4257  if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
4258  return getCanonicalDecl(VD);
4259  }
4260  if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
4261  if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
4262  return getCanonicalDecl(ME->getMemberDecl());
4263  return nullptr;
4264 }
4265 
4266 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
4267  // Check test-expr for canonical form, save upper-bound UB, flags for
4268  // less/greater and for strict/non-strict comparison.
4269  // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
4270  // var relational-op b
4271  // b relational-op var
4272  //
4273  if (!S) {
4274  SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl;
4275  return true;
4276  }
4277  S = getExprAsWritten(S);
4278  SourceLocation CondLoc = S->getBeginLoc();
4279  if (auto *BO = dyn_cast<BinaryOperator>(S)) {
4280  if (BO->isRelationalOp()) {
4281  if (getInitLCDecl(BO->getLHS()) == LCDecl)
4282  return setUB(BO->getRHS(),
4283  (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
4284  (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
4285  BO->getSourceRange(), BO->getOperatorLoc());
4286  if (getInitLCDecl(BO->getRHS()) == LCDecl)
4287  return setUB(BO->getLHS(),
4288  (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
4289  (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
4290  BO->getSourceRange(), BO->getOperatorLoc());
4291  } else if (BO->getOpcode() == BO_NE)
4292  return setUB(getInitLCDecl(BO->getLHS()) == LCDecl ?
4293  BO->getRHS() : BO->getLHS(),
4294  /*LessOp=*/llvm::None,
4295  /*StrictOp=*/true,
4296  BO->getSourceRange(), BO->getOperatorLoc());
4297  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
4298  if (CE->getNumArgs() == 2) {
4299  auto Op = CE->getOperator();
4300  switch (Op) {
4301  case OO_Greater:
4302  case OO_GreaterEqual:
4303  case OO_Less:
4304  case OO_LessEqual:
4305  if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4306  return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
4307  Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
4308  CE->getOperatorLoc());
4309  if (getInitLCDecl(CE->getArg(1)) == LCDecl)
4310  return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
4311  Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
4312  CE->getOperatorLoc());
4313  break;
4314  case OO_ExclaimEqual:
4315  return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ?
4316  CE->getArg(1) : CE->getArg(0),
4317  /*LessOp=*/llvm::None,
4318  /*StrictOp=*/true,
4319  CE->getSourceRange(),
4320  CE->getOperatorLoc());
4321  break;
4322  default:
4323  break;
4324  }
4325  }
4326  }
4327  if (dependent() || SemaRef.CurContext->isDependentContext())
4328  return false;
4329  SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
4330  << S->getSourceRange() << LCDecl;
4331  return true;
4332 }
4333 
4334 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
4335  // RHS of canonical loop form increment can be:
4336  // var + incr
4337  // incr + var
4338  // var - incr
4339  //
4340  RHS = RHS->IgnoreParenImpCasts();
4341  if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
4342  if (BO->isAdditiveOp()) {
4343  bool IsAdd = BO->getOpcode() == BO_Add;
4344  if (getInitLCDecl(BO->getLHS()) == LCDecl)
4345  return setStep(BO->getRHS(), !IsAdd);
4346  if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
4347  return setStep(BO->getLHS(), /*Subtract=*/false);
4348  }
4349  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
4350  bool IsAdd = CE->getOperator() == OO_Plus;
4351  if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
4352  if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4353  return setStep(CE->getArg(1), !IsAdd);
4354  if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
4355  return setStep(CE->getArg(0), /*Subtract=*/false);
4356  }
4357  }
4358  if (dependent() || SemaRef.CurContext->isDependentContext())
4359  return false;
4360  SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
4361  << RHS->getSourceRange() << LCDecl;
4362  return true;
4363 }
4364 
4365 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
4366  // Check incr-expr for canonical loop form and return true if it
4367  // does not conform.
4368  // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
4369  // ++var
4370  // var++
4371  // --var
4372  // var--
4373  // var += incr
4374  // var -= incr
4375  // var = var + incr
4376  // var = incr + var
4377  // var = var - incr
4378  //
4379  if (!S) {
4380  SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
4381  return true;
4382  }
4383  if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
4384  if (!ExprTemp->cleanupsHaveSideEffects())
4385  S = ExprTemp->getSubExpr();
4386 
4387  IncrementSrcRange = S->getSourceRange();
4388  S = S->IgnoreParens();
4389  if (auto *UO = dyn_cast<UnaryOperator>(S)) {
4390  if (UO->isIncrementDecrementOp() &&
4391  getInitLCDecl(UO->getSubExpr()) == LCDecl)
4392  return setStep(SemaRef
4393  .ActOnIntegerConstant(UO->getBeginLoc(),
4394  (UO->isDecrementOp() ? -1 : 1))
4395  .get(),
4396  /*Subtract=*/false);
4397  } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
4398  switch (BO->getOpcode()) {
4399  case BO_AddAssign:
4400  case BO_SubAssign:
4401  if (getInitLCDecl(BO->getLHS()) == LCDecl)
4402  return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
4403  break;
4404  case BO_Assign:
4405  if (getInitLCDecl(BO->getLHS()) == LCDecl)
4406  return checkAndSetIncRHS(BO->getRHS());
4407  break;
4408  default:
4409  break;
4410  }
4411  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
4412  switch (CE->getOperator()) {
4413  case OO_PlusPlus:
4414  case OO_MinusMinus:
4415  if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4416  return setStep(SemaRef
4417  .ActOnIntegerConstant(
4418  CE->getBeginLoc(),
4419  ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
4420  .get(),
4421  /*Subtract=*/false);
4422  break;
4423  case OO_PlusEqual:
4424  case OO_MinusEqual:
4425  if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4426  return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
4427  break;
4428  case OO_Equal:
4429  if (getInitLCDecl(CE->getArg(0)) == LCDecl)
4430  return checkAndSetIncRHS(CE->getArg(1));
4431  break;
4432  default:
4433  break;
4434  }
4435  }
4436  if (dependent() || SemaRef.CurContext->isDependentContext())
4437  return false;
4438  SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
4439  << S->getSourceRange() << LCDecl;
4440  return true;
4441 }
4442 
4443 static ExprResult
4444 tryBuildCapture(Sema &SemaRef, Expr *Capture,
4445  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
4446  if (SemaRef.CurContext->isDependentContext())
4447  return ExprResult(Capture);
4448  if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
4449  return SemaRef.PerformImplicitConversion(
4450  Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
4451  /*AllowExplicit=*/true);
4452  auto I = Captures.find(Capture);
4453  if (I != Captures.end())
4454  return buildCapture(SemaRef, Capture, I->second);
4455  DeclRefExpr *Ref = nullptr;
4456  ExprResult Res = buildCapture(SemaRef, Capture, Ref);
4457  Captures[Capture] = Ref;
4458  return Res;
4459 }
4460 
4461 /// Build the expression to calculate the number of iterations.
4462 Expr *OpenMPIterationSpaceChecker::buildNumIterations(
4463  Scope *S, const bool LimitedType,
4464  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
4465  ExprResult Diff;
4466  QualType VarType = LCDecl->getType().getNonReferenceType();
4467  if (VarType->isIntegerType() || VarType->isPointerType() ||
4468  SemaRef.getLangOpts().CPlusPlus) {
4469  // Upper - Lower
4470  Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB;
4471  Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB;
4472  Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
4473  Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
4474  if (!Upper || !Lower)
4475  return nullptr;
4476 
4477  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
4478 
4479  if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) {
4480  // BuildBinOp already emitted error, this one is to point user to upper
4481  // and lower bound, and to tell what is passed to 'operator-'.
4482  SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
4483  << Upper->getSourceRange() << Lower->getSourceRange();
4484  return nullptr;
4485  }
4486  }
4487 
4488  if (!Diff.isUsable())
4489  return nullptr;
4490 
4491  // Upper - Lower [- 1]
4492  if (TestIsStrictOp)
4493  Diff = SemaRef.BuildBinOp(
4494  S, DefaultLoc, BO_Sub, Diff.get(),
4495  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
4496  if (!Diff.isUsable())
4497  return nullptr;
4498 
4499  // Upper - Lower [- 1] + Step
4500  ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
4501  if (!NewStep.isUsable())
4502  return nullptr;
4503  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
4504  if (!Diff.isUsable())
4505  return nullptr;
4506 
4507  // Parentheses (for dumping/debugging purposes only).
4508  Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
4509  if (!Diff.isUsable())
4510  return nullptr;
4511 
4512  // (Upper - Lower [- 1] + Step) / Step
4513  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
4514  if (!Diff.isUsable())
4515  return nullptr;
4516 
4517  // OpenMP runtime requires 32-bit or 64-bit loop variables.
4518  QualType Type = Diff.get()->getType();
4519  ASTContext &C = SemaRef.Context;
4520  bool UseVarType = VarType->hasIntegerRepresentation() &&
4521  C.getTypeSize(Type) > C.getTypeSize(VarType);
4522  if (!Type->isIntegerType() || UseVarType) {
4523  unsigned NewSize =
4524  UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
4525  bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
4527  Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
4528  if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
4529  Diff = SemaRef.PerformImplicitConversion(
4530  Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
4531  if (!Diff.isUsable())
4532  return nullptr;
4533  }
4534  }
4535  if (LimitedType) {
4536  unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
4537  if (NewSize != C.getTypeSize(Type)) {
4538  if (NewSize < C.getTypeSize(Type)) {
4539  assert(NewSize == 64 && "incorrect loop var size");
4540  SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
4541  << InitSrcRange << ConditionSrcRange;
4542  }
4543  QualType NewType = C.getIntTypeForBitwidth(
4544  NewSize, Type->hasSignedIntegerRepresentation() ||
4545  C.getTypeSize(Type) < NewSize);
4546  if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
4547  Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
4548  Sema::AA_Converting, true);
4549  if (!Diff.isUsable())
4550  return nullptr;
4551  }
4552  }
4553  }
4554 
4555  return Diff.get();
4556 }
4557 
4558 Expr *OpenMPIterationSpaceChecker::buildPreCond(
4559  Scope *S, Expr *Cond,
4560  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
4561  // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
4562  bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
4563  SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
4564 
4565  ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
4566  ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
4567  if (!NewLB.isUsable() || !NewUB.isUsable())
4568  return nullptr;
4569 
4570  ExprResult CondExpr =
4571  SemaRef.BuildBinOp(S, DefaultLoc,
4572  TestIsLessOp.getValue() ?
4573  (TestIsStrictOp ? BO_LT : BO_LE) :
4574  (TestIsStrictOp ? BO_GT : BO_GE),
4575  NewLB.get(), NewUB.get());
4576  if (CondExpr.isUsable()) {
4577  if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
4578  SemaRef.Context.BoolTy))
4579  CondExpr = SemaRef.PerformImplicitConversion(
4580  CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
4581  /*AllowExplicit=*/true);
4582  }
4583  SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
4584  // Otherwise use original loop conditon and evaluate it in runtime.
4585  return CondExpr.isUsable() ? CondExpr.get() : Cond;
4586 }
4587 
4588 /// Build reference expression to the counter be used for codegen.
4589 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
4590  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
4591  DSAStackTy &DSA) const {
4592  auto *VD = dyn_cast<VarDecl>(LCDecl);
4593  if (!VD) {
4594  VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
4596  SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
4597  const DSAStackTy::DSAVarData Data =
4598  DSA.getTopDSA(LCDecl, /*FromParent=*/false);
4599  // If the loop control decl is explicitly marked as private, do not mark it
4600  // as captured again.
4601  if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
4602  Captures.insert(std::make_pair(LCRef, Ref));
4603  return Ref;
4604  }
4605  return buildDeclRefExpr(SemaRef, VD, VD->getType().getNonReferenceType(),
4606  DefaultLoc);
4607 }
4608 
4609 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
4610  if (LCDecl && !LCDecl->isInvalidDecl()) {
4611  QualType Type = LCDecl->getType().getNonReferenceType();
4612  VarDecl *PrivateVar = buildVarDecl(
4613  SemaRef, DefaultLoc, Type, LCDecl->getName(),
4614  LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
4615  isa<VarDecl>(LCDecl)
4616  ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
4617  : nullptr);
4618  if (PrivateVar->isInvalidDecl())
4619  return nullptr;
4620  return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
4621  }
4622  return nullptr;
4623 }
4624 
4625 /// Build initialization of the counter to be used for codegen.
4627 
4628 /// Build step of the counter be used for codegen.
4629 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
4630 
4631 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
4632  Scope *S, Expr *Counter,
4633  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
4634  Expr *Inc, OverloadedOperatorKind OOK) {
4635  Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
4636  if (!Cnt)
4637  return nullptr;
4638  if (Inc) {
4639  assert((OOK == OO_Plus || OOK == OO_Minus) &&
4640  "Expected only + or - operations for depend clauses.");
4641  BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
4642  Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
4643  if (!Cnt)
4644  return nullptr;
4645  }
4646  ExprResult Diff;
4647  QualType VarType = LCDecl->getType().getNonReferenceType();
4648  if (VarType->isIntegerType() || VarType->isPointerType() ||
4649  SemaRef.getLangOpts().CPlusPlus) {
4650  // Upper - Lower
4651  Expr *Upper =
4652  TestIsLessOp.getValue() ? Cnt : tryBuildCapture(SemaRef, UB, Captures).get();
4653  Expr *Lower =
4654  TestIsLessOp.getValue() ? tryBuildCapture(SemaRef, LB, Captures).get() : Cnt;
4655  if (!Upper || !Lower)
4656  return nullptr;
4657 
4658  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
4659 
4660  if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) {
4661  // BuildBinOp already emitted error, this one is to point user to upper
4662  // and lower bound, and to tell what is passed to 'operator-'.
4663  SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
4664  << Upper->getSourceRange() << Lower->getSourceRange();
4665  return nullptr;
4666  }
4667  }
4668 
4669  if (!Diff.isUsable())
4670  return nullptr;
4671 
4672  // Parentheses (for dumping/debugging purposes only).
4673  Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
4674  if (!Diff.isUsable())
4675  return nullptr;
4676 
4677  ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
4678  if (!NewStep.isUsable())
4679  return nullptr;
4680  // (Upper - Lower) / Step
4681  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
4682  if (!Diff.isUsable())
4683  return nullptr;
4684 
4685  return Diff.get();
4686 }
4687 
4688 /// Iteration space of a single for loop.
4689 struct LoopIterationSpace final {
4690  /// Condition of the loop.
4691  Expr *PreCond = nullptr;
4692  /// This expression calculates the number of iterations in the loop.
4693  /// It is always possible to calculate it before starting the loop.
4694  Expr *NumIterations = nullptr;
4695  /// The loop counter variable.
4696  Expr *CounterVar = nullptr;
4697  /// Private loop counter variable.
4698  Expr *PrivateCounterVar = nullptr;
4699  /// This is initializer for the initial value of #CounterVar.
4700  Expr *CounterInit = nullptr;
4701  /// This is step for the #CounterVar used to generate its update:
4702  /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
4703  Expr *CounterStep = nullptr;
4704  /// Should step be subtracted?
4705  bool Subtract = false;
4706  /// Source range of the loop init.
4707  SourceRange InitSrcRange;
4708  /// Source range of the loop condition.
4709  SourceRange CondSrcRange;
4710  /// Source range of the loop increment.
4711  SourceRange IncSrcRange;
4712 };
4713 
4714 } // namespace
4715 
4717  assert(getLangOpts().OpenMP && "OpenMP is not active.");
4718  assert(Init && "Expected loop in canonical form.");
4719  unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
4720  if (AssociatedLoops > 0 &&
4721  isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
4722  DSAStack->loopStart();
4723  OpenMPIterationSpaceChecker ISC(*this, ForLoc);
4724  if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
4725  if (ValueDecl *D = ISC.getLoopDecl()) {
4726  auto *VD = dyn_cast<VarDecl>(D);
4727  if (!VD) {
4728  if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
4729  VD = Private;
4730  } else {
4731  DeclRefExpr *Ref = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
4732  /*WithInit=*/false);
4733  VD = cast<VarDecl>(Ref->getDecl());
4734  }
4735  }
4736  DSAStack->addLoopControlVariable(D, VD);
4737  const Decl *LD = DSAStack->getPossiblyLoopCunter();
4738  if (LD != D->getCanonicalDecl()) {
4739  DSAStack->resetPossibleLoopCounter();
4740  if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
4741  MarkDeclarationsReferencedInExpr(
4742  buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
4743  Var->getType().getNonLValueExprType(Context),
4744  ForLoc, /*RefersToCapture=*/true));
4745  }
4746  }
4747  }
4748  DSAStack->setAssociatedLoops(AssociatedLoops - 1);
4749  }
4750 }
4751 
4752 /// Called on a for stmt to check and extract its iteration space
4753 /// for further processing (such as collapsing).
4755  OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
4756  unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
4757  unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
4758  Expr *OrderedLoopCountExpr,
4759  Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
4760  LoopIterationSpace &ResultIterSpace,
4761  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
4762  // OpenMP [2.6, Canonical Loop Form]
4763  // for (init-expr; test-expr; incr-expr) structured-block
4764  auto *For = dyn_cast_or_null<ForStmt>(S);
4765  if (!For) {
4766  SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
4767  << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
4768  << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
4769  << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
4770  if (TotalNestedLoopCount > 1) {
4771  if (CollapseLoopCountExpr && OrderedLoopCountExpr)
4772  SemaRef.Diag(DSA.getConstructLoc(),
4773  diag::note_omp_collapse_ordered_expr)
4774  << 2 << CollapseLoopCountExpr->getSourceRange()
4775  << OrderedLoopCountExpr->getSourceRange();
4776  else if (CollapseLoopCountExpr)
4777  SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
4778  diag::note_omp_collapse_ordered_expr)
4779  << 0 << CollapseLoopCountExpr->getSourceRange();
4780  else
4781  SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
4782  diag::note_omp_collapse_ordered_expr)
4783  << 1 << OrderedLoopCountExpr->getSourceRange();
4784  }
4785  return true;
4786  }
4787  assert(For->getBody());
4788 
4789  OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc());
4790 
4791  // Check init.
4792  Stmt *Init = For->getInit();
4793  if (ISC.checkAndSetInit(Init))
4794  return true;
4795 
4796  bool HasErrors = false;
4797 
4798  // Check loop variable's type.
4799  if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
4800  Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
4801 
4802  // OpenMP [2.6, Canonical Loop Form]
4803  // Var is one of the following:
4804  // A variable of signed or unsigned integer type.
4805  // For C++, a variable of a random access iterator type.
4806  // For C, a variable of a pointer type.
4807  QualType VarType = LCDecl->getType().getNonReferenceType();
4808  if (!VarType->isDependentType() && !VarType->isIntegerType() &&
4809  !VarType->isPointerType() &&
4810  !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
4811  SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
4812  << SemaRef.getLangOpts().CPlusPlus;
4813  HasErrors = true;
4814  }
4815 
4816  // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
4817  // a Construct
4818  // The loop iteration variable(s) in the associated for-loop(s) of a for or
4819  // parallel for construct is (are) private.
4820  // The loop iteration variable in the associated for-loop of a simd
4821  // construct with just one associated for-loop is linear with a
4822  // constant-linear-step that is the increment of the associated for-loop.
4823  // Exclude loop var from the list of variables with implicitly defined data
4824  // sharing attributes.
4825  VarsWithImplicitDSA.erase(LCDecl);
4826 
4827  // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
4828  // in a Construct, C/C++].
4829  // The loop iteration variable in the associated for-loop of a simd
4830  // construct with just one associated for-loop may be listed in a linear
4831  // clause with a constant-linear-step that is the increment of the
4832  // associated for-loop.
4833  // The loop iteration variable(s) in the associated for-loop(s) of a for or
4834  // parallel for construct may be listed in a private or lastprivate clause.
4835  DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl, false);
4836  // If LoopVarRefExpr is nullptr it means the corresponding loop variable is
4837  // declared in the loop and it is predetermined as a private.
4838  OpenMPClauseKind PredeterminedCKind =
4839  isOpenMPSimdDirective(DKind)
4840  ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate)
4841  : OMPC_private;
4842  if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
4843  DVar.CKind != PredeterminedCKind) ||
4844  ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
4845  isOpenMPDistributeDirective(DKind)) &&
4846  !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
4847  DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
4848  (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
4849  SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
4850  << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind)
4851  << getOpenMPClauseName(PredeterminedCKind);
4852  if (DVar.RefExpr == nullptr)
4853  DVar.CKind = PredeterminedCKind;
4854  reportOriginalDsa(SemaRef, &DSA, LCDecl, DVar, /*IsLoopIterVar=*/true);
4855  HasErrors = true;
4856  } else if (LoopDeclRefExpr != nullptr) {
4857  // Make the loop iteration variable private (for worksharing constructs),
4858  // linear (for simd directives with the only one associated loop) or
4859  // lastprivate (for simd directives with several collapsed or ordered
4860  // loops).
4861  if (DVar.CKind == OMPC_unknown)
4862  DVar = DSA.hasDSA(LCDecl, isOpenMPPrivate,
4863  [](OpenMPDirectiveKind) -> bool { return true; },
4864  /*FromParent=*/false);
4865  DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind);
4866  }
4867 
4868  assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
4869 
4870  // Check test-expr.
4871  HasErrors |= ISC.checkAndSetCond(For->getCond());
4872 
4873  // Check incr-expr.
4874  HasErrors |= ISC.checkAndSetInc(For->getInc());
4875  }
4876 
4877  if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
4878  return HasErrors;
4879 
4880  // Build the loop's iteration space representation.
4881  ResultIterSpace.PreCond =
4882  ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures);
4883  ResultIterSpace.NumIterations = ISC.buildNumIterations(
4884  DSA.getCurScope(),
4885  (isOpenMPWorksharingDirective(DKind) ||
4887  Captures);
4888  ResultIterSpace.CounterVar = ISC.buildCounterVar(Captures, DSA);
4889  ResultIterSpace.PrivateCounterVar = ISC.buildPrivateCounterVar();
4890  ResultIterSpace.CounterInit = ISC.buildCounterInit();
4891  ResultIterSpace.CounterStep = ISC.buildCounterStep();
4892  ResultIterSpace.InitSrcRange = ISC.getInitSrcRange();
4893  ResultIterSpace.CondSrcRange = ISC.getConditionSrcRange();
4894  ResultIterSpace.IncSrcRange = ISC.getIncrementSrcRange();
4895  ResultIterSpace.Subtract = ISC.shouldSubtractStep();
4896 
4897  HasErrors |= (ResultIterSpace.PreCond == nullptr ||
4898  ResultIterSpace.NumIterations == nullptr ||
4899  ResultIterSpace.CounterVar == nullptr ||
4900  ResultIterSpace.PrivateCounterVar == nullptr ||
4901  ResultIterSpace.CounterInit == nullptr ||
4902  ResultIterSpace.CounterStep == nullptr);
4903  if (!HasErrors && DSA.isOrderedRegion()) {
4904  if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
4905  if (CurrentNestedLoopCount <
4906  DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
4907  DSA.getOrderedRegionParam().second->setLoopNumIterations(
4908  CurrentNestedLoopCount, ResultIterSpace.NumIterations);
4909  DSA.getOrderedRegionParam().second->setLoopCounter(
4910  CurrentNestedLoopCount, ResultIterSpace.CounterVar);
4911  }
4912  }
4913  for (auto &Pair : DSA.getDoacrossDependClauses()) {
4914  if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
4915  // Erroneous case - clause has some problems.
4916  continue;
4917  }
4918  if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
4919  Pair.second.size() <= CurrentNestedLoopCount) {
4920  // Erroneous case - clause has some problems.
4921  Pair.first->setLoopData(CurrentNestedLoopCount, nullptr);
4922  continue;
4923  }
4924  Expr *CntValue;
4925  if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
4926  CntValue = ISC.buildOrderedLoopData(
4927  DSA.getCurScope(), ResultIterSpace.CounterVar, Captures,
4928  Pair.first->getDependencyLoc());
4929  else
4930  CntValue = ISC.buildOrderedLoopData(
4931  DSA.getCurScope(), ResultIterSpace.CounterVar, Captures,
4932  Pair.first->getDependencyLoc(),
4933  Pair.second[CurrentNestedLoopCount].first,
4934  Pair.second[CurrentNestedLoopCount].second);
4935  Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
4936  }
4937  }
4938 
4939  return HasErrors;
4940 }
4941 
4942 /// Build 'VarRef = Start.
4943 static ExprResult
4945  ExprResult Start,
4946  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
4947  // Build 'VarRef = Start.
4948  ExprResult NewStart = tryBuildCapture(SemaRef, Start.get(), Captures);
4949  if (!NewStart.isUsable())
4950  return ExprError();
4951  if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
4952  VarRef.get()->getType())) {
4953  NewStart = SemaRef.PerformImplicitConversion(
4954  NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
4955  /*AllowExplicit=*/true);
4956  if (!NewStart.isUsable())
4957  return ExprError();
4958  }
4959 
4960  ExprResult Init =
4961  SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
4962  return Init;
4963 }
4964 
4965 /// Build 'VarRef = Start + Iter * Step'.
4967  Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
4968  ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
4969  llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
4970  // Add parentheses (for debugging purposes only).
4971  Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
4972  if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
4973  !Step.isUsable())
4974  return ExprError();
4975 
4976  ExprResult NewStep = Step;
4977  if (Captures)
4978  NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
4979  if (NewStep.isInvalid())
4980  return ExprError();
4981  ExprResult Update =
4982  SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
4983  if (!Update.isUsable())
4984  return ExprError();
4985 
4986  // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
4987  // 'VarRef = Start (+|-) Iter * Step'.
4988  ExprResult NewStart = Start;
4989  if (Captures)
4990  NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
4991  if (NewStart.isInvalid())
4992  return ExprError();
4993 
4994  // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
4995  ExprResult SavedUpdate = Update;
4996  ExprResult UpdateVal;
4997  if (VarRef.get()->getType()->isOverloadableType() ||
4998  NewStart.get()->getType()->isOverloadableType() ||
4999  Update.get()->getType()->isOverloadableType()) {
5000  bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics();
5001  SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
5002  Update =
5003  SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
5004  if (Update.isUsable()) {
5005  UpdateVal =
5006  SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
5007  VarRef.get(), SavedUpdate.get());
5008  if (UpdateVal.isUsable()) {
5009  Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
5010  UpdateVal.get());
5011  }
5012  }
5013  SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress);
5014  }
5015 
5016  // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
5017  if (!Update.isUsable() || !UpdateVal.isUsable()) {
5018  Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
5019  NewStart.get(), SavedUpdate.get());
5020  if (!Update.isUsable())
5021  return ExprError();
5022 
5023  if (!SemaRef.Context.hasSameType(Update.get()->getType(),
5024  VarRef.get()->getType())) {
5025  Update = SemaRef.PerformImplicitConversion(
5026  Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
5027  if (!Update.isUsable())
5028  return ExprError();
5029  }
5030 
5031  Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
5032  }
5033  return Update;
5034 }
5035 
5036 /// Convert integer expression \a E to make it have at least \a Bits
5037 /// bits.
5038 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
5039  if (E == nullptr)
5040  return ExprError();
5041  ASTContext &C = SemaRef.Context;
5042  QualType OldType = E->getType();
5043  unsigned HasBits = C.getTypeSize(OldType);
5044  if (HasBits >= Bits)
5045  return ExprResult(E);
5046  // OK to convert to signed, because new type has more bits than old.
5047  QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
5048  return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
5049  true);
5050 }
5051 
5052 /// Check if the given expression \a E is a constant integer that fits
5053 /// into \a Bits bits.
5054 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
5055  if (E == nullptr)
5056  return false;
5057  llvm::APSInt Result;
5058  if (E->isIntegerConstantExpr(Result, SemaRef.Context))
5059  return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits);
5060  return false;
5061 }
5062 
5063 /// Build preinits statement for the given declarations.
5064 static Stmt *buildPreInits(ASTContext &Context,
5065  MutableArrayRef<Decl *> PreInits) {
5066  if (!PreInits.empty()) {
5067  return new (Context) DeclStmt(
5068  DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
5070  }
5071  return nullptr;
5072 }
5073 
5074 /// Build preinits statement for the given declarations.
5075 static Stmt *
5077  const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
5078  if (!Captures.empty()) {
5079  SmallVector<Decl *, 16> PreInits;
5080  for (const auto &Pair : Captures)
5081  PreInits.push_back(Pair.second->getDecl());
5082  return buildPreInits(Context, PreInits);
5083  }
5084  return nullptr;
5085 }
5086 
5087 /// Build postupdate expression for the given list of postupdates expressions.
5088 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
5089  Expr *PostUpdate = nullptr;
5090  if (!PostUpdates.empty()) {
5091  for (Expr *E : PostUpdates) {
5092  Expr *ConvE = S.BuildCStyleCastExpr(
5093  E->getExprLoc(),
5095  E->getExprLoc(), E)
5096  .get();
5097  PostUpdate = PostUpdate
5098  ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
5099  PostUpdate, ConvE)
5100  .get()
5101  : ConvE;
5102  }
5103  }
5104  return PostUpdate;
5105 }
5106 
5107 /// Called on a for stmt to check itself and nested loops (if any).
5108 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
5109 /// number of collapsed loops otherwise.
5110 static unsigned
5111 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
5112  Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
5113  DSAStackTy &DSA,
5114  Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
5116  unsigned NestedLoopCount = 1;
5117  if (CollapseLoopCountExpr) {
5118  // Found 'collapse' clause - calculate collapse number.
5120  if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext()))
5121  NestedLoopCount = Result.Val.getInt().getLimitedValue();
5122  }
5123  unsigned OrderedLoopCount = 1;
5124  if (OrderedLoopCountExpr) {
5125  // Found 'ordered' clause - calculate collapse number.
5126  Expr::EvalResult EVResult;
5127  if (OrderedLoopCountExpr->EvaluateAsInt(EVResult, SemaRef.getASTContext())) {
5128  llvm::APSInt Result = EVResult.Val.getInt();
5129  if (Result.getLimitedValue() < NestedLoopCount) {
5130  SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
5131  diag::err_omp_wrong_ordered_loop_count)
5132  << OrderedLoopCountExpr->getSourceRange();
5133  SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
5134  diag::note_collapse_loop_count)
5135  << CollapseLoopCountExpr->getSourceRange();
5136  }
5137  OrderedLoopCount = Result.getLimitedValue();
5138  }
5139  }
5140  // This is helper routine for loop directives (e.g., 'for', 'simd',
5141  // 'for simd', etc.).
5142  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
5144  IterSpaces.resize(std::max(OrderedLoopCount, NestedLoopCount));
5145  Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true);
5146  for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
5148  DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
5149  std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
5150  OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt],
5151  Captures))
5152  return 0;
5153  // Move on to the next nested for loop, or to the loop body.
5154  // OpenMP [2.8.1, simd construct, Restrictions]
5155  // All loops associated with the construct must be perfectly nested; that
5156  // is, there must be no intervening code nor any OpenMP directive between
5157  // any two loops.
5158  CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers();
5159  }
5160  for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) {
5162  DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
5163  std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
5164  OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt],
5165  Captures))
5166  return 0;
5167  if (Cnt > 0 && IterSpaces[Cnt].CounterVar) {
5168  // Handle initialization of captured loop iterator variables.
5169  auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
5170  if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
5171  Captures[DRE] = DRE;
5172  }
5173  }
5174  // Move on to the next nested for loop, or to the loop body.
5175  // OpenMP [2.8.1, simd construct, Restrictions]
5176  // All loops associated with the construct must be perfectly nested; that
5177  // is, there must be no intervening code nor any OpenMP directive between
5178  // any two loops.
5179  CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers();
5180  }
5181 
5182  Built.clear(/* size */ NestedLoopCount);
5183 
5184  if (SemaRef.CurContext->isDependentContext())
5185  return NestedLoopCount;
5186 
5187  // An example of what is generated for the following code:
5188  //
5189  // #pragma omp simd collapse(2) ordered(2)
5190  // for (i = 0; i < NI; ++i)
5191  // for (k = 0; k < NK; ++k)
5192  // for (j = J0; j < NJ; j+=2) {
5193  // <loop body>
5194  // }
5195  //
5196  // We generate the code below.
5197  // Note: the loop body may be outlined in CodeGen.
5198  // Note: some counters may be C++ classes, operator- is used to find number of
5199  // iterations and operator+= to calculate counter value.
5200  // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
5201  // or i64 is currently supported).
5202  //
5203  // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
5204  // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
5205  // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
5206  // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
5207  // // similar updates for vars in clauses (e.g. 'linear')
5208  // <loop body (using local i and j)>
5209  // }
5210  // i = NI; // assign final values of counters
5211  // j = NJ;
5212  //
5213 
5214  // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
5215  // the iteration counts of the collapsed for loops.
5216  // Precondition tests if there is at least one iteration (all conditions are
5217  // true).
5218  auto PreCond = ExprResult(IterSpaces[0].PreCond);
5219  Expr *N0 = IterSpaces[0].NumIterations;
5220  ExprResult LastIteration32 =
5221  widenIterationCount(/*Bits=*/32,
5222  SemaRef
5223  .PerformImplicitConversion(
5224  N0->IgnoreImpCasts(), N0->getType(),
5225  Sema::AA_Converting, /*AllowExplicit=*/true)
5226  .get(),
5227  SemaRef);
5228  ExprResult LastIteration64 = widenIterationCount(
5229  /*Bits=*/64,
5230  SemaRef
5231  .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
5233  /*AllowExplicit=*/true)
5234  .get(),
5235  SemaRef);
5236 
5237  if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
5238  return NestedLoopCount;
5239 
5240  ASTContext &C = SemaRef.Context;
5241  bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
5242 
5243  Scope *CurScope = DSA.getCurScope();
5244  for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
5245  if (PreCond.isUsable()) {
5246  PreCond =
5247  SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
5248  PreCond.get(), IterSpaces[Cnt].PreCond);
5249  }
5250  Expr *N = IterSpaces[Cnt].NumIterations;
5251  SourceLocation Loc = N->getExprLoc();
5252  AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
5253  if (LastIteration32.isUsable())
5254  LastIteration32 = SemaRef.BuildBinOp(
5255  CurScope, Loc, BO_Mul, LastIteration32.get(),
5256  SemaRef
5259  /*AllowExplicit=*/true)
5260  .get());
5261  if (LastIteration64.isUsable())
5262  LastIteration64 = SemaRef.BuildBinOp(
5263  CurScope, Loc, BO_Mul, LastIteration64.get(),
5264  SemaRef
5267  /*AllowExplicit=*/true)
5268  .get());
5269  }
5270 
5271  // Choose either the 32-bit or 64-bit version.
5272  ExprResult LastIteration = LastIteration64;
5273  if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
5274  (LastIteration32.isUsable() &&
5275  C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
5276  (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
5277  fitsInto(
5278  /*Bits=*/32,
5279  LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
5280  LastIteration64.get(), SemaRef))))
5281  LastIteration = LastIteration32;
5282  QualType VType = LastIteration.get()->getType();
5283  QualType RealVType = VType;
5284  QualType StrideVType = VType;
5285  if (isOpenMPTaskLoopDirective(DKind)) {
5286  VType =
5287  SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
5288  StrideVType =
5289  SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
5290  }
5291 
5292  if (!LastIteration.isUsable())
5293  return 0;
5294 
5295  // Save the number of iterations.
5296  ExprResult NumIterations = LastIteration;
5297  {
5298  LastIteration = SemaRef.BuildBinOp(
5299  CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
5300  LastIteration.get(),
5301  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
5302  if (!LastIteration.isUsable())
5303  return 0;
5304  }
5305 
5306  // Calculate the last iteration number beforehand instead of doing this on
5307  // each iteration. Do not do this if the number of iterations may be kfold-ed.
5308  llvm::APSInt Result;
5309  bool IsConstant =
5310  LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context);
5311  ExprResult CalcLastIteration;
5312  if (!IsConstant) {
5313  ExprResult SaveRef =
5314  tryBuildCapture(SemaRef, LastIteration.get(), Captures);
5315  LastIteration = SaveRef;
5316 
5317  // Prepare SaveRef + 1.
5318  NumIterations = SemaRef.BuildBinOp(
5319  CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
5320  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
5321  if (!NumIterations.isUsable())
5322  return 0;
5323  }
5324 
5325  SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
5326 
5327  // Build variables passed into runtime, necessary for worksharing directives.
5328  ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
5330  isOpenMPDistributeDirective(DKind)) {
5331  // Lower bound variable, initialized with zero.
5332  VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
5333  LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
5334  SemaRef.AddInitializerToDecl(LBDecl,
5335  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
5336  /*DirectInit*/ false);
5337 
5338  // Upper bound variable, initialized with last iteration number.
5339  VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
5340  UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
5341  SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
5342  /*DirectInit*/ false);
5343 
5344  // A 32-bit variable-flag where runtime returns 1 for the last iteration.
5345  // This will be used to implement clause 'lastprivate'.
5346  QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
5347  VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
5348  IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
5349  SemaRef.AddInitializerToDecl(ILDecl,
5350  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
5351  /*DirectInit*/ false);
5352 
5353  // Stride variable returned by runtime (we initialize it to 1 by default).
5354  VarDecl *STDecl =
5355  buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
5356  ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
5357  SemaRef.AddInitializerToDecl(STDecl,
5358  SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
5359  /*DirectInit*/ false);
5360 
5361  // Build expression: UB = min(UB, LastIteration)
5362  // It is necessary for CodeGen of directives with static scheduling.
5363  ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
5364  UB.get(), LastIteration.get());
5365  ExprResult CondOp = SemaRef.ActOnConditionalOp(
5366  LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
5367  LastIteration.get(), UB.get());
5368  EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
5369  CondOp.get());
5370  EUB = SemaRef.ActOnFinishFullExpr(EUB.get());
5371 
5372  // If we have a combined directive that combines 'distribute', 'for' or
5373  // 'simd' we need to be able to access the bounds of the schedule of the
5374  // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
5375  // by scheduling 'distribute' have to be passed to the schedule of 'for'.
5376  if (isOpenMPLoopBoundSharingDirective(DKind)) {
5377  // Lower bound variable, initialized with zero.
5378  VarDecl *CombLBDecl =
5379  buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
5380  CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
5381  SemaRef.AddInitializerToDecl(
5382  CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
5383  /*DirectInit*/ false);
5384 
5385  // Upper bound variable, initialized with last iteration number.
5386  VarDecl *CombUBDecl =
5387  buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
5388  CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
5389  SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
5390  /*DirectInit*/ false);
5391 
5392  ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
5393  CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
5394  ExprResult CombCondOp =
5395  SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
5396  LastIteration.get(), CombUB.get());
5397  CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
5398  CombCondOp.get());
5399  CombEUB = SemaRef.ActOnFinishFullExpr(CombEUB.get());
5400 
5401  const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
5402  // We expect to have at least 2 more parameters than the 'parallel'
5403  // directive does - the lower and upper bounds of the previous schedule.
5404  assert(CD->getNumParams() >= 4 &&
5405  "Unexpected number of parameters in loop combined directive");
5406 
5407  // Set the proper type for the bounds given what we learned from the
5408  // enclosed loops.
5409  ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
5410  ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
5411 
5412  // Previous lower and upper bounds are obtained from the region
5413  // parameters.
5414  PrevLB =
5415  buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
5416  PrevUB =
5417  buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
5418  }
5419  }
5420 
5421  // Build the iteration variable and its initialization before loop.
5422  ExprResult IV;
5423  ExprResult Init, CombInit;
5424  {
5425  VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
5426  IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
5427  Expr *RHS =
5428  (isOpenMPWorksharingDirective(DKind) ||
5430  ? LB.get()
5431  : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
5432  Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
5433  Init = SemaRef.ActOnFinishFullExpr(Init.get());
5434 
5435  if (isOpenMPLoopBoundSharingDirective(DKind)) {
5436  Expr *CombRHS =
5437  (isOpenMPWorksharingDirective(DKind) ||
5438  isOpenMPTaskLoopDirective(DKind) ||
5440  ? CombLB.get()
5441  : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
5442  CombInit =
5443  SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
5444  CombInit = SemaRef.ActOnFinishFullExpr(CombInit.get());
5445  }
5446  }
5447 
5448  // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops.
5449  SourceLocation CondLoc = AStmt->getBeginLoc();
5450  ExprResult Cond =
5451  (isOpenMPWorksharingDirective(DKind) ||
5453  ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get())
5454  : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
5455  NumIterations.get());
5456  ExprResult CombDistCond;
5457  if (isOpenMPLoopBoundSharingDirective(DKind)) {
5458  CombDistCond =
5459  SemaRef.BuildBinOp(
5460  CurScope, CondLoc, BO_LT, IV.get(), NumIterations.get());
5461  }
5462 
5463  ExprResult CombCond;
5464  if (isOpenMPLoopBoundSharingDirective(DKind)) {
5465  CombCond =
5466  SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), CombUB.get());
5467  }
5468  // Loop increment (IV = IV + 1)
5469  SourceLocation IncLoc = AStmt->getBeginLoc();
5470  ExprResult Inc =
5471  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
5472  SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
5473  if (!Inc.isUsable())
5474  return 0;
5475  Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
5476  Inc = SemaRef.ActOnFinishFullExpr(Inc.get());
5477  if (!Inc.isUsable())
5478  return 0;
5479 
5480  // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
5481  // Used for directives with static scheduling.
5482  // In combined construct, add combined version that use CombLB and CombUB
5483  // base variables for the update
5484  ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
5486  isOpenMPDistributeDirective(DKind)) {
5487  // LB + ST
5488  NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
5489  if (!NextLB.isUsable())
5490  return 0;
5491  // LB = LB + ST
5492  NextLB =
5493  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
5494  NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get());
5495  if (!NextLB.isUsable())
5496  return 0;
5497  // UB + ST
5498  NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
5499  if (!NextUB.isUsable())
5500  return 0;
5501  // UB = UB + ST
5502  NextUB =
5503  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
5504  NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get());
5505  if (!NextUB.isUsable())
5506  return 0;
5507  if (isOpenMPLoopBoundSharingDirective(DKind)) {
5508  CombNextLB =
5509  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
5510  if (!NextLB.isUsable())
5511  return 0;
5512  // LB = LB + ST
5513  CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
5514  CombNextLB.get());
5515  CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get());
5516  if (!CombNextLB.isUsable())
5517  return 0;
5518  // UB + ST
5519  CombNextUB =
5520  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
5521  if (!CombNextUB.isUsable())
5522  return 0;
5523  // UB = UB + ST
5524  CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
5525  CombNextUB.get());
5526  CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get());
5527  if (!CombNextUB.isUsable())
5528  return 0;
5529  }
5530  }
5531 
5532  // Create increment expression for distribute loop when combined in a same
5533  // directive with for as IV = IV + ST; ensure upper bound expression based
5534  // on PrevUB instead of NumIterations - used to implement 'for' when found
5535  // in combination with 'distribute', like in 'distribute parallel for'
5536  SourceLocation DistIncLoc = AStmt->getBeginLoc();
5537  ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
5538  if (isOpenMPLoopBoundSharingDirective(DKind)) {
5539  DistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get());
5540  assert(DistCond.isUsable() && "distribute cond expr was not built");
5541 
5542  DistInc =
5543  SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
5544  assert(DistInc.isUsable() && "distribute inc expr was not built");
5545  DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
5546  DistInc.get());
5547  DistInc = SemaRef.ActOnFinishFullExpr(DistInc.get());
5548  assert(DistInc.isUsable() && "distribute inc expr was not built");
5549 
5550  // Build expression: UB = min(UB, prevUB) for #for in composite or combined
5551  // construct
5552  SourceLocation DistEUBLoc = AStmt->getBeginLoc();
5553  ExprResult IsUBGreater =
5554  SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get());
5555  ExprResult CondOp = SemaRef.ActOnConditionalOp(
5556  DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
5557  PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
5558  CondOp.get());
5559  PrevEUB = SemaRef.ActOnFinishFullExpr(PrevEUB.get());
5560 
5561  // Build IV <= PrevUB to be used in parallel for is in combination with
5562  // a distribute directive with schedule(static, 1)
5563  ParForInDistCond =
5564  SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), PrevUB.get());
5565  }
5566 
5567  // Build updates and final values of the loop counters.
5568  bool HasErrors = false;
5569  Built.Counters.resize(NestedLoopCount);
5570  Built.Inits.resize(NestedLoopCount);
5571  Built.Updates.resize(NestedLoopCount);
5572  Built.Finals.resize(NestedLoopCount);
5573  {
5574  // We implement the following algorithm for obtaining the
5575  // original loop iteration variable values based on the
5576  // value of the collapsed loop iteration variable IV.
5577  //
5578  // Let n+1 be the number of collapsed loops in the nest.
5579  // Iteration variables (I0, I1, .... In)
5580  // Iteration counts (N0, N1, ... Nn)
5581  //
5582  // Acc = IV;
5583  //
5584  // To compute Ik for loop k, 0 <= k <= n, generate:
5585  // Prod = N(k+1) * N(k+2) * ... * Nn;
5586  // Ik = Acc / Prod;
5587  // Acc -= Ik * Prod;
5588  //
5589  ExprResult Acc = IV;
5590  for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
5591  LoopIterationSpace &IS = IterSpaces[Cnt];
5592  SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
5593  ExprResult Iter;
5594 
5595  // Compute prod
5596  ExprResult Prod =
5597  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
5598  for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K)
5599  Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
5600  IterSpaces[K].NumIterations);
5601 
5602  // Iter = Acc / Prod
5603  // If there is at least one more inner loop to avoid
5604  // multiplication by 1.
5605  if (Cnt + 1 < NestedLoopCount)
5606  Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div,
5607  Acc.get(), Prod.get());
5608  else
5609  Iter = Acc;
5610  if (!Iter.isUsable()) {
5611  HasErrors = true;
5612  break;
5613  }
5614 
5615  // Update Acc:
5616  // Acc -= Iter * Prod
5617  // Check if there is at least one more inner loop to avoid
5618  // multiplication by 1.
5619  if (Cnt + 1 < NestedLoopCount)
5620  Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul,
5621  Iter.get(), Prod.get());
5622  else
5623  Prod = Iter;
5624  Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub,
5625  Acc.get(), Prod.get());
5626 
5627  // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
5628  auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
5629  DeclRefExpr *CounterVar = buildDeclRefExpr(
5630  SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
5631  /*RefersToCapture=*/true);
5632  ExprResult Init = buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
5633  IS.CounterInit, Captures);
5634  if (!Init.isUsable()) {
5635  HasErrors = true;
5636  break;
5637  }
5639  SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
5640  IS.CounterStep, IS.Subtract, &Captures);
5641  if (!Update.isUsable()) {
5642  HasErrors = true;
5643  break;
5644  }
5645 
5646  // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
5648  SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit,
5649  IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures);
5650  if (!Final.isUsable()) {
5651  HasErrors = true;
5652  break;
5653  }
5654 
5655  if (!Update.isUsable() || !Final.isUsable()) {
5656  HasErrors = true;
5657  break;
5658  }
5659  // Save results
5660  Built.Counters[Cnt] = IS.CounterVar;
5661  Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
5662  Built.Inits[Cnt] = Init.get();
5663  Built.Updates[Cnt] = Update.get();
5664  Built.Finals[Cnt] = Final.get();
5665  }
5666  }
5667 
5668  if (HasErrors)
5669  return 0;
5670 
5671  // Save results
5672  Built.IterationVarRef = IV.get();
5673  Built.LastIteration = LastIteration.get();
5674  Built.NumIterations = NumIterations.get();
5675  Built.CalcLastIteration =
5676  SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get();
5677  Built.PreCond = PreCond.get();
5678  Built.PreInits = buildPreInits(C, Captures);
5679  Built.Cond = Cond.get();
5680  Built.Init = Init.get();
5681  Built.Inc = Inc.get();
5682  Built.LB = LB.get();
5683  Built.UB = UB.get();
5684  Built.IL = IL.get();
5685  Built.ST = ST.get();
5686  Built.EUB = EUB.get();
5687  Built.NLB = NextLB.get();
5688  Built.NUB = NextUB.get();
5689  Built.PrevLB = PrevLB.get();
5690  Built.PrevUB = PrevUB.get();
5691  Built.DistInc = DistInc.get();
5692  Built.PrevEUB = PrevEUB.get();
5693  Built.DistCombinedFields.LB = CombLB.get();
5694  Built.DistCombinedFields.UB = CombUB.get();
5695  Built.DistCombinedFields.EUB = CombEUB.get();
5696  Built.DistCombinedFields.Init = CombInit.get();
5697  Built.DistCombinedFields.Cond = CombCond.get();
5698  Built.DistCombinedFields.NLB = CombNextLB.get();
5699  Built.DistCombinedFields.NUB = CombNextUB.get();
5700  Built.DistCombinedFields.DistCond = CombDistCond.get();
5701  Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
5702 
5703  return NestedLoopCount;
5704 }
5705 
5707  auto CollapseClauses =
5708  OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
5709  if (CollapseClauses.begin() != CollapseClauses.end())
5710  return (*CollapseClauses.begin())->getNumForLoops();
5711  return nullptr;
5712 }
5713 
5715  auto OrderedClauses =
5716  OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
5717  if (OrderedClauses.begin() != OrderedClauses.end())
5718  return (*OrderedClauses.begin())->getNumForLoops();
5719  return nullptr;
5720 }
5721 
5723  const ArrayRef<OMPClause *> Clauses) {
5724  const OMPSafelenClause *Safelen = nullptr;
5725  const OMPSimdlenClause *Simdlen = nullptr;
5726 
5727  for (const OMPClause *Clause : Clauses) {
5728  if (Clause->getClauseKind() == OMPC_safelen)
5729  Safelen = cast<OMPSafelenClause>(Clause);
5730  else if (Clause->getClauseKind() == OMPC_simdlen)
5731  Simdlen = cast<OMPSimdlenClause>(Clause);
5732  if (Safelen && Simdlen)
5733  break;
5734  }
5735 
5736  if (Simdlen && Safelen) {
5737  const Expr *SimdlenLength = Simdlen->getSimdlen();
5738  const Expr *SafelenLength = Safelen->getSafelen();
5739  if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
5740  SimdlenLength->isInstantiationDependent() ||
5741  SimdlenLength->containsUnexpandedParameterPack())
5742  return false;
5743  if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
5744  SafelenLength->isInstantiationDependent() ||
5745  SafelenLength->containsUnexpandedParameterPack())
5746  return false;
5747  Expr::EvalResult SimdlenResult, SafelenResult;
5748  SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
5749  SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
5750  llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
5751  llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
5752  // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
5753  // If both simdlen and safelen clauses are specified, the value of the
5754  // simdlen parameter must be less than or equal to the value of the safelen
5755  // parameter.
5756  if (SimdlenRes > SafelenRes) {
5757  S.Diag(SimdlenLength->getExprLoc(),
5758  diag::err_omp_wrong_simdlen_safelen_values)
5759  << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
5760  return true;
5761  }
5762  }
5763  return false;
5764 }
5765 
5766 StmtResult
5768  SourceLocation StartLoc, SourceLocation EndLoc,
5769  VarsWithInheritedDSAType &VarsWithImplicitDSA) {
5770  if (!AStmt)
5771  return StmtError();
5772 
5773  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5775  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5776  // define the nested loops number.
5777  unsigned NestedLoopCount = checkOpenMPLoop(
5778  OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
5779  AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
5780  if (NestedLoopCount == 0)
5781  return StmtError();
5782 
5783  assert((CurContext->isDependentContext() || B.builtAll()) &&
5784  "omp simd loop exprs were not built");
5785 
5786  if (!CurContext->isDependentContext()) {
5787  // Finalize the clauses that need pre-built expressions for CodeGen.
5788  for (OMPClause *C : Clauses) {
5789  if (auto *LC = dyn_cast<OMPLinearClause>(C))
5790  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5791  B.NumIterations, *this, CurScope,
5792  DSAStack))
5793  return StmtError();
5794  }
5795  }
5796 
5797  if (checkSimdlenSafelenSpecified(*this, Clauses))
5798  return StmtError();
5799 
5800  setFunctionHasBranchProtectedScope();
5801  return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5802  Clauses, AStmt, B);
5803 }
5804 
5805 StmtResult
5807  SourceLocation StartLoc, SourceLocation EndLoc,
5808  VarsWithInheritedDSAType &VarsWithImplicitDSA) {
5809  if (!AStmt)
5810  return StmtError();
5811 
5812  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5814  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5815  // define the nested loops number.
5816  unsigned NestedLoopCount = checkOpenMPLoop(
5817  OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
5818  AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
5819  if (NestedLoopCount == 0)
5820  return StmtError();
5821 
5822  assert((CurContext->isDependentContext() || B.builtAll()) &&
5823  "omp for loop exprs were not built");
5824 
5825  if (!CurContext->isDependentContext()) {
5826  // Finalize the clauses that need pre-built expressions for CodeGen.
5827  for (OMPClause *C : Clauses) {
5828  if (auto *LC = dyn_cast<OMPLinearClause>(C))
5829  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5830  B.NumIterations, *this, CurScope,
5831  DSAStack))
5832  return StmtError();
5833  }
5834  }
5835 
5836  setFunctionHasBranchProtectedScope();
5837  return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5838  Clauses, AStmt, B, DSAStack->isCancelRegion());
5839 }
5840 
5842  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5843  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
5844  if (!AStmt)
5845  return StmtError();
5846 
5847  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5849  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5850  // define the nested loops number.
5851  unsigned NestedLoopCount =
5852  checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
5853  getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
5854  VarsWithImplicitDSA, B);
5855  if (NestedLoopCount == 0)
5856  return StmtError();
5857 
5858  assert((CurContext->isDependentContext() || B.builtAll()) &&
5859  "omp for simd loop exprs were not built");
5860 
5861  if (!CurContext->isDependentContext()) {
5862  // Finalize the clauses that need pre-built expressions for CodeGen.
5863  for (OMPClause *C : Clauses) {
5864  if (auto *LC = dyn_cast<OMPLinearClause>(C))
5865  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5866  B.NumIterations, *this, CurScope,
5867  DSAStack))
5868  return StmtError();
5869  }
5870  }
5871 
5872  if (checkSimdlenSafelenSpecified(*this, Clauses))
5873  return StmtError();
5874 
5875  setFunctionHasBranchProtectedScope();
5876  return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5877  Clauses, AStmt, B);
5878 }
5879 
5881  Stmt *AStmt,
5882  SourceLocation StartLoc,
5883  SourceLocation EndLoc) {
5884  if (!AStmt)
5885  return StmtError();
5886 
5887  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5888  auto BaseStmt = AStmt;
5889  while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
5890  BaseStmt = CS->getCapturedStmt();
5891  if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
5892  auto S = C->children();
5893  if (S.begin() == S.end())
5894  return StmtError();
5895  // All associated statements must be '#pragma omp section' except for
5896  // the first one.
5897  for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
5898  if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
5899  if (SectionStmt)
5900  Diag(SectionStmt->getBeginLoc(),
5901  diag::err_omp_sections_substmt_not_section);
5902  return StmtError();
5903  }
5904  cast<OMPSectionDirective>(SectionStmt)
5905  ->setHasCancel(DSAStack->isCancelRegion());
5906  }
5907  } else {
5908  Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
5909  return StmtError();
5910  }
5911 
5912  setFunctionHasBranchProtectedScope();
5913 
5914  return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
5915  DSAStack->isCancelRegion());
5916 }
5917 
5919  SourceLocation StartLoc,
5920  SourceLocation EndLoc) {
5921  if (!AStmt)
5922  return StmtError();
5923 
5924  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5925 
5926  setFunctionHasBranchProtectedScope();
5927  DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
5928 
5929  return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
5930  DSAStack->isCancelRegion());
5931 }
5932 
5934  Stmt *AStmt,
5935  SourceLocation StartLoc,
5936  SourceLocation EndLoc) {
5937  if (!AStmt)
5938  return StmtError();
5939 
5940  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5941 
5942  setFunctionHasBranchProtectedScope();
5943 
5944  // OpenMP [2.7.3, single Construct, Restrictions]
5945  // The copyprivate clause must not be used with the nowait clause.
5946  const OMPClause *Nowait = nullptr;
5947  const OMPClause *Copyprivate = nullptr;
5948  for (const OMPClause *Clause : Clauses) {
5949  if (Clause->getClauseKind() == OMPC_nowait)
5950  Nowait = Clause;
5951  else if (Clause->getClauseKind() == OMPC_copyprivate)
5952  Copyprivate = Clause;
5953  if (Copyprivate && Nowait) {
5954  Diag(Copyprivate->getBeginLoc(),
5955  diag::err_omp_single_copyprivate_with_nowait);
5956  Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
5957  return StmtError();
5958  }
5959  }
5960 
5961  return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
5962 }
5963 
5965  SourceLocation StartLoc,
5966  SourceLocation EndLoc) {
5967  if (!AStmt)
5968  return StmtError();
5969 
5970  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5971 
5972  setFunctionHasBranchProtectedScope();
5973 
5974  return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
5975 }
5976 
5978  const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
5979  Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
5980  if (!AStmt)
5981  return StmtError();
5982 
5983  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5984 
5985  bool ErrorFound = false;
5986  llvm::APSInt Hint;
5987  SourceLocation HintLoc;
5988  bool DependentHint = false;
5989  for (const OMPClause *C : Clauses) {
5990  if (C->getClauseKind() == OMPC_hint) {
5991  if (!DirName.getName()) {
5992  Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
5993  ErrorFound = true;
5994  }
5995  Expr *E = cast<OMPHintClause>(C)->getHint();
5996  if (E->isTypeDependent() || E->isValueDependent() ||
5997  E->isInstantiationDependent()) {
5998  DependentHint = true;
5999  } else {
6000  Hint = E->EvaluateKnownConstInt(Context);
6001  HintLoc = C->getBeginLoc();
6002  }
6003  }
6004  }
6005  if (ErrorFound)
6006  return StmtError();
6007  const auto Pair = DSAStack->getCriticalWithHint(DirName);
6008  if (Pair.first && DirName.getName() && !DependentHint) {
6009  if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
6010  Diag(StartLoc, diag::err_omp_critical_with_hint);
6011  if (HintLoc.isValid())
6012  Diag(HintLoc, diag::note_omp_critical_hint_here)
6013  << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false);
6014  else
6015  Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
6016  if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
6017  Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
6018  << 1
6019  << C->getHint()->EvaluateKnownConstInt(Context).toString(
6020  /*Radix=*/10, /*Signed=*/false);
6021  } else {
6022  Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
6023  }
6024  }
6025  }
6026 
6027  setFunctionHasBranchProtectedScope();
6028 
6029  auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
6030  Clauses, AStmt);
6031  if (!Pair.first && DirName.getName() && !DependentHint)
6032  DSAStack->addCriticalWithHint(Dir, Hint);
6033  return Dir;
6034 }
6035 
6037  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6038  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
6039  if (!AStmt)
6040  return StmtError();
6041 
6042  auto *CS = cast<CapturedStmt>(AStmt);
6043  // 1.2.2 OpenMP Language Terminology
6044  // Structured block - An executable statement with a single entry at the
6045  // top and a single exit at the bottom.
6046  // The point of exit cannot be a branch out of the structured block.
6047  // longjmp() and throw() must not violate the entry/exit criteria.
6048  CS->getCapturedDecl()->setNothrow();
6049 
6051  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6052  // define the nested loops number.
6053  unsigned NestedLoopCount =
6054  checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
6055  getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
6056  VarsWithImplicitDSA, B);
6057  if (NestedLoopCount == 0)
6058  return StmtError();
6059 
6060  assert((CurContext->isDependentContext() || B.builtAll()) &&
6061  "omp parallel for loop exprs were not built");
6062 
6063  if (!CurContext->isDependentContext()) {
6064  // Finalize the clauses that need pre-built expressions for CodeGen.
6065  for (OMPClause *C : Clauses) {
6066  if (auto *LC = dyn_cast<OMPLinearClause>(C))
6067  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
6068  B.NumIterations, *this, CurScope,
6069  DSAStack))
6070  return StmtError();
6071  }
6072  }
6073 
6074  setFunctionHasBranchProtectedScope();
6075  return OMPParallelForDirective::Create(Context, StartLoc, EndLoc,
6076  NestedLoopCount, Clauses, AStmt, B,
6077  DSAStack->isCancelRegion());
6078 }
6079 
6081  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6082  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
6083  if (!AStmt)
6084  return StmtError();
6085 
6086  auto *CS = cast<CapturedStmt>(AStmt);
6087  // 1.2.2 OpenMP Language Terminology
6088  // Structured block - An executable statement with a single entry at the
6089  // top and a single exit at the bottom.
6090  // The point of exit cannot be a branch out of the structured block.
6091  // longjmp() and throw() must not violate the entry/exit criteria.
6092  CS->getCapturedDecl()->setNothrow();
6093 
6095  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6096  // define the nested loops number.
6097  unsigned NestedLoopCount =
6098  checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
6099  getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
6100  VarsWithImplicitDSA, B);
6101  if (NestedLoopCount == 0)
6102  return StmtError();
6103 
6104  if (!CurContext->isDependentContext()) {
6105  // Finalize the clauses that need pre-built expressions for CodeGen.
6106  for (OMPClause *C : Clauses) {
6107  if (auto *LC = dyn_cast<OMPLinearClause>(C))
6108  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
6109  B.NumIterations, *this, CurScope,
6110  DSAStack))
6111  return StmtError();
6112  }
6113  }
6114 
6115  if (checkSimdlenSafelenSpecified(*this, Clauses))
6116  return StmtError();
6117 
6118  setFunctionHasBranchProtectedScope();
6120  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
6121 }
6122 
6123 StmtResult
6125  Stmt *AStmt, SourceLocation StartLoc,
6126  SourceLocation EndLoc) {
6127  if (!AStmt)
6128  return StmtError();
6129 
6130  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6131  auto BaseStmt = AStmt;
6132  while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
6133  BaseStmt = CS->getCapturedStmt();
6134  if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
6135  auto S = C->children();
6136  if (S.begin() == S.end())
6137  return StmtError();
6138  // All associated statements must be '#pragma omp section' except for
6139  // the first one.
6140  for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
6141  if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
6142  if (SectionStmt)
6143  Diag(SectionStmt->getBeginLoc(),
6144  diag::err_omp_parallel_sections_substmt_not_section);
6145  return StmtError();
6146  }
6147  cast<OMPSectionDirective>(SectionStmt)
6148  ->setHasCancel(DSAStack->isCancelRegion());
6149  }
6150  } else {
6151  Diag(AStmt->getBeginLoc(),
6152  diag::err_omp_parallel_sections_not_compound_stmt);
6153  return StmtError();
6154  }
6155 
6156  setFunctionHasBranchProtectedScope();
6157 
6159  Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion());
6160 }
6161 
6163  Stmt *AStmt, SourceLocation StartLoc,
6164  SourceLocation EndLoc) {
6165  if (!AStmt)
6166  return StmtError();
6167 
6168  auto *CS = cast<CapturedStmt>(AStmt);
6169  // 1.2.2 OpenMP Language Terminology
6170  // Structured block - An executable statement with a single entry at the
6171  // top and a single exit at the bottom.
6172  // The point of exit cannot be a branch out of the structured block.
6173  // longjmp() and throw() must not violate the entry/exit criteria.
6174  CS->getCapturedDecl()->setNothrow();
6175 
6176  setFunctionHasBranchProtectedScope();
6177 
6178  return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
6179  DSAStack->isCancelRegion());
6180 }
6181 
6183  SourceLocation EndLoc) {
6184  return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
6185 }
6186 
6188  SourceLocation EndLoc) {
6189  return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
6190 }
6191 
6193  SourceLocation EndLoc) {
6194  return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
6195 }
6196 
6198  Stmt *AStmt,
6199  SourceLocation StartLoc,
6200  SourceLocation EndLoc) {
6201  if (!AStmt)
6202  return StmtError();
6203 
6204  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6205 
6206  setFunctionHasBranchProtectedScope();
6207 
6208  return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
6209  AStmt,
6210  DSAStack->getTaskgroupReductionRef());
6211 }
6212 
6214  SourceLocation StartLoc,
6215  SourceLocation EndLoc) {
6216  assert(Clauses.size() <= 1 && "Extra clauses in flush directive");
6217  return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
6218 }
6219 
6221  Stmt *AStmt,
6222  SourceLocation StartLoc,
6223  SourceLocation EndLoc) {
6224  const OMPClause *DependFound = nullptr;
6225  const OMPClause *DependSourceClause = nullptr;
6226  const OMPClause *DependSinkClause = nullptr;
6227  bool ErrorFound = false;
6228  const OMPThreadsClause *TC = nullptr;
6229  const OMPSIMDClause *SC = nullptr;
6230  for (const OMPClause *C : Clauses) {
6231  if (auto *DC = dyn_cast<OMPDependClause>(C)) {
6232  DependFound = C;
6233  if (DC->getDependencyKind() == OMPC_DEPEND_source) {
6234  if (DependSourceClause) {
6235  Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
6236  << getOpenMPDirectiveName(OMPD_ordered)
6237  << getOpenMPClauseName(OMPC_depend) << 2;
6238  ErrorFound = true;
6239  } else {
6240  DependSourceClause = C;
6241  }
6242  if (DependSinkClause) {
6243  Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
6244  << 0;
6245  ErrorFound = true;
6246  }
6247  } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
6248  if (DependSourceClause) {
6249  Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
6250  << 1;
6251  ErrorFound = true;
6252  }
6253  DependSinkClause = C;
6254  }
6255  } else if (C->getClauseKind() == OMPC_threads) {
6256  TC = cast<OMPThreadsClause>(C);
6257  } else if (C->getClauseKind() == OMPC_simd) {
6258  SC = cast<OMPSIMDClause>(C);
6259  }
6260  }
6261  if (!ErrorFound && !SC &&
6262  isOpenMPSimdDirective(DSAStack->getParentDirective())) {
6263  // OpenMP [2.8.1,simd Construct, Restrictions]
6264  // An ordered construct with the simd clause is the only OpenMP construct
6265  // that can appear in the simd region.
6266  Diag(StartLoc, diag::err_omp_prohibited_region_simd);
6267  ErrorFound = true;
6268  } else if (DependFound && (TC || SC)) {
6269  Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
6270  << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
6271  ErrorFound = true;
6272  } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) {
6273  Diag(DependFound->getBeginLoc(),
6274  diag::err_omp_ordered_directive_without_param);
6275  ErrorFound = true;
6276  } else if (TC || Clauses.empty()) {
6277  if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) {
6278  SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
6279  Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
6280  << (TC != nullptr);
6281  Diag(Param->getBeginLoc(), diag::note_omp_ordered_param);
6282  ErrorFound = true;
6283  }
6284  }
6285  if ((!AStmt && !DependFound) || ErrorFound)
6286  return StmtError();
6287 
6288  if (AStmt) {
6289  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6290 
6291  setFunctionHasBranchProtectedScope();
6292  }
6293 
6294  return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
6295 }
6296 
6297 namespace {
6298 /// Helper class for checking expression in 'omp atomic [update]'
6299 /// construct.
6300 class OpenMPAtomicUpdateChecker {
6301  /// Error results for atomic update expressions.
6302  enum ExprAnalysisErrorCode {
6303  /// A statement is not an expression statement.
6304  NotAnExpression,
6305  /// Expression is not builtin binary or unary operation.
6306  NotABinaryOrUnaryExpression,
6307  /// Unary operation is not post-/pre- increment/decrement operation.
6308  NotAnUnaryIncDecExpression,
6309  /// An expression is not of scalar type.
6310  NotAScalarType,
6311  /// A binary operation is not an assignment operation.
6312  NotAnAssignmentOp,
6313  /// RHS part of the binary operation is not a binary expression.
6314  NotABinaryExpression,
6315  /// RHS part is not additive/multiplicative/shift/biwise binary
6316  /// expression.
6317  NotABinaryOperator,
6318  /// RHS binary operation does not have reference to the updated LHS
6319  /// part.
6320  NotAnUpdateExpression,
6321  /// No errors is found.
6322  NoError
6323  };
6324  /// Reference to Sema.
6325  Sema &SemaRef;
6326  /// A location for note diagnostics (when error is found).
6327  SourceLocation NoteLoc;
6328  /// 'x' lvalue part of the source atomic expression.
6329  Expr *X;
6330  /// 'expr' rvalue part of the source atomic expression.
6331  Expr *E;
6332  /// Helper expression of the form
6333  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
6334  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
6335  Expr *UpdateExpr;
6336  /// Is 'x' a LHS in a RHS part of full update expression. It is
6337  /// important for non-associative operations.
6338  bool IsXLHSInRHSPart;
6339  BinaryOperatorKind Op;
6340  SourceLocation OpLoc;
6341  /// true if the source expression is a postfix unary operation, false
6342  /// if it is a prefix unary operation.
6343  bool IsPostfixUpdate;
6344 
6345 public:
6346  OpenMPAtomicUpdateChecker(Sema &SemaRef)
6347  : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
6348  IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
6349  /// Check specified statement that it is suitable for 'atomic update'
6350  /// constructs and extract 'x', 'expr' and Operation from the original
6351  /// expression. If DiagId and NoteId == 0, then only check is performed
6352  /// without error notification.
6353  /// \param DiagId Diagnostic which should be emitted if error is found.
6354  /// \param NoteId Diagnostic note for the main error message.
6355  /// \return true if statement is not an update expression, false otherwise.
6356  bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
6357  /// Return the 'x' lvalue part of the source atomic expression.
6358  Expr *getX() const { return X; }
6359  /// Return the 'expr' rvalue part of the source atomic expression.
6360  Expr *getExpr() const { return E; }
6361  /// Return the update expression used in calculation of the updated
6362  /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
6363  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
6364  Expr *getUpdateExpr() const { return UpdateExpr; }
6365  /// Return true if 'x' is LHS in RHS part of full update expression,
6366  /// false otherwise.
6367  bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
6368 
6369  /// true if the source expression is a postfix unary operation, false
6370  /// if it is a prefix unary operation.
6371  bool isPostfixUpdate() const { return IsPostfixUpdate; }
6372 
6373 private:
6374  bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
6375  unsigned NoteId = 0);
6376 };
6377 } // namespace
6378 
6379 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
6380  BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
6381  ExprAnalysisErrorCode ErrorFound = NoError;
6382  SourceLocation ErrorLoc, NoteLoc;
6383  SourceRange ErrorRange, NoteRange;
6384  // Allowed constructs are:
6385  // x = x binop expr;
6386  // x = expr binop x;
6387  if (AtomicBinOp->getOpcode() == BO_Assign) {
6388  X = AtomicBinOp->getLHS();
6389  if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
6390  AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
6391  if (AtomicInnerBinOp->isMultiplicativeOp() ||
6392  AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
6393  AtomicInnerBinOp->isBitwiseOp()) {
6394  Op = AtomicInnerBinOp->getOpcode();
6395  OpLoc = AtomicInnerBinOp->getOperatorLoc();
6396  Expr *LHS = AtomicInnerBinOp->getLHS();
6397  Expr *RHS = AtomicInnerBinOp->getRHS();
6398  llvm::FoldingSetNodeID XId, LHSId, RHSId;
6399  X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
6400  /*Canonical=*/true);
6401  LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
6402  /*Canonical=*/true);
6403  RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
6404  /*Canonical=*/true);
6405  if (XId == LHSId) {
6406  E = RHS;
6407  IsXLHSInRHSPart = true;
6408  } else if (XId == RHSId) {
6409  E = LHS;
6410  IsXLHSInRHSPart = false;
6411  } else {
6412  ErrorLoc = AtomicInnerBinOp->getExprLoc();
6413  ErrorRange = AtomicInnerBinOp->getSourceRange();
6414  NoteLoc = X->getExprLoc();
6415  NoteRange = X->getSourceRange();
6416  ErrorFound = NotAnUpdateExpression;
6417  }
6418  } else {
6419  ErrorLoc = AtomicInnerBinOp->getExprLoc();
6420  ErrorRange = AtomicInnerBinOp->getSourceRange();
6421  NoteLoc = AtomicInnerBinOp->getOperatorLoc();
6422  NoteRange = SourceRange(NoteLoc, NoteLoc);
6423  ErrorFound = NotABinaryOperator;
6424  }
6425  } else {
6426  NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
6427  NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
6428  ErrorFound = NotABinaryExpression;
6429  }
6430  } else {
6431  ErrorLoc = AtomicBinOp->getExprLoc();
6432  ErrorRange = AtomicBinOp->getSourceRange();
6433  NoteLoc = AtomicBinOp->getOperatorLoc();
6434  NoteRange = SourceRange(NoteLoc, NoteLoc);
6435  ErrorFound = NotAnAssignmentOp;
6436  }
6437  if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
6438  SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
6439  SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
6440  return true;
6441  }
6442  if (SemaRef.CurContext->isDependentContext())
6443  E = X = UpdateExpr = nullptr;
6444  return ErrorFound != NoError;
6445 }
6446 
6447 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
6448  unsigned NoteId) {
6449  ExprAnalysisErrorCode ErrorFound = NoError;
6450  SourceLocation ErrorLoc, NoteLoc;
6451  SourceRange ErrorRange, NoteRange;
6452  // Allowed constructs are:
6453  // x++;
6454  // x--;
6455  // ++x;
6456  // --x;
6457  // x binop= expr;
6458  // x = x binop expr;
6459  // x = expr binop x;
6460  if (auto *AtomicBody = dyn_cast<Expr>(S)) {
6461  AtomicBody = AtomicBody->IgnoreParenImpCasts();
6462  if (AtomicBody->getType()->isScalarType() ||
6463  AtomicBody->isInstantiationDependent()) {
6464  if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
6465  AtomicBody->IgnoreParenImpCasts())) {
6466  // Check for Compound Assignment Operation
6468  AtomicCompAssignOp->getOpcode());
6469  OpLoc = AtomicCompAssignOp->getOperatorLoc();
6470  E = AtomicCompAssignOp->getRHS();
6471  X = AtomicCompAssignOp->getLHS()->IgnoreParens();
6472  IsXLHSInRHSPart = true;
6473  } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
6474  AtomicBody->IgnoreParenImpCasts())) {
6475  // Check for Binary Operation
6476  if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
6477  return true;
6478  } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
6479  AtomicBody->IgnoreParenImpCasts())) {
6480  // Check for Unary Operation
6481  if (AtomicUnaryOp->isIncrementDecrementOp()) {
6482  IsPostfixUpdate = AtomicUnaryOp->isPostfix();
6483  Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
6484  OpLoc = AtomicUnaryOp->getOperatorLoc();
6485  X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
6486  E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
6487  IsXLHSInRHSPart = true;
6488  } else {
6489  ErrorFound = NotAnUnaryIncDecExpression;
6490  ErrorLoc = AtomicUnaryOp->getExprLoc();
6491  ErrorRange = AtomicUnaryOp->getSourceRange();
6492  NoteLoc = AtomicUnaryOp->getOperatorLoc();
6493  NoteRange = SourceRange(NoteLoc, NoteLoc);
6494  }
6495  } else if (!AtomicBody->isInstantiationDependent()) {
6496  ErrorFound = NotABinaryOrUnaryExpression;
6497  NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
6498  NoteRange = ErrorRange = AtomicBody->getSourceRange();
6499  }
6500  } else {
6501  ErrorFound = NotAScalarType;
6502  NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
6503  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
6504  }
6505  } else {
6506  ErrorFound = NotAnExpression;
6507  NoteLoc = ErrorLoc = S->getBeginLoc();
6508  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
6509  }
6510  if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
6511  SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
6512  SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
6513  return true;
6514  }
6515  if (SemaRef.CurContext->isDependentContext())
6516  E = X = UpdateExpr = nullptr;
6517  if (ErrorFound == NoError && E && X) {
6518  // Build an update expression of form 'OpaqueValueExpr(x) binop
6519  // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
6520  // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
6521  auto *OVEX = new (SemaRef.getASTContext())
6522  OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue);
6523  auto *OVEExpr = new (SemaRef.getASTContext())
6525  ExprResult Update =
6526  SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
6527  IsXLHSInRHSPart ? OVEExpr : OVEX);
6528  if (Update.isInvalid())
6529  return true;
6530  Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
6532  if (Update.isInvalid())
6533  return true;
6534  UpdateExpr = Update.get();
6535  }
6536  return ErrorFound != NoError;
6537 }
6538 
6540  Stmt *AStmt,
6541  SourceLocation StartLoc,
6542  SourceLocation EndLoc) {
6543  if (!AStmt)
6544  return StmtError();
6545 
6546  auto *CS = cast<CapturedStmt>(AStmt);
6547  // 1.2.2 OpenMP Language Terminology
6548  // Structured block - An executable statement with a single entry at the
6549  // top and a single exit at the bottom.
6550  // The point of exit cannot be a branch out of the structured block.
6551  // longjmp() and throw() must not violate the entry/exit criteria.
6552  OpenMPClauseKind AtomicKind = OMPC_unknown;
6553  SourceLocation AtomicKindLoc;
6554  for (const OMPClause *C : Clauses) {
6555  if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
6556  C->getClauseKind() == OMPC_update ||
6557  C->getClauseKind() == OMPC_capture) {
6558  if (AtomicKind != OMPC_unknown) {
6559  Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
6560  << SourceRange(C->getBeginLoc(), C->getEndLoc());
6561  Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause)
6562  << getOpenMPClauseName(AtomicKind);
6563  } else {
6564  AtomicKind = C->getClauseKind();
6565  AtomicKindLoc = C->getBeginLoc();
6566  }
6567  }
6568  }
6569 
6570  Stmt *Body = CS->getCapturedStmt();
6571  if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
6572  Body = EWC->getSubExpr();
6573 
6574  Expr *X = nullptr;
6575  Expr *V = nullptr;
6576  Expr *E = nullptr;
6577  Expr *UE = nullptr;
6578  bool IsXLHSInRHSPart = false;
6579  bool IsPostfixUpdate = false;
6580  // OpenMP [2.12.6, atomic Construct]
6581  // In the next expressions:
6582  // * x and v (as applicable) are both l-value expressions with scalar type.
6583  // * During the execution of an atomic region, multiple syntactic
6584  // occurrences of x must designate the same storage location.
6585  // * Neither of v and expr (as applicable) may access the storage location
6586  // designated by x.
6587  // * Neither of x and expr (as applicable) may access the storage location
6588  // designated by v.
6589  // * expr is an expression with scalar type.
6590  // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
6591  // * binop, binop=, ++, and -- are not overloaded operators.
6592  // * The expression x binop expr must be numerically equivalent to x binop
6593  // (expr). This requirement is satisfied if the operators in expr have
6594  // precedence greater than binop, or by using parentheses around expr or
6595  // subexpressions of expr.
6596  // * The expression expr binop x must be numerically equivalent to (expr)
6597  // binop x. This requirement is satisfied if the operators in expr have
6598  // precedence equal to or greater than binop, or by using parentheses around
6599  // expr or subexpressions of expr.
6600  // * For forms that allow multiple occurrences of x, the number of times
6601  // that x is evaluated is unspecified.
6602  if (AtomicKind == OMPC_read) {
6603  enum {
6604  NotAnExpression,
6605  NotAnAssignmentOp,
6606  NotAScalarType,
6607  NotAnLValue,
6608  NoError
6609  } ErrorFound = NoError;
6610  SourceLocation ErrorLoc, NoteLoc;
6611  SourceRange ErrorRange, NoteRange;
6612  // If clause is read:
6613  // v = x;
6614  if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
6615  const auto *AtomicBinOp =
6616  dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
6617  if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
6618  X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
6619  V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
6620  if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
6621  (V->isInstantiationDependent() || V->getType()->isScalarType())) {
6622  if (!X->isLValue() || !V->isLValue()) {
6623  const Expr *NotLValueExpr = X->isLValue() ? V : X;
6624  ErrorFound = NotAnLValue;
6625  ErrorLoc = AtomicBinOp->getExprLoc();
6626  ErrorRange = AtomicBinOp->getSourceRange();
6627  NoteLoc = NotLValueExpr->getExprLoc();
6628  NoteRange = NotLValueExpr->getSourceRange();
6629  }
6630  } else if (!X->isInstantiationDependent() ||
6631  !V->isInstantiationDependent()) {
6632  const Expr *NotScalarExpr =
6634  ? V
6635  : X;
6636  ErrorFound = NotAScalarType;
6637  ErrorLoc = AtomicBinOp->getExprLoc();
6638  ErrorRange = AtomicBinOp->getSourceRange();
6639  NoteLoc = NotScalarExpr->getExprLoc();
6640  NoteRange = NotScalarExpr->getSourceRange();
6641  }
6642  } else if (!AtomicBody->isInstantiationDependent()) {
6643  ErrorFound = NotAnAssignmentOp;
6644  ErrorLoc = AtomicBody->getExprLoc();
6645  ErrorRange = AtomicBody->getSourceRange();
6646  NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
6647  : AtomicBody->getExprLoc();
6648  NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
6649  : AtomicBody->getSourceRange();
6650  }
6651  } else {
6652  ErrorFound = NotAnExpression;
6653  NoteLoc = ErrorLoc = Body->getBeginLoc();
6654  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
6655  }
6656  if (ErrorFound != NoError) {
6657  Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
6658  << ErrorRange;
6659  Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
6660  << NoteRange;
6661  return StmtError();
6662  }
6663  if (CurContext->isDependentContext())
6664  V = X = nullptr;
6665  } else if (AtomicKind == OMPC_write) {
6666  enum {
6667  NotAnExpression,
6668  NotAnAssignmentOp,
6669  NotAScalarType,
6670  NotAnLValue,
6671  NoError
6672  } ErrorFound = NoError;
6673  SourceLocation ErrorLoc, NoteLoc;
6674  SourceRange ErrorRange, NoteRange;
6675  // If clause is write:
6676  // x = expr;
6677  if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
6678  const auto *AtomicBinOp =
6679  dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
6680  if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
6681  X = AtomicBinOp->getLHS();
6682  E = AtomicBinOp->getRHS();
6683  if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
6684  (E->isInstantiationDependent() || E->getType()->isScalarType())) {
6685  if (!X->isLValue()) {
6686  ErrorFound = NotAnLValue;
6687  ErrorLoc = AtomicBinOp->getExprLoc();
6688  ErrorRange = AtomicBinOp->getSourceRange();
6689  NoteLoc = X->getExprLoc();
6690  NoteRange = X->getSourceRange();
6691  }
6692  } else if (!X->isInstantiationDependent() ||
6693  !E->isInstantiationDependent()) {
6694  const Expr *NotScalarExpr =
6696  ? E
6697  : X;
6698  ErrorFound = NotAScalarType;
6699  ErrorLoc = AtomicBinOp->getExprLoc();
6700  ErrorRange = AtomicBinOp->getSourceRange();
6701  NoteLoc = NotScalarExpr->getExprLoc();
6702  NoteRange = NotScalarExpr->getSourceRange();
6703  }
6704  } else if (!AtomicBody->isInstantiationDependent()) {
6705  ErrorFound = NotAnAssignmentOp;
6706  ErrorLoc = AtomicBody->getExprLoc();
6707  ErrorRange = AtomicBody->getSourceRange();
6708  NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
6709  : AtomicBody->getExprLoc();
6710  NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
6711  : AtomicBody->getSourceRange();
6712  }
6713  } else {
6714  ErrorFound = NotAnExpression;
6715  NoteLoc = ErrorLoc = Body->getBeginLoc();
6716  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
6717  }
6718  if (ErrorFound != NoError) {
6719  Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
6720  << ErrorRange;
6721  Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
6722  << NoteRange;
6723  return StmtError();
6724  }
6725  if (CurContext->isDependentContext())
6726  E = X = nullptr;
6727  } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
6728  // If clause is update:
6729  // x++;
6730  // x--;
6731  // ++x;
6732  // --x;
6733  // x binop= expr;
6734  // x = x binop expr;
6735  // x = expr binop x;
6736  OpenMPAtomicUpdateChecker Checker(*this);
6737  if (Checker.checkStatement(
6738  Body, (AtomicKind == OMPC_update)
6739  ? diag::err_omp_atomic_update_not_expression_statement
6740  : diag::err_omp_atomic_not_expression_statement,
6741  diag::note_omp_atomic_update))
6742  return StmtError();
6743  if (!CurContext->isDependentContext()) {
6744  E = Checker.getExpr();
6745  X = Checker.getX();
6746  UE = Checker.getUpdateExpr();
6747  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6748  }
6749  } else if (AtomicKind == OMPC_capture) {
6750  enum {
6751  NotAnAssignmentOp,
6752  NotACompoundStatement,
6753  NotTwoSubstatements,
6754  NotASpecificExpression,
6755  NoError
6756  } ErrorFound = NoError;
6757  SourceLocation ErrorLoc, NoteLoc;
6758  SourceRange ErrorRange, NoteRange;
6759  if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
6760  // If clause is a capture:
6761  // v = x++;
6762  // v = x--;
6763  // v = ++x;
6764  // v = --x;
6765  // v = x binop= expr;
6766  // v = x = x binop expr;
6767  // v = x = expr binop x;
6768  const auto *AtomicBinOp =
6769  dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
6770  if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
6771  V = AtomicBinOp->getLHS();
6772  Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
6773  OpenMPAtomicUpdateChecker Checker(*this);
6774  if (Checker.checkStatement(
6775  Body, diag::err_omp_atomic_capture_not_expression_statement,
6776  diag::note_omp_atomic_update))
6777  return StmtError();
6778  E = Checker.getExpr();
6779  X = Checker.getX();
6780  UE = Checker.getUpdateExpr();
6781  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6782  IsPostfixUpdate = Checker.isPostfixUpdate();
6783  } else if (!AtomicBody->isInstantiationDependent()) {
6784  ErrorLoc = AtomicBody->getExprLoc();
6785  ErrorRange = AtomicBody->getSourceRange();
6786  NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
6787  : AtomicBody->getExprLoc();
6788  NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
6789  : AtomicBody->getSourceRange();
6790  ErrorFound = NotAnAssignmentOp;
6791  }
6792  if (ErrorFound != NoError) {
6793  Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
6794  << ErrorRange;
6795  Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
6796  return StmtError();
6797  }
6798  if (CurContext->isDependentContext())
6799  UE = V = E = X = nullptr;
6800  } else {
6801  // If clause is a capture:
6802  // { v = x; x = expr; }
6803  // { v = x; x++; }
6804  // { v = x; x--; }
6805  // { v = x; ++x; }
6806  // { v = x; --x; }
6807  // { v = x; x binop= expr; }
6808  // { v = x; x = x binop expr; }
6809  // { v = x; x = expr binop x; }
6810  // { x++; v = x; }
6811  // { x--; v = x; }
6812  // { ++x; v = x; }
6813  // { --x; v = x; }
6814  // { x binop= expr; v = x; }
6815  // { x = x binop expr; v = x; }
6816  // { x = expr binop x; v = x; }
6817  if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
6818  // Check that this is { expr1; expr2; }
6819  if (CS->size() == 2) {
6820  Stmt *First = CS->body_front();
6821  Stmt *Second = CS->body_back();
6822  if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
6823  First = EWC->getSubExpr()->IgnoreParenImpCasts();
6824  if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
6825  Second = EWC->getSubExpr()->IgnoreParenImpCasts();
6826  // Need to find what subexpression is 'v' and what is 'x'.
6827  OpenMPAtomicUpdateChecker Checker(*this);
6828  bool IsUpdateExprFound = !Checker.checkStatement(Second);
6829  BinaryOperator *BinOp = nullptr;
6830  if (IsUpdateExprFound) {
6831  BinOp = dyn_cast<BinaryOperator>(First);
6832  IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
6833  }
6834  if (IsUpdateExprFound && !CurContext->isDependentContext()) {
6835  // { v = x; x++; }
6836  // { v = x; x--; }
6837  // { v = x; ++x; }
6838  // { v = x; --x; }
6839  // { v = x; x binop= expr; }
6840  // { v = x; x = x binop expr; }
6841  // { v = x; x = expr binop x; }
6842  // Check that the first expression has form v = x.
6843  Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
6844  llvm::FoldingSetNodeID XId, PossibleXId;
6845  Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
6846  PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
6847  IsUpdateExprFound = XId == PossibleXId;
6848  if (IsUpdateExprFound) {
6849  V = BinOp->getLHS();
6850  X = Checker.getX();
6851  E = Checker.getExpr();
6852  UE = Checker.getUpdateExpr();
6853  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6854  IsPostfixUpdate = true;
6855  }
6856  }
6857  if (!IsUpdateExprFound) {
6858  IsUpdateExprFound = !Checker.checkStatement(First);
6859  BinOp = nullptr;
6860  if (IsUpdateExprFound) {
6861  BinOp = dyn_cast<BinaryOperator>(Second);
6862  IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
6863  }
6864  if (IsUpdateExprFound && !CurContext->isDependentContext()) {
6865  // { x++; v = x; }
6866  // { x--; v = x; }
6867  // { ++x; v = x; }
6868  // { --x; v = x; }
6869  // { x binop= expr; v = x; }
6870  // { x = x binop expr; v = x; }
6871  // { x = expr binop x; v = x; }
6872  // Check that the second expression has form v = x.
6873  Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
6874  llvm::FoldingSetNodeID XId, PossibleXId;
6875  Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
6876  PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
6877  IsUpdateExprFound = XId == PossibleXId;
6878  if (IsUpdateExprFound) {
6879  V = BinOp->getLHS();
6880  X = Checker.getX();
6881  E = Checker.getExpr();
6882  UE = Checker.getUpdateExpr();
6883  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6884  IsPostfixUpdate = false;
6885  }
6886  }
6887  }
6888  if (!IsUpdateExprFound) {
6889  // { v = x; x = expr; }
6890  auto *FirstExpr = dyn_cast<Expr>(First);
6891  auto *SecondExpr = dyn_cast<Expr>(Second);
6892  if (!FirstExpr || !SecondExpr ||
6893  !(FirstExpr->isInstantiationDependent() ||
6894  SecondExpr->isInstantiationDependent())) {
6895  auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
6896  if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
6897  ErrorFound = NotAnAssignmentOp;
6898  NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
6899  : First->getBeginLoc();
6900  NoteRange = ErrorRange = FirstBinOp
6901  ? FirstBinOp->getSourceRange()
6902  : SourceRange(ErrorLoc, ErrorLoc);
6903  } else {
6904  auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
6905  if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
6906  ErrorFound = NotAnAssignmentOp;
6907  NoteLoc = ErrorLoc = SecondBinOp
6908  ? SecondBinOp->getOperatorLoc()
6909  : Second->getBeginLoc();
6910  NoteRange = ErrorRange =
6911  SecondBinOp ? SecondBinOp->getSourceRange()
6912  : SourceRange(ErrorLoc, ErrorLoc);
6913  } else {
6914  Expr *PossibleXRHSInFirst =
6915  FirstBinOp->getRHS()->IgnoreParenImpCasts();
6916  Expr *PossibleXLHSInSecond =
6917  SecondBinOp->getLHS()->IgnoreParenImpCasts();
6918  llvm::FoldingSetNodeID X1Id, X2Id;
6919  PossibleXRHSInFirst->Profile(X1Id, Context,
6920  /*Canonical=*/true);
6921  PossibleXLHSInSecond->Profile(X2Id, Context,
6922  /*Canonical=*/true);
6923  IsUpdateExprFound = X1Id == X2Id;
6924  if (IsUpdateExprFound) {
6925  V = FirstBinOp->getLHS();
6926  X = SecondBinOp->getLHS();
6927  E = SecondBinOp->getRHS();
6928  UE = nullptr;
6929  IsXLHSInRHSPart = false;
6930  IsPostfixUpdate = true;
6931  } else {
6932  ErrorFound = NotASpecificExpression;
6933  ErrorLoc = FirstBinOp->getExprLoc();
6934  ErrorRange = FirstBinOp->getSourceRange();
6935  NoteLoc = SecondBinOp->getLHS()->getExprLoc();
6936  NoteRange = SecondBinOp->getRHS()->getSourceRange();
6937  }
6938  }
6939  }
6940  }
6941  }
6942  } else {
6943  NoteLoc = ErrorLoc = Body->getBeginLoc();
6944  NoteRange = ErrorRange =
6945  SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
6946  ErrorFound = NotTwoSubstatements;
6947  }
6948  } else {
6949  NoteLoc = ErrorLoc = Body->getBeginLoc();
6950  NoteRange = ErrorRange =
6951  SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
6952  ErrorFound = NotACompoundStatement;
6953  }
6954  if (ErrorFound != NoError) {
6955  Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
6956  << ErrorRange;
6957  Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
6958  return StmtError();
6959  }
6960  if (CurContext->isDependentContext())
6961  UE = V = E = X = nullptr;
6962  }
6963  }
6964 
6965  setFunctionHasBranchProtectedScope();
6966 
6967  return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
6968  X, V, E, UE, IsXLHSInRHSPart,
6969  IsPostfixUpdate);
6970 }
6971 
6973  Stmt *AStmt,
6974  SourceLocation StartLoc,
6975  SourceLocation EndLoc) {
6976  if (!AStmt)
6977  return StmtError();
6978 
6979  auto *CS = cast<CapturedStmt>(AStmt);
6980  // 1.2.2 OpenMP Language Terminology
6981  // Structured block - An executable statement with a single entry at the
6982  // top and a single exit at the bottom.
6983  // The point of exit cannot be a branch out of the structured block.
6984  // longjmp() and throw() must not violate the entry/exit criteria.
6985  CS->getCapturedDecl()->setNothrow();
6986  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
6987  ThisCaptureLevel > 1; --ThisCaptureLevel) {
6988  CS = cast<CapturedStmt>(CS->getCapturedStmt());
6989  // 1.2.2 OpenMP Language Terminology
6990  // Structured block - An executable statement with a single entry at the
6991  // top and a single exit at the bottom.
6992  // The point of exit cannot be a branch out of the structured block.
6993  // longjmp() and throw() must not violate the entry/exit criteria.
6994  CS->getCapturedDecl()->setNothrow();
6995  }
6996 
6997  // OpenMP [2.16, Nesting of Regions]
6998  // If specified, a teams construct must be contained within a target
6999  // construct. That target construct must contain no statements or directives
7000  // outside of the teams construct.
7001  if (DSAStack->hasInnerTeamsRegion()) {
7002  const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
7003  bool OMPTeamsFound = true;
7004  if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
7005  auto I = CS->body_begin();
7006  while (I != CS->body_end()) {
7007  const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
7008  if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind())) {
7009  OMPTeamsFound = false;
7010  break;
7011  }
7012  ++I;
7013  }
7014  assert(I != CS->body_end() && "Not found statement");
7015  S = *I;
7016  } else {
7017  const auto *OED = dyn_cast<OMPExecutableDirective>(S);
7018  OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
7019  }
7020  if (!OMPTeamsFound) {
7021  Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
7022  Diag(DSAStack->getInnerTeamsRegionLoc(),
7023  diag::note_omp_nested_teams_construct_here);
7024  Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
7025  << isa<OMPExecutableDirective>(S);
7026  return StmtError();
7027  }
7028  }
7029 
7030  setFunctionHasBranchProtectedScope();
7031 
7032  return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
7033 }
7034 
7035 StmtResult
7037  Stmt *AStmt, SourceLocation StartLoc,
7038  SourceLocation EndLoc) {
7039  if (!AStmt)
7040  return StmtError();
7041 
7042  auto *CS = cast<CapturedStmt>(AStmt);
7043  // 1.2.2 OpenMP Language Terminology
7044  // Structured block - An executable statement with a single entry at the
7045  // top and a single exit at the bottom.
7046  // The point of exit cannot be a branch out of the structured block.
7047  // longjmp() and throw() must not violate the entry/exit criteria.
7048  CS->getCapturedDecl()->setNothrow();
7049  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
7050  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7051  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7052  // 1.2.2 OpenMP Language Terminology
7053  // Structured block - An executable statement with a single entry at the
7054  // top and a single exit at the bottom.
7055  // The point of exit cannot be a branch out of the structured block.
7056  // longjmp() and throw() must not violate the entry/exit criteria.
7057  CS->getCapturedDecl()->setNothrow();
7058  }
7059 
7060  setFunctionHasBranchProtectedScope();
7061 
7062  return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses,
7063  AStmt);
7064 }
7065 
7067  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7068  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7069  if (!AStmt)
7070  return StmtError();
7071 
7072  auto *CS = cast<CapturedStmt>(AStmt);
7073  // 1.2.2 OpenMP Language Terminology
7074  // Structured block - An executable statement with a single entry at the
7075  // top and a single exit at the bottom.
7076  // The point of exit cannot be a branch out of the structured block.
7077  // longjmp() and throw() must not violate the entry/exit criteria.
7078  CS->getCapturedDecl()->setNothrow();
7079  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
7080  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7081  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7082  // 1.2.2 OpenMP Language Terminology
7083  // Structured block - An executable statement with a single entry at the
7084  // top and a single exit at the bottom.
7085  // The point of exit cannot be a branch out of the structured block.
7086  // longjmp() and throw() must not violate the entry/exit criteria.
7087  CS->getCapturedDecl()->setNothrow();
7088  }
7089 
7091  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7092  // define the nested loops number.
7093  unsigned NestedLoopCount =
7094  checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
7095  getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
7096  VarsWithImplicitDSA, B);
7097  if (NestedLoopCount == 0)
7098  return StmtError();
7099 
7100  assert((CurContext->isDependentContext() || B.builtAll()) &&
7101  "omp target parallel for loop exprs were not built");
7102 
7103  if (!CurContext->isDependentContext()) {
7104  // Finalize the clauses that need pre-built expressions for CodeGen.
7105  for (OMPClause *C : Clauses) {
7106  if (auto *LC = dyn_cast<OMPLinearClause>(C))
7107  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7108  B.NumIterations, *this, CurScope,
7109  DSAStack))
7110  return StmtError();
7111  }
7112  }
7113 
7114  setFunctionHasBranchProtectedScope();
7115  return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc,
7116  NestedLoopCount, Clauses, AStmt,
7117  B, DSAStack->isCancelRegion());
7118 }
7119 
7120 /// Check for existence of a map clause in the list of clauses.
7121 static bool hasClauses(ArrayRef<OMPClause *> Clauses,
7122  const OpenMPClauseKind K) {
7123  return llvm::any_of(
7124  Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
7125 }
7126 
7127 template <typename... Params>
7129  const Params... ClauseTypes) {
7130  return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
7131 }
7132 
7134  Stmt *AStmt,
7135  SourceLocation StartLoc,
7136  SourceLocation EndLoc) {
7137  if (!AStmt)
7138  return StmtError();
7139 
7140  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
7141 
7142  // OpenMP [2.10.1, Restrictions, p. 97]
7143  // At least one map clause must appear on the directive.
7144  if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) {
7145  Diag(StartLoc, diag::err_omp_no_clause_for_directive)
7146  << "'map' or 'use_device_ptr'"
7147  << getOpenMPDirectiveName(OMPD_target_data);
7148  return StmtError();
7149  }
7150 
7151  setFunctionHasBranchProtectedScope();
7152 
7153  return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
7154  AStmt);
7155 }
7156 
7157 StmtResult
7159  SourceLocation StartLoc,
7160  SourceLocation EndLoc, Stmt *AStmt) {
7161  if (!AStmt)
7162  return StmtError();
7163 
7164  auto *CS = cast<CapturedStmt>(AStmt);
7165  // 1.2.2 OpenMP Language Terminology
7166  // Structured block - An executable statement with a single entry at the
7167  // top and a single exit at the bottom.
7168  // The point of exit cannot be a branch out of the structured block.
7169  // longjmp() and throw() must not violate the entry/exit criteria.
7170  CS->getCapturedDecl()->setNothrow();
7171  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
7172  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7173  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7174  // 1.2.2 OpenMP Language Terminology
7175  // Structured block - An executable statement with a single entry at the
7176  // top and a single exit at the bottom.
7177  // The point of exit cannot be a branch out of the structured block.
7178  // longjmp() and throw() must not violate the entry/exit criteria.
7179  CS->getCapturedDecl()->setNothrow();
7180  }
7181 
7182  // OpenMP [2.10.2, Restrictions, p. 99]
7183  // At least one map clause must appear on the directive.
7184  if (!hasClauses(Clauses, OMPC_map)) {
7185  Diag(StartLoc, diag::err_omp_no_clause_for_directive)
7186  << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
7187  return StmtError();
7188  }
7189 
7190  return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
7191  AStmt);
7192 }
7193 
7194 StmtResult
7196  SourceLocation StartLoc,
7197  SourceLocation EndLoc, Stmt *AStmt) {
7198  if (!AStmt)
7199  return StmtError();
7200 
7201  auto *CS = cast<CapturedStmt>(AStmt);
7202  // 1.2.2 OpenMP Language Terminology
7203  // Structured block - An executable statement with a single entry at the
7204  // top and a single exit at the bottom.
7205  // The point of exit cannot be a branch out of the structured block.
7206  // longjmp() and throw() must not violate the entry/exit criteria.
7207  CS->getCapturedDecl()->setNothrow();
7208  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
7209  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7210  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7211  // 1.2.2 OpenMP Language Terminology
7212  // Structured block - An executable statement with a single entry at the
7213  // top and a single exit at the bottom.
7214  // The point of exit cannot be a branch out of the structured block.
7215  // longjmp() and throw() must not violate the entry/exit criteria.
7216  CS->getCapturedDecl()->setNothrow();
7217  }
7218 
7219  // OpenMP [2.10.3, Restrictions, p. 102]
7220  // At least one map clause must appear on the directive.
7221  if (!hasClauses(Clauses, OMPC_map)) {
7222  Diag(StartLoc, diag::err_omp_no_clause_for_directive)
7223  << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
7224  return StmtError();
7225  }
7226 
7227  return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
7228  AStmt);
7229 }
7230 
7232  SourceLocation StartLoc,
7233  SourceLocation EndLoc,
7234  Stmt *AStmt) {
7235  if (!AStmt)
7236  return StmtError();
7237 
7238  auto *CS = cast<CapturedStmt>(AStmt);
7239  // 1.2.2 OpenMP Language Terminology
7240  // Structured block - An executable statement with a single entry at the
7241  // top and a single exit at the bottom.
7242  // The point of exit cannot be a branch out of the structured block.
7243  // longjmp() and throw() must not violate the entry/exit criteria.
7244  CS->getCapturedDecl()->setNothrow();
7245  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
7246  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7247  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7248  // 1.2.2 OpenMP Language Terminology
7249  // Structured block - An executable statement with a single entry at the
7250  // top and a single exit at the bottom.
7251  // The point of exit cannot be a branch out of the structured block.
7252  // longjmp() and throw() must not violate the entry/exit criteria.
7253  CS->getCapturedDecl()->setNothrow();
7254  }
7255 
7256  if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
7257  Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
7258  return StmtError();
7259  }
7260  return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
7261  AStmt);
7262 }
7263 
7265  Stmt *AStmt, SourceLocation StartLoc,
7266  SourceLocation EndLoc) {
7267  if (!AStmt)
7268  return StmtError();
7269 
7270  auto *CS = cast<CapturedStmt>(AStmt);
7271  // 1.2.2 OpenMP Language Terminology
7272  // Structured block - An executable statement with a single entry at the
7273  // top and a single exit at the bottom.
7274  // The point of exit cannot be a branch out of the structured block.
7275  // longjmp() and throw() must not violate the entry/exit criteria.
7276  CS->getCapturedDecl()->setNothrow();
7277 
7278  setFunctionHasBranchProtectedScope();
7279 
7280  DSAStack->setParentTeamsRegionLoc(StartLoc);
7281 
7282  return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
7283 }
7284 
7285 StmtResult
7287  SourceLocation EndLoc,
7288  OpenMPDirectiveKind CancelRegion) {
7289  if (DSAStack->isParentNowaitRegion()) {
7290  Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
7291  return StmtError();
7292  }
7293  if (DSAStack->isParentOrderedRegion()) {
7294  Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
7295  return StmtError();
7296  }
7297  return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
7298  CancelRegion);
7299 }
7300 
7302  SourceLocation StartLoc,
7303  SourceLocation EndLoc,
7304  OpenMPDirectiveKind CancelRegion) {
7305  if (DSAStack->isParentNowaitRegion()) {
7306  Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
7307  return StmtError();
7308  }
7309  if (DSAStack->isParentOrderedRegion()) {
7310  Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
7311  return StmtError();
7312  }
7313  DSAStack->setParentCancelRegion(/*Cancel=*/true);
7314  return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
7315  CancelRegion);
7316 }
7317 
7319  ArrayRef<OMPClause *> Clauses) {
7320  const OMPClause *PrevClause = nullptr;
7321  bool ErrorFound = false;
7322  for (const OMPClause *C : Clauses) {
7323  if (C->getClauseKind() == OMPC_grainsize ||
7324  C->getClauseKind() == OMPC_num_tasks) {
7325  if (!PrevClause)
7326  PrevClause = C;
7327  else if (PrevClause->getClauseKind() != C->getClauseKind()) {
7328  S.Diag(C->getBeginLoc(),
7329  diag::err_omp_grainsize_num_tasks_mutually_exclusive)
7330  << getOpenMPClauseName(C->getClauseKind())
7331  << getOpenMPClauseName(PrevClause->getClauseKind());
7332  S.Diag(PrevClause->getBeginLoc(),
7333  diag::note_omp_previous_grainsize_num_tasks)
7334  << getOpenMPClauseName(PrevClause->getClauseKind());
7335  ErrorFound = true;
7336  }
7337  }
7338  }
7339  return ErrorFound;
7340 }
7341 
7343  ArrayRef<OMPClause *> Clauses) {
7344  const OMPClause *ReductionClause = nullptr;
7345  const OMPClause *NogroupClause = nullptr;
7346  for (const OMPClause *C : Clauses) {
7347  if (C->getClauseKind() == OMPC_reduction) {
7348  ReductionClause = C;
7349  if (NogroupClause)
7350  break;
7351  continue;
7352  }
7353  if (C->getClauseKind() == OMPC_nogroup) {
7354  NogroupClause = C;
7355  if (ReductionClause)
7356  break;
7357  continue;
7358  }
7359  }
7360  if (ReductionClause && NogroupClause) {
7361  S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
7362  << SourceRange(NogroupClause->getBeginLoc(),
7363  NogroupClause->getEndLoc());
7364  return true;
7365  }
7366  return false;
7367 }
7368 
7370  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7371  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7372  if (!AStmt)
7373  return StmtError();
7374 
7375  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
7377  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7378  // define the nested loops number.
7379  unsigned NestedLoopCount =
7380  checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
7381  /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
7382  VarsWithImplicitDSA, B);
7383  if (NestedLoopCount == 0)
7384  return StmtError();
7385 
7386  assert((CurContext->isDependentContext() || B.builtAll()) &&
7387  "omp for loop exprs were not built");
7388 
7389  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
7390  // The grainsize clause and num_tasks clause are mutually exclusive and may
7391  // not appear on the same taskloop directive.
7392  if (checkGrainsizeNumTasksClauses(*this, Clauses))
7393  return StmtError();
7394  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
7395  // If a reduction clause is present on the taskloop directive, the nogroup
7396  // clause must not be specified.
7397  if (checkReductionClauseWithNogroup(*this, Clauses))
7398  return StmtError();
7399 
7400  setFunctionHasBranchProtectedScope();
7401  return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
7402  NestedLoopCount, Clauses, AStmt, B);
7403 }
7404 
7406  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7407  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7408  if (!AStmt)
7409  return StmtError();
7410 
7411  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
7413  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7414  // define the nested loops number.
7415  unsigned NestedLoopCount =
7416  checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
7417  /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
7418  VarsWithImplicitDSA, B);
7419  if (NestedLoopCount == 0)
7420  return StmtError();
7421 
7422  assert((CurContext->isDependentContext() || B.builtAll()) &&
7423  "omp for loop exprs were not built");
7424 
7425  if (!CurContext->isDependentContext()) {
7426  // Finalize the clauses that need pre-built expressions for CodeGen.
7427  for (OMPClause *C : Clauses) {
7428  if (auto *LC = dyn_cast<OMPLinearClause>(C))
7429  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7430  B.NumIterations, *this, CurScope,
7431  DSAStack))
7432  return StmtError();
7433  }
7434  }
7435 
7436  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
7437  // The grainsize clause and num_tasks clause are mutually exclusive and may
7438  // not appear on the same taskloop directive.
7439  if (checkGrainsizeNumTasksClauses(*this, Clauses))
7440  return StmtError();
7441  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
7442  // If a reduction clause is present on the taskloop directive, the nogroup
7443  // clause must not be specified.
7444  if (checkReductionClauseWithNogroup(*this, Clauses))
7445  return StmtError();
7446  if (checkSimdlenSafelenSpecified(*this, Clauses))
7447  return StmtError();
7448 
7449  setFunctionHasBranchProtectedScope();
7450  return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
7451  NestedLoopCount, Clauses, AStmt, B);
7452 }
7453 
7455  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7456  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7457  if (!AStmt)
7458  return StmtError();
7459 
7460  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
7462  // In presence of clause 'collapse' with number of loops, it will
7463  // define the nested loops number.
7464  unsigned NestedLoopCount =
7465  checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
7466  nullptr /*ordered not a clause on distribute*/, AStmt,
7467  *this, *DSAStack, VarsWithImplicitDSA, B);
7468  if (NestedLoopCount == 0)
7469  return StmtError();
7470 
7471  assert((CurContext->isDependentContext() || B.builtAll()) &&
7472  "omp for loop exprs were not built");
7473 
7474  setFunctionHasBranchProtectedScope();
7475  return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
7476  NestedLoopCount, Clauses, AStmt, B);
7477 }
7478 
7480  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7481  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7482  if (!AStmt)
7483  return StmtError();
7484 
7485  auto *CS = cast<CapturedStmt>(AStmt);
7486  // 1.2.2 OpenMP Language Terminology
7487  // Structured block - An executable statement with a single entry at the
7488  // top and a single exit at the bottom.
7489  // The point of exit cannot be a branch out of the structured block.
7490  // longjmp() and throw() must not violate the entry/exit criteria.
7491  CS->getCapturedDecl()->setNothrow();
7492  for (int ThisCaptureLevel =
7493  getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
7494  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7495  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7496  // 1.2.2 OpenMP Language Terminology
7497  // Structured block - An executable statement with a single entry at the
7498  // top and a single exit at the bottom.
7499  // The point of exit cannot be a branch out of the structured block.
7500  // longjmp() and throw() must not violate the entry/exit criteria.
7501  CS->getCapturedDecl()->setNothrow();
7502  }
7503 
7505  // In presence of clause 'collapse' with number of loops, it will
7506  // define the nested loops number.
7507  unsigned NestedLoopCount = checkOpenMPLoop(
7508  OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
7509  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7510  VarsWithImplicitDSA, B);
7511  if (NestedLoopCount == 0)
7512  return StmtError();
7513 
7514  assert((CurContext->isDependentContext() || B.builtAll()) &&
7515  "omp for loop exprs were not built");
7516 
7517  setFunctionHasBranchProtectedScope();
7519  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
7520  DSAStack->isCancelRegion());
7521 }
7522 
7524  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7525  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7526  if (!AStmt)
7527  return StmtError();
7528 
7529  auto *CS = cast<CapturedStmt>(AStmt);
7530  // 1.2.2 OpenMP Language Terminology
7531  // Structured block - An executable statement with a single entry at the
7532  // top and a single exit at the bottom.
7533  // The point of exit cannot be a branch out of the structured block.
7534  // longjmp() and throw() must not violate the entry/exit criteria.
7535  CS->getCapturedDecl()->setNothrow();
7536  for (int ThisCaptureLevel =
7537  getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
7538  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7539  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7540  // 1.2.2 OpenMP Language Terminology
7541  // Structured block - An executable statement with a single entry at the
7542  // top and a single exit at the bottom.
7543  // The point of exit cannot be a branch out of the structured block.
7544  // longjmp() and throw() must not violate the entry/exit criteria.
7545  CS->getCapturedDecl()->setNothrow();
7546  }
7547 
7549  // In presence of clause 'collapse' with number of loops, it will
7550  // define the nested loops number.
7551  unsigned NestedLoopCount = checkOpenMPLoop(
7552  OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
7553  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7554  VarsWithImplicitDSA, B);
7555  if (NestedLoopCount == 0)
7556  return StmtError();
7557 
7558  assert((CurContext->isDependentContext() || B.builtAll()) &&
7559  "omp for loop exprs were not built");
7560 
7561  if (!CurContext->isDependentContext()) {
7562  // Finalize the clauses that need pre-built expressions for CodeGen.
7563  for (OMPClause *C : Clauses) {
7564  if (auto *LC = dyn_cast<OMPLinearClause>(C))
7565  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7566  B.NumIterations, *this, CurScope,
7567  DSAStack))
7568  return StmtError();
7569  }
7570  }
7571 
7572  if (checkSimdlenSafelenSpecified(*this, Clauses))
7573  return StmtError();
7574 
7575  setFunctionHasBranchProtectedScope();
7577  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7578 }
7579 
7581  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7582  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7583  if (!AStmt)
7584  return StmtError();
7585 
7586  auto *CS = cast<CapturedStmt>(AStmt);
7587  // 1.2.2 OpenMP Language Terminology
7588  // Structured block - An executable statement with a single entry at the
7589  // top and a single exit at the bottom.
7590  // The point of exit cannot be a branch out of the structured block.
7591  // longjmp() and throw() must not violate the entry/exit criteria.
7592  CS->getCapturedDecl()->setNothrow();
7593  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
7594  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7595  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7596  // 1.2.2 OpenMP Language Terminology
7597  // Structured block - An executable statement with a single entry at the
7598  // top and a single exit at the bottom.
7599  // The point of exit cannot be a branch out of the structured block.
7600  // longjmp() and throw() must not violate the entry/exit criteria.
7601  CS->getCapturedDecl()->setNothrow();
7602  }
7603 
7605  // In presence of clause 'collapse' with number of loops, it will
7606  // define the nested loops number.
7607  unsigned NestedLoopCount =
7608  checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
7609  nullptr /*ordered not a clause on distribute*/, CS, *this,
7610  *DSAStack, VarsWithImplicitDSA, B);
7611  if (NestedLoopCount == 0)
7612  return StmtError();
7613 
7614  assert((CurContext->isDependentContext() || B.builtAll()) &&
7615  "omp for loop exprs were not built");
7616 
7617  if (!CurContext->isDependentContext()) {
7618  // Finalize the clauses that need pre-built expressions for CodeGen.
7619  for (OMPClause *C : Clauses) {
7620  if (auto *LC = dyn_cast<OMPLinearClause>(C))
7621  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7622  B.NumIterations, *this, CurScope,
7623  DSAStack))
7624  return StmtError();
7625  }
7626  }
7627 
7628  if (checkSimdlenSafelenSpecified(*this, Clauses))
7629  return StmtError();
7630 
7631  setFunctionHasBranchProtectedScope();
7632  return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
7633  NestedLoopCount, Clauses, AStmt, B);
7634 }
7635 
7637  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7638  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7639  if (!AStmt)
7640  return StmtError();
7641 
7642  auto *CS = cast<CapturedStmt>(AStmt);
7643  // 1.2.2 OpenMP Language Terminology
7644  // Structured block - An executable statement with a single entry at the
7645  // top and a single exit at the bottom.
7646  // The point of exit cannot be a branch out of the structured block.
7647  // longjmp() and throw() must not violate the entry/exit criteria.
7648  CS->getCapturedDecl()->setNothrow();
7649  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
7650  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7651  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7652  // 1.2.2 OpenMP Language Terminology
7653  // Structured block - An executable statement with a single entry at the
7654  // top and a single exit at the bottom.
7655  // The point of exit cannot be a branch out of the structured block.
7656  // longjmp() and throw() must not violate the entry/exit criteria.
7657  CS->getCapturedDecl()->setNothrow();
7658  }
7659 
7661  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7662  // define the nested loops number.
7663  unsigned NestedLoopCount = checkOpenMPLoop(
7664  OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
7665  getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
7666  VarsWithImplicitDSA, B);
7667  if (NestedLoopCount == 0)
7668  return StmtError();
7669 
7670  assert((CurContext->isDependentContext() || B.builtAll()) &&
7671  "omp target parallel for simd loop exprs were not built");
7672 
7673  if (!CurContext->isDependentContext()) {
7674  // Finalize the clauses that need pre-built expressions for CodeGen.
7675  for (OMPClause *C : Clauses) {
7676  if (auto *LC = dyn_cast<OMPLinearClause>(C))
7677  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7678  B.NumIterations, *this, CurScope,
7679  DSAStack))
7680  return StmtError();
7681  }
7682  }
7683  if (checkSimdlenSafelenSpecified(*this, Clauses))
7684  return StmtError();
7685 
7686  setFunctionHasBranchProtectedScope();
7688  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7689 }
7690 
7692  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7693  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7694  if (!AStmt)
7695  return StmtError();
7696 
7697  auto *CS = cast<CapturedStmt>(AStmt);
7698  // 1.2.2 OpenMP Language Terminology
7699  // Structured block - An executable statement with a single entry at the
7700  // top and a single exit at the bottom.
7701  // The point of exit cannot be a branch out of the structured block.
7702  // longjmp() and throw() must not violate the entry/exit criteria.
7703  CS->getCapturedDecl()->setNothrow();
7704  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
7705  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7706  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7707  // 1.2.2 OpenMP Language Terminology
7708  // Structured block - An executable statement with a single entry at the
7709  // top and a single exit at the bottom.
7710  // The point of exit cannot be a branch out of the structured block.
7711  // longjmp() and throw() must not violate the entry/exit criteria.
7712  CS->getCapturedDecl()->setNothrow();
7713  }
7714 
7716  // In presence of clause 'collapse' with number of loops, it will define the
7717  // nested loops number.
7718  unsigned NestedLoopCount =
7719  checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
7720  getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
7721  VarsWithImplicitDSA, B);
7722  if (NestedLoopCount == 0)
7723  return StmtError();
7724 
7725  assert((CurContext->isDependentContext() || B.builtAll()) &&
7726  "omp target simd loop exprs were not built");
7727 
7728  if (!CurContext->isDependentContext()) {
7729  // Finalize the clauses that need pre-built expressions for CodeGen.
7730  for (OMPClause *C : Clauses) {
7731  if (auto *LC = dyn_cast<OMPLinearClause>(C))
7732  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7733  B.NumIterations, *this, CurScope,
7734  DSAStack))
7735  return StmtError();
7736  }
7737  }
7738 
7739  if (checkSimdlenSafelenSpecified(*this, Clauses))
7740  return StmtError();
7741 
7742  setFunctionHasBranchProtectedScope();
7743  return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
7744  NestedLoopCount, Clauses, AStmt, B);
7745 }
7746 
7748  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7749  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7750  if (!AStmt)
7751  return StmtError();
7752 
7753  auto *CS = cast<CapturedStmt>(AStmt);
7754  // 1.2.2 OpenMP Language Terminology
7755  // Structured block - An executable statement with a single entry at the
7756  // top and a single exit at the bottom.
7757  // The point of exit cannot be a branch out of the structured block.
7758  // longjmp() and throw() must not violate the entry/exit criteria.
7759  CS->getCapturedDecl()->setNothrow();
7760  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
7761  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7762  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7763  // 1.2.2 OpenMP Language Terminology
7764  // Structured block - An executable statement with a single entry at the
7765  // top and a single exit at the bottom.
7766  // The point of exit cannot be a branch out of the structured block.
7767  // longjmp() and throw() must not violate the entry/exit criteria.
7768  CS->getCapturedDecl()->setNothrow();
7769  }
7770 
7772  // In presence of clause 'collapse' with number of loops, it will
7773  // define the nested loops number.
7774  unsigned NestedLoopCount =
7775  checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
7776  nullptr /*ordered not a clause on distribute*/, CS, *this,
7777  *DSAStack, VarsWithImplicitDSA, B);
7778  if (NestedLoopCount == 0)
7779  return StmtError();
7780 
7781  assert((CurContext->isDependentContext() || B.builtAll()) &&
7782  "omp teams distribute loop exprs were not built");
7783 
7784  setFunctionHasBranchProtectedScope();
7785 
7786  DSAStack->setParentTeamsRegionLoc(StartLoc);
7787 
7789  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7790 }
7791 
7793  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7794  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7795  if (!AStmt)
7796  return StmtError();
7797 
7798  auto *CS = cast<CapturedStmt>(AStmt);
7799  // 1.2.2 OpenMP Language Terminology
7800  // Structured block - An executable statement with a single entry at the
7801  // top and a single exit at the bottom.
7802  // The point of exit cannot be a branch out of the structured block.
7803  // longjmp() and throw() must not violate the entry/exit criteria.
7804  CS->getCapturedDecl()->setNothrow();
7805  for (int ThisCaptureLevel =
7806  getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
7807  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7808  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7809  // 1.2.2 OpenMP Language Terminology
7810  // Structured block - An executable statement with a single entry at the
7811  // top and a single exit at the bottom.
7812  // The point of exit cannot be a branch out of the structured block.
7813  // longjmp() and throw() must not violate the entry/exit criteria.
7814  CS->getCapturedDecl()->setNothrow();
7815  }
7816 
7817 
7819  // In presence of clause 'collapse' with number of loops, it will
7820  // define the nested loops number.
7821  unsigned NestedLoopCount = checkOpenMPLoop(
7822  OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
7823  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7824  VarsWithImplicitDSA, B);
7825 
7826  if (NestedLoopCount == 0)
7827  return StmtError();
7828 
7829  assert((CurContext->isDependentContext() || B.builtAll()) &&
7830  "omp teams distribute simd loop exprs were not built");
7831 
7832  if (!CurContext->isDependentContext()) {
7833  // Finalize the clauses that need pre-built expressions for CodeGen.
7834  for (OMPClause *C : Clauses) {
7835  if (auto *LC = dyn_cast<OMPLinearClause>(C))
7836  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7837  B.NumIterations, *this, CurScope,
7838  DSAStack))
7839  return StmtError();
7840  }
7841  }
7842 
7843  if (checkSimdlenSafelenSpecified(*this, Clauses))
7844  return StmtError();
7845 
7846  setFunctionHasBranchProtectedScope();
7847 
7848  DSAStack->setParentTeamsRegionLoc(StartLoc);
7849 
7851  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7852 }
7853 
7855  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7856  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7857  if (!AStmt)
7858  return StmtError();
7859 
7860  auto *CS = cast<CapturedStmt>(AStmt);
7861  // 1.2.2 OpenMP Language Terminology
7862  // Structured block - An executable statement with a single entry at the
7863  // top and a single exit at the bottom.
7864  // The point of exit cannot be a branch out of the structured block.
7865  // longjmp() and throw() must not violate the entry/exit criteria.
7866  CS->getCapturedDecl()->setNothrow();
7867 
7868  for (int ThisCaptureLevel =
7869  getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
7870  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7871  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7872  // 1.2.2 OpenMP Language Terminology
7873  // Structured block - An executable statement with a single entry at the
7874  // top and a single exit at the bottom.
7875  // The point of exit cannot be a branch out of the structured block.
7876  // longjmp() and throw() must not violate the entry/exit criteria.
7877  CS->getCapturedDecl()->setNothrow();
7878  }
7879 
7881  // In presence of clause 'collapse' with number of loops, it will
7882  // define the nested loops number.
7883  unsigned NestedLoopCount = checkOpenMPLoop(
7884  OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
7885  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7886  VarsWithImplicitDSA, B);
7887 
7888  if (NestedLoopCount == 0)
7889  return StmtError();
7890 
7891  assert((CurContext->isDependentContext() || B.builtAll()) &&
7892  "omp for loop exprs were not built");
7893 
7894  if (!CurContext->isDependentContext()) {
7895  // Finalize the clauses that need pre-built expressions for CodeGen.
7896  for (OMPClause *C : Clauses) {
7897  if (auto *LC = dyn_cast<OMPLinearClause>(C))
7898  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7899  B.NumIterations, *this, CurScope,
7900  DSAStack))
7901  return StmtError();
7902  }
7903  }
7904 
7905  if (checkSimdlenSafelenSpecified(*this, Clauses))
7906  return StmtError();
7907 
7908  setFunctionHasBranchProtectedScope();
7909 
7910  DSAStack->setParentTeamsRegionLoc(StartLoc);
7911 
7913  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7914 }
7915 
7917  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7918  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7919  if (!AStmt)
7920  return StmtError();
7921 
7922  auto *CS = cast<CapturedStmt>(AStmt);
7923  // 1.2.2 OpenMP Language Terminology
7924  // Structured block - An executable statement with a single entry at the
7925  // top and a single exit at the bottom.
7926  // The point of exit cannot be a branch out of the structured block.
7927  // longjmp() and throw() must not violate the entry/exit criteria.
7928  CS->getCapturedDecl()->setNothrow();
7929 
7930  for (int ThisCaptureLevel =
7931  getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
7932  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7933  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7934  // 1.2.2 OpenMP Language Terminology
7935  // Structured block - An executable statement with a single entry at the
7936  // top and a single exit at the bottom.
7937  // The point of exit cannot be a branch out of the structured block.
7938  // longjmp() and throw() must not violate the entry/exit criteria.
7939  CS->getCapturedDecl()->setNothrow();
7940  }
7941 
7943  // In presence of clause 'collapse' with number of loops, it will
7944  // define the nested loops number.
7945  unsigned NestedLoopCount = checkOpenMPLoop(
7946  OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
7947  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7948  VarsWithImplicitDSA, B);
7949 
7950  if (NestedLoopCount == 0)
7951  return StmtError();
7952 
7953  assert((CurContext->isDependentContext() || B.builtAll()) &&
7954  "omp for loop exprs were not built");
7955 
7956  setFunctionHasBranchProtectedScope();
7957 
7958  DSAStack->setParentTeamsRegionLoc(StartLoc);
7959 
7961  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
7962  DSAStack->isCancelRegion());
7963 }
7964 
7966  Stmt *AStmt,
7967  SourceLocation StartLoc,
7968  SourceLocation EndLoc) {
7969  if (!AStmt)
7970  return StmtError();
7971 
7972  auto *CS = cast<CapturedStmt>(AStmt);
7973  // 1.2.2 OpenMP Language Terminology
7974  // Structured block - An executable statement with a single entry at the
7975  // top and a single exit at the bottom.
7976  // The point of exit cannot be a branch out of the structured block.
7977  // longjmp() and throw() must not violate the entry/exit criteria.
7978  CS->getCapturedDecl()->setNothrow();
7979 
7980  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
7981  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7982  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7983  // 1.2.2 OpenMP Language Terminology
7984  // Structured block - An executable statement with a single entry at the
7985  // top and a single exit at the bottom.
7986  // The point of exit cannot be a branch out of the structured block.
7987  // longjmp() and throw() must not violate the entry/exit criteria.
7988  CS->getCapturedDecl()->setNothrow();
7989  }
7990  setFunctionHasBranchProtectedScope();
7991 
7992  return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
7993  AStmt);
7994 }
7995 
7997  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7998  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7999  if (!AStmt)
8000  return StmtError();
8001 
8002  auto *CS = cast<CapturedStmt>(AStmt);
8003  // 1.2.2 OpenMP Language Terminology
8004  // Structured block - An executable statement with a single entry at the
8005  // top and a single exit at the bottom.
8006  // The point of exit cannot be a branch out of the structured block.
8007  // longjmp() and throw() must not violate the entry/exit criteria.
8008  CS->getCapturedDecl()->setNothrow();
8009  for (int ThisCaptureLevel =
8010  getOpenMPCaptureLevels(OMPD_target_teams_distribute);
8011  ThisCaptureLevel > 1; --ThisCaptureLevel) {
8012  CS = cast<CapturedStmt>(CS->getCapturedStmt());
8013  // 1.2.2 OpenMP Language Terminology
8014  // Structured block - An executable statement with a single entry at the
8015  // top and a single exit at the bottom.
8016  // The point of exit cannot be a branch out of the structured block.
8017  // longjmp() and throw() must not violate the entry/exit criteria.
8018  CS->getCapturedDecl()->setNothrow();
8019  }
8020 
8022  // In presence of clause 'collapse' with number of loops, it will
8023  // define the nested loops number.
8024  unsigned NestedLoopCount = checkOpenMPLoop(
8025  OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
8026  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
8027  VarsWithImplicitDSA, B);
8028  if (NestedLoopCount == 0)
8029  return StmtError();
8030 
8031  assert((CurContext->isDependentContext() || B.builtAll()) &&
8032  "omp target teams distribute loop exprs were not built");
8033 
8034  setFunctionHasBranchProtectedScope();
8036  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8037 }
8038 
8040  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
8041  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8042  if (!AStmt)
8043  return StmtError();
8044 
8045  auto *CS = cast<CapturedStmt>(AStmt);
8046  // 1.2.2 OpenMP Language Terminology
8047  // Structured block - An executable statement with a single entry at the
8048  // top and a single exit at the bottom.
8049  // The point of exit cannot be a branch out of the structured block.
8050  // longjmp() and throw() must not violate the entry/exit criteria.
8051  CS->getCapturedDecl()->setNothrow();
8052  for (int ThisCaptureLevel =
8053  getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
8054  ThisCaptureLevel > 1; --ThisCaptureLevel) {
8055  CS = cast<CapturedStmt>(CS->getCapturedStmt());
8056  // 1.2.2 OpenMP Language Terminology
8057  // Structured block - An executable statement with a single entry at the
8058  // top and a single exit at the bottom.
8059  // The point of exit cannot be a branch out of the structured block.
8060  // longjmp() and throw() must not violate the entry/exit criteria.
8061  CS->getCapturedDecl()->setNothrow();
8062  }
8063 
8065  // In presence of clause 'collapse' with number of loops, it will
8066  // define the nested loops number.
8067  unsigned NestedLoopCount = checkOpenMPLoop(
8068  OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
8069  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
8070  VarsWithImplicitDSA, B);
8071  if (NestedLoopCount == 0)
8072  return StmtError();
8073 
8074  assert((CurContext->isDependentContext() || B.builtAll()) &&
8075  "omp target teams distribute parallel for loop exprs were not built");
8076 
8077  if (!CurContext->isDependentContext()) {
8078  // Finalize the clauses that need pre-built expressions for CodeGen.
8079  for (OMPClause *C : Clauses) {
8080  if (auto *LC = dyn_cast<OMPLinearClause>(C))
8081  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8082  B.NumIterations, *this, CurScope,
8083  DSAStack))
8084  return StmtError();
8085  }
8086  }
8087 
8088  setFunctionHasBranchProtectedScope();
8090  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
8091  DSAStack->isCancelRegion());
8092 }
8093 
8095  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
8096  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8097  if (!AStmt)
8098  return StmtError();
8099 
8100  auto *CS = cast<CapturedStmt>(AStmt);
8101  // 1.2.2 OpenMP Language Terminology
8102  // Structured block - An executable statement with a single entry at the
8103  // top and a single exit at the bottom.
8104  // The point of exit cannot be a branch out of the structured block.
8105  // longjmp() and throw() must not violate the entry/exit criteria.
8106  CS->getCapturedDecl()->setNothrow();
8107  for (int ThisCaptureLevel = getOpenMPCaptureLevels(
8108  OMPD_target_teams_distribute_parallel_for_simd);
8109  ThisCaptureLevel > 1; --ThisCaptureLevel) {
8110  CS = cast<CapturedStmt>(CS->getCapturedStmt());
8111  // 1.2.2 OpenMP Language Terminology
8112  // Structured block - An executable statement with a single entry at the
8113  // top and a single exit at the bottom.
8114  // The point of exit cannot be a branch out of the structured block.
8115  // longjmp() and throw() must not violate the entry/exit criteria.
8116  CS->getCapturedDecl()->setNothrow();
8117  }
8118 
8120  // In presence of clause 'collapse' with number of loops, it will
8121  // define the nested loops number.
8122  unsigned NestedLoopCount =
8123  checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
8124  getCollapseNumberExpr(Clauses),
8125  nullptr /*ordered not a clause on distribute*/, CS, *this,
8126  *DSAStack, VarsWithImplicitDSA, B);
8127  if (NestedLoopCount == 0)
8128  return StmtError();
8129 
8130  assert((CurContext->isDependentContext() || B.builtAll()) &&
8131  "omp target teams distribute parallel for simd loop exprs were not "
8132  "built");
8133 
8134  if (!CurContext->isDependentContext()) {
8135  // Finalize the clauses that need pre-built expressions for CodeGen.
8136  for (OMPClause *C : Clauses) {
8137  if (auto *LC = dyn_cast<OMPLinearClause>(C))
8138  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8139  B.NumIterations, *this, CurScope,
8140  DSAStack))
8141  return StmtError();
8142  }
8143  }
8144 
8145  if (checkSimdlenSafelenSpecified(*this, Clauses))
8146  return StmtError();
8147 
8148  setFunctionHasBranchProtectedScope();
8150  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8151 }
8152 
8154  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
8155  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8156  if (!AStmt)
8157  return StmtError();
8158 
8159  auto *CS = cast<CapturedStmt>(AStmt);
8160  // 1.2.2 OpenMP Language Terminology
8161  // Structured block - An executable statement with a single entry at the
8162  // top and a single exit at the bottom.
8163  // The point of exit cannot be a branch out of the structured block.
8164  // longjmp() and throw() must not violate the entry/exit criteria.
8165  CS->getCapturedDecl()->setNothrow();
8166  for (int ThisCaptureLevel =
8167  getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
8168  ThisCaptureLevel > 1; --ThisCaptureLevel) {
8169  CS = cast<CapturedStmt>(CS->getCapturedStmt());
8170  // 1.2.2 OpenMP Language Terminology
8171  // Structured block - An executable statement with a single entry at the
8172  // top and a single exit at the bottom.
8173  // The point of exit cannot be a branch out of the structured block.
8174  // longjmp() and throw() must not violate the entry/exit criteria.
8175  CS->getCapturedDecl()->setNothrow();
8176  }
8177 
8179  // In presence of clause 'collapse' with number of loops, it will
8180  // define the nested loops number.
8181  unsigned NestedLoopCount = checkOpenMPLoop(
8182  OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
8183  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
8184  VarsWithImplicitDSA, B);
8185  if (NestedLoopCount == 0)
8186  return StmtError();
8187 
8188  assert((CurContext->isDependentContext() || B.builtAll()) &&
8189  "omp target teams distribute simd loop exprs were not built");
8190 
8191  if (!CurContext->isDependentContext()) {
8192  // Finalize the clauses that need pre-built expressions for CodeGen.
8193  for (OMPClause *C : Clauses) {
8194  if (auto *LC = dyn_cast<OMPLinearClause>(C))
8195  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8196  B.NumIterations, *this, CurScope,
8197  DSAStack))
8198  return StmtError();
8199  }
8200  }
8201 
8202  if (checkSimdlenSafelenSpecified(*this, Clauses))
8203  return StmtError();
8204 
8205  setFunctionHasBranchProtectedScope();
8207  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8208 }
8209 
8211  SourceLocation StartLoc,
8212  SourceLocation LParenLoc,
8213  SourceLocation EndLoc) {
8214  OMPClause *Res = nullptr;
8215  switch (Kind) {
8216  case OMPC_final:
8217  Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
8218  break;
8219  case OMPC_num_threads:
8220  Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
8221  break;
8222  case OMPC_safelen:
8223  Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
8224  break;
8225  case OMPC_simdlen:
8226  Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
8227  break;
8228  case OMPC_collapse:
8229  Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
8230  break;
8231  case OMPC_ordered:
8232  Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
8233  break;
8234  case OMPC_device:
8235  Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc);
8236  break;
8237  case OMPC_num_teams:
8238  Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
8239  break;
8240  case OMPC_thread_limit:
8241  Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
8242  break;
8243  case OMPC_priority:
8244  Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
8245  break;
8246  case OMPC_grainsize:
8247  Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
8248  break;
8249  case OMPC_num_tasks:
8250  Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
8251  break;
8252  case OMPC_hint:
8253  Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
8254  break;
8255  case OMPC_if:
8256  case OMPC_default:
8257  case OMPC_proc_bind:
8258  case OMPC_schedule:
8259  case OMPC_private:
8260  case OMPC_firstprivate:
8261  case OMPC_lastprivate:
8262  case OMPC_shared:
8263  case OMPC_reduction:
8264  case OMPC_task_reduction:
8265  case OMPC_in_reduction:
8266  case OMPC_linear:
8267  case OMPC_aligned:
8268  case OMPC_copyin:
8269  case OMPC_copyprivate:
8270  case OMPC_nowait:
8271  case OMPC_untied:
8272  case OMPC_mergeable:
8273  case OMPC_threadprivate:
8274  case OMPC_flush:
8275  case OMPC_read:
8276  case OMPC_write:
8277  case OMPC_update:
8278  case OMPC_capture:
8279  case OMPC_seq_cst:
8280  case OMPC_depend:
8281  case OMPC_threads:
8282  case OMPC_simd:
8283  case OMPC_map:
8284  case OMPC_nogroup:
8285  case OMPC_dist_schedule:
8286  case OMPC_defaultmap:
8287  case OMPC_unknown:
8288  case OMPC_uniform:
8289  case OMPC_to:
8290  case OMPC_from:
8291  case OMPC_use_device_ptr:
8292  case OMPC_is_device_ptr:
8293  case OMPC_unified_address:
8294  case OMPC_unified_shared_memory:
8295  case OMPC_reverse_offload:
8296  case OMPC_dynamic_allocators:
8297  case OMPC_atomic_default_mem_order:
8298  llvm_unreachable("Clause is not allowed.");
8299  }
8300  return Res;
8301 }
8302 
8303 // An OpenMP directive such as 'target parallel' has two captured regions:
8304 // for the 'target' and 'parallel' respectively. This function returns
8305 // the region in which to capture expressions associated with a clause.
8306 // A return value of OMPD_unknown signifies that the expression should not
8307 // be captured.
8310  OpenMPDirectiveKind NameModifier = OMPD_unknown) {
8311  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
8312  switch (CKind) {
8313  case OMPC_if:
8314  switch (DKind) {
8315  case OMPD_target_parallel:
8316  case OMPD_target_parallel_for:
8317  case OMPD_target_parallel_for_simd:
8318  // If this clause applies to the nested 'parallel' region, capture within
8319  // the 'target' region, otherwise do not capture.
8320  if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
8321  CaptureRegion = OMPD_target;
8322  break;
8323  case OMPD_target_teams_distribute_parallel_for:
8324  case OMPD_target_teams_distribute_parallel_for_simd:
8325  // If this clause applies to the nested 'parallel' region, capture within
8326  // the 'teams' region, otherwise do not capture.
8327  if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
8328  CaptureRegion = OMPD_teams;
8329  break;
8330  case OMPD_teams_distribute_parallel_for:
8331  case OMPD_teams_distribute_parallel_for_simd:
8332  CaptureRegion = OMPD_teams;
8333  break;
8334  case OMPD_target_update:
8335  case OMPD_target_enter_data:
8336  case OMPD_target_exit_data:
8337  CaptureRegion = OMPD_task;
8338  break;
8339  case OMPD_cancel:
8340  case OMPD_parallel:
8341  case OMPD_parallel_sections:
8342  case OMPD_parallel_for:
8343  case OMPD_parallel_for_simd:
8344  case OMPD_target:
8345  case OMPD_target_simd:
8346  case OMPD_target_teams:
8347  case OMPD_target_teams_distribute:
8348  case OMPD_target_teams_distribute_simd:
8349  case OMPD_distribute_parallel_for:
8350  case OMPD_distribute_parallel_for_simd:
8351  case OMPD_task:
8352  case OMPD_taskloop:
8353  case OMPD_taskloop_simd:
8354  case OMPD_target_data:
8355  // Do not capture if-clause expressions.
8356  break;
8357  case OMPD_threadprivate:
8358  case OMPD_taskyield:
8359  case OMPD_barrier:
8360  case OMPD_taskwait:
8361  case OMPD_cancellation_point:
8362  case OMPD_flush:
8363  case OMPD_declare_reduction:
8364  case OMPD_declare_simd:
8365  case OMPD_declare_target:
8366  case OMPD_end_declare_target:
8367  case OMPD_teams:
8368  case OMPD_simd:
8369  case OMPD_for:
8370  case OMPD_for_simd:
8371  case OMPD_sections:
8372  case OMPD_section:
8373  case OMPD_single:
8374  case OMPD_master:
8375  case OMPD_critical:
8376  case OMPD_taskgroup:
8377  case OMPD_distribute:
8378  case OMPD_ordered:
8379  case OMPD_atomic:
8380  case OMPD_distribute_simd:
8381  case OMPD_teams_distribute:
8382  case OMPD_teams_distribute_simd:
8383  case OMPD_requires:
8384  llvm_unreachable("Unexpected OpenMP directive with if-clause");
8385  case OMPD_unknown:
8386  llvm_unreachable("Unknown OpenMP directive");
8387  }
8388  break;
8389  case OMPC_num_threads:
8390  switch (DKind) {
8391  case OMPD_target_parallel:
8392  case OMPD_target_parallel_for:
8393  case OMPD_target_parallel_for_simd:
8394  CaptureRegion = OMPD_target;
8395  break;
8396  case OMPD_teams_distribute_parallel_for:
8397  case OMPD_teams_distribute_parallel_for_simd:
8398  case OMPD_target_teams_distribute_parallel_for:
8399  case OMPD_target_teams_distribute_parallel_for_simd:
8400  CaptureRegion = OMPD_teams;
8401  break;
8402  case OMPD_parallel:
8403  case OMPD_parallel_sections:
8404  case OMPD_parallel_for:
8405  case OMPD_parallel_for_simd:
8406  case OMPD_distribute_parallel_for:
8407  case OMPD_distribute_parallel_for_simd:
8408  // Do not capture num_threads-clause expressions.
8409  break;
8410  case OMPD_target_data:
8411  case OMPD_target_enter_data:
8412  case OMPD_target_exit_data:
8413  case OMPD_target_update:
8414  case OMPD_target:
8415  case OMPD_target_simd:
8416  case OMPD_target_teams:
8417  case OMPD_target_teams_distribute:
8418  case OMPD_target_teams_distribute_simd:
8419  case OMPD_cancel:
8420  case OMPD_task:
8421  case OMPD_taskloop:
8422  case OMPD_taskloop_simd:
8423  case OMPD_threadprivate:
8424  case OMPD_taskyield:
8425  case OMPD_barrier:
8426  case OMPD_taskwait:
8427  case OMPD_cancellation_point:
8428  case OMPD_flush:
8429  case OMPD_declare_reduction:
8430  case OMPD_declare_simd:
8431  case OMPD_declare_target:
8432  case OMPD_end_declare_target:
8433  case OMPD_teams:
8434  case OMPD_simd:
8435  case OMPD_for:
8436  case OMPD_for_simd:
8437  case OMPD_sections:
8438  case OMPD_section:
8439  case OMPD_single:
8440  case OMPD_master:
8441  case OMPD_critical:
8442  case OMPD_taskgroup:
8443  case OMPD_distribute:
8444  case OMPD_ordered:
8445  case OMPD_atomic:
8446  case OMPD_distribute_simd:
8447  case OMPD_teams_distribute:
8448  case OMPD_teams_distribute_simd:
8449  case OMPD_requires:
8450  llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
8451  case OMPD_unknown:
8452  llvm_unreachable("Unknown OpenMP directive");
8453  }
8454  break;
8455  case OMPC_num_teams:
8456  switch (DKind) {
8457  case OMPD_target_teams:
8458  case OMPD_target_teams_distribute:
8459  case OMPD_target_teams_distribute_simd:
8460  case OMPD_target_teams_distribute_parallel_for:
8461  case OMPD_target_teams_distribute_parallel_for_simd:
8462  CaptureRegion = OMPD_target;
8463  break;
8464  case OMPD_teams_distribute_parallel_for:
8465  case OMPD_teams_distribute_parallel_for_simd:
8466  case OMPD_teams:
8467  case OMPD_teams_distribute:
8468  case OMPD_teams_distribute_simd:
8469  // Do not capture num_teams-clause expressions.
8470  break;
8471  case OMPD_distribute_parallel_for:
8472  case OMPD_distribute_parallel_for_simd:
8473  case OMPD_task:
8474  case OMPD_taskloop:
8475  case OMPD_taskloop_simd:
8476  case OMPD_target_data:
8477  case OMPD_target_enter_data:
8478  case OMPD_target_exit_data:
8479  case OMPD_target_update:
8480  case OMPD_cancel:
8481  case OMPD_parallel:
8482  case OMPD_parallel_sections:
8483  case OMPD_parallel_for:
8484  case OMPD_parallel_for_simd:
8485  case OMPD_target:
8486  case OMPD_target_simd:
8487  case OMPD_target_parallel:
8488  case OMPD_target_parallel_for:
8489  case OMPD_target_parallel_for_simd:
8490  case OMPD_threadprivate:
8491  case OMPD_taskyield:
8492  case OMPD_barrier:
8493  case OMPD_taskwait:
8494  case OMPD_cancellation_point:
8495  case OMPD_flush:
8496  case OMPD_declare_reduction:
8497  case OMPD_declare_simd:
8498  case OMPD_declare_target:
8499  case OMPD_end_declare_target:
8500  case OMPD_simd:
8501  case OMPD_for:
8502  case OMPD_for_simd:
8503  case OMPD_sections:
8504  case OMPD_section:
8505  case OMPD_single:
8506  case OMPD_master:
8507  case OMPD_critical:
8508  case OMPD_taskgroup:
8509  case OMPD_distribute:
8510  case OMPD_ordered:
8511  case OMPD_atomic:
8512  case OMPD_distribute_simd:
8513  case OMPD_requires:
8514  llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
8515  case OMPD_unknown:
8516  llvm_unreachable("Unknown OpenMP directive");
8517  }
8518  break;
8519  case OMPC_thread_limit:
8520  switch (DKind) {
8521  case OMPD_target_teams:
8522  case OMPD_target_teams_distribute:
8523  case OMPD_target_teams_distribute_simd:
8524  case OMPD_target_teams_distribute_parallel_for:
8525  case OMPD_target_teams_distribute_parallel_for_simd:
8526  CaptureRegion = OMPD_target;
8527  break;
8528  case OMPD_teams_distribute_parallel_for:
8529  case OMPD_teams_distribute_parallel_for_simd:
8530  case OMPD_teams:
8531  case OMPD_teams_distribute:
8532  case OMPD_teams_distribute_simd:
8533  // Do not capture thread_limit-clause expressions.
8534  break;
8535  case OMPD_distribute_parallel_for:
8536  case OMPD_distribute_parallel_for_simd:
8537  case OMPD_task:
8538  case OMPD_taskloop:
8539  case OMPD_taskloop_simd:
8540  case OMPD_target_data:
8541  case OMPD_target_enter_data:
8542  case OMPD_target_exit_data:
8543  case OMPD_target_update:
8544  case OMPD_cancel:
8545  case OMPD_parallel:
8546  case OMPD_parallel_sections:
8547  case OMPD_parallel_for:
8548  case OMPD_parallel_for_simd:
8549  case OMPD_target:
8550  case OMPD_target_simd:
8551  case OMPD_target_parallel:
8552  case OMPD_target_parallel_for:
8553  case OMPD_target_parallel_for_simd:
8554  case OMPD_threadprivate:
8555  case OMPD_taskyield:
8556  case OMPD_barrier:
8557  case OMPD_taskwait:
8558  case OMPD_cancellation_point:
8559  case OMPD_flush:
8560  case OMPD_declare_reduction:
8561  case OMPD_declare_simd:
8562  case OMPD_declare_target:
8563  case OMPD_end_declare_target:
8564  case OMPD_simd:
8565  case OMPD_for:
8566  case OMPD_for_simd:
8567  case OMPD_sections:
8568  case OMPD_section:
8569  case OMPD_single:
8570  case OMPD_master:
8571  case OMPD_critical:
8572  case OMPD_taskgroup:
8573  case OMPD_distribute:
8574  case OMPD_ordered:
8575  case OMPD_atomic:
8576  case OMPD_distribute_simd:
8577  case OMPD_requires:
8578  llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
8579  case OMPD_unknown:
8580  llvm_unreachable("Unknown OpenMP directive");
8581  }
8582  break;
8583  case OMPC_schedule:
8584  switch (DKind) {
8585  case OMPD_parallel_for:
8586  case OMPD_parallel_for_simd:
8587  case OMPD_distribute_parallel_for:
8588  case OMPD_distribute_parallel_for_simd:
8589  case OMPD_teams_distribute_parallel_for:
8590  case OMPD_teams_distribute_parallel_for_simd:
8591  case OMPD_target_parallel_for:
8592  case OMPD_target_parallel_for_simd:
8593  case OMPD_target_teams_distribute_parallel_for:
8594  case OMPD_target_teams_distribute_parallel_for_simd:
8595  CaptureRegion = OMPD_parallel;
8596  break;
8597  case OMPD_for:
8598  case OMPD_for_simd:
8599  // Do not capture schedule-clause expressions.
8600  break;
8601  case OMPD_task:
8602  case OMPD_taskloop:
8603  case OMPD_taskloop_simd:
8604  case OMPD_target_data:
8605  case OMPD_target_enter_data:
8606  case OMPD_target_exit_data:
8607  case OMPD_target_update:
8608  case OMPD_teams:
8609  case OMPD_teams_distribute:
8610  case OMPD_teams_distribute_simd:
8611  case OMPD_target_teams_distribute:
8612  case OMPD_target_teams_distribute_simd:
8613  case OMPD_target:
8614  case OMPD_target_simd:
8615  case OMPD_target_parallel:
8616  case OMPD_cancel:
8617  case OMPD_parallel:
8618  case OMPD_parallel_sections:
8619  case OMPD_threadprivate:
8620  case OMPD_taskyield:
8621  case OMPD_barrier:
8622  case OMPD_taskwait:
8623  case OMPD_cancellation_point:
8624  case OMPD_flush:
8625  case OMPD_declare_reduction:
8626  case OMPD_declare_simd:
8627  case OMPD_declare_target:
8628  case OMPD_end_declare_target:
8629  case OMPD_simd:
8630  case OMPD_sections:
8631  case OMPD_section:
8632  case OMPD_single:
8633  case OMPD_master:
8634  case OMPD_critical:
8635  case OMPD_taskgroup:
8636  case OMPD_distribute:
8637  case OMPD_ordered:
8638  case OMPD_atomic:
8639  case OMPD_distribute_simd:
8640  case OMPD_target_teams:
8641  case OMPD_requires:
8642  llvm_unreachable("Unexpected OpenMP directive with schedule clause");
8643  case OMPD_unknown:
8644  llvm_unreachable("Unknown OpenMP directive");
8645  }
8646  break;
8647  case OMPC_dist_schedule:
8648  switch (DKind) {
8649  case OMPD_teams_distribute_parallel_for:
8650  case OMPD_teams_distribute_parallel_for_simd:
8651  case OMPD_teams_distribute:
8652  case OMPD_teams_distribute_simd:
8653  case OMPD_target_teams_distribute_parallel_for:
8654  case OMPD_target_teams_distribute_parallel_for_simd:
8655  case OMPD_target_teams_distribute:
8656  case OMPD_target_teams_distribute_simd:
8657  CaptureRegion = OMPD_teams;
8658  break;
8659  case OMPD_distribute_parallel_for:
8660  case OMPD_distribute_parallel_for_simd:
8661  case OMPD_distribute:
8662  case OMPD_distribute_simd:
8663  // Do not capture thread_limit-clause expressions.
8664  break;
8665  case OMPD_parallel_for:
8666  case OMPD_parallel_for_simd:
8667  case OMPD_target_parallel_for_simd:
8668  case OMPD_target_parallel_for:
8669  case OMPD_task:
8670  case OMPD_taskloop:
8671  case OMPD_taskloop_simd:
8672  case OMPD_target_data:
8673  case OMPD_target_enter_data:
8674  case OMPD_target_exit_data:
8675  case OMPD_target_update:
8676  case OMPD_teams:
8677  case OMPD_target:
8678  case OMPD_target_simd:
8679  case OMPD_target_parallel:
8680  case OMPD_cancel:
8681  case OMPD_parallel:
8682  case OMPD_parallel_sections:
8683  case OMPD_threadprivate:
8684  case OMPD_taskyield:
8685  case OMPD_barrier:
8686  case OMPD_taskwait:
8687  case OMPD_cancellation_point:
8688  case OMPD_flush:
8689  case OMPD_declare_reduction:
8690  case OMPD_declare_simd:
8691  case OMPD_declare_target:
8692  case OMPD_end_declare_target:
8693  case OMPD_simd:
8694  case OMPD_for:
8695  case OMPD_for_simd:
8696  case OMPD_sections:
8697  case OMPD_section:
8698  case OMPD_single:
8699  case OMPD_master:
8700  case OMPD_critical:
8701  case OMPD_taskgroup:
8702  case OMPD_ordered:
8703  case OMPD_atomic:
8704  case OMPD_target_teams:
8705  case OMPD_requires:
8706  llvm_unreachable("Unexpected OpenMP directive with schedule clause");
8707  case OMPD_unknown:
8708  llvm_unreachable("Unknown OpenMP directive");
8709  }
8710  break;
8711  case OMPC_device:
8712  switch (DKind) {
8713  case OMPD_target_update:
8714  case OMPD_target_enter_data:
8715  case OMPD_target_exit_data:
8716  case OMPD_target:
8717  case OMPD_target_simd:
8718  case OMPD_target_teams:
8719  case OMPD_target_parallel:
8720  case OMPD_target_teams_distribute:
8721  case OMPD_target_teams_distribute_simd:
8722  case OMPD_target_parallel_for:
8723  case OMPD_target_parallel_for_simd:
8724  case OMPD_target_teams_distribute_parallel_for:
8725  case OMPD_target_teams_distribute_parallel_for_simd:
8726  CaptureRegion = OMPD_task;
8727  break;
8728  case OMPD_target_data:
8729  // Do not capture device-clause expressions.
8730  break;
8731  case OMPD_teams_distribute_parallel_for:
8732  case OMPD_teams_distribute_parallel_for_simd:
8733  case OMPD_teams:
8734  case OMPD_teams_distribute:
8735  case OMPD_teams_distribute_simd:
8736  case OMPD_distribute_parallel_for:
8737  case OMPD_distribute_parallel_for_simd:
8738  case OMPD_task:
8739  case OMPD_taskloop:
8740  case OMPD_taskloop_simd:
8741  case OMPD_cancel:
8742  case OMPD_parallel:
8743  case OMPD_parallel_sections:
8744  case OMPD_parallel_for:
8745  case OMPD_parallel_for_simd:
8746  case OMPD_threadprivate:
8747  case OMPD_taskyield:
8748  case OMPD_barrier:
8749  case OMPD_taskwait:
8750  case OMPD_cancellation_point:
8751  case OMPD_flush:
8752  case OMPD_declare_reduction:
8753  case OMPD_declare_simd:
8754  case OMPD_declare_target:
8755  case OMPD_end_declare_target:
8756  case OMPD_simd:
8757  case OMPD_for:
8758  case OMPD_for_simd:
8759  case OMPD_sections:
8760  case OMPD_section:
8761  case OMPD_single:
8762  case OMPD_master:
8763  case OMPD_critical:
8764  case OMPD_taskgroup:
8765  case OMPD_distribute:
8766  case OMPD_ordered:
8767  case OMPD_atomic:
8768  case OMPD_distribute_simd:
8769  case OMPD_requires:
8770  llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
8771  case OMPD_unknown:
8772  llvm_unreachable("Unknown OpenMP directive");
8773  }
8774  break;
8775  case OMPC_firstprivate:
8776  case OMPC_lastprivate:
8777  case OMPC_reduction:
8778  case OMPC_task_reduction:
8779  case OMPC_in_reduction:
8780  case OMPC_linear:
8781  case OMPC_default:
8782  case OMPC_proc_bind:
8783  case OMPC_final:
8784  case OMPC_safelen:
8785  case OMPC_simdlen:
8786  case OMPC_collapse:
8787  case OMPC_private:
8788  case OMPC_shared:
8789  case OMPC_aligned:
8790  case OMPC_copyin:
8791  case OMPC_copyprivate:
8792  case OMPC_ordered:
8793  case OMPC_nowait:
8794  case OMPC_untied:
8795  case OMPC_mergeable:
8796  case OMPC_threadprivate:
8797  case OMPC_flush:
8798  case OMPC_read:
8799  case OMPC_write:
8800  case OMPC_update:
8801  case OMPC_capture:
8802  case OMPC_seq_cst:
8803  case OMPC_depend:
8804  case OMPC_threads:
8805  case OMPC_simd:
8806  case OMPC_map:
8807  case OMPC_priority:
8808  case OMPC_grainsize:
8809  case OMPC_nogroup:
8810  case OMPC_num_tasks:
8811  case OMPC_hint:
8812  case OMPC_defaultmap:
8813  case OMPC_unknown:
8814  case OMPC_uniform:
8815  case OMPC_to:
8816  case OMPC_from:
8817  case OMPC_use_device_ptr:
8818  case OMPC_is_device_ptr:
8819  case OMPC_unified_address:
8820  case OMPC_unified_shared_memory:
8821  case OMPC_reverse_offload:
8822  case OMPC_dynamic_allocators:
8823  case OMPC_atomic_default_mem_order:
8824  llvm_unreachable("Unexpected OpenMP clause.");
8825  }
8826  return CaptureRegion;
8827 }
8828 
8830  Expr *Condition, SourceLocation StartLoc,
8831  SourceLocation LParenLoc,
8832  SourceLocation NameModifierLoc,
8834  SourceLocation EndLoc) {
8835  Expr *ValExpr = Condition;
8836  Stmt *HelperValStmt = nullptr;
8837  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
8838  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
8839  !Condition->isInstantiationDependent() &&
8840  !Condition->containsUnexpandedParameterPack()) {
8841  ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
8842  if (Val.isInvalid())
8843  return nullptr;
8844 
8845  ValExpr = Val.get();
8846 
8847  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
8848  CaptureRegion =
8849  getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier);
8850  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
8851  ValExpr = MakeFullExpr(ValExpr).get();
8852  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
8853  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
8854  HelperValStmt = buildPreInits(Context, Captures);
8855  }
8856  }
8857 
8858  return new (Context)
8859  OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
8860  LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
8861 }
8862 
8864  SourceLocation StartLoc,
8865  SourceLocation LParenLoc,
8866  SourceLocation EndLoc) {
8867  Expr *ValExpr = Condition;
8868  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
8869  !Condition->isInstantiationDependent() &&
8870  !Condition->containsUnexpandedParameterPack()) {
8871  ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
8872  if (Val.isInvalid())
8873  return nullptr;
8874 
8875  ValExpr = MakeFullExpr(Val.get()).get();
8876  }
8877 
8878  return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc);
8879 }
8881  Expr *Op) {
8882  if (!Op)
8883  return ExprError();
8884 
8885  class IntConvertDiagnoser : public ICEConvertDiagnoser {
8886  public:
8887  IntConvertDiagnoser()
8888  : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
8889  SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
8890  QualType T) override {
8891  return S.Diag(Loc, diag::err_omp_not_integral) << T;
8892  }
8893  SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
8894  QualType T) override {
8895  return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
8896  }
8897  SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
8898  QualType T,
8899  QualType ConvTy) override {
8900  return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
8901  }
8902  SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
8903  QualType ConvTy) override {
8904  return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
8905  << ConvTy->isEnumeralType() << ConvTy;
8906  }
8907  SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
8908  QualType T) override {
8909  return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
8910  }
8911  SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
8912  QualType ConvTy) override {
8913  return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
8914  << ConvTy->isEnumeralType() << ConvTy;
8915  }
8916  SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
8917  QualType) override {
8918  llvm_unreachable("conversion functions are permitted");
8919  }
8920  } ConvertDiagnoser;
8921  return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
8922 }
8923 
8924 static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef,
8925  OpenMPClauseKind CKind,
8926  bool StrictlyPositive) {
8927  if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
8928  !ValExpr->isInstantiationDependent()) {
8929  SourceLocation Loc = ValExpr->getExprLoc();
8930  ExprResult Value =
8931  SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
8932  if (Value.isInvalid())
8933  return false;
8934 
8935  ValExpr = Value.get();
8936  // The expression must evaluate to a non-negative integer value.
8937  llvm::APSInt Result;
8938  if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) &&
8939  Result.isSigned() &&
8940  !((!StrictlyPositive && Result.isNonNegative()) ||
8941  (StrictlyPositive && Result.isStrictlyPositive()))) {
8942  SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
8943  << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
8944  << ValExpr->getSourceRange();
8945  return false;
8946  }
8947  }
8948  return true;
8949 }
8950 
8952  SourceLocation StartLoc,
8953  SourceLocation LParenLoc,
8954  SourceLocation EndLoc) {
8955  Expr *ValExpr = NumThreads;
8956  Stmt *HelperValStmt = nullptr;
8957 
8958  // OpenMP [2.5, Restrictions]
8959  // The num_threads expression must evaluate to a positive integer value.
8960  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
8961  /*StrictlyPositive=*/true))
8962  return nullptr;
8963 
8964  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
8965  OpenMPDirectiveKind CaptureRegion =
8966  getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads);
8967  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
8968  ValExpr = MakeFullExpr(ValExpr).get();
8969  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
8970  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
8971  HelperValStmt = buildPreInits(Context, Captures);
8972  }
8973 
8974  return new (Context) OMPNumThreadsClause(
8975  ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
8976 }
8977 
8978 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
8979  OpenMPClauseKind CKind,
8980  bool StrictlyPositive) {
8981  if (!E)
8982  return ExprError();
8983  if (E->isValueDependent() || E->isTypeDependent() ||
8985  return E;
8986  llvm::APSInt Result;
8987  ExprResult ICE = VerifyIntegerConstantExpression(E, &Result);
8988  if (ICE.isInvalid())
8989  return ExprError();
8990  if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
8991  (!StrictlyPositive && !Result.isNonNegative())) {
8992  Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
8993  << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
8994  << E->getSourceRange();
8995  return ExprError();
8996  }
8997  if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
8998  Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
8999  << E->getSourceRange();
9000  return ExprError();
9001  }
9002  if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
9003  DSAStack->setAssociatedLoops(Result.getExtValue());
9004  else if (CKind == OMPC_ordered)
9005  DSAStack->setAssociatedLoops(Result.getExtValue());
9006  return ICE;
9007 }
9008 
9010  SourceLocation LParenLoc,
9011  SourceLocation EndLoc) {
9012  // OpenMP [2.8.1, simd construct, Description]
9013  // The parameter of the safelen clause must be a constant
9014  // positive integer expression.
9015  ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
9016  if (Safelen.isInvalid())
9017  return nullptr;
9018  return new (Context)
9019  OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
9020 }
9021 
9023  SourceLocation LParenLoc,
9024  SourceLocation EndLoc) {
9025  // OpenMP [2.8.1, simd construct, Description]
9026  // The parameter of the simdlen clause must be a constant
9027  // positive integer expression.
9028  ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
9029  if (Simdlen.isInvalid())
9030  return nullptr;
9031  return new (Context)
9032  OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
9033 }
9034 
9036  SourceLocation StartLoc,
9037  SourceLocation LParenLoc,
9038  SourceLocation EndLoc) {
9039  // OpenMP [2.7.1, loop construct, Description]
9040  // OpenMP [2.8.1, simd construct, Description]
9041  // OpenMP [2.9.6, distribute construct, Description]
9042  // The parameter of the collapse clause must be a constant
9043  // positive integer expression.
9044  ExprResult NumForLoopsResult =
9045  VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
9046  if (NumForLoopsResult.isInvalid())
9047  return nullptr;
9048  return new (Context)
9049  OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
9050 }
9051 
9053  SourceLocation EndLoc,
9054  SourceLocation LParenLoc,
9055  Expr *NumForLoops) {
9056  // OpenMP [2.7.1, loop construct, Description]
9057  // OpenMP [2.8.1, simd construct, Description]
9058  // OpenMP [2.9.6, distribute construct, Description]
9059  // The parameter of the ordered clause must be a constant
9060  // positive integer expression if any.
9061  if (NumForLoops && LParenLoc.isValid()) {
9062  ExprResult NumForLoopsResult =
9063  VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
9064  if (NumForLoopsResult.isInvalid())
9065  return nullptr;
9066  NumForLoops = NumForLoopsResult.get();
9067  } else {
9068  NumForLoops = nullptr;
9069  }
9070  auto *Clause = OMPOrderedClause::Create(
9071  Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0,
9072  StartLoc, LParenLoc, EndLoc);
9073  DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
9074  return Clause;
9075 }
9076 
9078  OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
9079  SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
9080  OMPClause *Res = nullptr;
9081  switch (Kind) {
9082  case OMPC_default:
9083  Res =
9084  ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument),
9085  ArgumentLoc, StartLoc, LParenLoc, EndLoc);
9086  break;
9087  case OMPC_proc_bind:
9088  Res = ActOnOpenMPProcBindClause(
9089  static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc,
9090  LParenLoc, EndLoc);
9091  break;
9092  case OMPC_atomic_default_mem_order:
9093  Res = ActOnOpenMPAtomicDefaultMemOrderClause(
9094  static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
9095  ArgumentLoc, StartLoc, LParenLoc, EndLoc);
9096  break;
9097  case OMPC_if:
9098  case OMPC_final:
9099  case OMPC_num_threads:
9100  case OMPC_safelen:
9101  case OMPC_simdlen:
9102  case OMPC_collapse:
9103  case OMPC_schedule:
9104  case OMPC_private:
9105  case OMPC_firstprivate:
9106  case OMPC_lastprivate:
9107  case OMPC_shared:
9108  case OMPC_reduction:
9109  case OMPC_task_reduction:
9110  case OMPC_in_reduction:
9111  case OMPC_linear:
9112  case OMPC_aligned:
9113  case OMPC_copyin:
9114  case OMPC_copyprivate:
9115  case OMPC_ordered:
9116  case OMPC_nowait:
9117  case OMPC_untied:
9118  case OMPC_mergeable:
9119  case OMPC_threadprivate:
9120  case OMPC_flush:
9121  case OMPC_read:
9122  case OMPC_write:
9123  case OMPC_update:
9124  case OMPC_capture:
9125  case OMPC_seq_cst:
9126  case OMPC_depend:
9127  case OMPC_device:
9128  case OMPC_threads:
9129  case OMPC_simd:
9130  case OMPC_map:
9131  case OMPC_num_teams:
9132  case OMPC_thread_limit:
9133  case OMPC_priority:
9134  case OMPC_grainsize:
9135  case OMPC_nogroup:
9136  case OMPC_num_tasks:
9137  case OMPC_hint:
9138  case OMPC_dist_schedule:
9139  case OMPC_defaultmap:
9140  case OMPC_unknown:
9141  case OMPC_uniform:
9142  case OMPC_to:
9143  case OMPC_from:
9144  case OMPC_use_device_ptr:
9145  case OMPC_is_device_ptr:
9146  case OMPC_unified_address:
9147  case OMPC_unified_shared_memory:
9148  case OMPC_reverse_offload:
9149  case OMPC_dynamic_allocators:
9150  llvm_unreachable("Clause is not allowed.");
9151  }
9152  return Res;
9153 }
9154 
9155 static std::string
9157  ArrayRef<unsigned> Exclude = llvm::None) {
9158  SmallString<256> Buffer;
9159  llvm::raw_svector_ostream Out(Buffer);
9160  unsigned Bound = Last >= 2 ? Last - 2 : 0;
9161  unsigned Skipped = Exclude.size();
9162  auto S = Exclude.begin(), E = Exclude.end();
9163  for (unsigned I = First; I < Last; ++I) {
9164  if (std::find(S, E, I) != E) {
9165  --Skipped;
9166  continue;
9167  }
9168  Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
9169  if (I == Bound - Skipped)
9170  Out << " or ";
9171  else if (I != Bound + 1 - Skipped)
9172  Out << ", ";
9173  }
9174  return Out.str();
9175 }
9176 
9178  SourceLocation KindKwLoc,
9179  SourceLocation StartLoc,
9180  SourceLocation LParenLoc,
9181  SourceLocation EndLoc) {
9182  if (Kind == OMPC_DEFAULT_unknown) {
9183  static_assert(OMPC_DEFAULT_unknown > 0,
9184  "OMPC_DEFAULT_unknown not greater than 0");
9185  Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
9186  << getListOfPossibleValues(OMPC_default, /*First=*/0,
9187  /*Last=*/OMPC_DEFAULT_unknown)
9188  << getOpenMPClauseName(OMPC_default);
9189  return nullptr;
9190  }
9191  switch (Kind) {
9192  case OMPC_DEFAULT_none:
9193  DSAStack->setDefaultDSANone(KindKwLoc);
9194  break;
9195  case OMPC_DEFAULT_shared:
9196  DSAStack->setDefaultDSAShared(KindKwLoc);
9197  break;
9198  case OMPC_DEFAULT_unknown:
9199  llvm_unreachable("Clause kind is not allowed.");
9200  break;
9201  }
9202  return new (Context)
9203  OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
9204 }
9205 
9207  SourceLocation KindKwLoc,
9208  SourceLocation StartLoc,
9209  SourceLocation LParenLoc,
9210  SourceLocation EndLoc) {
9211  if (Kind == OMPC_PROC_BIND_unknown) {
9212  Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
9213  << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0,
9214  /*Last=*/OMPC_PROC_BIND_unknown)
9215  << getOpenMPClauseName(OMPC_proc_bind);
9216  return nullptr;
9217  }
9218  return new (Context)
9219  OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
9220 }
9221 
9224  SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
9226  Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
9228  OMPC_atomic_default_mem_order, /*First=*/0,
9230  << getOpenMPClauseName(OMPC_atomic_default_mem_order);
9231  return nullptr;
9232  }
9233  return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
9234  LParenLoc, EndLoc);
9235 }
9236 
9239  SourceLocation StartLoc, SourceLocation LParenLoc,
9240  ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
9241  SourceLocation EndLoc) {
9242  OMPClause *Res = nullptr;
9243  switch (Kind) {
9244  case OMPC_schedule:
9245  enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
9246  assert(Argument.size() == NumberOfElements &&
9247  ArgumentLoc.size() == NumberOfElements);
9248  Res = ActOnOpenMPScheduleClause(
9249  static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
9250  static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
9251  static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
9252  StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
9253  ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
9254  break;
9255  case OMPC_if:
9256  assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
9257  Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
9258  Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
9259  DelimLoc, EndLoc);
9260  break;
9261  case OMPC_dist_schedule:
9262  Res = ActOnOpenMPDistScheduleClause(
9263  static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
9264  StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
9265  break;
9266  case OMPC_defaultmap:
9267  enum { Modifier, DefaultmapKind };
9268  Res = ActOnOpenMPDefaultmapClause(
9269  static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
9270  static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
9271  StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
9272  EndLoc);
9273  break;
9274  case OMPC_final:
9275  case OMPC_num_threads:
9276  case OMPC_safelen:
9277  case OMPC_simdlen:
9278  case OMPC_collapse:
9279  case OMPC_default:
9280  case OMPC_proc_bind:
9281  case OMPC_private:
9282  case OMPC_firstprivate:
9283  case OMPC_lastprivate:
9284  case OMPC_shared:
9285  case OMPC_reduction:
9286  case OMPC_task_reduction:
9287  case OMPC_in_reduction:
9288  case OMPC_linear:
9289  case OMPC_aligned:
9290  case OMPC_copyin:
9291  case OMPC_copyprivate:
9292  case OMPC_ordered:
9293  case OMPC_nowait:
9294  case OMPC_untied:
9295  case OMPC_mergeable:
9296  case OMPC_threadprivate:
9297  case OMPC_flush:
9298  case OMPC_read:
9299  case OMPC_write:
9300  case OMPC_update:
9301  case OMPC_capture:
9302  case OMPC_seq_cst:
9303  case OMPC_depend:
9304  case OMPC_device:
9305  case OMPC_threads:
9306  case OMPC_simd:
9307  case OMPC_map:
9308  case OMPC_num_teams:
9309  case OMPC_thread_limit:
9310  case OMPC_priority:
9311  case OMPC_grainsize:
9312  case OMPC_nogroup:
9313  case OMPC_num_tasks:
9314  case OMPC_hint:
9315  case OMPC_unknown:
9316  case OMPC_uniform:
9317  case OMPC_to:
9318  case OMPC_from:
9319  case OMPC_use_device_ptr:
9320  case OMPC_is_device_ptr:
9321  case OMPC_unified_address:
9322  case OMPC_unified_shared_memory:
9323  case OMPC_reverse_offload:
9324  case OMPC_dynamic_allocators:
9325  case OMPC_atomic_default_mem_order:
9326  llvm_unreachable("Clause is not allowed.");
9327  }
9328  return Res;
9329 }
9330 
9333  SourceLocation M1Loc, SourceLocation M2Loc) {
9334  if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
9335  SmallVector<unsigned, 2> Excluded;
9337  Excluded.push_back(M2);
9338  if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
9339  Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
9340  if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
9341  Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
9342  S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
9343  << getListOfPossibleValues(OMPC_schedule,
9344  /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
9345  /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
9346  Excluded)
9347  << getOpenMPClauseName(OMPC_schedule);
9348  return true;
9349  }
9350  return false;
9351 }
9352 
9355  OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
9356  SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
9357  SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
9358  if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
9359  checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
9360  return nullptr;
9361  // OpenMP, 2.7.1, Loop Construct, Restrictions
9362  // Either the monotonic modifier or the nonmonotonic modifier can be specified
9363  // but not both.
9364  if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
9365  (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
9366  M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
9367  (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
9368  M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
9369  Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
9370  << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
9371  << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
9372  return nullptr;
9373  }
9374  if (Kind == OMPC_SCHEDULE_unknown) {
9375  std::string Values;
9376  if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
9377  unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
9378  Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
9379  /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
9380  Exclude);
9381  } else {
9382  Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
9383  /*Last=*/OMPC_SCHEDULE_unknown);
9384  }
9385  Diag(KindLoc, diag::err_omp_unexpected_clause_value)
9386  << Values << getOpenMPClauseName(OMPC_schedule);
9387  return nullptr;
9388  }
9389  // OpenMP, 2.7.1, Loop Construct, Restrictions
9390  // The nonmonotonic modifier can only be specified with schedule(dynamic) or
9391  // schedule(guided).
9392  if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
9393  M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
9394  Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
9395  Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
9396  diag::err_omp_schedule_nonmonotonic_static);
9397  return nullptr;
9398  }
9399  Expr *ValExpr = ChunkSize;
9400  Stmt *HelperValStmt = nullptr;
9401  if (ChunkSize) {
9402  if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
9403  !ChunkSize->isInstantiationDependent() &&
9404  !ChunkSize->containsUnexpandedParameterPack()) {
9405  SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
9406  ExprResult Val =
9407  PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
9408  if (Val.isInvalid())
9409  return nullptr;
9410 
9411  ValExpr = Val.get();
9412 
9413  // OpenMP [2.7.1, Restrictions]
9414  // chunk_size must be a loop invariant integer expression with a positive
9415  // value.
9416  llvm::APSInt Result;
9417  if (ValExpr->isIntegerConstantExpr(Result, Context)) {
9418  if (Result.isSigned() && !Result.isStrictlyPositive()) {
9419  Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
9420  << "schedule" << 1 << ChunkSize->getSourceRange();
9421  return nullptr;
9422  }
9424  DSAStack->getCurrentDirective(), OMPC_schedule) !=
9425  OMPD_unknown &&
9426  !CurContext->isDependentContext()) {
9427  ValExpr = MakeFullExpr(ValExpr).get();
9428  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
9429  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
9430  HelperValStmt = buildPreInits(Context, Captures);
9431  }
9432  }
9433  }
9434 
9435  return new (Context)
9436  OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
9437  ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
9438 }
9439 
9441  SourceLocation StartLoc,
9442  SourceLocation EndLoc) {
9443  OMPClause *Res = nullptr;
9444  switch (Kind) {
9445  case OMPC_ordered:
9446  Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
9447  break;
9448  case OMPC_nowait:
9449  Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
9450  break;
9451  case OMPC_untied:
9452  Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
9453  break;
9454  case OMPC_mergeable:
9455  Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
9456  break;
9457  case OMPC_read:
9458  Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
9459  break;
9460  case OMPC_write:
9461  Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
9462  break;
9463  case OMPC_update:
9464  Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
9465  break;
9466  case OMPC_capture:
9467  Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
9468  break;
9469  case OMPC_seq_cst:
9470  Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
9471  break;
9472  case OMPC_threads:
9473  Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
9474  break;
9475  case OMPC_simd:
9476  Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
9477  break;
9478  case OMPC_nogroup:
9479  Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
9480  break;
9481  case OMPC_unified_address:
9482  Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
9483  break;
9484  case OMPC_unified_shared_memory:
9485  Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
9486  break;
9487  case OMPC_reverse_offload:
9488  Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
9489  break;
9490  case OMPC_dynamic_allocators:
9491  Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
9492  break;
9493  case OMPC_if:
9494  case OMPC_final:
9495  case OMPC_num_threads:
9496  case OMPC_safelen:
9497  case OMPC_simdlen:
9498  case OMPC_collapse:
9499  case OMPC_schedule:
9500  case OMPC_private:
9501  case OMPC_firstprivate:
9502  case OMPC_lastprivate:
9503  case OMPC_shared:
9504  case OMPC_reduction:
9505  case OMPC_task_reduction:
9506  case OMPC_in_reduction:
9507  case OMPC_linear:
9508  case OMPC_aligned:
9509  case OMPC_copyin:
9510  case OMPC_copyprivate:
9511  case OMPC_default:
9512  case OMPC_proc_bind:
9513  case OMPC_threadprivate:
9514  case OMPC_flush:
9515  case OMPC_depend:
9516  case OMPC_device:
9517  case OMPC_map:
9518  case OMPC_num_teams:
9519  case OMPC_thread_limit:
9520  case OMPC_priority:
9521  case OMPC_grainsize:
9522  case OMPC_num_tasks:
9523  case OMPC_hint:
9524  case OMPC_dist_schedule:
9525  case OMPC_defaultmap:
9526  case OMPC_unknown:
9527  case OMPC_uniform:
9528  case OMPC_to:
9529  case OMPC_from:
9530  case OMPC_use_device_ptr:
9531  case OMPC_is_device_ptr:
9532  case OMPC_atomic_default_mem_order:
9533  llvm_unreachable("Clause is not allowed.");
9534  }
9535  return Res;
9536 }
9537 
9539  SourceLocation EndLoc) {
9540  DSAStack->setNowaitRegion();
9541  return new (Context) OMPNowaitClause(StartLoc, EndLoc);
9542 }
9543 
9545  SourceLocation EndLoc) {
9546  return new (Context) OMPUntiedClause(StartLoc, EndLoc);
9547 }
9548 
9550  SourceLocation EndLoc) {
9551  return new (Context) OMPMergeableClause(StartLoc, EndLoc);
9552 }
9553 
9555  SourceLocation EndLoc) {
9556  return new (Context) OMPReadClause(StartLoc, EndLoc);
9557 }
9558 
9560  SourceLocation EndLoc) {
9561  return new (Context) OMPWriteClause(StartLoc, EndLoc);
9562 }
9563 
9565  SourceLocation EndLoc) {
9566  return new (Context) OMPUpdateClause(StartLoc, EndLoc);
9567 }
9568 
9570  SourceLocation EndLoc) {
9571  return new (Context) OMPCaptureClause(StartLoc, EndLoc);
9572 }
9573 
9575  SourceLocation EndLoc) {
9576  return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
9577 }
9578 
9580  SourceLocation EndLoc) {
9581  return new (Context) OMPThreadsClause(StartLoc, EndLoc);
9582 }
9583 
9585  SourceLocation EndLoc) {
9586  return new (Context) OMPSIMDClause(StartLoc, EndLoc);
9587 }
9588 
9590  SourceLocation EndLoc) {
9591  return new (Context) OMPNogroupClause(StartLoc, EndLoc);
9592 }
9593 
9595  SourceLocation EndLoc) {
9596  return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
9597 }
9598 
9600  SourceLocation EndLoc) {
9601  return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
9602 }
9603 
9605  SourceLocation EndLoc) {
9606  return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
9607 }
9608 
9610  SourceLocation EndLoc) {
9611  return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
9612 }
9613 
9615  OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr,
9617  SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
9618  const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind,
9619  OpenMPLinearClauseKind LinKind,
9620  ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
9621  ArrayRef<SourceLocation> MapTypeModifiersLoc,
9622  OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
9623  SourceLocation DepLinMapLoc) {
9624  OMPClause *Res = nullptr;
9625  switch (Kind) {
9626  case OMPC_private:
9627  Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9628  break;
9629  case OMPC_firstprivate:
9630  Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9631  break;
9632  case OMPC_lastprivate:
9633  Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9634  break;
9635  case OMPC_shared:
9636  Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
9637  break;
9638  case OMPC_reduction:
9639  Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
9640  EndLoc, ReductionIdScopeSpec, ReductionId);
9641  break;
9642  case OMPC_task_reduction:
9643  Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
9644  EndLoc, ReductionIdScopeSpec,
9645  ReductionId);
9646  break;
9647  case OMPC_in_reduction:
9648  Res =
9649  ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
9650  EndLoc, ReductionIdScopeSpec, ReductionId);
9651  break;
9652  case OMPC_linear:
9653  Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc,
9654  LinKind, DepLinMapLoc, ColonLoc, EndLoc);
9655  break;
9656  case OMPC_aligned:
9657  Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc,
9658  ColonLoc, EndLoc);
9659  break;
9660  case OMPC_copyin:
9661  Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
9662  break;
9663  case OMPC_copyprivate:
9664  Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9665  break;
9666  case OMPC_flush:
9667  Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
9668  break;
9669  case OMPC_depend:
9670  Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList,
9671  StartLoc, LParenLoc, EndLoc);
9672  break;
9673  case OMPC_map:
9674  Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, MapType,
9675  IsMapTypeImplicit, DepLinMapLoc, ColonLoc,
9676  VarList, StartLoc, LParenLoc, EndLoc);
9677  break;
9678  case OMPC_to:
9679  Res = ActOnOpenMPToClause(VarList, StartLoc, LParenLoc, EndLoc);
9680  break;
9681  case OMPC_from:
9682  Res = ActOnOpenMPFromClause(VarList, StartLoc, LParenLoc, EndLoc);
9683  break;
9684  case OMPC_use_device_ptr:
9685  Res = ActOnOpenMPUseDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc);
9686  break;
9687  case OMPC_is_device_ptr:
9688  Res = ActOnOpenMPIsDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc);
9689  break;
9690  case OMPC_if:
9691  case OMPC_final:
9692  case OMPC_num_threads:
9693  case OMPC_safelen:
9694  case OMPC_simdlen:
9695  case OMPC_collapse:
9696  case OMPC_default:
9697  case OMPC_proc_bind:
9698  case OMPC_schedule:
9699  case OMPC_ordered:
9700  case OMPC_nowait:
9701  case OMPC_untied:
9702  case OMPC_mergeable:
9703  case OMPC_threadprivate:
9704  case OMPC_read:
9705  case OMPC_write:
9706  case OMPC_update:
9707  case OMPC_capture:
9708  case OMPC_seq_cst:
9709  case OMPC_device:
9710  case OMPC_threads:
9711  case OMPC_simd:
9712  case OMPC_num_teams:
9713  case OMPC_thread_limit:
9714  case OMPC_priority:
9715  case OMPC_grainsize:
9716  case OMPC_nogroup:
9717  case OMPC_num_tasks:
9718  case OMPC_hint:
9719  case OMPC_dist_schedule:
9720  case OMPC_defaultmap:
9721  case OMPC_unknown:
9722  case OMPC_uniform:
9723  case OMPC_unified_address:
9724  case OMPC_unified_shared_memory:
9725  case OMPC_reverse_offload:
9726  case OMPC_dynamic_allocators:
9727  case OMPC_atomic_default_mem_order:
9728  llvm_unreachable("Clause is not allowed.");
9729  }
9730  return Res;
9731 }
9732 
9734  ExprObjectKind OK, SourceLocation Loc) {
9735  ExprResult Res = BuildDeclRefExpr(
9736  Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
9737  if (!Res.isUsable())
9738  return ExprError();
9739  if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
9740  Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
9741  if (!Res.isUsable())
9742  return ExprError();
9743  }
9744  if (VK != VK_LValue && Res.get()->isGLValue()) {
9745  Res = DefaultLvalueConversion(Res.get());
9746  if (!Res.isUsable())
9747  return ExprError();
9748  }
9749  return Res;
9750 }
9751 
9752 static std::pair<ValueDecl *, bool>
9754  SourceRange &ERange, bool AllowArraySection = false) {
9755  if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
9757  return std::make_pair(nullptr, true);
9758 
9759  // OpenMP [3.1, C/C++]
9760  // A list item is a variable name.
9761  // OpenMP [2.9.3.3, Restrictions, p.1]
9762  // A variable that is part of another variable (as an array or
9763  // structure element) cannot appear in a private clause.
9764  RefExpr = RefExpr->IgnoreParens();
9765  enum {
9766  NoArrayExpr = -1,
9767  ArraySubscript = 0,
9768  OMPArraySection = 1
9769  } IsArrayExpr = NoArrayExpr;
9770  if (AllowArraySection) {
9771  if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
9772  Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
9773  while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
9774  Base = TempASE->getBase()->IgnoreParenImpCasts();
9775  RefExpr = Base;
9776  IsArrayExpr = ArraySubscript;
9777  } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
9778  Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
9779  while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
9780  Base = TempOASE->getBase()->IgnoreParenImpCasts();
9781  while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
9782  Base = TempASE->getBase()->IgnoreParenImpCasts();
9783  RefExpr = Base;
9784  IsArrayExpr = OMPArraySection;
9785  }
9786  }
9787  ELoc = RefExpr->getExprLoc();
9788  ERange = RefExpr->getSourceRange();
9789  RefExpr = RefExpr->IgnoreParenImpCasts();
9790  auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
9791  auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
9792  if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
9793  (S.getCurrentThisType().isNull() || !ME ||
9794  !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
9795  !isa<FieldDecl>(ME->getMemberDecl()))) {
9796  if (IsArrayExpr != NoArrayExpr) {
9797  S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
9798  << ERange;
9799  } else {
9800  S.Diag(ELoc,
9801  AllowArraySection
9802  ? diag::err_omp_expected_var_name_member_expr_or_array_item
9803  : diag::err_omp_expected_var_name_member_expr)
9804  << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
9805  }
9806  return std::make_pair(nullptr, false);
9807  }
9808  return std::make_pair(
9809  getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
9810 }
9811 
9813  SourceLocation StartLoc,
9814  SourceLocation LParenLoc,
9815  SourceLocation EndLoc) {
9817  SmallVector<Expr *, 8> PrivateCopies;
9818  for (Expr *RefExpr : VarList) {
9819  assert(RefExpr && "NULL expr in OpenMP private clause.");
9820  SourceLocation ELoc;
9821  SourceRange ERange;
9822  Expr *SimpleRefExpr = RefExpr;
9823  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
9824  if (Res.second) {
9825  // It will be analyzed later.
9826  Vars.push_back(RefExpr);
9827  PrivateCopies.push_back(nullptr);
9828  }
9829  ValueDecl *D = Res.first;
9830  if (!D)
9831  continue;
9832 
9833  QualType Type = D->getType();
9834  auto *VD = dyn_cast<VarDecl>(D);
9835 
9836  // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
9837  // A variable that appears in a private clause must not have an incomplete
9838  // type or a reference type.
9839  if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
9840  continue;
9841  Type = Type.getNonReferenceType();
9842 
9843  // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
9844  // A variable that is privatized must not have a const-qualified type
9845  // unless it is of class type with a mutable member. This restriction does
9846  // not apply to the firstprivate clause.
9847  //
9848  // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
9849  // A variable that appears in a private clause must not have a
9850  // const-qualified type unless it is of class type with a mutable member.
9851  if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
9852  continue;
9853 
9854  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
9855  // in a Construct]
9856  // Variables with the predetermined data-sharing attributes may not be
9857  // listed in data-sharing attributes clauses, except for the cases
9858  // listed below. For these exceptions only, listing a predetermined
9859  // variable in a data-sharing attribute clause is allowed and overrides
9860  // the variable's predetermined data-sharing attributes.
9861  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
9862  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
9863  Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
9864  << getOpenMPClauseName(OMPC_private);
9865  reportOriginalDsa(*this, DSAStack, D, DVar);
9866  continue;
9867  }
9868 
9869  OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
9870  // Variably modified types are not supported for tasks.
9871  if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
9872  isOpenMPTaskingDirective(CurrDir)) {
9873  Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
9874  << getOpenMPClauseName(OMPC_private) << Type
9875  << getOpenMPDirectiveName(CurrDir);
9876  bool IsDecl =
9877  !VD ||
9878  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
9879  Diag(D->getLocation(),
9880  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9881  << D;
9882  continue;
9883  }
9884 
9885  // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
9886  // A list item cannot appear in both a map clause and a data-sharing
9887  // attribute clause on the same construct
9888  if (isOpenMPTargetExecutionDirective(CurrDir)) {
9889  OpenMPClauseKind ConflictKind;
9890  if (DSAStack->checkMappableExprComponentListsForDecl(
9891  VD, /*CurrentRegionOnly=*/true,
9893  OpenMPClauseKind WhereFoundClauseKind) -> bool {
9894  ConflictKind = WhereFoundClauseKind;
9895  return true;
9896  })) {
9897  Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
9898  << getOpenMPClauseName(OMPC_private)
9899  << getOpenMPClauseName(ConflictKind)
9900  << getOpenMPDirectiveName(CurrDir);
9901  reportOriginalDsa(*this, DSAStack, D, DVar);
9902  continue;
9903  }
9904  }
9905 
9906  // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
9907  // A variable of class type (or array thereof) that appears in a private
9908  // clause requires an accessible, unambiguous default constructor for the
9909  // class type.
9910  // Generate helper private variable and initialize it with the default
9911  // value. The address of the original variable is replaced by the address of
9912  // the new private variable in CodeGen. This new variable is not added to
9913  // IdResolver, so the code in the OpenMP region uses original variable for
9914  // proper diagnostics.
9915  Type = Type.getUnqualifiedType();
9916  VarDecl *VDPrivate =
9917  buildVarDecl(*this, ELoc, Type, D->getName(),
9918  D->hasAttrs() ? &D->getAttrs() : nullptr,
9919  VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
9920  ActOnUninitializedDecl(VDPrivate);
9921  if (VDPrivate->isInvalidDecl())
9922  continue;
9923  DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
9924  *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
9925 
9926  DeclRefExpr *Ref = nullptr;
9927  if (!VD && !CurContext->isDependentContext())
9928  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
9929  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
9930  Vars.push_back((VD || CurContext->isDependentContext())
9931  ? RefExpr->IgnoreParens()
9932  : Ref);
9933  PrivateCopies.push_back(VDPrivateRefExpr);
9934  }
9935 
9936  if (Vars.empty())
9937  return nullptr;
9938 
9939  return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
9940  PrivateCopies);
9941 }
9942 
9943 namespace {
9944 class DiagsUninitializedSeveretyRAII {
9945 private:
9946  DiagnosticsEngine &Diags;
9947  SourceLocation SavedLoc;
9948  bool IsIgnored = false;
9949 
9950 public:
9951  DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
9952  bool IsIgnored)
9953  : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
9954  if (!IsIgnored) {
9955  Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
9956  /*Map*/ diag::Severity::Ignored, Loc);
9957  }
9958  }
9959  ~DiagsUninitializedSeveretyRAII() {
9960  if (!IsIgnored)
9961  Diags.popMappings(SavedLoc);
9962  }
9963 };
9964 }
9965 
9967  SourceLocation StartLoc,
9968  SourceLocation LParenLoc,
9969  SourceLocation EndLoc) {
9971  SmallVector<Expr *, 8> PrivateCopies;
9973  SmallVector<Decl *, 4> ExprCaptures;
9974  bool IsImplicitClause =
9975  StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
9976  SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc();
9977 
9978  for (Expr *RefExpr : VarList) {
9979  assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
9980  SourceLocation ELoc;
9981  SourceRange ERange;
9982  Expr *SimpleRefExpr = RefExpr;
9983  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
9984  if (Res.second) {
9985  // It will be analyzed later.
9986  Vars.push_back(RefExpr);
9987  PrivateCopies.push_back(nullptr);
9988  Inits.push_back(nullptr);
9989  }
9990  ValueDecl *D = Res.first;
9991  if (!D)
9992  continue;
9993 
9994  ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
9995  QualType Type = D->getType();
9996  auto *VD = dyn_cast<VarDecl>(D);
9997 
9998  // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
9999  // A variable that appears in a private clause must not have an incomplete
10000  // type or a reference type.
10001  if (RequireCompleteType(ELoc, Type,
10002  diag::err_omp_firstprivate_incomplete_type))
10003  continue;
10004  Type = Type.getNonReferenceType();
10005 
10006  // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
10007  // A variable of class type (or array thereof) that appears in a private
10008  // clause requires an accessible, unambiguous copy constructor for the
10009  // class type.
10010  QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
10011 
10012  // If an implicit firstprivate variable found it was checked already.
10013  DSAStackTy::DSAVarData TopDVar;
10014  if (!IsImplicitClause) {
10015  DSAStackTy::DSAVarData DVar =
10016  DSAStack->getTopDSA(D, /*FromParent=*/false);
10017  TopDVar = DVar;
10018  OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
10019  bool IsConstant = ElemType.isConstant(Context);
10020  // OpenMP [2.4.13, Data-sharing Attribute Clauses]
10021  // A list item that specifies a given variable may not appear in more
10022  // than one clause on the same directive, except that a variable may be
10023  // specified in both firstprivate and lastprivate clauses.
10024  // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
10025  // A list item may appear in a firstprivate or lastprivate clause but not
10026  // both.
10027  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
10028  (isOpenMPDistributeDirective(CurrDir) ||
10029  DVar.CKind != OMPC_lastprivate) &&
10030  DVar.RefExpr) {
10031  Diag(ELoc, diag::err_omp_wrong_dsa)
10032  << getOpenMPClauseName(DVar.CKind)
10033  << getOpenMPClauseName(OMPC_firstprivate);
10034  reportOriginalDsa(*this, DSAStack, D, DVar);
10035  continue;
10036  }
10037 
10038  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
10039  // in a Construct]
10040  // Variables with the predetermined data-sharing attributes may not be
10041  // listed in data-sharing attributes clauses, except for the cases
10042  // listed below. For these exceptions only, listing a predetermined
10043  // variable in a data-sharing attribute clause is allowed and overrides
10044  // the variable's predetermined data-sharing attributes.
10045  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
10046  // in a Construct, C/C++, p.2]
10047  // Variables with const-qualified type having no mutable member may be
10048  // listed in a firstprivate clause, even if they are static data members.
10049  if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
10050  DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
10051  Diag(ELoc, diag::err_omp_wrong_dsa)
10052  << getOpenMPClauseName(DVar.CKind)
10053  << getOpenMPClauseName(OMPC_firstprivate);
10054  reportOriginalDsa(*this, DSAStack, D, DVar);
10055  continue;
10056  }
10057 
10058  // OpenMP [2.9.3.4, Restrictions, p.2]
10059  // A list item that is private within a parallel region must not appear
10060  // in a firstprivate clause on a worksharing construct if any of the
10061  // worksharing regions arising from the worksharing construct ever bind
10062  // to any of the parallel regions arising from the parallel construct.
10063  // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
10064  // A list item that is private within a teams region must not appear in a
10065  // firstprivate clause on a distribute construct if any of the distribute
10066  // regions arising from the distribute construct ever bind to any of the
10067  // teams regions arising from the teams construct.
10068  // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
10069  // A list item that appears in a reduction clause of a teams construct
10070  // must not appear in a firstprivate clause on a distribute construct if
10071  // any of the distribute regions arising from the distribute construct
10072  // ever bind to any of the teams regions arising from the teams construct.
10073  if ((isOpenMPWorksharingDirective(CurrDir) ||
10074  isOpenMPDistributeDirective(CurrDir)) &&
10075  !isOpenMPParallelDirective(CurrDir) &&
10076  !isOpenMPTeamsDirective(CurrDir)) {
10077  DVar = DSAStack->getImplicitDSA(D, true);
10078  if (DVar.CKind != OMPC_shared &&
10079  (isOpenMPParallelDirective(DVar.DKind) ||
10080  isOpenMPTeamsDirective(DVar.DKind) ||
10081  DVar.DKind == OMPD_unknown)) {
10082  Diag(ELoc, diag::err_omp_required_access)
10083  << getOpenMPClauseName(OMPC_firstprivate)
10084  << getOpenMPClauseName(OMPC_shared);
10085  reportOriginalDsa(*this, DSAStack, D, DVar);
10086  continue;
10087  }
10088  }
10089  // OpenMP [2.9.3.4, Restrictions, p.3]
10090  // A list item that appears in a reduction clause of a parallel construct
10091  // must not appear in a firstprivate clause on a worksharing or task
10092  // construct if any of the worksharing or task regions arising from the
10093  // worksharing or task construct ever bind to any of the parallel regions
10094  // arising from the parallel construct.
10095  // OpenMP [2.9.3.4, Restrictions, p.4]
10096  // A list item that appears in a reduction clause in worksharing
10097  // construct must not appear in a firstprivate clause in a task construct
10098  // encountered during execution of any of the worksharing regions arising
10099  // from the worksharing construct.
10100  if (isOpenMPTaskingDirective(CurrDir)) {
10101  DVar = DSAStack->hasInnermostDSA(
10102  D, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
10103  [](OpenMPDirectiveKind K) {
10104  return isOpenMPParallelDirective(K) ||
10107  },
10108  /*FromParent=*/true);
10109  if (DVar.CKind == OMPC_reduction &&
10110  (isOpenMPParallelDirective(DVar.DKind) ||
10111  isOpenMPWorksharingDirective(DVar.DKind) ||
10112  isOpenMPTeamsDirective(DVar.DKind))) {
10113  Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
10114  << getOpenMPDirectiveName(DVar.DKind);
10115  reportOriginalDsa(*this, DSAStack, D, DVar);
10116  continue;
10117  }
10118  }
10119 
10120  // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
10121  // A list item cannot appear in both a map clause and a data-sharing
10122  // attribute clause on the same construct
10123  if (isOpenMPTargetExecutionDirective(CurrDir)) {
10124  OpenMPClauseKind ConflictKind;
10125  if (DSAStack->checkMappableExprComponentListsForDecl(
10126  VD, /*CurrentRegionOnly=*/true,
10127  [&ConflictKind](
10129  OpenMPClauseKind WhereFoundClauseKind) {
10130  ConflictKind = WhereFoundClauseKind;
10131  return true;
10132  })) {
10133  Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
10134  << getOpenMPClauseName(OMPC_firstprivate)
10135  << getOpenMPClauseName(ConflictKind)
10136  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
10137  reportOriginalDsa(*this, DSAStack, D, DVar);
10138  continue;
10139  }
10140  }
10141  }
10142 
10143  // Variably modified types are not supported for tasks.
10144  if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
10145  isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
10146  Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
10147  << getOpenMPClauseName(OMPC_firstprivate) << Type
10148  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
10149  bool IsDecl =
10150  !VD ||
10151  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
10152  Diag(D->getLocation(),
10153  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10154  << D;
10155  continue;
10156  }
10157 
10158  Type = Type.getUnqualifiedType();
10159  VarDecl *VDPrivate =
10160  buildVarDecl(*this, ELoc, Type, D->getName(),
10161  D->hasAttrs() ? &D->getAttrs() : nullptr,
10162  VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
10163  // Generate helper private variable and initialize it with the value of the
10164  // original variable. The address of the original variable is replaced by
10165  // the address of the new private variable in the CodeGen. This new variable
10166  // is not added to IdResolver, so the code in the OpenMP region uses
10167  // original variable for proper diagnostics and variable capturing.
10168  Expr *VDInitRefExpr = nullptr;
10169  // For arrays generate initializer for single element and replace it by the
10170  // original array element in CodeGen.
10171  if (Type->isArrayType()) {
10172  VarDecl *VDInit =
10173  buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
10174  VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
10175  Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
10176  ElemType = ElemType.getUnqualifiedType();
10177  VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
10178  ".firstprivate.temp");
10179  InitializedEntity Entity =
10182 
10183  InitializationSequence InitSeq(*this, Entity, Kind, Init);
10184  ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
10185  if (Result.isInvalid())
10186  VDPrivate->setInvalidDecl();
10187  else
10188  VDPrivate->setInit(Result.getAs<Expr>());
10189  // Remove temp variable declaration.
10190  Context.Deallocate(VDInitTemp);
10191  } else {
10192  VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
10193  ".firstprivate.temp");
10194  VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
10195  RefExpr->getExprLoc());
10196  AddInitializerToDecl(VDPrivate,
10197  DefaultLvalueConversion(VDInitRefExpr).get(),
10198  /*DirectInit=*/false);
10199  }
10200  if (VDPrivate->isInvalidDecl()) {
10201  if (IsImplicitClause) {
10202  Diag(RefExpr->getExprLoc(),
10203  diag::note_omp_task_predetermined_firstprivate_here);
10204  }
10205  continue;
10206  }
10207  CurContext->addDecl(VDPrivate);
10208  DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
10209  *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
10210  RefExpr->getExprLoc());
10211  DeclRefExpr *Ref = nullptr;
10212  if (!VD && !CurContext->isDependentContext()) {
10213  if (TopDVar.CKind == OMPC_lastprivate) {
10214  Ref = TopDVar.PrivateCopy;
10215  } else {
10216  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
10217  if (!isOpenMPCapturedDecl(D))
10218  ExprCaptures.push_back(Ref->getDecl());
10219  }
10220  }
10221  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
10222  Vars.push_back((VD || CurContext->isDependentContext())
10223  ? RefExpr->IgnoreParens()
10224  : Ref);
10225  PrivateCopies.push_back(VDPrivateRefExpr);
10226  Inits.push_back(VDInitRefExpr);
10227  }
10228 
10229  if (Vars.empty())
10230  return nullptr;
10231 
10232  return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
10233  Vars, PrivateCopies, Inits,
10234  buildPreInits(Context, ExprCaptures));
10235 }
10236 
10238  SourceLocation StartLoc,
10239  SourceLocation LParenLoc,
10240  SourceLocation EndLoc) {
10242  SmallVector<Expr *, 8> SrcExprs;
10243  SmallVector<Expr *, 8> DstExprs;
10244  SmallVector<Expr *, 8> AssignmentOps;
10245  SmallVector<Decl *, 4> ExprCaptures;
10246  SmallVector<Expr *, 4> ExprPostUpdates;
10247  for (Expr *RefExpr : VarList) {
10248  assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
10249  SourceLocation ELoc;
10250  SourceRange ERange;
10251  Expr *SimpleRefExpr = RefExpr;
10252  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
10253  if (Res.second) {
10254  // It will be analyzed later.
10255  Vars.push_back(RefExpr);
10256  SrcExprs.push_back(nullptr);
10257  DstExprs.push_back(nullptr);
10258  AssignmentOps.push_back(nullptr);
10259  }
10260  ValueDecl *D = Res.first;
10261  if (!D)
10262  continue;
10263 
10264  QualType Type = D->getType();
10265  auto *VD = dyn_cast<VarDecl>(D);
10266 
10267  // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
10268  // A variable that appears in a lastprivate clause must not have an
10269  // incomplete type or a reference type.
10270  if (RequireCompleteType(ELoc, Type,
10271  diag::err_omp_lastprivate_incomplete_type))
10272  continue;
10273  Type = Type.getNonReferenceType();
10274 
10275  // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
10276  // A variable that is privatized must not have a const-qualified type
10277  // unless it is of class type with a mutable member. This restriction does
10278  // not apply to the firstprivate clause.
10279  //
10280  // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
10281  // A variable that appears in a lastprivate clause must not have a
10282  // const-qualified type unless it is of class type with a mutable member.
10283  if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
10284  continue;
10285 
10286  OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
10287  // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
10288  // in a Construct]
10289  // Variables with the predetermined data-sharing attributes may not be
10290  // listed in data-sharing attributes clauses, except for the cases
10291  // listed below.
10292  // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
10293  // A list item may appear in a firstprivate or lastprivate clause but not
10294  // both.
10295  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
10296  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
10297  (isOpenMPDistributeDirective(CurrDir) ||
10298  DVar.CKind != OMPC_firstprivate) &&
10299  (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
10300  Diag(ELoc, diag::err_omp_wrong_dsa)
10301  << getOpenMPClauseName(DVar.CKind)
10302  << getOpenMPClauseName(OMPC_lastprivate);
10303  reportOriginalDsa(*this, DSAStack, D, DVar);
10304  continue;
10305  }
10306 
10307  // OpenMP [2.14.3.5, Restrictions, p.2]
10308  // A list item that is private within a parallel region, or that appears in
10309  // the reduction clause of a parallel construct, must not appear in a
10310  // lastprivate clause on a worksharing construct if any of the corresponding
10311  // worksharing regions ever binds to any of the corresponding parallel
10312  // regions.
10313  DSAStackTy::DSAVarData TopDVar = DVar;
10314  if (isOpenMPWorksharingDirective(CurrDir) &&
10315  !isOpenMPParallelDirective(CurrDir) &&
10316  !isOpenMPTeamsDirective(CurrDir)) {
10317  DVar = DSAStack->getImplicitDSA(D, true);
10318  if (DVar.CKind != OMPC_shared) {
10319  Diag(ELoc, diag::err_omp_required_access)
10320  << getOpenMPClauseName(OMPC_lastprivate)
10321  << getOpenMPClauseName(OMPC_shared);
10322  reportOriginalDsa(*this, DSAStack, D, DVar);
10323  continue;
10324  }
10325  }
10326 
10327  // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
10328  // A variable of class type (or array thereof) that appears in a
10329  // lastprivate clause requires an accessible, unambiguous default
10330  // constructor for the class type, unless the list item is also specified
10331  // in a firstprivate clause.
10332  // A variable of class type (or array thereof) that appears in a
10333  // lastprivate clause requires an accessible, unambiguous copy assignment
10334  // operator for the class type.
10335  Type = Context.getBaseElementType(Type).getNonReferenceType();
10336  VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
10337  Type.getUnqualifiedType(), ".lastprivate.src",
10338  D->hasAttrs() ? &D->getAttrs() : nullptr);
10339  DeclRefExpr *PseudoSrcExpr =
10340  buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
10341  VarDecl *DstVD =
10342  buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
10343  D->hasAttrs() ? &D->getAttrs() : nullptr);
10344  DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
10345  // For arrays generate assignment operation for single element and replace
10346  // it by the original array element in CodeGen.
10347  ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
10348  PseudoDstExpr, PseudoSrcExpr);
10349  if (AssignmentOp.isInvalid())
10350  continue;
10351  AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc,
10352  /*DiscardedValue=*/true);
10353  if (AssignmentOp.isInvalid())
10354  continue;
10355 
10356  DeclRefExpr *Ref = nullptr;
10357  if (!VD && !CurContext->isDependentContext()) {
10358  if (TopDVar.CKind == OMPC_firstprivate) {
10359  Ref = TopDVar.PrivateCopy;
10360  } else {
10361  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
10362  if (!isOpenMPCapturedDecl(D))
10363  ExprCaptures.push_back(Ref->getDecl());
10364  }
10365  if (TopDVar.CKind == OMPC_firstprivate ||
10366  (!isOpenMPCapturedDecl(D) &&
10367  Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
10368  ExprResult RefRes = DefaultLvalueConversion(Ref);
10369  if (!RefRes.isUsable())
10370  continue;
10371  ExprResult PostUpdateRes =
10372  BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
10373  RefRes.get());
10374  if (!PostUpdateRes.isUsable())
10375  continue;
10376  ExprPostUpdates.push_back(
10377  IgnoredValueConversions(PostUpdateRes.get()).get());
10378  }
10379  }
10380  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
10381  Vars.push_back((VD || CurContext->isDependentContext())
10382  ? RefExpr->IgnoreParens()
10383  : Ref);
10384  SrcExprs.push_back(PseudoSrcExpr);
10385  DstExprs.push_back(PseudoDstExpr);
10386  AssignmentOps.push_back(AssignmentOp.get());
10387  }
10388 
10389  if (Vars.empty())
10390  return nullptr;
10391 
10392  return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
10393  Vars, SrcExprs, DstExprs, AssignmentOps,
10394  buildPreInits(Context, ExprCaptures),
10395  buildPostUpdate(*this, ExprPostUpdates));
10396 }
10397 
10399  SourceLocation StartLoc,
10400  SourceLocation LParenLoc,
10401  SourceLocation EndLoc) {
10403  for (Expr *RefExpr : VarList) {
10404  assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
10405  SourceLocation ELoc;
10406  SourceRange ERange;
10407  Expr *SimpleRefExpr = RefExpr;
10408  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
10409  if (Res.second) {
10410  // It will be analyzed later.
10411  Vars.push_back(RefExpr);
10412  }
10413  ValueDecl *D = Res.first;
10414  if (!D)
10415  continue;
10416 
10417  auto *VD = dyn_cast<VarDecl>(D);
10418  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
10419  // in a Construct]
10420  // Variables with the predetermined data-sharing attributes may not be
10421  // listed in data-sharing attributes clauses, except for the cases
10422  // listed below. For these exceptions only, listing a predetermined
10423  // variable in a data-sharing attribute clause is allowed and overrides
10424  // the variable's predetermined data-sharing attributes.
10425  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
10426  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
10427  DVar.RefExpr) {
10428  Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
10429  << getOpenMPClauseName(OMPC_shared);
10430  reportOriginalDsa(*this, DSAStack, D, DVar);
10431  continue;
10432  }
10433 
10434  DeclRefExpr *Ref = nullptr;
10435  if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
10436  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
10437  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
10438  Vars.push_back((VD || !Ref || CurContext->isDependentContext())
10439  ? RefExpr->IgnoreParens()
10440  : Ref);
10441  }
10442 
10443  if (Vars.empty())
10444  return nullptr;
10445 
10446  return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
10447 }
10448 
10449 namespace {
10450 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
10451  DSAStackTy *Stack;
10452 
10453 public:
10454  bool VisitDeclRefExpr(DeclRefExpr *E) {
10455  if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
10456  DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
10457  if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
10458  return false;
10459  if (DVar.CKind != OMPC_unknown)
10460  return true;
10461  DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
10462  VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; },
10463  /*FromParent=*/true);
10464  return DVarPrivate.CKind != OMPC_unknown;
10465  }
10466  return false;
10467  }
10468  bool VisitStmt(Stmt *S) {
10469  for (Stmt *Child : S->children()) {
10470  if (Child && Visit(Child))
10471  return true;
10472  }
10473  return false;
10474  }
10475  explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
10476 };
10477 } // namespace
10478 
10479 namespace {
10480 // Transform MemberExpression for specified FieldDecl of current class to
10481 // DeclRefExpr to specified OMPCapturedExprDecl.
10482 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
10483  typedef TreeTransform<TransformExprToCaptures> BaseTransform;
10484  ValueDecl *Field = nullptr;
10485  DeclRefExpr *CapturedExpr = nullptr;
10486 
10487 public:
10488  TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
10489  : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
10490 
10491  ExprResult TransformMemberExpr(MemberExpr *E) {
10492  if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
10493  E->getMemberDecl() == Field) {
10494  CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
10495  return CapturedExpr;
10496  }
10497  return BaseTransform::TransformMemberExpr(E);
10498  }
10499  DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
10500 };
10501 } // namespace
10502 
10503 template <typename T, typename U>
10505  const llvm::function_ref<T(ValueDecl *)> Gen) {
10506  for (U &Set : Lookups) {
10507  for (auto *D : Set) {
10508  if (T Res = Gen(cast<ValueDecl>(D)))
10509  return Res;
10510  }
10511  }
10512  return T();
10513 }
10514 
10516  assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case");
10517 
10518  for (auto RD : D->redecls()) {
10519  // Don't bother with extra checks if we already know this one isn't visible.
10520  if (RD == D)
10521  continue;
10522 
10523  auto ND = cast<NamedDecl>(RD);
10524  if (LookupResult::isVisible(SemaRef, ND))
10525  return ND;
10526  }
10527 
10528  return nullptr;
10529 }
10530 
10531 static void
10532 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &ReductionId,
10533  SourceLocation Loc, QualType Ty,
10534  SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
10535  // Find all of the associated namespaces and classes based on the
10536  // arguments we have.
10537  Sema::AssociatedNamespaceSet AssociatedNamespaces;
10538  Sema::AssociatedClassSet AssociatedClasses;
10539  OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
10540  SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
10541  AssociatedClasses);
10542 
10543  // C++ [basic.lookup.argdep]p3:
10544  // Let X be the lookup set produced by unqualified lookup (3.4.1)
10545  // and let Y be the lookup set produced by argument dependent
10546  // lookup (defined as follows). If X contains [...] then Y is
10547  // empty. Otherwise Y is the set of declarations found in the
10548  // namespaces associated with the argument types as described
10549  // below. The set of declarations found by the lookup of the name
10550  // is the union of X and Y.
10551  //
10552  // Here, we compute Y and add its members to the overloaded
10553  // candidate set.
10554  for (auto *NS : AssociatedNamespaces) {
10555  // When considering an associated namespace, the lookup is the
10556  // same as the lookup performed when the associated namespace is
10557  // used as a qualifier (3.4.3.2) except that:
10558  //
10559  // -- Any using-directives in the associated namespace are
10560  // ignored.
10561  //
10562  // -- Any namespace-scope friend functions declared in
10563  // associated classes are visible within their respective
10564  // namespaces even if they are not visible during an ordinary
10565  // lookup (11.4).
10566  DeclContext::lookup_result R = NS->lookup(ReductionId.getName());
10567  for (auto *D : R) {
10568  auto *Underlying = D;
10569  if (auto *USD = dyn_cast<UsingShadowDecl>(D))
10570  Underlying = USD->getTargetDecl();
10571 
10572  if (!isa<OMPDeclareReductionDecl>(Underlying))
10573  continue;
10574 
10575  if (!SemaRef.isVisible(D)) {
10576  D = findAcceptableDecl(SemaRef, D);
10577  if (!D)
10578  continue;
10579  if (auto *USD = dyn_cast<UsingShadowDecl>(D))
10580  Underlying = USD->getTargetDecl();
10581  }
10582  Lookups.emplace_back();
10583  Lookups.back().addDecl(Underlying);
10584  }
10585  }
10586 }
10587 
10588 static ExprResult
10590  Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
10591  const DeclarationNameInfo &ReductionId, QualType Ty,
10592  CXXCastPath &BasePath, Expr *UnresolvedReduction) {
10593  if (ReductionIdScopeSpec.isInvalid())
10594  return ExprError();
10595  SmallVector<UnresolvedSet<8>, 4> Lookups;
10596  if (S) {
10597  LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
10598  Lookup.suppressDiagnostics();
10599  while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
10600  NamedDecl *D = Lookup.getRepresentativeDecl();
10601  do {
10602  S = S->getParent();
10603  } while (S && !S->isDeclScope(D));
10604  if (S)
10605  S = S->getParent();
10606  Lookups.emplace_back();
10607  Lookups.back().append(Lookup.begin(), Lookup.end());
10608  Lookup.clear();
10609  }
10610  } else if (auto *ULE =
10611  cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
10612  Lookups.push_back(UnresolvedSet<8>());
10613  Decl *PrevD = nullptr;
10614  for (NamedDecl *D : ULE->decls()) {
10615  if (D == PrevD)
10616  Lookups.push_back(UnresolvedSet<8>());
10617  else if (auto *DRD = cast<OMPDeclareReductionDecl>(D))
10618  Lookups.back().addDecl(DRD);
10619  PrevD = D;
10620  }
10621  }
10622  if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
10625  filterLookupForUDR<bool>(Lookups, [](ValueDecl *D) {
10626  return !D->isInvalidDecl() &&
10627  (D->getType()->isDependentType() ||
10630  })) {
10631  UnresolvedSet<8> ResSet;
10632  for (const UnresolvedSet<8> &Set : Lookups) {
10633  if (Set.empty())
10634  continue;
10635  ResSet.append(Set.begin(), Set.end());
10636  // The last item marks the end of all declarations at the specified scope.
10637  ResSet.addDecl(Set[Set.size() - 1]);
10638  }
10640  SemaRef.Context, /*NamingClass=*/nullptr,
10641  ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
10642  /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
10643  }
10644  // Lookup inside the classes.
10645  // C++ [over.match.oper]p3:
10646  // For a unary operator @ with an operand of a type whose
10647  // cv-unqualified version is T1, and for a binary operator @ with
10648  // a left operand of a type whose cv-unqualified version is T1 and
10649  // a right operand of a type whose cv-unqualified version is T2,
10650  // three sets of candidate functions, designated member
10651  // candidates, non-member candidates and built-in candidates, are
10652  // constructed as follows:
10653  // -- If T1 is a complete class type or a class currently being
10654  // defined, the set of member candidates is the result of the
10655  // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
10656  // the set of member candidates is empty.
10657  LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
10658  Lookup.suppressDiagnostics();
10659  if (const auto *TyRec = Ty->getAs<RecordType>()) {
10660  // Complete the type if it can be completed.
10661  // If the type is neither complete nor being defined, bail out now.
10662  if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
10663  TyRec->getDecl()->getDefinition()) {
10664  Lookup.clear();
10665  SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
10666  if (Lookup.empty()) {
10667  Lookups.emplace_back();
10668  Lookups.back().append(Lookup.begin(), Lookup.end());
10669  }
10670  }
10671  }
10672  // Perform ADL.
10673  argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
10674  if (auto *VD = filterLookupForUDR<ValueDecl *>(
10675  Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
10676  if (!D->isInvalidDecl() &&
10677  SemaRef.Context.hasSameType(D->getType(), Ty))
10678  return D;
10679  return nullptr;
10680  }))
10681  return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc);
10682  if (auto *VD = filterLookupForUDR<ValueDecl *>(
10683  Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
10684  if (!D->isInvalidDecl() &&
10685  SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
10686  !Ty.isMoreQualifiedThan(D->getType()))
10687  return D;
10688  return nullptr;
10689  })) {
10690  CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
10691  /*DetectVirtual=*/false);
10692  if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
10693  if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
10694  VD->getType().getUnqualifiedType()))) {
10695  if (SemaRef.CheckBaseClassAccess(Loc, VD->getType(), Ty, Paths.front(),
10696  /*DiagID=*/0) !=
10698  SemaRef.BuildBasePathArray(Paths, BasePath);
10699  return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc);
10700  }
10701  }
10702  }
10703  }
10704  if (ReductionIdScopeSpec.isSet()) {
10705  SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range;
10706  return ExprError();
10707  }
10708  return ExprEmpty();
10709 }
10710 
10711 namespace {
10712 /// Data for the reduction-based clauses.
10713 struct ReductionData {
10714  /// List of original reduction items.
10716  /// List of private copies of the reduction items.
10718  /// LHS expressions for the reduction_op expressions.
10720  /// RHS expressions for the reduction_op expressions.
10722  /// Reduction operation expression.
10723  SmallVector<Expr *, 8> ReductionOps;
10724  /// Taskgroup descriptors for the corresponding reduction items in
10725  /// in_reduction clauses.
10726  SmallVector<Expr *, 8> TaskgroupDescriptors;
10727  /// List of captures for clause.
10728  SmallVector<Decl *, 4> ExprCaptures;
10729  /// List of postupdate expressions.
10730  SmallVector<Expr *, 4> ExprPostUpdates;
10731  ReductionData() = delete;
10732  /// Reserves required memory for the reduction data.
10733  ReductionData(unsigned Size) {
10734  Vars.reserve(Size);
10735  Privates.reserve(Size);
10736  LHSs.reserve(Size);
10737  RHSs.reserve(Size);
10738  ReductionOps.reserve(Size);
10739  TaskgroupDescriptors.reserve(Size);
10740  ExprCaptures.reserve(Size);
10741  ExprPostUpdates.reserve(Size);
10742  }
10743  /// Stores reduction item and reduction operation only (required for dependent
10744  /// reduction item).
10745  void push(Expr *Item, Expr *ReductionOp) {
10746  Vars.emplace_back(Item);
10747  Privates.emplace_back(nullptr);
10748  LHSs.emplace_back(nullptr);
10749  RHSs.emplace_back(nullptr);
10750  ReductionOps.emplace_back(ReductionOp);
10751  TaskgroupDescriptors.emplace_back(nullptr);
10752  }
10753  /// Stores reduction data.
10754  void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
10755  Expr *TaskgroupDescriptor) {
10756  Vars.emplace_back(Item);
10757  Privates.emplace_back(Private);
10758  LHSs.emplace_back(LHS);
10759  RHSs.emplace_back(RHS);
10760  ReductionOps.emplace_back(ReductionOp);
10761  TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
10762  }
10763 };
10764 } // namespace
10765 
10767  ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
10768  SmallVectorImpl<llvm::APSInt> &ArraySizes) {
10769  const Expr *Length = OASE->getLength();
10770  if (Length == nullptr) {
10771  // For array sections of the form [1:] or [:], we would need to analyze
10772  // the lower bound...
10773  if (OASE->getColonLoc().isValid())
10774  return false;
10775 
10776  // This is an array subscript which has implicit length 1!
10777  SingleElement = true;
10778  ArraySizes.push_back(llvm::APSInt::get(1));
10779  } else {
10781  if (!Length->EvaluateAsInt(Result, Context))
10782  return false;
10783 
10784  llvm::APSInt ConstantLengthValue = Result.Val.getInt();
10785  SingleElement = (ConstantLengthValue.getSExtValue() == 1);
10786  ArraySizes.push_back(ConstantLengthValue);
10787  }
10788 
10789  // Get the base of this array section and walk up from there.
10790  const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
10791 
10792  // We require length = 1 for all array sections except the right-most to
10793  // guarantee that the memory region is contiguous and has no holes in it.
10794  while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
10795  Length = TempOASE->getLength();
10796  if (Length == nullptr) {
10797  // For array sections of the form [1:] or [:], we would need to analyze
10798  // the lower bound...
10799  if (OASE->getColonLoc().isValid())
10800  return false;
10801 
10802  // This is an array subscript which has implicit length 1!
10803  ArraySizes.push_back(llvm::APSInt::get(1));
10804  } else {
10806  if (!Length->EvaluateAsInt(Result, Context))
10807  return false;
10808 
10809  llvm::APSInt ConstantLengthValue = Result.Val.getInt();
10810  if (ConstantLengthValue.getSExtValue() != 1)
10811  return false;
10812 
10813  ArraySizes.push_back(ConstantLengthValue);
10814  }
10815  Base = TempOASE->getBase()->IgnoreParenImpCasts();
10816  }
10817 
10818  // If we have a single element, we don't need to add the implicit lengths.
10819  if (!SingleElement) {
10820  while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
10821  // Has implicit length 1!
10822  ArraySizes.push_back(llvm::APSInt::get(1));
10823  Base = TempASE->getBase()->IgnoreParenImpCasts();
10824  }
10825  }
10826 
10827  // This array section can be privatized as a single value or as a constant
10828  // sized array.
10829  return true;
10830 }
10831 
10833  Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
10834  ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
10836  CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
10837  ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
10838  DeclarationName DN = ReductionId.getName();
10840  BinaryOperatorKind BOK = BO_Comma;
10841 
10842  ASTContext &Context = S.Context;
10843  // OpenMP [2.14.3.6, reduction clause]
10844  // C
10845  // reduction-identifier is either an identifier or one of the following
10846  // operators: +, -, *, &, |, ^, && and ||
10847  // C++
10848  // reduction-identifier is either an id-expression or one of the following
10849  // operators: +, -, *, &, |, ^, && and ||
10850  switch (OOK) {
10851  case OO_Plus:
10852  case OO_Minus:
10853  BOK = BO_Add;
10854  break;
10855  case OO_Star:
10856  BOK = BO_Mul;
10857  break;
10858  case OO_Amp:
10859  BOK = BO_And;
10860  break;
10861  case OO_Pipe:
10862  BOK = BO_Or;
10863  break;
10864  case OO_Caret:
10865  BOK = BO_Xor;
10866  break;
10867  case OO_AmpAmp:
10868  BOK = BO_LAnd;
10869  break;
10870  case OO_PipePipe:
10871  BOK = BO_LOr;
10872  break;
10873  case OO_New:
10874  case OO_Delete:
10875  case OO_Array_New:
10876  case OO_Array_Delete:
10877  case OO_Slash:
10878  case OO_Percent:
10879  case OO_Tilde:
10880  case OO_Exclaim:
10881  case OO_Equal:
10882  case OO_Less:
10883  case OO_Greater:
10884  case OO_LessEqual:
10885  case OO_GreaterEqual:
10886  case OO_PlusEqual:
10887  case OO_MinusEqual:
10888  case OO_StarEqual:
10889  case OO_SlashEqual:
10890  case OO_PercentEqual:
10891  case OO_CaretEqual:
10892  case OO_AmpEqual:
10893  case OO_PipeEqual:
10894  case OO_LessLess:
10895  case OO_GreaterGreater:
10896  case OO_LessLessEqual:
10897  case OO_GreaterGreaterEqual:
10898  case OO_EqualEqual:
10899  case OO_ExclaimEqual:
10900  case OO_Spaceship:
10901  case OO_PlusPlus:
10902  case OO_MinusMinus:
10903  case OO_Comma:
10904  case OO_ArrowStar:
10905  case OO_Arrow:
10906  case OO_Call:
10907  case OO_Subscript:
10908  case OO_Conditional:
10909  case OO_Coawait:
10911  llvm_unreachable("Unexpected reduction identifier");
10912  case OO_None:
10913  if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
10914  if (II->isStr("max"))
10915  BOK = BO_GT;
10916  else if (II->isStr("min"))
10917  BOK = BO_LT;
10918  }
10919  break;
10920  }
10921  SourceRange ReductionIdRange;
10922  if (ReductionIdScopeSpec.isValid())
10923  ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
10924  else
10925  ReductionIdRange.setBegin(ReductionId.getBeginLoc());
10926  ReductionIdRange.setEnd(ReductionId.getEndLoc());
10927 
10928  auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
10929  bool FirstIter = true;
10930  for (Expr *RefExpr : VarList) {
10931  assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
10932  // OpenMP [2.1, C/C++]
10933  // A list item is a variable or array section, subject to the restrictions
10934  // specified in Section 2.4 on page 42 and in each of the sections
10935  // describing clauses and directives for which a list appears.
10936  // OpenMP [2.14.3.3, Restrictions, p.1]
10937  // A variable that is part of another variable (as an array or
10938  // structure element) cannot appear in a private clause.
10939  if (!FirstIter && IR != ER)
10940  ++IR;
10941  FirstIter = false;
10942  SourceLocation ELoc;
10943  SourceRange ERange;
10944  Expr *SimpleRefExpr = RefExpr;
10945  auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
10946  /*AllowArraySection=*/true);
10947  if (Res.second) {
10948  // Try to find 'declare reduction' corresponding construct before using
10949  // builtin/overloaded operators.
10950  QualType Type = Context.DependentTy;
10951  CXXCastPath BasePath;
10952  ExprResult DeclareReductionRef = buildDeclareReductionRef(
10953  S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
10954  ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
10955  Expr *ReductionOp = nullptr;
10956  if (S.CurContext->isDependentContext() &&
10957  (DeclareReductionRef.isUnset() ||
10958  isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
10959  ReductionOp = DeclareReductionRef.get();
10960  // It will be analyzed later.
10961  RD.push(RefExpr, ReductionOp);
10962  }
10963  ValueDecl *D = Res.first;
10964  if (!D)
10965  continue;
10966 
10967  Expr *TaskgroupDescriptor = nullptr;
10968  QualType Type;
10969  auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
10970  auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
10971  if (ASE) {
10972  Type = ASE->getType().getNonReferenceType();
10973  } else if (OASE) {
10974  QualType BaseType =
10976  if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
10977  Type = ATy->getElementType();
10978  else
10979  Type = BaseType->getPointeeType();
10980  Type = Type.getNonReferenceType();
10981  } else {
10982  Type = Context.getBaseElementType(D->getType().getNonReferenceType());
10983  }
10984  auto *VD = dyn_cast<VarDecl>(D);
10985 
10986  // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
10987  // A variable that appears in a private clause must not have an incomplete
10988  // type or a reference type.
10989  if (S.RequireCompleteType(ELoc, D->getType(),
10990  diag::err_omp_reduction_incomplete_type))
10991  continue;
10992  // OpenMP [2.14.3.6, reduction clause, Restrictions]
10993  // A list item that appears in a reduction clause must not be
10994  // const-qualified.
10995  if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
10996  /*AcceptIfMutable*/ false, ASE || OASE))
10997  continue;
10998 
10999  OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
11000  // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
11001  // If a list-item is a reference type then it must bind to the same object
11002  // for all threads of the team.
11003  if (!ASE && !OASE) {
11004  if (VD) {
11005  VarDecl *VDDef = VD->getDefinition();
11006  if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
11007  DSARefChecker Check(Stack);
11008  if (Check.Visit(VDDef->getInit())) {
11009  S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
11010  << getOpenMPClauseName(ClauseKind) << ERange;
11011  S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
11012  continue;
11013  }
11014  }
11015  }
11016 
11017  // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
11018  // in a Construct]
11019  // Variables with the predetermined data-sharing attributes may not be
11020  // listed in data-sharing attributes clauses, except for the cases
11021  // listed below. For these exceptions only, listing a predetermined
11022  // variable in a data-sharing attribute clause is allowed and overrides
11023  // the variable's predetermined data-sharing attributes.
11024  // OpenMP [2.14.3.6, Restrictions, p.3]
11025  // Any number of reduction clauses can be specified on the directive,
11026  // but a list item can appear only once in the reduction clauses for that
11027  // directive.
11028  DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
11029  if (DVar.CKind == OMPC_reduction) {
11030  S.Diag(ELoc, diag::err_omp_once_referenced)
11031  << getOpenMPClauseName(ClauseKind);
11032  if (DVar.RefExpr)
11033  S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
11034  continue;
11035  }
11036  if (DVar.CKind != OMPC_unknown) {
11037  S.Diag(ELoc, diag::err_omp_wrong_dsa)
11038  << getOpenMPClauseName(DVar.CKind)
11039  << getOpenMPClauseName(OMPC_reduction);
11040  reportOriginalDsa(S, Stack, D, DVar);
11041  continue;
11042  }
11043 
11044  // OpenMP [2.14.3.6, Restrictions, p.1]
11045  // A list item that appears in a reduction clause of a worksharing
11046  // construct must be shared in the parallel regions to which any of the
11047  // worksharing regions arising from the worksharing construct bind.
11048  if (isOpenMPWorksharingDirective(CurrDir) &&
11049  !isOpenMPParallelDirective(CurrDir) &&
11050  !isOpenMPTeamsDirective(CurrDir)) {
11051  DVar = Stack->getImplicitDSA(D, true);
11052  if (DVar.CKind != OMPC_shared) {
11053  S.Diag(ELoc, diag::err_omp_required_access)
11054  << getOpenMPClauseName(OMPC_reduction)
11055  << getOpenMPClauseName(OMPC_shared);
11056  reportOriginalDsa(S, Stack, D, DVar);
11057  continue;
11058  }
11059  }
11060  }
11061 
11062  // Try to find 'declare reduction' corresponding construct before using
11063  // builtin/overloaded operators.
11064  CXXCastPath BasePath;
11065  ExprResult DeclareReductionRef = buildDeclareReductionRef(
11066  S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
11067  ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
11068  if (DeclareReductionRef.isInvalid())
11069  continue;
11070  if (S.CurContext->isDependentContext() &&
11071  (DeclareReductionRef.isUnset() ||
11072  isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
11073  RD.push(RefExpr, DeclareReductionRef.get());
11074  continue;
11075  }
11076  if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
11077  // Not allowed reduction identifier is found.
11078  S.Diag(ReductionId.getBeginLoc(),
11079  diag::err_omp_unknown_reduction_identifier)
11080  << Type << ReductionIdRange;
11081  continue;
11082  }
11083 
11084  // OpenMP [2.14.3.6, reduction clause, Restrictions]
11085  // The type of a list item that appears in a reduction clause must be valid
11086  // for the reduction-identifier. For a max or min reduction in C, the type
11087  // of the list item must be an allowed arithmetic data type: char, int,
11088  // float, double, or _Bool, possibly modified with long, short, signed, or
11089  // unsigned. For a max or min reduction in C++, the type of the list item
11090  // must be an allowed arithmetic data type: char, wchar_t, int, float,
11091  // double, or bool, possibly modified with long, short, signed, or unsigned.
11092  if (DeclareReductionRef.isUnset()) {
11093  if ((BOK == BO_GT || BOK == BO_LT) &&
11094  !(Type->isScalarType() ||
11095  (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
11096  S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
11097  << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
11098  if (!ASE && !OASE) {
11099  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
11101  S.Diag(D->getLocation(),
11102  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11103  << D;
11104  }
11105  continue;
11106  }
11107  if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
11108  !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
11109  S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
11110  << getOpenMPClauseName(ClauseKind);
11111  if (!ASE && !OASE) {
11112  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
11114  S.Diag(D->getLocation(),
11115  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11116  << D;
11117  }
11118  continue;
11119  }
11120  }
11121 
11122  Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
11123  VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
11124  D->hasAttrs() ? &D->getAttrs() : nullptr);
11125  VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
11126  D->hasAttrs() ? &D->getAttrs() : nullptr);
11127  QualType PrivateTy = Type;
11128 
11129  // Try if we can determine constant lengths for all array sections and avoid
11130  // the VLA.
11131  bool ConstantLengthOASE = false;
11132  if (OASE) {
11133  bool SingleElement;
11135  ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
11136  Context, OASE, SingleElement, ArraySizes);
11137 
11138  // If we don't have a single element, we must emit a constant array type.
11139  if (ConstantLengthOASE && !SingleElement) {
11140  for (llvm::APSInt &Size : ArraySizes)
11141  PrivateTy = Context.getConstantArrayType(
11142  PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0);
11143  }
11144  }
11145 
11146  if ((OASE && !ConstantLengthOASE) ||
11147  (!OASE && !ASE &&
11149  if (!Context.getTargetInfo().isVLASupported() &&
11151  S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
11152  S.Diag(ELoc, diag::note_vla_unsupported);
11153  continue;
11154  }
11155  // For arrays/array sections only:
11156  // Create pseudo array type for private copy. The size for this array will
11157  // be generated during codegen.
11158  // For array subscripts or single variables Private Ty is the same as Type
11159  // (type of the variable or single array element).
11160  PrivateTy = Context.getVariableArrayType(
11161  Type,
11162  new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue),
11163  ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
11164  } else if (!ASE && !OASE &&
11165  Context.getAsArrayType(D->getType().getNonReferenceType())) {
11166  PrivateTy = D->getType().getNonReferenceType();
11167  }
11168  // Private copy.
11169  VarDecl *PrivateVD =
11170  buildVarDecl(S, ELoc, PrivateTy, D->getName(),
11171  D->hasAttrs() ? &D->getAttrs() : nullptr,
11172  VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
11173  // Add initializer for private variable.
11174  Expr *Init = nullptr;
11175  DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
11176  DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
11177  if (DeclareReductionRef.isUsable()) {
11178  auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
11179  auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
11180  if (DRD->getInitializer()) {
11181  Init = DRDRef;
11182  RHSVD->setInit(DRDRef);
11183  RHSVD->setInitStyle(VarDecl::CallInit);
11184  }
11185  } else {
11186  switch (BOK) {
11187  case BO_Add:
11188  case BO_Xor:
11189  case BO_Or:
11190  case BO_LOr:
11191  // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
11192  if (Type->isScalarType() || Type->isAnyComplexType())
11193  Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
11194  break;
11195  case BO_Mul:
11196  case BO_LAnd:
11197  if (Type->isScalarType() || Type->isAnyComplexType()) {
11198  // '*' and '&&' reduction ops - initializer is '1'.
11199  Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
11200  }
11201  break;
11202  case BO_And: {
11203  // '&' reduction op - initializer is '~0'.
11204  QualType OrigType = Type;
11205  if (auto *ComplexTy = OrigType->getAs<ComplexType>())
11206  Type = ComplexTy->getElementType();
11207  if (Type->isRealFloatingType()) {
11208  llvm::APFloat InitValue =
11209  llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type),
11210  /*isIEEE=*/true);
11211  Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
11212  Type, ELoc);
11213  } else if (Type->isScalarType()) {
11214  uint64_t Size = Context.getTypeSize(Type);
11215  QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
11216  llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
11217  Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
11218  }
11219  if (Init && OrigType->isAnyComplexType()) {
11220  // Init = 0xFFFF + 0xFFFFi;
11221  auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
11222  Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
11223  }
11224  Type = OrigType;
11225  break;
11226  }
11227  case BO_LT:
11228  case BO_GT: {
11229  // 'min' reduction op - initializer is 'Largest representable number in
11230  // the reduction list item type'.
11231  // 'max' reduction op - initializer is 'Least representable number in
11232  // the reduction list item type'.
11233  if (Type->isIntegerType() || Type->isPointerType()) {
11234  bool IsSigned = Type->hasSignedIntegerRepresentation();
11235  uint64_t Size = Context.getTypeSize(Type);
11236  QualType IntTy =
11237  Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
11238  llvm::APInt InitValue =
11239  (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
11240  : llvm::APInt::getMinValue(Size)
11241  : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
11242  : llvm::APInt::getMaxValue(Size);
11243  Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
11244  if (Type->isPointerType()) {
11245  // Cast to pointer type.
11247  ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
11248  if (CastExpr.isInvalid())
11249  continue;
11250  Init = CastExpr.get();
11251  }
11252  } else if (Type->isRealFloatingType()) {
11253  llvm::APFloat InitValue = llvm::APFloat::getLargest(
11254  Context.getFloatTypeSemantics(Type), BOK != BO_LT);
11255  Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
11256  Type, ELoc);
11257  }
11258  break;
11259  }
11260  case BO_PtrMemD:
11261  case BO_PtrMemI:
11262  case BO_MulAssign:
11263  case BO_Div:
11264  case BO_Rem:
11265  case BO_Sub:
11266  case BO_Shl:
11267  case BO_Shr:
11268  case BO_LE:
11269  case BO_GE:
11270  case BO_EQ:
11271  case BO_NE:
11272  case BO_Cmp:
11273  case BO_AndAssign:
11274  case BO_XorAssign:
11275  case BO_OrAssign:
11276  case BO_Assign:
11277  case BO_AddAssign:
11278  case BO_SubAssign:
11279  case BO_DivAssign:
11280  case BO_RemAssign:
11281  case BO_ShlAssign:
11282  case BO_ShrAssign:
11283  case BO_Comma:
11284  llvm_unreachable("Unexpected reduction operation");
11285  }
11286  }
11287  if (Init && DeclareReductionRef.isUnset())
11288  S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
11289  else if (!Init)
11290  S.ActOnUninitializedDecl(RHSVD);
11291  if (RHSVD->isInvalidDecl())
11292  continue;
11293  if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) {
11294  S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
11295  << Type << ReductionIdRange;
11296  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
11298  S.Diag(D->getLocation(),
11299  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11300  << D;
11301  continue;
11302  }
11303  // Store initializer for single element in private copy. Will be used during
11304  // codegen.
11305  PrivateVD->setInit(RHSVD->getInit());
11306  PrivateVD->setInitStyle(RHSVD->getInitStyle());
11307  DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
11308  ExprResult ReductionOp;
11309  if (DeclareReductionRef.isUsable()) {
11310  QualType RedTy = DeclareReductionRef.get()->getType();
11311  QualType PtrRedTy = Context.getPointerType(RedTy);
11312  ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
11313  ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
11314  if (!BasePath.empty()) {
11315  LHS = S.DefaultLvalueConversion(LHS.get());
11316  RHS = S.DefaultLvalueConversion(RHS.get());
11317  LHS = ImplicitCastExpr::Create(Context, PtrRedTy,
11318  CK_UncheckedDerivedToBase, LHS.get(),
11319  &BasePath, LHS.get()->getValueKind());
11320  RHS = ImplicitCastExpr::Create(Context, PtrRedTy,
11321  CK_UncheckedDerivedToBase, RHS.get(),
11322  &BasePath, RHS.get()->getValueKind());
11323  }
11325  QualType Params[] = {PtrRedTy, PtrRedTy};
11326  QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
11327  auto *OVE = new (Context) OpaqueValueExpr(
11328  ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary,
11329  S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
11330  Expr *Args[] = {LHS.get(), RHS.get()};
11331  ReductionOp =
11332  CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc);
11333  } else {
11334  ReductionOp = S.BuildBinOp(
11335  Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE);
11336  if (ReductionOp.isUsable()) {
11337  if (BOK != BO_LT && BOK != BO_GT) {
11338  ReductionOp =
11339  S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
11340  BO_Assign, LHSDRE, ReductionOp.get());
11341  } else {
11342  auto *ConditionalOp = new (Context)
11343  ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE,
11344  Type, VK_LValue, OK_Ordinary);
11345  ReductionOp =
11346  S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
11347  BO_Assign, LHSDRE, ConditionalOp);
11348  }
11349  if (ReductionOp.isUsable())
11350  ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get());
11351  }
11352  if (!ReductionOp.isUsable())
11353  continue;
11354  }
11355 
11356  // OpenMP [2.15.4.6, Restrictions, p.2]
11357  // A list item that appears in an in_reduction clause of a task construct
11358  // must appear in a task_reduction clause of a construct associated with a
11359  // taskgroup region that includes the participating task in its taskgroup
11360  // set. The construct associated with the innermost region that meets this
11361  // condition must specify the same reduction-identifier as the in_reduction
11362  // clause.
11363  if (ClauseKind == OMPC_in_reduction) {
11364  SourceRange ParentSR;
11365  BinaryOperatorKind ParentBOK;
11366  const Expr *ParentReductionOp;
11367  Expr *ParentBOKTD, *ParentReductionOpTD;
11368  DSAStackTy::DSAVarData ParentBOKDSA =
11369  Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
11370  ParentBOKTD);
11371  DSAStackTy::DSAVarData ParentReductionOpDSA =
11372  Stack->getTopMostTaskgroupReductionData(
11373  D, ParentSR, ParentReductionOp, ParentReductionOpTD);
11374  bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
11375  bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
11376  if (!IsParentBOK && !IsParentReductionOp) {
11377  S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction);
11378  continue;
11379  }
11380  if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
11381  (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK ||
11382  IsParentReductionOp) {
11383  bool EmitError = true;
11384  if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
11385  llvm::FoldingSetNodeID RedId, ParentRedId;
11386  ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
11387  DeclareReductionRef.get()->Profile(RedId, Context,
11388  /*Canonical=*/true);
11389  EmitError = RedId != ParentRedId;
11390  }
11391  if (EmitError) {
11392  S.Diag(ReductionId.getBeginLoc(),
11393  diag::err_omp_reduction_identifier_mismatch)
11394  << ReductionIdRange << RefExpr->getSourceRange();
11395  S.Diag(ParentSR.getBegin(),
11396  diag::note_omp_previous_reduction_identifier)
11397  << ParentSR
11398  << (IsParentBOK ? ParentBOKDSA.RefExpr
11399  : ParentReductionOpDSA.RefExpr)
11400  ->getSourceRange();
11401  continue;
11402  }
11403  }
11404  TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
11405  assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined.");
11406  }
11407 
11408  DeclRefExpr *Ref = nullptr;
11409  Expr *VarsExpr = RefExpr->IgnoreParens();
11410  if (!VD && !S.CurContext->isDependentContext()) {
11411  if (ASE || OASE) {
11412  TransformExprToCaptures RebuildToCapture(S, D);
11413  VarsExpr =
11414  RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
11415  Ref = RebuildToCapture.getCapturedExpr();
11416  } else {
11417  VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
11418  }
11419  if (!S.isOpenMPCapturedDecl(D)) {
11420  RD.ExprCaptures.emplace_back(Ref->getDecl());
11421  if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
11422  ExprResult RefRes = S.DefaultLvalueConversion(Ref);
11423  if (!RefRes.isUsable())
11424  continue;
11425  ExprResult PostUpdateRes =
11426  S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
11427  RefRes.get());
11428  if (!PostUpdateRes.isUsable())
11429  continue;
11430  if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
11431  Stack->getCurrentDirective() == OMPD_taskgroup) {
11432  S.Diag(RefExpr->getExprLoc(),
11433  diag::err_omp_reduction_non_addressable_expression)
11434  << RefExpr->getSourceRange();
11435  continue;
11436  }
11437  RD.ExprPostUpdates.emplace_back(
11438  S.IgnoredValueConversions(PostUpdateRes.get()).get());
11439  }
11440  }
11441  }
11442  // All reduction items are still marked as reduction (to do not increase
11443  // code base size).
11444  Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref);
11445  if (CurrDir == OMPD_taskgroup) {
11446  if (DeclareReductionRef.isUsable())
11447  Stack->addTaskgroupReductionData(D, ReductionIdRange,
11448  DeclareReductionRef.get());
11449  else
11450  Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
11451  }
11452  RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
11453  TaskgroupDescriptor);
11454  }
11455  return RD.Vars.empty();
11456 }
11457 
11459  ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
11461  CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
11462  ArrayRef<Expr *> UnresolvedReductions) {
11463  ReductionData RD(VarList.size());
11464  if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList,
11465  StartLoc, LParenLoc, ColonLoc, EndLoc,
11466  ReductionIdScopeSpec, ReductionId,
11467  UnresolvedReductions, RD))
11468  return nullptr;
11469 
11471  Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
11472  ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
11473  RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
11474  buildPreInits(Context, RD.ExprCaptures),
11475  buildPostUpdate(*this, RD.ExprPostUpdates));
11476 }
11477 
11479  ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
11481  CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
11482  ArrayRef<Expr *> UnresolvedReductions) {
11483  ReductionData RD(VarList.size());
11484  if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList,
11485  StartLoc, LParenLoc, ColonLoc, EndLoc,
11486  ReductionIdScopeSpec, ReductionId,
11487  UnresolvedReductions, RD))
11488  return nullptr;
11489 
11491  Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
11492  ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
11493  RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
11494  buildPreInits(Context, RD.ExprCaptures),
11495  buildPostUpdate(*this, RD.ExprPostUpdates));
11496 }
11497 
11499  ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
11501  CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
11502  ArrayRef<Expr *> UnresolvedReductions) {
11503  ReductionData RD(VarList.size());
11504  if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList,
11505  StartLoc, LParenLoc, ColonLoc, EndLoc,
11506  ReductionIdScopeSpec, ReductionId,
11507  UnresolvedReductions, RD))
11508  return nullptr;
11509 
11511  Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
11512  ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
11513  RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
11514  buildPreInits(Context, RD.ExprCaptures),
11515  buildPostUpdate(*this, RD.ExprPostUpdates));
11516 }
11517 
11519  SourceLocation LinLoc) {
11520  if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
11521  LinKind == OMPC_LINEAR_unknown) {
11522  Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
11523  return true;
11524  }
11525  return false;
11526 }
11527 
11529  OpenMPLinearClauseKind LinKind,
11530  QualType Type) {
11531  const auto *VD = dyn_cast_or_null<VarDecl>(D);
11532  // A variable must not have an incomplete type or a reference type.
11533  if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
11534  return true;
11535  if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
11536  !Type->isReferenceType()) {
11537  Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
11538  << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
11539  return true;
11540  }
11541  Type = Type.getNonReferenceType();
11542 
11543  // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
11544  // A variable that is privatized must not have a const-qualified type
11545  // unless it is of class type with a mutable member. This restriction does
11546  // not apply to the firstprivate clause.
11547  if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
11548  return true;
11549 
11550  // A list item must be of integral or pointer type.
11551  Type = Type.getUnqualifiedType().getCanonicalType();
11552  const auto *Ty = Type.getTypePtrOrNull();
11553  if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
11554  !Ty->isPointerType())) {
11555  Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
11556  if (D) {
11557  bool IsDecl =
11558  !VD ||
11559  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
11560  Diag(D->getLocation(),
11561  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11562  << D;
11563  }
11564  return true;
11565  }
11566  return false;
11567 }
11568 
11570  ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
11571  SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
11576  SmallVector<Decl *, 4> ExprCaptures;
11577  SmallVector<Expr *, 4> ExprPostUpdates;
11578  if (CheckOpenMPLinearModifier(LinKind, LinLoc))
11579  LinKind = OMPC_LINEAR_val;
11580  for (Expr *RefExpr : VarList) {
11581  assert(RefExpr && "NULL expr in OpenMP linear clause.");
11582  SourceLocation ELoc;
11583  SourceRange ERange;
11584  Expr *SimpleRefExpr = RefExpr;
11585  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
11586  if (Res.second) {
11587  // It will be analyzed later.
11588  Vars.push_back(RefExpr);
11589  Privates.push_back(nullptr);
11590  Inits.push_back(nullptr);
11591  }
11592  ValueDecl *D = Res.first;
11593  if (!D)
11594  continue;
11595 
11596  QualType Type = D->getType();
11597  auto *VD = dyn_cast<VarDecl>(D);
11598 
11599  // OpenMP [2.14.3.7, linear clause]
11600  // A list-item cannot appear in more than one linear clause.
11601  // A list-item that appears in a linear clause cannot appear in any
11602  // other data-sharing attribute clause.
11603  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
11604  if (DVar.RefExpr) {
11605  Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
11606  << getOpenMPClauseName(OMPC_linear);
11607  reportOriginalDsa(*this, DSAStack, D, DVar);
11608  continue;
11609  }
11610 
11611  if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
11612  continue;
11614 
11615  // Build private copy of original var.
11616  VarDecl *Private =
11617  buildVarDecl(*this, ELoc, Type, D->getName(),
11618  D->hasAttrs() ? &D->getAttrs() : nullptr,
11619  VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
11620  DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
11621  // Build var to save initial value.
11622  VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
11623  Expr *InitExpr;
11624  DeclRefExpr *Ref = nullptr;
11625  if (!VD && !CurContext->isDependentContext()) {
11626  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
11627  if (!isOpenMPCapturedDecl(D)) {
11628  ExprCaptures.push_back(Ref->getDecl());
11629  if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
11630  ExprResult RefRes = DefaultLvalueConversion(Ref);
11631  if (!RefRes.isUsable())
11632  continue;
11633  ExprResult PostUpdateRes =
11634  BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
11635  SimpleRefExpr, RefRes.get());
11636  if (!PostUpdateRes.isUsable())
11637  continue;
11638  ExprPostUpdates.push_back(
11639  IgnoredValueConversions(PostUpdateRes.get()).get());
11640  }
11641  }
11642  }
11643  if (LinKind == OMPC_LINEAR_uval)
11644  InitExpr = VD ? VD->getInit() : SimpleRefExpr;
11645  else
11646  InitExpr = VD ? SimpleRefExpr : Ref;
11647  AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
11648  /*DirectInit=*/false);
11649  DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
11650 
11651  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
11652  Vars.push_back((VD || CurContext->isDependentContext())
11653  ? RefExpr->IgnoreParens()
11654  : Ref);
11655  Privates.push_back(PrivateRef);
11656  Inits.push_back(InitRef);
11657  }
11658 
11659  if (Vars.empty())
11660  return nullptr;
11661 
11662  Expr *StepExpr = Step;
11663  Expr *CalcStepExpr = nullptr;
11664  if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
11665  !Step->isInstantiationDependent() &&
11667  SourceLocation StepLoc = Step->getBeginLoc();
11668  ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
11669  if (Val.isInvalid())
11670  return nullptr;
11671  StepExpr = Val.get();
11672 
11673  // Build var to save the step value.
11674  VarDecl *SaveVar =
11675  buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
11676  ExprResult SaveRef =
11677  buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
11679  BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
11680  CalcStep = ActOnFinishFullExpr(CalcStep.get());
11681 
11682  // Warn about zero linear step (it would be probably better specified as
11683  // making corresponding variables 'const').
11684  llvm::APSInt Result;
11685  bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context);
11686  if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive())
11687  Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0]
11688  << (Vars.size() > 1);
11689  if (!IsConstant && CalcStep.isUsable()) {
11690  // Calculate the step beforehand instead of doing this on each iteration.
11691  // (This is not used if the number of iterations may be kfold-ed).
11692  CalcStepExpr = CalcStep.get();
11693  }
11694  }
11695 
11696  return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
11697  ColonLoc, EndLoc, Vars, Privates, Inits,
11698  StepExpr, CalcStepExpr,
11699  buildPreInits(Context, ExprCaptures),
11700  buildPostUpdate(*this, ExprPostUpdates));
11701 }
11702 
11704  Expr *NumIterations, Sema &SemaRef,
11705  Scope *S, DSAStackTy *Stack) {
11706  // Walk the vars and build update/final expressions for the CodeGen.
11709  Expr *Step = Clause.getStep();
11710  Expr *CalcStep = Clause.getCalcStep();
11711  // OpenMP [2.14.3.7, linear clause]
11712  // If linear-step is not specified it is assumed to be 1.
11713  if (!Step)
11714  Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
11715  else if (CalcStep)
11716  Step = cast<BinaryOperator>(CalcStep)->getLHS();
11717  bool HasErrors = false;
11718  auto CurInit = Clause.inits().begin();
11719  auto CurPrivate = Clause.privates().begin();
11720  OpenMPLinearClauseKind LinKind = Clause.getModifier();
11721  for (Expr *RefExpr : Clause.varlists()) {
11722  SourceLocation ELoc;
11723  SourceRange ERange;
11724  Expr *SimpleRefExpr = RefExpr;
11725  auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
11726  ValueDecl *D = Res.first;
11727  if (Res.second || !D) {
11728  Updates.push_back(nullptr);
11729  Finals.push_back(nullptr);
11730  HasErrors = true;
11731  continue;
11732  }
11733  auto &&Info = Stack->isLoopControlVariable(D);
11734  // OpenMP [2.15.11, distribute simd Construct]
11735  // A list item may not appear in a linear clause, unless it is the loop
11736  // iteration variable.
11737  if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
11738  isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
11739  SemaRef.Diag(ELoc,
11740  diag::err_omp_linear_distribute_var_non_loop_iteration);
11741  Updates.push_back(nullptr);
11742  Finals.push_back(nullptr);
11743  HasErrors = true;
11744  continue;
11745  }
11746  Expr *InitExpr = *CurInit;
11747 
11748  // Build privatized reference to the current linear var.
11749  auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
11750  Expr *CapturedRef;
11751  if (LinKind == OMPC_LINEAR_uval)
11752  CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
11753  else
11754  CapturedRef =
11755  buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
11756  DE->getType().getUnqualifiedType(), DE->getExprLoc(),
11757  /*RefersToCapture=*/true);
11758 
11759  // Build update: Var = InitExpr + IV * Step
11761  if (!Info.first)
11762  Update =
11763  buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate,
11764  InitExpr, IV, Step, /* Subtract */ false);
11765  else
11766  Update = *CurPrivate;
11767  Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
11768  /*DiscardedValue=*/true);
11769 
11770  // Build final: Var = InitExpr + NumIterations * Step
11771  ExprResult Final;
11772  if (!Info.first)
11773  Final =
11774  buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
11775  InitExpr, NumIterations, Step, /*Subtract=*/false);
11776  else
11777  Final = *CurPrivate;
11778  Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
11779  /*DiscardedValue=*/true);
11780 
11781  if (!Update.isUsable() || !Final.isUsable()) {
11782  Updates.push_back(nullptr);
11783  Finals.push_back(nullptr);
11784  HasErrors = true;
11785  } else {
11786  Updates.push_back(Update.get());
11787  Finals.push_back(Final.get());
11788  }
11789  ++CurInit;
11790  ++CurPrivate;
11791  }
11792  Clause.setUpdates(Updates);
11793  Clause.setFinals(Finals);
11794  return HasErrors;
11795 }
11796 
11798  ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
11801  for (Expr *RefExpr : VarList) {
11802  assert(RefExpr && "NULL expr in OpenMP linear clause.");
11803  SourceLocation ELoc;
11804  SourceRange ERange;
11805  Expr *SimpleRefExpr = RefExpr;
11806  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
11807  if (Res.second) {
11808  // It will be analyzed later.
11809  Vars.push_back(RefExpr);
11810  }
11811  ValueDecl *D = Res.first;
11812  if (!D)
11813  continue;
11814 
11815  QualType QType = D->getType();
11816  auto *VD = dyn_cast<VarDecl>(D);
11817 
11818  // OpenMP [2.8.1, simd construct, Restrictions]
11819  // The type of list items appearing in the aligned clause must be
11820  // array, pointer, reference to array, or reference to pointer.
11822  const Type *Ty = QType.getTypePtrOrNull();
11823  if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
11824  Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
11825  << QType << getLangOpts().CPlusPlus << ERange;
11826  bool IsDecl =
11827  !VD ||
11828  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
11829  Diag(D->getLocation(),
11830  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11831  << D;
11832  continue;
11833  }
11834 
11835  // OpenMP [2.8.1, simd construct, Restrictions]
11836  // A list-item cannot appear in more than one aligned clause.
11837  if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
11838  Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange;
11839  Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
11840  << getOpenMPClauseName(OMPC_aligned);
11841  continue;
11842  }
11843 
11844  DeclRefExpr *Ref = nullptr;
11845  if (!VD && isOpenMPCapturedDecl(D))
11846  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
11847  Vars.push_back(DefaultFunctionArrayConversion(
11848  (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
11849  .get());
11850  }
11851 
11852  // OpenMP [2.8.1, simd construct, Description]
11853  // The parameter of the aligned clause, alignment, must be a constant
11854  // positive integer expression.
11855  // If no optional parameter is specified, implementation-defined default
11856  // alignments for SIMD instructions on the target platforms are assumed.
11857  if (Alignment != nullptr) {
11858  ExprResult AlignResult =
11859  VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
11860  if (AlignResult.isInvalid())
11861  return nullptr;
11862  Alignment = AlignResult.get();
11863  }
11864  if (Vars.empty())
11865  return nullptr;
11866 
11867  return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
11868  EndLoc, Vars, Alignment);
11869 }
11870 
11872  SourceLocation StartLoc,
11873  SourceLocation LParenLoc,
11874  SourceLocation EndLoc) {
11876  SmallVector<Expr *, 8> SrcExprs;
11877  SmallVector<Expr *, 8> DstExprs;
11878  SmallVector<Expr *, 8> AssignmentOps;
11879  for (Expr *RefExpr : VarList) {
11880  assert(RefExpr && "NULL expr in OpenMP copyin clause.");
11881  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
11882  // It will be analyzed later.
11883  Vars.push_back(RefExpr);
11884  SrcExprs.push_back(nullptr);
11885  DstExprs.push_back(nullptr);
11886  AssignmentOps.push_back(nullptr);
11887  continue;
11888  }
11889 
11890  SourceLocation ELoc = RefExpr->getExprLoc();
11891  // OpenMP [2.1, C/C++]
11892  // A list item is a variable name.
11893  // OpenMP [2.14.4.1, Restrictions, p.1]
11894  // A list item that appears in a copyin clause must be threadprivate.
11895  auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
11896  if (!DE || !isa<VarDecl>(DE->getDecl())) {
11897  Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
11898  << 0 << RefExpr->getSourceRange();
11899  continue;
11900  }
11901 
11902  Decl *D = DE->getDecl();
11903  auto *VD = cast<VarDecl>(D);
11904 
11905  QualType Type = VD->getType();
11906  if (Type->isDependentType() || Type->isInstantiationDependentType()) {
11907  // It will be analyzed later.
11908  Vars.push_back(DE);
11909  SrcExprs.push_back(nullptr);
11910  DstExprs.push_back(nullptr);
11911  AssignmentOps.push_back(nullptr);
11912  continue;
11913  }
11914 
11915  // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
11916  // A list item that appears in a copyin clause must be threadprivate.
11917  if (!DSAStack->isThreadPrivate(VD)) {
11918  Diag(ELoc, diag::err_omp_required_access)
11919  << getOpenMPClauseName(OMPC_copyin)
11920  << getOpenMPDirectiveName(OMPD_threadprivate);
11921  continue;
11922  }
11923 
11924  // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
11925  // A variable of class type (or array thereof) that appears in a
11926  // copyin clause requires an accessible, unambiguous copy assignment
11927  // operator for the class type.
11928  QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
11929  VarDecl *SrcVD =
11930  buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
11931  ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
11932  DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
11933  *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
11934  VarDecl *DstVD =
11935  buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
11936  VD->hasAttrs() ? &VD->getAttrs() : nullptr);
11937  DeclRefExpr *PseudoDstExpr =
11938  buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
11939  // For arrays generate assignment operation for single element and replace
11940  // it by the original array element in CodeGen.
11941  ExprResult AssignmentOp =
11942  BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
11943  PseudoSrcExpr);
11944  if (AssignmentOp.isInvalid())
11945  continue;
11946  AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
11947  /*DiscardedValue=*/true);
11948  if (AssignmentOp.isInvalid())
11949  continue;
11950 
11951  DSAStack->addDSA(VD, DE, OMPC_copyin);
11952  Vars.push_back(DE);
11953  SrcExprs.push_back(PseudoSrcExpr);
11954  DstExprs.push_back(PseudoDstExpr);
11955  AssignmentOps.push_back(AssignmentOp.get());
11956  }
11957 
11958  if (Vars.empty())
11959  return nullptr;
11960 
11961  return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
11962  SrcExprs, DstExprs, AssignmentOps);
11963 }
11964 
11966  SourceLocation StartLoc,
11967  SourceLocation LParenLoc,
11968  SourceLocation EndLoc) {
11970  SmallVector<Expr *, 8> SrcExprs;
11971  SmallVector<Expr *, 8> DstExprs;
11972  SmallVector<Expr *, 8> AssignmentOps;
11973  for (Expr *RefExpr : VarList) {
11974  assert(RefExpr && "NULL expr in OpenMP linear clause.");
11975  SourceLocation ELoc;
11976  SourceRange ERange;
11977  Expr *SimpleRefExpr = RefExpr;
11978  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
11979  if (Res.second) {
11980  // It will be analyzed later.
11981  Vars.push_back(RefExpr);
11982  SrcExprs.push_back(nullptr);
11983  DstExprs.push_back(nullptr);
11984  AssignmentOps.push_back(nullptr);
11985  }
11986  ValueDecl *D = Res.first;
11987  if (!D)
11988  continue;
11989 
11990  QualType Type = D->getType();
11991  auto *VD = dyn_cast<VarDecl>(D);
11992 
11993  // OpenMP [2.14.4.2, Restrictions, p.2]
11994  // A list item that appears in a copyprivate clause may not appear in a
11995  // private or firstprivate clause on the single construct.
11996  if (!VD || !DSAStack->isThreadPrivate(VD)) {
11997  DSAStackTy::DSAVarData DVar =
11998  DSAStack->getTopDSA(D, /*FromParent=*/false);
11999  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
12000  DVar.RefExpr) {
12001  Diag(ELoc, diag::err_omp_wrong_dsa)
12002  << getOpenMPClauseName(DVar.CKind)
12003  << getOpenMPClauseName(OMPC_copyprivate);
12004  reportOriginalDsa(*this, DSAStack, D, DVar);
12005  continue;
12006  }
12007 
12008  // OpenMP [2.11.4.2, Restrictions, p.1]
12009  // All list items that appear in a copyprivate clause must be either
12010  // threadprivate or private in the enclosing context.
12011  if (DVar.CKind == OMPC_unknown) {
12012  DVar = DSAStack->getImplicitDSA(D, false);
12013  if (DVar.CKind == OMPC_shared) {
12014  Diag(ELoc, diag::err_omp_required_access)
12015  << getOpenMPClauseName(OMPC_copyprivate)
12016  << "threadprivate or private in the enclosing context";
12017  reportOriginalDsa(*this, DSAStack, D, DVar);
12018  continue;
12019  }
12020  }
12021  }
12022 
12023  // Variably modified types are not supported.
12024  if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
12025  Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
12026  << getOpenMPClauseName(OMPC_copyprivate) << Type
12027  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
12028  bool IsDecl =
12029  !VD ||
12030  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
12031  Diag(D->getLocation(),
12032  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
12033  << D;
12034  continue;
12035  }
12036 
12037  // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
12038  // A variable of class type (or array thereof) that appears in a
12039  // copyin clause requires an accessible, unambiguous copy assignment
12040  // operator for the class type.
12041  Type = Context.getBaseElementType(Type.getNonReferenceType())
12042  .getUnqualifiedType();
12043  VarDecl *SrcVD =
12044  buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
12045  D->hasAttrs() ? &D->getAttrs() : nullptr);
12046  DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
12047  VarDecl *DstVD =
12048  buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
12049  D->hasAttrs() ? &D->getAttrs() : nullptr);
12050  DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
12051  ExprResult AssignmentOp = BuildBinOp(
12052  DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
12053  if (AssignmentOp.isInvalid())
12054  continue;
12055  AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc,
12056  /*DiscardedValue=*/true);
12057  if (AssignmentOp.isInvalid())
12058  continue;
12059 
12060  // No need to mark vars as copyprivate, they are already threadprivate or
12061  // implicitly private.
12062  assert(VD || isOpenMPCapturedDecl(D));
12063  Vars.push_back(
12064  VD ? RefExpr->IgnoreParens()
12065  : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
12066  SrcExprs.push_back(PseudoSrcExpr);
12067  DstExprs.push_back(PseudoDstExpr);
12068  AssignmentOps.push_back(AssignmentOp.get());
12069  }
12070 
12071  if (Vars.empty())
12072  return nullptr;
12073 
12074  return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
12075  Vars, SrcExprs, DstExprs, AssignmentOps);
12076 }
12077 
12079  SourceLocation StartLoc,
12080  SourceLocation LParenLoc,
12081  SourceLocation EndLoc) {
12082  if (VarList.empty())
12083  return nullptr;
12084 
12085  return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
12086 }
12087 
12088 OMPClause *
12091  ArrayRef<Expr *> VarList, SourceLocation StartLoc,
12092  SourceLocation LParenLoc, SourceLocation EndLoc) {
12093  if (DSAStack->getCurrentDirective() == OMPD_ordered &&
12094  DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
12095  Diag(DepLoc, diag::err_omp_unexpected_clause_value)
12096  << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
12097  return nullptr;
12098  }
12099  if (DSAStack->getCurrentDirective() != OMPD_ordered &&
12100  (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
12101  DepKind == OMPC_DEPEND_sink)) {
12102  unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink};
12103  Diag(DepLoc, diag::err_omp_unexpected_clause_value)
12104  << getListOfPossibleValues(OMPC_depend, /*First=*/0,
12105  /*Last=*/OMPC_DEPEND_unknown, Except)
12106  << getOpenMPClauseName(OMPC_depend);
12107  return nullptr;
12108  }
12111  llvm::APSInt DepCounter(/*BitWidth=*/32);
12112  llvm::APSInt TotalDepCount(/*BitWidth=*/32);
12113  if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
12114  if (const Expr *OrderedCountExpr =
12115  DSAStack->getParentOrderedRegionParam().first) {
12116  TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
12117  TotalDepCount.setIsUnsigned(/*Val=*/true);
12118  }
12119  }
12120  for (Expr *RefExpr : VarList) {
12121  assert(RefExpr && "NULL expr in OpenMP shared clause.");
12122  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
12123  // It will be analyzed later.
12124  Vars.push_back(RefExpr);
12125  continue;
12126  }
12127 
12128  SourceLocation ELoc = RefExpr->getExprLoc();
12129  Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
12130  if (DepKind == OMPC_DEPEND_sink) {
12131  if (DSAStack->getParentOrderedRegionParam().first &&
12132  DepCounter >= TotalDepCount) {
12133  Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
12134  continue;
12135  }
12136  ++DepCounter;
12137  // OpenMP [2.13.9, Summary]
12138  // depend(dependence-type : vec), where dependence-type is:
12139  // 'sink' and where vec is the iteration vector, which has the form:
12140  // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
12141  // where n is the value specified by the ordered clause in the loop
12142  // directive, xi denotes the loop iteration variable of the i-th nested
12143  // loop associated with the loop directive, and di is a constant
12144  // non-negative integer.
12145  if (CurContext->isDependentContext()) {
12146  // It will be analyzed later.
12147  Vars.push_back(RefExpr);
12148  continue;
12149  }
12150  SimpleExpr = SimpleExpr->IgnoreImplicit();
12152  SourceLocation OOLoc;
12153  Expr *LHS = SimpleExpr;
12154  Expr *RHS = nullptr;
12155  if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
12156  OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
12157  OOLoc = BO->getOperatorLoc();
12158  LHS = BO->getLHS()->IgnoreParenImpCasts();
12159  RHS = BO->getRHS()->IgnoreParenImpCasts();
12160  } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
12161  OOK = OCE->getOperator();
12162  OOLoc = OCE->getOperatorLoc();
12163  LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
12164  RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
12165  } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
12166  OOK = MCE->getMethodDecl()
12167  ->getNameInfo()
12168  .getName()
12169  .getCXXOverloadedOperator();
12170  OOLoc = MCE->getCallee()->getExprLoc();
12171  LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
12172  RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
12173  }
12174  SourceLocation ELoc;
12175  SourceRange ERange;
12176  auto Res = getPrivateItem(*this, LHS, ELoc, ERange);
12177  if (Res.second) {
12178  // It will be analyzed later.
12179  Vars.push_back(RefExpr);
12180  }
12181  ValueDecl *D = Res.first;
12182  if (!D)
12183  continue;
12184 
12185  if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
12186  Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
12187  continue;
12188  }
12189  if (RHS) {
12190  ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
12191  RHS, OMPC_depend, /*StrictlyPositive=*/false);
12192  if (RHSRes.isInvalid())
12193  continue;
12194  }
12195  if (!CurContext->isDependentContext() &&
12196  DSAStack->getParentOrderedRegionParam().first &&
12197  DepCounter != DSAStack->isParentLoopControlVariable(D).first) {
12198  const ValueDecl *VD =
12199  DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue());
12200  if (VD)
12201  Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
12202  << 1 << VD;
12203  else
12204  Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
12205  continue;
12206  }
12207  OpsOffs.emplace_back(RHS, OOK);
12208  } else {
12209  auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
12210  if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
12211  (ASE &&
12212  !ASE->getBase()->getType().getNonReferenceType()->isPointerType() &&
12213  !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
12214  Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
12215  << RefExpr->getSourceRange();
12216  continue;
12217  }
12218  bool Suppress = getDiagnostics().getSuppressAllDiagnostics();
12219  getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
12220  ExprResult Res =
12221  CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RefExpr->IgnoreParenImpCasts());
12222  getDiagnostics().setSuppressAllDiagnostics(Suppress);
12223  if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) {
12224  Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
12225  << RefExpr->getSourceRange();
12226  continue;
12227  }
12228  }
12229  Vars.push_back(RefExpr->IgnoreParenImpCasts());
12230  }
12231 
12232  if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
12233  TotalDepCount > VarList.size() &&
12234  DSAStack->getParentOrderedRegionParam().first &&
12235  DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
12236  Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
12237  << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1);
12238  }
12239  if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
12240  Vars.empty())
12241  return nullptr;
12242 
12243  auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
12244  DepKind, DepLoc, ColonLoc, Vars,
12245  TotalDepCount.getZExtValue());
12246  if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
12247  DSAStack->isParentOrderedRegion())
12248  DSAStack->addDoacrossDependClause(C, OpsOffs);
12249  return C;
12250 }
12251 
12253  SourceLocation LParenLoc,
12254  SourceLocation EndLoc) {
12255  Expr *ValExpr = Device;
12256  Stmt *HelperValStmt = nullptr;
12257 
12258  // OpenMP [2.9.1, Restrictions]
12259  // The device expression must evaluate to a non-negative integer value.
12260  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
12261  /*StrictlyPositive=*/false))
12262  return nullptr;
12263 
12264  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
12265  OpenMPDirectiveKind CaptureRegion =
12266  getOpenMPCaptureRegionForClause(DKind, OMPC_device);
12267  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12268  ValExpr = MakeFullExpr(ValExpr).get();
12269  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12270  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12271  HelperValStmt = buildPreInits(Context, Captures);
12272  }
12273 
12274  return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion,
12275  StartLoc, LParenLoc, EndLoc);
12276 }
12277 
12278 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
12279  DSAStackTy *Stack, QualType QTy,
12280  bool FullCheck = true) {
12281  NamedDecl *ND;
12282  if (QTy->isIncompleteType(&ND)) {
12283  SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR;
12284  return false;
12285  }
12286  if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
12287  !QTy.isTrivialType(SemaRef.Context))
12288  SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
12289  return true;
12290 }
12291 
12292 /// Return true if it can be proven that the provided array expression
12293 /// (array section or array subscript) does NOT specify the whole size of the
12294 /// array whose base type is \a BaseQTy.
12296  const Expr *E,
12297  QualType BaseQTy) {
12298  const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
12299 
12300  // If this is an array subscript, it refers to the whole size if the size of
12301  // the dimension is constant and equals 1. Also, an array section assumes the
12302  // format of an array subscript if no colon is used.
12303  if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) {
12304  if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
12305  return ATy->getSize().getSExtValue() != 1;
12306  // Size can't be evaluated statically.
12307  return false;
12308  }
12309 
12310  assert(OASE && "Expecting array section if not an array subscript.");
12311  const Expr *LowerBound = OASE->getLowerBound();
12312  const Expr *Length = OASE->getLength();
12313 
12314  // If there is a lower bound that does not evaluates to zero, we are not
12315  // covering the whole dimension.
12316  if (LowerBound) {
12318  if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
12319  return false; // Can't get the integer value as a constant.
12320 
12321  llvm::APSInt ConstLowerBound = Result.Val.getInt();
12322  if (ConstLowerBound.getSExtValue())
12323  return true;
12324  }
12325 
12326  // If we don't have a length we covering the whole dimension.
12327  if (!Length)
12328  return false;
12329 
12330  // If the base is a pointer, we don't have a way to get the size of the
12331  // pointee.
12332  if (BaseQTy->isPointerType())
12333  return false;
12334 
12335  // We can only check if the length is the same as the size of the dimension
12336  // if we have a constant array.
12337  const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
12338  if (!CATy)
12339  return false;
12340 
12342  if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
12343  return false; // Can't get the integer value as a constant.
12344 
12345  llvm::APSInt ConstLength = Result.Val.getInt();
12346  return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
12347 }
12348 
12349 // Return true if it can be proven that the provided array expression (array
12350 // section or array subscript) does NOT specify a single element of the array
12351 // whose base type is \a BaseQTy.
12353  const Expr *E,
12354  QualType BaseQTy) {
12355  const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
12356 
12357  // An array subscript always refer to a single element. Also, an array section
12358  // assumes the format of an array subscript if no colon is used.
12359  if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid()))
12360  return false;
12361 
12362  assert(OASE && "Expecting array section if not an array subscript.");
12363  const Expr *Length = OASE->getLength();
12364 
12365  // If we don't have a length we have to check if the array has unitary size
12366  // for this dimension. Also, we should always expect a length if the base type
12367  // is pointer.
12368  if (!Length) {
12369  if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
12370  return ATy->getSize().getSExtValue() != 1;
12371  // We cannot assume anything.
12372  return false;
12373  }
12374 
12375  // Check if the length evaluates to 1.
12377  if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
12378  return false; // Can't get the integer value as a constant.
12379 
12380  llvm::APSInt ConstLength = Result.Val.getInt();
12381  return ConstLength.getSExtValue() != 1;
12382 }
12383 
12384 // Return the expression of the base of the mappable expression or null if it
12385 // cannot be determined and do all the necessary checks to see if the expression
12386 // is valid as a standalone mappable expression. In the process, record all the
12387 // components of the expression.
12389  Sema &SemaRef, Expr *E,
12391  OpenMPClauseKind CKind, bool NoDiagnose) {
12392  SourceLocation ELoc = E->getExprLoc();
12393  SourceRange ERange = E->getSourceRange();
12394 
12395  // The base of elements of list in a map clause have to be either:
12396  // - a reference to variable or field.
12397  // - a member expression.
12398  // - an array expression.
12399  //
12400  // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
12401  // reference to 'r'.
12402  //
12403  // If we have:
12404  //
12405  // struct SS {
12406  // Bla S;
12407  // foo() {
12408  // #pragma omp target map (S.Arr[:12]);
12409  // }
12410  // }
12411  //
12412  // We want to retrieve the member expression 'this->S';
12413 
12414  const Expr *RelevantExpr = nullptr;
12415 
12416  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2]
12417  // If a list item is an array section, it must specify contiguous storage.
12418  //
12419  // For this restriction it is sufficient that we make sure only references
12420  // to variables or fields and array expressions, and that no array sections
12421  // exist except in the rightmost expression (unless they cover the whole
12422  // dimension of the array). E.g. these would be invalid:
12423  //
12424  // r.ArrS[3:5].Arr[6:7]
12425  //
12426  // r.ArrS[3:5].x
12427  //
12428  // but these would be valid:
12429  // r.ArrS[3].Arr[6:7]
12430  //
12431  // r.ArrS[3].x
12432 
12433  bool AllowUnitySizeArraySection = true;
12434  bool AllowWholeSizeArraySection = true;
12435 
12436  while (!RelevantExpr) {
12437  E = E->IgnoreParenImpCasts();
12438 
12439  if (auto *CurE = dyn_cast<DeclRefExpr>(E)) {
12440  if (!isa<VarDecl>(CurE->getDecl()))
12441  return nullptr;
12442 
12443  RelevantExpr = CurE;
12444 
12445  // If we got a reference to a declaration, we should not expect any array
12446  // section before that.
12447  AllowUnitySizeArraySection = false;
12448  AllowWholeSizeArraySection = false;
12449 
12450  // Record the component.
12451  CurComponents.emplace_back(CurE, CurE->getDecl());
12452  } else if (auto *CurE = dyn_cast<MemberExpr>(E)) {
12453  Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts();
12454 
12455  if (isa<CXXThisExpr>(BaseE))
12456  // We found a base expression: this->Val.
12457  RelevantExpr = CurE;
12458  else
12459  E = BaseE;
12460 
12461  if (!isa<FieldDecl>(CurE->getMemberDecl())) {
12462  if (!NoDiagnose) {
12463  SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
12464  << CurE->getSourceRange();
12465  return nullptr;
12466  }
12467  if (RelevantExpr)
12468  return nullptr;
12469  continue;
12470  }
12471 
12472  auto *FD = cast<FieldDecl>(CurE->getMemberDecl());
12473 
12474  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
12475  // A bit-field cannot appear in a map clause.
12476  //
12477  if (FD->isBitField()) {
12478  if (!NoDiagnose) {
12479  SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
12480  << CurE->getSourceRange() << getOpenMPClauseName(CKind);
12481  return nullptr;
12482  }
12483  if (RelevantExpr)
12484  return nullptr;
12485  continue;
12486  }
12487 
12488  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
12489  // If the type of a list item is a reference to a type T then the type
12490  // will be considered to be T for all purposes of this clause.
12491  QualType CurType = BaseE->getType().getNonReferenceType();
12492 
12493  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
12494  // A list item cannot be a variable that is a member of a structure with
12495  // a union type.
12496  //
12497  if (CurType->isUnionType()) {
12498  if (!NoDiagnose) {
12499  SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
12500  << CurE->getSourceRange();
12501  return nullptr;
12502  }
12503  continue;
12504  }
12505 
12506  // If we got a member expression, we should not expect any array section
12507  // before that:
12508  //
12509  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
12510  // If a list item is an element of a structure, only the rightmost symbol
12511  // of the variable reference can be an array section.
12512  //
12513  AllowUnitySizeArraySection = false;
12514  AllowWholeSizeArraySection = false;
12515 
12516  // Record the component.
12517  CurComponents.emplace_back(CurE, FD);
12518  } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) {
12519  E = CurE->getBase()->IgnoreParenImpCasts();
12520 
12521  if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
12522  if (!NoDiagnose) {
12523  SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
12524  << 0 << CurE->getSourceRange();
12525  return nullptr;
12526  }
12527  continue;
12528  }
12529 
12530  // If we got an array subscript that express the whole dimension we
12531  // can have any array expressions before. If it only expressing part of
12532  // the dimension, we can only have unitary-size array expressions.
12534  E->getType()))
12535  AllowWholeSizeArraySection = false;
12536 
12537  if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
12539  if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) {
12540  if (!Result.Val.getInt().isNullValue()) {
12541  SemaRef.Diag(CurE->getIdx()->getExprLoc(),
12542  diag::err_omp_invalid_map_this_expr);
12543  SemaRef.Diag(CurE->getIdx()->getExprLoc(),
12544  diag::note_omp_invalid_subscript_on_this_ptr_map);
12545  }
12546  }
12547  RelevantExpr = TE;
12548  }
12549 
12550  // Record the component - we don't have any declaration associated.
12551  CurComponents.emplace_back(CurE, nullptr);
12552  } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) {
12553  assert(!NoDiagnose && "Array sections cannot be implicitly mapped.");
12554  E = CurE->getBase()->IgnoreParenImpCasts();
12555 
12556  QualType CurType =
12558 
12559  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
12560  // If the type of a list item is a reference to a type T then the type
12561  // will be considered to be T for all purposes of this clause.
12562  if (CurType->isReferenceType())
12563  CurType = CurType->getPointeeType();
12564 
12565  bool IsPointer = CurType->isAnyPointerType();
12566 
12567  if (!IsPointer && !CurType->isArrayType()) {
12568  SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
12569  << 0 << CurE->getSourceRange();
12570  return nullptr;
12571  }
12572 
12573  bool NotWhole =
12574  checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType);
12575  bool NotUnity =
12576  checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType);
12577 
12578  if (AllowWholeSizeArraySection) {
12579  // Any array section is currently allowed. Allowing a whole size array
12580  // section implies allowing a unity array section as well.
12581  //
12582  // If this array section refers to the whole dimension we can still
12583  // accept other array sections before this one, except if the base is a
12584  // pointer. Otherwise, only unitary sections are accepted.
12585  if (NotWhole || IsPointer)
12586  AllowWholeSizeArraySection = false;
12587  } else if (AllowUnitySizeArraySection && NotUnity) {
12588  // A unity or whole array section is not allowed and that is not
12589  // compatible with the properties of the current array section.
12590  SemaRef.Diag(
12591  ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
12592  << CurE->getSourceRange();
12593  return nullptr;
12594  }
12595 
12596  if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
12597  Expr::EvalResult ResultR;
12598  Expr::EvalResult ResultL;
12599  if (CurE->getLength()->EvaluateAsInt(ResultR,
12600  SemaRef.getASTContext())) {
12601  if (!ResultR.Val.getInt().isOneValue()) {
12602  SemaRef.Diag(CurE->getLength()->getExprLoc(),
12603  diag::err_omp_invalid_map_this_expr);
12604  SemaRef.Diag(CurE->getLength()->getExprLoc(),
12605  diag::note_omp_invalid_length_on_this_ptr_mapping);
12606  }
12607  }
12608  if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt(
12609  ResultL, SemaRef.getASTContext())) {
12610  if (!ResultL.Val.getInt().isNullValue()) {
12611  SemaRef.Diag(CurE->getLowerBound()->getExprLoc(),
12612  diag::err_omp_invalid_map_this_expr);
12613  SemaRef.Diag(CurE->getLowerBound()->getExprLoc(),
12614  diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
12615  }
12616  }
12617  RelevantExpr = TE;
12618  }
12619 
12620  // Record the component - we don't have any declaration associated.
12621  CurComponents.emplace_back(CurE, nullptr);
12622  } else {
12623  if (!NoDiagnose) {
12624  // If nothing else worked, this is not a valid map clause expression.
12625  SemaRef.Diag(
12626  ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
12627  << ERange;
12628  }
12629  return nullptr;
12630  }
12631  }
12632 
12633  return RelevantExpr;
12634 }
12635 
12636 // Return true if expression E associated with value VD has conflicts with other
12637 // map information.
12638 static bool checkMapConflicts(
12639  Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
12640  bool CurrentRegionOnly,
12642  OpenMPClauseKind CKind) {
12643  assert(VD && E);
12644  SourceLocation ELoc = E->getExprLoc();
12645  SourceRange ERange = E->getSourceRange();
12646 
12647  // In order to easily check the conflicts we need to match each component of
12648  // the expression under test with the components of the expressions that are
12649  // already in the stack.
12650 
12651  assert(!CurComponents.empty() && "Map clause expression with no components!");
12652  assert(CurComponents.back().getAssociatedDeclaration() == VD &&
12653  "Map clause expression with unexpected base!");
12654 
12655  // Variables to help detecting enclosing problems in data environment nests.
12656  bool IsEnclosedByDataEnvironmentExpr = false;
12657  const Expr *EnclosingExpr = nullptr;
12658 
12659  bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
12660  VD, CurrentRegionOnly,
12661  [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
12662  ERange, CKind, &EnclosingExpr,
12664  StackComponents,
12665  OpenMPClauseKind) {
12666  assert(!StackComponents.empty() &&
12667  "Map clause expression with no components!");
12668  assert(StackComponents.back().getAssociatedDeclaration() == VD &&
12669  "Map clause expression with unexpected base!");
12670  (void)VD;
12671 
12672  // The whole expression in the stack.
12673  const Expr *RE = StackComponents.front().getAssociatedExpression();
12674 
12675  // Expressions must start from the same base. Here we detect at which
12676  // point both expressions diverge from each other and see if we can
12677  // detect if the memory referred to both expressions is contiguous and
12678  // do not overlap.
12679  auto CI = CurComponents.rbegin();
12680  auto CE = CurComponents.rend();
12681  auto SI = StackComponents.rbegin();
12682  auto SE = StackComponents.rend();
12683  for (; CI != CE && SI != SE; ++CI, ++SI) {
12684 
12685  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
12686  // At most one list item can be an array item derived from a given
12687  // variable in map clauses of the same construct.
12688  if (CurrentRegionOnly &&
12689  (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
12690  isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) &&
12691  (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
12692  isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) {
12693  SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
12694  diag::err_omp_multiple_array_items_in_map_clause)
12695  << CI->getAssociatedExpression()->getSourceRange();
12696  SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
12697  diag::note_used_here)
12698  << SI->getAssociatedExpression()->getSourceRange();
12699  return true;
12700  }
12701 
12702  // Do both expressions have the same kind?
12703  if (CI->getAssociatedExpression()->getStmtClass() !=
12704  SI->getAssociatedExpression()->getStmtClass())
12705  break;
12706 
12707  // Are we dealing with different variables/fields?
12708  if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
12709  break;
12710  }
12711  // Check if the extra components of the expressions in the enclosing
12712  // data environment are redundant for the current base declaration.
12713  // If they are, the maps completely overlap, which is legal.
12714  for (; SI != SE; ++SI) {
12715  QualType Type;
12716  if (const auto *ASE =
12717  dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
12718  Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
12719  } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
12720  SI->getAssociatedExpression())) {
12721  const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
12722  Type =
12724  }
12725  if (Type.isNull() || Type->isAnyPointerType() ||
12727  SemaRef, SI->getAssociatedExpression(), Type))
12728  break;
12729  }
12730 
12731  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
12732  // List items of map clauses in the same construct must not share
12733  // original storage.
12734  //
12735  // If the expressions are exactly the same or one is a subset of the
12736  // other, it means they are sharing storage.
12737  if (CI == CE && SI == SE) {
12738  if (CurrentRegionOnly) {
12739  if (CKind == OMPC_map) {
12740  SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
12741  } else {
12742  assert(CKind == OMPC_to || CKind == OMPC_from);
12743  SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
12744  << ERange;
12745  }
12746  SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
12747  << RE->getSourceRange();
12748  return true;
12749  }
12750  // If we find the same expression in the enclosing data environment,
12751  // that is legal.
12752  IsEnclosedByDataEnvironmentExpr = true;
12753  return false;
12754  }
12755 
12756  QualType DerivedType =
12757  std::prev(CI)->getAssociatedDeclaration()->getType();
12758  SourceLocation DerivedLoc =
12759  std::prev(CI)->getAssociatedExpression()->getExprLoc();
12760 
12761  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
12762  // If the type of a list item is a reference to a type T then the type
12763  // will be considered to be T for all purposes of this clause.
12764  DerivedType = DerivedType.getNonReferenceType();
12765 
12766  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
12767  // A variable for which the type is pointer and an array section
12768  // derived from that variable must not appear as list items of map
12769  // clauses of the same construct.
12770  //
12771  // Also, cover one of the cases in:
12772  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
12773  // If any part of the original storage of a list item has corresponding
12774  // storage in the device data environment, all of the original storage
12775  // must have corresponding storage in the device data environment.
12776  //
12777  if (DerivedType->isAnyPointerType()) {
12778  if (CI == CE || SI == SE) {
12779  SemaRef.Diag(
12780  DerivedLoc,
12781  diag::err_omp_pointer_mapped_along_with_derived_section)
12782  << DerivedLoc;
12783  SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
12784  << RE->getSourceRange();
12785  return true;
12786  }
12787  if (CI->getAssociatedExpression()->getStmtClass() !=
12788  SI->getAssociatedExpression()->getStmtClass() ||
12789  CI->getAssociatedDeclaration()->getCanonicalDecl() ==
12790  SI->getAssociatedDeclaration()->getCanonicalDecl()) {
12791  assert(CI != CE && SI != SE);
12792  SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
12793  << DerivedLoc;
12794  SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
12795  << RE->getSourceRange();
12796  return true;
12797  }
12798  }
12799 
12800  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
12801  // List items of map clauses in the same construct must not share
12802  // original storage.
12803  //
12804  // An expression is a subset of the other.
12805  if (CurrentRegionOnly && (CI == CE || SI == SE)) {
12806  if (CKind == OMPC_map) {
12807  if (CI != CE || SI != SE) {
12808  // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
12809  // a pointer.
12810  auto Begin =
12811  CI != CE ? CurComponents.begin() : StackComponents.begin();
12812  auto End = CI != CE ? CurComponents.end() : StackComponents.end();
12813  auto It = Begin;
12814  while (It != End && !It->getAssociatedDeclaration())
12815  std::advance(It, 1);
12816  assert(It != End &&
12817  "Expected at least one component with the declaration.");
12818  if (It != Begin && It->getAssociatedDeclaration()
12819  ->getType()
12820  .getCanonicalType()
12821  ->isAnyPointerType()) {
12822  IsEnclosedByDataEnvironmentExpr = false;
12823  EnclosingExpr = nullptr;
12824  return false;
12825  }
12826  }
12827  SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
12828  } else {
12829  assert(CKind == OMPC_to || CKind == OMPC_from);
12830  SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
12831  << ERange;
12832  }
12833  SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
12834  << RE->getSourceRange();
12835  return true;
12836  }
12837 
12838  // The current expression uses the same base as other expression in the
12839  // data environment but does not contain it completely.
12840  if (!CurrentRegionOnly && SI != SE)
12841  EnclosingExpr = RE;
12842 
12843  // The current expression is a subset of the expression in the data
12844  // environment.
12845  IsEnclosedByDataEnvironmentExpr |=
12846  (!CurrentRegionOnly && CI != CE && SI == SE);
12847 
12848  return false;
12849  });
12850 
12851  if (CurrentRegionOnly)
12852  return FoundError;
12853 
12854  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
12855  // If any part of the original storage of a list item has corresponding
12856  // storage in the device data environment, all of the original storage must
12857  // have corresponding storage in the device data environment.
12858  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
12859  // If a list item is an element of a structure, and a different element of
12860  // the structure has a corresponding list item in the device data environment
12861  // prior to a task encountering the construct associated with the map clause,
12862  // then the list item must also have a corresponding list item in the device
12863  // data environment prior to the task encountering the construct.
12864  //
12865  if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
12866  SemaRef.Diag(ELoc,
12867  diag::err_omp_original_storage_is_shared_and_does_not_contain)
12868  << ERange;
12869  SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
12870  << EnclosingExpr->getSourceRange();
12871  return true;
12872  }
12873 
12874  return FoundError;
12875 }
12876 
12877 namespace {
12878 // Utility struct that gathers all the related lists associated with a mappable
12879 // expression.
12880 struct MappableVarListInfo {
12881  // The list of expressions.
12882  ArrayRef<Expr *> VarList;
12883  // The list of processed expressions.
12884  SmallVector<Expr *, 16> ProcessedVarList;
12885  // The mappble components for each expression.
12887  // The base declaration of the variable.
12888  SmallVector<ValueDecl *, 16> VarBaseDeclarations;
12889 
12890  MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
12891  // We have a list of components and base declarations for each entry in the
12892  // variable list.
12893  VarComponents.reserve(VarList.size());
12894  VarBaseDeclarations.reserve(VarList.size());
12895  }
12896 };
12897 }
12898 
12899 // Check the validity of the provided variable list for the provided clause kind
12900 // \a CKind. In the check process the valid expressions, and mappable expression
12901 // components and variables are extracted and used to fill \a Vars,
12902 // \a ClauseComponents, and \a ClauseBaseDeclarations. \a MapType and
12903 // \a IsMapTypeImplicit are expected to be valid if the clause kind is 'map'.
12904 static void
12905 checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS,
12906  OpenMPClauseKind CKind, MappableVarListInfo &MVLI,
12907  SourceLocation StartLoc,
12909  bool IsMapTypeImplicit = false) {
12910  // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
12911  assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
12912  "Unexpected clause kind with mappable expressions!");
12913 
12914  // Keep track of the mappable components and base declarations in this clause.
12915  // Each entry in the list is going to have a list of components associated. We
12916  // record each set of the components so that we can build the clause later on.
12917  // In the end we should have the same amount of declarations and component
12918  // lists.
12919 
12920  for (Expr *RE : MVLI.VarList) {
12921  assert(RE && "Null expr in omp to/from/map clause");
12922  SourceLocation ELoc = RE->getExprLoc();
12923 
12924  const Expr *VE = RE->IgnoreParenLValueCasts();
12925 
12926  if (VE->isValueDependent() || VE->isTypeDependent() ||
12927  VE->isInstantiationDependent() ||
12929  // We can only analyze this information once the missing information is
12930  // resolved.
12931  MVLI.ProcessedVarList.push_back(RE);
12932  continue;
12933  }
12934 
12935  Expr *SimpleExpr = RE->IgnoreParenCasts();
12936 
12937  if (!RE->IgnoreParenImpCasts()->isLValue()) {
12938  SemaRef.Diag(ELoc,
12939  diag::err_omp_expected_named_var_member_or_array_expression)
12940  << RE->getSourceRange();
12941  continue;
12942  }
12943 
12945  ValueDecl *CurDeclaration = nullptr;
12946 
12947  // Obtain the array or member expression bases if required. Also, fill the
12948  // components array with all the components identified in the process.
12949  const Expr *BE = checkMapClauseExpressionBase(
12950  SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false);
12951  if (!BE)
12952  continue;
12953 
12954  assert(!CurComponents.empty() &&
12955  "Invalid mappable expression information.");
12956 
12957  if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
12958  // Add store "this" pointer to class in DSAStackTy for future checking
12959  DSAS->addMappedClassesQualTypes(TE->getType());
12960  // Skip restriction checking for variable or field declarations
12961  MVLI.ProcessedVarList.push_back(RE);
12962  MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
12963  MVLI.VarComponents.back().append(CurComponents.begin(),
12964  CurComponents.end());
12965  MVLI.VarBaseDeclarations.push_back(nullptr);
12966  continue;
12967  }
12968 
12969  // For the following checks, we rely on the base declaration which is
12970  // expected to be associated with the last component. The declaration is
12971  // expected to be a variable or a field (if 'this' is being mapped).
12972  CurDeclaration = CurComponents.back().getAssociatedDeclaration();
12973  assert(CurDeclaration && "Null decl on map clause.");
12974  assert(
12975  CurDeclaration->isCanonicalDecl() &&
12976  "Expecting components to have associated only canonical declarations.");
12977 
12978  auto *VD = dyn_cast<VarDecl>(CurDeclaration);
12979  const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
12980 
12981  assert((VD || FD) && "Only variables or fields are expected here!");
12982  (void)FD;
12983 
12984  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
12985  // threadprivate variables cannot appear in a map clause.
12986  // OpenMP 4.5 [2.10.5, target update Construct]
12987  // threadprivate variables cannot appear in a from clause.
12988  if (VD && DSAS->isThreadPrivate(VD)) {
12989  DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
12990  SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
12991  << getOpenMPClauseName(CKind);
12992  reportOriginalDsa(SemaRef, DSAS, VD, DVar);
12993  continue;
12994  }
12995 
12996  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
12997  // A list item cannot appear in both a map clause and a data-sharing
12998  // attribute clause on the same construct.
12999 
13000  // Check conflicts with other map clause expressions. We check the conflicts
13001  // with the current construct separately from the enclosing data
13002  // environment, because the restrictions are different. We only have to
13003  // check conflicts across regions for the map clauses.
13004  if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
13005  /*CurrentRegionOnly=*/true, CurComponents, CKind))
13006  break;
13007  if (CKind == OMPC_map &&
13008  checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
13009  /*CurrentRegionOnly=*/false, CurComponents, CKind))
13010  break;
13011 
13012  // OpenMP 4.5 [2.10.5, target update Construct]
13013  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
13014  // If the type of a list item is a reference to a type T then the type will
13015  // be considered to be T for all purposes of this clause.
13016  auto I = llvm::find_if(
13017  CurComponents,
13019  return MC.getAssociatedDeclaration();
13020  });
13021  assert(I != CurComponents.end() && "Null decl on map clause.");
13022  QualType Type =
13023  I->getAssociatedDeclaration()->getType().getNonReferenceType();
13024 
13025  // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
13026  // A list item in a to or from clause must have a mappable type.
13027  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
13028  // A list item must have a mappable type.
13029  if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
13030  DSAS, Type))
13031  continue;
13032 
13033  if (CKind == OMPC_map) {
13034  // target enter data
13035  // OpenMP [2.10.2, Restrictions, p. 99]
13036  // A map-type must be specified in all map clauses and must be either
13037  // to or alloc.
13038  OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
13039  if (DKind == OMPD_target_enter_data &&
13040  !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
13041  SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
13042  << (IsMapTypeImplicit ? 1 : 0)
13043  << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
13044  << getOpenMPDirectiveName(DKind);
13045  continue;
13046  }
13047 
13048  // target exit_data
13049  // OpenMP [2.10.3, Restrictions, p. 102]
13050  // A map-type must be specified in all map clauses and must be either
13051  // from, release, or delete.
13052  if (DKind == OMPD_target_exit_data &&
13053  !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
13054  MapType == OMPC_MAP_delete)) {
13055  SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
13056  << (IsMapTypeImplicit ? 1 : 0)
13057  << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
13058  << getOpenMPDirectiveName(DKind);
13059  continue;
13060  }
13061 
13062  // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
13063  // A list item cannot appear in both a map clause and a data-sharing
13064  // attribute clause on the same construct
13065  if (VD && isOpenMPTargetExecutionDirective(DKind)) {
13066  DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
13067  if (isOpenMPPrivate(DVar.CKind)) {
13068  SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
13069  << getOpenMPClauseName(DVar.CKind)
13070  << getOpenMPClauseName(OMPC_map)
13071  << getOpenMPDirectiveName(DSAS->getCurrentDirective());
13072  reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
13073  continue;
13074  }
13075  }
13076  }
13077 
13078  // Save the current expression.
13079  MVLI.ProcessedVarList.push_back(RE);
13080 
13081  // Store the components in the stack so that they can be used to check
13082  // against other clauses later on.
13083  DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
13084  /*WhereFoundClauseKind=*/OMPC_map);
13085 
13086  // Save the components and declaration to create the clause. For purposes of
13087  // the clause creation, any component list that has has base 'this' uses
13088  // null as base declaration.
13089  MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
13090  MVLI.VarComponents.back().append(CurComponents.begin(),
13091  CurComponents.end());
13092  MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
13093  : CurDeclaration);
13094  }
13095 }
13096 
13097 OMPClause *
13099  ArrayRef<SourceLocation> MapTypeModifiersLoc,
13100  OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
13102  ArrayRef<Expr *> VarList, SourceLocation StartLoc,
13103  SourceLocation LParenLoc, SourceLocation EndLoc) {
13104  MappableVarListInfo MVLI(VarList);
13105  checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, StartLoc,
13106  MapType, IsMapTypeImplicit);
13107 
13111 
13112  // Process map-type-modifiers, flag errors for duplicate modifiers.
13113  unsigned Count = 0;
13114  for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
13115  if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
13116  llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) {
13117  Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
13118  continue;
13119  }
13120  assert(Count < OMPMapClause::NumberOfModifiers &&
13121  "Modifiers exceed the allowed number of map type modifiers");
13122  Modifiers[Count] = MapTypeModifiers[I];
13123  ModifiersLoc[Count] = MapTypeModifiersLoc[I];
13124  ++Count;
13125  }
13126 
13127  // We need to produce a map clause even if we don't have variables so that
13128  // other diagnostics related with non-existing map clauses are accurate.
13129  return OMPMapClause::Create(Context, StartLoc, LParenLoc, EndLoc,
13130  MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
13131  MVLI.VarComponents, Modifiers, ModifiersLoc,
13132  MapType, IsMapTypeImplicit, MapLoc);
13133 }
13134 
13137  assert(ParsedType.isUsable());
13138 
13139  QualType ReductionType = GetTypeFromParser(ParsedType.get());
13140  if (ReductionType.isNull())
13141  return QualType();
13142 
13143  // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
13144  // A type name in a declare reduction directive cannot be a function type, an
13145  // array type, a reference type, or a type qualified with const, volatile or
13146  // restrict.
13147  if (ReductionType.hasQualifiers()) {
13148  Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
13149  return QualType();
13150  }
13151 
13152  if (ReductionType->isFunctionType()) {
13153  Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
13154  return QualType();
13155  }
13156  if (ReductionType->isReferenceType()) {
13157  Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
13158  return QualType();
13159  }
13160  if (ReductionType->isArrayType()) {
13161  Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
13162  return QualType();
13163  }
13164  return ReductionType;
13165 }
13166 
13168  Scope *S, DeclContext *DC, DeclarationName Name,
13169  ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
13170  AccessSpecifier AS, Decl *PrevDeclInScope) {
13171  SmallVector<Decl *, 8> Decls;
13172  Decls.reserve(ReductionTypes.size());
13173 
13174  LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
13175  forRedeclarationInCurContext());
13176  // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
13177  // A reduction-identifier may not be re-declared in the current scope for the
13178  // same type or for a type that is compatible according to the base language
13179  // rules.
13180  llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
13181  OMPDeclareReductionDecl *PrevDRD = nullptr;
13182  bool InCompoundScope = true;
13183  if (S != nullptr) {
13184  // Find previous declaration with the same name not referenced in other
13185  // declarations.
13186  FunctionScopeInfo *ParentFn = getEnclosingFunction();
13187  InCompoundScope =
13188  (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
13189  LookupName(Lookup, S);
13190  FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
13191  /*AllowInlineNamespace=*/false);
13192  llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
13194  while (Filter.hasNext()) {
13195  auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
13196  if (InCompoundScope) {
13197  auto I = UsedAsPrevious.find(PrevDecl);
13198  if (I == UsedAsPrevious.end())
13199  UsedAsPrevious[PrevDecl] = false;
13200  if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
13201  UsedAsPrevious[D] = true;
13202  }
13203  PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
13204  PrevDecl->getLocation();
13205  }
13206  Filter.done();
13207  if (InCompoundScope) {
13208  for (const auto &PrevData : UsedAsPrevious) {
13209  if (!PrevData.second) {
13210  PrevDRD = PrevData.first;
13211  break;
13212  }
13213  }
13214  }
13215  } else if (PrevDeclInScope != nullptr) {
13216  auto *PrevDRDInScope = PrevDRD =
13217  cast<OMPDeclareReductionDecl>(PrevDeclInScope);
13218  do {
13219  PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
13220  PrevDRDInScope->getLocation();
13221  PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
13222  } while (PrevDRDInScope != nullptr);
13223  }
13224  for (const auto &TyData : ReductionTypes) {
13225  const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
13226  bool Invalid = false;
13227  if (I != PreviousRedeclTypes.end()) {
13228  Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
13229  << TyData.first;
13230  Diag(I->second, diag::note_previous_definition);
13231  Invalid = true;
13232  }
13233  PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
13234  auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
13235  Name, TyData.first, PrevDRD);
13236  DC->addDecl(DRD);
13237  DRD->setAccess(AS);
13238  Decls.push_back(DRD);
13239  if (Invalid)
13240  DRD->setInvalidDecl();
13241  else
13242  PrevDRD = DRD;
13243  }
13244 
13245  return DeclGroupPtrTy::make(
13246  DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
13247 }
13248 
13250  auto *DRD = cast<OMPDeclareReductionDecl>(D);
13251 
13252  // Enter new function scope.
13253  PushFunctionScope();
13254  setFunctionHasBranchProtectedScope();
13255  getCurFunction()->setHasOMPDeclareReductionCombiner();
13256 
13257  if (S != nullptr)
13258  PushDeclContext(S, DRD);
13259  else
13260  CurContext = DRD;
13261 
13262  PushExpressionEvaluationContext(
13263  ExpressionEvaluationContext::PotentiallyEvaluated);
13264 
13265  QualType ReductionType = DRD->getType();
13266  // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
13267  // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
13268  // uses semantics of argument handles by value, but it should be passed by
13269  // reference. C lang does not support references, so pass all parameters as
13270  // pointers.
13271  // Create 'T omp_in;' variable.
13272  VarDecl *OmpInParm =
13273  buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
13274  // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
13275  // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
13276  // uses semantics of argument handles by value, but it should be passed by
13277  // reference. C lang does not support references, so pass all parameters as
13278  // pointers.
13279  // Create 'T omp_out;' variable.
13280  VarDecl *OmpOutParm =
13281  buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
13282  if (S != nullptr) {
13283  PushOnScopeChains(OmpInParm, S);
13284  PushOnScopeChains(OmpOutParm, S);
13285  } else {
13286  DRD->addDecl(OmpInParm);
13287  DRD->addDecl(OmpOutParm);
13288  }
13289  Expr *InE =
13290  ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
13291  Expr *OutE =
13292  ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
13293  DRD->setCombinerData(InE, OutE);
13294 }
13295 
13297  auto *DRD = cast<OMPDeclareReductionDecl>(D);
13298  DiscardCleanupsInEvaluationContext();
13299  PopExpressionEvaluationContext();
13300 
13301  PopDeclContext();
13302  PopFunctionScopeInfo();
13303 
13304  if (Combiner != nullptr)
13305  DRD->setCombiner(Combiner);
13306  else
13307  DRD->setInvalidDecl();
13308 }
13309 
13311  auto *DRD = cast<OMPDeclareReductionDecl>(D);
13312 
13313  // Enter new function scope.
13314  PushFunctionScope();
13315  setFunctionHasBranchProtectedScope();
13316 
13317  if (S != nullptr)
13318  PushDeclContext(S, DRD);
13319  else
13320  CurContext = DRD;
13321 
13322  PushExpressionEvaluationContext(
13323  ExpressionEvaluationContext::PotentiallyEvaluated);
13324 
13325  QualType ReductionType = DRD->getType();
13326  // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
13327  // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
13328  // uses semantics of argument handles by value, but it should be passed by
13329  // reference. C lang does not support references, so pass all parameters as
13330  // pointers.
13331  // Create 'T omp_priv;' variable.
13332  VarDecl *OmpPrivParm =
13333  buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
13334  // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
13335  // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
13336  // uses semantics of argument handles by value, but it should be passed by
13337  // reference. C lang does not support references, so pass all parameters as
13338  // pointers.
13339  // Create 'T omp_orig;' variable.
13340  VarDecl *OmpOrigParm =
13341  buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
13342  if (S != nullptr) {
13343  PushOnScopeChains(OmpPrivParm, S);
13344  PushOnScopeChains(OmpOrigParm, S);
13345  } else {
13346  DRD->addDecl(OmpPrivParm);
13347  DRD->addDecl(OmpOrigParm);
13348  }
13349  Expr *OrigE =
13350  ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
13351  Expr *PrivE =
13352  ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
13353  DRD->setInitializerData(OrigE, PrivE);
13354  return OmpPrivParm;
13355 }
13356 
13358  VarDecl *OmpPrivParm) {
13359  auto *DRD = cast<OMPDeclareReductionDecl>(D);
13360  DiscardCleanupsInEvaluationContext();
13361  PopExpressionEvaluationContext();
13362 
13363  PopDeclContext();
13364  PopFunctionScopeInfo();
13365 
13366  if (Initializer != nullptr) {
13367  DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
13368  } else if (OmpPrivParm->hasInit()) {
13369  DRD->setInitializer(OmpPrivParm->getInit(),
13370  OmpPrivParm->isDirectInit()
13373  } else {
13374  DRD->setInvalidDecl();
13375  }
13376 }
13377 
13379  Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
13380  for (Decl *D : DeclReductions.get()) {
13381  if (IsValid) {
13382  if (S)
13383  PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
13384  /*AddToContext=*/false);
13385  } else {
13386  D->setInvalidDecl();
13387  }
13388  }
13389  return DeclReductions;
13390 }
13391 
13393  SourceLocation StartLoc,
13394  SourceLocation LParenLoc,
13395  SourceLocation EndLoc) {
13396  Expr *ValExpr = NumTeams;
13397  Stmt *HelperValStmt = nullptr;
13398 
13399  // OpenMP [teams Constrcut, Restrictions]
13400  // The num_teams expression must evaluate to a positive integer value.
13401  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
13402  /*StrictlyPositive=*/true))
13403  return nullptr;
13404 
13405  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
13406  OpenMPDirectiveKind CaptureRegion =
13407  getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams);
13408  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
13409  ValExpr = MakeFullExpr(ValExpr).get();
13410  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13411  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
13412  HelperValStmt = buildPreInits(Context, Captures);
13413  }
13414 
13415  return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
13416  StartLoc, LParenLoc, EndLoc);
13417 }
13418 
13420  SourceLocation StartLoc,
13421  SourceLocation LParenLoc,
13422  SourceLocation EndLoc) {
13423  Expr *ValExpr = ThreadLimit;
13424  Stmt *HelperValStmt = nullptr;
13425 
13426  // OpenMP [teams Constrcut, Restrictions]
13427  // The thread_limit expression must evaluate to a positive integer value.
13428  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
13429  /*StrictlyPositive=*/true))
13430  return nullptr;
13431 
13432  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
13433  OpenMPDirectiveKind CaptureRegion =
13434  getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit);
13435  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
13436  ValExpr = MakeFullExpr(ValExpr).get();
13437  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13438  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
13439  HelperValStmt = buildPreInits(Context, Captures);
13440  }
13441 
13442  return new (Context) OMPThreadLimitClause(
13443  ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
13444 }
13445 
13447  SourceLocation StartLoc,
13448  SourceLocation LParenLoc,
13449  SourceLocation EndLoc) {
13450  Expr *ValExpr = Priority;
13451 
13452  // OpenMP [2.9.1, task Constrcut]
13453  // The priority-value is a non-negative numerical scalar expression.
13454  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_priority,
13455  /*StrictlyPositive=*/false))
13456  return nullptr;
13457 
13458  return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc);
13459 }
13460 
13462  SourceLocation StartLoc,
13463  SourceLocation LParenLoc,
13464  SourceLocation EndLoc) {
13465  Expr *ValExpr = Grainsize;
13466 
13467  // OpenMP [2.9.2, taskloop Constrcut]
13468  // The parameter of the grainsize clause must be a positive integer
13469  // expression.
13470  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize,
13471  /*StrictlyPositive=*/true))
13472  return nullptr;
13473 
13474  return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc);
13475 }
13476 
13478  SourceLocation StartLoc,
13479  SourceLocation LParenLoc,
13480  SourceLocation EndLoc) {
13481  Expr *ValExpr = NumTasks;
13482 
13483  // OpenMP [2.9.2, taskloop Constrcut]
13484  // The parameter of the num_tasks clause must be a positive integer
13485  // expression.
13486  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks,
13487  /*StrictlyPositive=*/true))
13488  return nullptr;
13489 
13490  return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc);
13491 }
13492 
13494  SourceLocation LParenLoc,
13495  SourceLocation EndLoc) {
13496  // OpenMP [2.13.2, critical construct, Description]
13497  // ... where hint-expression is an integer constant expression that evaluates
13498  // to a valid lock hint.
13499  ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
13500  if (HintExpr.isInvalid())
13501  return nullptr;
13502  return new (Context)
13503  OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
13504 }
13505 
13507  OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
13508  SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
13509  SourceLocation EndLoc) {
13510  if (Kind == OMPC_DIST_SCHEDULE_unknown) {
13511  std::string Values;
13512  Values += "'";
13513  Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
13514  Values += "'";
13515  Diag(KindLoc, diag::err_omp_unexpected_clause_value)
13516  << Values << getOpenMPClauseName(OMPC_dist_schedule);
13517  return nullptr;
13518  }
13519  Expr *ValExpr = ChunkSize;
13520  Stmt *HelperValStmt = nullptr;
13521  if (ChunkSize) {
13522  if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
13523  !ChunkSize->isInstantiationDependent() &&
13524  !ChunkSize->containsUnexpandedParameterPack()) {
13525  SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
13526  ExprResult Val =
13527  PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
13528  if (Val.isInvalid())
13529  return nullptr;
13530 
13531  ValExpr = Val.get();
13532 
13533  // OpenMP [2.7.1, Restrictions]
13534  // chunk_size must be a loop invariant integer expression with a positive
13535  // value.
13536  llvm::APSInt Result;
13537  if (ValExpr->isIntegerConstantExpr(Result, Context)) {
13538  if (Result.isSigned() && !Result.isStrictlyPositive()) {
13539  Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
13540  << "dist_schedule" << ChunkSize->getSourceRange();
13541  return nullptr;
13542  }
13544  DSAStack->getCurrentDirective(), OMPC_dist_schedule) !=
13545  OMPD_unknown &&
13546  !CurContext->isDependentContext()) {
13547  ValExpr = MakeFullExpr(ValExpr).get();
13548  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13549  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
13550  HelperValStmt = buildPreInits(Context, Captures);
13551  }
13552  }
13553  }
13554 
13555  return new (Context)
13556  OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
13557  Kind, ValExpr, HelperValStmt);
13558 }
13559 
13562  SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
13563  SourceLocation KindLoc, SourceLocation EndLoc) {
13564  // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)'
13565  if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) {
13566  std::string Value;
13567  SourceLocation Loc;
13568  Value += "'";
13569  if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
13570  Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
13571  OMPC_DEFAULTMAP_MODIFIER_tofrom);
13572  Loc = MLoc;
13573  } else {
13574  Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
13575  OMPC_DEFAULTMAP_scalar);
13576  Loc = KindLoc;
13577  }
13578  Value += "'";
13579  Diag(Loc, diag::err_omp_unexpected_clause_value)
13580  << Value << getOpenMPClauseName(OMPC_defaultmap);
13581  return nullptr;
13582  }
13583  DSAStack->setDefaultDMAToFromScalar(StartLoc);
13584 
13585  return new (Context)
13586  OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
13587 }
13588 
13590  DeclContext *CurLexicalContext = getCurLexicalContext();
13591  if (!CurLexicalContext->isFileContext() &&
13592  !CurLexicalContext->isExternCContext() &&
13593  !CurLexicalContext->isExternCXXContext() &&
13594  !isa<CXXRecordDecl>(CurLexicalContext) &&
13595  !isa<ClassTemplateDecl>(CurLexicalContext) &&
13596  !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
13597  !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
13598  Diag(Loc, diag::err_omp_region_not_file_context);
13599  return false;
13600  }
13601  ++DeclareTargetNestingLevel;
13602  return true;
13603 }
13604 
13606  assert(DeclareTargetNestingLevel > 0 &&
13607  "Unexpected ActOnFinishOpenMPDeclareTargetDirective");
13608  --DeclareTargetNestingLevel;
13609 }
13610 
13612  CXXScopeSpec &ScopeSpec,
13613  const DeclarationNameInfo &Id,
13614  OMPDeclareTargetDeclAttr::MapTypeTy MT,
13615  NamedDeclSetType &SameDirectiveDecls) {
13616  LookupResult Lookup(*this, Id, LookupOrdinaryName);
13617  LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
13618 
13619  if (Lookup.isAmbiguous())
13620  return;
13621  Lookup.suppressDiagnostics();
13622 
13623  if (!Lookup.isSingleResult()) {
13624  if (TypoCorrection Corrected =
13625  CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr,
13626  llvm::make_unique<VarOrFuncDeclFilterCCC>(*this),
13627  CTK_ErrorRecovery)) {
13628  diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
13629  << Id.getName());
13630  checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
13631  return;
13632  }
13633 
13634  Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
13635  return;
13636  }
13637 
13638  NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
13639  if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
13640  isa<FunctionTemplateDecl>(ND)) {
13641  if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl())))
13642  Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName();
13644  OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
13645  cast<ValueDecl>(ND));
13646  if (!Res) {
13647  auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT);
13648  ND->addAttr(A);
13649  if (ASTMutationListener *ML = Context.getASTMutationListener())
13650  ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
13651  checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Id.getLoc());
13652  } else if (*Res != MT) {
13653  Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link)
13654  << Id.getName();
13655  }
13656  } else {
13657  Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
13658  }
13659 }
13660 
13662  Sema &SemaRef, Decl *D) {
13663  if (!D || !isa<VarDecl>(D))
13664  return;
13665  auto *VD = cast<VarDecl>(D);
13666  if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
13667  return;
13668  SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
13669  SemaRef.Diag(SL, diag::note_used_here) << SR;
13670 }
13671 
13673  Sema &SemaRef, DSAStackTy *Stack,
13674  ValueDecl *VD) {
13675  return VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
13676  checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
13677  /*FullCheck=*/false);
13678 }
13679 
13681  SourceLocation IdLoc) {
13682  if (!D || D->isInvalidDecl())
13683  return;
13684  SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
13685  SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
13686  if (auto *VD = dyn_cast<VarDecl>(D)) {
13687  // Only global variables can be marked as declare target.
13688  if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
13689  !VD->isStaticDataMember())
13690  return;
13691  // 2.10.6: threadprivate variable cannot appear in a declare target
13692  // directive.
13693  if (DSAStack->isThreadPrivate(VD)) {
13694  Diag(SL, diag::err_omp_threadprivate_in_target);
13695  reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false));
13696  return;
13697  }
13698  }
13699  if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
13700  D = FTD->getTemplatedDecl();
13701  if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
13703  OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
13704  if (Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
13705  assert(IdLoc.isValid() && "Source location is expected");
13706  Diag(IdLoc, diag::err_omp_function_in_link_clause);
13707  Diag(FD->getLocation(), diag::note_defined_here) << FD;
13708  return;
13709  }
13710  }
13711  if (auto *VD = dyn_cast<ValueDecl>(D)) {
13712  // Problem if any with var declared with incomplete type will be reported
13713  // as normal, so no need to check it here.
13714  if ((E || !VD->getType()->isIncompleteType()) &&
13715  !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD))
13716  return;
13717  if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) {
13718  // Checking declaration inside declare target region.
13719  if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
13720  isa<FunctionTemplateDecl>(D)) {
13721  auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
13722  Context, OMPDeclareTargetDeclAttr::MT_To);
13723  D->addAttr(A);
13724  if (ASTMutationListener *ML = Context.getASTMutationListener())
13725  ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
13726  }
13727  return;
13728  }
13729  }
13730  if (!E)
13731  return;
13732  checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
13733 }
13734 
13736  SourceLocation StartLoc,
13737  SourceLocation LParenLoc,
13738  SourceLocation EndLoc) {
13739  MappableVarListInfo MVLI(VarList);
13740  checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, StartLoc);
13741  if (MVLI.ProcessedVarList.empty())
13742  return nullptr;
13743 
13744  return OMPToClause::Create(Context, StartLoc, LParenLoc, EndLoc,
13745  MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
13746  MVLI.VarComponents);
13747 }
13748 
13750  SourceLocation StartLoc,
13751  SourceLocation LParenLoc,
13752  SourceLocation EndLoc) {
13753  MappableVarListInfo MVLI(VarList);
13754  checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, StartLoc);
13755  if (MVLI.ProcessedVarList.empty())
13756  return nullptr;
13757 
13758  return OMPFromClause::Create(Context, StartLoc, LParenLoc, EndLoc,
13759  MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
13760  MVLI.VarComponents);
13761 }
13762 
13764  SourceLocation StartLoc,
13765  SourceLocation LParenLoc,
13766  SourceLocation EndLoc) {
13767  MappableVarListInfo MVLI(VarList);
13768  SmallVector<Expr *, 8> PrivateCopies;
13770 
13771  for (Expr *RefExpr : VarList) {
13772  assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
13773  SourceLocation ELoc;
13774  SourceRange ERange;
13775  Expr *SimpleRefExpr = RefExpr;
13776  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
13777  if (Res.second) {
13778  // It will be analyzed later.
13779  MVLI.ProcessedVarList.push_back(RefExpr);
13780  PrivateCopies.push_back(nullptr);
13781  Inits.push_back(nullptr);
13782  }
13783  ValueDecl *D = Res.first;
13784  if (!D)
13785  continue;
13786 
13787  QualType Type = D->getType();
13788  Type = Type.getNonReferenceType().getUnqualifiedType();
13789 
13790  auto *VD = dyn_cast<VarDecl>(D);
13791 
13792  // Item should be a pointer or reference to pointer.
13793  if (!Type->isPointerType()) {
13794  Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
13795  << 0 << RefExpr->getSourceRange();
13796  continue;
13797  }
13798 
13799  // Build the private variable and the expression that refers to it.
13800  auto VDPrivate =
13801  buildVarDecl(*this, ELoc, Type, D->getName(),
13802  D->hasAttrs() ? &D->getAttrs() : nullptr,
13803  VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
13804  if (VDPrivate->isInvalidDecl())
13805  continue;
13806 
13807  CurContext->addDecl(VDPrivate);
13808  DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
13809  *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
13810 
13811  // Add temporary variable to initialize the private copy of the pointer.
13812  VarDecl *VDInit =
13813  buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
13814  DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
13815  *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
13816  AddInitializerToDecl(VDPrivate,
13817  DefaultLvalueConversion(VDInitRefExpr).get(),
13818  /*DirectInit=*/false);
13819 
13820  // If required, build a capture to implement the privatization initialized
13821  // with the current list item value.
13822  DeclRefExpr *Ref = nullptr;
13823  if (!VD)
13824  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
13825  MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
13826  PrivateCopies.push_back(VDPrivateRefExpr);
13827  Inits.push_back(VDInitRefExpr);
13828 
13829  // We need to add a data sharing attribute for this variable to make sure it
13830  // is correctly captured. A variable that shows up in a use_device_ptr has
13831  // similar properties of a first private variable.
13832  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
13833 
13834  // Create a mappable component for the list item. List items in this clause
13835  // only need a component.
13836  MVLI.VarBaseDeclarations.push_back(D);
13837  MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
13838  MVLI.VarComponents.back().push_back(
13840  }
13841 
13842  if (MVLI.ProcessedVarList.empty())
13843  return nullptr;
13844 
13846  Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList,
13847  PrivateCopies, Inits, MVLI.VarBaseDeclarations, MVLI.VarComponents);
13848 }
13849 
13851  SourceLocation StartLoc,
13852  SourceLocation LParenLoc,
13853  SourceLocation EndLoc) {
13854  MappableVarListInfo MVLI(VarList);
13855  for (Expr *RefExpr : VarList) {
13856  assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
13857  SourceLocation ELoc;
13858  SourceRange ERange;
13859  Expr *SimpleRefExpr = RefExpr;
13860  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
13861  if (Res.second) {
13862  // It will be analyzed later.
13863  MVLI.ProcessedVarList.push_back(RefExpr);
13864  }
13865  ValueDecl *D = Res.first;
13866  if (!D)
13867  continue;
13868 
13869  QualType Type = D->getType();
13870  // item should be a pointer or array or reference to pointer or array
13871  if (!Type.getNonReferenceType()->isPointerType() &&
13872  !Type.getNonReferenceType()->isArrayType()) {
13873  Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
13874  << 0 << RefExpr->getSourceRange();
13875  continue;
13876  }
13877 
13878  // Check if the declaration in the clause does not show up in any data
13879  // sharing attribute.
13880  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
13881  if (isOpenMPPrivate(DVar.CKind)) {
13882  Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
13883  << getOpenMPClauseName(DVar.CKind)
13884  << getOpenMPClauseName(OMPC_is_device_ptr)
13885  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
13886  reportOriginalDsa(*this, DSAStack, D, DVar);
13887  continue;
13888  }
13889 
13890  const Expr *ConflictExpr;
13891  if (DSAStack->checkMappableExprComponentListsForDecl(
13892  D, /*CurrentRegionOnly=*/true,
13893  [&ConflictExpr](
13895  OpenMPClauseKind) -> bool {
13896  ConflictExpr = R.front().getAssociatedExpression();
13897  return true;
13898  })) {
13899  Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
13900  Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
13901  << ConflictExpr->getSourceRange();
13902  continue;
13903  }
13904 
13905  // Store the components in the stack so that they can be used to check
13906  // against other clauses later on.
13908  DSAStack->addMappableExpressionComponents(
13909  D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
13910 
13911  // Record the expression we've just processed.
13912  MVLI.ProcessedVarList.push_back(SimpleRefExpr);
13913 
13914  // Create a mappable component for the list item. List items in this clause
13915  // only need a component. We use a null declaration to signal fields in
13916  // 'this'.
13917  assert((isa<DeclRefExpr>(SimpleRefExpr) ||
13918  isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
13919  "Unexpected device pointer expression!");
13920  MVLI.VarBaseDeclarations.push_back(
13921  isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
13922  MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
13923  MVLI.VarComponents.back().push_back(MC);
13924  }
13925 
13926  if (MVLI.ProcessedVarList.empty())
13927  return nullptr;
13928 
13930  Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList,
13931  MVLI.VarBaseDeclarations, MVLI.VarComponents);
13932 }
static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, SourceLocation M1Loc, SourceLocation M2Loc)
static bool isConstNotMutableType(Sema &SemaRef, QualType Type, bool AcceptIfMutable=true, bool *IsClassType=nullptr)
static OMPTaskReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef< Expr *> Privates, ArrayRef< Expr *> LHSExprs, ArrayRef< Expr *> RHSExprs, ArrayRef< Expr *> ReductionOps, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
Expr * NLB
Update of LowerBound for statically scheduled &#39;omp for&#39; loops.
Definition: StmtOpenMP.h:692
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:720
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Expr.cpp:465
Expr * NUB
Update of UpperBound for statically scheduled omp loops for outer loop in combined constructs (e...
Definition: StmtOpenMP.h:652
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:718
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:548
Represents a function declaration or definition.
Definition: Decl.h:1738
OMPClause * ActOnOpenMPSimdlenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;simdlen&#39; clause.
This represents &#39;thread_limit&#39; clause in the &#39;#pragma omp ...&#39; directive.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
static bool checkOpenMPIterationSpace(OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, LoopIterationSpace &ResultIterSpace, llvm::MapVector< const Expr *, DeclRefExpr *> &Captures)
Called on a for stmt to check and extract its iteration space for further processing (such as collaps...
StmtResult ActOnOpenMPSectionDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp section&#39; after parsing of the associated statement.
OMPClause * ActOnOpenMPTaskReductionClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr *> UnresolvedReductions=llvm::None)
Called on well-formed &#39;task_reduction&#39; clause.
static OMPDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
PtrTy get() const
Definition: Ownership.h:81
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
CanQualType VoidPtrTy
Definition: ASTContext.h:1044
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:638
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:6345
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
Definition: Expr.h:2778
ArrayRef< OMPClause * > clauses()
Definition: StmtOpenMP.h:260
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:3426
SourceLocation getExprLoc() const
Definition: Expr.h:3323
ExprResult ActOnConditionalOp(SourceLocation QuestionLoc, SourceLocation ColonLoc, Expr *CondExpr, Expr *LHSExpr, Expr *RHSExpr)
ActOnConditionalOp - Parse a ?: operation.
Definition: SemaExpr.cpp:7471
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:3197
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:193
void EndOpenMPDSABlock(Stmt *CurDirective)
Called on end of data sharing attribute block.
OpenMPDefaultmapClauseKind
OpenMP attributes for &#39;defaultmap&#39; clause.
Definition: OpenMPKinds.h:116
This represents &#39;atomic_default_mem_order&#39; clause in the &#39;#pragma omp requires&#39; directive.
Definition: OpenMPClause.h:870
static OMPCopyprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> SrcExprs, ArrayRef< Expr *> DstExprs, ArrayRef< Expr *> AssignmentOps)
Creates clause with a list of variables VL.
static OMPTeamsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:840
StmtResult ActOnOpenMPDistributeDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp distribute&#39; after parsing of the associated statement.
StmtResult ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName, ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp critical&#39; after parsing of the associated statement.
OMPClause * ActOnOpenMPUntiedClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;untied&#39; clause.
bool EvaluateAsInt(EvalResult &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...
static OMPClauseWithPreInit * get(OMPClause *C)
Stmt - This represents one statement.
Definition: Stmt.h:66
Filter makeFilter()
Create a filter for this result set.
Definition: Lookup.h:671
static OMPTaskgroupDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *ReductionRef)
Creates directive.
Definition: StmtOpenMP.cpp:525
StmtResult ActOnOpenMPTargetDataDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp target data&#39; after parsing of the associated statement.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
Definition: Type.cpp:505
Class that handles pre-initialization statement for some clauses, like &#39;shedule&#39;, &#39;firstprivate&#39; etc...
Definition: OpenMPClause.h:99
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.
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, ArrayRef< OpenMPMapModifierKind > MapTypeModifiers, ArrayRef< SourceLocation > MapTypeModifiersLoc, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation DepLinMapLoc)
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:690
Expr * DistInc
DistInc - increment expression for distribute loop when found combined with a further loop level (e...
Definition: StmtOpenMP.h:704
Expr * getBase() const
Definition: Expr.h:2772
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:1308
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:87
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:35
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
static constexpr unsigned NumberOfModifiers
Number of allowed map-type-modifiers.
VarDecl * getDefinition(ASTContext &)
Get the real (not just tentative) definition for this declaration.
Definition: Decl.cpp:2132
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.
Opcode getOpcode() const
Definition: Expr.h:3327
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
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
CapturedStmt * getInnermostCapturedStmt()
Get innermost captured statement for the construct.
Definition: StmtOpenMP.h:226
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:6245
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:1407
StmtResult ActOnOpenMPTargetTeamsDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp target teams&#39; after parsing of the associated statement.
OMPClause * ActOnOpenMPGrainsizeClause(Expr *Size, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;grainsize&#39; clause.
SourceLocation getBeginLoc() const
getBeginLoc - Retrieve the location of the first token.
const char * getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind, unsigned Type)
static OMPDeclareReductionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, QualType T, OMPDeclareReductionDecl *PrevDeclInScope)
Create declare reduction node.
Definition: DeclOpenMP.cpp:102
SourceLocation getEndLoc() const LLVM_READONLY
QualType withConst() const
Definition: Type.h:810
StmtResult ActOnOpenMPForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp for simd&#39; after parsing of the associated statement.
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:690
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
Definition: Specifiers.h:98
A container of type source information.
Definition: Decl.h:87
This represents &#39;update&#39; clause in the &#39;#pragma omp atomic&#39; directive.
Wrapper for void* pointer.
Definition: Ownership.h:51
static bool checkMapConflicts(Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, bool CurrentRegionOnly, OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, OpenMPClauseKind CKind)
bool CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, SourceLocation LinLoc)
Checks correctness of linear modifiers.
OMPClause * ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;proc_bind&#39; clause.
OMPClause * ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;hint&#39; clause.
static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, DSAStackTy *Stack, QualType QTy, bool FullCheck=true)
StmtResult ActOnOpenMPTaskDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp task&#39; after parsing of the associated statement.
void setInitStyle(InitializationStyle Style)
Definition: Decl.h:1265
bool hasNext() const
Definition: Lookup.h:628
Describes the capture of a variable or of this, or of a C++1y init-capture.
Definition: LambdaCapture.h:26
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:2484
static std::pair< ValueDecl *, bool > getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, SourceRange &ERange, bool AllowArraySection=false)
LLVM_ATTRIBUTE_REINITIALIZES void clear()
Clears out any current state.
Definition: Lookup.h:543
OpenMPDefaultmapClauseModifier
OpenMP modifiers for &#39;defaultmap&#39; clause.
Definition: OpenMPKinds.h:124
static bool checkReductionClauseWithNogroup(Sema &S, ArrayRef< OMPClause *> Clauses)
float __ovld __cnfn distance(float p0, float p1)
Returns the distance between p0 and p1.
OMPClause * ActOnOpenMPPriorityClause(Expr *Priority, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;priority&#39; clause.
static int getOpenMPCaptureLevels(OpenMPDirectiveKind Kind)
Return the number of captured regions created for an OpenMP directive.
SourceLocation getSecondScheduleModifierLoc() const
Get the second modifier location.
static const ValueDecl * getCanonicalDecl(const ValueDecl *D)
Definition: SemaOpenMP.cpp:709
bool capturesVariable(const VarDecl *Var) const
True if this variable has been captured.
Definition: Stmt.cpp:1289
StmtResult ActOnOpenMPTargetTeamsDistributeParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp target teams distribute parallel for&#39; after parsing of the associa...
StmtResult ActOnOpenMPTargetParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp target parallel for&#39; after parsing of the associated statement...
bool isTrivialType(const ASTContext &Context) const
Return true if this is a trivial type per (C++0x [basic.types]p9)
Definition: Type.cpp:2157
Expr * PrevLB
PreviousLowerBound - local variable passed to runtime in the enclosing schedule or null if that does ...
Definition: StmtOpenMP.h:697
Retains information about a function, method, or block that is currently being parsed.
Definition: ScopeInfo.h:97
void setNothrow(bool Nothrow=true)
Definition: Decl.cpp:4470
This represents &#39;read&#39; clause in the &#39;#pragma omp atomic&#39; directive.
static OMPTeamsDistributeDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Represents a variable declaration or definition.
Definition: Decl.h:813
ActionResult< Stmt * > StmtResult
Definition: Ownership.h:268
static OMPToClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> Vars, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
static OMPMapClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> Vars, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists, ArrayRef< OpenMPMapModifierKind > MapModifiers, ArrayRef< SourceLocation > MapModifiersLoc, OpenMPMapClauseKind Type, bool TypeIsImplicit, SourceLocation TypeLoc)
Creates clause with a list of variables VL.
This represents &#39;num_threads&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:382
bool isEnumeralType() const
Definition: Type.h:6373
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:6748
bool isOverloadableType() const
Determines whether this is a type for which one can define an overloaded operator.
Definition: Type.h:6670
varlist_range varlists()
Definition: OpenMPClause.h:207
Extra information about a function prototype.
Definition: Type.h:3767
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:1129
bool isAmbiguous() const
Definition: Lookup.h:290
Expr * IgnoreImplicit() LLVM_READONLY
IgnoreImplicit - Skip past any implicit AST nodes which might surround this expression.
Definition: Expr.h:747
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:542
void setBegin(SourceLocation b)
Not a TLS variable.
Definition: Decl.h:830
static const Expr * getExprAsWritten(const Expr *E)
Definition: SemaOpenMP.cpp:690
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;.
static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, QualType Type, OpenMPClauseKind CKind, SourceLocation ELoc, bool AcceptIfMutable=true, bool ListItemNotVar=false)
bool hasDefinition() const
Definition: DeclCXX.h:776
This represents &#39;reverse_offload&#39; clause in the &#39;#pragma omp requires&#39; directive. ...
Definition: OpenMPClause.h:807
OMPClause * ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;depend&#39; clause.
StmtResult ActOnOpenMPParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp parallel for&#39; after parsing of the associated statement.
Struct that defines common infrastructure to handle mappable expressions used in OpenMP clauses...
bool isUnset() const
Definition: Ownership.h:172
This represents &#39;nogroup&#39; clause in the &#39;#pragma omp ...&#39; directive.
This represents &#39;safelen&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:447
Expr * LastIteration
Loop last iteration number.
Definition: StmtOpenMP.h:668
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveStart(Scope *S, DeclContext *DC, DeclarationName Name, ArrayRef< std::pair< QualType, SourceLocation >> ReductionTypes, AccessSpecifier AS, Decl *PrevDeclInScope=nullptr)
Called on start of &#39;#pragma omp declare reduction&#39;.
ExprResult PerformImplicitConversion(Expr *From, QualType ToType, AssignmentAction Action, bool AllowExplicit=false)
PerformImplicitConversion - Perform an implicit conversion of the expression From to the type ToType...
DeclGroupPtrTy ActOnOpenMPDeclareSimdDirective(DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, ArrayRef< Expr *> Uniforms, ArrayRef< Expr *> Aligneds, ArrayRef< Expr *> Alignments, ArrayRef< Expr *> Linears, ArrayRef< unsigned > LinModifiers, ArrayRef< Expr *> Steps, SourceRange SR)
Called on well-formed &#39;#pragma omp declare simd&#39; after parsing of the associated method/function.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:270
void ActOnUninitializedDecl(Decl *dcl)
Definition: SemaDecl.cpp:11436
OpenMPMapModifierKind
OpenMP modifier kind for &#39;map&#39; clause.
Definition: OpenMPKinds.h:100
Expr * IgnoreImpCasts() LLVM_READONLY
IgnoreImpCasts - Skip past any implicit casts which might surround this expression.
Definition: Expr.h:3167
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
bool Encloses(const DeclContext *DC) const
Determine whether this declaration context encloses the declaration context DC.
Definition: DeclBase.cpp:1148
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:152
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:2774
Step
Definition: OpenMPClause.h:152
static OMPInReductionClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, ArrayRef< Expr *> Privates, ArrayRef< Expr *> LHSExprs, ArrayRef< Expr *> RHSExprs, ArrayRef< Expr *> ReductionOps, ArrayRef< Expr *> TaskgroupDescriptors, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
static NamedDecl * findAcceptableDecl(Sema &SemaRef, NamedDecl *D)
static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, const Expr *E, QualType BaseQTy)
OMPClause * ActOnOpenMPFirstprivateClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;firstprivate&#39; clause.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:155
A C++ nested-name-specifier augmented with source location information.
ExprResult ExprEmpty()
Definition: Ownership.h:289
The results of name lookup within a DeclContext.
Definition: DeclBase.h:1187
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.
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.cpp:288
bool isOpenMPTaskingDirective(OpenMPDirectiveKind Kind)
Checks if the specified directive kind is one of tasking directives - task, taskloop or taksloop simd...
OpenMPLinearClauseKind
OpenMP attributes for &#39;linear&#39; clause.
Definition: OpenMPKinds.h:84
Represents a member of a struct/union/class.
Definition: Decl.h:2579
OMPClause * ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, Expr *Condition, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation NameModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed &#39;if&#39; clause.
StmtResult ActOnOpenMPTeamsDistributeDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp teams distribute&#39; after parsing of the associated statement...
bool isNamespace() const
Definition: DeclBase.h:1832
static OMPTargetUpdateDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
OMPClause * ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;dynamic_allocators&#39; clause.
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:2890
bool isReferenceType() const
Definition: Type.h:6308
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Definition: DeclBase.h:406
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:406
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:1872
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:1478
void EndOpenMPClause()
End analysis of clauses.
IdentifierTable & Idents
Definition: ASTContext.h:566
StmtResult ActOnOpenMPTargetEnterDataDirective(ArrayRef< OMPClause *> Clauses, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AStmt)
Called on well-formed &#39;#pragma omp target enter data&#39; after parsing of the associated statement...
An r-value expression (a pr-value in the C++11 taxonomy) produces a temporary value.
Definition: Specifiers.h:110
DeclClass * getAsSingle() const
Definition: Lookup.h:496
OpenMPDistScheduleClauseKind
OpenMP attributes for &#39;dist_schedule&#39; clause.
Definition: OpenMPKinds.h:109
bool isGLValue() const
Definition: Expr.h:252
BinaryOperatorKind
OMPClause * ActOnOpenMPNumTeamsClause(Expr *NumTeams, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;num_teams&#39; clause.
bool isCompleteType(SourceLocation Loc, QualType T)
Definition: Sema.h:1654
Represents the results of name lookup.
Definition: Lookup.h:47
PtrTy get() const
Definition: Ownership.h:174
StmtResult ActOnOpenMPSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp simd&#39; after parsing of the associated statement.
Expr * LB
DistributeLowerBound - used when composing &#39;omp distribute&#39; with &#39;omp for&#39; in a same construct...
Definition: StmtOpenMP.h:633
Expr * EUB
DistributeEnsureUpperBound - used when composing &#39;omp distribute&#39; with &#39;omp for&#39; in a same construct...
Definition: StmtOpenMP.h:639
bool isOpenMPTeamsDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a teams-kind directive.
APValue Val
Val - This is the value the expression can be folded to.
Definition: Expr.h:573
OMPClause * ActOnOpenMPNogroupClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;nogroup&#39; clause.
OMPClause * ActOnOpenMPReadClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;read&#39; clause.
StmtResult ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp target teams distribute parallel for simd&#39; after parsing of the as...
OMPClause * ActOnOpenMPScheduleClause(OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc)
Called on well-formed &#39;schedule&#39; clause.
static OMPTeamsDistributeSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
static OMPLastprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> SrcExprs, ArrayRef< Expr *> DstExprs, ArrayRef< Expr *> AssignmentOps, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type...
Definition: Type.h:6797
static DeclRefExpr * buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, SourceLocation Loc, bool RefersToCapture=false)
Definition: SemaOpenMP.cpp:954
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:237
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:149
StmtResult StmtError()
Definition: Ownership.h:284
static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef)
Convert integer expression E to make it have at least Bits bits.
bool containsUnexpandedParameterPack() const
Whether this type is or contains an unexpanded parameter pack, used to support C++0x variadic templat...
Definition: Type.h:1831
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:3292
static void argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &ReductionId, SourceLocation Loc, QualType Ty, SmallVectorImpl< UnresolvedSet< 8 >> &Lookups)
Look up the name of an OpenMP user-defined reduction operation.
Definition: Sema.h:3092
OMPClause * ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc, SourceLocation EndLoc)
std::pair< StringRef, QualType > CapturedParamNameType
Definition: Sema.h:3834
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
This represents &#39;default&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:606
Expr * IgnoreParenCasts() LLVM_READONLY
IgnoreParenCasts - Ignore parentheses and casts.
Definition: Expr.cpp:2595
Scope - A scope is a transient data structure that is used while parsing the program.
Definition: Scope.h:41
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:7284
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:6072
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:672
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:3003
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:323
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
Definition: Decl.cpp:1918
const LangOptions & getLangOpts() const
Definition: Sema.h:1231
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:792
StmtResult ActOnOpenMPForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp for&#39; after parsing of the associated statement.
bool isTypeDependent() const
isTypeDependent - Determines whether this expression is type-dependent (C++ [temp.dep.expr]), which means that its type could change from one template instantiation to the next.
Definition: Expr.h:167
bool isScalarType() const
Definition: Type.h:6629
An ordinary object is located at an address in memory.
Definition: Specifiers.h:126
StmtResult ActOnOpenMPTargetTeamsDistributeDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp target teams distribute&#39; after parsing of the associated statement...
Represents the body of a CapturedStmt, and serves as its DeclContext.
Definition: Decl.h:4044
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 UnresolvedLookupExpr * Create(const ASTContext &Context, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded, UnresolvedSetIterator Begin, UnresolvedSetIterator End)
Definition: ExprCXX.cpp:325
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const
Retrieve a nested-name-specifier with location information, copied into the given AST context...
Definition: DeclSpec.cpp:143
OMPClause * ActOnOpenMPSafelenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;safelen&#39; clause.
OMPClause * ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;default&#39; clause.
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclBase.h:870
static OMPCopyinClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> SrcExprs, ArrayRef< Expr *> DstExprs, ArrayRef< Expr *> AssignmentOps)
Creates clause with a list of variables VL.
Expr * NUB
Update of UpperBound for statically scheduled &#39;omp for&#39; loops.
Definition: StmtOpenMP.h:694
static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, ArrayRef< OMPClause *> Clauses, ArrayRef< OpenMPDirectiveKind > AllowedNameModifiers)
static OMPDependClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, OpenMPDependClauseKind DepKind, SourceLocation DepLoc, SourceLocation ColonLoc, ArrayRef< Expr *> VL, unsigned NumLoops)
Creates clause with a list of variables VL.
Expr * Cond
Loop condition.
Definition: StmtOpenMP.h:676
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:1235
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:674
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:664
This represents &#39;dynamic_allocators&#39; clause in the &#39;#pragma omp requires&#39; directive.
Definition: OpenMPClause.h:838
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:531
ConditionalOperator - The ?: ternary operator.
Definition: Expr.h:3587
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:278
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1613
Describes the capture of either a variable, or &#39;this&#39;, or variable-length array type.
Definition: Stmt.h:3118
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:12259
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:6216
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:1844
static OMPCriticalDirective * Create(const ASTContext &C, const DeclarationNameInfo &Name, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive.
Definition: StmtOpenMP.cpp:310
static OMPOrderedClause * Create(const ASTContext &C, Expr *Num, unsigned NumLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Build &#39;ordered&#39; clause.
static bool checkGrainsizeNumTasksClauses(Sema &S, ArrayRef< OMPClause *> Clauses)
Expr * DistCond
Distribute Loop condition used when composing &#39;omp distribute&#39; with &#39;omp for&#39; in a same construct whe...
Definition: StmtOpenMP.h:655
Expr * IterationVarRef
Loop iteration variable.
Definition: StmtOpenMP.h:666
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:643
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
This represents &#39;#pragma omp requires...&#39; directive.
Definition: DeclOpenMP.h:250
Scope * getCurScope() const
Retrieve the parser&#39;s current scope.
Definition: Sema.h:10728
This represents implicit clause &#39;depend&#39; for the &#39;#pragma omp task&#39; directive.
Allows QualTypes to be sorted and hence used in maps and sets.
bool isCanonicalDecl() const
Whether this particular Decl is a canonical one.
Definition: DeclBase.h:876
const Stmt * getAssociatedStmt() const
Returns statement associated with the directive.
Definition: StmtOpenMP.h:196
static CallExpr * Create(const ASTContext &Ctx, Expr *Fn, ArrayRef< Expr *> Args, QualType Ty, ExprValueKind VK, SourceLocation RParenLoc, unsigned MinNumArgs=0, ADLCallKind UsesADL=NotADL)
Create a call expression.
Definition: Expr.cpp:1283
bool CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, OpenMPLinearClauseKind LinKind, QualType Type)
Checks that the specified declaration matches requirements for the linear decls.
This represents &#39;proc_bind&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:675
This represents &#39;capture&#39; clause in the &#39;#pragma omp atomic&#39; directive.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:637
This represents one expression.
Definition: Expr.h:106
void StartOpenMPClause(OpenMPClauseKind K)
Start analysis of clauses.
QualType getPointeeType() const
Definition: Type.h:2694
Allow any unmodeled side effect.
Definition: Expr.h:599
SourceLocation End
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
Definition: Specifiers.h:107
bool isDeclScope(Decl *D)
isDeclScope - Return true if this is the scope that the specified decl is declared in...
Definition: Scope.h:321
int Id
Definition: ASTDiff.cpp:191
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
Definition: Decl.h:1036
void ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner)
Finish current declare reduction construct initializer.
static OMPTargetTeamsDistributeParallelForSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
void BuildBasePathArray(const CXXBasePaths &Paths, CXXCastPath &BasePath)
This represents &#39;simdlen&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h: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:147
OMPThreadPrivateDecl * CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef< Expr *> VarList)
Builds a new OpenMPThreadPrivateDecl and checks its correctness.
bool isOpenMPParallelDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a parallel-kind directive.
OMPClause * ActOnOpenMPCopyinClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;copyin&#39; clause.
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:6811
OMPClause * ActOnOpenMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;mergeable&#39; clause.
Inits[]
Definition: OpenMPClause.h:151
static InitializedEntity InitializeVariable(VarDecl *Var)
Create the initialization entity for a variable.
unsigned getNumParams() const
Definition: Decl.h:4089
static OMPMasterDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt)
Creates directive.
Definition: StmtOpenMP.cpp:292
void setInit(Expr *I)
Definition: Decl.cpp:2205
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:1818
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
StmtResult ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp taskyield&#39;.
SourceLocation getBeginLoc() const
Definition: DeclSpec.h:72
DeclContext * getDeclContext()
Definition: DeclBase.h:427
void startOpenMPLoop()
If the current region is a loop-based region, mark the start of the loop construct.
bool isAnyComplexType() const
Definition: Type.h:6377
static OMPTargetDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:674
static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, OpenMPDirectiveKind CurrentRegion, const DeclarationNameInfo &CurrentName, OpenMPDirectiveKind CancelRegion, SourceLocation StartLoc)
SourceLocation Begin
An abstract interface that should be implemented by listeners that want to be notified when an AST en...
static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, Sema &SemaRef, DSAStackTy *Stack, ValueDecl *VD)
OMPClause * ActOnOpenMPDefaultmapClause(OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, SourceLocation KindLoc, SourceLocation EndLoc)
Called on well-formed &#39;defaultmap&#39; clause.
bool isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const
Check if the specified variable is used in &#39;private&#39; clause.
static FloatingLiteral * Create(const ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L)
Definition: Expr.cpp:848
StmtResult ActOnOpenMPTargetParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp target parallel for simd&#39; after parsing of the associated statemen...
bool RequireCompleteType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
Definition: SemaType.cpp:7603
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:729
This represents &#39;ordered&#39; clause in the &#39;#pragma omp ...&#39; directive.
bool isVisible(const NamedDecl *D)
Determine whether a declaration is visible to name lookup.
Definition: Sema.h:1598
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn&#39;t...
Expr * PrevUB
PreviousUpperBound - local variable passed to runtime in the enclosing schedule or null if that does ...
Definition: StmtOpenMP.h:700
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
OMPClause * ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;unified_address&#39; clause.
SmallVector< sema::FunctionScopeInfo *, 4 > FunctionScopes
Stack containing information about each of the nested function, block, and method scopes that are cur...
Definition: Sema.h:552
bool isSingleResult() const
Determines if this names a single result which is not an unresolved value using decl.
Definition: Lookup.h:297
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type...
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.
static const Expr * checkMapClauseExpressionBase(Sema &SemaRef, Expr *E, OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, OpenMPClauseKind CKind, bool NoDiagnose)
Expr * ParForInDistCond
&#39;omp parallel for&#39; loop condition used when composed with &#39;omp distribute&#39; in the same construct and ...
Definition: StmtOpenMP.h:659
bool isInvalid() const
Definition: Ownership.h:170
OMPClause * ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind, ArrayRef< unsigned > Arguments, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, ArrayRef< SourceLocation > ArgumentsLoc, SourceLocation DelimLoc, SourceLocation EndLoc)
OMPClause * ActOnOpenMPInReductionClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr *> UnresolvedReductions=llvm::None)
Called on well-formed &#39;in_reduction&#39; clause.
bool isOpenMPTaskLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a taskloop directive.
QualType getFunctionType(QualType ResultTy, ArrayRef< QualType > Args, const FunctionProtoType::ExtProtoInfo &EPI) const
Return a normal function type with a typed argument list.
Definition: ASTContext.h:1380
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
Definition: DeclBase.cpp:1078
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:1114
bool isUsable() const
Definition: Ownership.h:171
Represents a C++ conversion function within a class.
Definition: DeclCXX.h:2768
Expr * NLB
Update of LowerBound for statically scheduled omp loops for outer loop in combined constructs (e...
Definition: StmtOpenMP.h:649
The result type of a method or function.
bool isUnionType() const
Definition: Type.cpp:475
StmtResult ActOnOpenMPTaskLoopDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp taskloop&#39; after parsing of the associated statement.
OpenMPProcBindClauseKind
OpenMP attributes for &#39;proc_bind&#39; clause.
Definition: OpenMPKinds.h:51
bool isNull() const
Return true if this QualType doesn&#39;t point to a type yet.
Definition: Type.h:703
StmtResult ActOnOpenMPParallelDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp parallel&#39; after parsing of the associated statement.
StmtResult ActOnOpenMPTargetSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp target simd&#39; after parsing of the associated statement.
void checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, SourceLocation IdLoc=SourceLocation())
Check declaration inside target region.
void setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, unsigned Level)
Sets OpenMP capture kind (OMPC_private, OMPC_firstprivate, OMPC_map etc.) for FD based on DSA for the...
OMPClause * ActOnOpenMPFlushClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;flush&#39; pseudo clause.
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition: Decl.cpp:2026
DefaultDataSharingAttributes
Default data sharing attributes, which can be applied to directive.
Definition: SemaOpenMP.cpp:46
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1...
Definition: Expr.h:1517
bool isDirectInit() const
Whether the initializer is a direct-initializer (list or call).
Definition: Decl.h:1284
OMPClause * ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;device&#39; clause.
DeclGroupPtrTy ActOnOpenMPRequiresDirective(SourceLocation Loc, ArrayRef< OMPClause *> ClauseList)
Called on well-formed &#39;#pragma omp requires&#39;.
Expr * NumIterations
Loop number of iterations.
Definition: StmtOpenMP.h:670
static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)
Create a copy initialization.
ExprResult ActOnFinishFullExpr(Expr *Expr)
Definition: Sema.h:5347
OMPRequiresDecl * CheckOMPRequiresDecl(SourceLocation Loc, ArrayRef< OMPClause *> Clauses)
Check restrictions on Requires directive.
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:479
This represents &#39;untied&#39; clause in the &#39;#pragma omp ...&#39; directive.
bool hasAttrs() const
Definition: DeclBase.h:473
ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)
Definition: SemaCast.cpp:2736
ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E)
Definition: SemaExpr.cpp:3600
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:688
This represents &#39;unified_address&#39; clause in the &#39;#pragma omp requires&#39; directive. ...
Definition: OpenMPClause.h:745
SmallVector< Expr *, 4 > PrivateCounters
PrivateCounters Loop counters.
Definition: StmtOpenMP.h:714
OMPClause * ActOnOpenMPAtomicDefaultMemOrderClause(OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;atomic_default_mem_order&#39; clause.
OMPClause * ActOnOpenMPMapClause(ArrayRef< OpenMPMapModifierKind > MapTypeModifiers, ArrayRef< SourceLocation > MapTypeModifiersLoc, 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.
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:945
llvm::cl::opt< std::string > Filter
#define false
Definition: stdbool.h:33
Kind
This captures a statement into a function.
Definition: Stmt.h:3105
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:6111
ActionResult - This structure is used while parsing/acting on expressions, stmts, etc...
Definition: Ownership.h:157
SmallVector< Expr *, 4 > Counters
Counters Loop counters.
Definition: StmtOpenMP.h:712
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on a template...
Definition: Expr.h:191
ASTContext & getASTContext() const
Definition: Sema.h:1238
llvm::SmallDenseMap< const ValueDecl *, const Expr *, 4 > VarsWithInheritedDSAType
Definition: Sema.h:8857
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:3324
void FindAssociatedClassesAndNamespaces(SourceLocation InstantiationLoc, ArrayRef< Expr *> Args, AssociatedNamespaceSet &AssociatedNamespaces, AssociatedClassSet &AssociatedClasses)
Find the associated classes and namespaces for argument-dependent lookup for a call with the given se...
This represents &#39;#pragma omp declare reduction ...&#39; directive.
Definition: DeclOpenMP.h:103
StmtResult ActOnOpenMPTeamsDistributeSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp teams distribute simd&#39; after parsing of the associated statement...
QualType getUIntPtrType() const
Return a type compatible with "uintptr_t" (C99 7.18.1.4), as defined by the target.
Pseudo declaration for capturing expressions.
Definition: DeclOpenMP.h:217
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:2095
This is a basic class for representing single OpenMP executable directive.
Definition: StmtOpenMP.h:33
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:948
static unsigned checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, DSAStackTy &DSA, Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, OMPLoopDirective::HelperExprs &Built)
Called on a for stmt to check itself and nested loops (if any).
static OMPParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:335
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:1143
void setReferenced(bool R=true)
Definition: DeclBase.h:577
OpenMPDirectiveKind
OpenMP directives.
Definition: OpenMPKinds.h:23
IdentifierTable & getIdentifierTable()
Definition: Preprocessor.h:823
StmtResult ActOnOpenMPTeamsDistributeParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp teams distribute parallel for simd&#39; after parsing of the associate...
ExprObjectKind
A further classification of the kind of object referenced by an l-value or x-value.
Definition: Specifiers.h:124
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
DeclarationNameInfo getDirectiveName() const
Return name of the directive.
Definition: StmtOpenMP.h:1536
static OMPParallelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, bool HasCancel)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:57
StmtResult ActOnOpenMPDistributeSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp distribute simd&#39; after parsing of the associated statement...
static OMPTargetExitDataDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:818
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:183
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:102
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
Definition: Decl.h:1078
ExprResult DefaultLvalueConversion(Expr *E)
Definition: SemaExpr.cpp:553
C-style initialization with assignment.
Definition: Decl.h:818
Expr * PrevEUB
PrevEUB - expression similar to EUB but to be used when loop scheduling uses PrevLB and PrevUB (e...
Definition: StmtOpenMP.h:710
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:1016
bool isOpenMPLoopBoundSharingDirective(OpenMPDirectiveKind Kind)
Checks if the specified directive kind is one of the composite or combined directives that need loop ...
void addDecl(NamedDecl *D)
Definition: UnresolvedSet.h:89
OMPClause * ActOnOpenMPCopyprivateClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;copyprivate&#39; clause.
Describes the kind of initialization being performed, along with location information for tokens rela...
bool isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level) const
Return true if the provided declaration VD should be captured by reference.
bool isValueDependent() const
isValueDependent - Determines whether this expression is value-dependent (C++ [temp.dep.constexpr]).
Definition: Expr.h:149
StmtResult ActOnOpenMPOrderedDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp ordered&#39; after parsing of the associated statement.
bool isAnyPointerType() const
Definition: Type.h:6300
static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, OpenMPDirectiveKind CancelRegion, SourceLocation StartLoc)
A class for iterating through a result set and possibly filtering out results.
Definition: Lookup.h:606
This declaration is only a declaration.
Definition: Decl.h:1147
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.
static VarDecl * buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, StringRef Name, const AttrVec *Attrs=nullptr, DeclRefExpr *OrigRef=nullptr)
Build a variable declaration for OpenMP loop iteration variable.
Definition: SemaOpenMP.cpp:933
Stmt * getCapturedStmt()
Retrieve the statement being captured.
Definition: Stmt.h:3206
OMPClause * ActOnOpenMPSeqCstClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;seq_cst&#39; clause.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language...
Definition: Expr.h:249
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required...
Definition: DeclBase.cpp:397
Updates[]
Definition: OpenMPClause.h:151
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:725
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:684
void clear(unsigned Size)
Initialize all the fields to null.
Definition: StmtOpenMP.h:737
DefaultMapAttributes
Attributes of the defaultmap clause.
Definition: SemaOpenMP.cpp:53
NamedDecl * next()
Definition: Lookup.h:632
Expr * Init
Loop iteration variable init.
Definition: StmtOpenMP.h:678
ExprResult PerformOpenMPImplicitIntegerConversion(SourceLocation OpLoc, Expr *Op)
#define DSAStack
static OMPAlignedClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, Expr *A)
Creates clause with a list of variables VL and alignment A.
bool isVLASupported() const
Whether target supports variable-length arrays.
Definition: TargetInfo.h:1154
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:2293
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
Definition: Type.h:2085
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:215
OMPClause * ActOnOpenMPSIMDClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;simd&#39; clause.
const llvm::fltSemantics & getFloatTypeSemantics(QualType T) const
Return the APFloat &#39;semantics&#39; for the specified scalar floating point type.
static bool checkOMPArraySectionConstantForReduction(ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, SmallVectorImpl< llvm::APSInt > &ArraySizes)
Expr * getLHS() const
Definition: Expr.h:3332
static Expr * getCollapseNumberExpr(ArrayRef< OMPClause *> Clauses)
void setStep(Expr *Step)
Sets the linear step for clause.
Definition: OpenMPClause.h:111
static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, const ValueDecl *D, const DSAStackTy::DSAVarData &DVar, bool IsLoopIterVar=false)
OMPClause * ActOnOpenMPNumThreadsClause(Expr *NumThreads, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;num_threads&#39; clause.
static DeclGroupRef Create(ASTContext &C, Decl **Decls, unsigned NumDecls)
Definition: DeclGroup.h:69
* Finals[]
Definition: OpenMPClause.h:152
QualType withRestrict() const
Definition: Type.h:826
static OMPCapturedExprDecl * Create(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, QualType T, SourceLocation StartLoc)
Definition: DeclOpenMP.cpp:132
OMPClause * ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;unified_address&#39; clause.
OpenMPScheduleClauseModifier
OpenMP modifiers for &#39;schedule&#39; clause.
Definition: OpenMPKinds.h:67
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
Definition: DeclBase.h:941
Dataflow Directional Tag Classes.
std::string getAsString() const
getAsString - Retrieve the human-readable string for this name.
This represents &#39;device&#39; clause in the &#39;#pragma omp ...&#39; directive.
bool isValid() const
Return true if this is a valid SourceLocation object.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1262
EvalResult is a struct with detailed info about an evaluated expression.
Definition: Expr.h:571
static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, const Expr *E, QualType BaseQTy)
Return true if it can be proven that the provided array expression (array section or array subscript)...
SmallVector< Expr *, 4 > Inits
Expressions for loop counters inits for CodeGen.
Definition: StmtOpenMP.h:716
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:226
static ExprResult buildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, llvm::MapVector< const Expr *, DeclRefExpr *> *Captures=nullptr)
Build &#39;VarRef = Start + Iter * Step&#39;.
void ActOnCapturedRegionError()
Definition: SemaStmt.cpp:4345
static std::string getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, ArrayRef< unsigned > Exclude=llvm::None)
OpenMPAtomicDefaultMemOrderClauseKind
OpenMP attributes for &#39;atomic_default_mem_order&#39; clause.
Definition: OpenMPKinds.h:133
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:1220
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.
The name of a declaration.
bool isOpenMPSimdDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a simd directive.
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup.
Definition: Lookup.h:506
static OMPCapturedExprDecl * buildCaptureDecl(Sema &S, IdentifierInfo *Id, Expr *CaptureExpr, bool WithInit, bool AsExpression)
bool shouldDiagnoseTargetSupportFromOpenMP() const
Return true if (un)supported features for the current target should be diagnosed if OpenMP (offloadin...
Definition: Sema.h:8829
static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, bool StrictlyPositive)
This represents &#39;unified_shared_memory&#39; clause in the &#39;#pragma omp requires&#39; directive.
Definition: OpenMPClause.h:776
OMPClause * ActOnOpenMPUseDevicePtrClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;use_device_ptr&#39; clause.
This represents clause &#39;linear&#39; in the &#39;#pragma omp ...&#39; directives.
bool isAmbiguous(CanQualType BaseType)
Determine whether the path from the most-derived type to the given base type is ambiguous (i...
bool isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level) const
Check if the specified variable is captured by &#39;target&#39; directive.
bool isIntegerConstantExpr(llvm::APSInt &Result, const ASTContext &Ctx, SourceLocation *Loc=nullptr, bool isEvaluated=true) const
isIntegerConstantExpr - Return true if this expression is a valid integer constant expression...
DeclGroupPtrTy ActOnOpenMPDeclareReductionDirectiveEnd(Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid)
Called at the end of &#39;#pragma omp declare reduction&#39;.
static bool actOnOMPReductionKindClause(Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr *> UnresolvedReductions, ReductionData &RD)
bool isOpenMPThreadPrivate(OpenMPClauseKind Kind)
Checks if the specified clause is one of threadprivate clauses like &#39;threadprivate&#39;, &#39;copyin&#39; or &#39;copyprivate&#39;.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspnd...
static OMPFirstprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> PrivateVL, ArrayRef< Expr *> InitVL, Stmt *PreInit)
Creates clause with a list of variables VL.
SourceLocation getBeginLoc() const
Returns the starting location of the clause.
Definition: OpenMPClause.h:67
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:10977
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:2693
ExprResult IgnoredValueConversions(Expr *E)
IgnoredValueConversions - Given that an expression&#39;s result is syntactically ignored, perform any conversions that are required.
SourceLocation getEndLoc() const
Returns the ending location of the clause.
Definition: OpenMPClause.h:70
Class that represents a component of a mappable expression.
StmtResult ActOnOpenMPTargetTeamsDistributeSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp target teams distribute simd&#39; after parsing of the associated stat...
Not an overloaded operator.
Definition: OperatorKinds.h:23
void getOpenMPCaptureRegions(llvm::SmallVectorImpl< OpenMPDirectiveKind > &CaptureRegions, OpenMPDirectiveKind DKind)
Return the captured regions of an OpenMP directive.
void ActOnFinishOpenMPDeclareTargetDirective()
Called at the end of target region i.e. &#39;#pragme omp end declare target&#39;.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:4370
Complex values, per C99 6.2.5p11.
Definition: Type.h:2477
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:2312
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:6578
void setSeverity(diag::kind Diag, diag::Severity Map, SourceLocation Loc)
This allows the client to specify that certain warnings are ignored.
Definition: Diagnostic.cpp:343
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
CanQualType DependentTy
Definition: ASTContext.h:1045
bool isDeclInScope(NamedDecl *D, DeclContext *Ctx, Scope *S=nullptr, bool AllowInlineNamespace=false)
isDeclInScope - If &#39;Ctx&#39; is a function/method, isDeclInScope returns true if &#39;D&#39; is in Scope &#39;S&#39;...
Definition: SemaDecl.cpp:1407
OMPClause * ActOnOpenMPIsDevicePtrClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;is_device_ptr&#39; clause.
void ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, VarDecl *OmpPrivParm)
Finish current declare reduction construct initializer.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
Definition: Decl.h:1060
Expr * Inc
Loop increment.
Definition: StmtOpenMP.h:680
DeclContext * getCurLexicalContext() const
Definition: Sema.h:10739
OMPClause * ActOnOpenMPToClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;to&#39; clause.
OpenMPScheduleClauseKind
OpenMP attributes for &#39;schedule&#39; clause.
Definition: OpenMPKinds.h:59
Expr * IgnoreParenLValueCasts() LLVM_READONLY
Ignore parentheses and lvalue casts.
Definition: Expr.cpp:2650
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:110
CXXBasePath & front()
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:2673
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
Definition: ASTContext.h:2269
ImplicitParamDecl * getParam(unsigned i) const
Definition: Decl.h:4091
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:12871
static ExprResult buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, llvm::MapVector< const Expr *, DeclRefExpr *> &Captures)
Build &#39;VarRef = Start.
OpenMPDefaultClauseKind
OpenMP attributes for &#39;default&#39; clause.
Definition: OpenMPKinds.h:43
void addDecl(Decl *D)
Add the declaration D into this context.
Definition: DeclBase.cpp:1507
bool hasAssociatedStmt() const
Returns true if directive has associated statement.
Definition: StmtOpenMP.h:193
StmtResult ActOnOpenMPDistributeParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp distribute parallel for simd&#39; after parsing of the associated stat...
static OMPTargetTeamsDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
QualType getNonLValueExprType(const ASTContext &Context) const
Determine the type of a (typically non-lvalue) expression with the specified result type...
Definition: Type.cpp:2806
static OMPRequiresDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef< OMPClause *> CL)
Create requires node.
Definition: DeclOpenMP.cpp:62
Capturing the *this object by reference.
Definition: Lambda.h:35
This represents &#39;write&#39; clause in the &#39;#pragma omp atomic&#39; directive.
const char * getOpenMPDirectiveName(OpenMPDirectiveKind Kind)
Definition: OpenMPKinds.cpp:31
const Type * getTypePtrOrNull() const
Definition: Type.h:6076
StmtResult ActOnOpenMPParallelForSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp parallel for simd&#39; after parsing of the associated statement...
void markUsed(ASTContext &C)
Mark the declaration used, in the sense of odr-use.
Definition: DeclBase.cpp:412
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
Definition: ASTContext.h:2070
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:2031
StmtResult ActOnOpenMPTaskLoopSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp taskloop simd&#39; after parsing of the associated statement...
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
ASTMutationListener * getASTMutationListener() const
Retrieve a pointer to the AST mutation listener associated with this AST context, if any...
Definition: ASTContext.h:1098
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Definition: ASTContext.h:2253
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:636
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
Definition: SemaDecl.cpp:13954
bool hasMutableFields() const
Determine whether this class, or any of its class subobjects, contains a mutable field.
Definition: DeclCXX.h:1356
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:1265
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:821
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:1687
bool typesAreCompatible(QualType T1, QualType T2, bool CompareUnqualified=false)
Compatibility predicates used to check assignment expressions.
OpenMPScheduleClauseModifier getSecondScheduleModifier() const
Get the second modifier of the clause.
void Deallocate(void *Ptr) const
Definition: ASTContext.h:675
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition: Expr.h:2687
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:633
Expr * UB
UpperBound - local variable passed to runtime.
Definition: StmtOpenMP.h:686
static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, Sema &SemaRef, Decl *D)
Describes the sequence of initializations required to initialize a given object or reference with a s...
ActionResult< Expr * > ExprResult
Definition: Ownership.h:267
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition: Type.h:6152
This represents &#39;nowait&#39; clause in the &#39;#pragma omp ...&#39; directive.
void setEnd(SourceLocation e)
void ActOnOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id, OMPDeclareTargetDeclAttr::MapTypeTy MT, NamedDeclSetType &SameDirectiveDecls)
Called on correct id-expression from the &#39;#pragma omp declare target&#39;.
bool hasSignedIntegerRepresentation() const
Determine whether this type has an signed integer representation of some sort, e.g., it is an signed integer type or a vector.
Definition: Type.cpp:1874
Represents a C++ struct/union/class.
Definition: DeclCXX.h:300
OpenMPScheduleClauseModifier getFirstScheduleModifier() const
Get the first modifier of the clause.
This represents &#39;num_tasks&#39; clause in the &#39;#pragma omp ...&#39; directive.
sema::FunctionScopeInfo * getCurFunction() const
Definition: Sema.h:1358
static QualType getBaseOriginalType(const Expr *Base)
Return original type of the base expression for array section.
Definition: Expr.cpp:4257
StmtResult ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp taskwait&#39;.
bool hasIntegerRepresentation() const
Determine whether this type has an integer representation of some sort, e.g., it is an integer type o...
Definition: Type.cpp:1733
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:151
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:1481
SourceLocation getFirstScheduleModifierLoc() const
Get the first modifier location.
Do not present this diagnostic, ignore it.
Capturing by reference.
Definition: Lambda.h:38
AccessResult CheckBaseClassAccess(SourceLocation AccessLoc, QualType Base, QualType Derived, const CXXBasePath &Path, unsigned DiagID, bool ForceCheck=false, bool ForceUnprivileged=false)
Checks access for a hierarchy conversion.
OMPClause * ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;thread_limit&#39; clause.
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
Definition: Sema.h:336
bool containsUnexpandedParameterPack() const
Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates)...
Definition: Expr.h:214
Declaration of a class template.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
StmtResult ActOnOpenMPAtomicDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp atomic&#39; after parsing of the associated statement.
static OMPSimdDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:83
void addAttr(Attr *A)
Definition: DeclBase.cpp:840
StmtResult ActOnOpenMPSingleDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp single&#39; after parsing of the associated statement.
iterator end() const
Definition: Lookup.h:325
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:276
DeclGroupPtrTy ActOnOpenMPThreadprivateDirective(SourceLocation Loc, ArrayRef< Expr *> VarList)
Called on well-formed &#39;#pragma omp threadprivate&#39;.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:276
ExprResult ExprError()
Definition: Ownership.h:283
This represents &#39;dist_schedule&#39; clause in the &#39;#pragma omp ...&#39; directive.
__DEVICE__ int max(int __a, int __b)
static OMPTaskwaitDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
Definition: StmtOpenMP.cpp:511
Expr * Cond
Distribute Loop condition used when composing &#39;omp distribute&#39; with &#39;omp for&#39; in a same construct...
Definition: StmtOpenMP.h:646
Stmt * PreInits
Init statement for all captured expressions.
Definition: StmtOpenMP.h:722
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:2079
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...
capture_range captures()
Definition: Stmt.h:3240
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1041
Expr * getRHS() const
Definition: Expr.h:3334
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:6296
static OverloadedOperatorKind getOverloadedOperator(Opcode Opc)
Retrieve the overloaded operator kind that corresponds to the given binary opcode.
Definition: Expr.cpp:1935
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef)
Check if the given expression E is a constant integer that fits into Bits bits.
static OMPFlushClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL)
Creates clause with a list of variables VL.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
OMPClause * ActOnOpenMPAlignedClause(ArrayRef< Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc)
Called on well-formed &#39;aligned&#39; clause.
DefinitionKind isThisDeclarationADefinition(ASTContext &) const
Check whether this declaration is a definition.
Definition: Decl.cpp:2029
bool isStaticDataMember() const
Determines whether this is a static data member.
Definition: Decl.h:1135
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
Definition: Lookup.h:572
SmallVector< CompoundScopeInfo, 4 > CompoundScopes
The stack of currently active compound stamement scopes in the function.
Definition: ScopeInfo.h:204
QualType getType() const
Definition: Decl.h:648
bool empty() const
Return true if no decls were found.
Definition: Lookup.h:328
An l-value expression is a reference to an object with independent storage.
Definition: Specifiers.h:114
StmtResult ActOnOpenMPParallelSectionsDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp parallel sections&#39; after parsing of the associated statement...
static OMPCancelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion)
Creates directive.
Definition: StmtOpenMP.cpp:571
bool isOpenMPLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a directive with an associated loop construct.
OMPClause * ActOnOpenMPFromClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;from&#39; clause.
Expr * IL
IsLastIteration - local flag variable passed to runtime.
Definition: StmtOpenMP.h:682
A trivial tuple used to represent a source range.
ASTContext & Context
Definition: Sema.h:324
This represents a decl that may have a name.
Definition: Decl.h:249
static OMPCancellationPointDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Creates directive.
Definition: StmtOpenMP.cpp:550
bool isTranslationUnit() const
Definition: DeclBase.h:1823
void setAccess(AccessSpecifier AS)
Definition: DeclBase.h:457
CanQualType BoolTy
Definition: ASTContext.h:1017
static T filterLookupForUDR(SmallVectorImpl< U > &Lookups, const llvm::function_ref< T(ValueDecl *)> Gen)
OMPClause * ActOnOpenMPOrderedClause(SourceLocation StartLoc, SourceLocation EndLoc, SourceLocation LParenLoc=SourceLocation(), Expr *NumForLoops=nullptr)
Called on well-formed &#39;ordered&#39; clause.
Directive - Abstract class representing a parsed verify directive.
QualType getVariableArrayType(QualType EltTy, Expr *NumElts, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals, SourceRange Brackets) const
Return a non-unique reference to the type for a variable array of the specified element type...
OMPClause * ActOnOpenMPCollapseClause(Expr *NumForLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;collapse&#39; clause.
bool isConstant(const ASTContext &Ctx) const
Definition: Type.h:773
ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
Definition: SemaExpr.cpp:12755
APSInt & getInt()
Definition: APValue.h:252
static OMPClauseWithPostUpdate * get(OMPClause *C)
iterator begin() const
Definition: Lookup.h:324
OMPClause * ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;reverse_offload&#39; clause.
Describes an entity that is being initialized.
NamedDecl * getRepresentativeDecl() const
Fetches a representative decl. Useful for lazy diagnostics.
Definition: Lookup.h:513
bool hasInit() const
Definition: Decl.cpp:2164
SourceLocation getBegin() const
SourceLocation ColonLoc
Location of &#39;:&#39;.
Definition: OpenMPClause.h:108
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:40
VerifyDiagnosticConsumer::Directive Directive
bool isExternCXXContext() const
Determines whether this context or some of its ancestors is a linkage specification context that spec...
Definition: DeclBase.cpp:1144
Represents the canonical version of C arrays with a specified constant size.
Definition: Type.h:2872
bool getSuppressAllDiagnostics() const
Definition: Diagnostic.h:636
OMPClause * ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
SourceLocation getLocation() const
Definition: DeclBase.h:418
StmtResult ActOnOpenMPTeamsDistributeParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp teams distribute parallel for&#39; after parsing of the associated sta...
Expr * getLength()
Get length of array section.
Definition: ExprOpenMP.h:99
QualType getIntTypeForBitwidth(unsigned DestWidth, unsigned Signed) const
getIntTypeForBitwidth - sets integer QualTy according to specified details: bitwidth, signed/unsigned.
StmtResult ActOnOpenMPDistributeParallelForDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp distribute parallel for&#39; after parsing of the associated statement...
bool isOpenMPNestingTeamsDirective(OpenMPDirectiveKind DKind)
Checks if the specified composite/combined directive constitutes a teams directive in the outermost n...
Helper class that creates diagnostics with optional template instantiation stacks.
Definition: Sema.h:1261
Expr * IgnoreParens() LLVM_READONLY
IgnoreParens - Ignore parentheses.
Definition: Expr.cpp:2560
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
static bool isVisible(Sema &SemaRef, NamedDecl *D)
Determine whether the given declaration is visible to the program.
Definition: Lookup.h:338