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(), /*DiscardedValue*/ false);
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 =
5400  SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
5401 
5402  const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
5403  // We expect to have at least 2 more parameters than the 'parallel'
5404  // directive does - the lower and upper bounds of the previous schedule.
5405  assert(CD->getNumParams() >= 4 &&
5406  "Unexpected number of parameters in loop combined directive");
5407 
5408  // Set the proper type for the bounds given what we learned from the
5409  // enclosed loops.
5410  ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
5411  ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
5412 
5413  // Previous lower and upper bounds are obtained from the region
5414  // parameters.
5415  PrevLB =
5416  buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
5417  PrevUB =
5418  buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
5419  }
5420  }
5421 
5422  // Build the iteration variable and its initialization before loop.
5423  ExprResult IV;
5424  ExprResult Init, CombInit;
5425  {
5426  VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
5427  IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
5428  Expr *RHS =
5429  (isOpenMPWorksharingDirective(DKind) ||
5431  ? LB.get()
5432  : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
5433  Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
5434  Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
5435 
5436  if (isOpenMPLoopBoundSharingDirective(DKind)) {
5437  Expr *CombRHS =
5438  (isOpenMPWorksharingDirective(DKind) ||
5439  isOpenMPTaskLoopDirective(DKind) ||
5441  ? CombLB.get()
5442  : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
5443  CombInit =
5444  SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
5445  CombInit =
5446  SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
5447  }
5448  }
5449 
5450  // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops.
5451  SourceLocation CondLoc = AStmt->getBeginLoc();
5452  ExprResult Cond =
5453  (isOpenMPWorksharingDirective(DKind) ||
5455  ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get())
5456  : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
5457  NumIterations.get());
5458  ExprResult CombDistCond;
5459  if (isOpenMPLoopBoundSharingDirective(DKind)) {
5460  CombDistCond =
5461  SemaRef.BuildBinOp(
5462  CurScope, CondLoc, BO_LT, IV.get(), NumIterations.get());
5463  }
5464 
5465  ExprResult CombCond;
5466  if (isOpenMPLoopBoundSharingDirective(DKind)) {
5467  CombCond =
5468  SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), CombUB.get());
5469  }
5470  // Loop increment (IV = IV + 1)
5471  SourceLocation IncLoc = AStmt->getBeginLoc();
5472  ExprResult Inc =
5473  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
5474  SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
5475  if (!Inc.isUsable())
5476  return 0;
5477  Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
5478  Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
5479  if (!Inc.isUsable())
5480  return 0;
5481 
5482  // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
5483  // Used for directives with static scheduling.
5484  // In combined construct, add combined version that use CombLB and CombUB
5485  // base variables for the update
5486  ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
5488  isOpenMPDistributeDirective(DKind)) {
5489  // LB + ST
5490  NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
5491  if (!NextLB.isUsable())
5492  return 0;
5493  // LB = LB + ST
5494  NextLB =
5495  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
5496  NextLB =
5497  SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
5498  if (!NextLB.isUsable())
5499  return 0;
5500  // UB + ST
5501  NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
5502  if (!NextUB.isUsable())
5503  return 0;
5504  // UB = UB + ST
5505  NextUB =
5506  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
5507  NextUB =
5508  SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
5509  if (!NextUB.isUsable())
5510  return 0;
5511  if (isOpenMPLoopBoundSharingDirective(DKind)) {
5512  CombNextLB =
5513  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
5514  if (!NextLB.isUsable())
5515  return 0;
5516  // LB = LB + ST
5517  CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
5518  CombNextLB.get());
5519  CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
5520  /*DiscardedValue*/ false);
5521  if (!CombNextLB.isUsable())
5522  return 0;
5523  // UB + ST
5524  CombNextUB =
5525  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
5526  if (!CombNextUB.isUsable())
5527  return 0;
5528  // UB = UB + ST
5529  CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
5530  CombNextUB.get());
5531  CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
5532  /*DiscardedValue*/ false);
5533  if (!CombNextUB.isUsable())
5534  return 0;
5535  }
5536  }
5537 
5538  // Create increment expression for distribute loop when combined in a same
5539  // directive with for as IV = IV + ST; ensure upper bound expression based
5540  // on PrevUB instead of NumIterations - used to implement 'for' when found
5541  // in combination with 'distribute', like in 'distribute parallel for'
5542  SourceLocation DistIncLoc = AStmt->getBeginLoc();
5543  ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
5544  if (isOpenMPLoopBoundSharingDirective(DKind)) {
5545  DistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get());
5546  assert(DistCond.isUsable() && "distribute cond expr was not built");
5547 
5548  DistInc =
5549  SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
5550  assert(DistInc.isUsable() && "distribute inc expr was not built");
5551  DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
5552  DistInc.get());
5553  DistInc =
5554  SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
5555  assert(DistInc.isUsable() && "distribute inc expr was not built");
5556 
5557  // Build expression: UB = min(UB, prevUB) for #for in composite or combined
5558  // construct
5559  SourceLocation DistEUBLoc = AStmt->getBeginLoc();
5560  ExprResult IsUBGreater =
5561  SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get());
5562  ExprResult CondOp = SemaRef.ActOnConditionalOp(
5563  DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
5564  PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
5565  CondOp.get());
5566  PrevEUB =
5567  SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
5568 
5569  // Build IV <= PrevUB to be used in parallel for is in combination with
5570  // a distribute directive with schedule(static, 1)
5571  ParForInDistCond =
5572  SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), PrevUB.get());
5573  }
5574 
5575  // Build updates and final values of the loop counters.
5576  bool HasErrors = false;
5577  Built.Counters.resize(NestedLoopCount);
5578  Built.Inits.resize(NestedLoopCount);
5579  Built.Updates.resize(NestedLoopCount);
5580  Built.Finals.resize(NestedLoopCount);
5581  {
5582  // We implement the following algorithm for obtaining the
5583  // original loop iteration variable values based on the
5584  // value of the collapsed loop iteration variable IV.
5585  //
5586  // Let n+1 be the number of collapsed loops in the nest.
5587  // Iteration variables (I0, I1, .... In)
5588  // Iteration counts (N0, N1, ... Nn)
5589  //
5590  // Acc = IV;
5591  //
5592  // To compute Ik for loop k, 0 <= k <= n, generate:
5593  // Prod = N(k+1) * N(k+2) * ... * Nn;
5594  // Ik = Acc / Prod;
5595  // Acc -= Ik * Prod;
5596  //
5597  ExprResult Acc = IV;
5598  for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
5599  LoopIterationSpace &IS = IterSpaces[Cnt];
5600  SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
5601  ExprResult Iter;
5602 
5603  // Compute prod
5604  ExprResult Prod =
5605  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
5606  for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K)
5607  Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
5608  IterSpaces[K].NumIterations);
5609 
5610  // Iter = Acc / Prod
5611  // If there is at least one more inner loop to avoid
5612  // multiplication by 1.
5613  if (Cnt + 1 < NestedLoopCount)
5614  Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div,
5615  Acc.get(), Prod.get());
5616  else
5617  Iter = Acc;
5618  if (!Iter.isUsable()) {
5619  HasErrors = true;
5620  break;
5621  }
5622 
5623  // Update Acc:
5624  // Acc -= Iter * Prod
5625  // Check if there is at least one more inner loop to avoid
5626  // multiplication by 1.
5627  if (Cnt + 1 < NestedLoopCount)
5628  Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul,
5629  Iter.get(), Prod.get());
5630  else
5631  Prod = Iter;
5632  Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub,
5633  Acc.get(), Prod.get());
5634 
5635  // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
5636  auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
5637  DeclRefExpr *CounterVar = buildDeclRefExpr(
5638  SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
5639  /*RefersToCapture=*/true);
5640  ExprResult Init = buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
5641  IS.CounterInit, Captures);
5642  if (!Init.isUsable()) {
5643  HasErrors = true;
5644  break;
5645  }
5647  SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
5648  IS.CounterStep, IS.Subtract, &Captures);
5649  if (!Update.isUsable()) {
5650  HasErrors = true;
5651  break;
5652  }
5653 
5654  // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
5656  SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit,
5657  IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures);
5658  if (!Final.isUsable()) {
5659  HasErrors = true;
5660  break;
5661  }
5662 
5663  if (!Update.isUsable() || !Final.isUsable()) {
5664  HasErrors = true;
5665  break;
5666  }
5667  // Save results
5668  Built.Counters[Cnt] = IS.CounterVar;
5669  Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
5670  Built.Inits[Cnt] = Init.get();
5671  Built.Updates[Cnt] = Update.get();
5672  Built.Finals[Cnt] = Final.get();
5673  }
5674  }
5675 
5676  if (HasErrors)
5677  return 0;
5678 
5679  // Save results
5680  Built.IterationVarRef = IV.get();
5681  Built.LastIteration = LastIteration.get();
5682  Built.NumIterations = NumIterations.get();
5683  Built.CalcLastIteration = SemaRef
5684  .ActOnFinishFullExpr(CalcLastIteration.get(),
5685  /*DiscardedValue*/ false)
5686  .get();
5687  Built.PreCond = PreCond.get();
5688  Built.PreInits = buildPreInits(C, Captures);
5689  Built.Cond = Cond.get();
5690  Built.Init = Init.get();
5691  Built.Inc = Inc.get();
5692  Built.LB = LB.get();
5693  Built.UB = UB.get();
5694  Built.IL = IL.get();
5695  Built.ST = ST.get();
5696  Built.EUB = EUB.get();
5697  Built.NLB = NextLB.get();
5698  Built.NUB = NextUB.get();
5699  Built.PrevLB = PrevLB.get();
5700  Built.PrevUB = PrevUB.get();
5701  Built.DistInc = DistInc.get();
5702  Built.PrevEUB = PrevEUB.get();
5703  Built.DistCombinedFields.LB = CombLB.get();
5704  Built.DistCombinedFields.UB = CombUB.get();
5705  Built.DistCombinedFields.EUB = CombEUB.get();
5706  Built.DistCombinedFields.Init = CombInit.get();
5707  Built.DistCombinedFields.Cond = CombCond.get();
5708  Built.DistCombinedFields.NLB = CombNextLB.get();
5709  Built.DistCombinedFields.NUB = CombNextUB.get();
5710  Built.DistCombinedFields.DistCond = CombDistCond.get();
5711  Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
5712 
5713  return NestedLoopCount;
5714 }
5715 
5717  auto CollapseClauses =
5718  OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
5719  if (CollapseClauses.begin() != CollapseClauses.end())
5720  return (*CollapseClauses.begin())->getNumForLoops();
5721  return nullptr;
5722 }
5723 
5725  auto OrderedClauses =
5726  OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
5727  if (OrderedClauses.begin() != OrderedClauses.end())
5728  return (*OrderedClauses.begin())->getNumForLoops();
5729  return nullptr;
5730 }
5731 
5733  const ArrayRef<OMPClause *> Clauses) {
5734  const OMPSafelenClause *Safelen = nullptr;
5735  const OMPSimdlenClause *Simdlen = nullptr;
5736 
5737  for (const OMPClause *Clause : Clauses) {
5738  if (Clause->getClauseKind() == OMPC_safelen)
5739  Safelen = cast<OMPSafelenClause>(Clause);
5740  else if (Clause->getClauseKind() == OMPC_simdlen)
5741  Simdlen = cast<OMPSimdlenClause>(Clause);
5742  if (Safelen && Simdlen)
5743  break;
5744  }
5745 
5746  if (Simdlen && Safelen) {
5747  const Expr *SimdlenLength = Simdlen->getSimdlen();
5748  const Expr *SafelenLength = Safelen->getSafelen();
5749  if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
5750  SimdlenLength->isInstantiationDependent() ||
5751  SimdlenLength->containsUnexpandedParameterPack())
5752  return false;
5753  if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
5754  SafelenLength->isInstantiationDependent() ||
5755  SafelenLength->containsUnexpandedParameterPack())
5756  return false;
5757  Expr::EvalResult SimdlenResult, SafelenResult;
5758  SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
5759  SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
5760  llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
5761  llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
5762  // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
5763  // If both simdlen and safelen clauses are specified, the value of the
5764  // simdlen parameter must be less than or equal to the value of the safelen
5765  // parameter.
5766  if (SimdlenRes > SafelenRes) {
5767  S.Diag(SimdlenLength->getExprLoc(),
5768  diag::err_omp_wrong_simdlen_safelen_values)
5769  << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
5770  return true;
5771  }
5772  }
5773  return false;
5774 }
5775 
5776 StmtResult
5778  SourceLocation StartLoc, SourceLocation EndLoc,
5779  VarsWithInheritedDSAType &VarsWithImplicitDSA) {
5780  if (!AStmt)
5781  return StmtError();
5782 
5783  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5785  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5786  // define the nested loops number.
5787  unsigned NestedLoopCount = checkOpenMPLoop(
5788  OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
5789  AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
5790  if (NestedLoopCount == 0)
5791  return StmtError();
5792 
5793  assert((CurContext->isDependentContext() || B.builtAll()) &&
5794  "omp simd loop exprs were not built");
5795 
5796  if (!CurContext->isDependentContext()) {
5797  // Finalize the clauses that need pre-built expressions for CodeGen.
5798  for (OMPClause *C : Clauses) {
5799  if (auto *LC = dyn_cast<OMPLinearClause>(C))
5800  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5801  B.NumIterations, *this, CurScope,
5802  DSAStack))
5803  return StmtError();
5804  }
5805  }
5806 
5807  if (checkSimdlenSafelenSpecified(*this, Clauses))
5808  return StmtError();
5809 
5810  setFunctionHasBranchProtectedScope();
5811  return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5812  Clauses, AStmt, B);
5813 }
5814 
5815 StmtResult
5817  SourceLocation StartLoc, SourceLocation EndLoc,
5818  VarsWithInheritedDSAType &VarsWithImplicitDSA) {
5819  if (!AStmt)
5820  return StmtError();
5821 
5822  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5824  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5825  // define the nested loops number.
5826  unsigned NestedLoopCount = checkOpenMPLoop(
5827  OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
5828  AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
5829  if (NestedLoopCount == 0)
5830  return StmtError();
5831 
5832  assert((CurContext->isDependentContext() || B.builtAll()) &&
5833  "omp for loop exprs were not built");
5834 
5835  if (!CurContext->isDependentContext()) {
5836  // Finalize the clauses that need pre-built expressions for CodeGen.
5837  for (OMPClause *C : Clauses) {
5838  if (auto *LC = dyn_cast<OMPLinearClause>(C))
5839  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5840  B.NumIterations, *this, CurScope,
5841  DSAStack))
5842  return StmtError();
5843  }
5844  }
5845 
5846  setFunctionHasBranchProtectedScope();
5847  return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5848  Clauses, AStmt, B, DSAStack->isCancelRegion());
5849 }
5850 
5852  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
5853  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
5854  if (!AStmt)
5855  return StmtError();
5856 
5857  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5859  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
5860  // define the nested loops number.
5861  unsigned NestedLoopCount =
5862  checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
5863  getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
5864  VarsWithImplicitDSA, B);
5865  if (NestedLoopCount == 0)
5866  return StmtError();
5867 
5868  assert((CurContext->isDependentContext() || B.builtAll()) &&
5869  "omp for simd loop exprs were not built");
5870 
5871  if (!CurContext->isDependentContext()) {
5872  // Finalize the clauses that need pre-built expressions for CodeGen.
5873  for (OMPClause *C : Clauses) {
5874  if (auto *LC = dyn_cast<OMPLinearClause>(C))
5875  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
5876  B.NumIterations, *this, CurScope,
5877  DSAStack))
5878  return StmtError();
5879  }
5880  }
5881 
5882  if (checkSimdlenSafelenSpecified(*this, Clauses))
5883  return StmtError();
5884 
5885  setFunctionHasBranchProtectedScope();
5886  return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
5887  Clauses, AStmt, B);
5888 }
5889 
5891  Stmt *AStmt,
5892  SourceLocation StartLoc,
5893  SourceLocation EndLoc) {
5894  if (!AStmt)
5895  return StmtError();
5896 
5897  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5898  auto BaseStmt = AStmt;
5899  while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
5900  BaseStmt = CS->getCapturedStmt();
5901  if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
5902  auto S = C->children();
5903  if (S.begin() == S.end())
5904  return StmtError();
5905  // All associated statements must be '#pragma omp section' except for
5906  // the first one.
5907  for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
5908  if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
5909  if (SectionStmt)
5910  Diag(SectionStmt->getBeginLoc(),
5911  diag::err_omp_sections_substmt_not_section);
5912  return StmtError();
5913  }
5914  cast<OMPSectionDirective>(SectionStmt)
5915  ->setHasCancel(DSAStack->isCancelRegion());
5916  }
5917  } else {
5918  Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
5919  return StmtError();
5920  }
5921 
5922  setFunctionHasBranchProtectedScope();
5923 
5924  return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
5925  DSAStack->isCancelRegion());
5926 }
5927 
5929  SourceLocation StartLoc,
5930  SourceLocation EndLoc) {
5931  if (!AStmt)
5932  return StmtError();
5933 
5934  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5935 
5936  setFunctionHasBranchProtectedScope();
5937  DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
5938 
5939  return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
5940  DSAStack->isCancelRegion());
5941 }
5942 
5944  Stmt *AStmt,
5945  SourceLocation StartLoc,
5946  SourceLocation EndLoc) {
5947  if (!AStmt)
5948  return StmtError();
5949 
5950  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5951 
5952  setFunctionHasBranchProtectedScope();
5953 
5954  // OpenMP [2.7.3, single Construct, Restrictions]
5955  // The copyprivate clause must not be used with the nowait clause.
5956  const OMPClause *Nowait = nullptr;
5957  const OMPClause *Copyprivate = nullptr;
5958  for (const OMPClause *Clause : Clauses) {
5959  if (Clause->getClauseKind() == OMPC_nowait)
5960  Nowait = Clause;
5961  else if (Clause->getClauseKind() == OMPC_copyprivate)
5962  Copyprivate = Clause;
5963  if (Copyprivate && Nowait) {
5964  Diag(Copyprivate->getBeginLoc(),
5965  diag::err_omp_single_copyprivate_with_nowait);
5966  Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
5967  return StmtError();
5968  }
5969  }
5970 
5971  return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
5972 }
5973 
5975  SourceLocation StartLoc,
5976  SourceLocation EndLoc) {
5977  if (!AStmt)
5978  return StmtError();
5979 
5980  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5981 
5982  setFunctionHasBranchProtectedScope();
5983 
5984  return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
5985 }
5986 
5988  const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
5989  Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
5990  if (!AStmt)
5991  return StmtError();
5992 
5993  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5994 
5995  bool ErrorFound = false;
5996  llvm::APSInt Hint;
5997  SourceLocation HintLoc;
5998  bool DependentHint = false;
5999  for (const OMPClause *C : Clauses) {
6000  if (C->getClauseKind() == OMPC_hint) {
6001  if (!DirName.getName()) {
6002  Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
6003  ErrorFound = true;
6004  }
6005  Expr *E = cast<OMPHintClause>(C)->getHint();
6006  if (E->isTypeDependent() || E->isValueDependent() ||
6007  E->isInstantiationDependent()) {
6008  DependentHint = true;
6009  } else {
6010  Hint = E->EvaluateKnownConstInt(Context);
6011  HintLoc = C->getBeginLoc();
6012  }
6013  }
6014  }
6015  if (ErrorFound)
6016  return StmtError();
6017  const auto Pair = DSAStack->getCriticalWithHint(DirName);
6018  if (Pair.first && DirName.getName() && !DependentHint) {
6019  if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
6020  Diag(StartLoc, diag::err_omp_critical_with_hint);
6021  if (HintLoc.isValid())
6022  Diag(HintLoc, diag::note_omp_critical_hint_here)
6023  << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false);
6024  else
6025  Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
6026  if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
6027  Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
6028  << 1
6029  << C->getHint()->EvaluateKnownConstInt(Context).toString(
6030  /*Radix=*/10, /*Signed=*/false);
6031  } else {
6032  Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
6033  }
6034  }
6035  }
6036 
6037  setFunctionHasBranchProtectedScope();
6038 
6039  auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
6040  Clauses, AStmt);
6041  if (!Pair.first && DirName.getName() && !DependentHint)
6042  DSAStack->addCriticalWithHint(Dir, Hint);
6043  return Dir;
6044 }
6045 
6047  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6048  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
6049  if (!AStmt)
6050  return StmtError();
6051 
6052  auto *CS = cast<CapturedStmt>(AStmt);
6053  // 1.2.2 OpenMP Language Terminology
6054  // Structured block - An executable statement with a single entry at the
6055  // top and a single exit at the bottom.
6056  // The point of exit cannot be a branch out of the structured block.
6057  // longjmp() and throw() must not violate the entry/exit criteria.
6058  CS->getCapturedDecl()->setNothrow();
6059 
6061  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6062  // define the nested loops number.
6063  unsigned NestedLoopCount =
6064  checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
6065  getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
6066  VarsWithImplicitDSA, B);
6067  if (NestedLoopCount == 0)
6068  return StmtError();
6069 
6070  assert((CurContext->isDependentContext() || B.builtAll()) &&
6071  "omp parallel for loop exprs were not built");
6072 
6073  if (!CurContext->isDependentContext()) {
6074  // Finalize the clauses that need pre-built expressions for CodeGen.
6075  for (OMPClause *C : Clauses) {
6076  if (auto *LC = dyn_cast<OMPLinearClause>(C))
6077  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
6078  B.NumIterations, *this, CurScope,
6079  DSAStack))
6080  return StmtError();
6081  }
6082  }
6083 
6084  setFunctionHasBranchProtectedScope();
6085  return OMPParallelForDirective::Create(Context, StartLoc, EndLoc,
6086  NestedLoopCount, Clauses, AStmt, B,
6087  DSAStack->isCancelRegion());
6088 }
6089 
6091  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6092  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
6093  if (!AStmt)
6094  return StmtError();
6095 
6096  auto *CS = cast<CapturedStmt>(AStmt);
6097  // 1.2.2 OpenMP Language Terminology
6098  // Structured block - An executable statement with a single entry at the
6099  // top and a single exit at the bottom.
6100  // The point of exit cannot be a branch out of the structured block.
6101  // longjmp() and throw() must not violate the entry/exit criteria.
6102  CS->getCapturedDecl()->setNothrow();
6103 
6105  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
6106  // define the nested loops number.
6107  unsigned NestedLoopCount =
6108  checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
6109  getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
6110  VarsWithImplicitDSA, B);
6111  if (NestedLoopCount == 0)
6112  return StmtError();
6113 
6114  if (!CurContext->isDependentContext()) {
6115  // Finalize the clauses that need pre-built expressions for CodeGen.
6116  for (OMPClause *C : Clauses) {
6117  if (auto *LC = dyn_cast<OMPLinearClause>(C))
6118  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
6119  B.NumIterations, *this, CurScope,
6120  DSAStack))
6121  return StmtError();
6122  }
6123  }
6124 
6125  if (checkSimdlenSafelenSpecified(*this, Clauses))
6126  return StmtError();
6127 
6128  setFunctionHasBranchProtectedScope();
6130  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
6131 }
6132 
6133 StmtResult
6135  Stmt *AStmt, SourceLocation StartLoc,
6136  SourceLocation EndLoc) {
6137  if (!AStmt)
6138  return StmtError();
6139 
6140  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6141  auto BaseStmt = AStmt;
6142  while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
6143  BaseStmt = CS->getCapturedStmt();
6144  if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
6145  auto S = C->children();
6146  if (S.begin() == S.end())
6147  return StmtError();
6148  // All associated statements must be '#pragma omp section' except for
6149  // the first one.
6150  for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
6151  if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
6152  if (SectionStmt)
6153  Diag(SectionStmt->getBeginLoc(),
6154  diag::err_omp_parallel_sections_substmt_not_section);
6155  return StmtError();
6156  }
6157  cast<OMPSectionDirective>(SectionStmt)
6158  ->setHasCancel(DSAStack->isCancelRegion());
6159  }
6160  } else {
6161  Diag(AStmt->getBeginLoc(),
6162  diag::err_omp_parallel_sections_not_compound_stmt);
6163  return StmtError();
6164  }
6165 
6166  setFunctionHasBranchProtectedScope();
6167 
6169  Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion());
6170 }
6171 
6173  Stmt *AStmt, SourceLocation StartLoc,
6174  SourceLocation EndLoc) {
6175  if (!AStmt)
6176  return StmtError();
6177 
6178  auto *CS = cast<CapturedStmt>(AStmt);
6179  // 1.2.2 OpenMP Language Terminology
6180  // Structured block - An executable statement with a single entry at the
6181  // top and a single exit at the bottom.
6182  // The point of exit cannot be a branch out of the structured block.
6183  // longjmp() and throw() must not violate the entry/exit criteria.
6184  CS->getCapturedDecl()->setNothrow();
6185 
6186  setFunctionHasBranchProtectedScope();
6187 
6188  return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
6189  DSAStack->isCancelRegion());
6190 }
6191 
6193  SourceLocation EndLoc) {
6194  return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
6195 }
6196 
6198  SourceLocation EndLoc) {
6199  return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
6200 }
6201 
6203  SourceLocation EndLoc) {
6204  return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
6205 }
6206 
6208  Stmt *AStmt,
6209  SourceLocation StartLoc,
6210  SourceLocation EndLoc) {
6211  if (!AStmt)
6212  return StmtError();
6213 
6214  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6215 
6216  setFunctionHasBranchProtectedScope();
6217 
6218  return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
6219  AStmt,
6220  DSAStack->getTaskgroupReductionRef());
6221 }
6222 
6224  SourceLocation StartLoc,
6225  SourceLocation EndLoc) {
6226  assert(Clauses.size() <= 1 && "Extra clauses in flush directive");
6227  return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
6228 }
6229 
6231  Stmt *AStmt,
6232  SourceLocation StartLoc,
6233  SourceLocation EndLoc) {
6234  const OMPClause *DependFound = nullptr;
6235  const OMPClause *DependSourceClause = nullptr;
6236  const OMPClause *DependSinkClause = nullptr;
6237  bool ErrorFound = false;
6238  const OMPThreadsClause *TC = nullptr;
6239  const OMPSIMDClause *SC = nullptr;
6240  for (const OMPClause *C : Clauses) {
6241  if (auto *DC = dyn_cast<OMPDependClause>(C)) {
6242  DependFound = C;
6243  if (DC->getDependencyKind() == OMPC_DEPEND_source) {
6244  if (DependSourceClause) {
6245  Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
6246  << getOpenMPDirectiveName(OMPD_ordered)
6247  << getOpenMPClauseName(OMPC_depend) << 2;
6248  ErrorFound = true;
6249  } else {
6250  DependSourceClause = C;
6251  }
6252  if (DependSinkClause) {
6253  Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
6254  << 0;
6255  ErrorFound = true;
6256  }
6257  } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
6258  if (DependSourceClause) {
6259  Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
6260  << 1;
6261  ErrorFound = true;
6262  }
6263  DependSinkClause = C;
6264  }
6265  } else if (C->getClauseKind() == OMPC_threads) {
6266  TC = cast<OMPThreadsClause>(C);
6267  } else if (C->getClauseKind() == OMPC_simd) {
6268  SC = cast<OMPSIMDClause>(C);
6269  }
6270  }
6271  if (!ErrorFound && !SC &&
6272  isOpenMPSimdDirective(DSAStack->getParentDirective())) {
6273  // OpenMP [2.8.1,simd Construct, Restrictions]
6274  // An ordered construct with the simd clause is the only OpenMP construct
6275  // that can appear in the simd region.
6276  Diag(StartLoc, diag::err_omp_prohibited_region_simd);
6277  ErrorFound = true;
6278  } else if (DependFound && (TC || SC)) {
6279  Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
6280  << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
6281  ErrorFound = true;
6282  } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) {
6283  Diag(DependFound->getBeginLoc(),
6284  diag::err_omp_ordered_directive_without_param);
6285  ErrorFound = true;
6286  } else if (TC || Clauses.empty()) {
6287  if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) {
6288  SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
6289  Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
6290  << (TC != nullptr);
6291  Diag(Param->getBeginLoc(), diag::note_omp_ordered_param);
6292  ErrorFound = true;
6293  }
6294  }
6295  if ((!AStmt && !DependFound) || ErrorFound)
6296  return StmtError();
6297 
6298  if (AStmt) {
6299  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6300 
6301  setFunctionHasBranchProtectedScope();
6302  }
6303 
6304  return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
6305 }
6306 
6307 namespace {
6308 /// Helper class for checking expression in 'omp atomic [update]'
6309 /// construct.
6310 class OpenMPAtomicUpdateChecker {
6311  /// Error results for atomic update expressions.
6312  enum ExprAnalysisErrorCode {
6313  /// A statement is not an expression statement.
6314  NotAnExpression,
6315  /// Expression is not builtin binary or unary operation.
6316  NotABinaryOrUnaryExpression,
6317  /// Unary operation is not post-/pre- increment/decrement operation.
6318  NotAnUnaryIncDecExpression,
6319  /// An expression is not of scalar type.
6320  NotAScalarType,
6321  /// A binary operation is not an assignment operation.
6322  NotAnAssignmentOp,
6323  /// RHS part of the binary operation is not a binary expression.
6324  NotABinaryExpression,
6325  /// RHS part is not additive/multiplicative/shift/biwise binary
6326  /// expression.
6327  NotABinaryOperator,
6328  /// RHS binary operation does not have reference to the updated LHS
6329  /// part.
6330  NotAnUpdateExpression,
6331  /// No errors is found.
6332  NoError
6333  };
6334  /// Reference to Sema.
6335  Sema &SemaRef;
6336  /// A location for note diagnostics (when error is found).
6337  SourceLocation NoteLoc;
6338  /// 'x' lvalue part of the source atomic expression.
6339  Expr *X;
6340  /// 'expr' rvalue part of the source atomic expression.
6341  Expr *E;
6342  /// Helper expression of the form
6343  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
6344  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
6345  Expr *UpdateExpr;
6346  /// Is 'x' a LHS in a RHS part of full update expression. It is
6347  /// important for non-associative operations.
6348  bool IsXLHSInRHSPart;
6349  BinaryOperatorKind Op;
6350  SourceLocation OpLoc;
6351  /// true if the source expression is a postfix unary operation, false
6352  /// if it is a prefix unary operation.
6353  bool IsPostfixUpdate;
6354 
6355 public:
6356  OpenMPAtomicUpdateChecker(Sema &SemaRef)
6357  : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
6358  IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
6359  /// Check specified statement that it is suitable for 'atomic update'
6360  /// constructs and extract 'x', 'expr' and Operation from the original
6361  /// expression. If DiagId and NoteId == 0, then only check is performed
6362  /// without error notification.
6363  /// \param DiagId Diagnostic which should be emitted if error is found.
6364  /// \param NoteId Diagnostic note for the main error message.
6365  /// \return true if statement is not an update expression, false otherwise.
6366  bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
6367  /// Return the 'x' lvalue part of the source atomic expression.
6368  Expr *getX() const { return X; }
6369  /// Return the 'expr' rvalue part of the source atomic expression.
6370  Expr *getExpr() const { return E; }
6371  /// Return the update expression used in calculation of the updated
6372  /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
6373  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
6374  Expr *getUpdateExpr() const { return UpdateExpr; }
6375  /// Return true if 'x' is LHS in RHS part of full update expression,
6376  /// false otherwise.
6377  bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
6378 
6379  /// true if the source expression is a postfix unary operation, false
6380  /// if it is a prefix unary operation.
6381  bool isPostfixUpdate() const { return IsPostfixUpdate; }
6382 
6383 private:
6384  bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
6385  unsigned NoteId = 0);
6386 };
6387 } // namespace
6388 
6389 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
6390  BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
6391  ExprAnalysisErrorCode ErrorFound = NoError;
6392  SourceLocation ErrorLoc, NoteLoc;
6393  SourceRange ErrorRange, NoteRange;
6394  // Allowed constructs are:
6395  // x = x binop expr;
6396  // x = expr binop x;
6397  if (AtomicBinOp->getOpcode() == BO_Assign) {
6398  X = AtomicBinOp->getLHS();
6399  if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
6400  AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
6401  if (AtomicInnerBinOp->isMultiplicativeOp() ||
6402  AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
6403  AtomicInnerBinOp->isBitwiseOp()) {
6404  Op = AtomicInnerBinOp->getOpcode();
6405  OpLoc = AtomicInnerBinOp->getOperatorLoc();
6406  Expr *LHS = AtomicInnerBinOp->getLHS();
6407  Expr *RHS = AtomicInnerBinOp->getRHS();
6408  llvm::FoldingSetNodeID XId, LHSId, RHSId;
6409  X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
6410  /*Canonical=*/true);
6411  LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
6412  /*Canonical=*/true);
6413  RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
6414  /*Canonical=*/true);
6415  if (XId == LHSId) {
6416  E = RHS;
6417  IsXLHSInRHSPart = true;
6418  } else if (XId == RHSId) {
6419  E = LHS;
6420  IsXLHSInRHSPart = false;
6421  } else {
6422  ErrorLoc = AtomicInnerBinOp->getExprLoc();
6423  ErrorRange = AtomicInnerBinOp->getSourceRange();
6424  NoteLoc = X->getExprLoc();
6425  NoteRange = X->getSourceRange();
6426  ErrorFound = NotAnUpdateExpression;
6427  }
6428  } else {
6429  ErrorLoc = AtomicInnerBinOp->getExprLoc();
6430  ErrorRange = AtomicInnerBinOp->getSourceRange();
6431  NoteLoc = AtomicInnerBinOp->getOperatorLoc();
6432  NoteRange = SourceRange(NoteLoc, NoteLoc);
6433  ErrorFound = NotABinaryOperator;
6434  }
6435  } else {
6436  NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
6437  NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
6438  ErrorFound = NotABinaryExpression;
6439  }
6440  } else {
6441  ErrorLoc = AtomicBinOp->getExprLoc();
6442  ErrorRange = AtomicBinOp->getSourceRange();
6443  NoteLoc = AtomicBinOp->getOperatorLoc();
6444  NoteRange = SourceRange(NoteLoc, NoteLoc);
6445  ErrorFound = NotAnAssignmentOp;
6446  }
6447  if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
6448  SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
6449  SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
6450  return true;
6451  }
6452  if (SemaRef.CurContext->isDependentContext())
6453  E = X = UpdateExpr = nullptr;
6454  return ErrorFound != NoError;
6455 }
6456 
6457 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
6458  unsigned NoteId) {
6459  ExprAnalysisErrorCode ErrorFound = NoError;
6460  SourceLocation ErrorLoc, NoteLoc;
6461  SourceRange ErrorRange, NoteRange;
6462  // Allowed constructs are:
6463  // x++;
6464  // x--;
6465  // ++x;
6466  // --x;
6467  // x binop= expr;
6468  // x = x binop expr;
6469  // x = expr binop x;
6470  if (auto *AtomicBody = dyn_cast<Expr>(S)) {
6471  AtomicBody = AtomicBody->IgnoreParenImpCasts();
6472  if (AtomicBody->getType()->isScalarType() ||
6473  AtomicBody->isInstantiationDependent()) {
6474  if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
6475  AtomicBody->IgnoreParenImpCasts())) {
6476  // Check for Compound Assignment Operation
6478  AtomicCompAssignOp->getOpcode());
6479  OpLoc = AtomicCompAssignOp->getOperatorLoc();
6480  E = AtomicCompAssignOp->getRHS();
6481  X = AtomicCompAssignOp->getLHS()->IgnoreParens();
6482  IsXLHSInRHSPart = true;
6483  } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
6484  AtomicBody->IgnoreParenImpCasts())) {
6485  // Check for Binary Operation
6486  if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
6487  return true;
6488  } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
6489  AtomicBody->IgnoreParenImpCasts())) {
6490  // Check for Unary Operation
6491  if (AtomicUnaryOp->isIncrementDecrementOp()) {
6492  IsPostfixUpdate = AtomicUnaryOp->isPostfix();
6493  Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
6494  OpLoc = AtomicUnaryOp->getOperatorLoc();
6495  X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
6496  E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
6497  IsXLHSInRHSPart = true;
6498  } else {
6499  ErrorFound = NotAnUnaryIncDecExpression;
6500  ErrorLoc = AtomicUnaryOp->getExprLoc();
6501  ErrorRange = AtomicUnaryOp->getSourceRange();
6502  NoteLoc = AtomicUnaryOp->getOperatorLoc();
6503  NoteRange = SourceRange(NoteLoc, NoteLoc);
6504  }
6505  } else if (!AtomicBody->isInstantiationDependent()) {
6506  ErrorFound = NotABinaryOrUnaryExpression;
6507  NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
6508  NoteRange = ErrorRange = AtomicBody->getSourceRange();
6509  }
6510  } else {
6511  ErrorFound = NotAScalarType;
6512  NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
6513  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
6514  }
6515  } else {
6516  ErrorFound = NotAnExpression;
6517  NoteLoc = ErrorLoc = S->getBeginLoc();
6518  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
6519  }
6520  if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
6521  SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
6522  SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
6523  return true;
6524  }
6525  if (SemaRef.CurContext->isDependentContext())
6526  E = X = UpdateExpr = nullptr;
6527  if (ErrorFound == NoError && E && X) {
6528  // Build an update expression of form 'OpaqueValueExpr(x) binop
6529  // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
6530  // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
6531  auto *OVEX = new (SemaRef.getASTContext())
6532  OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue);
6533  auto *OVEExpr = new (SemaRef.getASTContext())
6535  ExprResult Update =
6536  SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
6537  IsXLHSInRHSPart ? OVEExpr : OVEX);
6538  if (Update.isInvalid())
6539  return true;
6540  Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
6542  if (Update.isInvalid())
6543  return true;
6544  UpdateExpr = Update.get();
6545  }
6546  return ErrorFound != NoError;
6547 }
6548 
6550  Stmt *AStmt,
6551  SourceLocation StartLoc,
6552  SourceLocation EndLoc) {
6553  if (!AStmt)
6554  return StmtError();
6555 
6556  auto *CS = cast<CapturedStmt>(AStmt);
6557  // 1.2.2 OpenMP Language Terminology
6558  // Structured block - An executable statement with a single entry at the
6559  // top and a single exit at the bottom.
6560  // The point of exit cannot be a branch out of the structured block.
6561  // longjmp() and throw() must not violate the entry/exit criteria.
6562  OpenMPClauseKind AtomicKind = OMPC_unknown;
6563  SourceLocation AtomicKindLoc;
6564  for (const OMPClause *C : Clauses) {
6565  if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
6566  C->getClauseKind() == OMPC_update ||
6567  C->getClauseKind() == OMPC_capture) {
6568  if (AtomicKind != OMPC_unknown) {
6569  Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
6570  << SourceRange(C->getBeginLoc(), C->getEndLoc());
6571  Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause)
6572  << getOpenMPClauseName(AtomicKind);
6573  } else {
6574  AtomicKind = C->getClauseKind();
6575  AtomicKindLoc = C->getBeginLoc();
6576  }
6577  }
6578  }
6579 
6580  Stmt *Body = CS->getCapturedStmt();
6581  if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
6582  Body = EWC->getSubExpr();
6583 
6584  Expr *X = nullptr;
6585  Expr *V = nullptr;
6586  Expr *E = nullptr;
6587  Expr *UE = nullptr;
6588  bool IsXLHSInRHSPart = false;
6589  bool IsPostfixUpdate = false;
6590  // OpenMP [2.12.6, atomic Construct]
6591  // In the next expressions:
6592  // * x and v (as applicable) are both l-value expressions with scalar type.
6593  // * During the execution of an atomic region, multiple syntactic
6594  // occurrences of x must designate the same storage location.
6595  // * Neither of v and expr (as applicable) may access the storage location
6596  // designated by x.
6597  // * Neither of x and expr (as applicable) may access the storage location
6598  // designated by v.
6599  // * expr is an expression with scalar type.
6600  // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
6601  // * binop, binop=, ++, and -- are not overloaded operators.
6602  // * The expression x binop expr must be numerically equivalent to x binop
6603  // (expr). This requirement is satisfied if the operators in expr have
6604  // precedence greater than binop, or by using parentheses around expr or
6605  // subexpressions of expr.
6606  // * The expression expr binop x must be numerically equivalent to (expr)
6607  // binop x. This requirement is satisfied if the operators in expr have
6608  // precedence equal to or greater than binop, or by using parentheses around
6609  // expr or subexpressions of expr.
6610  // * For forms that allow multiple occurrences of x, the number of times
6611  // that x is evaluated is unspecified.
6612  if (AtomicKind == OMPC_read) {
6613  enum {
6614  NotAnExpression,
6615  NotAnAssignmentOp,
6616  NotAScalarType,
6617  NotAnLValue,
6618  NoError
6619  } ErrorFound = NoError;
6620  SourceLocation ErrorLoc, NoteLoc;
6621  SourceRange ErrorRange, NoteRange;
6622  // If clause is read:
6623  // v = x;
6624  if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
6625  const auto *AtomicBinOp =
6626  dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
6627  if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
6628  X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
6629  V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
6630  if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
6631  (V->isInstantiationDependent() || V->getType()->isScalarType())) {
6632  if (!X->isLValue() || !V->isLValue()) {
6633  const Expr *NotLValueExpr = X->isLValue() ? V : X;
6634  ErrorFound = NotAnLValue;
6635  ErrorLoc = AtomicBinOp->getExprLoc();
6636  ErrorRange = AtomicBinOp->getSourceRange();
6637  NoteLoc = NotLValueExpr->getExprLoc();
6638  NoteRange = NotLValueExpr->getSourceRange();
6639  }
6640  } else if (!X->isInstantiationDependent() ||
6641  !V->isInstantiationDependent()) {
6642  const Expr *NotScalarExpr =
6644  ? V
6645  : X;
6646  ErrorFound = NotAScalarType;
6647  ErrorLoc = AtomicBinOp->getExprLoc();
6648  ErrorRange = AtomicBinOp->getSourceRange();
6649  NoteLoc = NotScalarExpr->getExprLoc();
6650  NoteRange = NotScalarExpr->getSourceRange();
6651  }
6652  } else if (!AtomicBody->isInstantiationDependent()) {
6653  ErrorFound = NotAnAssignmentOp;
6654  ErrorLoc = AtomicBody->getExprLoc();
6655  ErrorRange = AtomicBody->getSourceRange();
6656  NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
6657  : AtomicBody->getExprLoc();
6658  NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
6659  : AtomicBody->getSourceRange();
6660  }
6661  } else {
6662  ErrorFound = NotAnExpression;
6663  NoteLoc = ErrorLoc = Body->getBeginLoc();
6664  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
6665  }
6666  if (ErrorFound != NoError) {
6667  Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
6668  << ErrorRange;
6669  Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
6670  << NoteRange;
6671  return StmtError();
6672  }
6673  if (CurContext->isDependentContext())
6674  V = X = nullptr;
6675  } else if (AtomicKind == OMPC_write) {
6676  enum {
6677  NotAnExpression,
6678  NotAnAssignmentOp,
6679  NotAScalarType,
6680  NotAnLValue,
6681  NoError
6682  } ErrorFound = NoError;
6683  SourceLocation ErrorLoc, NoteLoc;
6684  SourceRange ErrorRange, NoteRange;
6685  // If clause is write:
6686  // x = expr;
6687  if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
6688  const auto *AtomicBinOp =
6689  dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
6690  if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
6691  X = AtomicBinOp->getLHS();
6692  E = AtomicBinOp->getRHS();
6693  if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
6694  (E->isInstantiationDependent() || E->getType()->isScalarType())) {
6695  if (!X->isLValue()) {
6696  ErrorFound = NotAnLValue;
6697  ErrorLoc = AtomicBinOp->getExprLoc();
6698  ErrorRange = AtomicBinOp->getSourceRange();
6699  NoteLoc = X->getExprLoc();
6700  NoteRange = X->getSourceRange();
6701  }
6702  } else if (!X->isInstantiationDependent() ||
6703  !E->isInstantiationDependent()) {
6704  const Expr *NotScalarExpr =
6706  ? E
6707  : X;
6708  ErrorFound = NotAScalarType;
6709  ErrorLoc = AtomicBinOp->getExprLoc();
6710  ErrorRange = AtomicBinOp->getSourceRange();
6711  NoteLoc = NotScalarExpr->getExprLoc();
6712  NoteRange = NotScalarExpr->getSourceRange();
6713  }
6714  } else if (!AtomicBody->isInstantiationDependent()) {
6715  ErrorFound = NotAnAssignmentOp;
6716  ErrorLoc = AtomicBody->getExprLoc();
6717  ErrorRange = AtomicBody->getSourceRange();
6718  NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
6719  : AtomicBody->getExprLoc();
6720  NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
6721  : AtomicBody->getSourceRange();
6722  }
6723  } else {
6724  ErrorFound = NotAnExpression;
6725  NoteLoc = ErrorLoc = Body->getBeginLoc();
6726  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
6727  }
6728  if (ErrorFound != NoError) {
6729  Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
6730  << ErrorRange;
6731  Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
6732  << NoteRange;
6733  return StmtError();
6734  }
6735  if (CurContext->isDependentContext())
6736  E = X = nullptr;
6737  } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
6738  // If clause is update:
6739  // x++;
6740  // x--;
6741  // ++x;
6742  // --x;
6743  // x binop= expr;
6744  // x = x binop expr;
6745  // x = expr binop x;
6746  OpenMPAtomicUpdateChecker Checker(*this);
6747  if (Checker.checkStatement(
6748  Body, (AtomicKind == OMPC_update)
6749  ? diag::err_omp_atomic_update_not_expression_statement
6750  : diag::err_omp_atomic_not_expression_statement,
6751  diag::note_omp_atomic_update))
6752  return StmtError();
6753  if (!CurContext->isDependentContext()) {
6754  E = Checker.getExpr();
6755  X = Checker.getX();
6756  UE = Checker.getUpdateExpr();
6757  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6758  }
6759  } else if (AtomicKind == OMPC_capture) {
6760  enum {
6761  NotAnAssignmentOp,
6762  NotACompoundStatement,
6763  NotTwoSubstatements,
6764  NotASpecificExpression,
6765  NoError
6766  } ErrorFound = NoError;
6767  SourceLocation ErrorLoc, NoteLoc;
6768  SourceRange ErrorRange, NoteRange;
6769  if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
6770  // If clause is a capture:
6771  // v = x++;
6772  // v = x--;
6773  // v = ++x;
6774  // v = --x;
6775  // v = x binop= expr;
6776  // v = x = x binop expr;
6777  // v = x = expr binop x;
6778  const auto *AtomicBinOp =
6779  dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
6780  if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
6781  V = AtomicBinOp->getLHS();
6782  Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
6783  OpenMPAtomicUpdateChecker Checker(*this);
6784  if (Checker.checkStatement(
6785  Body, diag::err_omp_atomic_capture_not_expression_statement,
6786  diag::note_omp_atomic_update))
6787  return StmtError();
6788  E = Checker.getExpr();
6789  X = Checker.getX();
6790  UE = Checker.getUpdateExpr();
6791  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6792  IsPostfixUpdate = Checker.isPostfixUpdate();
6793  } else if (!AtomicBody->isInstantiationDependent()) {
6794  ErrorLoc = AtomicBody->getExprLoc();
6795  ErrorRange = AtomicBody->getSourceRange();
6796  NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
6797  : AtomicBody->getExprLoc();
6798  NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
6799  : AtomicBody->getSourceRange();
6800  ErrorFound = NotAnAssignmentOp;
6801  }
6802  if (ErrorFound != NoError) {
6803  Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
6804  << ErrorRange;
6805  Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
6806  return StmtError();
6807  }
6808  if (CurContext->isDependentContext())
6809  UE = V = E = X = nullptr;
6810  } else {
6811  // If clause is a capture:
6812  // { v = x; x = expr; }
6813  // { v = x; x++; }
6814  // { v = x; x--; }
6815  // { v = x; ++x; }
6816  // { v = x; --x; }
6817  // { v = x; x binop= expr; }
6818  // { v = x; x = x binop expr; }
6819  // { v = x; x = expr binop x; }
6820  // { x++; v = x; }
6821  // { x--; v = x; }
6822  // { ++x; v = x; }
6823  // { --x; v = x; }
6824  // { x binop= expr; v = x; }
6825  // { x = x binop expr; v = x; }
6826  // { x = expr binop x; v = x; }
6827  if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
6828  // Check that this is { expr1; expr2; }
6829  if (CS->size() == 2) {
6830  Stmt *First = CS->body_front();
6831  Stmt *Second = CS->body_back();
6832  if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
6833  First = EWC->getSubExpr()->IgnoreParenImpCasts();
6834  if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
6835  Second = EWC->getSubExpr()->IgnoreParenImpCasts();
6836  // Need to find what subexpression is 'v' and what is 'x'.
6837  OpenMPAtomicUpdateChecker Checker(*this);
6838  bool IsUpdateExprFound = !Checker.checkStatement(Second);
6839  BinaryOperator *BinOp = nullptr;
6840  if (IsUpdateExprFound) {
6841  BinOp = dyn_cast<BinaryOperator>(First);
6842  IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
6843  }
6844  if (IsUpdateExprFound && !CurContext->isDependentContext()) {
6845  // { v = x; x++; }
6846  // { v = x; x--; }
6847  // { v = x; ++x; }
6848  // { v = x; --x; }
6849  // { v = x; x binop= expr; }
6850  // { v = x; x = x binop expr; }
6851  // { v = x; x = expr binop x; }
6852  // Check that the first expression has form v = x.
6853  Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
6854  llvm::FoldingSetNodeID XId, PossibleXId;
6855  Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
6856  PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
6857  IsUpdateExprFound = XId == PossibleXId;
6858  if (IsUpdateExprFound) {
6859  V = BinOp->getLHS();
6860  X = Checker.getX();
6861  E = Checker.getExpr();
6862  UE = Checker.getUpdateExpr();
6863  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6864  IsPostfixUpdate = true;
6865  }
6866  }
6867  if (!IsUpdateExprFound) {
6868  IsUpdateExprFound = !Checker.checkStatement(First);
6869  BinOp = nullptr;
6870  if (IsUpdateExprFound) {
6871  BinOp = dyn_cast<BinaryOperator>(Second);
6872  IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
6873  }
6874  if (IsUpdateExprFound && !CurContext->isDependentContext()) {
6875  // { x++; v = x; }
6876  // { x--; v = x; }
6877  // { ++x; v = x; }
6878  // { --x; v = x; }
6879  // { x binop= expr; v = x; }
6880  // { x = x binop expr; v = x; }
6881  // { x = expr binop x; v = x; }
6882  // Check that the second expression has form v = x.
6883  Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
6884  llvm::FoldingSetNodeID XId, PossibleXId;
6885  Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
6886  PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
6887  IsUpdateExprFound = XId == PossibleXId;
6888  if (IsUpdateExprFound) {
6889  V = BinOp->getLHS();
6890  X = Checker.getX();
6891  E = Checker.getExpr();
6892  UE = Checker.getUpdateExpr();
6893  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
6894  IsPostfixUpdate = false;
6895  }
6896  }
6897  }
6898  if (!IsUpdateExprFound) {
6899  // { v = x; x = expr; }
6900  auto *FirstExpr = dyn_cast<Expr>(First);
6901  auto *SecondExpr = dyn_cast<Expr>(Second);
6902  if (!FirstExpr || !SecondExpr ||
6903  !(FirstExpr->isInstantiationDependent() ||
6904  SecondExpr->isInstantiationDependent())) {
6905  auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
6906  if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
6907  ErrorFound = NotAnAssignmentOp;
6908  NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
6909  : First->getBeginLoc();
6910  NoteRange = ErrorRange = FirstBinOp
6911  ? FirstBinOp->getSourceRange()
6912  : SourceRange(ErrorLoc, ErrorLoc);
6913  } else {
6914  auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
6915  if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
6916  ErrorFound = NotAnAssignmentOp;
6917  NoteLoc = ErrorLoc = SecondBinOp
6918  ? SecondBinOp->getOperatorLoc()
6919  : Second->getBeginLoc();
6920  NoteRange = ErrorRange =
6921  SecondBinOp ? SecondBinOp->getSourceRange()
6922  : SourceRange(ErrorLoc, ErrorLoc);
6923  } else {
6924  Expr *PossibleXRHSInFirst =
6925  FirstBinOp->getRHS()->IgnoreParenImpCasts();
6926  Expr *PossibleXLHSInSecond =
6927  SecondBinOp->getLHS()->IgnoreParenImpCasts();
6928  llvm::FoldingSetNodeID X1Id, X2Id;
6929  PossibleXRHSInFirst->Profile(X1Id, Context,
6930  /*Canonical=*/true);
6931  PossibleXLHSInSecond->Profile(X2Id, Context,
6932  /*Canonical=*/true);
6933  IsUpdateExprFound = X1Id == X2Id;
6934  if (IsUpdateExprFound) {
6935  V = FirstBinOp->getLHS();
6936  X = SecondBinOp->getLHS();
6937  E = SecondBinOp->getRHS();
6938  UE = nullptr;
6939  IsXLHSInRHSPart = false;
6940  IsPostfixUpdate = true;
6941  } else {
6942  ErrorFound = NotASpecificExpression;
6943  ErrorLoc = FirstBinOp->getExprLoc();
6944  ErrorRange = FirstBinOp->getSourceRange();
6945  NoteLoc = SecondBinOp->getLHS()->getExprLoc();
6946  NoteRange = SecondBinOp->getRHS()->getSourceRange();
6947  }
6948  }
6949  }
6950  }
6951  }
6952  } else {
6953  NoteLoc = ErrorLoc = Body->getBeginLoc();
6954  NoteRange = ErrorRange =
6955  SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
6956  ErrorFound = NotTwoSubstatements;
6957  }
6958  } else {
6959  NoteLoc = ErrorLoc = Body->getBeginLoc();
6960  NoteRange = ErrorRange =
6961  SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
6962  ErrorFound = NotACompoundStatement;
6963  }
6964  if (ErrorFound != NoError) {
6965  Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
6966  << ErrorRange;
6967  Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
6968  return StmtError();
6969  }
6970  if (CurContext->isDependentContext())
6971  UE = V = E = X = nullptr;
6972  }
6973  }
6974 
6975  setFunctionHasBranchProtectedScope();
6976 
6977  return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
6978  X, V, E, UE, IsXLHSInRHSPart,
6979  IsPostfixUpdate);
6980 }
6981 
6983  Stmt *AStmt,
6984  SourceLocation StartLoc,
6985  SourceLocation EndLoc) {
6986  if (!AStmt)
6987  return StmtError();
6988 
6989  auto *CS = cast<CapturedStmt>(AStmt);
6990  // 1.2.2 OpenMP Language Terminology
6991  // Structured block - An executable statement with a single entry at the
6992  // top and a single exit at the bottom.
6993  // The point of exit cannot be a branch out of the structured block.
6994  // longjmp() and throw() must not violate the entry/exit criteria.
6995  CS->getCapturedDecl()->setNothrow();
6996  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
6997  ThisCaptureLevel > 1; --ThisCaptureLevel) {
6998  CS = cast<CapturedStmt>(CS->getCapturedStmt());
6999  // 1.2.2 OpenMP Language Terminology
7000  // Structured block - An executable statement with a single entry at the
7001  // top and a single exit at the bottom.
7002  // The point of exit cannot be a branch out of the structured block.
7003  // longjmp() and throw() must not violate the entry/exit criteria.
7004  CS->getCapturedDecl()->setNothrow();
7005  }
7006 
7007  // OpenMP [2.16, Nesting of Regions]
7008  // If specified, a teams construct must be contained within a target
7009  // construct. That target construct must contain no statements or directives
7010  // outside of the teams construct.
7011  if (DSAStack->hasInnerTeamsRegion()) {
7012  const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
7013  bool OMPTeamsFound = true;
7014  if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
7015  auto I = CS->body_begin();
7016  while (I != CS->body_end()) {
7017  const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
7018  if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind())) {
7019  OMPTeamsFound = false;
7020  break;
7021  }
7022  ++I;
7023  }
7024  assert(I != CS->body_end() && "Not found statement");
7025  S = *I;
7026  } else {
7027  const auto *OED = dyn_cast<OMPExecutableDirective>(S);
7028  OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
7029  }
7030  if (!OMPTeamsFound) {
7031  Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
7032  Diag(DSAStack->getInnerTeamsRegionLoc(),
7033  diag::note_omp_nested_teams_construct_here);
7034  Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
7035  << isa<OMPExecutableDirective>(S);
7036  return StmtError();
7037  }
7038  }
7039 
7040  setFunctionHasBranchProtectedScope();
7041 
7042  return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
7043 }
7044 
7045 StmtResult
7047  Stmt *AStmt, SourceLocation StartLoc,
7048  SourceLocation EndLoc) {
7049  if (!AStmt)
7050  return StmtError();
7051 
7052  auto *CS = cast<CapturedStmt>(AStmt);
7053  // 1.2.2 OpenMP Language Terminology
7054  // Structured block - An executable statement with a single entry at the
7055  // top and a single exit at the bottom.
7056  // The point of exit cannot be a branch out of the structured block.
7057  // longjmp() and throw() must not violate the entry/exit criteria.
7058  CS->getCapturedDecl()->setNothrow();
7059  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
7060  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7061  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7062  // 1.2.2 OpenMP Language Terminology
7063  // Structured block - An executable statement with a single entry at the
7064  // top and a single exit at the bottom.
7065  // The point of exit cannot be a branch out of the structured block.
7066  // longjmp() and throw() must not violate the entry/exit criteria.
7067  CS->getCapturedDecl()->setNothrow();
7068  }
7069 
7070  setFunctionHasBranchProtectedScope();
7071 
7072  return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses,
7073  AStmt);
7074 }
7075 
7077  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7078  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7079  if (!AStmt)
7080  return StmtError();
7081 
7082  auto *CS = cast<CapturedStmt>(AStmt);
7083  // 1.2.2 OpenMP Language Terminology
7084  // Structured block - An executable statement with a single entry at the
7085  // top and a single exit at the bottom.
7086  // The point of exit cannot be a branch out of the structured block.
7087  // longjmp() and throw() must not violate the entry/exit criteria.
7088  CS->getCapturedDecl()->setNothrow();
7089  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
7090  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7091  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7092  // 1.2.2 OpenMP Language Terminology
7093  // Structured block - An executable statement with a single entry at the
7094  // top and a single exit at the bottom.
7095  // The point of exit cannot be a branch out of the structured block.
7096  // longjmp() and throw() must not violate the entry/exit criteria.
7097  CS->getCapturedDecl()->setNothrow();
7098  }
7099 
7101  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7102  // define the nested loops number.
7103  unsigned NestedLoopCount =
7104  checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
7105  getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
7106  VarsWithImplicitDSA, B);
7107  if (NestedLoopCount == 0)
7108  return StmtError();
7109 
7110  assert((CurContext->isDependentContext() || B.builtAll()) &&
7111  "omp target parallel for loop exprs were not built");
7112 
7113  if (!CurContext->isDependentContext()) {
7114  // Finalize the clauses that need pre-built expressions for CodeGen.
7115  for (OMPClause *C : Clauses) {
7116  if (auto *LC = dyn_cast<OMPLinearClause>(C))
7117  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7118  B.NumIterations, *this, CurScope,
7119  DSAStack))
7120  return StmtError();
7121  }
7122  }
7123 
7124  setFunctionHasBranchProtectedScope();
7125  return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc,
7126  NestedLoopCount, Clauses, AStmt,
7127  B, DSAStack->isCancelRegion());
7128 }
7129 
7130 /// Check for existence of a map clause in the list of clauses.
7131 static bool hasClauses(ArrayRef<OMPClause *> Clauses,
7132  const OpenMPClauseKind K) {
7133  return llvm::any_of(
7134  Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
7135 }
7136 
7137 template <typename... Params>
7139  const Params... ClauseTypes) {
7140  return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
7141 }
7142 
7144  Stmt *AStmt,
7145  SourceLocation StartLoc,
7146  SourceLocation EndLoc) {
7147  if (!AStmt)
7148  return StmtError();
7149 
7150  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
7151 
7152  // OpenMP [2.10.1, Restrictions, p. 97]
7153  // At least one map clause must appear on the directive.
7154  if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) {
7155  Diag(StartLoc, diag::err_omp_no_clause_for_directive)
7156  << "'map' or 'use_device_ptr'"
7157  << getOpenMPDirectiveName(OMPD_target_data);
7158  return StmtError();
7159  }
7160 
7161  setFunctionHasBranchProtectedScope();
7162 
7163  return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
7164  AStmt);
7165 }
7166 
7167 StmtResult
7169  SourceLocation StartLoc,
7170  SourceLocation EndLoc, Stmt *AStmt) {
7171  if (!AStmt)
7172  return StmtError();
7173 
7174  auto *CS = cast<CapturedStmt>(AStmt);
7175  // 1.2.2 OpenMP Language Terminology
7176  // Structured block - An executable statement with a single entry at the
7177  // top and a single exit at the bottom.
7178  // The point of exit cannot be a branch out of the structured block.
7179  // longjmp() and throw() must not violate the entry/exit criteria.
7180  CS->getCapturedDecl()->setNothrow();
7181  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
7182  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7183  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7184  // 1.2.2 OpenMP Language Terminology
7185  // Structured block - An executable statement with a single entry at the
7186  // top and a single exit at the bottom.
7187  // The point of exit cannot be a branch out of the structured block.
7188  // longjmp() and throw() must not violate the entry/exit criteria.
7189  CS->getCapturedDecl()->setNothrow();
7190  }
7191 
7192  // OpenMP [2.10.2, Restrictions, p. 99]
7193  // At least one map clause must appear on the directive.
7194  if (!hasClauses(Clauses, OMPC_map)) {
7195  Diag(StartLoc, diag::err_omp_no_clause_for_directive)
7196  << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
7197  return StmtError();
7198  }
7199 
7200  return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
7201  AStmt);
7202 }
7203 
7204 StmtResult
7206  SourceLocation StartLoc,
7207  SourceLocation EndLoc, Stmt *AStmt) {
7208  if (!AStmt)
7209  return StmtError();
7210 
7211  auto *CS = cast<CapturedStmt>(AStmt);
7212  // 1.2.2 OpenMP Language Terminology
7213  // Structured block - An executable statement with a single entry at the
7214  // top and a single exit at the bottom.
7215  // The point of exit cannot be a branch out of the structured block.
7216  // longjmp() and throw() must not violate the entry/exit criteria.
7217  CS->getCapturedDecl()->setNothrow();
7218  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
7219  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7220  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7221  // 1.2.2 OpenMP Language Terminology
7222  // Structured block - An executable statement with a single entry at the
7223  // top and a single exit at the bottom.
7224  // The point of exit cannot be a branch out of the structured block.
7225  // longjmp() and throw() must not violate the entry/exit criteria.
7226  CS->getCapturedDecl()->setNothrow();
7227  }
7228 
7229  // OpenMP [2.10.3, Restrictions, p. 102]
7230  // At least one map clause must appear on the directive.
7231  if (!hasClauses(Clauses, OMPC_map)) {
7232  Diag(StartLoc, diag::err_omp_no_clause_for_directive)
7233  << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
7234  return StmtError();
7235  }
7236 
7237  return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
7238  AStmt);
7239 }
7240 
7242  SourceLocation StartLoc,
7243  SourceLocation EndLoc,
7244  Stmt *AStmt) {
7245  if (!AStmt)
7246  return StmtError();
7247 
7248  auto *CS = cast<CapturedStmt>(AStmt);
7249  // 1.2.2 OpenMP Language Terminology
7250  // Structured block - An executable statement with a single entry at the
7251  // top and a single exit at the bottom.
7252  // The point of exit cannot be a branch out of the structured block.
7253  // longjmp() and throw() must not violate the entry/exit criteria.
7254  CS->getCapturedDecl()->setNothrow();
7255  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
7256  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7257  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7258  // 1.2.2 OpenMP Language Terminology
7259  // Structured block - An executable statement with a single entry at the
7260  // top and a single exit at the bottom.
7261  // The point of exit cannot be a branch out of the structured block.
7262  // longjmp() and throw() must not violate the entry/exit criteria.
7263  CS->getCapturedDecl()->setNothrow();
7264  }
7265 
7266  if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
7267  Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
7268  return StmtError();
7269  }
7270  return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
7271  AStmt);
7272 }
7273 
7275  Stmt *AStmt, SourceLocation StartLoc,
7276  SourceLocation EndLoc) {
7277  if (!AStmt)
7278  return StmtError();
7279 
7280  auto *CS = cast<CapturedStmt>(AStmt);
7281  // 1.2.2 OpenMP Language Terminology
7282  // Structured block - An executable statement with a single entry at the
7283  // top and a single exit at the bottom.
7284  // The point of exit cannot be a branch out of the structured block.
7285  // longjmp() and throw() must not violate the entry/exit criteria.
7286  CS->getCapturedDecl()->setNothrow();
7287 
7288  setFunctionHasBranchProtectedScope();
7289 
7290  DSAStack->setParentTeamsRegionLoc(StartLoc);
7291 
7292  return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
7293 }
7294 
7295 StmtResult
7297  SourceLocation EndLoc,
7298  OpenMPDirectiveKind CancelRegion) {
7299  if (DSAStack->isParentNowaitRegion()) {
7300  Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
7301  return StmtError();
7302  }
7303  if (DSAStack->isParentOrderedRegion()) {
7304  Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
7305  return StmtError();
7306  }
7307  return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
7308  CancelRegion);
7309 }
7310 
7312  SourceLocation StartLoc,
7313  SourceLocation EndLoc,
7314  OpenMPDirectiveKind CancelRegion) {
7315  if (DSAStack->isParentNowaitRegion()) {
7316  Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
7317  return StmtError();
7318  }
7319  if (DSAStack->isParentOrderedRegion()) {
7320  Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
7321  return StmtError();
7322  }
7323  DSAStack->setParentCancelRegion(/*Cancel=*/true);
7324  return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
7325  CancelRegion);
7326 }
7327 
7329  ArrayRef<OMPClause *> Clauses) {
7330  const OMPClause *PrevClause = nullptr;
7331  bool ErrorFound = false;
7332  for (const OMPClause *C : Clauses) {
7333  if (C->getClauseKind() == OMPC_grainsize ||
7334  C->getClauseKind() == OMPC_num_tasks) {
7335  if (!PrevClause)
7336  PrevClause = C;
7337  else if (PrevClause->getClauseKind() != C->getClauseKind()) {
7338  S.Diag(C->getBeginLoc(),
7339  diag::err_omp_grainsize_num_tasks_mutually_exclusive)
7340  << getOpenMPClauseName(C->getClauseKind())
7341  << getOpenMPClauseName(PrevClause->getClauseKind());
7342  S.Diag(PrevClause->getBeginLoc(),
7343  diag::note_omp_previous_grainsize_num_tasks)
7344  << getOpenMPClauseName(PrevClause->getClauseKind());
7345  ErrorFound = true;
7346  }
7347  }
7348  }
7349  return ErrorFound;
7350 }
7351 
7353  ArrayRef<OMPClause *> Clauses) {
7354  const OMPClause *ReductionClause = nullptr;
7355  const OMPClause *NogroupClause = nullptr;
7356  for (const OMPClause *C : Clauses) {
7357  if (C->getClauseKind() == OMPC_reduction) {
7358  ReductionClause = C;
7359  if (NogroupClause)
7360  break;
7361  continue;
7362  }
7363  if (C->getClauseKind() == OMPC_nogroup) {
7364  NogroupClause = C;
7365  if (ReductionClause)
7366  break;
7367  continue;
7368  }
7369  }
7370  if (ReductionClause && NogroupClause) {
7371  S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
7372  << SourceRange(NogroupClause->getBeginLoc(),
7373  NogroupClause->getEndLoc());
7374  return true;
7375  }
7376  return false;
7377 }
7378 
7380  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7381  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7382  if (!AStmt)
7383  return StmtError();
7384 
7385  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
7387  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7388  // define the nested loops number.
7389  unsigned NestedLoopCount =
7390  checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
7391  /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
7392  VarsWithImplicitDSA, B);
7393  if (NestedLoopCount == 0)
7394  return StmtError();
7395 
7396  assert((CurContext->isDependentContext() || B.builtAll()) &&
7397  "omp for loop exprs were not built");
7398 
7399  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
7400  // The grainsize clause and num_tasks clause are mutually exclusive and may
7401  // not appear on the same taskloop directive.
7402  if (checkGrainsizeNumTasksClauses(*this, Clauses))
7403  return StmtError();
7404  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
7405  // If a reduction clause is present on the taskloop directive, the nogroup
7406  // clause must not be specified.
7407  if (checkReductionClauseWithNogroup(*this, Clauses))
7408  return StmtError();
7409 
7410  setFunctionHasBranchProtectedScope();
7411  return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
7412  NestedLoopCount, Clauses, AStmt, B);
7413 }
7414 
7416  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7417  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7418  if (!AStmt)
7419  return StmtError();
7420 
7421  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
7423  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7424  // define the nested loops number.
7425  unsigned NestedLoopCount =
7426  checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
7427  /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
7428  VarsWithImplicitDSA, B);
7429  if (NestedLoopCount == 0)
7430  return StmtError();
7431 
7432  assert((CurContext->isDependentContext() || B.builtAll()) &&
7433  "omp for loop exprs were not built");
7434 
7435  if (!CurContext->isDependentContext()) {
7436  // Finalize the clauses that need pre-built expressions for CodeGen.
7437  for (OMPClause *C : Clauses) {
7438  if (auto *LC = dyn_cast<OMPLinearClause>(C))
7439  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7440  B.NumIterations, *this, CurScope,
7441  DSAStack))
7442  return StmtError();
7443  }
7444  }
7445 
7446  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
7447  // The grainsize clause and num_tasks clause are mutually exclusive and may
7448  // not appear on the same taskloop directive.
7449  if (checkGrainsizeNumTasksClauses(*this, Clauses))
7450  return StmtError();
7451  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
7452  // If a reduction clause is present on the taskloop directive, the nogroup
7453  // clause must not be specified.
7454  if (checkReductionClauseWithNogroup(*this, Clauses))
7455  return StmtError();
7456  if (checkSimdlenSafelenSpecified(*this, Clauses))
7457  return StmtError();
7458 
7459  setFunctionHasBranchProtectedScope();
7460  return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
7461  NestedLoopCount, Clauses, AStmt, B);
7462 }
7463 
7465  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7466  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7467  if (!AStmt)
7468  return StmtError();
7469 
7470  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
7472  // In presence of clause 'collapse' with number of loops, it will
7473  // define the nested loops number.
7474  unsigned NestedLoopCount =
7475  checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
7476  nullptr /*ordered not a clause on distribute*/, AStmt,
7477  *this, *DSAStack, VarsWithImplicitDSA, B);
7478  if (NestedLoopCount == 0)
7479  return StmtError();
7480 
7481  assert((CurContext->isDependentContext() || B.builtAll()) &&
7482  "omp for loop exprs were not built");
7483 
7484  setFunctionHasBranchProtectedScope();
7485  return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
7486  NestedLoopCount, Clauses, AStmt, B);
7487 }
7488 
7490  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7491  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7492  if (!AStmt)
7493  return StmtError();
7494 
7495  auto *CS = cast<CapturedStmt>(AStmt);
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  for (int ThisCaptureLevel =
7503  getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
7504  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7505  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7506  // 1.2.2 OpenMP Language Terminology
7507  // Structured block - An executable statement with a single entry at the
7508  // top and a single exit at the bottom.
7509  // The point of exit cannot be a branch out of the structured block.
7510  // longjmp() and throw() must not violate the entry/exit criteria.
7511  CS->getCapturedDecl()->setNothrow();
7512  }
7513 
7515  // In presence of clause 'collapse' with number of loops, it will
7516  // define the nested loops number.
7517  unsigned NestedLoopCount = checkOpenMPLoop(
7518  OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
7519  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7520  VarsWithImplicitDSA, B);
7521  if (NestedLoopCount == 0)
7522  return StmtError();
7523 
7524  assert((CurContext->isDependentContext() || B.builtAll()) &&
7525  "omp for loop exprs were not built");
7526 
7527  setFunctionHasBranchProtectedScope();
7529  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
7530  DSAStack->isCancelRegion());
7531 }
7532 
7534  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7535  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7536  if (!AStmt)
7537  return StmtError();
7538 
7539  auto *CS = cast<CapturedStmt>(AStmt);
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  for (int ThisCaptureLevel =
7547  getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
7548  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7549  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7550  // 1.2.2 OpenMP Language Terminology
7551  // Structured block - An executable statement with a single entry at the
7552  // top and a single exit at the bottom.
7553  // The point of exit cannot be a branch out of the structured block.
7554  // longjmp() and throw() must not violate the entry/exit criteria.
7555  CS->getCapturedDecl()->setNothrow();
7556  }
7557 
7559  // In presence of clause 'collapse' with number of loops, it will
7560  // define the nested loops number.
7561  unsigned NestedLoopCount = checkOpenMPLoop(
7562  OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
7563  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7564  VarsWithImplicitDSA, B);
7565  if (NestedLoopCount == 0)
7566  return StmtError();
7567 
7568  assert((CurContext->isDependentContext() || B.builtAll()) &&
7569  "omp for loop exprs were not built");
7570 
7571  if (!CurContext->isDependentContext()) {
7572  // Finalize the clauses that need pre-built expressions for CodeGen.
7573  for (OMPClause *C : Clauses) {
7574  if (auto *LC = dyn_cast<OMPLinearClause>(C))
7575  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7576  B.NumIterations, *this, CurScope,
7577  DSAStack))
7578  return StmtError();
7579  }
7580  }
7581 
7582  if (checkSimdlenSafelenSpecified(*this, Clauses))
7583  return StmtError();
7584 
7585  setFunctionHasBranchProtectedScope();
7587  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7588 }
7589 
7591  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7592  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7593  if (!AStmt)
7594  return StmtError();
7595 
7596  auto *CS = cast<CapturedStmt>(AStmt);
7597  // 1.2.2 OpenMP Language Terminology
7598  // Structured block - An executable statement with a single entry at the
7599  // top and a single exit at the bottom.
7600  // The point of exit cannot be a branch out of the structured block.
7601  // longjmp() and throw() must not violate the entry/exit criteria.
7602  CS->getCapturedDecl()->setNothrow();
7603  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
7604  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7605  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7606  // 1.2.2 OpenMP Language Terminology
7607  // Structured block - An executable statement with a single entry at the
7608  // top and a single exit at the bottom.
7609  // The point of exit cannot be a branch out of the structured block.
7610  // longjmp() and throw() must not violate the entry/exit criteria.
7611  CS->getCapturedDecl()->setNothrow();
7612  }
7613 
7615  // In presence of clause 'collapse' with number of loops, it will
7616  // define the nested loops number.
7617  unsigned NestedLoopCount =
7618  checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
7619  nullptr /*ordered not a clause on distribute*/, CS, *this,
7620  *DSAStack, VarsWithImplicitDSA, B);
7621  if (NestedLoopCount == 0)
7622  return StmtError();
7623 
7624  assert((CurContext->isDependentContext() || B.builtAll()) &&
7625  "omp for loop exprs were not built");
7626 
7627  if (!CurContext->isDependentContext()) {
7628  // Finalize the clauses that need pre-built expressions for CodeGen.
7629  for (OMPClause *C : Clauses) {
7630  if (auto *LC = dyn_cast<OMPLinearClause>(C))
7631  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7632  B.NumIterations, *this, CurScope,
7633  DSAStack))
7634  return StmtError();
7635  }
7636  }
7637 
7638  if (checkSimdlenSafelenSpecified(*this, Clauses))
7639  return StmtError();
7640 
7641  setFunctionHasBranchProtectedScope();
7642  return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
7643  NestedLoopCount, Clauses, AStmt, B);
7644 }
7645 
7647  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7648  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7649  if (!AStmt)
7650  return StmtError();
7651 
7652  auto *CS = cast<CapturedStmt>(AStmt);
7653  // 1.2.2 OpenMP Language Terminology
7654  // Structured block - An executable statement with a single entry at the
7655  // top and a single exit at the bottom.
7656  // The point of exit cannot be a branch out of the structured block.
7657  // longjmp() and throw() must not violate the entry/exit criteria.
7658  CS->getCapturedDecl()->setNothrow();
7659  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
7660  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7661  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7662  // 1.2.2 OpenMP Language Terminology
7663  // Structured block - An executable statement with a single entry at the
7664  // top and a single exit at the bottom.
7665  // The point of exit cannot be a branch out of the structured block.
7666  // longjmp() and throw() must not violate the entry/exit criteria.
7667  CS->getCapturedDecl()->setNothrow();
7668  }
7669 
7671  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
7672  // define the nested loops number.
7673  unsigned NestedLoopCount = checkOpenMPLoop(
7674  OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
7675  getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
7676  VarsWithImplicitDSA, B);
7677  if (NestedLoopCount == 0)
7678  return StmtError();
7679 
7680  assert((CurContext->isDependentContext() || B.builtAll()) &&
7681  "omp target parallel for simd loop exprs were not built");
7682 
7683  if (!CurContext->isDependentContext()) {
7684  // Finalize the clauses that need pre-built expressions for CodeGen.
7685  for (OMPClause *C : Clauses) {
7686  if (auto *LC = dyn_cast<OMPLinearClause>(C))
7687  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7688  B.NumIterations, *this, CurScope,
7689  DSAStack))
7690  return StmtError();
7691  }
7692  }
7693  if (checkSimdlenSafelenSpecified(*this, Clauses))
7694  return StmtError();
7695 
7696  setFunctionHasBranchProtectedScope();
7698  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7699 }
7700 
7702  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7703  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7704  if (!AStmt)
7705  return StmtError();
7706 
7707  auto *CS = cast<CapturedStmt>(AStmt);
7708  // 1.2.2 OpenMP Language Terminology
7709  // Structured block - An executable statement with a single entry at the
7710  // top and a single exit at the bottom.
7711  // The point of exit cannot be a branch out of the structured block.
7712  // longjmp() and throw() must not violate the entry/exit criteria.
7713  CS->getCapturedDecl()->setNothrow();
7714  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
7715  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7716  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7717  // 1.2.2 OpenMP Language Terminology
7718  // Structured block - An executable statement with a single entry at the
7719  // top and a single exit at the bottom.
7720  // The point of exit cannot be a branch out of the structured block.
7721  // longjmp() and throw() must not violate the entry/exit criteria.
7722  CS->getCapturedDecl()->setNothrow();
7723  }
7724 
7726  // In presence of clause 'collapse' with number of loops, it will define the
7727  // nested loops number.
7728  unsigned NestedLoopCount =
7729  checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
7730  getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
7731  VarsWithImplicitDSA, B);
7732  if (NestedLoopCount == 0)
7733  return StmtError();
7734 
7735  assert((CurContext->isDependentContext() || B.builtAll()) &&
7736  "omp target simd loop exprs were not built");
7737 
7738  if (!CurContext->isDependentContext()) {
7739  // Finalize the clauses that need pre-built expressions for CodeGen.
7740  for (OMPClause *C : Clauses) {
7741  if (auto *LC = dyn_cast<OMPLinearClause>(C))
7742  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7743  B.NumIterations, *this, CurScope,
7744  DSAStack))
7745  return StmtError();
7746  }
7747  }
7748 
7749  if (checkSimdlenSafelenSpecified(*this, Clauses))
7750  return StmtError();
7751 
7752  setFunctionHasBranchProtectedScope();
7753  return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
7754  NestedLoopCount, Clauses, AStmt, B);
7755 }
7756 
7758  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7759  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7760  if (!AStmt)
7761  return StmtError();
7762 
7763  auto *CS = cast<CapturedStmt>(AStmt);
7764  // 1.2.2 OpenMP Language Terminology
7765  // Structured block - An executable statement with a single entry at the
7766  // top and a single exit at the bottom.
7767  // The point of exit cannot be a branch out of the structured block.
7768  // longjmp() and throw() must not violate the entry/exit criteria.
7769  CS->getCapturedDecl()->setNothrow();
7770  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
7771  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7772  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7773  // 1.2.2 OpenMP Language Terminology
7774  // Structured block - An executable statement with a single entry at the
7775  // top and a single exit at the bottom.
7776  // The point of exit cannot be a branch out of the structured block.
7777  // longjmp() and throw() must not violate the entry/exit criteria.
7778  CS->getCapturedDecl()->setNothrow();
7779  }
7780 
7782  // In presence of clause 'collapse' with number of loops, it will
7783  // define the nested loops number.
7784  unsigned NestedLoopCount =
7785  checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
7786  nullptr /*ordered not a clause on distribute*/, CS, *this,
7787  *DSAStack, VarsWithImplicitDSA, B);
7788  if (NestedLoopCount == 0)
7789  return StmtError();
7790 
7791  assert((CurContext->isDependentContext() || B.builtAll()) &&
7792  "omp teams distribute loop exprs were not built");
7793 
7794  setFunctionHasBranchProtectedScope();
7795 
7796  DSAStack->setParentTeamsRegionLoc(StartLoc);
7797 
7799  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7800 }
7801 
7803  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7804  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7805  if (!AStmt)
7806  return StmtError();
7807 
7808  auto *CS = cast<CapturedStmt>(AStmt);
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  for (int ThisCaptureLevel =
7816  getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
7817  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7818  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7819  // 1.2.2 OpenMP Language Terminology
7820  // Structured block - An executable statement with a single entry at the
7821  // top and a single exit at the bottom.
7822  // The point of exit cannot be a branch out of the structured block.
7823  // longjmp() and throw() must not violate the entry/exit criteria.
7824  CS->getCapturedDecl()->setNothrow();
7825  }
7826 
7827 
7829  // In presence of clause 'collapse' with number of loops, it will
7830  // define the nested loops number.
7831  unsigned NestedLoopCount = checkOpenMPLoop(
7832  OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
7833  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7834  VarsWithImplicitDSA, B);
7835 
7836  if (NestedLoopCount == 0)
7837  return StmtError();
7838 
7839  assert((CurContext->isDependentContext() || B.builtAll()) &&
7840  "omp teams distribute simd loop exprs were not built");
7841 
7842  if (!CurContext->isDependentContext()) {
7843  // Finalize the clauses that need pre-built expressions for CodeGen.
7844  for (OMPClause *C : Clauses) {
7845  if (auto *LC = dyn_cast<OMPLinearClause>(C))
7846  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7847  B.NumIterations, *this, CurScope,
7848  DSAStack))
7849  return StmtError();
7850  }
7851  }
7852 
7853  if (checkSimdlenSafelenSpecified(*this, Clauses))
7854  return StmtError();
7855 
7856  setFunctionHasBranchProtectedScope();
7857 
7858  DSAStack->setParentTeamsRegionLoc(StartLoc);
7859 
7861  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7862 }
7863 
7865  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7866  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7867  if (!AStmt)
7868  return StmtError();
7869 
7870  auto *CS = cast<CapturedStmt>(AStmt);
7871  // 1.2.2 OpenMP Language Terminology
7872  // Structured block - An executable statement with a single entry at the
7873  // top and a single exit at the bottom.
7874  // The point of exit cannot be a branch out of the structured block.
7875  // longjmp() and throw() must not violate the entry/exit criteria.
7876  CS->getCapturedDecl()->setNothrow();
7877 
7878  for (int ThisCaptureLevel =
7879  getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
7880  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7881  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7882  // 1.2.2 OpenMP Language Terminology
7883  // Structured block - An executable statement with a single entry at the
7884  // top and a single exit at the bottom.
7885  // The point of exit cannot be a branch out of the structured block.
7886  // longjmp() and throw() must not violate the entry/exit criteria.
7887  CS->getCapturedDecl()->setNothrow();
7888  }
7889 
7891  // In presence of clause 'collapse' with number of loops, it will
7892  // define the nested loops number.
7893  unsigned NestedLoopCount = checkOpenMPLoop(
7894  OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
7895  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7896  VarsWithImplicitDSA, B);
7897 
7898  if (NestedLoopCount == 0)
7899  return StmtError();
7900 
7901  assert((CurContext->isDependentContext() || B.builtAll()) &&
7902  "omp for loop exprs were not built");
7903 
7904  if (!CurContext->isDependentContext()) {
7905  // Finalize the clauses that need pre-built expressions for CodeGen.
7906  for (OMPClause *C : Clauses) {
7907  if (auto *LC = dyn_cast<OMPLinearClause>(C))
7908  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
7909  B.NumIterations, *this, CurScope,
7910  DSAStack))
7911  return StmtError();
7912  }
7913  }
7914 
7915  if (checkSimdlenSafelenSpecified(*this, Clauses))
7916  return StmtError();
7917 
7918  setFunctionHasBranchProtectedScope();
7919 
7920  DSAStack->setParentTeamsRegionLoc(StartLoc);
7921 
7923  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
7924 }
7925 
7927  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
7928  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
7929  if (!AStmt)
7930  return StmtError();
7931 
7932  auto *CS = cast<CapturedStmt>(AStmt);
7933  // 1.2.2 OpenMP Language Terminology
7934  // Structured block - An executable statement with a single entry at the
7935  // top and a single exit at the bottom.
7936  // The point of exit cannot be a branch out of the structured block.
7937  // longjmp() and throw() must not violate the entry/exit criteria.
7938  CS->getCapturedDecl()->setNothrow();
7939 
7940  for (int ThisCaptureLevel =
7941  getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
7942  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7943  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7944  // 1.2.2 OpenMP Language Terminology
7945  // Structured block - An executable statement with a single entry at the
7946  // top and a single exit at the bottom.
7947  // The point of exit cannot be a branch out of the structured block.
7948  // longjmp() and throw() must not violate the entry/exit criteria.
7949  CS->getCapturedDecl()->setNothrow();
7950  }
7951 
7953  // In presence of clause 'collapse' with number of loops, it will
7954  // define the nested loops number.
7955  unsigned NestedLoopCount = checkOpenMPLoop(
7956  OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
7957  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
7958  VarsWithImplicitDSA, B);
7959 
7960  if (NestedLoopCount == 0)
7961  return StmtError();
7962 
7963  assert((CurContext->isDependentContext() || B.builtAll()) &&
7964  "omp for loop exprs were not built");
7965 
7966  setFunctionHasBranchProtectedScope();
7967 
7968  DSAStack->setParentTeamsRegionLoc(StartLoc);
7969 
7971  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
7972  DSAStack->isCancelRegion());
7973 }
7974 
7976  Stmt *AStmt,
7977  SourceLocation StartLoc,
7978  SourceLocation EndLoc) {
7979  if (!AStmt)
7980  return StmtError();
7981 
7982  auto *CS = cast<CapturedStmt>(AStmt);
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  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
7991  ThisCaptureLevel > 1; --ThisCaptureLevel) {
7992  CS = cast<CapturedStmt>(CS->getCapturedStmt());
7993  // 1.2.2 OpenMP Language Terminology
7994  // Structured block - An executable statement with a single entry at the
7995  // top and a single exit at the bottom.
7996  // The point of exit cannot be a branch out of the structured block.
7997  // longjmp() and throw() must not violate the entry/exit criteria.
7998  CS->getCapturedDecl()->setNothrow();
7999  }
8000  setFunctionHasBranchProtectedScope();
8001 
8002  return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
8003  AStmt);
8004 }
8005 
8007  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
8008  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8009  if (!AStmt)
8010  return StmtError();
8011 
8012  auto *CS = cast<CapturedStmt>(AStmt);
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  for (int ThisCaptureLevel =
8020  getOpenMPCaptureLevels(OMPD_target_teams_distribute);
8021  ThisCaptureLevel > 1; --ThisCaptureLevel) {
8022  CS = cast<CapturedStmt>(CS->getCapturedStmt());
8023  // 1.2.2 OpenMP Language Terminology
8024  // Structured block - An executable statement with a single entry at the
8025  // top and a single exit at the bottom.
8026  // The point of exit cannot be a branch out of the structured block.
8027  // longjmp() and throw() must not violate the entry/exit criteria.
8028  CS->getCapturedDecl()->setNothrow();
8029  }
8030 
8032  // In presence of clause 'collapse' with number of loops, it will
8033  // define the nested loops number.
8034  unsigned NestedLoopCount = checkOpenMPLoop(
8035  OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
8036  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
8037  VarsWithImplicitDSA, B);
8038  if (NestedLoopCount == 0)
8039  return StmtError();
8040 
8041  assert((CurContext->isDependentContext() || B.builtAll()) &&
8042  "omp target teams distribute loop exprs were not built");
8043 
8044  setFunctionHasBranchProtectedScope();
8046  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8047 }
8048 
8050  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
8051  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8052  if (!AStmt)
8053  return StmtError();
8054 
8055  auto *CS = cast<CapturedStmt>(AStmt);
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  for (int ThisCaptureLevel =
8063  getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
8064  ThisCaptureLevel > 1; --ThisCaptureLevel) {
8065  CS = cast<CapturedStmt>(CS->getCapturedStmt());
8066  // 1.2.2 OpenMP Language Terminology
8067  // Structured block - An executable statement with a single entry at the
8068  // top and a single exit at the bottom.
8069  // The point of exit cannot be a branch out of the structured block.
8070  // longjmp() and throw() must not violate the entry/exit criteria.
8071  CS->getCapturedDecl()->setNothrow();
8072  }
8073 
8075  // In presence of clause 'collapse' with number of loops, it will
8076  // define the nested loops number.
8077  unsigned NestedLoopCount = checkOpenMPLoop(
8078  OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
8079  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
8080  VarsWithImplicitDSA, B);
8081  if (NestedLoopCount == 0)
8082  return StmtError();
8083 
8084  assert((CurContext->isDependentContext() || B.builtAll()) &&
8085  "omp target teams distribute parallel for loop exprs were not built");
8086 
8087  if (!CurContext->isDependentContext()) {
8088  // Finalize the clauses that need pre-built expressions for CodeGen.
8089  for (OMPClause *C : Clauses) {
8090  if (auto *LC = dyn_cast<OMPLinearClause>(C))
8091  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8092  B.NumIterations, *this, CurScope,
8093  DSAStack))
8094  return StmtError();
8095  }
8096  }
8097 
8098  setFunctionHasBranchProtectedScope();
8100  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
8101  DSAStack->isCancelRegion());
8102 }
8103 
8105  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
8106  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8107  if (!AStmt)
8108  return StmtError();
8109 
8110  auto *CS = cast<CapturedStmt>(AStmt);
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  for (int ThisCaptureLevel = getOpenMPCaptureLevels(
8118  OMPD_target_teams_distribute_parallel_for_simd);
8119  ThisCaptureLevel > 1; --ThisCaptureLevel) {
8120  CS = cast<CapturedStmt>(CS->getCapturedStmt());
8121  // 1.2.2 OpenMP Language Terminology
8122  // Structured block - An executable statement with a single entry at the
8123  // top and a single exit at the bottom.
8124  // The point of exit cannot be a branch out of the structured block.
8125  // longjmp() and throw() must not violate the entry/exit criteria.
8126  CS->getCapturedDecl()->setNothrow();
8127  }
8128 
8130  // In presence of clause 'collapse' with number of loops, it will
8131  // define the nested loops number.
8132  unsigned NestedLoopCount =
8133  checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
8134  getCollapseNumberExpr(Clauses),
8135  nullptr /*ordered not a clause on distribute*/, CS, *this,
8136  *DSAStack, VarsWithImplicitDSA, B);
8137  if (NestedLoopCount == 0)
8138  return StmtError();
8139 
8140  assert((CurContext->isDependentContext() || B.builtAll()) &&
8141  "omp target teams distribute parallel for simd loop exprs were not "
8142  "built");
8143 
8144  if (!CurContext->isDependentContext()) {
8145  // Finalize the clauses that need pre-built expressions for CodeGen.
8146  for (OMPClause *C : Clauses) {
8147  if (auto *LC = dyn_cast<OMPLinearClause>(C))
8148  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8149  B.NumIterations, *this, CurScope,
8150  DSAStack))
8151  return StmtError();
8152  }
8153  }
8154 
8155  if (checkSimdlenSafelenSpecified(*this, Clauses))
8156  return StmtError();
8157 
8158  setFunctionHasBranchProtectedScope();
8160  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8161 }
8162 
8164  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
8165  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8166  if (!AStmt)
8167  return StmtError();
8168 
8169  auto *CS = cast<CapturedStmt>(AStmt);
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  for (int ThisCaptureLevel =
8177  getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
8178  ThisCaptureLevel > 1; --ThisCaptureLevel) {
8179  CS = cast<CapturedStmt>(CS->getCapturedStmt());
8180  // 1.2.2 OpenMP Language Terminology
8181  // Structured block - An executable statement with a single entry at the
8182  // top and a single exit at the bottom.
8183  // The point of exit cannot be a branch out of the structured block.
8184  // longjmp() and throw() must not violate the entry/exit criteria.
8185  CS->getCapturedDecl()->setNothrow();
8186  }
8187 
8189  // In presence of clause 'collapse' with number of loops, it will
8190  // define the nested loops number.
8191  unsigned NestedLoopCount = checkOpenMPLoop(
8192  OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
8193  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
8194  VarsWithImplicitDSA, B);
8195  if (NestedLoopCount == 0)
8196  return StmtError();
8197 
8198  assert((CurContext->isDependentContext() || B.builtAll()) &&
8199  "omp target teams distribute simd loop exprs were not built");
8200 
8201  if (!CurContext->isDependentContext()) {
8202  // Finalize the clauses that need pre-built expressions for CodeGen.
8203  for (OMPClause *C : Clauses) {
8204  if (auto *LC = dyn_cast<OMPLinearClause>(C))
8205  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8206  B.NumIterations, *this, CurScope,
8207  DSAStack))
8208  return StmtError();
8209  }
8210  }
8211 
8212  if (checkSimdlenSafelenSpecified(*this, Clauses))
8213  return StmtError();
8214 
8215  setFunctionHasBranchProtectedScope();
8217  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8218 }
8219 
8221  SourceLocation StartLoc,
8222  SourceLocation LParenLoc,
8223  SourceLocation EndLoc) {
8224  OMPClause *Res = nullptr;
8225  switch (Kind) {
8226  case OMPC_final:
8227  Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
8228  break;
8229  case OMPC_num_threads:
8230  Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
8231  break;
8232  case OMPC_safelen:
8233  Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
8234  break;
8235  case OMPC_simdlen:
8236  Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
8237  break;
8238  case OMPC_collapse:
8239  Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
8240  break;
8241  case OMPC_ordered:
8242  Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
8243  break;
8244  case OMPC_device:
8245  Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc);
8246  break;
8247  case OMPC_num_teams:
8248  Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
8249  break;
8250  case OMPC_thread_limit:
8251  Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
8252  break;
8253  case OMPC_priority:
8254  Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
8255  break;
8256  case OMPC_grainsize:
8257  Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
8258  break;
8259  case OMPC_num_tasks:
8260  Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
8261  break;
8262  case OMPC_hint:
8263  Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
8264  break;
8265  case OMPC_if:
8266  case OMPC_default:
8267  case OMPC_proc_bind:
8268  case OMPC_schedule:
8269  case OMPC_private:
8270  case OMPC_firstprivate:
8271  case OMPC_lastprivate:
8272  case OMPC_shared:
8273  case OMPC_reduction:
8274  case OMPC_task_reduction:
8275  case OMPC_in_reduction:
8276  case OMPC_linear:
8277  case OMPC_aligned:
8278  case OMPC_copyin:
8279  case OMPC_copyprivate:
8280  case OMPC_nowait:
8281  case OMPC_untied:
8282  case OMPC_mergeable:
8283  case OMPC_threadprivate:
8284  case OMPC_flush:
8285  case OMPC_read:
8286  case OMPC_write:
8287  case OMPC_update:
8288  case OMPC_capture:
8289  case OMPC_seq_cst:
8290  case OMPC_depend:
8291  case OMPC_threads:
8292  case OMPC_simd:
8293  case OMPC_map:
8294  case OMPC_nogroup:
8295  case OMPC_dist_schedule:
8296  case OMPC_defaultmap:
8297  case OMPC_unknown:
8298  case OMPC_uniform:
8299  case OMPC_to:
8300  case OMPC_from:
8301  case OMPC_use_device_ptr:
8302  case OMPC_is_device_ptr:
8303  case OMPC_unified_address:
8304  case OMPC_unified_shared_memory:
8305  case OMPC_reverse_offload:
8306  case OMPC_dynamic_allocators:
8307  case OMPC_atomic_default_mem_order:
8308  llvm_unreachable("Clause is not allowed.");
8309  }
8310  return Res;
8311 }
8312 
8313 // An OpenMP directive such as 'target parallel' has two captured regions:
8314 // for the 'target' and 'parallel' respectively. This function returns
8315 // the region in which to capture expressions associated with a clause.
8316 // A return value of OMPD_unknown signifies that the expression should not
8317 // be captured.
8320  OpenMPDirectiveKind NameModifier = OMPD_unknown) {
8321  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
8322  switch (CKind) {
8323  case OMPC_if:
8324  switch (DKind) {
8325  case OMPD_target_parallel:
8326  case OMPD_target_parallel_for:
8327  case OMPD_target_parallel_for_simd:
8328  // If this clause applies to the nested 'parallel' region, capture within
8329  // the 'target' region, otherwise do not capture.
8330  if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
8331  CaptureRegion = OMPD_target;
8332  break;
8333  case OMPD_target_teams_distribute_parallel_for:
8334  case OMPD_target_teams_distribute_parallel_for_simd:
8335  // If this clause applies to the nested 'parallel' region, capture within
8336  // the 'teams' region, otherwise do not capture.
8337  if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
8338  CaptureRegion = OMPD_teams;
8339  break;
8340  case OMPD_teams_distribute_parallel_for:
8341  case OMPD_teams_distribute_parallel_for_simd:
8342  CaptureRegion = OMPD_teams;
8343  break;
8344  case OMPD_target_update:
8345  case OMPD_target_enter_data:
8346  case OMPD_target_exit_data:
8347  CaptureRegion = OMPD_task;
8348  break;
8349  case OMPD_cancel:
8350  case OMPD_parallel:
8351  case OMPD_parallel_sections:
8352  case OMPD_parallel_for:
8353  case OMPD_parallel_for_simd:
8354  case OMPD_target:
8355  case OMPD_target_simd:
8356  case OMPD_target_teams:
8357  case OMPD_target_teams_distribute:
8358  case OMPD_target_teams_distribute_simd:
8359  case OMPD_distribute_parallel_for:
8360  case OMPD_distribute_parallel_for_simd:
8361  case OMPD_task:
8362  case OMPD_taskloop:
8363  case OMPD_taskloop_simd:
8364  case OMPD_target_data:
8365  // Do not capture if-clause expressions.
8366  break;
8367  case OMPD_threadprivate:
8368  case OMPD_taskyield:
8369  case OMPD_barrier:
8370  case OMPD_taskwait:
8371  case OMPD_cancellation_point:
8372  case OMPD_flush:
8373  case OMPD_declare_reduction:
8374  case OMPD_declare_simd:
8375  case OMPD_declare_target:
8376  case OMPD_end_declare_target:
8377  case OMPD_teams:
8378  case OMPD_simd:
8379  case OMPD_for:
8380  case OMPD_for_simd:
8381  case OMPD_sections:
8382  case OMPD_section:
8383  case OMPD_single:
8384  case OMPD_master:
8385  case OMPD_critical:
8386  case OMPD_taskgroup:
8387  case OMPD_distribute:
8388  case OMPD_ordered:
8389  case OMPD_atomic:
8390  case OMPD_distribute_simd:
8391  case OMPD_teams_distribute:
8392  case OMPD_teams_distribute_simd:
8393  case OMPD_requires:
8394  llvm_unreachable("Unexpected OpenMP directive with if-clause");
8395  case OMPD_unknown:
8396  llvm_unreachable("Unknown OpenMP directive");
8397  }
8398  break;
8399  case OMPC_num_threads:
8400  switch (DKind) {
8401  case OMPD_target_parallel:
8402  case OMPD_target_parallel_for:
8403  case OMPD_target_parallel_for_simd:
8404  CaptureRegion = OMPD_target;
8405  break;
8406  case OMPD_teams_distribute_parallel_for:
8407  case OMPD_teams_distribute_parallel_for_simd:
8408  case OMPD_target_teams_distribute_parallel_for:
8409  case OMPD_target_teams_distribute_parallel_for_simd:
8410  CaptureRegion = OMPD_teams;
8411  break;
8412  case OMPD_parallel:
8413  case OMPD_parallel_sections:
8414  case OMPD_parallel_for:
8415  case OMPD_parallel_for_simd:
8416  case OMPD_distribute_parallel_for:
8417  case OMPD_distribute_parallel_for_simd:
8418  // Do not capture num_threads-clause expressions.
8419  break;
8420  case OMPD_target_data:
8421  case OMPD_target_enter_data:
8422  case OMPD_target_exit_data:
8423  case OMPD_target_update:
8424  case OMPD_target:
8425  case OMPD_target_simd:
8426  case OMPD_target_teams:
8427  case OMPD_target_teams_distribute:
8428  case OMPD_target_teams_distribute_simd:
8429  case OMPD_cancel:
8430  case OMPD_task:
8431  case OMPD_taskloop:
8432  case OMPD_taskloop_simd:
8433  case OMPD_threadprivate:
8434  case OMPD_taskyield:
8435  case OMPD_barrier:
8436  case OMPD_taskwait:
8437  case OMPD_cancellation_point:
8438  case OMPD_flush:
8439  case OMPD_declare_reduction:
8440  case OMPD_declare_simd:
8441  case OMPD_declare_target:
8442  case OMPD_end_declare_target:
8443  case OMPD_teams:
8444  case OMPD_simd:
8445  case OMPD_for:
8446  case OMPD_for_simd:
8447  case OMPD_sections:
8448  case OMPD_section:
8449  case OMPD_single:
8450  case OMPD_master:
8451  case OMPD_critical:
8452  case OMPD_taskgroup:
8453  case OMPD_distribute:
8454  case OMPD_ordered:
8455  case OMPD_atomic:
8456  case OMPD_distribute_simd:
8457  case OMPD_teams_distribute:
8458  case OMPD_teams_distribute_simd:
8459  case OMPD_requires:
8460  llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
8461  case OMPD_unknown:
8462  llvm_unreachable("Unknown OpenMP directive");
8463  }
8464  break;
8465  case OMPC_num_teams:
8466  switch (DKind) {
8467  case OMPD_target_teams:
8468  case OMPD_target_teams_distribute:
8469  case OMPD_target_teams_distribute_simd:
8470  case OMPD_target_teams_distribute_parallel_for:
8471  case OMPD_target_teams_distribute_parallel_for_simd:
8472  CaptureRegion = OMPD_target;
8473  break;
8474  case OMPD_teams_distribute_parallel_for:
8475  case OMPD_teams_distribute_parallel_for_simd:
8476  case OMPD_teams:
8477  case OMPD_teams_distribute:
8478  case OMPD_teams_distribute_simd:
8479  // Do not capture num_teams-clause expressions.
8480  break;
8481  case OMPD_distribute_parallel_for:
8482  case OMPD_distribute_parallel_for_simd:
8483  case OMPD_task:
8484  case OMPD_taskloop:
8485  case OMPD_taskloop_simd:
8486  case OMPD_target_data:
8487  case OMPD_target_enter_data:
8488  case OMPD_target_exit_data:
8489  case OMPD_target_update:
8490  case OMPD_cancel:
8491  case OMPD_parallel:
8492  case OMPD_parallel_sections:
8493  case OMPD_parallel_for:
8494  case OMPD_parallel_for_simd:
8495  case OMPD_target:
8496  case OMPD_target_simd:
8497  case OMPD_target_parallel:
8498  case OMPD_target_parallel_for:
8499  case OMPD_target_parallel_for_simd:
8500  case OMPD_threadprivate:
8501  case OMPD_taskyield:
8502  case OMPD_barrier:
8503  case OMPD_taskwait:
8504  case OMPD_cancellation_point:
8505  case OMPD_flush:
8506  case OMPD_declare_reduction:
8507  case OMPD_declare_simd:
8508  case OMPD_declare_target:
8509  case OMPD_end_declare_target:
8510  case OMPD_simd:
8511  case OMPD_for:
8512  case OMPD_for_simd:
8513  case OMPD_sections:
8514  case OMPD_section:
8515  case OMPD_single:
8516  case OMPD_master:
8517  case OMPD_critical:
8518  case OMPD_taskgroup:
8519  case OMPD_distribute:
8520  case OMPD_ordered:
8521  case OMPD_atomic:
8522  case OMPD_distribute_simd:
8523  case OMPD_requires:
8524  llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
8525  case OMPD_unknown:
8526  llvm_unreachable("Unknown OpenMP directive");
8527  }
8528  break;
8529  case OMPC_thread_limit:
8530  switch (DKind) {
8531  case OMPD_target_teams:
8532  case OMPD_target_teams_distribute:
8533  case OMPD_target_teams_distribute_simd:
8534  case OMPD_target_teams_distribute_parallel_for:
8535  case OMPD_target_teams_distribute_parallel_for_simd:
8536  CaptureRegion = OMPD_target;
8537  break;
8538  case OMPD_teams_distribute_parallel_for:
8539  case OMPD_teams_distribute_parallel_for_simd:
8540  case OMPD_teams:
8541  case OMPD_teams_distribute:
8542  case OMPD_teams_distribute_simd:
8543  // Do not capture thread_limit-clause expressions.
8544  break;
8545  case OMPD_distribute_parallel_for:
8546  case OMPD_distribute_parallel_for_simd:
8547  case OMPD_task:
8548  case OMPD_taskloop:
8549  case OMPD_taskloop_simd:
8550  case OMPD_target_data:
8551  case OMPD_target_enter_data:
8552  case OMPD_target_exit_data:
8553  case OMPD_target_update:
8554  case OMPD_cancel:
8555  case OMPD_parallel:
8556  case OMPD_parallel_sections:
8557  case OMPD_parallel_for:
8558  case OMPD_parallel_for_simd:
8559  case OMPD_target:
8560  case OMPD_target_simd:
8561  case OMPD_target_parallel:
8562  case OMPD_target_parallel_for:
8563  case OMPD_target_parallel_for_simd:
8564  case OMPD_threadprivate:
8565  case OMPD_taskyield:
8566  case OMPD_barrier:
8567  case OMPD_taskwait:
8568  case OMPD_cancellation_point:
8569  case OMPD_flush:
8570  case OMPD_declare_reduction:
8571  case OMPD_declare_simd:
8572  case OMPD_declare_target:
8573  case OMPD_end_declare_target:
8574  case OMPD_simd:
8575  case OMPD_for:
8576  case OMPD_for_simd:
8577  case OMPD_sections:
8578  case OMPD_section:
8579  case OMPD_single:
8580  case OMPD_master:
8581  case OMPD_critical:
8582  case OMPD_taskgroup:
8583  case OMPD_distribute:
8584  case OMPD_ordered:
8585  case OMPD_atomic:
8586  case OMPD_distribute_simd:
8587  case OMPD_requires:
8588  llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
8589  case OMPD_unknown:
8590  llvm_unreachable("Unknown OpenMP directive");
8591  }
8592  break;
8593  case OMPC_schedule:
8594  switch (DKind) {
8595  case OMPD_parallel_for:
8596  case OMPD_parallel_for_simd:
8597  case OMPD_distribute_parallel_for:
8598  case OMPD_distribute_parallel_for_simd:
8599  case OMPD_teams_distribute_parallel_for:
8600  case OMPD_teams_distribute_parallel_for_simd:
8601  case OMPD_target_parallel_for:
8602  case OMPD_target_parallel_for_simd:
8603  case OMPD_target_teams_distribute_parallel_for:
8604  case OMPD_target_teams_distribute_parallel_for_simd:
8605  CaptureRegion = OMPD_parallel;
8606  break;
8607  case OMPD_for:
8608  case OMPD_for_simd:
8609  // Do not capture schedule-clause expressions.
8610  break;
8611  case OMPD_task:
8612  case OMPD_taskloop:
8613  case OMPD_taskloop_simd:
8614  case OMPD_target_data:
8615  case OMPD_target_enter_data:
8616  case OMPD_target_exit_data:
8617  case OMPD_target_update:
8618  case OMPD_teams:
8619  case OMPD_teams_distribute:
8620  case OMPD_teams_distribute_simd:
8621  case OMPD_target_teams_distribute:
8622  case OMPD_target_teams_distribute_simd:
8623  case OMPD_target:
8624  case OMPD_target_simd:
8625  case OMPD_target_parallel:
8626  case OMPD_cancel:
8627  case OMPD_parallel:
8628  case OMPD_parallel_sections:
8629  case OMPD_threadprivate:
8630  case OMPD_taskyield:
8631  case OMPD_barrier:
8632  case OMPD_taskwait:
8633  case OMPD_cancellation_point:
8634  case OMPD_flush:
8635  case OMPD_declare_reduction:
8636  case OMPD_declare_simd:
8637  case OMPD_declare_target:
8638  case OMPD_end_declare_target:
8639  case OMPD_simd:
8640  case OMPD_sections:
8641  case OMPD_section:
8642  case OMPD_single:
8643  case OMPD_master:
8644  case OMPD_critical:
8645  case OMPD_taskgroup:
8646  case OMPD_distribute:
8647  case OMPD_ordered:
8648  case OMPD_atomic:
8649  case OMPD_distribute_simd:
8650  case OMPD_target_teams:
8651  case OMPD_requires:
8652  llvm_unreachable("Unexpected OpenMP directive with schedule clause");
8653  case OMPD_unknown:
8654  llvm_unreachable("Unknown OpenMP directive");
8655  }
8656  break;
8657  case OMPC_dist_schedule:
8658  switch (DKind) {
8659  case OMPD_teams_distribute_parallel_for:
8660  case OMPD_teams_distribute_parallel_for_simd:
8661  case OMPD_teams_distribute:
8662  case OMPD_teams_distribute_simd:
8663  case OMPD_target_teams_distribute_parallel_for:
8664  case OMPD_target_teams_distribute_parallel_for_simd:
8665  case OMPD_target_teams_distribute:
8666  case OMPD_target_teams_distribute_simd:
8667  CaptureRegion = OMPD_teams;
8668  break;
8669  case OMPD_distribute_parallel_for:
8670  case OMPD_distribute_parallel_for_simd:
8671  case OMPD_distribute:
8672  case OMPD_distribute_simd:
8673  // Do not capture thread_limit-clause expressions.
8674  break;
8675  case OMPD_parallel_for:
8676  case OMPD_parallel_for_simd:
8677  case OMPD_target_parallel_for_simd:
8678  case OMPD_target_parallel_for:
8679  case OMPD_task:
8680  case OMPD_taskloop:
8681  case OMPD_taskloop_simd:
8682  case OMPD_target_data:
8683  case OMPD_target_enter_data:
8684  case OMPD_target_exit_data:
8685  case OMPD_target_update:
8686  case OMPD_teams:
8687  case OMPD_target:
8688  case OMPD_target_simd:
8689  case OMPD_target_parallel:
8690  case OMPD_cancel:
8691  case OMPD_parallel:
8692  case OMPD_parallel_sections:
8693  case OMPD_threadprivate:
8694  case OMPD_taskyield:
8695  case OMPD_barrier:
8696  case OMPD_taskwait:
8697  case OMPD_cancellation_point:
8698  case OMPD_flush:
8699  case OMPD_declare_reduction:
8700  case OMPD_declare_simd:
8701  case OMPD_declare_target:
8702  case OMPD_end_declare_target:
8703  case OMPD_simd:
8704  case OMPD_for:
8705  case OMPD_for_simd:
8706  case OMPD_sections:
8707  case OMPD_section:
8708  case OMPD_single:
8709  case OMPD_master:
8710  case OMPD_critical:
8711  case OMPD_taskgroup:
8712  case OMPD_ordered:
8713  case OMPD_atomic:
8714  case OMPD_target_teams:
8715  case OMPD_requires:
8716  llvm_unreachable("Unexpected OpenMP directive with schedule clause");
8717  case OMPD_unknown:
8718  llvm_unreachable("Unknown OpenMP directive");
8719  }
8720  break;
8721  case OMPC_device:
8722  switch (DKind) {
8723  case OMPD_target_update:
8724  case OMPD_target_enter_data:
8725  case OMPD_target_exit_data:
8726  case OMPD_target:
8727  case OMPD_target_simd:
8728  case OMPD_target_teams:
8729  case OMPD_target_parallel:
8730  case OMPD_target_teams_distribute:
8731  case OMPD_target_teams_distribute_simd:
8732  case OMPD_target_parallel_for:
8733  case OMPD_target_parallel_for_simd:
8734  case OMPD_target_teams_distribute_parallel_for:
8735  case OMPD_target_teams_distribute_parallel_for_simd:
8736  CaptureRegion = OMPD_task;
8737  break;
8738  case OMPD_target_data:
8739  // Do not capture device-clause expressions.
8740  break;
8741  case OMPD_teams_distribute_parallel_for:
8742  case OMPD_teams_distribute_parallel_for_simd:
8743  case OMPD_teams:
8744  case OMPD_teams_distribute:
8745  case OMPD_teams_distribute_simd:
8746  case OMPD_distribute_parallel_for:
8747  case OMPD_distribute_parallel_for_simd:
8748  case OMPD_task:
8749  case OMPD_taskloop:
8750  case OMPD_taskloop_simd:
8751  case OMPD_cancel:
8752  case OMPD_parallel:
8753  case OMPD_parallel_sections:
8754  case OMPD_parallel_for:
8755  case OMPD_parallel_for_simd:
8756  case OMPD_threadprivate:
8757  case OMPD_taskyield:
8758  case OMPD_barrier:
8759  case OMPD_taskwait:
8760  case OMPD_cancellation_point:
8761  case OMPD_flush:
8762  case OMPD_declare_reduction:
8763  case OMPD_declare_simd:
8764  case OMPD_declare_target:
8765  case OMPD_end_declare_target:
8766  case OMPD_simd:
8767  case OMPD_for:
8768  case OMPD_for_simd:
8769  case OMPD_sections:
8770  case OMPD_section:
8771  case OMPD_single:
8772  case OMPD_master:
8773  case OMPD_critical:
8774  case OMPD_taskgroup:
8775  case OMPD_distribute:
8776  case OMPD_ordered:
8777  case OMPD_atomic:
8778  case OMPD_distribute_simd:
8779  case OMPD_requires:
8780  llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
8781  case OMPD_unknown:
8782  llvm_unreachable("Unknown OpenMP directive");
8783  }
8784  break;
8785  case OMPC_firstprivate:
8786  case OMPC_lastprivate:
8787  case OMPC_reduction:
8788  case OMPC_task_reduction:
8789  case OMPC_in_reduction:
8790  case OMPC_linear:
8791  case OMPC_default:
8792  case OMPC_proc_bind:
8793  case OMPC_final:
8794  case OMPC_safelen:
8795  case OMPC_simdlen:
8796  case OMPC_collapse:
8797  case OMPC_private:
8798  case OMPC_shared:
8799  case OMPC_aligned:
8800  case OMPC_copyin:
8801  case OMPC_copyprivate:
8802  case OMPC_ordered:
8803  case OMPC_nowait:
8804  case OMPC_untied:
8805  case OMPC_mergeable:
8806  case OMPC_threadprivate:
8807  case OMPC_flush:
8808  case OMPC_read:
8809  case OMPC_write:
8810  case OMPC_update:
8811  case OMPC_capture:
8812  case OMPC_seq_cst:
8813  case OMPC_depend:
8814  case OMPC_threads:
8815  case OMPC_simd:
8816  case OMPC_map:
8817  case OMPC_priority:
8818  case OMPC_grainsize:
8819  case OMPC_nogroup:
8820  case OMPC_num_tasks:
8821  case OMPC_hint:
8822  case OMPC_defaultmap:
8823  case OMPC_unknown:
8824  case OMPC_uniform:
8825  case OMPC_to:
8826  case OMPC_from:
8827  case OMPC_use_device_ptr:
8828  case OMPC_is_device_ptr:
8829  case OMPC_unified_address:
8830  case OMPC_unified_shared_memory:
8831  case OMPC_reverse_offload:
8832  case OMPC_dynamic_allocators:
8833  case OMPC_atomic_default_mem_order:
8834  llvm_unreachable("Unexpected OpenMP clause.");
8835  }
8836  return CaptureRegion;
8837 }
8838 
8840  Expr *Condition, SourceLocation StartLoc,
8841  SourceLocation LParenLoc,
8842  SourceLocation NameModifierLoc,
8844  SourceLocation EndLoc) {
8845  Expr *ValExpr = Condition;
8846  Stmt *HelperValStmt = nullptr;
8847  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
8848  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
8849  !Condition->isInstantiationDependent() &&
8850  !Condition->containsUnexpandedParameterPack()) {
8851  ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
8852  if (Val.isInvalid())
8853  return nullptr;
8854 
8855  ValExpr = Val.get();
8856 
8857  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
8858  CaptureRegion =
8859  getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier);
8860  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
8861  ValExpr = MakeFullExpr(ValExpr).get();
8862  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
8863  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
8864  HelperValStmt = buildPreInits(Context, Captures);
8865  }
8866  }
8867 
8868  return new (Context)
8869  OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
8870  LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
8871 }
8872 
8874  SourceLocation StartLoc,
8875  SourceLocation LParenLoc,
8876  SourceLocation EndLoc) {
8877  Expr *ValExpr = Condition;
8878  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
8879  !Condition->isInstantiationDependent() &&
8880  !Condition->containsUnexpandedParameterPack()) {
8881  ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
8882  if (Val.isInvalid())
8883  return nullptr;
8884 
8885  ValExpr = MakeFullExpr(Val.get()).get();
8886  }
8887 
8888  return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc);
8889 }
8891  Expr *Op) {
8892  if (!Op)
8893  return ExprError();
8894 
8895  class IntConvertDiagnoser : public ICEConvertDiagnoser {
8896  public:
8897  IntConvertDiagnoser()
8898  : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
8899  SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
8900  QualType T) override {
8901  return S.Diag(Loc, diag::err_omp_not_integral) << T;
8902  }
8903  SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
8904  QualType T) override {
8905  return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
8906  }
8907  SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
8908  QualType T,
8909  QualType ConvTy) override {
8910  return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
8911  }
8912  SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
8913  QualType ConvTy) override {
8914  return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
8915  << ConvTy->isEnumeralType() << ConvTy;
8916  }
8917  SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
8918  QualType T) override {
8919  return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
8920  }
8921  SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
8922  QualType ConvTy) override {
8923  return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
8924  << ConvTy->isEnumeralType() << ConvTy;
8925  }
8926  SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
8927  QualType) override {
8928  llvm_unreachable("conversion functions are permitted");
8929  }
8930  } ConvertDiagnoser;
8931  return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
8932 }
8933 
8934 static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef,
8935  OpenMPClauseKind CKind,
8936  bool StrictlyPositive) {
8937  if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
8938  !ValExpr->isInstantiationDependent()) {
8939  SourceLocation Loc = ValExpr->getExprLoc();
8940  ExprResult Value =
8941  SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
8942  if (Value.isInvalid())
8943  return false;
8944 
8945  ValExpr = Value.get();
8946  // The expression must evaluate to a non-negative integer value.
8947  llvm::APSInt Result;
8948  if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) &&
8949  Result.isSigned() &&
8950  !((!StrictlyPositive && Result.isNonNegative()) ||
8951  (StrictlyPositive && Result.isStrictlyPositive()))) {
8952  SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
8953  << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
8954  << ValExpr->getSourceRange();
8955  return false;
8956  }
8957  }
8958  return true;
8959 }
8960 
8962  SourceLocation StartLoc,
8963  SourceLocation LParenLoc,
8964  SourceLocation EndLoc) {
8965  Expr *ValExpr = NumThreads;
8966  Stmt *HelperValStmt = nullptr;
8967 
8968  // OpenMP [2.5, Restrictions]
8969  // The num_threads expression must evaluate to a positive integer value.
8970  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
8971  /*StrictlyPositive=*/true))
8972  return nullptr;
8973 
8974  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
8975  OpenMPDirectiveKind CaptureRegion =
8976  getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads);
8977  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
8978  ValExpr = MakeFullExpr(ValExpr).get();
8979  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
8980  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
8981  HelperValStmt = buildPreInits(Context, Captures);
8982  }
8983 
8984  return new (Context) OMPNumThreadsClause(
8985  ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
8986 }
8987 
8988 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
8989  OpenMPClauseKind CKind,
8990  bool StrictlyPositive) {
8991  if (!E)
8992  return ExprError();
8993  if (E->isValueDependent() || E->isTypeDependent() ||
8995  return E;
8996  llvm::APSInt Result;
8997  ExprResult ICE = VerifyIntegerConstantExpression(E, &Result);
8998  if (ICE.isInvalid())
8999  return ExprError();
9000  if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
9001  (!StrictlyPositive && !Result.isNonNegative())) {
9002  Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
9003  << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
9004  << E->getSourceRange();
9005  return ExprError();
9006  }
9007  if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
9008  Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
9009  << E->getSourceRange();
9010  return ExprError();
9011  }
9012  if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
9013  DSAStack->setAssociatedLoops(Result.getExtValue());
9014  else if (CKind == OMPC_ordered)
9015  DSAStack->setAssociatedLoops(Result.getExtValue());
9016  return ICE;
9017 }
9018 
9020  SourceLocation LParenLoc,
9021  SourceLocation EndLoc) {
9022  // OpenMP [2.8.1, simd construct, Description]
9023  // The parameter of the safelen clause must be a constant
9024  // positive integer expression.
9025  ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
9026  if (Safelen.isInvalid())
9027  return nullptr;
9028  return new (Context)
9029  OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
9030 }
9031 
9033  SourceLocation LParenLoc,
9034  SourceLocation EndLoc) {
9035  // OpenMP [2.8.1, simd construct, Description]
9036  // The parameter of the simdlen clause must be a constant
9037  // positive integer expression.
9038  ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
9039  if (Simdlen.isInvalid())
9040  return nullptr;
9041  return new (Context)
9042  OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
9043 }
9044 
9046  SourceLocation StartLoc,
9047  SourceLocation LParenLoc,
9048  SourceLocation EndLoc) {
9049  // OpenMP [2.7.1, loop construct, Description]
9050  // OpenMP [2.8.1, simd construct, Description]
9051  // OpenMP [2.9.6, distribute construct, Description]
9052  // The parameter of the collapse clause must be a constant
9053  // positive integer expression.
9054  ExprResult NumForLoopsResult =
9055  VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
9056  if (NumForLoopsResult.isInvalid())
9057  return nullptr;
9058  return new (Context)
9059  OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
9060 }
9061 
9063  SourceLocation EndLoc,
9064  SourceLocation LParenLoc,
9065  Expr *NumForLoops) {
9066  // OpenMP [2.7.1, loop construct, Description]
9067  // OpenMP [2.8.1, simd construct, Description]
9068  // OpenMP [2.9.6, distribute construct, Description]
9069  // The parameter of the ordered clause must be a constant
9070  // positive integer expression if any.
9071  if (NumForLoops && LParenLoc.isValid()) {
9072  ExprResult NumForLoopsResult =
9073  VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
9074  if (NumForLoopsResult.isInvalid())
9075  return nullptr;
9076  NumForLoops = NumForLoopsResult.get();
9077  } else {
9078  NumForLoops = nullptr;
9079  }
9080  auto *Clause = OMPOrderedClause::Create(
9081  Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0,
9082  StartLoc, LParenLoc, EndLoc);
9083  DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
9084  return Clause;
9085 }
9086 
9088  OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
9089  SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
9090  OMPClause *Res = nullptr;
9091  switch (Kind) {
9092  case OMPC_default:
9093  Res =
9094  ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument),
9095  ArgumentLoc, StartLoc, LParenLoc, EndLoc);
9096  break;
9097  case OMPC_proc_bind:
9098  Res = ActOnOpenMPProcBindClause(
9099  static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc,
9100  LParenLoc, EndLoc);
9101  break;
9102  case OMPC_atomic_default_mem_order:
9103  Res = ActOnOpenMPAtomicDefaultMemOrderClause(
9104  static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
9105  ArgumentLoc, StartLoc, LParenLoc, EndLoc);
9106  break;
9107  case OMPC_if:
9108  case OMPC_final:
9109  case OMPC_num_threads:
9110  case OMPC_safelen:
9111  case OMPC_simdlen:
9112  case OMPC_collapse:
9113  case OMPC_schedule:
9114  case OMPC_private:
9115  case OMPC_firstprivate:
9116  case OMPC_lastprivate:
9117  case OMPC_shared:
9118  case OMPC_reduction:
9119  case OMPC_task_reduction:
9120  case OMPC_in_reduction:
9121  case OMPC_linear:
9122  case OMPC_aligned:
9123  case OMPC_copyin:
9124  case OMPC_copyprivate:
9125  case OMPC_ordered:
9126  case OMPC_nowait:
9127  case OMPC_untied:
9128  case OMPC_mergeable:
9129  case OMPC_threadprivate:
9130  case OMPC_flush:
9131  case OMPC_read:
9132  case OMPC_write:
9133  case OMPC_update:
9134  case OMPC_capture:
9135  case OMPC_seq_cst:
9136  case OMPC_depend:
9137  case OMPC_device:
9138  case OMPC_threads:
9139  case OMPC_simd:
9140  case OMPC_map:
9141  case OMPC_num_teams:
9142  case OMPC_thread_limit:
9143  case OMPC_priority:
9144  case OMPC_grainsize:
9145  case OMPC_nogroup:
9146  case OMPC_num_tasks:
9147  case OMPC_hint:
9148  case OMPC_dist_schedule:
9149  case OMPC_defaultmap:
9150  case OMPC_unknown:
9151  case OMPC_uniform:
9152  case OMPC_to:
9153  case OMPC_from:
9154  case OMPC_use_device_ptr:
9155  case OMPC_is_device_ptr:
9156  case OMPC_unified_address:
9157  case OMPC_unified_shared_memory:
9158  case OMPC_reverse_offload:
9159  case OMPC_dynamic_allocators:
9160  llvm_unreachable("Clause is not allowed.");
9161  }
9162  return Res;
9163 }
9164 
9165 static std::string
9167  ArrayRef<unsigned> Exclude = llvm::None) {
9168  SmallString<256> Buffer;
9169  llvm::raw_svector_ostream Out(Buffer);
9170  unsigned Bound = Last >= 2 ? Last - 2 : 0;
9171  unsigned Skipped = Exclude.size();
9172  auto S = Exclude.begin(), E = Exclude.end();
9173  for (unsigned I = First; I < Last; ++I) {
9174  if (std::find(S, E, I) != E) {
9175  --Skipped;
9176  continue;
9177  }
9178  Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
9179  if (I == Bound - Skipped)
9180  Out << " or ";
9181  else if (I != Bound + 1 - Skipped)
9182  Out << ", ";
9183  }
9184  return Out.str();
9185 }
9186 
9188  SourceLocation KindKwLoc,
9189  SourceLocation StartLoc,
9190  SourceLocation LParenLoc,
9191  SourceLocation EndLoc) {
9192  if (Kind == OMPC_DEFAULT_unknown) {
9193  static_assert(OMPC_DEFAULT_unknown > 0,
9194  "OMPC_DEFAULT_unknown not greater than 0");
9195  Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
9196  << getListOfPossibleValues(OMPC_default, /*First=*/0,
9197  /*Last=*/OMPC_DEFAULT_unknown)
9198  << getOpenMPClauseName(OMPC_default);
9199  return nullptr;
9200  }
9201  switch (Kind) {
9202  case OMPC_DEFAULT_none:
9203  DSAStack->setDefaultDSANone(KindKwLoc);
9204  break;
9205  case OMPC_DEFAULT_shared:
9206  DSAStack->setDefaultDSAShared(KindKwLoc);
9207  break;
9208  case OMPC_DEFAULT_unknown:
9209  llvm_unreachable("Clause kind is not allowed.");
9210  break;
9211  }
9212  return new (Context)
9213  OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
9214 }
9215 
9217  SourceLocation KindKwLoc,
9218  SourceLocation StartLoc,
9219  SourceLocation LParenLoc,
9220  SourceLocation EndLoc) {
9221  if (Kind == OMPC_PROC_BIND_unknown) {
9222  Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
9223  << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0,
9224  /*Last=*/OMPC_PROC_BIND_unknown)
9225  << getOpenMPClauseName(OMPC_proc_bind);
9226  return nullptr;
9227  }
9228  return new (Context)
9229  OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
9230 }
9231 
9234  SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
9236  Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
9238  OMPC_atomic_default_mem_order, /*First=*/0,
9240  << getOpenMPClauseName(OMPC_atomic_default_mem_order);
9241  return nullptr;
9242  }
9243  return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
9244  LParenLoc, EndLoc);
9245 }
9246 
9249  SourceLocation StartLoc, SourceLocation LParenLoc,
9250  ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
9251  SourceLocation EndLoc) {
9252  OMPClause *Res = nullptr;
9253  switch (Kind) {
9254  case OMPC_schedule:
9255  enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
9256  assert(Argument.size() == NumberOfElements &&
9257  ArgumentLoc.size() == NumberOfElements);
9258  Res = ActOnOpenMPScheduleClause(
9259  static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
9260  static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
9261  static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
9262  StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
9263  ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
9264  break;
9265  case OMPC_if:
9266  assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
9267  Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
9268  Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
9269  DelimLoc, EndLoc);
9270  break;
9271  case OMPC_dist_schedule:
9272  Res = ActOnOpenMPDistScheduleClause(
9273  static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
9274  StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
9275  break;
9276  case OMPC_defaultmap:
9277  enum { Modifier, DefaultmapKind };
9278  Res = ActOnOpenMPDefaultmapClause(
9279  static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
9280  static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
9281  StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
9282  EndLoc);
9283  break;
9284  case OMPC_final:
9285  case OMPC_num_threads:
9286  case OMPC_safelen:
9287  case OMPC_simdlen:
9288  case OMPC_collapse:
9289  case OMPC_default:
9290  case OMPC_proc_bind:
9291  case OMPC_private:
9292  case OMPC_firstprivate:
9293  case OMPC_lastprivate:
9294  case OMPC_shared:
9295  case OMPC_reduction:
9296  case OMPC_task_reduction:
9297  case OMPC_in_reduction:
9298  case OMPC_linear:
9299  case OMPC_aligned:
9300  case OMPC_copyin:
9301  case OMPC_copyprivate:
9302  case OMPC_ordered:
9303  case OMPC_nowait:
9304  case OMPC_untied:
9305  case OMPC_mergeable:
9306  case OMPC_threadprivate:
9307  case OMPC_flush:
9308  case OMPC_read:
9309  case OMPC_write:
9310  case OMPC_update:
9311  case OMPC_capture:
9312  case OMPC_seq_cst:
9313  case OMPC_depend:
9314  case OMPC_device:
9315  case OMPC_threads:
9316  case OMPC_simd:
9317  case OMPC_map:
9318  case OMPC_num_teams:
9319  case OMPC_thread_limit:
9320  case OMPC_priority:
9321  case OMPC_grainsize:
9322  case OMPC_nogroup:
9323  case OMPC_num_tasks:
9324  case OMPC_hint:
9325  case OMPC_unknown:
9326  case OMPC_uniform:
9327  case OMPC_to:
9328  case OMPC_from:
9329  case OMPC_use_device_ptr:
9330  case OMPC_is_device_ptr:
9331  case OMPC_unified_address:
9332  case OMPC_unified_shared_memory:
9333  case OMPC_reverse_offload:
9334  case OMPC_dynamic_allocators:
9335  case OMPC_atomic_default_mem_order:
9336  llvm_unreachable("Clause is not allowed.");
9337  }
9338  return Res;
9339 }
9340 
9343  SourceLocation M1Loc, SourceLocation M2Loc) {
9344  if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
9345  SmallVector<unsigned, 2> Excluded;
9347  Excluded.push_back(M2);
9348  if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
9349  Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
9350  if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
9351  Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
9352  S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
9353  << getListOfPossibleValues(OMPC_schedule,
9354  /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
9355  /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
9356  Excluded)
9357  << getOpenMPClauseName(OMPC_schedule);
9358  return true;
9359  }
9360  return false;
9361 }
9362 
9365  OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
9366  SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
9367  SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
9368  if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
9369  checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
9370  return nullptr;
9371  // OpenMP, 2.7.1, Loop Construct, Restrictions
9372  // Either the monotonic modifier or the nonmonotonic modifier can be specified
9373  // but not both.
9374  if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
9375  (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
9376  M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
9377  (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
9378  M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
9379  Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
9380  << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
9381  << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
9382  return nullptr;
9383  }
9384  if (Kind == OMPC_SCHEDULE_unknown) {
9385  std::string Values;
9386  if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
9387  unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
9388  Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
9389  /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
9390  Exclude);
9391  } else {
9392  Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
9393  /*Last=*/OMPC_SCHEDULE_unknown);
9394  }
9395  Diag(KindLoc, diag::err_omp_unexpected_clause_value)
9396  << Values << getOpenMPClauseName(OMPC_schedule);
9397  return nullptr;
9398  }
9399  // OpenMP, 2.7.1, Loop Construct, Restrictions
9400  // The nonmonotonic modifier can only be specified with schedule(dynamic) or
9401  // schedule(guided).
9402  if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
9403  M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
9404  Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
9405  Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
9406  diag::err_omp_schedule_nonmonotonic_static);
9407  return nullptr;
9408  }
9409  Expr *ValExpr = ChunkSize;
9410  Stmt *HelperValStmt = nullptr;
9411  if (ChunkSize) {
9412  if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
9413  !ChunkSize->isInstantiationDependent() &&
9414  !ChunkSize->containsUnexpandedParameterPack()) {
9415  SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
9416  ExprResult Val =
9417  PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
9418  if (Val.isInvalid())
9419  return nullptr;
9420 
9421  ValExpr = Val.get();
9422 
9423  // OpenMP [2.7.1, Restrictions]
9424  // chunk_size must be a loop invariant integer expression with a positive
9425  // value.
9426  llvm::APSInt Result;
9427  if (ValExpr->isIntegerConstantExpr(Result, Context)) {
9428  if (Result.isSigned() && !Result.isStrictlyPositive()) {
9429  Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
9430  << "schedule" << 1 << ChunkSize->getSourceRange();
9431  return nullptr;
9432  }
9434  DSAStack->getCurrentDirective(), OMPC_schedule) !=
9435  OMPD_unknown &&
9436  !CurContext->isDependentContext()) {
9437  ValExpr = MakeFullExpr(ValExpr).get();
9438  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
9439  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
9440  HelperValStmt = buildPreInits(Context, Captures);
9441  }
9442  }
9443  }
9444 
9445  return new (Context)
9446  OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
9447  ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
9448 }
9449 
9451  SourceLocation StartLoc,
9452  SourceLocation EndLoc) {
9453  OMPClause *Res = nullptr;
9454  switch (Kind) {
9455  case OMPC_ordered:
9456  Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
9457  break;
9458  case OMPC_nowait:
9459  Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
9460  break;
9461  case OMPC_untied:
9462  Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
9463  break;
9464  case OMPC_mergeable:
9465  Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
9466  break;
9467  case OMPC_read:
9468  Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
9469  break;
9470  case OMPC_write:
9471  Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
9472  break;
9473  case OMPC_update:
9474  Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
9475  break;
9476  case OMPC_capture:
9477  Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
9478  break;
9479  case OMPC_seq_cst:
9480  Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
9481  break;
9482  case OMPC_threads:
9483  Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
9484  break;
9485  case OMPC_simd:
9486  Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
9487  break;
9488  case OMPC_nogroup:
9489  Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
9490  break;
9491  case OMPC_unified_address:
9492  Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
9493  break;
9494  case OMPC_unified_shared_memory:
9495  Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
9496  break;
9497  case OMPC_reverse_offload:
9498  Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
9499  break;
9500  case OMPC_dynamic_allocators:
9501  Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
9502  break;
9503  case OMPC_if:
9504  case OMPC_final:
9505  case OMPC_num_threads:
9506  case OMPC_safelen:
9507  case OMPC_simdlen:
9508  case OMPC_collapse:
9509  case OMPC_schedule:
9510  case OMPC_private:
9511  case OMPC_firstprivate:
9512  case OMPC_lastprivate:
9513  case OMPC_shared:
9514  case OMPC_reduction:
9515  case OMPC_task_reduction:
9516  case OMPC_in_reduction:
9517  case OMPC_linear:
9518  case OMPC_aligned:
9519  case OMPC_copyin:
9520  case OMPC_copyprivate:
9521  case OMPC_default:
9522  case OMPC_proc_bind:
9523  case OMPC_threadprivate:
9524  case OMPC_flush:
9525  case OMPC_depend:
9526  case OMPC_device:
9527  case OMPC_map:
9528  case OMPC_num_teams:
9529  case OMPC_thread_limit:
9530  case OMPC_priority:
9531  case OMPC_grainsize:
9532  case OMPC_num_tasks:
9533  case OMPC_hint:
9534  case OMPC_dist_schedule:
9535  case OMPC_defaultmap:
9536  case OMPC_unknown:
9537  case OMPC_uniform:
9538  case OMPC_to:
9539  case OMPC_from:
9540  case OMPC_use_device_ptr:
9541  case OMPC_is_device_ptr:
9542  case OMPC_atomic_default_mem_order:
9543  llvm_unreachable("Clause is not allowed.");
9544  }
9545  return Res;
9546 }
9547 
9549  SourceLocation EndLoc) {
9550  DSAStack->setNowaitRegion();
9551  return new (Context) OMPNowaitClause(StartLoc, EndLoc);
9552 }
9553 
9555  SourceLocation EndLoc) {
9556  return new (Context) OMPUntiedClause(StartLoc, EndLoc);
9557 }
9558 
9560  SourceLocation EndLoc) {
9561  return new (Context) OMPMergeableClause(StartLoc, EndLoc);
9562 }
9563 
9565  SourceLocation EndLoc) {
9566  return new (Context) OMPReadClause(StartLoc, EndLoc);
9567 }
9568 
9570  SourceLocation EndLoc) {
9571  return new (Context) OMPWriteClause(StartLoc, EndLoc);
9572 }
9573 
9575  SourceLocation EndLoc) {
9576  return new (Context) OMPUpdateClause(StartLoc, EndLoc);
9577 }
9578 
9580  SourceLocation EndLoc) {
9581  return new (Context) OMPCaptureClause(StartLoc, EndLoc);
9582 }
9583 
9585  SourceLocation EndLoc) {
9586  return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
9587 }
9588 
9590  SourceLocation EndLoc) {
9591  return new (Context) OMPThreadsClause(StartLoc, EndLoc);
9592 }
9593 
9595  SourceLocation EndLoc) {
9596  return new (Context) OMPSIMDClause(StartLoc, EndLoc);
9597 }
9598 
9600  SourceLocation EndLoc) {
9601  return new (Context) OMPNogroupClause(StartLoc, EndLoc);
9602 }
9603 
9605  SourceLocation EndLoc) {
9606  return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
9607 }
9608 
9610  SourceLocation EndLoc) {
9611  return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
9612 }
9613 
9615  SourceLocation EndLoc) {
9616  return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
9617 }
9618 
9620  SourceLocation EndLoc) {
9621  return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
9622 }
9623 
9625  OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr,
9627  SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec,
9628  const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind,
9629  OpenMPLinearClauseKind LinKind,
9630  ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
9631  ArrayRef<SourceLocation> MapTypeModifiersLoc,
9632  OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
9633  SourceLocation DepLinMapLoc) {
9634  OMPClause *Res = nullptr;
9635  switch (Kind) {
9636  case OMPC_private:
9637  Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9638  break;
9639  case OMPC_firstprivate:
9640  Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9641  break;
9642  case OMPC_lastprivate:
9643  Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9644  break;
9645  case OMPC_shared:
9646  Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
9647  break;
9648  case OMPC_reduction:
9649  Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
9650  EndLoc, ReductionIdScopeSpec, ReductionId);
9651  break;
9652  case OMPC_task_reduction:
9653  Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
9654  EndLoc, ReductionIdScopeSpec,
9655  ReductionId);
9656  break;
9657  case OMPC_in_reduction:
9658  Res =
9659  ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
9660  EndLoc, ReductionIdScopeSpec, ReductionId);
9661  break;
9662  case OMPC_linear:
9663  Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc,
9664  LinKind, DepLinMapLoc, ColonLoc, EndLoc);
9665  break;
9666  case OMPC_aligned:
9667  Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc,
9668  ColonLoc, EndLoc);
9669  break;
9670  case OMPC_copyin:
9671  Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
9672  break;
9673  case OMPC_copyprivate:
9674  Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
9675  break;
9676  case OMPC_flush:
9677  Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
9678  break;
9679  case OMPC_depend:
9680  Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList,
9681  StartLoc, LParenLoc, EndLoc);
9682  break;
9683  case OMPC_map:
9684  Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, MapType,
9685  IsMapTypeImplicit, DepLinMapLoc, ColonLoc,
9686  VarList, StartLoc, LParenLoc, EndLoc);
9687  break;
9688  case OMPC_to:
9689  Res = ActOnOpenMPToClause(VarList, StartLoc, LParenLoc, EndLoc);
9690  break;
9691  case OMPC_from:
9692  Res = ActOnOpenMPFromClause(VarList, StartLoc, LParenLoc, EndLoc);
9693  break;
9694  case OMPC_use_device_ptr:
9695  Res = ActOnOpenMPUseDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc);
9696  break;
9697  case OMPC_is_device_ptr:
9698  Res = ActOnOpenMPIsDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc);
9699  break;
9700  case OMPC_if:
9701  case OMPC_final:
9702  case OMPC_num_threads:
9703  case OMPC_safelen:
9704  case OMPC_simdlen:
9705  case OMPC_collapse:
9706  case OMPC_default:
9707  case OMPC_proc_bind:
9708  case OMPC_schedule:
9709  case OMPC_ordered:
9710  case OMPC_nowait:
9711  case OMPC_untied:
9712  case OMPC_mergeable:
9713  case OMPC_threadprivate:
9714  case OMPC_read:
9715  case OMPC_write:
9716  case OMPC_update:
9717  case OMPC_capture:
9718  case OMPC_seq_cst:
9719  case OMPC_device:
9720  case OMPC_threads:
9721  case OMPC_simd:
9722  case OMPC_num_teams:
9723  case OMPC_thread_limit:
9724  case OMPC_priority:
9725  case OMPC_grainsize:
9726  case OMPC_nogroup:
9727  case OMPC_num_tasks:
9728  case OMPC_hint:
9729  case OMPC_dist_schedule:
9730  case OMPC_defaultmap:
9731  case OMPC_unknown:
9732  case OMPC_uniform:
9733  case OMPC_unified_address:
9734  case OMPC_unified_shared_memory:
9735  case OMPC_reverse_offload:
9736  case OMPC_dynamic_allocators:
9737  case OMPC_atomic_default_mem_order:
9738  llvm_unreachable("Clause is not allowed.");
9739  }
9740  return Res;
9741 }
9742 
9744  ExprObjectKind OK, SourceLocation Loc) {
9745  ExprResult Res = BuildDeclRefExpr(
9746  Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
9747  if (!Res.isUsable())
9748  return ExprError();
9749  if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
9750  Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
9751  if (!Res.isUsable())
9752  return ExprError();
9753  }
9754  if (VK != VK_LValue && Res.get()->isGLValue()) {
9755  Res = DefaultLvalueConversion(Res.get());
9756  if (!Res.isUsable())
9757  return ExprError();
9758  }
9759  return Res;
9760 }
9761 
9762 static std::pair<ValueDecl *, bool>
9764  SourceRange &ERange, bool AllowArraySection = false) {
9765  if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
9767  return std::make_pair(nullptr, true);
9768 
9769  // OpenMP [3.1, C/C++]
9770  // A list item is a variable name.
9771  // OpenMP [2.9.3.3, Restrictions, p.1]
9772  // A variable that is part of another variable (as an array or
9773  // structure element) cannot appear in a private clause.
9774  RefExpr = RefExpr->IgnoreParens();
9775  enum {
9776  NoArrayExpr = -1,
9777  ArraySubscript = 0,
9778  OMPArraySection = 1
9779  } IsArrayExpr = NoArrayExpr;
9780  if (AllowArraySection) {
9781  if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
9782  Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
9783  while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
9784  Base = TempASE->getBase()->IgnoreParenImpCasts();
9785  RefExpr = Base;
9786  IsArrayExpr = ArraySubscript;
9787  } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
9788  Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
9789  while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
9790  Base = TempOASE->getBase()->IgnoreParenImpCasts();
9791  while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
9792  Base = TempASE->getBase()->IgnoreParenImpCasts();
9793  RefExpr = Base;
9794  IsArrayExpr = OMPArraySection;
9795  }
9796  }
9797  ELoc = RefExpr->getExprLoc();
9798  ERange = RefExpr->getSourceRange();
9799  RefExpr = RefExpr->IgnoreParenImpCasts();
9800  auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
9801  auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
9802  if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
9803  (S.getCurrentThisType().isNull() || !ME ||
9804  !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
9805  !isa<FieldDecl>(ME->getMemberDecl()))) {
9806  if (IsArrayExpr != NoArrayExpr) {
9807  S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
9808  << ERange;
9809  } else {
9810  S.Diag(ELoc,
9811  AllowArraySection
9812  ? diag::err_omp_expected_var_name_member_expr_or_array_item
9813  : diag::err_omp_expected_var_name_member_expr)
9814  << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
9815  }
9816  return std::make_pair(nullptr, false);
9817  }
9818  return std::make_pair(
9819  getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
9820 }
9821 
9823  SourceLocation StartLoc,
9824  SourceLocation LParenLoc,
9825  SourceLocation EndLoc) {
9827  SmallVector<Expr *, 8> PrivateCopies;
9828  for (Expr *RefExpr : VarList) {
9829  assert(RefExpr && "NULL expr in OpenMP private clause.");
9830  SourceLocation ELoc;
9831  SourceRange ERange;
9832  Expr *SimpleRefExpr = RefExpr;
9833  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
9834  if (Res.second) {
9835  // It will be analyzed later.
9836  Vars.push_back(RefExpr);
9837  PrivateCopies.push_back(nullptr);
9838  }
9839  ValueDecl *D = Res.first;
9840  if (!D)
9841  continue;
9842 
9843  QualType Type = D->getType();
9844  auto *VD = dyn_cast<VarDecl>(D);
9845 
9846  // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
9847  // A variable that appears in a private clause must not have an incomplete
9848  // type or a reference type.
9849  if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
9850  continue;
9851  Type = Type.getNonReferenceType();
9852 
9853  // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
9854  // A variable that is privatized must not have a const-qualified type
9855  // unless it is of class type with a mutable member. This restriction does
9856  // not apply to the firstprivate clause.
9857  //
9858  // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
9859  // A variable that appears in a private clause must not have a
9860  // const-qualified type unless it is of class type with a mutable member.
9861  if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
9862  continue;
9863 
9864  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
9865  // in a Construct]
9866  // Variables with the predetermined data-sharing attributes may not be
9867  // listed in data-sharing attributes clauses, except for the cases
9868  // listed below. For these exceptions only, listing a predetermined
9869  // variable in a data-sharing attribute clause is allowed and overrides
9870  // the variable's predetermined data-sharing attributes.
9871  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
9872  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
9873  Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
9874  << getOpenMPClauseName(OMPC_private);
9875  reportOriginalDsa(*this, DSAStack, D, DVar);
9876  continue;
9877  }
9878 
9879  OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
9880  // Variably modified types are not supported for tasks.
9881  if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
9882  isOpenMPTaskingDirective(CurrDir)) {
9883  Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
9884  << getOpenMPClauseName(OMPC_private) << Type
9885  << getOpenMPDirectiveName(CurrDir);
9886  bool IsDecl =
9887  !VD ||
9888  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
9889  Diag(D->getLocation(),
9890  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
9891  << D;
9892  continue;
9893  }
9894 
9895  // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
9896  // A list item cannot appear in both a map clause and a data-sharing
9897  // attribute clause on the same construct
9898  if (isOpenMPTargetExecutionDirective(CurrDir)) {
9899  OpenMPClauseKind ConflictKind;
9900  if (DSAStack->checkMappableExprComponentListsForDecl(
9901  VD, /*CurrentRegionOnly=*/true,
9903  OpenMPClauseKind WhereFoundClauseKind) -> bool {
9904  ConflictKind = WhereFoundClauseKind;
9905  return true;
9906  })) {
9907  Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
9908  << getOpenMPClauseName(OMPC_private)
9909  << getOpenMPClauseName(ConflictKind)
9910  << getOpenMPDirectiveName(CurrDir);
9911  reportOriginalDsa(*this, DSAStack, D, DVar);
9912  continue;
9913  }
9914  }
9915 
9916  // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
9917  // A variable of class type (or array thereof) that appears in a private
9918  // clause requires an accessible, unambiguous default constructor for the
9919  // class type.
9920  // Generate helper private variable and initialize it with the default
9921  // value. The address of the original variable is replaced by the address of
9922  // the new private variable in CodeGen. This new variable is not added to
9923  // IdResolver, so the code in the OpenMP region uses original variable for
9924  // proper diagnostics.
9925  Type = Type.getUnqualifiedType();
9926  VarDecl *VDPrivate =
9927  buildVarDecl(*this, ELoc, Type, D->getName(),
9928  D->hasAttrs() ? &D->getAttrs() : nullptr,
9929  VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
9930  ActOnUninitializedDecl(VDPrivate);
9931  if (VDPrivate->isInvalidDecl())
9932  continue;
9933  DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
9934  *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
9935 
9936  DeclRefExpr *Ref = nullptr;
9937  if (!VD && !CurContext->isDependentContext())
9938  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
9939  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
9940  Vars.push_back((VD || CurContext->isDependentContext())
9941  ? RefExpr->IgnoreParens()
9942  : Ref);
9943  PrivateCopies.push_back(VDPrivateRefExpr);
9944  }
9945 
9946  if (Vars.empty())
9947  return nullptr;
9948 
9949  return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
9950  PrivateCopies);
9951 }
9952 
9953 namespace {
9954 class DiagsUninitializedSeveretyRAII {
9955 private:
9956  DiagnosticsEngine &Diags;
9957  SourceLocation SavedLoc;
9958  bool IsIgnored = false;
9959 
9960 public:
9961  DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
9962  bool IsIgnored)
9963  : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
9964  if (!IsIgnored) {
9965  Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
9966  /*Map*/ diag::Severity::Ignored, Loc);
9967  }
9968  }
9969  ~DiagsUninitializedSeveretyRAII() {
9970  if (!IsIgnored)
9971  Diags.popMappings(SavedLoc);
9972  }
9973 };
9974 }
9975 
9977  SourceLocation StartLoc,
9978  SourceLocation LParenLoc,
9979  SourceLocation EndLoc) {
9981  SmallVector<Expr *, 8> PrivateCopies;
9983  SmallVector<Decl *, 4> ExprCaptures;
9984  bool IsImplicitClause =
9985  StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
9986  SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc();
9987 
9988  for (Expr *RefExpr : VarList) {
9989  assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
9990  SourceLocation ELoc;
9991  SourceRange ERange;
9992  Expr *SimpleRefExpr = RefExpr;
9993  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
9994  if (Res.second) {
9995  // It will be analyzed later.
9996  Vars.push_back(RefExpr);
9997  PrivateCopies.push_back(nullptr);
9998  Inits.push_back(nullptr);
9999  }
10000  ValueDecl *D = Res.first;
10001  if (!D)
10002  continue;
10003 
10004  ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
10005  QualType Type = D->getType();
10006  auto *VD = dyn_cast<VarDecl>(D);
10007 
10008  // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
10009  // A variable that appears in a private clause must not have an incomplete
10010  // type or a reference type.
10011  if (RequireCompleteType(ELoc, Type,
10012  diag::err_omp_firstprivate_incomplete_type))
10013  continue;
10014  Type = Type.getNonReferenceType();
10015 
10016  // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
10017  // A variable of class type (or array thereof) that appears in a private
10018  // clause requires an accessible, unambiguous copy constructor for the
10019  // class type.
10020  QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
10021 
10022  // If an implicit firstprivate variable found it was checked already.
10023  DSAStackTy::DSAVarData TopDVar;
10024  if (!IsImplicitClause) {
10025  DSAStackTy::DSAVarData DVar =
10026  DSAStack->getTopDSA(D, /*FromParent=*/false);
10027  TopDVar = DVar;
10028  OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
10029  bool IsConstant = ElemType.isConstant(Context);
10030  // OpenMP [2.4.13, Data-sharing Attribute Clauses]
10031  // A list item that specifies a given variable may not appear in more
10032  // than one clause on the same directive, except that a variable may be
10033  // specified in both firstprivate and lastprivate clauses.
10034  // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
10035  // A list item may appear in a firstprivate or lastprivate clause but not
10036  // both.
10037  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
10038  (isOpenMPDistributeDirective(CurrDir) ||
10039  DVar.CKind != OMPC_lastprivate) &&
10040  DVar.RefExpr) {
10041  Diag(ELoc, diag::err_omp_wrong_dsa)
10042  << getOpenMPClauseName(DVar.CKind)
10043  << getOpenMPClauseName(OMPC_firstprivate);
10044  reportOriginalDsa(*this, DSAStack, D, DVar);
10045  continue;
10046  }
10047 
10048  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
10049  // in a Construct]
10050  // Variables with the predetermined data-sharing attributes may not be
10051  // listed in data-sharing attributes clauses, except for the cases
10052  // listed below. For these exceptions only, listing a predetermined
10053  // variable in a data-sharing attribute clause is allowed and overrides
10054  // the variable's predetermined data-sharing attributes.
10055  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
10056  // in a Construct, C/C++, p.2]
10057  // Variables with const-qualified type having no mutable member may be
10058  // listed in a firstprivate clause, even if they are static data members.
10059  if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
10060  DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
10061  Diag(ELoc, diag::err_omp_wrong_dsa)
10062  << getOpenMPClauseName(DVar.CKind)
10063  << getOpenMPClauseName(OMPC_firstprivate);
10064  reportOriginalDsa(*this, DSAStack, D, DVar);
10065  continue;
10066  }
10067 
10068  // OpenMP [2.9.3.4, Restrictions, p.2]
10069  // A list item that is private within a parallel region must not appear
10070  // in a firstprivate clause on a worksharing construct if any of the
10071  // worksharing regions arising from the worksharing construct ever bind
10072  // to any of the parallel regions arising from the parallel construct.
10073  // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
10074  // A list item that is private within a teams region must not appear in a
10075  // firstprivate clause on a distribute construct if any of the distribute
10076  // regions arising from the distribute construct ever bind to any of the
10077  // teams regions arising from the teams construct.
10078  // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
10079  // A list item that appears in a reduction clause of a teams construct
10080  // must not appear in a firstprivate clause on a distribute construct if
10081  // any of the distribute regions arising from the distribute construct
10082  // ever bind to any of the teams regions arising from the teams construct.
10083  if ((isOpenMPWorksharingDirective(CurrDir) ||
10084  isOpenMPDistributeDirective(CurrDir)) &&
10085  !isOpenMPParallelDirective(CurrDir) &&
10086  !isOpenMPTeamsDirective(CurrDir)) {
10087  DVar = DSAStack->getImplicitDSA(D, true);
10088  if (DVar.CKind != OMPC_shared &&
10089  (isOpenMPParallelDirective(DVar.DKind) ||
10090  isOpenMPTeamsDirective(DVar.DKind) ||
10091  DVar.DKind == OMPD_unknown)) {
10092  Diag(ELoc, diag::err_omp_required_access)
10093  << getOpenMPClauseName(OMPC_firstprivate)
10094  << getOpenMPClauseName(OMPC_shared);
10095  reportOriginalDsa(*this, DSAStack, D, DVar);
10096  continue;
10097  }
10098  }
10099  // OpenMP [2.9.3.4, Restrictions, p.3]
10100  // A list item that appears in a reduction clause of a parallel construct
10101  // must not appear in a firstprivate clause on a worksharing or task
10102  // construct if any of the worksharing or task regions arising from the
10103  // worksharing or task construct ever bind to any of the parallel regions
10104  // arising from the parallel construct.
10105  // OpenMP [2.9.3.4, Restrictions, p.4]
10106  // A list item that appears in a reduction clause in worksharing
10107  // construct must not appear in a firstprivate clause in a task construct
10108  // encountered during execution of any of the worksharing regions arising
10109  // from the worksharing construct.
10110  if (isOpenMPTaskingDirective(CurrDir)) {
10111  DVar = DSAStack->hasInnermostDSA(
10112  D, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
10113  [](OpenMPDirectiveKind K) {
10114  return isOpenMPParallelDirective(K) ||
10117  },
10118  /*FromParent=*/true);
10119  if (DVar.CKind == OMPC_reduction &&
10120  (isOpenMPParallelDirective(DVar.DKind) ||
10121  isOpenMPWorksharingDirective(DVar.DKind) ||
10122  isOpenMPTeamsDirective(DVar.DKind))) {
10123  Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
10124  << getOpenMPDirectiveName(DVar.DKind);
10125  reportOriginalDsa(*this, DSAStack, D, DVar);
10126  continue;
10127  }
10128  }
10129 
10130  // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
10131  // A list item cannot appear in both a map clause and a data-sharing
10132  // attribute clause on the same construct
10133  if (isOpenMPTargetExecutionDirective(CurrDir)) {
10134  OpenMPClauseKind ConflictKind;
10135  if (DSAStack->checkMappableExprComponentListsForDecl(
10136  VD, /*CurrentRegionOnly=*/true,
10137  [&ConflictKind](
10139  OpenMPClauseKind WhereFoundClauseKind) {
10140  ConflictKind = WhereFoundClauseKind;
10141  return true;
10142  })) {
10143  Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
10144  << getOpenMPClauseName(OMPC_firstprivate)
10145  << getOpenMPClauseName(ConflictKind)
10146  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
10147  reportOriginalDsa(*this, DSAStack, D, DVar);
10148  continue;
10149  }
10150  }
10151  }
10152 
10153  // Variably modified types are not supported for tasks.
10154  if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
10155  isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
10156  Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
10157  << getOpenMPClauseName(OMPC_firstprivate) << Type
10158  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
10159  bool IsDecl =
10160  !VD ||
10161  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
10162  Diag(D->getLocation(),
10163  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
10164  << D;
10165  continue;
10166  }
10167 
10168  Type = Type.getUnqualifiedType();
10169  VarDecl *VDPrivate =
10170  buildVarDecl(*this, ELoc, Type, D->getName(),
10171  D->hasAttrs() ? &D->getAttrs() : nullptr,
10172  VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
10173  // Generate helper private variable and initialize it with the value of the
10174  // original variable. The address of the original variable is replaced by
10175  // the address of the new private variable in the CodeGen. This new variable
10176  // is not added to IdResolver, so the code in the OpenMP region uses
10177  // original variable for proper diagnostics and variable capturing.
10178  Expr *VDInitRefExpr = nullptr;
10179  // For arrays generate initializer for single element and replace it by the
10180  // original array element in CodeGen.
10181  if (Type->isArrayType()) {
10182  VarDecl *VDInit =
10183  buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
10184  VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
10185  Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
10186  ElemType = ElemType.getUnqualifiedType();
10187  VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
10188  ".firstprivate.temp");
10189  InitializedEntity Entity =
10192 
10193  InitializationSequence InitSeq(*this, Entity, Kind, Init);
10194  ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
10195  if (Result.isInvalid())
10196  VDPrivate->setInvalidDecl();
10197  else
10198  VDPrivate->setInit(Result.getAs<Expr>());
10199  // Remove temp variable declaration.
10200  Context.Deallocate(VDInitTemp);
10201  } else {
10202  VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
10203  ".firstprivate.temp");
10204  VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
10205  RefExpr->getExprLoc());
10206  AddInitializerToDecl(VDPrivate,
10207  DefaultLvalueConversion(VDInitRefExpr).get(),
10208  /*DirectInit=*/false);
10209  }
10210  if (VDPrivate->isInvalidDecl()) {
10211  if (IsImplicitClause) {
10212  Diag(RefExpr->getExprLoc(),
10213  diag::note_omp_task_predetermined_firstprivate_here);
10214  }
10215  continue;
10216  }
10217  CurContext->addDecl(VDPrivate);
10218  DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
10219  *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
10220  RefExpr->getExprLoc());
10221  DeclRefExpr *Ref = nullptr;
10222  if (!VD && !CurContext->isDependentContext()) {
10223  if (TopDVar.CKind == OMPC_lastprivate) {
10224  Ref = TopDVar.PrivateCopy;
10225  } else {
10226  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
10227  if (!isOpenMPCapturedDecl(D))
10228  ExprCaptures.push_back(Ref->getDecl());
10229  }
10230  }
10231  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
10232  Vars.push_back((VD || CurContext->isDependentContext())
10233  ? RefExpr->IgnoreParens()
10234  : Ref);
10235  PrivateCopies.push_back(VDPrivateRefExpr);
10236  Inits.push_back(VDInitRefExpr);
10237  }
10238 
10239  if (Vars.empty())
10240  return nullptr;
10241 
10242  return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
10243  Vars, PrivateCopies, Inits,
10244  buildPreInits(Context, ExprCaptures));
10245 }
10246 
10248  SourceLocation StartLoc,
10249  SourceLocation LParenLoc,
10250  SourceLocation EndLoc) {
10252  SmallVector<Expr *, 8> SrcExprs;
10253  SmallVector<Expr *, 8> DstExprs;
10254  SmallVector<Expr *, 8> AssignmentOps;
10255  SmallVector<Decl *, 4> ExprCaptures;
10256  SmallVector<Expr *, 4> ExprPostUpdates;
10257  for (Expr *RefExpr : VarList) {
10258  assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
10259  SourceLocation ELoc;
10260  SourceRange ERange;
10261  Expr *SimpleRefExpr = RefExpr;
10262  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
10263  if (Res.second) {
10264  // It will be analyzed later.
10265  Vars.push_back(RefExpr);
10266  SrcExprs.push_back(nullptr);
10267  DstExprs.push_back(nullptr);
10268  AssignmentOps.push_back(nullptr);
10269  }
10270  ValueDecl *D = Res.first;
10271  if (!D)
10272  continue;
10273 
10274  QualType Type = D->getType();
10275  auto *VD = dyn_cast<VarDecl>(D);
10276 
10277  // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
10278  // A variable that appears in a lastprivate clause must not have an
10279  // incomplete type or a reference type.
10280  if (RequireCompleteType(ELoc, Type,
10281  diag::err_omp_lastprivate_incomplete_type))
10282  continue;
10283  Type = Type.getNonReferenceType();
10284 
10285  // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
10286  // A variable that is privatized must not have a const-qualified type
10287  // unless it is of class type with a mutable member. This restriction does
10288  // not apply to the firstprivate clause.
10289  //
10290  // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
10291  // A variable that appears in a lastprivate clause must not have a
10292  // const-qualified type unless it is of class type with a mutable member.
10293  if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
10294  continue;
10295 
10296  OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
10297  // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
10298  // in a Construct]
10299  // Variables with the predetermined data-sharing attributes may not be
10300  // listed in data-sharing attributes clauses, except for the cases
10301  // listed below.
10302  // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
10303  // A list item may appear in a firstprivate or lastprivate clause but not
10304  // both.
10305  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
10306  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
10307  (isOpenMPDistributeDirective(CurrDir) ||
10308  DVar.CKind != OMPC_firstprivate) &&
10309  (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
10310  Diag(ELoc, diag::err_omp_wrong_dsa)
10311  << getOpenMPClauseName(DVar.CKind)
10312  << getOpenMPClauseName(OMPC_lastprivate);
10313  reportOriginalDsa(*this, DSAStack, D, DVar);
10314  continue;
10315  }
10316 
10317  // OpenMP [2.14.3.5, Restrictions, p.2]
10318  // A list item that is private within a parallel region, or that appears in
10319  // the reduction clause of a parallel construct, must not appear in a
10320  // lastprivate clause on a worksharing construct if any of the corresponding
10321  // worksharing regions ever binds to any of the corresponding parallel
10322  // regions.
10323  DSAStackTy::DSAVarData TopDVar = DVar;
10324  if (isOpenMPWorksharingDirective(CurrDir) &&
10325  !isOpenMPParallelDirective(CurrDir) &&
10326  !isOpenMPTeamsDirective(CurrDir)) {
10327  DVar = DSAStack->getImplicitDSA(D, true);
10328  if (DVar.CKind != OMPC_shared) {
10329  Diag(ELoc, diag::err_omp_required_access)
10330  << getOpenMPClauseName(OMPC_lastprivate)
10331  << getOpenMPClauseName(OMPC_shared);
10332  reportOriginalDsa(*this, DSAStack, D, DVar);
10333  continue;
10334  }
10335  }
10336 
10337  // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
10338  // A variable of class type (or array thereof) that appears in a
10339  // lastprivate clause requires an accessible, unambiguous default
10340  // constructor for the class type, unless the list item is also specified
10341  // in a firstprivate clause.
10342  // A variable of class type (or array thereof) that appears in a
10343  // lastprivate clause requires an accessible, unambiguous copy assignment
10344  // operator for the class type.
10345  Type = Context.getBaseElementType(Type).getNonReferenceType();
10346  VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
10347  Type.getUnqualifiedType(), ".lastprivate.src",
10348  D->hasAttrs() ? &D->getAttrs() : nullptr);
10349  DeclRefExpr *PseudoSrcExpr =
10350  buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
10351  VarDecl *DstVD =
10352  buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
10353  D->hasAttrs() ? &D->getAttrs() : nullptr);
10354  DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
10355  // For arrays generate assignment operation for single element and replace
10356  // it by the original array element in CodeGen.
10357  ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
10358  PseudoDstExpr, PseudoSrcExpr);
10359  if (AssignmentOp.isInvalid())
10360  continue;
10361  AssignmentOp =
10362  ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
10363  if (AssignmentOp.isInvalid())
10364  continue;
10365 
10366  DeclRefExpr *Ref = nullptr;
10367  if (!VD && !CurContext->isDependentContext()) {
10368  if (TopDVar.CKind == OMPC_firstprivate) {
10369  Ref = TopDVar.PrivateCopy;
10370  } else {
10371  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
10372  if (!isOpenMPCapturedDecl(D))
10373  ExprCaptures.push_back(Ref->getDecl());
10374  }
10375  if (TopDVar.CKind == OMPC_firstprivate ||
10376  (!isOpenMPCapturedDecl(D) &&
10377  Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
10378  ExprResult RefRes = DefaultLvalueConversion(Ref);
10379  if (!RefRes.isUsable())
10380  continue;
10381  ExprResult PostUpdateRes =
10382  BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
10383  RefRes.get());
10384  if (!PostUpdateRes.isUsable())
10385  continue;
10386  ExprPostUpdates.push_back(
10387  IgnoredValueConversions(PostUpdateRes.get()).get());
10388  }
10389  }
10390  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
10391  Vars.push_back((VD || CurContext->isDependentContext())
10392  ? RefExpr->IgnoreParens()
10393  : Ref);
10394  SrcExprs.push_back(PseudoSrcExpr);
10395  DstExprs.push_back(PseudoDstExpr);
10396  AssignmentOps.push_back(AssignmentOp.get());
10397  }
10398 
10399  if (Vars.empty())
10400  return nullptr;
10401 
10402  return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
10403  Vars, SrcExprs, DstExprs, AssignmentOps,
10404  buildPreInits(Context, ExprCaptures),
10405  buildPostUpdate(*this, ExprPostUpdates));
10406 }
10407 
10409  SourceLocation StartLoc,
10410  SourceLocation LParenLoc,
10411  SourceLocation EndLoc) {
10413  for (Expr *RefExpr : VarList) {
10414  assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
10415  SourceLocation ELoc;
10416  SourceRange ERange;
10417  Expr *SimpleRefExpr = RefExpr;
10418  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
10419  if (Res.second) {
10420  // It will be analyzed later.
10421  Vars.push_back(RefExpr);
10422  }
10423  ValueDecl *D = Res.first;
10424  if (!D)
10425  continue;
10426 
10427  auto *VD = dyn_cast<VarDecl>(D);
10428  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
10429  // in a Construct]
10430  // Variables with the predetermined data-sharing attributes may not be
10431  // listed in data-sharing attributes clauses, except for the cases
10432  // listed below. For these exceptions only, listing a predetermined
10433  // variable in a data-sharing attribute clause is allowed and overrides
10434  // the variable's predetermined data-sharing attributes.
10435  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
10436  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
10437  DVar.RefExpr) {
10438  Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
10439  << getOpenMPClauseName(OMPC_shared);
10440  reportOriginalDsa(*this, DSAStack, D, DVar);
10441  continue;
10442  }
10443 
10444  DeclRefExpr *Ref = nullptr;
10445  if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
10446  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
10447  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
10448  Vars.push_back((VD || !Ref || CurContext->isDependentContext())
10449  ? RefExpr->IgnoreParens()
10450  : Ref);
10451  }
10452 
10453  if (Vars.empty())
10454  return nullptr;
10455 
10456  return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
10457 }
10458 
10459 namespace {
10460 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
10461  DSAStackTy *Stack;
10462 
10463 public:
10464  bool VisitDeclRefExpr(DeclRefExpr *E) {
10465  if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
10466  DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
10467  if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
10468  return false;
10469  if (DVar.CKind != OMPC_unknown)
10470  return true;
10471  DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
10472  VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; },
10473  /*FromParent=*/true);
10474  return DVarPrivate.CKind != OMPC_unknown;
10475  }
10476  return false;
10477  }
10478  bool VisitStmt(Stmt *S) {
10479  for (Stmt *Child : S->children()) {
10480  if (Child && Visit(Child))
10481  return true;
10482  }
10483  return false;
10484  }
10485  explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
10486 };
10487 } // namespace
10488 
10489 namespace {
10490 // Transform MemberExpression for specified FieldDecl of current class to
10491 // DeclRefExpr to specified OMPCapturedExprDecl.
10492 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
10493  typedef TreeTransform<TransformExprToCaptures> BaseTransform;
10494  ValueDecl *Field = nullptr;
10495  DeclRefExpr *CapturedExpr = nullptr;
10496 
10497 public:
10498  TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
10499  : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
10500 
10501  ExprResult TransformMemberExpr(MemberExpr *E) {
10502  if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
10503  E->getMemberDecl() == Field) {
10504  CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
10505  return CapturedExpr;
10506  }
10507  return BaseTransform::TransformMemberExpr(E);
10508  }
10509  DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
10510 };
10511 } // namespace
10512 
10513 template <typename T, typename U>
10515  const llvm::function_ref<T(ValueDecl *)> Gen) {
10516  for (U &Set : Lookups) {
10517  for (auto *D : Set) {
10518  if (T Res = Gen(cast<ValueDecl>(D)))
10519  return Res;
10520  }
10521  }
10522  return T();
10523 }
10524 
10526  assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case");
10527 
10528  for (auto RD : D->redecls()) {
10529  // Don't bother with extra checks if we already know this one isn't visible.
10530  if (RD == D)
10531  continue;
10532 
10533  auto ND = cast<NamedDecl>(RD);
10534  if (LookupResult::isVisible(SemaRef, ND))
10535  return ND;
10536  }
10537 
10538  return nullptr;
10539 }
10540 
10541 static void
10542 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &ReductionId,
10543  SourceLocation Loc, QualType Ty,
10544  SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
10545  // Find all of the associated namespaces and classes based on the
10546  // arguments we have.
10547  Sema::AssociatedNamespaceSet AssociatedNamespaces;
10548  Sema::AssociatedClassSet AssociatedClasses;
10549  OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
10550  SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
10551  AssociatedClasses);
10552 
10553  // C++ [basic.lookup.argdep]p3:
10554  // Let X be the lookup set produced by unqualified lookup (3.4.1)
10555  // and let Y be the lookup set produced by argument dependent
10556  // lookup (defined as follows). If X contains [...] then Y is
10557  // empty. Otherwise Y is the set of declarations found in the
10558  // namespaces associated with the argument types as described
10559  // below. The set of declarations found by the lookup of the name
10560  // is the union of X and Y.
10561  //
10562  // Here, we compute Y and add its members to the overloaded
10563  // candidate set.
10564  for (auto *NS : AssociatedNamespaces) {
10565  // When considering an associated namespace, the lookup is the
10566  // same as the lookup performed when the associated namespace is
10567  // used as a qualifier (3.4.3.2) except that:
10568  //
10569  // -- Any using-directives in the associated namespace are
10570  // ignored.
10571  //
10572  // -- Any namespace-scope friend functions declared in
10573  // associated classes are visible within their respective
10574  // namespaces even if they are not visible during an ordinary
10575  // lookup (11.4).
10576  DeclContext::lookup_result R = NS->lookup(ReductionId.getName());
10577  for (auto *D : R) {
10578  auto *Underlying = D;
10579  if (auto *USD = dyn_cast<UsingShadowDecl>(D))
10580  Underlying = USD->getTargetDecl();
10581 
10582  if (!isa<OMPDeclareReductionDecl>(Underlying))
10583  continue;
10584 
10585  if (!SemaRef.isVisible(D)) {
10586  D = findAcceptableDecl(SemaRef, D);
10587  if (!D)
10588  continue;
10589  if (auto *USD = dyn_cast<UsingShadowDecl>(D))
10590  Underlying = USD->getTargetDecl();
10591  }
10592  Lookups.emplace_back();
10593  Lookups.back().addDecl(Underlying);
10594  }
10595  }
10596 }
10597 
10598 static ExprResult
10600  Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
10601  const DeclarationNameInfo &ReductionId, QualType Ty,
10602  CXXCastPath &BasePath, Expr *UnresolvedReduction) {
10603  if (ReductionIdScopeSpec.isInvalid())
10604  return ExprError();
10605  SmallVector<UnresolvedSet<8>, 4> Lookups;
10606  if (S) {
10607  LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
10608  Lookup.suppressDiagnostics();
10609  while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
10610  NamedDecl *D = Lookup.getRepresentativeDecl();
10611  do {
10612  S = S->getParent();
10613  } while (S && !S->isDeclScope(D));
10614  if (S)
10615  S = S->getParent();
10616  Lookups.emplace_back();
10617  Lookups.back().append(Lookup.begin(), Lookup.end());
10618  Lookup.clear();
10619  }
10620  } else if (auto *ULE =
10621  cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
10622  Lookups.push_back(UnresolvedSet<8>());
10623  Decl *PrevD = nullptr;
10624  for (NamedDecl *D : ULE->decls()) {
10625  if (D == PrevD)
10626  Lookups.push_back(UnresolvedSet<8>());
10627  else if (auto *DRD = cast<OMPDeclareReductionDecl>(D))
10628  Lookups.back().addDecl(DRD);
10629  PrevD = D;
10630  }
10631  }
10632  if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
10635  filterLookupForUDR<bool>(Lookups, [](ValueDecl *D) {
10636  return !D->isInvalidDecl() &&
10637  (D->getType()->isDependentType() ||
10640  })) {
10641  UnresolvedSet<8> ResSet;
10642  for (const UnresolvedSet<8> &Set : Lookups) {
10643  if (Set.empty())
10644  continue;
10645  ResSet.append(Set.begin(), Set.end());
10646  // The last item marks the end of all declarations at the specified scope.
10647  ResSet.addDecl(Set[Set.size() - 1]);
10648  }
10650  SemaRef.Context, /*NamingClass=*/nullptr,
10651  ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
10652  /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
10653  }
10654  // Lookup inside the classes.
10655  // C++ [over.match.oper]p3:
10656  // For a unary operator @ with an operand of a type whose
10657  // cv-unqualified version is T1, and for a binary operator @ with
10658  // a left operand of a type whose cv-unqualified version is T1 and
10659  // a right operand of a type whose cv-unqualified version is T2,
10660  // three sets of candidate functions, designated member
10661  // candidates, non-member candidates and built-in candidates, are
10662  // constructed as follows:
10663  // -- If T1 is a complete class type or a class currently being
10664  // defined, the set of member candidates is the result of the
10665  // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
10666  // the set of member candidates is empty.
10667  LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
10668  Lookup.suppressDiagnostics();
10669  if (const auto *TyRec = Ty->getAs<RecordType>()) {
10670  // Complete the type if it can be completed.
10671  // If the type is neither complete nor being defined, bail out now.
10672  if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
10673  TyRec->getDecl()->getDefinition()) {
10674  Lookup.clear();
10675  SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
10676  if (Lookup.empty()) {
10677  Lookups.emplace_back();
10678  Lookups.back().append(Lookup.begin(), Lookup.end());
10679  }
10680  }
10681  }
10682  // Perform ADL.
10683  argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
10684  if (auto *VD = filterLookupForUDR<ValueDecl *>(
10685  Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
10686  if (!D->isInvalidDecl() &&
10687  SemaRef.Context.hasSameType(D->getType(), Ty))
10688  return D;
10689  return nullptr;
10690  }))
10691  return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc);
10692  if (auto *VD = filterLookupForUDR<ValueDecl *>(
10693  Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
10694  if (!D->isInvalidDecl() &&
10695  SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
10696  !Ty.isMoreQualifiedThan(D->getType()))
10697  return D;
10698  return nullptr;
10699  })) {
10700  CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
10701  /*DetectVirtual=*/false);
10702  if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
10703  if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
10704  VD->getType().getUnqualifiedType()))) {
10705  if (SemaRef.CheckBaseClassAccess(Loc, VD->getType(), Ty, Paths.front(),
10706  /*DiagID=*/0) !=
10708  SemaRef.BuildBasePathArray(Paths, BasePath);
10709  return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc);
10710  }
10711  }
10712  }
10713  }
10714  if (ReductionIdScopeSpec.isSet()) {
10715  SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range;
10716  return ExprError();
10717  }
10718  return ExprEmpty();
10719 }
10720 
10721 namespace {
10722 /// Data for the reduction-based clauses.
10723 struct ReductionData {
10724  /// List of original reduction items.
10726  /// List of private copies of the reduction items.
10728  /// LHS expressions for the reduction_op expressions.
10730  /// RHS expressions for the reduction_op expressions.
10732  /// Reduction operation expression.
10733  SmallVector<Expr *, 8> ReductionOps;
10734  /// Taskgroup descriptors for the corresponding reduction items in
10735  /// in_reduction clauses.
10736  SmallVector<Expr *, 8> TaskgroupDescriptors;
10737  /// List of captures for clause.
10738  SmallVector<Decl *, 4> ExprCaptures;
10739  /// List of postupdate expressions.
10740  SmallVector<Expr *, 4> ExprPostUpdates;
10741  ReductionData() = delete;
10742  /// Reserves required memory for the reduction data.
10743  ReductionData(unsigned Size) {
10744  Vars.reserve(Size);
10745  Privates.reserve(Size);
10746  LHSs.reserve(Size);
10747  RHSs.reserve(Size);
10748  ReductionOps.reserve(Size);
10749  TaskgroupDescriptors.reserve(Size);
10750  ExprCaptures.reserve(Size);
10751  ExprPostUpdates.reserve(Size);
10752  }
10753  /// Stores reduction item and reduction operation only (required for dependent
10754  /// reduction item).
10755  void push(Expr *Item, Expr *ReductionOp) {
10756  Vars.emplace_back(Item);
10757  Privates.emplace_back(nullptr);
10758  LHSs.emplace_back(nullptr);
10759  RHSs.emplace_back(nullptr);
10760  ReductionOps.emplace_back(ReductionOp);
10761  TaskgroupDescriptors.emplace_back(nullptr);
10762  }
10763  /// Stores reduction data.
10764  void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
10765  Expr *TaskgroupDescriptor) {
10766  Vars.emplace_back(Item);
10767  Privates.emplace_back(Private);
10768  LHSs.emplace_back(LHS);
10769  RHSs.emplace_back(RHS);
10770  ReductionOps.emplace_back(ReductionOp);
10771  TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
10772  }
10773 };
10774 } // namespace
10775 
10777  ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
10778  SmallVectorImpl<llvm::APSInt> &ArraySizes) {
10779  const Expr *Length = OASE->getLength();
10780  if (Length == nullptr) {
10781  // For array sections of the form [1:] or [:], we would need to analyze
10782  // the lower bound...
10783  if (OASE->getColonLoc().isValid())
10784  return false;
10785 
10786  // This is an array subscript which has implicit length 1!
10787  SingleElement = true;
10788  ArraySizes.push_back(llvm::APSInt::get(1));
10789  } else {
10791  if (!Length->EvaluateAsInt(Result, Context))
10792  return false;
10793 
10794  llvm::APSInt ConstantLengthValue = Result.Val.getInt();
10795  SingleElement = (ConstantLengthValue.getSExtValue() == 1);
10796  ArraySizes.push_back(ConstantLengthValue);
10797  }
10798 
10799  // Get the base of this array section and walk up from there.
10800  const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
10801 
10802  // We require length = 1 for all array sections except the right-most to
10803  // guarantee that the memory region is contiguous and has no holes in it.
10804  while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
10805  Length = TempOASE->getLength();
10806  if (Length == nullptr) {
10807  // For array sections of the form [1:] or [:], we would need to analyze
10808  // the lower bound...
10809  if (OASE->getColonLoc().isValid())
10810  return false;
10811 
10812  // This is an array subscript which has implicit length 1!
10813  ArraySizes.push_back(llvm::APSInt::get(1));
10814  } else {
10816  if (!Length->EvaluateAsInt(Result, Context))
10817  return false;
10818 
10819  llvm::APSInt ConstantLengthValue = Result.Val.getInt();
10820  if (ConstantLengthValue.getSExtValue() != 1)
10821  return false;
10822 
10823  ArraySizes.push_back(ConstantLengthValue);
10824  }
10825  Base = TempOASE->getBase()->IgnoreParenImpCasts();
10826  }
10827 
10828  // If we have a single element, we don't need to add the implicit lengths.
10829  if (!SingleElement) {
10830  while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
10831  // Has implicit length 1!
10832  ArraySizes.push_back(llvm::APSInt::get(1));
10833  Base = TempASE->getBase()->IgnoreParenImpCasts();
10834  }
10835  }
10836 
10837  // This array section can be privatized as a single value or as a constant
10838  // sized array.
10839  return true;
10840 }
10841 
10843  Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
10844  ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
10846  CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
10847  ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
10848  DeclarationName DN = ReductionId.getName();
10850  BinaryOperatorKind BOK = BO_Comma;
10851 
10852  ASTContext &Context = S.Context;
10853  // OpenMP [2.14.3.6, reduction clause]
10854  // C
10855  // reduction-identifier is either an identifier or one of the following
10856  // operators: +, -, *, &, |, ^, && and ||
10857  // C++
10858  // reduction-identifier is either an id-expression or one of the following
10859  // operators: +, -, *, &, |, ^, && and ||
10860  switch (OOK) {
10861  case OO_Plus:
10862  case OO_Minus:
10863  BOK = BO_Add;
10864  break;
10865  case OO_Star:
10866  BOK = BO_Mul;
10867  break;
10868  case OO_Amp:
10869  BOK = BO_And;
10870  break;
10871  case OO_Pipe:
10872  BOK = BO_Or;
10873  break;
10874  case OO_Caret:
10875  BOK = BO_Xor;
10876  break;
10877  case OO_AmpAmp:
10878  BOK = BO_LAnd;
10879  break;
10880  case OO_PipePipe:
10881  BOK = BO_LOr;
10882  break;
10883  case OO_New:
10884  case OO_Delete:
10885  case OO_Array_New:
10886  case OO_Array_Delete:
10887  case OO_Slash:
10888  case OO_Percent:
10889  case OO_Tilde:
10890  case OO_Exclaim:
10891  case OO_Equal:
10892  case OO_Less:
10893  case OO_Greater:
10894  case OO_LessEqual:
10895  case OO_GreaterEqual:
10896  case OO_PlusEqual:
10897  case OO_MinusEqual:
10898  case OO_StarEqual:
10899  case OO_SlashEqual:
10900  case OO_PercentEqual:
10901  case OO_CaretEqual:
10902  case OO_AmpEqual:
10903  case OO_PipeEqual:
10904  case OO_LessLess:
10905  case OO_GreaterGreater:
10906  case OO_LessLessEqual:
10907  case OO_GreaterGreaterEqual:
10908  case OO_EqualEqual:
10909  case OO_ExclaimEqual:
10910  case OO_Spaceship:
10911  case OO_PlusPlus:
10912  case OO_MinusMinus:
10913  case OO_Comma:
10914  case OO_ArrowStar:
10915  case OO_Arrow:
10916  case OO_Call:
10917  case OO_Subscript:
10918  case OO_Conditional:
10919  case OO_Coawait:
10921  llvm_unreachable("Unexpected reduction identifier");
10922  case OO_None:
10923  if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
10924  if (II->isStr("max"))
10925  BOK = BO_GT;
10926  else if (II->isStr("min"))
10927  BOK = BO_LT;
10928  }
10929  break;
10930  }
10931  SourceRange ReductionIdRange;
10932  if (ReductionIdScopeSpec.isValid())
10933  ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
10934  else
10935  ReductionIdRange.setBegin(ReductionId.getBeginLoc());
10936  ReductionIdRange.setEnd(ReductionId.getEndLoc());
10937 
10938  auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
10939  bool FirstIter = true;
10940  for (Expr *RefExpr : VarList) {
10941  assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
10942  // OpenMP [2.1, C/C++]
10943  // A list item is a variable or array section, subject to the restrictions
10944  // specified in Section 2.4 on page 42 and in each of the sections
10945  // describing clauses and directives for which a list appears.
10946  // OpenMP [2.14.3.3, Restrictions, p.1]
10947  // A variable that is part of another variable (as an array or
10948  // structure element) cannot appear in a private clause.
10949  if (!FirstIter && IR != ER)
10950  ++IR;
10951  FirstIter = false;
10952  SourceLocation ELoc;
10953  SourceRange ERange;
10954  Expr *SimpleRefExpr = RefExpr;
10955  auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
10956  /*AllowArraySection=*/true);
10957  if (Res.second) {
10958  // Try to find 'declare reduction' corresponding construct before using
10959  // builtin/overloaded operators.
10960  QualType Type = Context.DependentTy;
10961  CXXCastPath BasePath;
10962  ExprResult DeclareReductionRef = buildDeclareReductionRef(
10963  S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
10964  ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
10965  Expr *ReductionOp = nullptr;
10966  if (S.CurContext->isDependentContext() &&
10967  (DeclareReductionRef.isUnset() ||
10968  isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
10969  ReductionOp = DeclareReductionRef.get();
10970  // It will be analyzed later.
10971  RD.push(RefExpr, ReductionOp);
10972  }
10973  ValueDecl *D = Res.first;
10974  if (!D)
10975  continue;
10976 
10977  Expr *TaskgroupDescriptor = nullptr;
10978  QualType Type;
10979  auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
10980  auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
10981  if (ASE) {
10982  Type = ASE->getType().getNonReferenceType();
10983  } else if (OASE) {
10984  QualType BaseType =
10986  if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
10987  Type = ATy->getElementType();
10988  else
10989  Type = BaseType->getPointeeType();
10990  Type = Type.getNonReferenceType();
10991  } else {
10992  Type = Context.getBaseElementType(D->getType().getNonReferenceType());
10993  }
10994  auto *VD = dyn_cast<VarDecl>(D);
10995 
10996  // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
10997  // A variable that appears in a private clause must not have an incomplete
10998  // type or a reference type.
10999  if (S.RequireCompleteType(ELoc, D->getType(),
11000  diag::err_omp_reduction_incomplete_type))
11001  continue;
11002  // OpenMP [2.14.3.6, reduction clause, Restrictions]
11003  // A list item that appears in a reduction clause must not be
11004  // const-qualified.
11005  if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
11006  /*AcceptIfMutable*/ false, ASE || OASE))
11007  continue;
11008 
11009  OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
11010  // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
11011  // If a list-item is a reference type then it must bind to the same object
11012  // for all threads of the team.
11013  if (!ASE && !OASE) {
11014  if (VD) {
11015  VarDecl *VDDef = VD->getDefinition();
11016  if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
11017  DSARefChecker Check(Stack);
11018  if (Check.Visit(VDDef->getInit())) {
11019  S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
11020  << getOpenMPClauseName(ClauseKind) << ERange;
11021  S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
11022  continue;
11023  }
11024  }
11025  }
11026 
11027  // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
11028  // in a Construct]
11029  // Variables with the predetermined data-sharing attributes may not be
11030  // listed in data-sharing attributes clauses, except for the cases
11031  // listed below. For these exceptions only, listing a predetermined
11032  // variable in a data-sharing attribute clause is allowed and overrides
11033  // the variable's predetermined data-sharing attributes.
11034  // OpenMP [2.14.3.6, Restrictions, p.3]
11035  // Any number of reduction clauses can be specified on the directive,
11036  // but a list item can appear only once in the reduction clauses for that
11037  // directive.
11038  DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
11039  if (DVar.CKind == OMPC_reduction) {
11040  S.Diag(ELoc, diag::err_omp_once_referenced)
11041  << getOpenMPClauseName(ClauseKind);
11042  if (DVar.RefExpr)
11043  S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
11044  continue;
11045  }
11046  if (DVar.CKind != OMPC_unknown) {
11047  S.Diag(ELoc, diag::err_omp_wrong_dsa)
11048  << getOpenMPClauseName(DVar.CKind)
11049  << getOpenMPClauseName(OMPC_reduction);
11050  reportOriginalDsa(S, Stack, D, DVar);
11051  continue;
11052  }
11053 
11054  // OpenMP [2.14.3.6, Restrictions, p.1]
11055  // A list item that appears in a reduction clause of a worksharing
11056  // construct must be shared in the parallel regions to which any of the
11057  // worksharing regions arising from the worksharing construct bind.
11058  if (isOpenMPWorksharingDirective(CurrDir) &&
11059  !isOpenMPParallelDirective(CurrDir) &&
11060  !isOpenMPTeamsDirective(CurrDir)) {
11061  DVar = Stack->getImplicitDSA(D, true);
11062  if (DVar.CKind != OMPC_shared) {
11063  S.Diag(ELoc, diag::err_omp_required_access)
11064  << getOpenMPClauseName(OMPC_reduction)
11065  << getOpenMPClauseName(OMPC_shared);
11066  reportOriginalDsa(S, Stack, D, DVar);
11067  continue;
11068  }
11069  }
11070  }
11071 
11072  // Try to find 'declare reduction' corresponding construct before using
11073  // builtin/overloaded operators.
11074  CXXCastPath BasePath;
11075  ExprResult DeclareReductionRef = buildDeclareReductionRef(
11076  S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
11077  ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
11078  if (DeclareReductionRef.isInvalid())
11079  continue;
11080  if (S.CurContext->isDependentContext() &&
11081  (DeclareReductionRef.isUnset() ||
11082  isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
11083  RD.push(RefExpr, DeclareReductionRef.get());
11084  continue;
11085  }
11086  if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
11087  // Not allowed reduction identifier is found.
11088  S.Diag(ReductionId.getBeginLoc(),
11089  diag::err_omp_unknown_reduction_identifier)
11090  << Type << ReductionIdRange;
11091  continue;
11092  }
11093 
11094  // OpenMP [2.14.3.6, reduction clause, Restrictions]
11095  // The type of a list item that appears in a reduction clause must be valid
11096  // for the reduction-identifier. For a max or min reduction in C, the type
11097  // of the list item must be an allowed arithmetic data type: char, int,
11098  // float, double, or _Bool, possibly modified with long, short, signed, or
11099  // unsigned. For a max or min reduction in C++, the type of the list item
11100  // must be an allowed arithmetic data type: char, wchar_t, int, float,
11101  // double, or bool, possibly modified with long, short, signed, or unsigned.
11102  if (DeclareReductionRef.isUnset()) {
11103  if ((BOK == BO_GT || BOK == BO_LT) &&
11104  !(Type->isScalarType() ||
11105  (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
11106  S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
11107  << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
11108  if (!ASE && !OASE) {
11109  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
11111  S.Diag(D->getLocation(),
11112  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11113  << D;
11114  }
11115  continue;
11116  }
11117  if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
11118  !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
11119  S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
11120  << getOpenMPClauseName(ClauseKind);
11121  if (!ASE && !OASE) {
11122  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
11124  S.Diag(D->getLocation(),
11125  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11126  << D;
11127  }
11128  continue;
11129  }
11130  }
11131 
11132  Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
11133  VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
11134  D->hasAttrs() ? &D->getAttrs() : nullptr);
11135  VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
11136  D->hasAttrs() ? &D->getAttrs() : nullptr);
11137  QualType PrivateTy = Type;
11138 
11139  // Try if we can determine constant lengths for all array sections and avoid
11140  // the VLA.
11141  bool ConstantLengthOASE = false;
11142  if (OASE) {
11143  bool SingleElement;
11145  ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
11146  Context, OASE, SingleElement, ArraySizes);
11147 
11148  // If we don't have a single element, we must emit a constant array type.
11149  if (ConstantLengthOASE && !SingleElement) {
11150  for (llvm::APSInt &Size : ArraySizes)
11151  PrivateTy = Context.getConstantArrayType(
11152  PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0);
11153  }
11154  }
11155 
11156  if ((OASE && !ConstantLengthOASE) ||
11157  (!OASE && !ASE &&
11159  if (!Context.getTargetInfo().isVLASupported() &&
11161  S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
11162  S.Diag(ELoc, diag::note_vla_unsupported);
11163  continue;
11164  }
11165  // For arrays/array sections only:
11166  // Create pseudo array type for private copy. The size for this array will
11167  // be generated during codegen.
11168  // For array subscripts or single variables Private Ty is the same as Type
11169  // (type of the variable or single array element).
11170  PrivateTy = Context.getVariableArrayType(
11171  Type,
11172  new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue),
11173  ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
11174  } else if (!ASE && !OASE &&
11175  Context.getAsArrayType(D->getType().getNonReferenceType())) {
11176  PrivateTy = D->getType().getNonReferenceType();
11177  }
11178  // Private copy.
11179  VarDecl *PrivateVD =
11180  buildVarDecl(S, ELoc, PrivateTy, D->getName(),
11181  D->hasAttrs() ? &D->getAttrs() : nullptr,
11182  VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
11183  // Add initializer for private variable.
11184  Expr *Init = nullptr;
11185  DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
11186  DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
11187  if (DeclareReductionRef.isUsable()) {
11188  auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
11189  auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
11190  if (DRD->getInitializer()) {
11191  Init = DRDRef;
11192  RHSVD->setInit(DRDRef);
11193  RHSVD->setInitStyle(VarDecl::CallInit);
11194  }
11195  } else {
11196  switch (BOK) {
11197  case BO_Add:
11198  case BO_Xor:
11199  case BO_Or:
11200  case BO_LOr:
11201  // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
11202  if (Type->isScalarType() || Type->isAnyComplexType())
11203  Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
11204  break;
11205  case BO_Mul:
11206  case BO_LAnd:
11207  if (Type->isScalarType() || Type->isAnyComplexType()) {
11208  // '*' and '&&' reduction ops - initializer is '1'.
11209  Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
11210  }
11211  break;
11212  case BO_And: {
11213  // '&' reduction op - initializer is '~0'.
11214  QualType OrigType = Type;
11215  if (auto *ComplexTy = OrigType->getAs<ComplexType>())
11216  Type = ComplexTy->getElementType();
11217  if (Type->isRealFloatingType()) {
11218  llvm::APFloat InitValue =
11219  llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type),
11220  /*isIEEE=*/true);
11221  Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
11222  Type, ELoc);
11223  } else if (Type->isScalarType()) {
11224  uint64_t Size = Context.getTypeSize(Type);
11225  QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
11226  llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
11227  Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
11228  }
11229  if (Init && OrigType->isAnyComplexType()) {
11230  // Init = 0xFFFF + 0xFFFFi;
11231  auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
11232  Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
11233  }
11234  Type = OrigType;
11235  break;
11236  }
11237  case BO_LT:
11238  case BO_GT: {
11239  // 'min' reduction op - initializer is 'Largest representable number in
11240  // the reduction list item type'.
11241  // 'max' reduction op - initializer is 'Least representable number in
11242  // the reduction list item type'.
11243  if (Type->isIntegerType() || Type->isPointerType()) {
11244  bool IsSigned = Type->hasSignedIntegerRepresentation();
11245  uint64_t Size = Context.getTypeSize(Type);
11246  QualType IntTy =
11247  Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
11248  llvm::APInt InitValue =
11249  (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
11250  : llvm::APInt::getMinValue(Size)
11251  : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
11252  : llvm::APInt::getMaxValue(Size);
11253  Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
11254  if (Type->isPointerType()) {
11255  // Cast to pointer type.
11257  ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
11258  if (CastExpr.isInvalid())
11259  continue;
11260  Init = CastExpr.get();
11261  }
11262  } else if (Type->isRealFloatingType()) {
11263  llvm::APFloat InitValue = llvm::APFloat::getLargest(
11264  Context.getFloatTypeSemantics(Type), BOK != BO_LT);
11265  Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
11266  Type, ELoc);
11267  }
11268  break;
11269  }
11270  case BO_PtrMemD:
11271  case BO_PtrMemI:
11272  case BO_MulAssign:
11273  case BO_Div:
11274  case BO_Rem:
11275  case BO_Sub:
11276  case BO_Shl:
11277  case BO_Shr:
11278  case BO_LE:
11279  case BO_GE:
11280  case BO_EQ:
11281  case BO_NE:
11282  case BO_Cmp:
11283  case BO_AndAssign:
11284  case BO_XorAssign:
11285  case BO_OrAssign:
11286  case BO_Assign:
11287  case BO_AddAssign:
11288  case BO_SubAssign:
11289  case BO_DivAssign:
11290  case BO_RemAssign:
11291  case BO_ShlAssign:
11292  case BO_ShrAssign:
11293  case BO_Comma:
11294  llvm_unreachable("Unexpected reduction operation");
11295  }
11296  }
11297  if (Init && DeclareReductionRef.isUnset())
11298  S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
11299  else if (!Init)
11300  S.ActOnUninitializedDecl(RHSVD);
11301  if (RHSVD->isInvalidDecl())
11302  continue;
11303  if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) {
11304  S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
11305  << Type << ReductionIdRange;
11306  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
11308  S.Diag(D->getLocation(),
11309  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11310  << D;
11311  continue;
11312  }
11313  // Store initializer for single element in private copy. Will be used during
11314  // codegen.
11315  PrivateVD->setInit(RHSVD->getInit());
11316  PrivateVD->setInitStyle(RHSVD->getInitStyle());
11317  DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
11318  ExprResult ReductionOp;
11319  if (DeclareReductionRef.isUsable()) {
11320  QualType RedTy = DeclareReductionRef.get()->getType();
11321  QualType PtrRedTy = Context.getPointerType(RedTy);
11322  ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
11323  ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
11324  if (!BasePath.empty()) {
11325  LHS = S.DefaultLvalueConversion(LHS.get());
11326  RHS = S.DefaultLvalueConversion(RHS.get());
11327  LHS = ImplicitCastExpr::Create(Context, PtrRedTy,
11328  CK_UncheckedDerivedToBase, LHS.get(),
11329  &BasePath, LHS.get()->getValueKind());
11330  RHS = ImplicitCastExpr::Create(Context, PtrRedTy,
11331  CK_UncheckedDerivedToBase, RHS.get(),
11332  &BasePath, RHS.get()->getValueKind());
11333  }
11335  QualType Params[] = {PtrRedTy, PtrRedTy};
11336  QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
11337  auto *OVE = new (Context) OpaqueValueExpr(
11338  ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary,
11339  S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
11340  Expr *Args[] = {LHS.get(), RHS.get()};
11341  ReductionOp =
11342  CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc);
11343  } else {
11344  ReductionOp = S.BuildBinOp(
11345  Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE);
11346  if (ReductionOp.isUsable()) {
11347  if (BOK != BO_LT && BOK != BO_GT) {
11348  ReductionOp =
11349  S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
11350  BO_Assign, LHSDRE, ReductionOp.get());
11351  } else {
11352  auto *ConditionalOp = new (Context)
11353  ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE,
11354  Type, VK_LValue, OK_Ordinary);
11355  ReductionOp =
11356  S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
11357  BO_Assign, LHSDRE, ConditionalOp);
11358  }
11359  if (ReductionOp.isUsable())
11360  ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
11361  /*DiscardedValue*/ false);
11362  }
11363  if (!ReductionOp.isUsable())
11364  continue;
11365  }
11366 
11367  // OpenMP [2.15.4.6, Restrictions, p.2]
11368  // A list item that appears in an in_reduction clause of a task construct
11369  // must appear in a task_reduction clause of a construct associated with a
11370  // taskgroup region that includes the participating task in its taskgroup
11371  // set. The construct associated with the innermost region that meets this
11372  // condition must specify the same reduction-identifier as the in_reduction
11373  // clause.
11374  if (ClauseKind == OMPC_in_reduction) {
11375  SourceRange ParentSR;
11376  BinaryOperatorKind ParentBOK;
11377  const Expr *ParentReductionOp;
11378  Expr *ParentBOKTD, *ParentReductionOpTD;
11379  DSAStackTy::DSAVarData ParentBOKDSA =
11380  Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
11381  ParentBOKTD);
11382  DSAStackTy::DSAVarData ParentReductionOpDSA =
11383  Stack->getTopMostTaskgroupReductionData(
11384  D, ParentSR, ParentReductionOp, ParentReductionOpTD);
11385  bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
11386  bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
11387  if (!IsParentBOK && !IsParentReductionOp) {
11388  S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction);
11389  continue;
11390  }
11391  if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
11392  (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK ||
11393  IsParentReductionOp) {
11394  bool EmitError = true;
11395  if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
11396  llvm::FoldingSetNodeID RedId, ParentRedId;
11397  ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
11398  DeclareReductionRef.get()->Profile(RedId, Context,
11399  /*Canonical=*/true);
11400  EmitError = RedId != ParentRedId;
11401  }
11402  if (EmitError) {
11403  S.Diag(ReductionId.getBeginLoc(),
11404  diag::err_omp_reduction_identifier_mismatch)
11405  << ReductionIdRange << RefExpr->getSourceRange();
11406  S.Diag(ParentSR.getBegin(),
11407  diag::note_omp_previous_reduction_identifier)
11408  << ParentSR
11409  << (IsParentBOK ? ParentBOKDSA.RefExpr
11410  : ParentReductionOpDSA.RefExpr)
11411  ->getSourceRange();
11412  continue;
11413  }
11414  }
11415  TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
11416  assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined.");
11417  }
11418 
11419  DeclRefExpr *Ref = nullptr;
11420  Expr *VarsExpr = RefExpr->IgnoreParens();
11421  if (!VD && !S.CurContext->isDependentContext()) {
11422  if (ASE || OASE) {
11423  TransformExprToCaptures RebuildToCapture(S, D);
11424  VarsExpr =
11425  RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
11426  Ref = RebuildToCapture.getCapturedExpr();
11427  } else {
11428  VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
11429  }
11430  if (!S.isOpenMPCapturedDecl(D)) {
11431  RD.ExprCaptures.emplace_back(Ref->getDecl());
11432  if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
11433  ExprResult RefRes = S.DefaultLvalueConversion(Ref);
11434  if (!RefRes.isUsable())
11435  continue;
11436  ExprResult PostUpdateRes =
11437  S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
11438  RefRes.get());
11439  if (!PostUpdateRes.isUsable())
11440  continue;
11441  if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
11442  Stack->getCurrentDirective() == OMPD_taskgroup) {
11443  S.Diag(RefExpr->getExprLoc(),
11444  diag::err_omp_reduction_non_addressable_expression)
11445  << RefExpr->getSourceRange();
11446  continue;
11447  }
11448  RD.ExprPostUpdates.emplace_back(
11449  S.IgnoredValueConversions(PostUpdateRes.get()).get());
11450  }
11451  }
11452  }
11453  // All reduction items are still marked as reduction (to do not increase
11454  // code base size).
11455  Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref);
11456  if (CurrDir == OMPD_taskgroup) {
11457  if (DeclareReductionRef.isUsable())
11458  Stack->addTaskgroupReductionData(D, ReductionIdRange,
11459  DeclareReductionRef.get());
11460  else
11461  Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
11462  }
11463  RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
11464  TaskgroupDescriptor);
11465  }
11466  return RD.Vars.empty();
11467 }
11468 
11470  ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
11472  CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
11473  ArrayRef<Expr *> UnresolvedReductions) {
11474  ReductionData RD(VarList.size());
11475  if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList,
11476  StartLoc, LParenLoc, ColonLoc, EndLoc,
11477  ReductionIdScopeSpec, ReductionId,
11478  UnresolvedReductions, RD))
11479  return nullptr;
11480 
11482  Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
11483  ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
11484  RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
11485  buildPreInits(Context, RD.ExprCaptures),
11486  buildPostUpdate(*this, RD.ExprPostUpdates));
11487 }
11488 
11490  ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
11492  CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
11493  ArrayRef<Expr *> UnresolvedReductions) {
11494  ReductionData RD(VarList.size());
11495  if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList,
11496  StartLoc, LParenLoc, ColonLoc, EndLoc,
11497  ReductionIdScopeSpec, ReductionId,
11498  UnresolvedReductions, RD))
11499  return nullptr;
11500 
11502  Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
11503  ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
11504  RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
11505  buildPreInits(Context, RD.ExprCaptures),
11506  buildPostUpdate(*this, RD.ExprPostUpdates));
11507 }
11508 
11510  ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
11512  CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
11513  ArrayRef<Expr *> UnresolvedReductions) {
11514  ReductionData RD(VarList.size());
11515  if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList,
11516  StartLoc, LParenLoc, ColonLoc, EndLoc,
11517  ReductionIdScopeSpec, ReductionId,
11518  UnresolvedReductions, RD))
11519  return nullptr;
11520 
11522  Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
11523  ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
11524  RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
11525  buildPreInits(Context, RD.ExprCaptures),
11526  buildPostUpdate(*this, RD.ExprPostUpdates));
11527 }
11528 
11530  SourceLocation LinLoc) {
11531  if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
11532  LinKind == OMPC_LINEAR_unknown) {
11533  Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
11534  return true;
11535  }
11536  return false;
11537 }
11538 
11540  OpenMPLinearClauseKind LinKind,
11541  QualType Type) {
11542  const auto *VD = dyn_cast_or_null<VarDecl>(D);
11543  // A variable must not have an incomplete type or a reference type.
11544  if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
11545  return true;
11546  if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
11547  !Type->isReferenceType()) {
11548  Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
11549  << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
11550  return true;
11551  }
11552  Type = Type.getNonReferenceType();
11553 
11554  // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
11555  // A variable that is privatized must not have a const-qualified type
11556  // unless it is of class type with a mutable member. This restriction does
11557  // not apply to the firstprivate clause.
11558  if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
11559  return true;
11560 
11561  // A list item must be of integral or pointer type.
11562  Type = Type.getUnqualifiedType().getCanonicalType();
11563  const auto *Ty = Type.getTypePtrOrNull();
11564  if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) &&
11565  !Ty->isPointerType())) {
11566  Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
11567  if (D) {
11568  bool IsDecl =
11569  !VD ||
11570  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
11571  Diag(D->getLocation(),
11572  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11573  << D;
11574  }
11575  return true;
11576  }
11577  return false;
11578 }
11579 
11581  ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
11582  SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
11587  SmallVector<Decl *, 4> ExprCaptures;
11588  SmallVector<Expr *, 4> ExprPostUpdates;
11589  if (CheckOpenMPLinearModifier(LinKind, LinLoc))
11590  LinKind = OMPC_LINEAR_val;
11591  for (Expr *RefExpr : VarList) {
11592  assert(RefExpr && "NULL expr in OpenMP linear clause.");
11593  SourceLocation ELoc;
11594  SourceRange ERange;
11595  Expr *SimpleRefExpr = RefExpr;
11596  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
11597  if (Res.second) {
11598  // It will be analyzed later.
11599  Vars.push_back(RefExpr);
11600  Privates.push_back(nullptr);
11601  Inits.push_back(nullptr);
11602  }
11603  ValueDecl *D = Res.first;
11604  if (!D)
11605  continue;
11606 
11607  QualType Type = D->getType();
11608  auto *VD = dyn_cast<VarDecl>(D);
11609 
11610  // OpenMP [2.14.3.7, linear clause]
11611  // A list-item cannot appear in more than one linear clause.
11612  // A list-item that appears in a linear clause cannot appear in any
11613  // other data-sharing attribute clause.
11614  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
11615  if (DVar.RefExpr) {
11616  Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
11617  << getOpenMPClauseName(OMPC_linear);
11618  reportOriginalDsa(*this, DSAStack, D, DVar);
11619  continue;
11620  }
11621 
11622  if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
11623  continue;
11625 
11626  // Build private copy of original var.
11627  VarDecl *Private =
11628  buildVarDecl(*this, ELoc, Type, D->getName(),
11629  D->hasAttrs() ? &D->getAttrs() : nullptr,
11630  VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
11631  DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
11632  // Build var to save initial value.
11633  VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
11634  Expr *InitExpr;
11635  DeclRefExpr *Ref = nullptr;
11636  if (!VD && !CurContext->isDependentContext()) {
11637  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
11638  if (!isOpenMPCapturedDecl(D)) {
11639  ExprCaptures.push_back(Ref->getDecl());
11640  if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
11641  ExprResult RefRes = DefaultLvalueConversion(Ref);
11642  if (!RefRes.isUsable())
11643  continue;
11644  ExprResult PostUpdateRes =
11645  BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
11646  SimpleRefExpr, RefRes.get());
11647  if (!PostUpdateRes.isUsable())
11648  continue;
11649  ExprPostUpdates.push_back(
11650  IgnoredValueConversions(PostUpdateRes.get()).get());
11651  }
11652  }
11653  }
11654  if (LinKind == OMPC_LINEAR_uval)
11655  InitExpr = VD ? VD->getInit() : SimpleRefExpr;
11656  else
11657  InitExpr = VD ? SimpleRefExpr : Ref;
11658  AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
11659  /*DirectInit=*/false);
11660  DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
11661 
11662  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
11663  Vars.push_back((VD || CurContext->isDependentContext())
11664  ? RefExpr->IgnoreParens()
11665  : Ref);
11666  Privates.push_back(PrivateRef);
11667  Inits.push_back(InitRef);
11668  }
11669 
11670  if (Vars.empty())
11671  return nullptr;
11672 
11673  Expr *StepExpr = Step;
11674  Expr *CalcStepExpr = nullptr;
11675  if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
11676  !Step->isInstantiationDependent() &&
11678  SourceLocation StepLoc = Step->getBeginLoc();
11679  ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
11680  if (Val.isInvalid())
11681  return nullptr;
11682  StepExpr = Val.get();
11683 
11684  // Build var to save the step value.
11685  VarDecl *SaveVar =
11686  buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
11687  ExprResult SaveRef =
11688  buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
11690  BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
11691  CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
11692 
11693  // Warn about zero linear step (it would be probably better specified as
11694  // making corresponding variables 'const').
11695  llvm::APSInt Result;
11696  bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context);
11697  if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive())
11698  Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0]
11699  << (Vars.size() > 1);
11700  if (!IsConstant && CalcStep.isUsable()) {
11701  // Calculate the step beforehand instead of doing this on each iteration.
11702  // (This is not used if the number of iterations may be kfold-ed).
11703  CalcStepExpr = CalcStep.get();
11704  }
11705  }
11706 
11707  return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
11708  ColonLoc, EndLoc, Vars, Privates, Inits,
11709  StepExpr, CalcStepExpr,
11710  buildPreInits(Context, ExprCaptures),
11711  buildPostUpdate(*this, ExprPostUpdates));
11712 }
11713 
11715  Expr *NumIterations, Sema &SemaRef,
11716  Scope *S, DSAStackTy *Stack) {
11717  // Walk the vars and build update/final expressions for the CodeGen.
11720  Expr *Step = Clause.getStep();
11721  Expr *CalcStep = Clause.getCalcStep();
11722  // OpenMP [2.14.3.7, linear clause]
11723  // If linear-step is not specified it is assumed to be 1.
11724  if (!Step)
11725  Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
11726  else if (CalcStep)
11727  Step = cast<BinaryOperator>(CalcStep)->getLHS();
11728  bool HasErrors = false;
11729  auto CurInit = Clause.inits().begin();
11730  auto CurPrivate = Clause.privates().begin();
11731  OpenMPLinearClauseKind LinKind = Clause.getModifier();
11732  for (Expr *RefExpr : Clause.varlists()) {
11733  SourceLocation ELoc;
11734  SourceRange ERange;
11735  Expr *SimpleRefExpr = RefExpr;
11736  auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
11737  ValueDecl *D = Res.first;
11738  if (Res.second || !D) {
11739  Updates.push_back(nullptr);
11740  Finals.push_back(nullptr);
11741  HasErrors = true;
11742  continue;
11743  }
11744  auto &&Info = Stack->isLoopControlVariable(D);
11745  // OpenMP [2.15.11, distribute simd Construct]
11746  // A list item may not appear in a linear clause, unless it is the loop
11747  // iteration variable.
11748  if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
11749  isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
11750  SemaRef.Diag(ELoc,
11751  diag::err_omp_linear_distribute_var_non_loop_iteration);
11752  Updates.push_back(nullptr);
11753  Finals.push_back(nullptr);
11754  HasErrors = true;
11755  continue;
11756  }
11757  Expr *InitExpr = *CurInit;
11758 
11759  // Build privatized reference to the current linear var.
11760  auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
11761  Expr *CapturedRef;
11762  if (LinKind == OMPC_LINEAR_uval)
11763  CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
11764  else
11765  CapturedRef =
11766  buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
11767  DE->getType().getUnqualifiedType(), DE->getExprLoc(),
11768  /*RefersToCapture=*/true);
11769 
11770  // Build update: Var = InitExpr + IV * Step
11772  if (!Info.first)
11773  Update =
11774  buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate,
11775  InitExpr, IV, Step, /* Subtract */ false);
11776  else
11777  Update = *CurPrivate;
11778  Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
11779  /*DiscardedValue*/ false);
11780 
11781  // Build final: Var = InitExpr + NumIterations * Step
11782  ExprResult Final;
11783  if (!Info.first)
11784  Final =
11785  buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
11786  InitExpr, NumIterations, Step, /*Subtract=*/false);
11787  else
11788  Final = *CurPrivate;
11789  Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
11790  /*DiscardedValue*/ false);
11791 
11792  if (!Update.isUsable() || !Final.isUsable()) {
11793  Updates.push_back(nullptr);
11794  Finals.push_back(nullptr);
11795  HasErrors = true;
11796  } else {
11797  Updates.push_back(Update.get());
11798  Finals.push_back(Final.get());
11799  }
11800  ++CurInit;
11801  ++CurPrivate;
11802  }
11803  Clause.setUpdates(Updates);
11804  Clause.setFinals(Finals);
11805  return HasErrors;
11806 }
11807 
11809  ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
11812  for (Expr *RefExpr : VarList) {
11813  assert(RefExpr && "NULL expr in OpenMP linear clause.");
11814  SourceLocation ELoc;
11815  SourceRange ERange;
11816  Expr *SimpleRefExpr = RefExpr;
11817  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
11818  if (Res.second) {
11819  // It will be analyzed later.
11820  Vars.push_back(RefExpr);
11821  }
11822  ValueDecl *D = Res.first;
11823  if (!D)
11824  continue;
11825 
11826  QualType QType = D->getType();
11827  auto *VD = dyn_cast<VarDecl>(D);
11828 
11829  // OpenMP [2.8.1, simd construct, Restrictions]
11830  // The type of list items appearing in the aligned clause must be
11831  // array, pointer, reference to array, or reference to pointer.
11833  const Type *Ty = QType.getTypePtrOrNull();
11834  if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
11835  Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
11836  << QType << getLangOpts().CPlusPlus << ERange;
11837  bool IsDecl =
11838  !VD ||
11839  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
11840  Diag(D->getLocation(),
11841  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
11842  << D;
11843  continue;
11844  }
11845 
11846  // OpenMP [2.8.1, simd construct, Restrictions]
11847  // A list-item cannot appear in more than one aligned clause.
11848  if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
11849  Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange;
11850  Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
11851  << getOpenMPClauseName(OMPC_aligned);
11852  continue;
11853  }
11854 
11855  DeclRefExpr *Ref = nullptr;
11856  if (!VD && isOpenMPCapturedDecl(D))
11857  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
11858  Vars.push_back(DefaultFunctionArrayConversion(
11859  (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
11860  .get());
11861  }
11862 
11863  // OpenMP [2.8.1, simd construct, Description]
11864  // The parameter of the aligned clause, alignment, must be a constant
11865  // positive integer expression.
11866  // If no optional parameter is specified, implementation-defined default
11867  // alignments for SIMD instructions on the target platforms are assumed.
11868  if (Alignment != nullptr) {
11869  ExprResult AlignResult =
11870  VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
11871  if (AlignResult.isInvalid())
11872  return nullptr;
11873  Alignment = AlignResult.get();
11874  }
11875  if (Vars.empty())
11876  return nullptr;
11877 
11878  return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
11879  EndLoc, Vars, Alignment);
11880 }
11881 
11883  SourceLocation StartLoc,
11884  SourceLocation LParenLoc,
11885  SourceLocation EndLoc) {
11887  SmallVector<Expr *, 8> SrcExprs;
11888  SmallVector<Expr *, 8> DstExprs;
11889  SmallVector<Expr *, 8> AssignmentOps;
11890  for (Expr *RefExpr : VarList) {
11891  assert(RefExpr && "NULL expr in OpenMP copyin clause.");
11892  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
11893  // It will be analyzed later.
11894  Vars.push_back(RefExpr);
11895  SrcExprs.push_back(nullptr);
11896  DstExprs.push_back(nullptr);
11897  AssignmentOps.push_back(nullptr);
11898  continue;
11899  }
11900 
11901  SourceLocation ELoc = RefExpr->getExprLoc();
11902  // OpenMP [2.1, C/C++]
11903  // A list item is a variable name.
11904  // OpenMP [2.14.4.1, Restrictions, p.1]
11905  // A list item that appears in a copyin clause must be threadprivate.
11906  auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
11907  if (!DE || !isa<VarDecl>(DE->getDecl())) {
11908  Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
11909  << 0 << RefExpr->getSourceRange();
11910  continue;
11911  }
11912 
11913  Decl *D = DE->getDecl();
11914  auto *VD = cast<VarDecl>(D);
11915 
11916  QualType Type = VD->getType();
11917  if (Type->isDependentType() || Type->isInstantiationDependentType()) {
11918  // It will be analyzed later.
11919  Vars.push_back(DE);
11920  SrcExprs.push_back(nullptr);
11921  DstExprs.push_back(nullptr);
11922  AssignmentOps.push_back(nullptr);
11923  continue;
11924  }
11925 
11926  // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
11927  // A list item that appears in a copyin clause must be threadprivate.
11928  if (!DSAStack->isThreadPrivate(VD)) {
11929  Diag(ELoc, diag::err_omp_required_access)
11930  << getOpenMPClauseName(OMPC_copyin)
11931  << getOpenMPDirectiveName(OMPD_threadprivate);
11932  continue;
11933  }
11934 
11935  // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
11936  // A variable of class type (or array thereof) that appears in a
11937  // copyin clause requires an accessible, unambiguous copy assignment
11938  // operator for the class type.
11939  QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
11940  VarDecl *SrcVD =
11941  buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
11942  ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
11943  DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
11944  *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
11945  VarDecl *DstVD =
11946  buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
11947  VD->hasAttrs() ? &VD->getAttrs() : nullptr);
11948  DeclRefExpr *PseudoDstExpr =
11949  buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
11950  // For arrays generate assignment operation for single element and replace
11951  // it by the original array element in CodeGen.
11952  ExprResult AssignmentOp =
11953  BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
11954  PseudoSrcExpr);
11955  if (AssignmentOp.isInvalid())
11956  continue;
11957  AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
11958  /*DiscardedValue*/ false);
11959  if (AssignmentOp.isInvalid())
11960  continue;
11961 
11962  DSAStack->addDSA(VD, DE, OMPC_copyin);
11963  Vars.push_back(DE);
11964  SrcExprs.push_back(PseudoSrcExpr);
11965  DstExprs.push_back(PseudoDstExpr);
11966  AssignmentOps.push_back(AssignmentOp.get());
11967  }
11968 
11969  if (Vars.empty())
11970  return nullptr;
11971 
11972  return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
11973  SrcExprs, DstExprs, AssignmentOps);
11974 }
11975 
11977  SourceLocation StartLoc,
11978  SourceLocation LParenLoc,
11979  SourceLocation EndLoc) {
11981  SmallVector<Expr *, 8> SrcExprs;
11982  SmallVector<Expr *, 8> DstExprs;
11983  SmallVector<Expr *, 8> AssignmentOps;
11984  for (Expr *RefExpr : VarList) {
11985  assert(RefExpr && "NULL expr in OpenMP linear clause.");
11986  SourceLocation ELoc;
11987  SourceRange ERange;
11988  Expr *SimpleRefExpr = RefExpr;
11989  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
11990  if (Res.second) {
11991  // It will be analyzed later.
11992  Vars.push_back(RefExpr);
11993  SrcExprs.push_back(nullptr);
11994  DstExprs.push_back(nullptr);
11995  AssignmentOps.push_back(nullptr);
11996  }
11997  ValueDecl *D = Res.first;
11998  if (!D)
11999  continue;
12000 
12001  QualType Type = D->getType();
12002  auto *VD = dyn_cast<VarDecl>(D);
12003 
12004  // OpenMP [2.14.4.2, Restrictions, p.2]
12005  // A list item that appears in a copyprivate clause may not appear in a
12006  // private or firstprivate clause on the single construct.
12007  if (!VD || !DSAStack->isThreadPrivate(VD)) {
12008  DSAStackTy::DSAVarData DVar =
12009  DSAStack->getTopDSA(D, /*FromParent=*/false);
12010  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
12011  DVar.RefExpr) {
12012  Diag(ELoc, diag::err_omp_wrong_dsa)
12013  << getOpenMPClauseName(DVar.CKind)
12014  << getOpenMPClauseName(OMPC_copyprivate);
12015  reportOriginalDsa(*this, DSAStack, D, DVar);
12016  continue;
12017  }
12018 
12019  // OpenMP [2.11.4.2, Restrictions, p.1]
12020  // All list items that appear in a copyprivate clause must be either
12021  // threadprivate or private in the enclosing context.
12022  if (DVar.CKind == OMPC_unknown) {
12023  DVar = DSAStack->getImplicitDSA(D, false);
12024  if (DVar.CKind == OMPC_shared) {
12025  Diag(ELoc, diag::err_omp_required_access)
12026  << getOpenMPClauseName(OMPC_copyprivate)
12027  << "threadprivate or private in the enclosing context";
12028  reportOriginalDsa(*this, DSAStack, D, DVar);
12029  continue;
12030  }
12031  }
12032  }
12033 
12034  // Variably modified types are not supported.
12035  if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
12036  Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
12037  << getOpenMPClauseName(OMPC_copyprivate) << Type
12038  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
12039  bool IsDecl =
12040  !VD ||
12041  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
12042  Diag(D->getLocation(),
12043  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
12044  << D;
12045  continue;
12046  }
12047 
12048  // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
12049  // A variable of class type (or array thereof) that appears in a
12050  // copyin clause requires an accessible, unambiguous copy assignment
12051  // operator for the class type.
12052  Type = Context.getBaseElementType(Type.getNonReferenceType())
12053  .getUnqualifiedType();
12054  VarDecl *SrcVD =
12055  buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
12056  D->hasAttrs() ? &D->getAttrs() : nullptr);
12057  DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
12058  VarDecl *DstVD =
12059  buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
12060  D->hasAttrs() ? &D->getAttrs() : nullptr);
12061  DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
12062  ExprResult AssignmentOp = BuildBinOp(
12063  DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
12064  if (AssignmentOp.isInvalid())
12065  continue;
12066  AssignmentOp =
12067  ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
12068  if (AssignmentOp.isInvalid())
12069  continue;
12070 
12071  // No need to mark vars as copyprivate, they are already threadprivate or
12072  // implicitly private.
12073  assert(VD || isOpenMPCapturedDecl(D));
12074  Vars.push_back(
12075  VD ? RefExpr->IgnoreParens()
12076  : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
12077  SrcExprs.push_back(PseudoSrcExpr);
12078  DstExprs.push_back(PseudoDstExpr);
12079  AssignmentOps.push_back(AssignmentOp.get());
12080  }
12081 
12082  if (Vars.empty())
12083  return nullptr;
12084 
12085  return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
12086  Vars, SrcExprs, DstExprs, AssignmentOps);
12087 }
12088 
12090  SourceLocation StartLoc,
12091  SourceLocation LParenLoc,
12092  SourceLocation EndLoc) {
12093  if (VarList.empty())
12094  return nullptr;
12095 
12096  return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
12097 }
12098 
12099 OMPClause *
12102  ArrayRef<Expr *> VarList, SourceLocation StartLoc,
12103  SourceLocation LParenLoc, SourceLocation EndLoc) {
12104  if (DSAStack->getCurrentDirective() == OMPD_ordered &&
12105  DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
12106  Diag(DepLoc, diag::err_omp_unexpected_clause_value)
12107  << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
12108  return nullptr;
12109  }
12110  if (DSAStack->getCurrentDirective() != OMPD_ordered &&
12111  (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
12112  DepKind == OMPC_DEPEND_sink)) {
12113  unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink};
12114  Diag(DepLoc, diag::err_omp_unexpected_clause_value)
12115  << getListOfPossibleValues(OMPC_depend, /*First=*/0,
12116  /*Last=*/OMPC_DEPEND_unknown, Except)
12117  << getOpenMPClauseName(OMPC_depend);
12118  return nullptr;
12119  }
12122  llvm::APSInt DepCounter(/*BitWidth=*/32);
12123  llvm::APSInt TotalDepCount(/*BitWidth=*/32);
12124  if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
12125  if (const Expr *OrderedCountExpr =
12126  DSAStack->getParentOrderedRegionParam().first) {
12127  TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
12128  TotalDepCount.setIsUnsigned(/*Val=*/true);
12129  }
12130  }
12131  for (Expr *RefExpr : VarList) {
12132  assert(RefExpr && "NULL expr in OpenMP shared clause.");
12133  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
12134  // It will be analyzed later.
12135  Vars.push_back(RefExpr);
12136  continue;
12137  }
12138 
12139  SourceLocation ELoc = RefExpr->getExprLoc();
12140  Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
12141  if (DepKind == OMPC_DEPEND_sink) {
12142  if (DSAStack->getParentOrderedRegionParam().first &&
12143  DepCounter >= TotalDepCount) {
12144  Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
12145  continue;
12146  }
12147  ++DepCounter;
12148  // OpenMP [2.13.9, Summary]
12149  // depend(dependence-type : vec), where dependence-type is:
12150  // 'sink' and where vec is the iteration vector, which has the form:
12151  // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
12152  // where n is the value specified by the ordered clause in the loop
12153  // directive, xi denotes the loop iteration variable of the i-th nested
12154  // loop associated with the loop directive, and di is a constant
12155  // non-negative integer.
12156  if (CurContext->isDependentContext()) {
12157  // It will be analyzed later.
12158  Vars.push_back(RefExpr);
12159  continue;
12160  }
12161  SimpleExpr = SimpleExpr->IgnoreImplicit();
12163  SourceLocation OOLoc;
12164  Expr *LHS = SimpleExpr;
12165  Expr *RHS = nullptr;
12166  if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
12167  OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
12168  OOLoc = BO->getOperatorLoc();
12169  LHS = BO->getLHS()->IgnoreParenImpCasts();
12170  RHS = BO->getRHS()->IgnoreParenImpCasts();
12171  } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
12172  OOK = OCE->getOperator();
12173  OOLoc = OCE->getOperatorLoc();
12174  LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
12175  RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
12176  } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
12177  OOK = MCE->getMethodDecl()
12178  ->getNameInfo()
12179  .getName()
12180  .getCXXOverloadedOperator();
12181  OOLoc = MCE->getCallee()->getExprLoc();
12182  LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
12183  RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
12184  }
12185  SourceLocation ELoc;
12186  SourceRange ERange;
12187  auto Res = getPrivateItem(*this, LHS, ELoc, ERange);
12188  if (Res.second) {
12189  // It will be analyzed later.
12190  Vars.push_back(RefExpr);
12191  }
12192  ValueDecl *D = Res.first;
12193  if (!D)
12194  continue;
12195 
12196  if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
12197  Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
12198  continue;
12199  }
12200  if (RHS) {
12201  ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
12202  RHS, OMPC_depend, /*StrictlyPositive=*/false);
12203  if (RHSRes.isInvalid())
12204  continue;
12205  }
12206  if (!CurContext->isDependentContext() &&
12207  DSAStack->getParentOrderedRegionParam().first &&
12208  DepCounter != DSAStack->isParentLoopControlVariable(D).first) {
12209  const ValueDecl *VD =
12210  DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue());
12211  if (VD)
12212  Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
12213  << 1 << VD;
12214  else
12215  Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
12216  continue;
12217  }
12218  OpsOffs.emplace_back(RHS, OOK);
12219  } else {
12220  auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
12221  if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
12222  (ASE &&
12223  !ASE->getBase()->getType().getNonReferenceType()->isPointerType() &&
12224  !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
12225  Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
12226  << RefExpr->getSourceRange();
12227  continue;
12228  }
12229  bool Suppress = getDiagnostics().getSuppressAllDiagnostics();
12230  getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true);
12231  ExprResult Res =
12232  CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RefExpr->IgnoreParenImpCasts());
12233  getDiagnostics().setSuppressAllDiagnostics(Suppress);
12234  if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) {
12235  Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
12236  << RefExpr->getSourceRange();
12237  continue;
12238  }
12239  }
12240  Vars.push_back(RefExpr->IgnoreParenImpCasts());
12241  }
12242 
12243  if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
12244  TotalDepCount > VarList.size() &&
12245  DSAStack->getParentOrderedRegionParam().first &&
12246  DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
12247  Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
12248  << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1);
12249  }
12250  if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
12251  Vars.empty())
12252  return nullptr;
12253 
12254  auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
12255  DepKind, DepLoc, ColonLoc, Vars,
12256  TotalDepCount.getZExtValue());
12257  if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
12258  DSAStack->isParentOrderedRegion())
12259  DSAStack->addDoacrossDependClause(C, OpsOffs);
12260  return C;
12261 }
12262 
12264  SourceLocation LParenLoc,
12265  SourceLocation EndLoc) {
12266  Expr *ValExpr = Device;
12267  Stmt *HelperValStmt = nullptr;
12268 
12269  // OpenMP [2.9.1, Restrictions]
12270  // The device expression must evaluate to a non-negative integer value.
12271  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
12272  /*StrictlyPositive=*/false))
12273  return nullptr;
12274 
12275  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
12276  OpenMPDirectiveKind CaptureRegion =
12277  getOpenMPCaptureRegionForClause(DKind, OMPC_device);
12278  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
12279  ValExpr = MakeFullExpr(ValExpr).get();
12280  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12281  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12282  HelperValStmt = buildPreInits(Context, Captures);
12283  }
12284 
12285  return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion,
12286  StartLoc, LParenLoc, EndLoc);
12287 }
12288 
12289 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
12290  DSAStackTy *Stack, QualType QTy,
12291  bool FullCheck = true) {
12292  NamedDecl *ND;
12293  if (QTy->isIncompleteType(&ND)) {
12294  SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR;
12295  return false;
12296  }
12297  if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
12298  !QTy.isTrivialType(SemaRef.Context))
12299  SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
12300  return true;
12301 }
12302 
12303 /// Return true if it can be proven that the provided array expression
12304 /// (array section or array subscript) does NOT specify the whole size of the
12305 /// array whose base type is \a BaseQTy.
12307  const Expr *E,
12308  QualType BaseQTy) {
12309  const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
12310 
12311  // If this is an array subscript, it refers to the whole size if the size of
12312  // the dimension is constant and equals 1. Also, an array section assumes the
12313  // format of an array subscript if no colon is used.
12314  if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) {
12315  if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
12316  return ATy->getSize().getSExtValue() != 1;
12317  // Size can't be evaluated statically.
12318  return false;
12319  }
12320 
12321  assert(OASE && "Expecting array section if not an array subscript.");
12322  const Expr *LowerBound = OASE->getLowerBound();
12323  const Expr *Length = OASE->getLength();
12324 
12325  // If there is a lower bound that does not evaluates to zero, we are not
12326  // covering the whole dimension.
12327  if (LowerBound) {
12329  if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
12330  return false; // Can't get the integer value as a constant.
12331 
12332  llvm::APSInt ConstLowerBound = Result.Val.getInt();
12333  if (ConstLowerBound.getSExtValue())
12334  return true;
12335  }
12336 
12337  // If we don't have a length we covering the whole dimension.
12338  if (!Length)
12339  return false;
12340 
12341  // If the base is a pointer, we don't have a way to get the size of the
12342  // pointee.
12343  if (BaseQTy->isPointerType())
12344  return false;
12345 
12346  // We can only check if the length is the same as the size of the dimension
12347  // if we have a constant array.
12348  const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
12349  if (!CATy)
12350  return false;
12351 
12353  if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
12354  return false; // Can't get the integer value as a constant.
12355 
12356  llvm::APSInt ConstLength = Result.Val.getInt();
12357  return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
12358 }
12359 
12360 // Return true if it can be proven that the provided array expression (array
12361 // section or array subscript) does NOT specify a single element of the array
12362 // whose base type is \a BaseQTy.
12364  const Expr *E,
12365  QualType BaseQTy) {
12366  const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
12367 
12368  // An array subscript always refer to a single element. Also, an array section
12369  // assumes the format of an array subscript if no colon is used.
12370  if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid()))
12371  return false;
12372 
12373  assert(OASE && "Expecting array section if not an array subscript.");
12374  const Expr *Length = OASE->getLength();
12375 
12376  // If we don't have a length we have to check if the array has unitary size
12377  // for this dimension. Also, we should always expect a length if the base type
12378  // is pointer.
12379  if (!Length) {
12380  if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
12381  return ATy->getSize().getSExtValue() != 1;
12382  // We cannot assume anything.
12383  return false;
12384  }
12385 
12386  // Check if the length evaluates to 1.
12388  if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
12389  return false; // Can't get the integer value as a constant.
12390 
12391  llvm::APSInt ConstLength = Result.Val.getInt();
12392  return ConstLength.getSExtValue() != 1;
12393 }
12394 
12395 // Return the expression of the base of the mappable expression or null if it
12396 // cannot be determined and do all the necessary checks to see if the expression
12397 // is valid as a standalone mappable expression. In the process, record all the
12398 // components of the expression.
12400  Sema &SemaRef, Expr *E,
12402  OpenMPClauseKind CKind, bool NoDiagnose) {
12403  SourceLocation ELoc = E->getExprLoc();
12404  SourceRange ERange = E->getSourceRange();
12405 
12406  // The base of elements of list in a map clause have to be either:
12407  // - a reference to variable or field.
12408  // - a member expression.
12409  // - an array expression.
12410  //
12411  // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
12412  // reference to 'r'.
12413  //
12414  // If we have:
12415  //
12416  // struct SS {
12417  // Bla S;
12418  // foo() {
12419  // #pragma omp target map (S.Arr[:12]);
12420  // }
12421  // }
12422  //
12423  // We want to retrieve the member expression 'this->S';
12424 
12425  const Expr *RelevantExpr = nullptr;
12426 
12427  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2]
12428  // If a list item is an array section, it must specify contiguous storage.
12429  //
12430  // For this restriction it is sufficient that we make sure only references
12431  // to variables or fields and array expressions, and that no array sections
12432  // exist except in the rightmost expression (unless they cover the whole
12433  // dimension of the array). E.g. these would be invalid:
12434  //
12435  // r.ArrS[3:5].Arr[6:7]
12436  //
12437  // r.ArrS[3:5].x
12438  //
12439  // but these would be valid:
12440  // r.ArrS[3].Arr[6:7]
12441  //
12442  // r.ArrS[3].x
12443 
12444  bool AllowUnitySizeArraySection = true;
12445  bool AllowWholeSizeArraySection = true;
12446 
12447  while (!RelevantExpr) {
12448  E = E->IgnoreParenImpCasts();
12449 
12450  if (auto *CurE = dyn_cast<DeclRefExpr>(E)) {
12451  if (!isa<VarDecl>(CurE->getDecl()))
12452  return nullptr;
12453 
12454  RelevantExpr = CurE;
12455 
12456  // If we got a reference to a declaration, we should not expect any array
12457  // section before that.
12458  AllowUnitySizeArraySection = false;
12459  AllowWholeSizeArraySection = false;
12460 
12461  // Record the component.
12462  CurComponents.emplace_back(CurE, CurE->getDecl());
12463  } else if (auto *CurE = dyn_cast<MemberExpr>(E)) {
12464  Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts();
12465 
12466  if (isa<CXXThisExpr>(BaseE))
12467  // We found a base expression: this->Val.
12468  RelevantExpr = CurE;
12469  else
12470  E = BaseE;
12471 
12472  if (!isa<FieldDecl>(CurE->getMemberDecl())) {
12473  if (!NoDiagnose) {
12474  SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
12475  << CurE->getSourceRange();
12476  return nullptr;
12477  }
12478  if (RelevantExpr)
12479  return nullptr;
12480  continue;
12481  }
12482 
12483  auto *FD = cast<FieldDecl>(CurE->getMemberDecl());
12484 
12485  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
12486  // A bit-field cannot appear in a map clause.
12487  //
12488  if (FD->isBitField()) {
12489  if (!NoDiagnose) {
12490  SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
12491  << CurE->getSourceRange() << getOpenMPClauseName(CKind);
12492  return nullptr;
12493  }
12494  if (RelevantExpr)
12495  return nullptr;
12496  continue;
12497  }
12498 
12499  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
12500  // If the type of a list item is a reference to a type T then the type
12501  // will be considered to be T for all purposes of this clause.
12502  QualType CurType = BaseE->getType().getNonReferenceType();
12503 
12504  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
12505  // A list item cannot be a variable that is a member of a structure with
12506  // a union type.
12507  //
12508  if (CurType->isUnionType()) {
12509  if (!NoDiagnose) {
12510  SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
12511  << CurE->getSourceRange();
12512  return nullptr;
12513  }
12514  continue;
12515  }
12516 
12517  // If we got a member expression, we should not expect any array section
12518  // before that:
12519  //
12520  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
12521  // If a list item is an element of a structure, only the rightmost symbol
12522  // of the variable reference can be an array section.
12523  //
12524  AllowUnitySizeArraySection = false;
12525  AllowWholeSizeArraySection = false;
12526 
12527  // Record the component.
12528  CurComponents.emplace_back(CurE, FD);
12529  } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) {
12530  E = CurE->getBase()->IgnoreParenImpCasts();
12531 
12532  if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
12533  if (!NoDiagnose) {
12534  SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
12535  << 0 << CurE->getSourceRange();
12536  return nullptr;
12537  }
12538  continue;
12539  }
12540 
12541  // If we got an array subscript that express the whole dimension we
12542  // can have any array expressions before. If it only expressing part of
12543  // the dimension, we can only have unitary-size array expressions.
12545  E->getType()))
12546  AllowWholeSizeArraySection = false;
12547 
12548  if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
12550  if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) {
12551  if (!Result.Val.getInt().isNullValue()) {
12552  SemaRef.Diag(CurE->getIdx()->getExprLoc(),
12553  diag::err_omp_invalid_map_this_expr);
12554  SemaRef.Diag(CurE->getIdx()->getExprLoc(),
12555  diag::note_omp_invalid_subscript_on_this_ptr_map);
12556  }
12557  }
12558  RelevantExpr = TE;
12559  }
12560 
12561  // Record the component - we don't have any declaration associated.
12562  CurComponents.emplace_back(CurE, nullptr);
12563  } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) {
12564  assert(!NoDiagnose && "Array sections cannot be implicitly mapped.");
12565  E = CurE->getBase()->IgnoreParenImpCasts();
12566 
12567  QualType CurType =
12569 
12570  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
12571  // If the type of a list item is a reference to a type T then the type
12572  // will be considered to be T for all purposes of this clause.
12573  if (CurType->isReferenceType())
12574  CurType = CurType->getPointeeType();
12575 
12576  bool IsPointer = CurType->isAnyPointerType();
12577 
12578  if (!IsPointer && !CurType->isArrayType()) {
12579  SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
12580  << 0 << CurE->getSourceRange();
12581  return nullptr;
12582  }
12583 
12584  bool NotWhole =
12585  checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType);
12586  bool NotUnity =
12587  checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType);
12588 
12589  if (AllowWholeSizeArraySection) {
12590  // Any array section is currently allowed. Allowing a whole size array
12591  // section implies allowing a unity array section as well.
12592  //
12593  // If this array section refers to the whole dimension we can still
12594  // accept other array sections before this one, except if the base is a
12595  // pointer. Otherwise, only unitary sections are accepted.
12596  if (NotWhole || IsPointer)
12597  AllowWholeSizeArraySection = false;
12598  } else if (AllowUnitySizeArraySection && NotUnity) {
12599  // A unity or whole array section is not allowed and that is not
12600  // compatible with the properties of the current array section.
12601  SemaRef.Diag(
12602  ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
12603  << CurE->getSourceRange();
12604  return nullptr;
12605  }
12606 
12607  if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
12608  Expr::EvalResult ResultR;
12609  Expr::EvalResult ResultL;
12610  if (CurE->getLength()->EvaluateAsInt(ResultR,
12611  SemaRef.getASTContext())) {
12612  if (!ResultR.Val.getInt().isOneValue()) {
12613  SemaRef.Diag(CurE->getLength()->getExprLoc(),
12614  diag::err_omp_invalid_map_this_expr);
12615  SemaRef.Diag(CurE->getLength()->getExprLoc(),
12616  diag::note_omp_invalid_length_on_this_ptr_mapping);
12617  }
12618  }
12619  if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt(
12620  ResultL, SemaRef.getASTContext())) {
12621  if (!ResultL.Val.getInt().isNullValue()) {
12622  SemaRef.Diag(CurE->getLowerBound()->getExprLoc(),
12623  diag::err_omp_invalid_map_this_expr);
12624  SemaRef.Diag(CurE->getLowerBound()->getExprLoc(),
12625  diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
12626  }
12627  }
12628  RelevantExpr = TE;
12629  }
12630 
12631  // Record the component - we don't have any declaration associated.
12632  CurComponents.emplace_back(CurE, nullptr);
12633  } else {
12634  if (!NoDiagnose) {
12635  // If nothing else worked, this is not a valid map clause expression.
12636  SemaRef.Diag(
12637  ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
12638  << ERange;
12639  }
12640  return nullptr;
12641  }
12642  }
12643 
12644  return RelevantExpr;
12645 }
12646 
12647 // Return true if expression E associated with value VD has conflicts with other
12648 // map information.
12649 static bool checkMapConflicts(
12650  Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
12651  bool CurrentRegionOnly,
12653  OpenMPClauseKind CKind) {
12654  assert(VD && E);
12655  SourceLocation ELoc = E->getExprLoc();
12656  SourceRange ERange = E->getSourceRange();
12657 
12658  // In order to easily check the conflicts we need to match each component of
12659  // the expression under test with the components of the expressions that are
12660  // already in the stack.
12661 
12662  assert(!CurComponents.empty() && "Map clause expression with no components!");
12663  assert(CurComponents.back().getAssociatedDeclaration() == VD &&
12664  "Map clause expression with unexpected base!");
12665 
12666  // Variables to help detecting enclosing problems in data environment nests.
12667  bool IsEnclosedByDataEnvironmentExpr = false;
12668  const Expr *EnclosingExpr = nullptr;
12669 
12670  bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
12671  VD, CurrentRegionOnly,
12672  [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
12673  ERange, CKind, &EnclosingExpr,
12675  StackComponents,
12676  OpenMPClauseKind) {
12677  assert(!StackComponents.empty() &&
12678  "Map clause expression with no components!");
12679  assert(StackComponents.back().getAssociatedDeclaration() == VD &&
12680  "Map clause expression with unexpected base!");
12681  (void)VD;
12682 
12683  // The whole expression in the stack.
12684  const Expr *RE = StackComponents.front().getAssociatedExpression();
12685 
12686  // Expressions must start from the same base. Here we detect at which
12687  // point both expressions diverge from each other and see if we can
12688  // detect if the memory referred to both expressions is contiguous and
12689  // do not overlap.
12690  auto CI = CurComponents.rbegin();
12691  auto CE = CurComponents.rend();
12692  auto SI = StackComponents.rbegin();
12693  auto SE = StackComponents.rend();
12694  for (; CI != CE && SI != SE; ++CI, ++SI) {
12695 
12696  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
12697  // At most one list item can be an array item derived from a given
12698  // variable in map clauses of the same construct.
12699  if (CurrentRegionOnly &&
12700  (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
12701  isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) &&
12702  (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
12703  isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) {
12704  SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
12705  diag::err_omp_multiple_array_items_in_map_clause)
12706  << CI->getAssociatedExpression()->getSourceRange();
12707  SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
12708  diag::note_used_here)
12709  << SI->getAssociatedExpression()->getSourceRange();
12710  return true;
12711  }
12712 
12713  // Do both expressions have the same kind?
12714  if (CI->getAssociatedExpression()->getStmtClass() !=
12715  SI->getAssociatedExpression()->getStmtClass())
12716  break;
12717 
12718  // Are we dealing with different variables/fields?
12719  if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
12720  break;
12721  }
12722  // Check if the extra components of the expressions in the enclosing
12723  // data environment are redundant for the current base declaration.
12724  // If they are, the maps completely overlap, which is legal.
12725  for (; SI != SE; ++SI) {
12726  QualType Type;
12727  if (const auto *ASE =
12728  dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
12729  Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
12730  } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
12731  SI->getAssociatedExpression())) {
12732  const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
12733  Type =
12735  }
12736  if (Type.isNull() || Type->isAnyPointerType() ||
12738  SemaRef, SI->getAssociatedExpression(), Type))
12739  break;
12740  }
12741 
12742  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
12743  // List items of map clauses in the same construct must not share
12744  // original storage.
12745  //
12746  // If the expressions are exactly the same or one is a subset of the
12747  // other, it means they are sharing storage.
12748  if (CI == CE && SI == SE) {
12749  if (CurrentRegionOnly) {
12750  if (CKind == OMPC_map) {
12751  SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
12752  } else {
12753  assert(CKind == OMPC_to || CKind == OMPC_from);
12754  SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
12755  << ERange;
12756  }
12757  SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
12758  << RE->getSourceRange();
12759  return true;
12760  }
12761  // If we find the same expression in the enclosing data environment,
12762  // that is legal.
12763  IsEnclosedByDataEnvironmentExpr = true;
12764  return false;
12765  }
12766 
12767  QualType DerivedType =
12768  std::prev(CI)->getAssociatedDeclaration()->getType();
12769  SourceLocation DerivedLoc =
12770  std::prev(CI)->getAssociatedExpression()->getExprLoc();
12771 
12772  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
12773  // If the type of a list item is a reference to a type T then the type
12774  // will be considered to be T for all purposes of this clause.
12775  DerivedType = DerivedType.getNonReferenceType();
12776 
12777  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
12778  // A variable for which the type is pointer and an array section
12779  // derived from that variable must not appear as list items of map
12780  // clauses of the same construct.
12781  //
12782  // Also, cover one of the cases in:
12783  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
12784  // If any part of the original storage of a list item has corresponding
12785  // storage in the device data environment, all of the original storage
12786  // must have corresponding storage in the device data environment.
12787  //
12788  if (DerivedType->isAnyPointerType()) {
12789  if (CI == CE || SI == SE) {
12790  SemaRef.Diag(
12791  DerivedLoc,
12792  diag::err_omp_pointer_mapped_along_with_derived_section)
12793  << DerivedLoc;
12794  SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
12795  << RE->getSourceRange();
12796  return true;
12797  }
12798  if (CI->getAssociatedExpression()->getStmtClass() !=
12799  SI->getAssociatedExpression()->getStmtClass() ||
12800  CI->getAssociatedDeclaration()->getCanonicalDecl() ==
12801  SI->getAssociatedDeclaration()->getCanonicalDecl()) {
12802  assert(CI != CE && SI != SE);
12803  SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
12804  << DerivedLoc;
12805  SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
12806  << RE->getSourceRange();
12807  return true;
12808  }
12809  }
12810 
12811  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
12812  // List items of map clauses in the same construct must not share
12813  // original storage.
12814  //
12815  // An expression is a subset of the other.
12816  if (CurrentRegionOnly && (CI == CE || SI == SE)) {
12817  if (CKind == OMPC_map) {
12818  if (CI != CE || SI != SE) {
12819  // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
12820  // a pointer.
12821  auto Begin =
12822  CI != CE ? CurComponents.begin() : StackComponents.begin();
12823  auto End = CI != CE ? CurComponents.end() : StackComponents.end();
12824  auto It = Begin;
12825  while (It != End && !It->getAssociatedDeclaration())
12826  std::advance(It, 1);
12827  assert(It != End &&
12828  "Expected at least one component with the declaration.");
12829  if (It != Begin && It->getAssociatedDeclaration()
12830  ->getType()
12831  .getCanonicalType()
12832  ->isAnyPointerType()) {
12833  IsEnclosedByDataEnvironmentExpr = false;
12834  EnclosingExpr = nullptr;
12835  return false;
12836  }
12837  }
12838  SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
12839  } else {
12840  assert(CKind == OMPC_to || CKind == OMPC_from);
12841  SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
12842  << ERange;
12843  }
12844  SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
12845  << RE->getSourceRange();
12846  return true;
12847  }
12848 
12849  // The current expression uses the same base as other expression in the
12850  // data environment but does not contain it completely.
12851  if (!CurrentRegionOnly && SI != SE)
12852  EnclosingExpr = RE;
12853 
12854  // The current expression is a subset of the expression in the data
12855  // environment.
12856  IsEnclosedByDataEnvironmentExpr |=
12857  (!CurrentRegionOnly && CI != CE && SI == SE);
12858 
12859  return false;
12860  });
12861 
12862  if (CurrentRegionOnly)
12863  return FoundError;
12864 
12865  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
12866  // If any part of the original storage of a list item has corresponding
12867  // storage in the device data environment, all of the original storage must
12868  // have corresponding storage in the device data environment.
12869  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
12870  // If a list item is an element of a structure, and a different element of
12871  // the structure has a corresponding list item in the device data environment
12872  // prior to a task encountering the construct associated with the map clause,
12873  // then the list item must also have a corresponding list item in the device
12874  // data environment prior to the task encountering the construct.
12875  //
12876  if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
12877  SemaRef.Diag(ELoc,
12878  diag::err_omp_original_storage_is_shared_and_does_not_contain)
12879  << ERange;
12880  SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
12881  << EnclosingExpr->getSourceRange();
12882  return true;
12883  }
12884 
12885  return FoundError;
12886 }
12887 
12888 namespace {
12889 // Utility struct that gathers all the related lists associated with a mappable
12890 // expression.
12891 struct MappableVarListInfo {
12892  // The list of expressions.
12893  ArrayRef<Expr *> VarList;
12894  // The list of processed expressions.
12895  SmallVector<Expr *, 16> ProcessedVarList;
12896  // The mappble components for each expression.
12898  // The base declaration of the variable.
12899  SmallVector<ValueDecl *, 16> VarBaseDeclarations;
12900 
12901  MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
12902  // We have a list of components and base declarations for each entry in the
12903  // variable list.
12904  VarComponents.reserve(VarList.size());
12905  VarBaseDeclarations.reserve(VarList.size());
12906  }
12907 };
12908 }
12909 
12910 // Check the validity of the provided variable list for the provided clause kind
12911 // \a CKind. In the check process the valid expressions, and mappable expression
12912 // components and variables are extracted and used to fill \a Vars,
12913 // \a ClauseComponents, and \a ClauseBaseDeclarations. \a MapType and
12914 // \a IsMapTypeImplicit are expected to be valid if the clause kind is 'map'.
12915 static void
12916 checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS,
12917  OpenMPClauseKind CKind, MappableVarListInfo &MVLI,
12918  SourceLocation StartLoc,
12920  bool IsMapTypeImplicit = false) {
12921  // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
12922  assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
12923  "Unexpected clause kind with mappable expressions!");
12924 
12925  // Keep track of the mappable components and base declarations in this clause.
12926  // Each entry in the list is going to have a list of components associated. We
12927  // record each set of the components so that we can build the clause later on.
12928  // In the end we should have the same amount of declarations and component
12929  // lists.
12930 
12931  for (Expr *RE : MVLI.VarList) {
12932  assert(RE && "Null expr in omp to/from/map clause");
12933  SourceLocation ELoc = RE->getExprLoc();
12934 
12935  const Expr *VE = RE->IgnoreParenLValueCasts();
12936 
12937  if (VE->isValueDependent() || VE->isTypeDependent() ||
12938  VE->isInstantiationDependent() ||
12940  // We can only analyze this information once the missing information is
12941  // resolved.
12942  MVLI.ProcessedVarList.push_back(RE);
12943  continue;
12944  }
12945 
12946  Expr *SimpleExpr = RE->IgnoreParenCasts();
12947 
12948  if (!RE->IgnoreParenImpCasts()->isLValue()) {
12949  SemaRef.Diag(ELoc,
12950  diag::err_omp_expected_named_var_member_or_array_expression)
12951  << RE->getSourceRange();
12952  continue;
12953  }
12954 
12956  ValueDecl *CurDeclaration = nullptr;
12957 
12958  // Obtain the array or member expression bases if required. Also, fill the
12959  // components array with all the components identified in the process.
12960  const Expr *BE = checkMapClauseExpressionBase(
12961  SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false);
12962  if (!BE)
12963  continue;
12964 
12965  assert(!CurComponents.empty() &&
12966  "Invalid mappable expression information.");
12967 
12968  if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
12969  // Add store "this" pointer to class in DSAStackTy for future checking
12970  DSAS->addMappedClassesQualTypes(TE->getType());
12971  // Skip restriction checking for variable or field declarations
12972  MVLI.ProcessedVarList.push_back(RE);
12973  MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
12974  MVLI.VarComponents.back().append(CurComponents.begin(),
12975  CurComponents.end());
12976  MVLI.VarBaseDeclarations.push_back(nullptr);
12977  continue;
12978  }
12979 
12980  // For the following checks, we rely on the base declaration which is
12981  // expected to be associated with the last component. The declaration is
12982  // expected to be a variable or a field (if 'this' is being mapped).
12983  CurDeclaration = CurComponents.back().getAssociatedDeclaration();
12984  assert(CurDeclaration && "Null decl on map clause.");
12985  assert(
12986  CurDeclaration->isCanonicalDecl() &&
12987  "Expecting components to have associated only canonical declarations.");
12988 
12989  auto *VD = dyn_cast<VarDecl>(CurDeclaration);
12990  const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
12991 
12992  assert((VD || FD) && "Only variables or fields are expected here!");
12993  (void)FD;
12994 
12995  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
12996  // threadprivate variables cannot appear in a map clause.
12997  // OpenMP 4.5 [2.10.5, target update Construct]
12998  // threadprivate variables cannot appear in a from clause.
12999  if (VD && DSAS->isThreadPrivate(VD)) {
13000  DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
13001  SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
13002  << getOpenMPClauseName(CKind);
13003  reportOriginalDsa(SemaRef, DSAS, VD, DVar);
13004  continue;
13005  }
13006 
13007  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
13008  // A list item cannot appear in both a map clause and a data-sharing
13009  // attribute clause on the same construct.
13010 
13011  // Check conflicts with other map clause expressions. We check the conflicts
13012  // with the current construct separately from the enclosing data
13013  // environment, because the restrictions are different. We only have to
13014  // check conflicts across regions for the map clauses.
13015  if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
13016  /*CurrentRegionOnly=*/true, CurComponents, CKind))
13017  break;
13018  if (CKind == OMPC_map &&
13019  checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
13020  /*CurrentRegionOnly=*/false, CurComponents, CKind))
13021  break;
13022 
13023  // OpenMP 4.5 [2.10.5, target update Construct]
13024  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
13025  // If the type of a list item is a reference to a type T then the type will
13026  // be considered to be T for all purposes of this clause.
13027  auto I = llvm::find_if(
13028  CurComponents,
13030  return MC.getAssociatedDeclaration();
13031  });
13032  assert(I != CurComponents.end() && "Null decl on map clause.");
13033  QualType Type =
13034  I->getAssociatedDeclaration()->getType().getNonReferenceType();
13035 
13036  // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
13037  // A list item in a to or from clause must have a mappable type.
13038  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
13039  // A list item must have a mappable type.
13040  if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
13041  DSAS, Type))
13042  continue;
13043 
13044  if (CKind == OMPC_map) {
13045  // target enter data
13046  // OpenMP [2.10.2, Restrictions, p. 99]
13047  // A map-type must be specified in all map clauses and must be either
13048  // to or alloc.
13049  OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
13050  if (DKind == OMPD_target_enter_data &&
13051  !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
13052  SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
13053  << (IsMapTypeImplicit ? 1 : 0)
13054  << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
13055  << getOpenMPDirectiveName(DKind);
13056  continue;
13057  }
13058 
13059  // target exit_data
13060  // OpenMP [2.10.3, Restrictions, p. 102]
13061  // A map-type must be specified in all map clauses and must be either
13062  // from, release, or delete.
13063  if (DKind == OMPD_target_exit_data &&
13064  !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
13065  MapType == OMPC_MAP_delete)) {
13066  SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
13067  << (IsMapTypeImplicit ? 1 : 0)
13068  << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
13069  << getOpenMPDirectiveName(DKind);
13070  continue;
13071  }
13072 
13073  // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
13074  // A list item cannot appear in both a map clause and a data-sharing
13075  // attribute clause on the same construct
13076  if (VD && isOpenMPTargetExecutionDirective(DKind)) {
13077  DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
13078  if (isOpenMPPrivate(DVar.CKind)) {
13079  SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
13080  << getOpenMPClauseName(DVar.CKind)
13081  << getOpenMPClauseName(OMPC_map)
13082  << getOpenMPDirectiveName(DSAS->getCurrentDirective());
13083  reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
13084  continue;
13085  }
13086  }
13087  }
13088 
13089  // Save the current expression.
13090  MVLI.ProcessedVarList.push_back(RE);
13091 
13092  // Store the components in the stack so that they can be used to check
13093  // against other clauses later on.
13094  DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
13095  /*WhereFoundClauseKind=*/OMPC_map);
13096 
13097  // Save the components and declaration to create the clause. For purposes of
13098  // the clause creation, any component list that has has base 'this' uses
13099  // null as base declaration.
13100  MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
13101  MVLI.VarComponents.back().append(CurComponents.begin(),
13102  CurComponents.end());
13103  MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
13104  : CurDeclaration);
13105  }
13106 }
13107 
13108 OMPClause *
13110  ArrayRef<SourceLocation> MapTypeModifiersLoc,
13111  OpenMPMapClauseKind MapType, bool IsMapTypeImplicit,
13113  ArrayRef<Expr *> VarList, SourceLocation StartLoc,
13114  SourceLocation LParenLoc, SourceLocation EndLoc) {
13115  MappableVarListInfo MVLI(VarList);
13116  checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, StartLoc,
13117  MapType, IsMapTypeImplicit);
13118 
13122 
13123  // Process map-type-modifiers, flag errors for duplicate modifiers.
13124  unsigned Count = 0;
13125  for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
13126  if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
13127  llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) {
13128  Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
13129  continue;
13130  }
13131  assert(Count < OMPMapClause::NumberOfModifiers &&
13132  "Modifiers exceed the allowed number of map type modifiers");
13133  Modifiers[Count] = MapTypeModifiers[I];
13134  ModifiersLoc[Count] = MapTypeModifiersLoc[I];
13135  ++Count;
13136  }
13137 
13138  // We need to produce a map clause even if we don't have variables so that
13139  // other diagnostics related with non-existing map clauses are accurate.
13140  return OMPMapClause::Create(Context, StartLoc, LParenLoc, EndLoc,
13141  MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
13142  MVLI.VarComponents, Modifiers, ModifiersLoc,
13143  MapType, IsMapTypeImplicit, MapLoc);
13144 }
13145 
13148  assert(ParsedType.isUsable());
13149 
13150  QualType ReductionType = GetTypeFromParser(ParsedType.get());
13151  if (ReductionType.isNull())
13152  return QualType();
13153 
13154  // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
13155  // A type name in a declare reduction directive cannot be a function type, an
13156  // array type, a reference type, or a type qualified with const, volatile or
13157  // restrict.
13158  if (ReductionType.hasQualifiers()) {
13159  Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
13160  return QualType();
13161  }
13162 
13163  if (ReductionType->isFunctionType()) {
13164  Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
13165  return QualType();
13166  }
13167  if (ReductionType->isReferenceType()) {
13168  Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
13169  return QualType();
13170  }
13171  if (ReductionType->isArrayType()) {
13172  Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
13173  return QualType();
13174  }
13175  return ReductionType;
13176 }
13177 
13179  Scope *S, DeclContext *DC, DeclarationName Name,
13180  ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
13181  AccessSpecifier AS, Decl *PrevDeclInScope) {
13182  SmallVector<Decl *, 8> Decls;
13183  Decls.reserve(ReductionTypes.size());
13184 
13185  LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
13186  forRedeclarationInCurContext());
13187  // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
13188  // A reduction-identifier may not be re-declared in the current scope for the
13189  // same type or for a type that is compatible according to the base language
13190  // rules.
13191  llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
13192  OMPDeclareReductionDecl *PrevDRD = nullptr;
13193  bool InCompoundScope = true;
13194  if (S != nullptr) {
13195  // Find previous declaration with the same name not referenced in other
13196  // declarations.
13197  FunctionScopeInfo *ParentFn = getEnclosingFunction();
13198  InCompoundScope =
13199  (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
13200  LookupName(Lookup, S);
13201  FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
13202  /*AllowInlineNamespace=*/false);
13203  llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
13205  while (Filter.hasNext()) {
13206  auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
13207  if (InCompoundScope) {
13208  auto I = UsedAsPrevious.find(PrevDecl);
13209  if (I == UsedAsPrevious.end())
13210  UsedAsPrevious[PrevDecl] = false;
13211  if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
13212  UsedAsPrevious[D] = true;
13213  }
13214  PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
13215  PrevDecl->getLocation();
13216  }
13217  Filter.done();
13218  if (InCompoundScope) {
13219  for (const auto &PrevData : UsedAsPrevious) {
13220  if (!PrevData.second) {
13221  PrevDRD = PrevData.first;
13222  break;
13223  }
13224  }
13225  }
13226  } else if (PrevDeclInScope != nullptr) {
13227  auto *PrevDRDInScope = PrevDRD =
13228  cast<OMPDeclareReductionDecl>(PrevDeclInScope);
13229  do {
13230  PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
13231  PrevDRDInScope->getLocation();
13232  PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
13233  } while (PrevDRDInScope != nullptr);
13234  }
13235  for (const auto &TyData : ReductionTypes) {
13236  const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
13237  bool Invalid = false;
13238  if (I != PreviousRedeclTypes.end()) {
13239  Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
13240  << TyData.first;
13241  Diag(I->second, diag::note_previous_definition);
13242  Invalid = true;
13243  }
13244  PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
13245  auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
13246  Name, TyData.first, PrevDRD);
13247  DC->addDecl(DRD);
13248  DRD->setAccess(AS);
13249  Decls.push_back(DRD);
13250  if (Invalid)
13251  DRD->setInvalidDecl();
13252  else
13253  PrevDRD = DRD;
13254  }
13255 
13256  return DeclGroupPtrTy::make(
13257  DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
13258 }
13259 
13261  auto *DRD = cast<OMPDeclareReductionDecl>(D);
13262 
13263  // Enter new function scope.
13264  PushFunctionScope();
13265  setFunctionHasBranchProtectedScope();
13266  getCurFunction()->setHasOMPDeclareReductionCombiner();
13267 
13268  if (S != nullptr)
13269  PushDeclContext(S, DRD);
13270  else
13271  CurContext = DRD;
13272 
13273  PushExpressionEvaluationContext(
13274  ExpressionEvaluationContext::PotentiallyEvaluated);
13275 
13276  QualType ReductionType = DRD->getType();
13277  // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
13278  // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
13279  // uses semantics of argument handles by value, but it should be passed by
13280  // reference. C lang does not support references, so pass all parameters as
13281  // pointers.
13282  // Create 'T omp_in;' variable.
13283  VarDecl *OmpInParm =
13284  buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
13285  // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
13286  // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
13287  // uses semantics of argument handles by value, but it should be passed by
13288  // reference. C lang does not support references, so pass all parameters as
13289  // pointers.
13290  // Create 'T omp_out;' variable.
13291  VarDecl *OmpOutParm =
13292  buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
13293  if (S != nullptr) {
13294  PushOnScopeChains(OmpInParm, S);
13295  PushOnScopeChains(OmpOutParm, S);
13296  } else {
13297  DRD->addDecl(OmpInParm);
13298  DRD->addDecl(OmpOutParm);
13299  }
13300  Expr *InE =
13301  ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
13302  Expr *OutE =
13303  ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
13304  DRD->setCombinerData(InE, OutE);
13305 }
13306 
13308  auto *DRD = cast<OMPDeclareReductionDecl>(D);
13309  DiscardCleanupsInEvaluationContext();
13310  PopExpressionEvaluationContext();
13311 
13312  PopDeclContext();
13313  PopFunctionScopeInfo();
13314 
13315  if (Combiner != nullptr)
13316  DRD->setCombiner(Combiner);
13317  else
13318  DRD->setInvalidDecl();
13319 }
13320 
13322  auto *DRD = cast<OMPDeclareReductionDecl>(D);
13323 
13324  // Enter new function scope.
13325  PushFunctionScope();
13326  setFunctionHasBranchProtectedScope();
13327 
13328  if (S != nullptr)
13329  PushDeclContext(S, DRD);
13330  else
13331  CurContext = DRD;
13332 
13333  PushExpressionEvaluationContext(
13334  ExpressionEvaluationContext::PotentiallyEvaluated);
13335 
13336  QualType ReductionType = DRD->getType();
13337  // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
13338  // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
13339  // uses semantics of argument handles by value, but it should be passed by
13340  // reference. C lang does not support references, so pass all parameters as
13341  // pointers.
13342  // Create 'T omp_priv;' variable.
13343  VarDecl *OmpPrivParm =
13344  buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
13345  // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
13346  // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
13347  // uses semantics of argument handles by value, but it should be passed by
13348  // reference. C lang does not support references, so pass all parameters as
13349  // pointers.
13350  // Create 'T omp_orig;' variable.
13351  VarDecl *OmpOrigParm =
13352  buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
13353  if (S != nullptr) {
13354  PushOnScopeChains(OmpPrivParm, S);
13355  PushOnScopeChains(OmpOrigParm, S);
13356  } else {
13357  DRD->addDecl(OmpPrivParm);
13358  DRD->addDecl(OmpOrigParm);
13359  }
13360  Expr *OrigE =
13361  ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
13362  Expr *PrivE =
13363  ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
13364  DRD->setInitializerData(OrigE, PrivE);
13365  return OmpPrivParm;
13366 }
13367 
13369  VarDecl *OmpPrivParm) {
13370  auto *DRD = cast<OMPDeclareReductionDecl>(D);
13371  DiscardCleanupsInEvaluationContext();
13372  PopExpressionEvaluationContext();
13373 
13374  PopDeclContext();
13375  PopFunctionScopeInfo();
13376 
13377  if (Initializer != nullptr) {
13378  DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
13379  } else if (OmpPrivParm->hasInit()) {
13380  DRD->setInitializer(OmpPrivParm->getInit(),
13381  OmpPrivParm->isDirectInit()
13384  } else {
13385  DRD->setInvalidDecl();
13386  }
13387 }
13388 
13390  Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
13391  for (Decl *D : DeclReductions.get()) {
13392  if (IsValid) {
13393  if (S)
13394  PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
13395  /*AddToContext=*/false);
13396  } else {
13397  D->setInvalidDecl();
13398  }
13399  }
13400  return DeclReductions;
13401 }
13402 
13404  SourceLocation StartLoc,
13405  SourceLocation LParenLoc,
13406  SourceLocation EndLoc) {
13407  Expr *ValExpr = NumTeams;
13408  Stmt *HelperValStmt = nullptr;
13409 
13410  // OpenMP [teams Constrcut, Restrictions]
13411  // The num_teams expression must evaluate to a positive integer value.
13412  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
13413  /*StrictlyPositive=*/true))
13414  return nullptr;
13415 
13416  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
13417  OpenMPDirectiveKind CaptureRegion =
13418  getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams);
13419  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
13420  ValExpr = MakeFullExpr(ValExpr).get();
13421  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13422  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
13423  HelperValStmt = buildPreInits(Context, Captures);
13424  }
13425 
13426  return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
13427  StartLoc, LParenLoc, EndLoc);
13428 }
13429 
13431  SourceLocation StartLoc,
13432  SourceLocation LParenLoc,
13433  SourceLocation EndLoc) {
13434  Expr *ValExpr = ThreadLimit;
13435  Stmt *HelperValStmt = nullptr;
13436 
13437  // OpenMP [teams Constrcut, Restrictions]
13438  // The thread_limit expression must evaluate to a positive integer value.
13439  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
13440  /*StrictlyPositive=*/true))
13441  return nullptr;
13442 
13443  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
13444  OpenMPDirectiveKind CaptureRegion =
13445  getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit);
13446  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
13447  ValExpr = MakeFullExpr(ValExpr).get();
13448  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13449  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
13450  HelperValStmt = buildPreInits(Context, Captures);
13451  }
13452 
13453  return new (Context) OMPThreadLimitClause(
13454  ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
13455 }
13456 
13458  SourceLocation StartLoc,
13459  SourceLocation LParenLoc,
13460  SourceLocation EndLoc) {
13461  Expr *ValExpr = Priority;
13462 
13463  // OpenMP [2.9.1, task Constrcut]
13464  // The priority-value is a non-negative numerical scalar expression.
13465  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_priority,
13466  /*StrictlyPositive=*/false))
13467  return nullptr;
13468 
13469  return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc);
13470 }
13471 
13473  SourceLocation StartLoc,
13474  SourceLocation LParenLoc,
13475  SourceLocation EndLoc) {
13476  Expr *ValExpr = Grainsize;
13477 
13478  // OpenMP [2.9.2, taskloop Constrcut]
13479  // The parameter of the grainsize clause must be a positive integer
13480  // expression.
13481  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize,
13482  /*StrictlyPositive=*/true))
13483  return nullptr;
13484 
13485  return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc);
13486 }
13487 
13489  SourceLocation StartLoc,
13490  SourceLocation LParenLoc,
13491  SourceLocation EndLoc) {
13492  Expr *ValExpr = NumTasks;
13493 
13494  // OpenMP [2.9.2, taskloop Constrcut]
13495  // The parameter of the num_tasks clause must be a positive integer
13496  // expression.
13497  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks,
13498  /*StrictlyPositive=*/true))
13499  return nullptr;
13500 
13501  return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc);
13502 }
13503 
13505  SourceLocation LParenLoc,
13506  SourceLocation EndLoc) {
13507  // OpenMP [2.13.2, critical construct, Description]
13508  // ... where hint-expression is an integer constant expression that evaluates
13509  // to a valid lock hint.
13510  ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
13511  if (HintExpr.isInvalid())
13512  return nullptr;
13513  return new (Context)
13514  OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
13515 }
13516 
13518  OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
13519  SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
13520  SourceLocation EndLoc) {
13521  if (Kind == OMPC_DIST_SCHEDULE_unknown) {
13522  std::string Values;
13523  Values += "'";
13524  Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
13525  Values += "'";
13526  Diag(KindLoc, diag::err_omp_unexpected_clause_value)
13527  << Values << getOpenMPClauseName(OMPC_dist_schedule);
13528  return nullptr;
13529  }
13530  Expr *ValExpr = ChunkSize;
13531  Stmt *HelperValStmt = nullptr;
13532  if (ChunkSize) {
13533  if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
13534  !ChunkSize->isInstantiationDependent() &&
13535  !ChunkSize->containsUnexpandedParameterPack()) {
13536  SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
13537  ExprResult Val =
13538  PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
13539  if (Val.isInvalid())
13540  return nullptr;
13541 
13542  ValExpr = Val.get();
13543 
13544  // OpenMP [2.7.1, Restrictions]
13545  // chunk_size must be a loop invariant integer expression with a positive
13546  // value.
13547  llvm::APSInt Result;
13548  if (ValExpr->isIntegerConstantExpr(Result, Context)) {
13549  if (Result.isSigned() && !Result.isStrictlyPositive()) {
13550  Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
13551  << "dist_schedule" << ChunkSize->getSourceRange();
13552  return nullptr;
13553  }
13555  DSAStack->getCurrentDirective(), OMPC_dist_schedule) !=
13556  OMPD_unknown &&
13557  !CurContext->isDependentContext()) {
13558  ValExpr = MakeFullExpr(ValExpr).get();
13559  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13560  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
13561  HelperValStmt = buildPreInits(Context, Captures);
13562  }
13563  }
13564  }
13565 
13566  return new (Context)
13567  OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
13568  Kind, ValExpr, HelperValStmt);
13569 }
13570 
13573  SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
13574  SourceLocation KindLoc, SourceLocation EndLoc) {
13575  // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)'
13576  if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) {
13577  std::string Value;
13578  SourceLocation Loc;
13579  Value += "'";
13580  if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
13581  Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
13582  OMPC_DEFAULTMAP_MODIFIER_tofrom);
13583  Loc = MLoc;
13584  } else {
13585  Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
13586  OMPC_DEFAULTMAP_scalar);
13587  Loc = KindLoc;
13588  }
13589  Value += "'";
13590  Diag(Loc, diag::err_omp_unexpected_clause_value)
13591  << Value << getOpenMPClauseName(OMPC_defaultmap);
13592  return nullptr;
13593  }
13594  DSAStack->setDefaultDMAToFromScalar(StartLoc);
13595 
13596  return new (Context)
13597  OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
13598 }
13599 
13601  DeclContext *CurLexicalContext = getCurLexicalContext();
13602  if (!CurLexicalContext->isFileContext() &&
13603  !CurLexicalContext->isExternCContext() &&
13604  !CurLexicalContext->isExternCXXContext() &&
13605  !isa<CXXRecordDecl>(CurLexicalContext) &&
13606  !isa<ClassTemplateDecl>(CurLexicalContext) &&
13607  !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
13608  !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
13609  Diag(Loc, diag::err_omp_region_not_file_context);
13610  return false;
13611  }
13612  ++DeclareTargetNestingLevel;
13613  return true;
13614 }
13615 
13617  assert(DeclareTargetNestingLevel > 0 &&
13618  "Unexpected ActOnFinishOpenMPDeclareTargetDirective");
13619  --DeclareTargetNestingLevel;
13620 }
13621 
13623  CXXScopeSpec &ScopeSpec,
13624  const DeclarationNameInfo &Id,
13625  OMPDeclareTargetDeclAttr::MapTypeTy MT,
13626  NamedDeclSetType &SameDirectiveDecls) {
13627  LookupResult Lookup(*this, Id, LookupOrdinaryName);
13628  LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
13629 
13630  if (Lookup.isAmbiguous())
13631  return;
13632  Lookup.suppressDiagnostics();
13633 
13634  if (!Lookup.isSingleResult()) {
13635  if (TypoCorrection Corrected =
13636  CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr,
13637  llvm::make_unique<VarOrFuncDeclFilterCCC>(*this),
13638  CTK_ErrorRecovery)) {
13639  diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
13640  << Id.getName());
13641  checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
13642  return;
13643  }
13644 
13645  Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
13646  return;
13647  }
13648 
13649  NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
13650  if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
13651  isa<FunctionTemplateDecl>(ND)) {
13652  if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl())))
13653  Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName();
13655  OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
13656  cast<ValueDecl>(ND));
13657  if (!Res) {
13658  auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT);
13659  ND->addAttr(A);
13660  if (ASTMutationListener *ML = Context.getASTMutationListener())
13661  ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
13662  checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Id.getLoc());
13663  } else if (*Res != MT) {
13664  Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link)
13665  << Id.getName();
13666  }
13667  } else {
13668  Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
13669  }
13670 }
13671 
13673  Sema &SemaRef, Decl *D) {
13674  if (!D || !isa<VarDecl>(D))
13675  return;
13676  auto *VD = cast<VarDecl>(D);
13677  if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
13678  return;
13679  SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
13680  SemaRef.Diag(SL, diag::note_used_here) << SR;
13681 }
13682 
13684  Sema &SemaRef, DSAStackTy *Stack,
13685  ValueDecl *VD) {
13686  return VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
13687  checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
13688  /*FullCheck=*/false);
13689 }
13690 
13692  SourceLocation IdLoc) {
13693  if (!D || D->isInvalidDecl())
13694  return;
13695  SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
13696  SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
13697  if (auto *VD = dyn_cast<VarDecl>(D)) {
13698  // Only global variables can be marked as declare target.
13699  if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
13700  !VD->isStaticDataMember())
13701  return;
13702  // 2.10.6: threadprivate variable cannot appear in a declare target
13703  // directive.
13704  if (DSAStack->isThreadPrivate(VD)) {
13705  Diag(SL, diag::err_omp_threadprivate_in_target);
13706  reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false));
13707  return;
13708  }
13709  }
13710  if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
13711  D = FTD->getTemplatedDecl();
13712  if (const auto *FD = dyn_cast<FunctionDecl>(D)) {
13714  OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
13715  if (Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
13716  assert(IdLoc.isValid() && "Source location is expected");
13717  Diag(IdLoc, diag::err_omp_function_in_link_clause);
13718  Diag(FD->getLocation(), diag::note_defined_here) << FD;
13719  return;
13720  }
13721  }
13722  if (auto *VD = dyn_cast<ValueDecl>(D)) {
13723  // Problem if any with var declared with incomplete type will be reported
13724  // as normal, so no need to check it here.
13725  if ((E || !VD->getType()->isIncompleteType()) &&
13726  !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD))
13727  return;
13728  if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) {
13729  // Checking declaration inside declare target region.
13730  if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
13731  isa<FunctionTemplateDecl>(D)) {
13732  auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
13733  Context, OMPDeclareTargetDeclAttr::MT_To);
13734  D->addAttr(A);
13735  if (ASTMutationListener *ML = Context.getASTMutationListener())
13736  ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
13737  }
13738  return;
13739  }
13740  }
13741  if (!E)
13742  return;
13743  checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
13744 }
13745 
13747  SourceLocation StartLoc,
13748  SourceLocation LParenLoc,
13749  SourceLocation EndLoc) {
13750  MappableVarListInfo MVLI(VarList);
13751  checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, StartLoc);
13752  if (MVLI.ProcessedVarList.empty())
13753  return nullptr;
13754 
13755  return OMPToClause::Create(Context, StartLoc, LParenLoc, EndLoc,
13756  MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
13757  MVLI.VarComponents);
13758 }
13759 
13761  SourceLocation StartLoc,
13762  SourceLocation LParenLoc,
13763  SourceLocation EndLoc) {
13764  MappableVarListInfo MVLI(VarList);
13765  checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, StartLoc);
13766  if (MVLI.ProcessedVarList.empty())
13767  return nullptr;
13768 
13769  return OMPFromClause::Create(Context, StartLoc, LParenLoc, EndLoc,
13770  MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
13771  MVLI.VarComponents);
13772 }
13773 
13775  SourceLocation StartLoc,
13776  SourceLocation LParenLoc,
13777  SourceLocation EndLoc) {
13778  MappableVarListInfo MVLI(VarList);
13779  SmallVector<Expr *, 8> PrivateCopies;
13781 
13782  for (Expr *RefExpr : VarList) {
13783  assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
13784  SourceLocation ELoc;
13785  SourceRange ERange;
13786  Expr *SimpleRefExpr = RefExpr;
13787  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
13788  if (Res.second) {
13789  // It will be analyzed later.
13790  MVLI.ProcessedVarList.push_back(RefExpr);
13791  PrivateCopies.push_back(nullptr);
13792  Inits.push_back(nullptr);
13793  }
13794  ValueDecl *D = Res.first;
13795  if (!D)
13796  continue;
13797 
13798  QualType Type = D->getType();
13799  Type = Type.getNonReferenceType().getUnqualifiedType();
13800 
13801  auto *VD = dyn_cast<VarDecl>(D);
13802 
13803  // Item should be a pointer or reference to pointer.
13804  if (!Type->isPointerType()) {
13805  Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
13806  << 0 << RefExpr->getSourceRange();
13807  continue;
13808  }
13809 
13810  // Build the private variable and the expression that refers to it.
13811  auto VDPrivate =
13812  buildVarDecl(*this, ELoc, Type, D->getName(),
13813  D->hasAttrs() ? &D->getAttrs() : nullptr,
13814  VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
13815  if (VDPrivate->isInvalidDecl())
13816  continue;
13817 
13818  CurContext->addDecl(VDPrivate);
13819  DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
13820  *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
13821 
13822  // Add temporary variable to initialize the private copy of the pointer.
13823  VarDecl *VDInit =
13824  buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
13825  DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
13826  *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
13827  AddInitializerToDecl(VDPrivate,
13828  DefaultLvalueConversion(VDInitRefExpr).get(),
13829  /*DirectInit=*/false);
13830 
13831  // If required, build a capture to implement the privatization initialized
13832  // with the current list item value.
13833  DeclRefExpr *Ref = nullptr;
13834  if (!VD)
13835  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
13836  MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
13837  PrivateCopies.push_back(VDPrivateRefExpr);
13838  Inits.push_back(VDInitRefExpr);
13839 
13840  // We need to add a data sharing attribute for this variable to make sure it
13841  // is correctly captured. A variable that shows up in a use_device_ptr has
13842  // similar properties of a first private variable.
13843  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
13844 
13845  // Create a mappable component for the list item. List items in this clause
13846  // only need a component.
13847  MVLI.VarBaseDeclarations.push_back(D);
13848  MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
13849  MVLI.VarComponents.back().push_back(
13851  }
13852 
13853  if (MVLI.ProcessedVarList.empty())
13854  return nullptr;
13855 
13857  Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList,
13858  PrivateCopies, Inits, MVLI.VarBaseDeclarations, MVLI.VarComponents);
13859 }
13860 
13862  SourceLocation StartLoc,
13863  SourceLocation LParenLoc,
13864  SourceLocation EndLoc) {
13865  MappableVarListInfo MVLI(VarList);
13866  for (Expr *RefExpr : VarList) {
13867  assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
13868  SourceLocation ELoc;
13869  SourceRange ERange;
13870  Expr *SimpleRefExpr = RefExpr;
13871  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
13872  if (Res.second) {
13873  // It will be analyzed later.
13874  MVLI.ProcessedVarList.push_back(RefExpr);
13875  }
13876  ValueDecl *D = Res.first;
13877  if (!D)
13878  continue;
13879 
13880  QualType Type = D->getType();
13881  // item should be a pointer or array or reference to pointer or array
13882  if (!Type.getNonReferenceType()->isPointerType() &&
13883  !Type.getNonReferenceType()->isArrayType()) {
13884  Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
13885  << 0 << RefExpr->getSourceRange();
13886  continue;
13887  }
13888 
13889  // Check if the declaration in the clause does not show up in any data
13890  // sharing attribute.
13891  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
13892  if (isOpenMPPrivate(DVar.CKind)) {
13893  Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
13894  << getOpenMPClauseName(DVar.CKind)
13895  << getOpenMPClauseName(OMPC_is_device_ptr)
13896  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
13897  reportOriginalDsa(*this, DSAStack, D, DVar);
13898  continue;
13899  }
13900 
13901  const Expr *ConflictExpr;
13902  if (DSAStack->checkMappableExprComponentListsForDecl(
13903  D, /*CurrentRegionOnly=*/true,
13904  [&ConflictExpr](
13906  OpenMPClauseKind) -> bool {
13907  ConflictExpr = R.front().getAssociatedExpression();
13908  return true;
13909  })) {
13910  Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
13911  Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
13912  << ConflictExpr->getSourceRange();
13913  continue;
13914  }
13915 
13916  // Store the components in the stack so that they can be used to check
13917  // against other clauses later on.
13919  DSAStack->addMappableExpressionComponents(
13920  D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
13921 
13922  // Record the expression we've just processed.
13923  MVLI.ProcessedVarList.push_back(SimpleRefExpr);
13924 
13925  // Create a mappable component for the list item. List items in this clause
13926  // only need a component. We use a null declaration to signal fields in
13927  // 'this'.
13928  assert((isa<DeclRefExpr>(SimpleRefExpr) ||
13929  isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
13930  "Unexpected device pointer expression!");
13931  MVLI.VarBaseDeclarations.push_back(
13932  isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
13933  MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
13934  MVLI.VarComponents.back().push_back(MC);
13935  }
13936 
13937  if (MVLI.ProcessedVarList.empty())
13938  return nullptr;
13939 
13941  Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList,
13942  MVLI.VarBaseDeclarations, MVLI.VarComponents);
13943 }
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:2773
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:3421
SourceLocation getExprLoc() const
Definition: Expr.h:3318
ExprResult ActOnConditionalOp(SourceLocation QuestionLoc, SourceLocation ColonLoc, Expr *CondExpr, Expr *LHSExpr, Expr *RHSExpr)
ActOnConditionalOp - Parse a ?: operation.
Definition: SemaExpr.cpp:7454
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:2767
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:3322
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
ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue)
Definition: Sema.h:5349
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:3162
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:2885
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:1655
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:3287
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:3093
OMPClause * ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc, SourceLocation EndLoc)
std::pair< StringRef, QualType > CapturedParamNameType
Definition: Sema.h:3836
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:2998
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:3582
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:12242
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:10729
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:1599
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.
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:8858
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:3319
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:3327
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:4332
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:8830
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:10740
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:12854
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:2682
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:3329
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:12738
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