clang  10.0.0git
SemaOpenMP.cpp
Go to the documentation of this file.
1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// This file implements semantic analysis for OpenMP directives and
10 /// clauses.
11 ///
12 //===----------------------------------------------------------------------===//
13 
14 #include "TreeTransform.h"
15 #include "clang/AST/ASTContext.h"
18 #include "clang/AST/Decl.h"
19 #include "clang/AST/DeclCXX.h"
20 #include "clang/AST/DeclOpenMP.h"
21 #include "clang/AST/StmtCXX.h"
22 #include "clang/AST/StmtOpenMP.h"
23 #include "clang/AST/StmtVisitor.h"
24 #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/IndexedMap.h"
33 #include "llvm/ADT/PointerEmbeddedInt.h"
34 #include "llvm/Frontend/OpenMP/OMPConstants.h"
35 using namespace clang;
36 using namespace llvm::omp;
37 
38 //===----------------------------------------------------------------------===//
39 // Stack of data-sharing attributes for variables
40 //===----------------------------------------------------------------------===//
41 
43  Sema &SemaRef, Expr *E,
45  OpenMPClauseKind CKind, bool NoDiagnose);
46 
47 namespace {
48 /// Default data sharing attributes, which can be applied to directive.
50  DSA_unspecified = 0, /// Data sharing attribute not specified.
51  DSA_none = 1 << 0, /// Default data sharing attribute 'none'.
52  DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'.
53 };
54 
55 /// Stack for tracking declarations used in OpenMP directives and
56 /// clauses and their data-sharing attributes.
57 class DSAStackTy {
58 public:
59  struct DSAVarData {
60  OpenMPDirectiveKind DKind = OMPD_unknown;
62  const Expr *RefExpr = nullptr;
63  DeclRefExpr *PrivateCopy = nullptr;
64  SourceLocation ImplicitDSALoc;
65  DSAVarData() = default;
66  DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
67  const Expr *RefExpr, DeclRefExpr *PrivateCopy,
68  SourceLocation ImplicitDSALoc)
69  : DKind(DKind), CKind(CKind), RefExpr(RefExpr),
70  PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {}
71  };
72  using OperatorOffsetTy =
74  using DoacrossDependMapTy =
75  llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
76 
77 private:
78  struct DSAInfo {
79  OpenMPClauseKind Attributes = OMPC_unknown;
80  /// Pointer to a reference expression and a flag which shows that the
81  /// variable is marked as lastprivate(true) or not (false).
82  llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
83  DeclRefExpr *PrivateCopy = nullptr;
84  };
85  using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
86  using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
87  using LCDeclInfo = std::pair<unsigned, VarDecl *>;
88  using LoopControlVariablesMapTy =
89  llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
90  /// Struct that associates a component with the clause kind where they are
91  /// found.
92  struct MappedExprComponentTy {
95  };
96  using MappedExprComponentsTy =
97  llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
98  using CriticalsWithHintsTy =
99  llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
100  struct ReductionData {
101  using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
102  SourceRange ReductionRange;
103  llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
104  ReductionData() = default;
105  void set(BinaryOperatorKind BO, SourceRange RR) {
106  ReductionRange = RR;
107  ReductionOp = BO;
108  }
109  void set(const Expr *RefExpr, SourceRange RR) {
110  ReductionRange = RR;
111  ReductionOp = RefExpr;
112  }
113  };
114  using DeclReductionMapTy =
115  llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
116  struct DefaultmapInfo {
117  OpenMPDefaultmapClauseModifier ImplicitBehavior =
119  SourceLocation SLoc;
120  DefaultmapInfo() = default;
121  DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc)
122  : ImplicitBehavior(M), SLoc(Loc) {}
123  };
124 
125  struct SharingMapTy {
126  DeclSAMapTy SharingMap;
127  DeclReductionMapTy ReductionMap;
128  UsedRefMapTy AlignedMap;
129  UsedRefMapTy NontemporalMap;
130  MappedExprComponentsTy MappedExprComponents;
131  LoopControlVariablesMapTy LCVMap;
132  DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
133  SourceLocation DefaultAttrLoc;
134  DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown];
135  OpenMPDirectiveKind Directive = OMPD_unknown;
136  DeclarationNameInfo DirectiveName;
137  Scope *CurScope = nullptr;
138  SourceLocation ConstructLoc;
139  /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
140  /// get the data (loop counters etc.) about enclosing loop-based construct.
141  /// This data is required during codegen.
142  DoacrossDependMapTy DoacrossDepends;
143  /// First argument (Expr *) contains optional argument of the
144  /// 'ordered' clause, the second one is true if the regions has 'ordered'
145  /// clause, false otherwise.
147  unsigned AssociatedLoops = 1;
148  bool HasMutipleLoops = false;
149  const Decl *PossiblyLoopCounter = nullptr;
150  bool NowaitRegion = false;
151  bool CancelRegion = false;
152  bool LoopStart = false;
153  bool BodyComplete = false;
154  SourceLocation InnerTeamsRegionLoc;
155  /// Reference to the taskgroup task_reduction reference expression.
156  Expr *TaskgroupReductionRef = nullptr;
157  llvm::DenseSet<QualType> MappedClassesQualTypes;
158  /// List of globals marked as declare target link in this target region
159  /// (isOpenMPTargetExecutionDirective(Directive) == true).
160  llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls;
161  SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
162  Scope *CurScope, SourceLocation Loc)
163  : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
164  ConstructLoc(Loc) {}
165  SharingMapTy() = default;
166  };
167 
168  using StackTy = SmallVector<SharingMapTy, 4>;
169 
170  /// Stack of used declaration and their data-sharing attributes.
171  DeclSAMapTy Threadprivates;
172  const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
174  /// true, if check for DSA must be from parent directive, false, if
175  /// from current directive.
176  OpenMPClauseKind ClauseKindMode = OMPC_unknown;
177  Sema &SemaRef;
178  bool ForceCapturing = false;
179  /// true if all the variables in the target executable directives must be
180  /// captured by reference.
181  bool ForceCaptureByReferenceInTargetExecutable = false;
182  CriticalsWithHintsTy Criticals;
183  unsigned IgnoredStackElements = 0;
184 
185  /// Iterators over the stack iterate in order from innermost to outermost
186  /// directive.
187  using const_iterator = StackTy::const_reverse_iterator;
188  const_iterator begin() const {
189  return Stack.empty() ? const_iterator()
190  : Stack.back().first.rbegin() + IgnoredStackElements;
191  }
192  const_iterator end() const {
193  return Stack.empty() ? const_iterator() : Stack.back().first.rend();
194  }
195  using iterator = StackTy::reverse_iterator;
196  iterator begin() {
197  return Stack.empty() ? iterator()
198  : Stack.back().first.rbegin() + IgnoredStackElements;
199  }
200  iterator end() {
201  return Stack.empty() ? iterator() : Stack.back().first.rend();
202  }
203 
204  // Convenience operations to get at the elements of the stack.
205 
206  bool isStackEmpty() const {
207  return Stack.empty() ||
208  Stack.back().second != CurrentNonCapturingFunctionScope ||
209  Stack.back().first.size() <= IgnoredStackElements;
210  }
211  size_t getStackSize() const {
212  return isStackEmpty() ? 0
213  : Stack.back().first.size() - IgnoredStackElements;
214  }
215 
216  SharingMapTy *getTopOfStackOrNull() {
217  size_t Size = getStackSize();
218  if (Size == 0)
219  return nullptr;
220  return &Stack.back().first[Size - 1];
221  }
222  const SharingMapTy *getTopOfStackOrNull() const {
223  return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull();
224  }
225  SharingMapTy &getTopOfStack() {
226  assert(!isStackEmpty() && "no current directive");
227  return *getTopOfStackOrNull();
228  }
229  const SharingMapTy &getTopOfStack() const {
230  return const_cast<DSAStackTy&>(*this).getTopOfStack();
231  }
232 
233  SharingMapTy *getSecondOnStackOrNull() {
234  size_t Size = getStackSize();
235  if (Size <= 1)
236  return nullptr;
237  return &Stack.back().first[Size - 2];
238  }
239  const SharingMapTy *getSecondOnStackOrNull() const {
240  return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull();
241  }
242 
243  /// Get the stack element at a certain level (previously returned by
244  /// \c getNestingLevel).
245  ///
246  /// Note that nesting levels count from outermost to innermost, and this is
247  /// the reverse of our iteration order where new inner levels are pushed at
248  /// the front of the stack.
249  SharingMapTy &getStackElemAtLevel(unsigned Level) {
250  assert(Level < getStackSize() && "no such stack element");
251  return Stack.back().first[Level];
252  }
253  const SharingMapTy &getStackElemAtLevel(unsigned Level) const {
254  return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level);
255  }
256 
257  DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const;
258 
259  /// Checks if the variable is a local for OpenMP region.
260  bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const;
261 
262  /// Vector of previously declared requires directives
264  /// omp_allocator_handle_t type.
265  QualType OMPAllocatorHandleT;
266  /// Expression for the predefined allocators.
267  Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
268  nullptr};
269  /// Vector of previously encountered target directives
270  SmallVector<SourceLocation, 2> TargetLocations;
271 
272 public:
273  explicit DSAStackTy(Sema &S) : SemaRef(S) {}
274 
275  /// Sets omp_allocator_handle_t type.
276  void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; }
277  /// Gets omp_allocator_handle_t type.
278  QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; }
279  /// Sets the given default allocator.
280  void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
281  Expr *Allocator) {
282  OMPPredefinedAllocators[AllocatorKind] = Allocator;
283  }
284  /// Returns the specified default allocator.
285  Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const {
286  return OMPPredefinedAllocators[AllocatorKind];
287  }
288 
289  bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
290  OpenMPClauseKind getClauseParsingMode() const {
291  assert(isClauseParsingMode() && "Must be in clause parsing mode.");
292  return ClauseKindMode;
293  }
294  void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
295 
296  bool isBodyComplete() const {
297  const SharingMapTy *Top = getTopOfStackOrNull();
298  return Top && Top->BodyComplete;
299  }
300  void setBodyComplete() {
301  getTopOfStack().BodyComplete = true;
302  }
303 
304  bool isForceVarCapturing() const { return ForceCapturing; }
305  void setForceVarCapturing(bool V) { ForceCapturing = V; }
306 
307  void setForceCaptureByReferenceInTargetExecutable(bool V) {
308  ForceCaptureByReferenceInTargetExecutable = V;
309  }
310  bool isForceCaptureByReferenceInTargetExecutable() const {
311  return ForceCaptureByReferenceInTargetExecutable;
312  }
313 
314  void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
315  Scope *CurScope, SourceLocation Loc) {
316  assert(!IgnoredStackElements &&
317  "cannot change stack while ignoring elements");
318  if (Stack.empty() ||
319  Stack.back().second != CurrentNonCapturingFunctionScope)
320  Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
321  Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
322  Stack.back().first.back().DefaultAttrLoc = Loc;
323  }
324 
325  void pop() {
326  assert(!IgnoredStackElements &&
327  "cannot change stack while ignoring elements");
328  assert(!Stack.back().first.empty() &&
329  "Data-sharing attributes stack is empty!");
330  Stack.back().first.pop_back();
331  }
332 
333  /// RAII object to temporarily leave the scope of a directive when we want to
334  /// logically operate in its parent.
335  class ParentDirectiveScope {
336  DSAStackTy &Self;
337  bool Active;
338  public:
339  ParentDirectiveScope(DSAStackTy &Self, bool Activate)
340  : Self(Self), Active(false) {
341  if (Activate)
342  enable();
343  }
344  ~ParentDirectiveScope() { disable(); }
345  void disable() {
346  if (Active) {
347  --Self.IgnoredStackElements;
348  Active = false;
349  }
350  }
351  void enable() {
352  if (!Active) {
353  ++Self.IgnoredStackElements;
354  Active = true;
355  }
356  }
357  };
358 
359  /// Marks that we're started loop parsing.
360  void loopInit() {
361  assert(isOpenMPLoopDirective(getCurrentDirective()) &&
362  "Expected loop-based directive.");
363  getTopOfStack().LoopStart = true;
364  }
365  /// Start capturing of the variables in the loop context.
366  void loopStart() {
367  assert(isOpenMPLoopDirective(getCurrentDirective()) &&
368  "Expected loop-based directive.");
369  getTopOfStack().LoopStart = false;
370  }
371  /// true, if variables are captured, false otherwise.
372  bool isLoopStarted() const {
373  assert(isOpenMPLoopDirective(getCurrentDirective()) &&
374  "Expected loop-based directive.");
375  return !getTopOfStack().LoopStart;
376  }
377  /// Marks (or clears) declaration as possibly loop counter.
378  void resetPossibleLoopCounter(const Decl *D = nullptr) {
379  getTopOfStack().PossiblyLoopCounter =
380  D ? D->getCanonicalDecl() : D;
381  }
382  /// Gets the possible loop counter decl.
383  const Decl *getPossiblyLoopCunter() const {
384  return getTopOfStack().PossiblyLoopCounter;
385  }
386  /// Start new OpenMP region stack in new non-capturing function.
387  void pushFunction() {
388  assert(!IgnoredStackElements &&
389  "cannot change stack while ignoring elements");
390  const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
391  assert(!isa<CapturingScopeInfo>(CurFnScope));
392  CurrentNonCapturingFunctionScope = CurFnScope;
393  }
394  /// Pop region stack for non-capturing function.
395  void popFunction(const FunctionScopeInfo *OldFSI) {
396  assert(!IgnoredStackElements &&
397  "cannot change stack while ignoring elements");
398  if (!Stack.empty() && Stack.back().second == OldFSI) {
399  assert(Stack.back().first.empty());
400  Stack.pop_back();
401  }
402  CurrentNonCapturingFunctionScope = nullptr;
403  for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
404  if (!isa<CapturingScopeInfo>(FSI)) {
405  CurrentNonCapturingFunctionScope = FSI;
406  break;
407  }
408  }
409  }
410 
411  void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) {
412  Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
413  }
414  const std::pair<const OMPCriticalDirective *, llvm::APSInt>
415  getCriticalWithHint(const DeclarationNameInfo &Name) const {
416  auto I = Criticals.find(Name.getAsString());
417  if (I != Criticals.end())
418  return I->second;
419  return std::make_pair(nullptr, llvm::APSInt());
420  }
421  /// If 'aligned' declaration for given variable \a D was not seen yet,
422  /// add it and return NULL; otherwise return previous occurrence's expression
423  /// for diagnostics.
424  const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE);
425  /// If 'nontemporal' declaration for given variable \a D was not seen yet,
426  /// add it and return NULL; otherwise return previous occurrence's expression
427  /// for diagnostics.
428  const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE);
429 
430  /// Register specified variable as loop control variable.
431  void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture);
432  /// Check if the specified variable is a loop control variable for
433  /// current region.
434  /// \return The index of the loop control variable in the list of associated
435  /// for-loops (from outer to inner).
436  const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const;
437  /// Check if the specified variable is a loop control variable for
438  /// parent region.
439  /// \return The index of the loop control variable in the list of associated
440  /// for-loops (from outer to inner).
441  const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const;
442  /// Get the loop control variable for the I-th loop (or nullptr) in
443  /// parent directive.
444  const ValueDecl *getParentLoopControlVariable(unsigned I) const;
445 
446  /// Adds explicit data sharing attribute to the specified declaration.
447  void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
448  DeclRefExpr *PrivateCopy = nullptr);
449 
450  /// Adds additional information for the reduction items with the reduction id
451  /// represented as an operator.
452  void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
453  BinaryOperatorKind BOK);
454  /// Adds additional information for the reduction items with the reduction id
455  /// represented as reduction identifier.
456  void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
457  const Expr *ReductionRef);
458  /// Returns the location and reduction operation from the innermost parent
459  /// region for the given \p D.
460  const DSAVarData
461  getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
462  BinaryOperatorKind &BOK,
463  Expr *&TaskgroupDescriptor) const;
464  /// Returns the location and reduction operation from the innermost parent
465  /// region for the given \p D.
466  const DSAVarData
467  getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
468  const Expr *&ReductionRef,
469  Expr *&TaskgroupDescriptor) const;
470  /// Return reduction reference expression for the current taskgroup.
471  Expr *getTaskgroupReductionRef() const {
472  assert(getTopOfStack().Directive == OMPD_taskgroup &&
473  "taskgroup reference expression requested for non taskgroup "
474  "directive.");
475  return getTopOfStack().TaskgroupReductionRef;
476  }
477  /// Checks if the given \p VD declaration is actually a taskgroup reduction
478  /// descriptor variable at the \p Level of OpenMP regions.
479  bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
480  return getStackElemAtLevel(Level).TaskgroupReductionRef &&
481  cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
482  ->getDecl() == VD;
483  }
484 
485  /// Returns data sharing attributes from top of the stack for the
486  /// specified declaration.
487  const DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
488  /// Returns data-sharing attributes for the specified declaration.
489  const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const;
490  /// Checks if the specified variables has data-sharing attributes which
491  /// match specified \a CPred predicate in any directive which matches \a DPred
492  /// predicate.
493  const DSAVarData
494  hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
495  const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
496  bool FromParent) const;
497  /// Checks if the specified variables has data-sharing attributes which
498  /// match specified \a CPred predicate in any innermost directive which
499  /// matches \a DPred predicate.
500  const DSAVarData
501  hasInnermostDSA(ValueDecl *D,
502  const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
503  const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
504  bool FromParent) const;
505  /// Checks if the specified variables has explicit data-sharing
506  /// attributes which match specified \a CPred predicate at the specified
507  /// OpenMP region.
508  bool hasExplicitDSA(const ValueDecl *D,
509  const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
510  unsigned Level, bool NotLastprivate = false) const;
511 
512  /// Returns true if the directive at level \Level matches in the
513  /// specified \a DPred predicate.
514  bool hasExplicitDirective(
515  const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
516  unsigned Level) const;
517 
518  /// Finds a directive which matches specified \a DPred predicate.
519  bool hasDirective(
520  const llvm::function_ref<bool(
522  DPred,
523  bool FromParent) const;
524 
525  /// Returns currently analyzed directive.
526  OpenMPDirectiveKind getCurrentDirective() const {
527  const SharingMapTy *Top = getTopOfStackOrNull();
528  return Top ? Top->Directive : OMPD_unknown;
529  }
530  /// Returns directive kind at specified level.
531  OpenMPDirectiveKind getDirective(unsigned Level) const {
532  assert(!isStackEmpty() && "No directive at specified level.");
533  return getStackElemAtLevel(Level).Directive;
534  }
535  /// Returns the capture region at the specified level.
536  OpenMPDirectiveKind getCaptureRegion(unsigned Level,
537  unsigned OpenMPCaptureLevel) const {
539  getOpenMPCaptureRegions(CaptureRegions, getDirective(Level));
540  return CaptureRegions[OpenMPCaptureLevel];
541  }
542  /// Returns parent directive.
543  OpenMPDirectiveKind getParentDirective() const {
544  const SharingMapTy *Parent = getSecondOnStackOrNull();
545  return Parent ? Parent->Directive : OMPD_unknown;
546  }
547 
548  /// Add requires decl to internal vector
549  void addRequiresDecl(OMPRequiresDecl *RD) {
550  RequiresDecls.push_back(RD);
551  }
552 
553  /// Checks if the defined 'requires' directive has specified type of clause.
554  template <typename ClauseType>
555  bool hasRequiresDeclWithClause() {
556  return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
557  return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
558  return isa<ClauseType>(C);
559  });
560  });
561  }
562 
563  /// Checks for a duplicate clause amongst previously declared requires
564  /// directives
565  bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const {
566  bool IsDuplicate = false;
567  for (OMPClause *CNew : ClauseList) {
568  for (const OMPRequiresDecl *D : RequiresDecls) {
569  for (const OMPClause *CPrev : D->clauselists()) {
570  if (CNew->getClauseKind() == CPrev->getClauseKind()) {
571  SemaRef.Diag(CNew->getBeginLoc(),
572  diag::err_omp_requires_clause_redeclaration)
573  << getOpenMPClauseName(CNew->getClauseKind());
574  SemaRef.Diag(CPrev->getBeginLoc(),
575  diag::note_omp_requires_previous_clause)
576  << getOpenMPClauseName(CPrev->getClauseKind());
577  IsDuplicate = true;
578  }
579  }
580  }
581  }
582  return IsDuplicate;
583  }
584 
585  /// Add location of previously encountered target to internal vector
586  void addTargetDirLocation(SourceLocation LocStart) {
587  TargetLocations.push_back(LocStart);
588  }
589 
590  // Return previously encountered target region locations.
591  ArrayRef<SourceLocation> getEncounteredTargetLocs() const {
592  return TargetLocations;
593  }
594 
595  /// Set default data sharing attribute to none.
596  void setDefaultDSANone(SourceLocation Loc) {
597  getTopOfStack().DefaultAttr = DSA_none;
598  getTopOfStack().DefaultAttrLoc = Loc;
599  }
600  /// Set default data sharing attribute to shared.
601  void setDefaultDSAShared(SourceLocation Loc) {
602  getTopOfStack().DefaultAttr = DSA_shared;
603  getTopOfStack().DefaultAttrLoc = Loc;
604  }
605  /// Set default data mapping attribute to Modifier:Kind
606  void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,
608  SourceLocation Loc) {
609  DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind];
610  DMI.ImplicitBehavior = M;
611  DMI.SLoc = Loc;
612  }
613  /// Check whether the implicit-behavior has been set in defaultmap
614  bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) {
615  return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
617  }
618 
619  DefaultDataSharingAttributes getDefaultDSA() const {
620  return isStackEmpty() ? DSA_unspecified
621  : getTopOfStack().DefaultAttr;
622  }
623  SourceLocation getDefaultDSALocation() const {
624  return isStackEmpty() ? SourceLocation()
625  : getTopOfStack().DefaultAttrLoc;
626  }
628  getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const {
629  return isStackEmpty()
631  : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior;
632  }
634  getDefaultmapModifierAtLevel(unsigned Level,
635  OpenMPDefaultmapClauseKind Kind) const {
636  return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior;
637  }
638  bool isDefaultmapCapturedByRef(unsigned Level,
639  OpenMPDefaultmapClauseKind Kind) const {
641  getDefaultmapModifierAtLevel(Level, Kind);
642  if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) {
643  return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
644  (M == OMPC_DEFAULTMAP_MODIFIER_to) ||
645  (M == OMPC_DEFAULTMAP_MODIFIER_from) ||
646  (M == OMPC_DEFAULTMAP_MODIFIER_tofrom);
647  }
648  return true;
649  }
650  static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M,
652  switch (Kind) {
653  case OMPC_DEFAULTMAP_scalar:
654  case OMPC_DEFAULTMAP_pointer:
655  return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) ||
656  (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) ||
657  (M == OMPC_DEFAULTMAP_MODIFIER_default);
658  case OMPC_DEFAULTMAP_aggregate:
659  return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
660  default:
661  break;
662  }
663  llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum");
664  }
665  bool mustBeFirstprivateAtLevel(unsigned Level,
666  OpenMPDefaultmapClauseKind Kind) const {
668  getDefaultmapModifierAtLevel(Level, Kind);
669  return mustBeFirstprivateBase(M, Kind);
670  }
671  bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const {
672  OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind);
673  return mustBeFirstprivateBase(M, Kind);
674  }
675 
676  /// Checks if the specified variable is a threadprivate.
677  bool isThreadPrivate(VarDecl *D) {
678  const DSAVarData DVar = getTopDSA(D, false);
679  return isOpenMPThreadPrivate(DVar.CKind);
680  }
681 
682  /// Marks current region as ordered (it has an 'ordered' clause).
683  void setOrderedRegion(bool IsOrdered, const Expr *Param,
684  OMPOrderedClause *Clause) {
685  if (IsOrdered)
686  getTopOfStack().OrderedRegion.emplace(Param, Clause);
687  else
688  getTopOfStack().OrderedRegion.reset();
689  }
690  /// Returns true, if region is ordered (has associated 'ordered' clause),
691  /// false - otherwise.
692  bool isOrderedRegion() const {
693  if (const SharingMapTy *Top = getTopOfStackOrNull())
694  return Top->OrderedRegion.hasValue();
695  return false;
696  }
697  /// Returns optional parameter for the ordered region.
698  std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
699  if (const SharingMapTy *Top = getTopOfStackOrNull())
700  if (Top->OrderedRegion.hasValue())
701  return Top->OrderedRegion.getValue();
702  return std::make_pair(nullptr, nullptr);
703  }
704  /// Returns true, if parent region is ordered (has associated
705  /// 'ordered' clause), false - otherwise.
706  bool isParentOrderedRegion() const {
707  if (const SharingMapTy *Parent = getSecondOnStackOrNull())
708  return Parent->OrderedRegion.hasValue();
709  return false;
710  }
711  /// Returns optional parameter for the ordered region.
712  std::pair<const Expr *, OMPOrderedClause *>
713  getParentOrderedRegionParam() const {
714  if (const SharingMapTy *Parent = getSecondOnStackOrNull())
715  if (Parent->OrderedRegion.hasValue())
716  return Parent->OrderedRegion.getValue();
717  return std::make_pair(nullptr, nullptr);
718  }
719  /// Marks current region as nowait (it has a 'nowait' clause).
720  void setNowaitRegion(bool IsNowait = true) {
721  getTopOfStack().NowaitRegion = IsNowait;
722  }
723  /// Returns true, if parent region is nowait (has associated
724  /// 'nowait' clause), false - otherwise.
725  bool isParentNowaitRegion() const {
726  if (const SharingMapTy *Parent = getSecondOnStackOrNull())
727  return Parent->NowaitRegion;
728  return false;
729  }
730  /// Marks parent region as cancel region.
731  void setParentCancelRegion(bool Cancel = true) {
732  if (SharingMapTy *Parent = getSecondOnStackOrNull())
733  Parent->CancelRegion |= Cancel;
734  }
735  /// Return true if current region has inner cancel construct.
736  bool isCancelRegion() const {
737  const SharingMapTy *Top = getTopOfStackOrNull();
738  return Top ? Top->CancelRegion : false;
739  }
740 
741  /// Set collapse value for the region.
742  void setAssociatedLoops(unsigned Val) {
743  getTopOfStack().AssociatedLoops = Val;
744  if (Val > 1)
745  getTopOfStack().HasMutipleLoops = true;
746  }
747  /// Return collapse value for region.
748  unsigned getAssociatedLoops() const {
749  const SharingMapTy *Top = getTopOfStackOrNull();
750  return Top ? Top->AssociatedLoops : 0;
751  }
752  /// Returns true if the construct is associated with multiple loops.
753  bool hasMutipleLoops() const {
754  const SharingMapTy *Top = getTopOfStackOrNull();
755  return Top ? Top->HasMutipleLoops : false;
756  }
757 
758  /// Marks current target region as one with closely nested teams
759  /// region.
760  void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
761  if (SharingMapTy *Parent = getSecondOnStackOrNull())
762  Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
763  }
764  /// Returns true, if current region has closely nested teams region.
765  bool hasInnerTeamsRegion() const {
766  return getInnerTeamsRegionLoc().isValid();
767  }
768  /// Returns location of the nested teams region (if any).
769  SourceLocation getInnerTeamsRegionLoc() const {
770  const SharingMapTy *Top = getTopOfStackOrNull();
771  return Top ? Top->InnerTeamsRegionLoc : SourceLocation();
772  }
773 
774  Scope *getCurScope() const {
775  const SharingMapTy *Top = getTopOfStackOrNull();
776  return Top ? Top->CurScope : nullptr;
777  }
778  SourceLocation getConstructLoc() const {
779  const SharingMapTy *Top = getTopOfStackOrNull();
780  return Top ? Top->ConstructLoc : SourceLocation();
781  }
782 
783  /// Do the check specified in \a Check to all component lists and return true
784  /// if any issue is found.
785  bool checkMappableExprComponentListsForDecl(
786  const ValueDecl *VD, bool CurrentRegionOnly,
787  const llvm::function_ref<
790  Check) const {
791  if (isStackEmpty())
792  return false;
793  auto SI = begin();
794  auto SE = end();
795 
796  if (SI == SE)
797  return false;
798 
799  if (CurrentRegionOnly)
800  SE = std::next(SI);
801  else
802  std::advance(SI, 1);
803 
804  for (; SI != SE; ++SI) {
805  auto MI = SI->MappedExprComponents.find(VD);
806  if (MI != SI->MappedExprComponents.end())
808  MI->second.Components)
809  if (Check(L, MI->second.Kind))
810  return true;
811  }
812  return false;
813  }
814 
815  /// Do the check specified in \a Check to all component lists at a given level
816  /// and return true if any issue is found.
817  bool checkMappableExprComponentListsForDeclAtLevel(
818  const ValueDecl *VD, unsigned Level,
819  const llvm::function_ref<
822  Check) const {
823  if (getStackSize() <= Level)
824  return false;
825 
826  const SharingMapTy &StackElem = getStackElemAtLevel(Level);
827  auto MI = StackElem.MappedExprComponents.find(VD);
828  if (MI != StackElem.MappedExprComponents.end())
830  MI->second.Components)
831  if (Check(L, MI->second.Kind))
832  return true;
833  return false;
834  }
835 
836  /// Create a new mappable expression component list associated with a given
837  /// declaration and initialize it with the provided list of components.
838  void addMappableExpressionComponents(
839  const ValueDecl *VD,
841  OpenMPClauseKind WhereFoundClauseKind) {
842  MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
843  // Create new entry and append the new components there.
844  MEC.Components.resize(MEC.Components.size() + 1);
845  MEC.Components.back().append(Components.begin(), Components.end());
846  MEC.Kind = WhereFoundClauseKind;
847  }
848 
849  unsigned getNestingLevel() const {
850  assert(!isStackEmpty());
851  return getStackSize() - 1;
852  }
853  void addDoacrossDependClause(OMPDependClause *C,
854  const OperatorOffsetTy &OpsOffs) {
855  SharingMapTy *Parent = getSecondOnStackOrNull();
856  assert(Parent && isOpenMPWorksharingDirective(Parent->Directive));
857  Parent->DoacrossDepends.try_emplace(C, OpsOffs);
858  }
859  llvm::iterator_range<DoacrossDependMapTy::const_iterator>
860  getDoacrossDependClauses() const {
861  const SharingMapTy &StackElem = getTopOfStack();
862  if (isOpenMPWorksharingDirective(StackElem.Directive)) {
863  const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
864  return llvm::make_range(Ref.begin(), Ref.end());
865  }
866  return llvm::make_range(StackElem.DoacrossDepends.end(),
867  StackElem.DoacrossDepends.end());
868  }
869 
870  // Store types of classes which have been explicitly mapped
871  void addMappedClassesQualTypes(QualType QT) {
872  SharingMapTy &StackElem = getTopOfStack();
873  StackElem.MappedClassesQualTypes.insert(QT);
874  }
875 
876  // Return set of mapped classes types
877  bool isClassPreviouslyMapped(QualType QT) const {
878  const SharingMapTy &StackElem = getTopOfStack();
879  return StackElem.MappedClassesQualTypes.count(QT) != 0;
880  }
881 
882  /// Adds global declare target to the parent target region.
883  void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) {
884  assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
885  E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
886  "Expected declare target link global.");
887  for (auto &Elem : *this) {
888  if (isOpenMPTargetExecutionDirective(Elem.Directive)) {
889  Elem.DeclareTargetLinkVarDecls.push_back(E);
890  return;
891  }
892  }
893  }
894 
895  /// Returns the list of globals with declare target link if current directive
896  /// is target.
897  ArrayRef<DeclRefExpr *> getLinkGlobals() const {
898  assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) &&
899  "Expected target executable directive.");
900  return getTopOfStack().DeclareTargetLinkVarDecls;
901  }
902 };
903 
904 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
905  return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
906 }
907 
908 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
909  return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) ||
910  DKind == OMPD_unknown;
911 }
912 
913 } // namespace
914 
915 static const Expr *getExprAsWritten(const Expr *E) {
916  if (const auto *FE = dyn_cast<FullExpr>(E))
917  E = FE->getSubExpr();
918 
919  if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
920  E = MTE->getSubExpr();
921 
922  while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
923  E = Binder->getSubExpr();
924 
925  if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
926  E = ICE->getSubExprAsWritten();
927  return E->IgnoreParens();
928 }
929 
931  return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
932 }
933 
934 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
935  if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
936  if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
937  D = ME->getMemberDecl();
938  const auto *VD = dyn_cast<VarDecl>(D);
939  const auto *FD = dyn_cast<FieldDecl>(D);
940  if (VD != nullptr) {
941  VD = VD->getCanonicalDecl();
942  D = VD;
943  } else {
944  assert(FD);
945  FD = FD->getCanonicalDecl();
946  D = FD;
947  }
948  return D;
949 }
950 
952  return const_cast<ValueDecl *>(
953  getCanonicalDecl(const_cast<const ValueDecl *>(D)));
954 }
955 
956 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
957  ValueDecl *D) const {
958  D = getCanonicalDecl(D);
959  auto *VD = dyn_cast<VarDecl>(D);
960  const auto *FD = dyn_cast<FieldDecl>(D);
961  DSAVarData DVar;
962  if (Iter == end()) {
963  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
964  // in a region but not in construct]
965  // File-scope or namespace-scope variables referenced in called routines
966  // in the region are shared unless they appear in a threadprivate
967  // directive.
968  if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
969  DVar.CKind = OMPC_shared;
970 
971  // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
972  // in a region but not in construct]
973  // Variables with static storage duration that are declared in called
974  // routines in the region are shared.
975  if (VD && VD->hasGlobalStorage())
976  DVar.CKind = OMPC_shared;
977 
978  // Non-static data members are shared by default.
979  if (FD)
980  DVar.CKind = OMPC_shared;
981 
982  return DVar;
983  }
984 
985  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
986  // in a Construct, C/C++, predetermined, p.1]
987  // Variables with automatic storage duration that are declared in a scope
988  // inside the construct are private.
989  if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
990  (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
991  DVar.CKind = OMPC_private;
992  return DVar;
993  }
994 
995  DVar.DKind = Iter->Directive;
996  // Explicitly specified attributes and local variables with predetermined
997  // attributes.
998  if (Iter->SharingMap.count(D)) {
999  const DSAInfo &Data = Iter->SharingMap.lookup(D);
1000  DVar.RefExpr = Data.RefExpr.getPointer();
1001  DVar.PrivateCopy = Data.PrivateCopy;
1002  DVar.CKind = Data.Attributes;
1003  DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1004  return DVar;
1005  }
1006 
1007  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1008  // in a Construct, C/C++, implicitly determined, p.1]
1009  // In a parallel or task construct, the data-sharing attributes of these
1010  // variables are determined by the default clause, if present.
1011  switch (Iter->DefaultAttr) {
1012  case DSA_shared:
1013  DVar.CKind = OMPC_shared;
1014  DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1015  return DVar;
1016  case DSA_none:
1017  return DVar;
1018  case DSA_unspecified:
1019  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1020  // in a Construct, implicitly determined, p.2]
1021  // In a parallel construct, if no default clause is present, these
1022  // variables are shared.
1023  DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1024  if ((isOpenMPParallelDirective(DVar.DKind) &&
1025  !isOpenMPTaskLoopDirective(DVar.DKind)) ||
1026  isOpenMPTeamsDirective(DVar.DKind)) {
1027  DVar.CKind = OMPC_shared;
1028  return DVar;
1029  }
1030 
1031  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1032  // in a Construct, implicitly determined, p.4]
1033  // In a task construct, if no default clause is present, a variable that in
1034  // the enclosing context is determined to be shared by all implicit tasks
1035  // bound to the current team is shared.
1036  if (isOpenMPTaskingDirective(DVar.DKind)) {
1037  DSAVarData DVarTemp;
1038  const_iterator I = Iter, E = end();
1039  do {
1040  ++I;
1041  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
1042  // Referenced in a Construct, implicitly determined, p.6]
1043  // In a task construct, if no default clause is present, a variable
1044  // whose data-sharing attribute is not determined by the rules above is
1045  // firstprivate.
1046  DVarTemp = getDSA(I, D);
1047  if (DVarTemp.CKind != OMPC_shared) {
1048  DVar.RefExpr = nullptr;
1049  DVar.CKind = OMPC_firstprivate;
1050  return DVar;
1051  }
1052  } while (I != E && !isImplicitTaskingRegion(I->Directive));
1053  DVar.CKind =
1054  (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1055  return DVar;
1056  }
1057  }
1058  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1059  // in a Construct, implicitly determined, p.3]
1060  // For constructs other than task, if no default clause is present, these
1061  // variables inherit their data-sharing attributes from the enclosing
1062  // context.
1063  return getDSA(++Iter, D);
1064 }
1065 
1066 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
1067  const Expr *NewDE) {
1068  assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1069  D = getCanonicalDecl(D);
1070  SharingMapTy &StackElem = getTopOfStack();
1071  auto It = StackElem.AlignedMap.find(D);
1072  if (It == StackElem.AlignedMap.end()) {
1073  assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1074  StackElem.AlignedMap[D] = NewDE;
1075  return nullptr;
1076  }
1077  assert(It->second && "Unexpected nullptr expr in the aligned map");
1078  return It->second;
1079 }
1080 
1081 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D,
1082  const Expr *NewDE) {
1083  assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1084  D = getCanonicalDecl(D);
1085  SharingMapTy &StackElem = getTopOfStack();
1086  auto It = StackElem.NontemporalMap.find(D);
1087  if (It == StackElem.NontemporalMap.end()) {
1088  assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1089  StackElem.NontemporalMap[D] = NewDE;
1090  return nullptr;
1091  }
1092  assert(It->second && "Unexpected nullptr expr in the aligned map");
1093  return It->second;
1094 }
1095 
1096 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
1097  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1098  D = getCanonicalDecl(D);
1099  SharingMapTy &StackElem = getTopOfStack();
1100  StackElem.LCVMap.try_emplace(
1101  D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
1102 }
1103 
1104 const DSAStackTy::LCDeclInfo
1105 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
1106  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1107  D = getCanonicalDecl(D);
1108  const SharingMapTy &StackElem = getTopOfStack();
1109  auto It = StackElem.LCVMap.find(D);
1110  if (It != StackElem.LCVMap.end())
1111  return It->second;
1112  return {0, nullptr};
1113 }
1114 
1115 const DSAStackTy::LCDeclInfo
1116 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
1117  const SharingMapTy *Parent = getSecondOnStackOrNull();
1118  assert(Parent && "Data-sharing attributes stack is empty");
1119  D = getCanonicalDecl(D);
1120  auto It = Parent->LCVMap.find(D);
1121  if (It != Parent->LCVMap.end())
1122  return It->second;
1123  return {0, nullptr};
1124 }
1125 
1126 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
1127  const SharingMapTy *Parent = getSecondOnStackOrNull();
1128  assert(Parent && "Data-sharing attributes stack is empty");
1129  if (Parent->LCVMap.size() < I)
1130  return nullptr;
1131  for (const auto &Pair : Parent->LCVMap)
1132  if (Pair.second.first == I)
1133  return Pair.first;
1134  return nullptr;
1135 }
1136 
1137 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
1138  DeclRefExpr *PrivateCopy) {
1139  D = getCanonicalDecl(D);
1140  if (A == OMPC_threadprivate) {
1141  DSAInfo &Data = Threadprivates[D];
1142  Data.Attributes = A;
1143  Data.RefExpr.setPointer(E);
1144  Data.PrivateCopy = nullptr;
1145  } else {
1146  DSAInfo &Data = getTopOfStack().SharingMap[D];
1147  assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
1148  (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
1149  (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
1150  (isLoopControlVariable(D).first && A == OMPC_private));
1151  if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
1152  Data.RefExpr.setInt(/*IntVal=*/true);
1153  return;
1154  }
1155  const bool IsLastprivate =
1156  A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
1157  Data.Attributes = A;
1158  Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1159  Data.PrivateCopy = PrivateCopy;
1160  if (PrivateCopy) {
1161  DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()];
1162  Data.Attributes = A;
1163  Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1164  Data.PrivateCopy = nullptr;
1165  }
1166  }
1167 }
1168 
1169 /// Build a variable declaration for OpenMP loop iteration variable.
1171  StringRef Name, const AttrVec *Attrs = nullptr,
1172  DeclRefExpr *OrigRef = nullptr) {
1173  DeclContext *DC = SemaRef.CurContext;
1174  IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
1175  TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
1176  auto *Decl =
1177  VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
1178  if (Attrs) {
1179  for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
1180  I != E; ++I)
1181  Decl->addAttr(*I);
1182  }
1183  Decl->setImplicit();
1184  if (OrigRef) {
1185  Decl->addAttr(
1186  OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
1187  }
1188  return Decl;
1189 }
1190 
1192  SourceLocation Loc,
1193  bool RefersToCapture = false) {
1194  D->setReferenced();
1195  D->markUsed(S.Context);
1197  SourceLocation(), D, RefersToCapture, Loc, Ty,
1198  VK_LValue);
1199 }
1200 
1201 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1202  BinaryOperatorKind BOK) {
1203  D = getCanonicalDecl(D);
1204  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1205  assert(
1206  getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1207  "Additional reduction info may be specified only for reduction items.");
1208  ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1209  assert(ReductionData.ReductionRange.isInvalid() &&
1210  getTopOfStack().Directive == OMPD_taskgroup &&
1211  "Additional reduction info may be specified only once for reduction "
1212  "items.");
1213  ReductionData.set(BOK, SR);
1214  Expr *&TaskgroupReductionRef =
1215  getTopOfStack().TaskgroupReductionRef;
1216  if (!TaskgroupReductionRef) {
1217  VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1218  SemaRef.Context.VoidPtrTy, ".task_red.");
1219  TaskgroupReductionRef =
1220  buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1221  }
1222 }
1223 
1224 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1225  const Expr *ReductionRef) {
1226  D = getCanonicalDecl(D);
1227  assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1228  assert(
1229  getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1230  "Additional reduction info may be specified only for reduction items.");
1231  ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1232  assert(ReductionData.ReductionRange.isInvalid() &&
1233  getTopOfStack().Directive == OMPD_taskgroup &&
1234  "Additional reduction info may be specified only once for reduction "
1235  "items.");
1236  ReductionData.set(ReductionRef, SR);
1237  Expr *&TaskgroupReductionRef =
1238  getTopOfStack().TaskgroupReductionRef;
1239  if (!TaskgroupReductionRef) {
1240  VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1241  SemaRef.Context.VoidPtrTy, ".task_red.");
1242  TaskgroupReductionRef =
1243  buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1244  }
1245 }
1246 
1247 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1248  const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
1249  Expr *&TaskgroupDescriptor) const {
1250  D = getCanonicalDecl(D);
1251  assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1252  for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1253  const DSAInfo &Data = I->SharingMap.lookup(D);
1254  if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
1255  continue;
1256  const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1257  if (!ReductionData.ReductionOp ||
1258  ReductionData.ReductionOp.is<const Expr *>())
1259  return DSAVarData();
1260  SR = ReductionData.ReductionRange;
1261  BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1262  assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1263  "expression for the descriptor is not "
1264  "set.");
1265  TaskgroupDescriptor = I->TaskgroupReductionRef;
1266  return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
1267  Data.PrivateCopy, I->DefaultAttrLoc);
1268  }
1269  return DSAVarData();
1270 }
1271 
1272 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1273  const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
1274  Expr *&TaskgroupDescriptor) const {
1275  D = getCanonicalDecl(D);
1276  assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1277  for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1278  const DSAInfo &Data = I->SharingMap.lookup(D);
1279  if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup)
1280  continue;
1281  const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1282  if (!ReductionData.ReductionOp ||
1283  !ReductionData.ReductionOp.is<const Expr *>())
1284  return DSAVarData();
1285  SR = ReductionData.ReductionRange;
1286  ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
1287  assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1288  "expression for the descriptor is not "
1289  "set.");
1290  TaskgroupDescriptor = I->TaskgroupReductionRef;
1291  return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(),
1292  Data.PrivateCopy, I->DefaultAttrLoc);
1293  }
1294  return DSAVarData();
1295 }
1296 
1297 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const {
1298  D = D->getCanonicalDecl();
1299  for (const_iterator E = end(); I != E; ++I) {
1300  if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1301  isOpenMPTargetExecutionDirective(I->Directive)) {
1302  Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr;
1303  Scope *CurScope = getCurScope();
1304  while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D))
1305  CurScope = CurScope->getParent();
1306  return CurScope != TopScope;
1307  }
1308  }
1309  return false;
1310 }
1311 
1312 static bool isConstNotMutableType(Sema &SemaRef, QualType Type,
1313  bool AcceptIfMutable = true,
1314  bool *IsClassType = nullptr) {
1315  ASTContext &Context = SemaRef.getASTContext();
1316  Type = Type.getNonReferenceType().getCanonicalType();
1317  bool IsConstant = Type.isConstant(Context);
1318  Type = Context.getBaseElementType(Type);
1319  const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus
1320  ? Type->getAsCXXRecordDecl()
1321  : nullptr;
1322  if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1323  if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1324  RD = CTD->getTemplatedDecl();
1325  if (IsClassType)
1326  *IsClassType = RD;
1327  return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD &&
1328  RD->hasDefinition() && RD->hasMutableFields());
1329 }
1330 
1331 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D,
1333  SourceLocation ELoc,
1334  bool AcceptIfMutable = true,
1335  bool ListItemNotVar = false) {
1336  ASTContext &Context = SemaRef.getASTContext();
1337  bool IsClassType;
1338  if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) {
1339  unsigned Diag = ListItemNotVar
1340  ? diag::err_omp_const_list_item
1341  : IsClassType ? diag::err_omp_const_not_mutable_variable
1342  : diag::err_omp_const_variable;
1343  SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind);
1344  if (!ListItemNotVar && D) {
1345  const VarDecl *VD = dyn_cast<VarDecl>(D);
1346  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
1348  SemaRef.Diag(D->getLocation(),
1349  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1350  << D;
1351  }
1352  return true;
1353  }
1354  return false;
1355 }
1356 
1357 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1358  bool FromParent) {
1359  D = getCanonicalDecl(D);
1360  DSAVarData DVar;
1361 
1362  auto *VD = dyn_cast<VarDecl>(D);
1363  auto TI = Threadprivates.find(D);
1364  if (TI != Threadprivates.end()) {
1365  DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1366  DVar.CKind = OMPC_threadprivate;
1367  return DVar;
1368  }
1369  if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1370  DVar.RefExpr = buildDeclRefExpr(
1371  SemaRef, VD, D->getType().getNonReferenceType(),
1372  VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1373  DVar.CKind = OMPC_threadprivate;
1374  addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1375  return DVar;
1376  }
1377  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1378  // in a Construct, C/C++, predetermined, p.1]
1379  // Variables appearing in threadprivate directives are threadprivate.
1380  if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1381  !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1382  SemaRef.getLangOpts().OpenMPUseTLS &&
1383  SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1384  (VD && VD->getStorageClass() == SC_Register &&
1385  VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1386  DVar.RefExpr = buildDeclRefExpr(
1387  SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1388  DVar.CKind = OMPC_threadprivate;
1389  addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1390  return DVar;
1391  }
1392  if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1393  VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1394  !isLoopControlVariable(D).first) {
1395  const_iterator IterTarget =
1396  std::find_if(begin(), end(), [](const SharingMapTy &Data) {
1397  return isOpenMPTargetExecutionDirective(Data.Directive);
1398  });
1399  if (IterTarget != end()) {
1400  const_iterator ParentIterTarget = IterTarget + 1;
1401  for (const_iterator Iter = begin();
1402  Iter != ParentIterTarget; ++Iter) {
1403  if (isOpenMPLocal(VD, Iter)) {
1404  DVar.RefExpr =
1405  buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1406  D->getLocation());
1407  DVar.CKind = OMPC_threadprivate;
1408  return DVar;
1409  }
1410  }
1411  if (!isClauseParsingMode() || IterTarget != begin()) {
1412  auto DSAIter = IterTarget->SharingMap.find(D);
1413  if (DSAIter != IterTarget->SharingMap.end() &&
1414  isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1415  DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1416  DVar.CKind = OMPC_threadprivate;
1417  return DVar;
1418  }
1419  const_iterator End = end();
1420  if (!SemaRef.isOpenMPCapturedByRef(
1421  D, std::distance(ParentIterTarget, End),
1422  /*OpenMPCaptureLevel=*/0)) {
1423  DVar.RefExpr =
1424  buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1425  IterTarget->ConstructLoc);
1426  DVar.CKind = OMPC_threadprivate;
1427  return DVar;
1428  }
1429  }
1430  }
1431  }
1432 
1433  if (isStackEmpty())
1434  // Not in OpenMP execution region and top scope was already checked.
1435  return DVar;
1436 
1437  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1438  // in a Construct, C/C++, predetermined, p.4]
1439  // Static data members are shared.
1440  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1441  // in a Construct, C/C++, predetermined, p.7]
1442  // Variables with static storage duration that are declared in a scope
1443  // inside the construct are shared.
1444  if (VD && VD->isStaticDataMember()) {
1445  // Check for explicitly specified attributes.
1446  const_iterator I = begin();
1447  const_iterator EndI = end();
1448  if (FromParent && I != EndI)
1449  ++I;
1450  auto It = I->SharingMap.find(D);
1451  if (It != I->SharingMap.end()) {
1452  const DSAInfo &Data = It->getSecond();
1453  DVar.RefExpr = Data.RefExpr.getPointer();
1454  DVar.PrivateCopy = Data.PrivateCopy;
1455  DVar.CKind = Data.Attributes;
1456  DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1457  DVar.DKind = I->Directive;
1458  return DVar;
1459  }
1460 
1461  DVar.CKind = OMPC_shared;
1462  return DVar;
1463  }
1464 
1465  auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
1466  // The predetermined shared attribute for const-qualified types having no
1467  // mutable members was removed after OpenMP 3.1.
1468  if (SemaRef.LangOpts.OpenMP <= 31) {
1469  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1470  // in a Construct, C/C++, predetermined, p.6]
1471  // Variables with const qualified type having no mutable member are
1472  // shared.
1473  if (isConstNotMutableType(SemaRef, D->getType())) {
1474  // Variables with const-qualified type having no mutable member may be
1475  // listed in a firstprivate clause, even if they are static data members.
1476  DSAVarData DVarTemp = hasInnermostDSA(
1477  D,
1478  [](OpenMPClauseKind C) {
1479  return C == OMPC_firstprivate || C == OMPC_shared;
1480  },
1481  MatchesAlways, FromParent);
1482  if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1483  return DVarTemp;
1484 
1485  DVar.CKind = OMPC_shared;
1486  return DVar;
1487  }
1488  }
1489 
1490  // Explicitly specified attributes and local variables with predetermined
1491  // attributes.
1492  const_iterator I = begin();
1493  const_iterator EndI = end();
1494  if (FromParent && I != EndI)
1495  ++I;
1496  auto It = I->SharingMap.find(D);
1497  if (It != I->SharingMap.end()) {
1498  const DSAInfo &Data = It->getSecond();
1499  DVar.RefExpr = Data.RefExpr.getPointer();
1500  DVar.PrivateCopy = Data.PrivateCopy;
1501  DVar.CKind = Data.Attributes;
1502  DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1503  DVar.DKind = I->Directive;
1504  }
1505 
1506  return DVar;
1507 }
1508 
1509 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1510  bool FromParent) const {
1511  if (isStackEmpty()) {
1512  const_iterator I;
1513  return getDSA(I, D);
1514  }
1515  D = getCanonicalDecl(D);
1516  const_iterator StartI = begin();
1517  const_iterator EndI = end();
1518  if (FromParent && StartI != EndI)
1519  ++StartI;
1520  return getDSA(StartI, D);
1521 }
1522 
1523 const DSAStackTy::DSAVarData
1524 DSAStackTy::hasDSA(ValueDecl *D,
1525  const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1526  const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1527  bool FromParent) const {
1528  if (isStackEmpty())
1529  return {};
1530  D = getCanonicalDecl(D);
1531  const_iterator I = begin();
1532  const_iterator EndI = end();
1533  if (FromParent && I != EndI)
1534  ++I;
1535  for (; I != EndI; ++I) {
1536  if (!DPred(I->Directive) &&
1537  !isImplicitOrExplicitTaskingRegion(I->Directive))
1538  continue;
1539  const_iterator NewI = I;
1540  DSAVarData DVar = getDSA(NewI, D);
1541  if (I == NewI && CPred(DVar.CKind))
1542  return DVar;
1543  }
1544  return {};
1545 }
1546 
1547 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1548  ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1549  const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1550  bool FromParent) const {
1551  if (isStackEmpty())
1552  return {};
1553  D = getCanonicalDecl(D);
1554  const_iterator StartI = begin();
1555  const_iterator EndI = end();
1556  if (FromParent && StartI != EndI)
1557  ++StartI;
1558  if (StartI == EndI || !DPred(StartI->Directive))
1559  return {};
1560  const_iterator NewI = StartI;
1561  DSAVarData DVar = getDSA(NewI, D);
1562  return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData();
1563 }
1564 
1565 bool DSAStackTy::hasExplicitDSA(
1566  const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred,
1567  unsigned Level, bool NotLastprivate) const {
1568  if (getStackSize() <= Level)
1569  return false;
1570  D = getCanonicalDecl(D);
1571  const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1572  auto I = StackElem.SharingMap.find(D);
1573  if (I != StackElem.SharingMap.end() &&
1574  I->getSecond().RefExpr.getPointer() &&
1575  CPred(I->getSecond().Attributes) &&
1576  (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1577  return true;
1578  // Check predetermined rules for the loop control variables.
1579  auto LI = StackElem.LCVMap.find(D);
1580  if (LI != StackElem.LCVMap.end())
1581  return CPred(OMPC_private);
1582  return false;
1583 }
1584 
1585 bool DSAStackTy::hasExplicitDirective(
1586  const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1587  unsigned Level) const {
1588  if (getStackSize() <= Level)
1589  return false;
1590  const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1591  return DPred(StackElem.Directive);
1592 }
1593 
1594 bool DSAStackTy::hasDirective(
1595  const llvm::function_ref<bool(OpenMPDirectiveKind,
1597  DPred,
1598  bool FromParent) const {
1599  // We look only in the enclosing region.
1600  size_t Skip = FromParent ? 2 : 1;
1601  for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
1602  I != E; ++I) {
1603  if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1604  return true;
1605  }
1606  return false;
1607 }
1608 
1609 void Sema::InitDataSharingAttributesStack() {
1610  VarDataSharingAttributesStack = new DSAStackTy(*this);
1611 }
1612 
1613 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1614 
1615 void Sema::pushOpenMPFunctionRegion() {
1616  DSAStack->pushFunction();
1617 }
1618 
1619 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
1620  DSAStack->popFunction(OldFSI);
1621 }
1622 
1624  assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice &&
1625  "Expected OpenMP device compilation.");
1626  return !S.isInOpenMPTargetExecutionDirective() &&
1628 }
1629 
1630 namespace {
1631 /// Status of the function emission on the host/device.
1633  Emitted,
1634  Discarded,
1635  Unknown,
1636 };
1637 } // anonymous namespace
1638 
1640  unsigned DiagID) {
1641  assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
1642  "Expected OpenMP device compilation.");
1643  FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl());
1644  DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop;
1645  switch (FES) {
1646  case FunctionEmissionStatus::Emitted:
1647  Kind = DeviceDiagBuilder::K_Immediate;
1648  break;
1650  Kind = isOpenMPDeviceDelayedContext(*this) ? DeviceDiagBuilder::K_Deferred
1651  : DeviceDiagBuilder::K_Immediate;
1652  break;
1653  case FunctionEmissionStatus::TemplateDiscarded:
1654  case FunctionEmissionStatus::OMPDiscarded:
1655  Kind = DeviceDiagBuilder::K_Nop;
1656  break;
1657  case FunctionEmissionStatus::CUDADiscarded:
1658  llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation");
1659  break;
1660  }
1661 
1662  return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this);
1663 }
1664 
1666  unsigned DiagID) {
1667  assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice &&
1668  "Expected OpenMP host compilation.");
1669  FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl());
1670  DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop;
1671  switch (FES) {
1672  case FunctionEmissionStatus::Emitted:
1673  Kind = DeviceDiagBuilder::K_Immediate;
1674  break;
1676  Kind = DeviceDiagBuilder::K_Deferred;
1677  break;
1678  case FunctionEmissionStatus::TemplateDiscarded:
1679  case FunctionEmissionStatus::OMPDiscarded:
1680  case FunctionEmissionStatus::CUDADiscarded:
1681  Kind = DeviceDiagBuilder::K_Nop;
1682  break;
1683  }
1684 
1685  return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this);
1686 }
1687 
1688 void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee,
1689  bool CheckForDelayedContext) {
1690  assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
1691  "Expected OpenMP device compilation.");
1692  assert(Callee && "Callee may not be null.");
1693  Callee = Callee->getMostRecentDecl();
1694  FunctionDecl *Caller = getCurFunctionDecl();
1695 
1696  // host only function are not available on the device.
1697  if (Caller) {
1698  FunctionEmissionStatus CallerS = getEmissionStatus(Caller);
1699  FunctionEmissionStatus CalleeS = getEmissionStatus(Callee);
1700  assert(CallerS != FunctionEmissionStatus::CUDADiscarded &&
1701  CalleeS != FunctionEmissionStatus::CUDADiscarded &&
1702  "CUDADiscarded unexpected in OpenMP device function check");
1703  if ((CallerS == FunctionEmissionStatus::Emitted ||
1704  (!isOpenMPDeviceDelayedContext(*this) &&
1705  CallerS == FunctionEmissionStatus::Unknown)) &&
1706  CalleeS == FunctionEmissionStatus::OMPDiscarded) {
1707  StringRef HostDevTy = getOpenMPSimpleClauseTypeName(
1708  OMPC_device_type, OMPC_DEVICE_TYPE_host);
1709  Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
1710  Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(),
1711  diag::note_omp_marked_device_type_here)
1712  << HostDevTy;
1713  return;
1714  }
1715  }
1716  // If the caller is known-emitted, mark the callee as known-emitted.
1717  // Otherwise, mark the call in our call graph so we can traverse it later.
1718  if ((CheckForDelayedContext && !isOpenMPDeviceDelayedContext(*this)) ||
1719  (!Caller && !CheckForDelayedContext) ||
1720  (Caller && getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted))
1721  markKnownEmitted(*this, Caller, Callee, Loc,
1722  [CheckForDelayedContext](Sema &S, FunctionDecl *FD) {
1723  return CheckForDelayedContext &&
1724  S.getEmissionStatus(FD) ==
1725  FunctionEmissionStatus::Emitted;
1726  });
1727  else if (Caller)
1728  DeviceCallGraph[Caller].insert({Callee, Loc});
1729 }
1730 
1731 void Sema::checkOpenMPHostFunction(SourceLocation Loc, FunctionDecl *Callee,
1732  bool CheckCaller) {
1733  assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice &&
1734  "Expected OpenMP host compilation.");
1735  assert(Callee && "Callee may not be null.");
1736  Callee = Callee->getMostRecentDecl();
1737  FunctionDecl *Caller = getCurFunctionDecl();
1738 
1739  // device only function are not available on the host.
1740  if (Caller) {
1741  FunctionEmissionStatus CallerS = getEmissionStatus(Caller);
1742  FunctionEmissionStatus CalleeS = getEmissionStatus(Callee);
1743  assert(
1744  (LangOpts.CUDA || (CallerS != FunctionEmissionStatus::CUDADiscarded &&
1745  CalleeS != FunctionEmissionStatus::CUDADiscarded)) &&
1746  "CUDADiscarded unexpected in OpenMP host function check");
1747  if (CallerS == FunctionEmissionStatus::Emitted &&
1748  CalleeS == FunctionEmissionStatus::OMPDiscarded) {
1749  StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
1750  OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
1751  Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
1752  Diag(Callee->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(),
1753  diag::note_omp_marked_device_type_here)
1754  << NoHostDevTy;
1755  return;
1756  }
1757  }
1758  // If the caller is known-emitted, mark the callee as known-emitted.
1759  // Otherwise, mark the call in our call graph so we can traverse it later.
1760  if (!shouldIgnoreInHostDeviceCheck(Callee)) {
1761  if ((!CheckCaller && !Caller) ||
1762  (Caller &&
1763  getEmissionStatus(Caller) == FunctionEmissionStatus::Emitted))
1764  markKnownEmitted(
1765  *this, Caller, Callee, Loc, [CheckCaller](Sema &S, FunctionDecl *FD) {
1766  return CheckCaller &&
1767  S.getEmissionStatus(FD) == FunctionEmissionStatus::Emitted;
1768  });
1769  else if (Caller)
1770  DeviceCallGraph[Caller].insert({Callee, Loc});
1771  }
1772 }
1773 
1774 void Sema::checkOpenMPDeviceExpr(const Expr *E) {
1775  assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice &&
1776  "OpenMP device compilation mode is expected.");
1777  QualType Ty = E->getType();
1778  if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) ||
1779  ((Ty->isFloat128Type() ||
1780  (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128)) &&
1781  !Context.getTargetInfo().hasFloat128Type()) ||
1782  (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 &&
1783  !Context.getTargetInfo().hasInt128Type()))
1784  targetDiag(E->getExprLoc(), diag::err_omp_unsupported_type)
1785  << static_cast<unsigned>(Context.getTypeSize(Ty)) << Ty
1786  << Context.getTargetInfo().getTriple().str() << E->getSourceRange();
1787 }
1788 
1791  if (LO.OpenMP <= 45) {
1792  if (VD->getType().getNonReferenceType()->isScalarType())
1793  return OMPC_DEFAULTMAP_scalar;
1794  return OMPC_DEFAULTMAP_aggregate;
1795  }
1797  return OMPC_DEFAULTMAP_pointer;
1798  if (VD->getType().getNonReferenceType()->isScalarType())
1799  return OMPC_DEFAULTMAP_scalar;
1800  return OMPC_DEFAULTMAP_aggregate;
1801 }
1802 
1804  unsigned OpenMPCaptureLevel) const {
1805  assert(LangOpts.OpenMP && "OpenMP is not allowed");
1806 
1807  ASTContext &Ctx = getASTContext();
1808  bool IsByRef = true;
1809 
1810  // Find the directive that is associated with the provided scope.
1811  D = cast<ValueDecl>(D->getCanonicalDecl());
1812  QualType Ty = D->getType();
1813 
1814  bool IsVariableUsedInMapClause = false;
1815  if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
1816  // This table summarizes how a given variable should be passed to the device
1817  // given its type and the clauses where it appears. This table is based on
1818  // the description in OpenMP 4.5 [2.10.4, target Construct] and
1819  // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
1820  //
1821  // =========================================================================
1822  // | type | defaultmap | pvt | first | is_device_ptr | map | res. |
1823  // | |(tofrom:scalar)| | pvt | | | |
1824  // =========================================================================
1825  // | scl | | | | - | | bycopy|
1826  // | scl | | - | x | - | - | bycopy|
1827  // | scl | | x | - | - | - | null |
1828  // | scl | x | | | - | | byref |
1829  // | scl | x | - | x | - | - | bycopy|
1830  // | scl | x | x | - | - | - | null |
1831  // | scl | | - | - | - | x | byref |
1832  // | scl | x | - | - | - | x | byref |
1833  //
1834  // | agg | n.a. | | | - | | byref |
1835  // | agg | n.a. | - | x | - | - | byref |
1836  // | agg | n.a. | x | - | - | - | null |
1837  // | agg | n.a. | - | - | - | x | byref |
1838  // | agg | n.a. | - | - | - | x[] | byref |
1839  //
1840  // | ptr | n.a. | | | - | | bycopy|
1841  // | ptr | n.a. | - | x | - | - | bycopy|
1842  // | ptr | n.a. | x | - | - | - | null |
1843  // | ptr | n.a. | - | - | - | x | byref |
1844  // | ptr | n.a. | - | - | - | x[] | bycopy|
1845  // | ptr | n.a. | - | - | x | | bycopy|
1846  // | ptr | n.a. | - | - | x | x | bycopy|
1847  // | ptr | n.a. | - | - | x | x[] | bycopy|
1848  // =========================================================================
1849  // Legend:
1850  // scl - scalar
1851  // ptr - pointer
1852  // agg - aggregate
1853  // x - applies
1854  // - - invalid in this combination
1855  // [] - mapped with an array section
1856  // byref - should be mapped by reference
1857  // byval - should be mapped by value
1858  // null - initialize a local variable to null on the device
1859  //
1860  // Observations:
1861  // - All scalar declarations that show up in a map clause have to be passed
1862  // by reference, because they may have been mapped in the enclosing data
1863  // environment.
1864  // - If the scalar value does not fit the size of uintptr, it has to be
1865  // passed by reference, regardless the result in the table above.
1866  // - For pointers mapped by value that have either an implicit map or an
1867  // array section, the runtime library may pass the NULL value to the
1868  // device instead of the value passed to it by the compiler.
1869 
1870  if (Ty->isReferenceType())
1871  Ty = Ty->castAs<ReferenceType>()->getPointeeType();
1872 
1873  // Locate map clauses and see if the variable being captured is referred to
1874  // in any of those clauses. Here we only care about variables, not fields,
1875  // because fields are part of aggregates.
1876  bool IsVariableAssociatedWithSection = false;
1877 
1878  DSAStack->checkMappableExprComponentListsForDeclAtLevel(
1879  D, Level,
1880  [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D](
1882  MapExprComponents,
1883  OpenMPClauseKind WhereFoundClauseKind) {
1884  // Only the map clause information influences how a variable is
1885  // captured. E.g. is_device_ptr does not require changing the default
1886  // behavior.
1887  if (WhereFoundClauseKind != OMPC_map)
1888  return false;
1889 
1890  auto EI = MapExprComponents.rbegin();
1891  auto EE = MapExprComponents.rend();
1892 
1893  assert(EI != EE && "Invalid map expression!");
1894 
1895  if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
1896  IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
1897 
1898  ++EI;
1899  if (EI == EE)
1900  return false;
1901 
1902  if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
1903  isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
1904  isa<MemberExpr>(EI->getAssociatedExpression())) {
1905  IsVariableAssociatedWithSection = true;
1906  // There is nothing more we need to know about this variable.
1907  return true;
1908  }
1909 
1910  // Keep looking for more map info.
1911  return false;
1912  });
1913 
1914  if (IsVariableUsedInMapClause) {
1915  // If variable is identified in a map clause it is always captured by
1916  // reference except if it is a pointer that is dereferenced somehow.
1917  IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
1918  } else {
1919  // By default, all the data that has a scalar type is mapped by copy
1920  // (except for reduction variables).
1921  // Defaultmap scalar is mutual exclusive to defaultmap pointer
1922  IsByRef =
1923  (DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
1924  !Ty->isAnyPointerType()) ||
1925  !Ty->isScalarType() ||
1926  DSAStack->isDefaultmapCapturedByRef(
1927  Level, getVariableCategoryFromDecl(LangOpts, D)) ||
1928  DSAStack->hasExplicitDSA(
1929  D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level);
1930  }
1931  }
1932 
1933  if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
1934  IsByRef =
1935  ((IsVariableUsedInMapClause &&
1936  DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) ==
1937  OMPD_target) ||
1938  !DSAStack->hasExplicitDSA(
1939  D,
1940  [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; },
1941  Level, /*NotLastprivate=*/true)) &&
1942  // If the variable is artificial and must be captured by value - try to
1943  // capture by value.
1944  !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
1945  !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue());
1946  }
1947 
1948  // When passing data by copy, we need to make sure it fits the uintptr size
1949  // and alignment, because the runtime library only deals with uintptr types.
1950  // If it does not fit the uintptr size, we need to pass the data by reference
1951  // instead.
1952  if (!IsByRef &&
1953  (Ctx.getTypeSizeInChars(Ty) >
1954  Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
1955  Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
1956  IsByRef = true;
1957  }
1958 
1959  return IsByRef;
1960 }
1961 
1962 unsigned Sema::getOpenMPNestingLevel() const {
1963  assert(getLangOpts().OpenMP);
1964  return DSAStack->getNestingLevel();
1965 }
1966 
1968  return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) &&
1969  !DSAStack->isClauseParsingMode()) ||
1970  DSAStack->hasDirective(
1972  SourceLocation) -> bool {
1973  return isOpenMPTargetExecutionDirective(K);
1974  },
1975  false);
1976 }
1977 
1979  unsigned StopAt) {
1980  assert(LangOpts.OpenMP && "OpenMP is not allowed");
1981  D = getCanonicalDecl(D);
1982 
1983  auto *VD = dyn_cast<VarDecl>(D);
1984  // Do not capture constexpr variables.
1985  if (VD && VD->isConstexpr())
1986  return nullptr;
1987 
1988  // If we want to determine whether the variable should be captured from the
1989  // perspective of the current capturing scope, and we've already left all the
1990  // capturing scopes of the top directive on the stack, check from the
1991  // perspective of its parent directive (if any) instead.
1992  DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
1993  *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete());
1994 
1995  // If we are attempting to capture a global variable in a directive with
1996  // 'target' we return true so that this global is also mapped to the device.
1997  //
1998  if (VD && !VD->hasLocalStorage() &&
1999  (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
2000  if (isInOpenMPDeclareTargetContext()) {
2001  // Try to mark variable as declare target if it is used in capturing
2002  // regions.
2003  if (LangOpts.OpenMP <= 45 &&
2004  !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2005  checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
2006  return nullptr;
2007  } else if (isInOpenMPTargetExecutionDirective()) {
2008  // If the declaration is enclosed in a 'declare target' directive,
2009  // then it should not be captured.
2010  //
2011  if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2012  return nullptr;
2013  return VD;
2014  }
2015  }
2016 
2017  if (CheckScopeInfo) {
2018  bool OpenMPFound = false;
2019  for (unsigned I = StopAt + 1; I > 0; --I) {
2020  FunctionScopeInfo *FSI = FunctionScopes[I - 1];
2021  if(!isa<CapturingScopeInfo>(FSI))
2022  return nullptr;
2023  if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2024  if (RSI->CapRegionKind == CR_OpenMP) {
2025  OpenMPFound = true;
2026  break;
2027  }
2028  }
2029  if (!OpenMPFound)
2030  return nullptr;
2031  }
2032 
2033  if (DSAStack->getCurrentDirective() != OMPD_unknown &&
2034  (!DSAStack->isClauseParsingMode() ||
2035  DSAStack->getParentDirective() != OMPD_unknown)) {
2036  auto &&Info = DSAStack->isLoopControlVariable(D);
2037  if (Info.first ||
2038  (VD && VD->hasLocalStorage() &&
2039  isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) ||
2040  (VD && DSAStack->isForceVarCapturing()))
2041  return VD ? VD : Info.second;
2042  DSAStackTy::DSAVarData DVarPrivate =
2043  DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
2044  if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind))
2045  return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2046  // Threadprivate variables must not be captured.
2047  if (isOpenMPThreadPrivate(DVarPrivate.CKind))
2048  return nullptr;
2049  // The variable is not private or it is the variable in the directive with
2050  // default(none) clause and not used in any clause.
2051  DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate,
2052  [](OpenMPDirectiveKind) { return true; },
2053  DSAStack->isClauseParsingMode());
2054  if (DVarPrivate.CKind != OMPC_unknown ||
2055  (VD && DSAStack->getDefaultDSA() == DSA_none))
2056  return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2057  }
2058  return nullptr;
2059 }
2060 
2061 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
2062  unsigned Level) const {
2064  getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level));
2065  FunctionScopesIndex -= Regions.size();
2066 }
2067 
2069  assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2070  if (isOpenMPLoopDirective(DSAStack->getCurrentDirective()))
2071  DSAStack->loopInit();
2072 }
2073 
2075  assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2076  if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2077  DSAStack->resetPossibleLoopCounter();
2078  DSAStack->loopStart();
2079  }
2080 }
2081 
2082 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const {
2083  assert(LangOpts.OpenMP && "OpenMP is not allowed");
2084  if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2085  if (DSAStack->getAssociatedLoops() > 0 &&
2086  !DSAStack->isLoopStarted()) {
2087  DSAStack->resetPossibleLoopCounter(D);
2088  DSAStack->loopStart();
2089  return true;
2090  }
2091  if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
2092  DSAStack->isLoopControlVariable(D).first) &&
2093  !DSAStack->hasExplicitDSA(
2094  D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) &&
2095  !isOpenMPSimdDirective(DSAStack->getCurrentDirective()))
2096  return true;
2097  }
2098  if (const auto *VD = dyn_cast<VarDecl>(D)) {
2099  if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2100  DSAStack->isForceVarCapturing() &&
2101  !DSAStack->hasExplicitDSA(
2102  D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level))
2103  return true;
2104  }
2105  return DSAStack->hasExplicitDSA(
2106  D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) ||
2107  (DSAStack->isClauseParsingMode() &&
2108  DSAStack->getClauseParsingMode() == OMPC_private) ||
2109  // Consider taskgroup reduction descriptor variable a private to avoid
2110  // possible capture in the region.
2111  (DSAStack->hasExplicitDirective(
2112  [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; },
2113  Level) &&
2114  DSAStack->isTaskgroupReductionRef(D, Level));
2115 }
2116 
2118  unsigned Level) {
2119  assert(LangOpts.OpenMP && "OpenMP is not allowed");
2120  D = getCanonicalDecl(D);
2122  for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) {
2123  const unsigned NewLevel = I - 1;
2124  if (DSAStack->hasExplicitDSA(D,
2125  [&OMPC](const OpenMPClauseKind K) {
2126  if (isOpenMPPrivate(K)) {
2127  OMPC = K;
2128  return true;
2129  }
2130  return false;
2131  },
2132  NewLevel))
2133  break;
2134  if (DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2135  D, NewLevel,
2137  OpenMPClauseKind) { return true; })) {
2138  OMPC = OMPC_map;
2139  break;
2140  }
2141  if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2142  NewLevel)) {
2143  OMPC = OMPC_map;
2144  if (DSAStack->mustBeFirstprivateAtLevel(
2145  NewLevel, getVariableCategoryFromDecl(LangOpts, D)))
2146  OMPC = OMPC_firstprivate;
2147  break;
2148  }
2149  }
2150  if (OMPC != OMPC_unknown)
2151  FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC));
2152 }
2153 
2155  unsigned Level) const {
2156  assert(LangOpts.OpenMP && "OpenMP is not allowed");
2157  // Return true if the current level is no longer enclosed in a target region.
2158 
2159  const auto *VD = dyn_cast<VarDecl>(D);
2160  return VD && !VD->hasLocalStorage() &&
2161  DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2162  Level);
2163 }
2164 
2165 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
2166 
2167 void Sema::finalizeOpenMPDelayedAnalysis() {
2168  assert(LangOpts.OpenMP && "Expected OpenMP compilation mode.");
2169  // Diagnose implicit declare target functions and their callees.
2170  for (const auto &CallerCallees : DeviceCallGraph) {
2172  OMPDeclareTargetDeclAttr::getDeviceType(
2173  CallerCallees.getFirst()->getMostRecentDecl());
2174  // Ignore host functions during device analyzis.
2175  if (LangOpts.OpenMPIsDevice && DevTy &&
2176  *DevTy == OMPDeclareTargetDeclAttr::DT_Host)
2177  continue;
2178  // Ignore nohost functions during host analyzis.
2179  if (!LangOpts.OpenMPIsDevice && DevTy &&
2180  *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2181  continue;
2182  for (const std::pair<CanonicalDeclPtr<FunctionDecl>, SourceLocation>
2183  &Callee : CallerCallees.getSecond()) {
2184  const FunctionDecl *FD = Callee.first->getMostRecentDecl();
2186  OMPDeclareTargetDeclAttr::getDeviceType(FD);
2187  if (LangOpts.OpenMPIsDevice && DevTy &&
2188  *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2189  // Diagnose host function called during device codegen.
2190  StringRef HostDevTy = getOpenMPSimpleClauseTypeName(
2191  OMPC_device_type, OMPC_DEVICE_TYPE_host);
2192  Diag(Callee.second, diag::err_omp_wrong_device_function_call)
2193  << HostDevTy << 0;
2194  Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(),
2195  diag::note_omp_marked_device_type_here)
2196  << HostDevTy;
2197  continue;
2198  }
2199  if (!LangOpts.OpenMPIsDevice && DevTy &&
2200  *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2201  // Diagnose nohost function called during host codegen.
2202  StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
2203  OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2204  Diag(Callee.second, diag::err_omp_wrong_device_function_call)
2205  << NoHostDevTy << 1;
2206  Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(),
2207  diag::note_omp_marked_device_type_here)
2208  << NoHostDevTy;
2209  continue;
2210  }
2211  }
2212  }
2213 }
2214 
2216  const DeclarationNameInfo &DirName,
2217  Scope *CurScope, SourceLocation Loc) {
2218  DSAStack->push(DKind, DirName, CurScope, Loc);
2219  PushExpressionEvaluationContext(
2220  ExpressionEvaluationContext::PotentiallyEvaluated);
2221 }
2222 
2224  DSAStack->setClauseParsingMode(K);
2225 }
2226 
2228  DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
2229 }
2230 
2231 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
2232  ArrayRef<OMPClause *> Clauses);
2233 static std::pair<ValueDecl *, bool>
2234 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
2235  SourceRange &ERange, bool AllowArraySection = false);
2236 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2237  bool WithInit);
2238 
2239 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
2240  // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
2241  // A variable of class type (or array thereof) that appears in a lastprivate
2242  // clause requires an accessible, unambiguous default constructor for the
2243  // class type, unless the list item is also specified in a firstprivate
2244  // clause.
2245  if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2246  for (OMPClause *C : D->clauses()) {
2247  if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2248  SmallVector<Expr *, 8> PrivateCopies;
2249  for (Expr *DE : Clause->varlists()) {
2250  if (DE->isValueDependent() || DE->isTypeDependent()) {
2251  PrivateCopies.push_back(nullptr);
2252  continue;
2253  }
2254  auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2255  auto *VD = cast<VarDecl>(DRE->getDecl());
2256  QualType Type = VD->getType().getNonReferenceType();
2257  const DSAStackTy::DSAVarData DVar =
2258  DSAStack->getTopDSA(VD, /*FromParent=*/false);
2259  if (DVar.CKind == OMPC_lastprivate) {
2260  // Generate helper private variable and initialize it with the
2261  // default value. The address of the original variable is replaced
2262  // by the address of the new private variable in CodeGen. This new
2263  // variable is not added to IdResolver, so the code in the OpenMP
2264  // region uses original variable for proper diagnostics.
2265  VarDecl *VDPrivate = buildVarDecl(
2266  *this, DE->getExprLoc(), Type.getUnqualifiedType(),
2267  VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
2268  ActOnUninitializedDecl(VDPrivate);
2269  if (VDPrivate->isInvalidDecl()) {
2270  PrivateCopies.push_back(nullptr);
2271  continue;
2272  }
2273  PrivateCopies.push_back(buildDeclRefExpr(
2274  *this, VDPrivate, DE->getType(), DE->getExprLoc()));
2275  } else {
2276  // The variable is also a firstprivate, so initialization sequence
2277  // for private copy is generated already.
2278  PrivateCopies.push_back(nullptr);
2279  }
2280  }
2281  Clause->setPrivateCopies(PrivateCopies);
2282  continue;
2283  }
2284  // Finalize nontemporal clause by handling private copies, if any.
2285  if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) {
2286  SmallVector<Expr *, 8> PrivateRefs;
2287  for (Expr *RefExpr : Clause->varlists()) {
2288  assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
2289  SourceLocation ELoc;
2290  SourceRange ERange;
2291  Expr *SimpleRefExpr = RefExpr;
2292  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
2293  if (Res.second)
2294  // It will be analyzed later.
2295  PrivateRefs.push_back(RefExpr);
2296  ValueDecl *D = Res.first;
2297  if (!D)
2298  continue;
2299 
2300  const DSAStackTy::DSAVarData DVar =
2301  DSAStack->getTopDSA(D, /*FromParent=*/false);
2302  PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2303  : SimpleRefExpr);
2304  }
2305  Clause->setPrivateRefs(PrivateRefs);
2306  continue;
2307  }
2308  }
2309  // Check allocate clauses.
2310  if (!CurContext->isDependentContext())
2311  checkAllocateClauses(*this, DSAStack, D->clauses());
2312  }
2313 
2314  DSAStack->pop();
2315  DiscardCleanupsInEvaluationContext();
2316  PopExpressionEvaluationContext();
2317 }
2318 
2319 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
2320  Expr *NumIterations, Sema &SemaRef,
2321  Scope *S, DSAStackTy *Stack);
2322 
2323 namespace {
2324 
2325 class VarDeclFilterCCC final : public CorrectionCandidateCallback {
2326 private:
2327  Sema &SemaRef;
2328 
2329 public:
2330  explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
2331  bool ValidateCandidate(const TypoCorrection &Candidate) override {
2332  NamedDecl *ND = Candidate.getCorrectionDecl();
2333  if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
2334  return VD->hasGlobalStorage() &&
2335  SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2336  SemaRef.getCurScope());
2337  }
2338  return false;
2339  }
2340 
2341  std::unique_ptr<CorrectionCandidateCallback> clone() override {
2342  return std::make_unique<VarDeclFilterCCC>(*this);
2343  }
2344 
2345 };
2346 
2347 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
2348 private:
2349  Sema &SemaRef;
2350 
2351 public:
2352  explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
2353  bool ValidateCandidate(const TypoCorrection &Candidate) override {
2354  NamedDecl *ND = Candidate.getCorrectionDecl();
2355  if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
2356  isa<FunctionDecl>(ND))) {
2357  return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2358  SemaRef.getCurScope());
2359  }
2360  return false;
2361  }
2362 
2363  std::unique_ptr<CorrectionCandidateCallback> clone() override {
2364  return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
2365  }
2366 };
2367 
2368 } // namespace
2369 
2371  CXXScopeSpec &ScopeSpec,
2372  const DeclarationNameInfo &Id,
2374  LookupResult Lookup(*this, Id, LookupOrdinaryName);
2375  LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
2376 
2377  if (Lookup.isAmbiguous())
2378  return ExprError();
2379 
2380  VarDecl *VD;
2381  if (!Lookup.isSingleResult()) {
2382  VarDeclFilterCCC CCC(*this);
2383  if (TypoCorrection Corrected =
2384  CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
2385  CTK_ErrorRecovery)) {
2386  diagnoseTypo(Corrected,
2387  PDiag(Lookup.empty()
2388  ? diag::err_undeclared_var_use_suggest
2389  : diag::err_omp_expected_var_arg_suggest)
2390  << Id.getName());
2391  VD = Corrected.getCorrectionDeclAs<VarDecl>();
2392  } else {
2393  Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
2394  : diag::err_omp_expected_var_arg)
2395  << Id.getName();
2396  return ExprError();
2397  }
2398  } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
2399  Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
2400  Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
2401  return ExprError();
2402  }
2403  Lookup.suppressDiagnostics();
2404 
2405  // OpenMP [2.9.2, Syntax, C/C++]
2406  // Variables must be file-scope, namespace-scope, or static block-scope.
2407  if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
2408  Diag(Id.getLoc(), diag::err_omp_global_var_arg)
2409  << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
2410  bool IsDecl =
2412  Diag(VD->getLocation(),
2413  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2414  << VD;
2415  return ExprError();
2416  }
2417 
2418  VarDecl *CanonicalVD = VD->getCanonicalDecl();
2419  NamedDecl *ND = CanonicalVD;
2420  // OpenMP [2.9.2, Restrictions, C/C++, p.2]
2421  // A threadprivate directive for file-scope variables must appear outside
2422  // any definition or declaration.
2423  if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
2424  !getCurLexicalContext()->isTranslationUnit()) {
2425  Diag(Id.getLoc(), diag::err_omp_var_scope)
2426  << getOpenMPDirectiveName(Kind) << VD;
2427  bool IsDecl =
2429  Diag(VD->getLocation(),
2430  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2431  << VD;
2432  return ExprError();
2433  }
2434  // OpenMP [2.9.2, Restrictions, C/C++, p.3]
2435  // A threadprivate directive for static class member variables must appear
2436  // in the class definition, in the same scope in which the member
2437  // variables are declared.
2438  if (CanonicalVD->isStaticDataMember() &&
2439  !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
2440  Diag(Id.getLoc(), diag::err_omp_var_scope)
2441  << getOpenMPDirectiveName(Kind) << VD;
2442  bool IsDecl =
2444  Diag(VD->getLocation(),
2445  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2446  << VD;
2447  return ExprError();
2448  }
2449  // OpenMP [2.9.2, Restrictions, C/C++, p.4]
2450  // A threadprivate directive for namespace-scope variables must appear
2451  // outside any definition or declaration other than the namespace
2452  // definition itself.
2453  if (CanonicalVD->getDeclContext()->isNamespace() &&
2454  (!getCurLexicalContext()->isFileContext() ||
2455  !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
2456  Diag(Id.getLoc(), diag::err_omp_var_scope)
2457  << getOpenMPDirectiveName(Kind) << VD;
2458  bool IsDecl =
2460  Diag(VD->getLocation(),
2461  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2462  << VD;
2463  return ExprError();
2464  }
2465  // OpenMP [2.9.2, Restrictions, C/C++, p.6]
2466  // A threadprivate directive for static block-scope variables must appear
2467  // in the scope of the variable and not in a nested scope.
2468  if (CanonicalVD->isLocalVarDecl() && CurScope &&
2469  !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
2470  Diag(Id.getLoc(), diag::err_omp_var_scope)
2471  << getOpenMPDirectiveName(Kind) << VD;
2472  bool IsDecl =
2474  Diag(VD->getLocation(),
2475  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2476  << VD;
2477  return ExprError();
2478  }
2479 
2480  // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
2481  // A threadprivate directive must lexically precede all references to any
2482  // of the variables in its list.
2483  if (Kind == OMPD_threadprivate && VD->isUsed() &&
2484  !DSAStack->isThreadPrivate(VD)) {
2485  Diag(Id.getLoc(), diag::err_omp_var_used)
2486  << getOpenMPDirectiveName(Kind) << VD;
2487  return ExprError();
2488  }
2489 
2490  QualType ExprType = VD->getType().getNonReferenceType();
2491  return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
2492  SourceLocation(), VD,
2493  /*RefersToEnclosingVariableOrCapture=*/false,
2494  Id.getLoc(), ExprType, VK_LValue);
2495 }
2496 
2499  ArrayRef<Expr *> VarList) {
2500  if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
2501  CurContext->addDecl(D);
2502  return DeclGroupPtrTy::make(DeclGroupRef(D));
2503  }
2504  return nullptr;
2505 }
2506 
2507 namespace {
2508 class LocalVarRefChecker final
2509  : public ConstStmtVisitor<LocalVarRefChecker, bool> {
2510  Sema &SemaRef;
2511 
2512 public:
2513  bool VisitDeclRefExpr(const DeclRefExpr *E) {
2514  if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
2515  if (VD->hasLocalStorage()) {
2516  SemaRef.Diag(E->getBeginLoc(),
2517  diag::err_omp_local_var_in_threadprivate_init)
2518  << E->getSourceRange();
2519  SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
2520  << VD << VD->getSourceRange();
2521  return true;
2522  }
2523  }
2524  return false;
2525  }
2526  bool VisitStmt(const Stmt *S) {
2527  for (const Stmt *Child : S->children()) {
2528  if (Child && Visit(Child))
2529  return true;
2530  }
2531  return false;
2532  }
2533  explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
2534 };
2535 } // namespace
2536 
2540  for (Expr *RefExpr : VarList) {
2541  auto *DE = cast<DeclRefExpr>(RefExpr);
2542  auto *VD = cast<VarDecl>(DE->getDecl());
2543  SourceLocation ILoc = DE->getExprLoc();
2544 
2545  // Mark variable as used.
2546  VD->setReferenced();
2547  VD->markUsed(Context);
2548 
2549  QualType QType = VD->getType();
2550  if (QType->isDependentType() || QType->isInstantiationDependentType()) {
2551  // It will be analyzed later.
2552  Vars.push_back(DE);
2553  continue;
2554  }
2555 
2556  // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2557  // A threadprivate variable must not have an incomplete type.
2558  if (RequireCompleteType(ILoc, VD->getType(),
2559  diag::err_omp_threadprivate_incomplete_type)) {
2560  continue;
2561  }
2562 
2563  // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2564  // A threadprivate variable must not have a reference type.
2565  if (VD->getType()->isReferenceType()) {
2566  Diag(ILoc, diag::err_omp_ref_type_arg)
2567  << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
2568  bool IsDecl =
2569  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2570  Diag(VD->getLocation(),
2571  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2572  << VD;
2573  continue;
2574  }
2575 
2576  // Check if this is a TLS variable. If TLS is not being supported, produce
2577  // the corresponding diagnostic.
2578  if ((VD->getTLSKind() != VarDecl::TLS_None &&
2579  !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
2580  getLangOpts().OpenMPUseTLS &&
2581  getASTContext().getTargetInfo().isTLSSupported())) ||
2582  (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
2583  !VD->isLocalVarDecl())) {
2584  Diag(ILoc, diag::err_omp_var_thread_local)
2585  << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
2586  bool IsDecl =
2587  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2588  Diag(VD->getLocation(),
2589  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2590  << VD;
2591  continue;
2592  }
2593 
2594  // Check if initial value of threadprivate variable reference variable with
2595  // local storage (it is not supported by runtime).
2596  if (const Expr *Init = VD->getAnyInitializer()) {
2597  LocalVarRefChecker Checker(*this);
2598  if (Checker.Visit(Init))
2599  continue;
2600  }
2601 
2602  Vars.push_back(RefExpr);
2603  DSAStack->addDSA(VD, DE, OMPC_threadprivate);
2604  VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
2605  Context, SourceRange(Loc, Loc)));
2606  if (ASTMutationListener *ML = Context.getASTMutationListener())
2607  ML->DeclarationMarkedOpenMPThreadPrivate(VD);
2608  }
2609  OMPThreadPrivateDecl *D = nullptr;
2610  if (!Vars.empty()) {
2611  D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
2612  Vars);
2613  D->setAccess(AS_public);
2614  }
2615  return D;
2616 }
2617 
2618 static OMPAllocateDeclAttr::AllocatorTypeTy
2619 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
2620  if (!Allocator)
2621  return OMPAllocateDeclAttr::OMPDefaultMemAlloc;
2622  if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
2623  Allocator->isInstantiationDependent() ||
2624  Allocator->containsUnexpandedParameterPack())
2625  return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
2626  auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
2627  const Expr *AE = Allocator->IgnoreParenImpCasts();
2628  for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc;
2629  I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
2630  auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
2631  const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
2632  llvm::FoldingSetNodeID AEId, DAEId;
2633  AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
2634  DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true);
2635  if (AEId == DAEId) {
2636  AllocatorKindRes = AllocatorKind;
2637  break;
2638  }
2639  }
2640  return AllocatorKindRes;
2641 }
2642 
2644  Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
2645  OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
2646  if (!VD->hasAttr<OMPAllocateDeclAttr>())
2647  return false;
2648  const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
2649  Expr *PrevAllocator = A->getAllocator();
2650  OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
2651  getAllocatorKind(S, Stack, PrevAllocator);
2652  bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
2653  if (AllocatorsMatch &&
2654  AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
2655  Allocator && PrevAllocator) {
2656  const Expr *AE = Allocator->IgnoreParenImpCasts();
2657  const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
2658  llvm::FoldingSetNodeID AEId, PAEId;
2659  AE->Profile(AEId, S.Context, /*Canonical=*/true);
2660  PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
2661  AllocatorsMatch = AEId == PAEId;
2662  }
2663  if (!AllocatorsMatch) {
2664  SmallString<256> AllocatorBuffer;
2665  llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
2666  if (Allocator)
2667  Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
2668  SmallString<256> PrevAllocatorBuffer;
2669  llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
2670  if (PrevAllocator)
2671  PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
2672  S.getPrintingPolicy());
2673 
2674  SourceLocation AllocatorLoc =
2675  Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
2676  SourceRange AllocatorRange =
2677  Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
2678  SourceLocation PrevAllocatorLoc =
2679  PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
2680  SourceRange PrevAllocatorRange =
2681  PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
2682  S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
2683  << (Allocator ? 1 : 0) << AllocatorStream.str()
2684  << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
2685  << AllocatorRange;
2686  S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
2687  << PrevAllocatorRange;
2688  return true;
2689  }
2690  return false;
2691 }
2692 
2693 static void
2695  OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
2696  Expr *Allocator, SourceRange SR) {
2697  if (VD->hasAttr<OMPAllocateDeclAttr>())
2698  return;
2699  if (Allocator &&
2700  (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
2701  Allocator->isInstantiationDependent() ||
2702  Allocator->containsUnexpandedParameterPack()))
2703  return;
2704  auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
2705  Allocator, SR);
2706  VD->addAttr(A);
2708  ML->DeclarationMarkedOpenMPAllocate(VD, A);
2709 }
2710 
2712  SourceLocation Loc, ArrayRef<Expr *> VarList,
2713  ArrayRef<OMPClause *> Clauses, DeclContext *Owner) {
2714  assert(Clauses.size() <= 1 && "Expected at most one clause.");
2715  Expr *Allocator = nullptr;
2716  if (Clauses.empty()) {
2717  // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
2718  // allocate directives that appear in a target region must specify an
2719  // allocator clause unless a requires directive with the dynamic_allocators
2720  // clause is present in the same compilation unit.
2721  if (LangOpts.OpenMPIsDevice &&
2722  !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
2723  targetDiag(Loc, diag::err_expected_allocator_clause);
2724  } else {
2725  Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator();
2726  }
2727  OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
2728  getAllocatorKind(*this, DSAStack, Allocator);
2730  for (Expr *RefExpr : VarList) {
2731  auto *DE = cast<DeclRefExpr>(RefExpr);
2732  auto *VD = cast<VarDecl>(DE->getDecl());
2733 
2734  // Check if this is a TLS variable or global register.
2735  if (VD->getTLSKind() != VarDecl::TLS_None ||
2736  VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
2737  (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
2738  !VD->isLocalVarDecl()))
2739  continue;
2740 
2741  // If the used several times in the allocate directive, the same allocator
2742  // must be used.
2743  if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD,
2744  AllocatorKind, Allocator))
2745  continue;
2746 
2747  // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
2748  // If a list item has a static storage type, the allocator expression in the
2749  // allocator clause must be a constant expression that evaluates to one of
2750  // the predefined memory allocator values.
2751  if (Allocator && VD->hasGlobalStorage()) {
2752  if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
2753  Diag(Allocator->getExprLoc(),
2754  diag::err_omp_expected_predefined_allocator)
2755  << Allocator->getSourceRange();
2756  bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
2758  Diag(VD->getLocation(),
2759  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2760  << VD;
2761  continue;
2762  }
2763  }
2764 
2765  Vars.push_back(RefExpr);
2766  applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator,
2767  DE->getSourceRange());
2768  }
2769  if (Vars.empty())
2770  return nullptr;
2771  if (!Owner)
2772  Owner = getCurLexicalContext();
2773  auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
2774  D->setAccess(AS_public);
2775  Owner->addDecl(D);
2776  return DeclGroupPtrTy::make(DeclGroupRef(D));
2777 }
2778 
2781  ArrayRef<OMPClause *> ClauseList) {
2782  OMPRequiresDecl *D = nullptr;
2783  if (!CurContext->isFileContext()) {
2784  Diag(Loc, diag::err_omp_invalid_scope) << "requires";
2785  } else {
2786  D = CheckOMPRequiresDecl(Loc, ClauseList);
2787  if (D) {
2788  CurContext->addDecl(D);
2789  DSAStack->addRequiresDecl(D);
2790  }
2791  }
2792  return DeclGroupPtrTy::make(DeclGroupRef(D));
2793 }
2794 
2796  ArrayRef<OMPClause *> ClauseList) {
2797  /// For target specific clauses, the requires directive cannot be
2798  /// specified after the handling of any of the target regions in the
2799  /// current compilation unit.
2800  ArrayRef<SourceLocation> TargetLocations =
2801  DSAStack->getEncounteredTargetLocs();
2802  if (!TargetLocations.empty()) {
2803  for (const OMPClause *CNew : ClauseList) {
2804  // Check if any of the requires clauses affect target regions.
2805  if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
2806  isa<OMPUnifiedAddressClause>(CNew) ||
2807  isa<OMPReverseOffloadClause>(CNew) ||
2808  isa<OMPDynamicAllocatorsClause>(CNew)) {
2809  Diag(Loc, diag::err_omp_target_before_requires)
2810  << getOpenMPClauseName(CNew->getClauseKind());
2811  for (SourceLocation TargetLoc : TargetLocations) {
2812  Diag(TargetLoc, diag::note_omp_requires_encountered_target);
2813  }
2814  }
2815  }
2816  }
2817 
2818  if (!DSAStack->hasDuplicateRequiresClause(ClauseList))
2819  return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
2820  ClauseList);
2821  return nullptr;
2822 }
2823 
2824 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2825  const ValueDecl *D,
2826  const DSAStackTy::DSAVarData &DVar,
2827  bool IsLoopIterVar = false) {
2828  if (DVar.RefExpr) {
2829  SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
2830  << getOpenMPClauseName(DVar.CKind);
2831  return;
2832  }
2833  enum {
2834  PDSA_StaticMemberShared,
2835  PDSA_StaticLocalVarShared,
2836  PDSA_LoopIterVarPrivate,
2837  PDSA_LoopIterVarLinear,
2838  PDSA_LoopIterVarLastprivate,
2839  PDSA_ConstVarShared,
2840  PDSA_GlobalVarShared,
2841  PDSA_TaskVarFirstprivate,
2842  PDSA_LocalVarPrivate,
2843  PDSA_Implicit
2844  } Reason = PDSA_Implicit;
2845  bool ReportHint = false;
2846  auto ReportLoc = D->getLocation();
2847  auto *VD = dyn_cast<VarDecl>(D);
2848  if (IsLoopIterVar) {
2849  if (DVar.CKind == OMPC_private)
2850  Reason = PDSA_LoopIterVarPrivate;
2851  else if (DVar.CKind == OMPC_lastprivate)
2852  Reason = PDSA_LoopIterVarLastprivate;
2853  else
2854  Reason = PDSA_LoopIterVarLinear;
2855  } else if (isOpenMPTaskingDirective(DVar.DKind) &&
2856  DVar.CKind == OMPC_firstprivate) {
2857  Reason = PDSA_TaskVarFirstprivate;
2858  ReportLoc = DVar.ImplicitDSALoc;
2859  } else if (VD && VD->isStaticLocal())
2860  Reason = PDSA_StaticLocalVarShared;
2861  else if (VD && VD->isStaticDataMember())
2862  Reason = PDSA_StaticMemberShared;
2863  else if (VD && VD->isFileVarDecl())
2864  Reason = PDSA_GlobalVarShared;
2865  else if (D->getType().isConstant(SemaRef.getASTContext()))
2866  Reason = PDSA_ConstVarShared;
2867  else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
2868  ReportHint = true;
2869  Reason = PDSA_LocalVarPrivate;
2870  }
2871  if (Reason != PDSA_Implicit) {
2872  SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
2873  << Reason << ReportHint
2874  << getOpenMPDirectiveName(Stack->getCurrentDirective());
2875  } else if (DVar.ImplicitDSALoc.isValid()) {
2876  SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
2877  << getOpenMPClauseName(DVar.CKind);
2878  }
2879 }
2880 
2881 static OpenMPMapClauseKind
2883  bool IsAggregateOrDeclareTarget) {
2885  switch (M) {
2886  case OMPC_DEFAULTMAP_MODIFIER_alloc:
2887  Kind = OMPC_MAP_alloc;
2888  break;
2889  case OMPC_DEFAULTMAP_MODIFIER_to:
2890  Kind = OMPC_MAP_to;
2891  break;
2892  case OMPC_DEFAULTMAP_MODIFIER_from:
2893  Kind = OMPC_MAP_from;
2894  break;
2895  case OMPC_DEFAULTMAP_MODIFIER_tofrom:
2896  Kind = OMPC_MAP_tofrom;
2897  break;
2898  case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
2900  llvm_unreachable("Unexpected defaultmap implicit behavior");
2901  case OMPC_DEFAULTMAP_MODIFIER_none:
2902  case OMPC_DEFAULTMAP_MODIFIER_default:
2904  // IsAggregateOrDeclareTarget could be true if:
2905  // 1. the implicit behavior for aggregate is tofrom
2906  // 2. it's a declare target link
2907  if (IsAggregateOrDeclareTarget) {
2908  Kind = OMPC_MAP_tofrom;
2909  break;
2910  }
2911  llvm_unreachable("Unexpected defaultmap implicit behavior");
2912  }
2913  assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known");
2914  return Kind;
2915 }
2916 
2917 namespace {
2918 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
2919  DSAStackTy *Stack;
2920  Sema &SemaRef;
2921  bool ErrorFound = false;
2922  bool TryCaptureCXXThisMembers = false;
2923  CapturedStmt *CS = nullptr;
2924  llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
2925  llvm::SmallVector<Expr *, 4> ImplicitMap[OMPC_MAP_delete];
2926  Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
2927  llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
2928 
2929  void VisitSubCaptures(OMPExecutableDirective *S) {
2930  // Check implicitly captured variables.
2931  if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
2932  return;
2933  visitSubCaptures(S->getInnermostCapturedStmt());
2934  // Try to capture inner this->member references to generate correct mappings
2935  // and diagnostics.
2936  if (TryCaptureCXXThisMembers ||
2937  (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
2938  llvm::any_of(S->getInnermostCapturedStmt()->captures(),
2939  [](const CapturedStmt::Capture &C) {
2940  return C.capturesThis();
2941  }))) {
2942  bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
2943  TryCaptureCXXThisMembers = true;
2945  TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
2946  }
2947  }
2948 
2949 public:
2950  void VisitDeclRefExpr(DeclRefExpr *E) {
2951  if (TryCaptureCXXThisMembers || E->isTypeDependent() ||
2954  return;
2955  if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
2956  // Check the datasharing rules for the expressions in the clauses.
2957  if (!CS) {
2958  if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
2959  if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
2960  Visit(CED->getInit());
2961  return;
2962  }
2963  } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
2964  // Do not analyze internal variables and do not enclose them into
2965  // implicit clauses.
2966  return;
2967  VD = VD->getCanonicalDecl();
2968  // Skip internally declared variables.
2969  if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD))
2970  return;
2971 
2972  DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
2973  // Check if the variable has explicit DSA set and stop analysis if it so.
2974  if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
2975  return;
2976 
2977  // Skip internally declared static variables.
2979  OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
2980  if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
2981  (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
2982  !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link))
2983  return;
2984 
2985  SourceLocation ELoc = E->getExprLoc();
2986  OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
2987  // The default(none) clause requires that each variable that is referenced
2988  // in the construct, and does not have a predetermined data-sharing
2989  // attribute, must have its data-sharing attribute explicitly determined
2990  // by being listed in a data-sharing attribute clause.
2991  if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none &&
2992  isImplicitOrExplicitTaskingRegion(DKind) &&
2993  VarsWithInheritedDSA.count(VD) == 0) {
2994  VarsWithInheritedDSA[VD] = E;
2995  return;
2996  }
2997 
2998  // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description]
2999  // If implicit-behavior is none, each variable referenced in the
3000  // construct that does not have a predetermined data-sharing attribute
3001  // and does not appear in a to or link clause on a declare target
3002  // directive must be listed in a data-mapping attribute clause, a
3003  // data-haring attribute clause (including a data-sharing attribute
3004  // clause on a combined construct where target. is one of the
3005  // constituent constructs), or an is_device_ptr clause.
3006  OpenMPDefaultmapClauseKind ClauseKind =
3008  if (SemaRef.getLangOpts().OpenMP >= 50) {
3009  bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3010  OMPC_DEFAULTMAP_MODIFIER_none;
3011  if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3012  VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3013  // Only check for data-mapping attribute and is_device_ptr here
3014  // since we have already make sure that the declaration does not
3015  // have a data-sharing attribute above
3016  if (!Stack->checkMappableExprComponentListsForDecl(
3017  VD, /*CurrentRegionOnly=*/true,
3019  MapExprComponents,
3020  OpenMPClauseKind) {
3021  auto MI = MapExprComponents.rbegin();
3022  auto ME = MapExprComponents.rend();
3023  return MI != ME && MI->getAssociatedDeclaration() == VD;
3024  })) {
3025  VarsWithInheritedDSA[VD] = E;
3026  return;
3027  }
3028  }
3029  }
3030 
3031  if (isOpenMPTargetExecutionDirective(DKind) &&
3032  !Stack->isLoopControlVariable(VD).first) {
3033  if (!Stack->checkMappableExprComponentListsForDecl(
3034  VD, /*CurrentRegionOnly=*/true,
3036  StackComponents,
3037  OpenMPClauseKind) {
3038  // Variable is used if it has been marked as an array, array
3039  // section or the variable iself.
3040  return StackComponents.size() == 1 ||
3041  std::all_of(
3042  std::next(StackComponents.rbegin()),
3043  StackComponents.rend(),
3044  [](const OMPClauseMappableExprCommon::
3045  MappableComponent &MC) {
3046  return MC.getAssociatedDeclaration() ==
3047  nullptr &&
3048  (isa<OMPArraySectionExpr>(
3049  MC.getAssociatedExpression()) ||
3050  isa<ArraySubscriptExpr>(
3051  MC.getAssociatedExpression()));
3052  });
3053  })) {
3054  bool IsFirstprivate = false;
3055  // By default lambdas are captured as firstprivates.
3056  if (const auto *RD =
3057  VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
3058  IsFirstprivate = RD->isLambda();
3059  IsFirstprivate =
3060  IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3061  if (IsFirstprivate) {
3062  ImplicitFirstprivate.emplace_back(E);
3063  } else {
3065  Stack->getDefaultmapModifier(ClauseKind);
3067  M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3068  ImplicitMap[Kind].emplace_back(E);
3069  }
3070  return;
3071  }
3072  }
3073 
3074  // OpenMP [2.9.3.6, Restrictions, p.2]
3075  // A list item that appears in a reduction clause of the innermost
3076  // enclosing worksharing or parallel construct may not be accessed in an
3077  // explicit task.
3078  DVar = Stack->hasInnermostDSA(
3079  VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
3080  [](OpenMPDirectiveKind K) {
3081  return isOpenMPParallelDirective(K) ||
3083  },
3084  /*FromParent=*/true);
3085  if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3086  ErrorFound = true;
3087  SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3088  reportOriginalDsa(SemaRef, Stack, VD, DVar);
3089  return;
3090  }
3091 
3092  // Define implicit data-sharing attributes for task.
3093  DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
3094  if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
3095  !Stack->isLoopControlVariable(VD).first) {
3096  ImplicitFirstprivate.push_back(E);
3097  return;
3098  }
3099 
3100  // Store implicitly used globals with declare target link for parent
3101  // target.
3102  if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
3103  *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3104  Stack->addToParentTargetRegionLinkGlobals(E);
3105  return;
3106  }
3107  }
3108  }
3109  void VisitMemberExpr(MemberExpr *E) {
3110  if (E->isTypeDependent() || E->isValueDependent() ||
3112  return;
3113  auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
3114  OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3115  if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) {
3116  if (!FD)
3117  return;
3118  DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
3119  // Check if the variable has explicit DSA set and stop analysis if it
3120  // so.
3121  if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3122  return;
3123 
3124  if (isOpenMPTargetExecutionDirective(DKind) &&
3125  !Stack->isLoopControlVariable(FD).first &&
3126  !Stack->checkMappableExprComponentListsForDecl(
3127  FD, /*CurrentRegionOnly=*/true,
3129  StackComponents,
3130  OpenMPClauseKind) {
3131  return isa<CXXThisExpr>(
3132  cast<MemberExpr>(
3133  StackComponents.back().getAssociatedExpression())
3134  ->getBase()
3135  ->IgnoreParens());
3136  })) {
3137  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
3138  // A bit-field cannot appear in a map clause.
3139  //
3140  if (FD->isBitField())
3141  return;
3142 
3143  // Check to see if the member expression is referencing a class that
3144  // has already been explicitly mapped
3145  if (Stack->isClassPreviouslyMapped(TE->getType()))
3146  return;
3147 
3149  Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3151  Modifier, /*IsAggregateOrDeclareTarget*/ true);
3152  ImplicitMap[Kind].emplace_back(E);
3153  return;
3154  }
3155 
3156  SourceLocation ELoc = E->getExprLoc();
3157  // OpenMP [2.9.3.6, Restrictions, p.2]
3158  // A list item that appears in a reduction clause of the innermost
3159  // enclosing worksharing or parallel construct may not be accessed in
3160  // an explicit task.
3161  DVar = Stack->hasInnermostDSA(
3162  FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
3163  [](OpenMPDirectiveKind K) {
3164  return isOpenMPParallelDirective(K) ||
3166  },
3167  /*FromParent=*/true);
3168  if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3169  ErrorFound = true;
3170  SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3171  reportOriginalDsa(SemaRef, Stack, FD, DVar);
3172  return;
3173  }
3174 
3175  // Define implicit data-sharing attributes for task.
3176  DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
3177  if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
3178  !Stack->isLoopControlVariable(FD).first) {
3179  // Check if there is a captured expression for the current field in the
3180  // region. Do not mark it as firstprivate unless there is no captured
3181  // expression.
3182  // TODO: try to make it firstprivate.
3183  if (DVar.CKind != OMPC_unknown)
3184  ImplicitFirstprivate.push_back(E);
3185  }
3186  return;
3187  }
3188  if (isOpenMPTargetExecutionDirective(DKind)) {
3190  if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
3191  /*NoDiagnose=*/true))
3192  return;
3193  const auto *VD = cast<ValueDecl>(
3194  CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
3195  if (!Stack->checkMappableExprComponentListsForDecl(
3196  VD, /*CurrentRegionOnly=*/true,
3197  [&CurComponents](
3199  StackComponents,
3200  OpenMPClauseKind) {
3201  auto CCI = CurComponents.rbegin();
3202  auto CCE = CurComponents.rend();
3203  for (const auto &SC : llvm::reverse(StackComponents)) {
3204  // Do both expressions have the same kind?
3205  if (CCI->getAssociatedExpression()->getStmtClass() !=
3206  SC.getAssociatedExpression()->getStmtClass())
3207  if (!(isa<OMPArraySectionExpr>(
3208  SC.getAssociatedExpression()) &&
3209  isa<ArraySubscriptExpr>(
3210  CCI->getAssociatedExpression())))
3211  return false;
3212 
3213  const Decl *CCD = CCI->getAssociatedDeclaration();
3214  const Decl *SCD = SC.getAssociatedDeclaration();
3215  CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
3216  SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
3217  if (SCD != CCD)
3218  return false;
3219  std::advance(CCI, 1);
3220  if (CCI == CCE)
3221  break;
3222  }
3223  return true;
3224  })) {
3225  Visit(E->getBase());
3226  }
3227  } else if (!TryCaptureCXXThisMembers) {
3228  Visit(E->getBase());
3229  }
3230  }
3231  void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
3232  for (OMPClause *C : S->clauses()) {
3233  // Skip analysis of arguments of implicitly defined firstprivate clause
3234  // for task|target directives.
3235  // Skip analysis of arguments of implicitly defined map clause for target
3236  // directives.
3237  if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
3238  C->isImplicit())) {
3239  for (Stmt *CC : C->children()) {
3240  if (CC)
3241  Visit(CC);
3242  }
3243  }
3244  }
3245  // Check implicitly captured variables.
3246  VisitSubCaptures(S);
3247  }
3248  void VisitStmt(Stmt *S) {
3249  for (Stmt *C : S->children()) {
3250  if (C) {
3251  // Check implicitly captured variables in the task-based directives to
3252  // check if they must be firstprivatized.
3253  Visit(C);
3254  }
3255  }
3256  }
3257 
3258  void visitSubCaptures(CapturedStmt *S) {
3259  for (const CapturedStmt::Capture &Cap : S->captures()) {
3260  if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
3261  continue;
3262  VarDecl *VD = Cap.getCapturedVar();
3263  // Do not try to map the variable if it or its sub-component was mapped
3264  // already.
3265  if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3266  Stack->checkMappableExprComponentListsForDecl(
3267  VD, /*CurrentRegionOnly=*/true,
3269  OpenMPClauseKind) { return true; }))
3270  continue;
3272  SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
3273  Cap.getLocation(), /*RefersToCapture=*/true);
3274  Visit(DRE);
3275  }
3276  }
3277  bool isErrorFound() const { return ErrorFound; }
3278  ArrayRef<Expr *> getImplicitFirstprivate() const {
3279  return ImplicitFirstprivate;
3280  }
3281  ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const {
3282  return ImplicitMap[Kind];
3283  }
3284  const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
3285  return VarsWithInheritedDSA;
3286  }
3287 
3288  DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
3289  : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
3290  // Process declare target link variables for the target directives.
3291  if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
3292  for (DeclRefExpr *E : Stack->getLinkGlobals())
3293  Visit(E);
3294  }
3295  }
3296 };
3297 } // namespace
3298 
3300  switch (DKind) {
3301  case OMPD_parallel:
3302  case OMPD_parallel_for:
3303  case OMPD_parallel_for_simd:
3304  case OMPD_parallel_sections:
3305  case OMPD_parallel_master:
3306  case OMPD_teams:
3307  case OMPD_teams_distribute:
3308  case OMPD_teams_distribute_simd: {
3309  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3310  QualType KmpInt32PtrTy =
3311  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3312  Sema::CapturedParamNameType Params[] = {
3313  std::make_pair(".global_tid.", KmpInt32PtrTy),
3314  std::make_pair(".bound_tid.", KmpInt32PtrTy),
3315  std::make_pair(StringRef(), QualType()) // __context with shared vars
3316  };
3317  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3318  Params);
3319  break;
3320  }
3321  case OMPD_target_teams:
3322  case OMPD_target_parallel:
3323  case OMPD_target_parallel_for:
3324  case OMPD_target_parallel_for_simd:
3325  case OMPD_target_teams_distribute:
3326  case OMPD_target_teams_distribute_simd: {
3327  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3328  QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3329  QualType KmpInt32PtrTy =
3330  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3331  QualType Args[] = {VoidPtrTy};
3333  EPI.Variadic = true;
3334  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3335  Sema::CapturedParamNameType Params[] = {
3336  std::make_pair(".global_tid.", KmpInt32Ty),
3337  std::make_pair(".part_id.", KmpInt32PtrTy),
3338  std::make_pair(".privates.", VoidPtrTy),
3339  std::make_pair(
3340  ".copy_fn.",
3341  Context.getPointerType(CopyFnType).withConst().withRestrict()),
3342  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3343  std::make_pair(StringRef(), QualType()) // __context with shared vars
3344  };
3345  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3346  Params, /*OpenMPCaptureLevel=*/0);
3347  // Mark this captured region as inlined, because we don't use outlined
3348  // function directly.
3349  getCurCapturedRegion()->TheCapturedDecl->addAttr(
3350  AlwaysInlineAttr::CreateImplicit(
3351  Context, {}, AttributeCommonInfo::AS_Keyword,
3352  AlwaysInlineAttr::Keyword_forceinline));
3353  Sema::CapturedParamNameType ParamsTarget[] = {
3354  std::make_pair(StringRef(), QualType()) // __context with shared vars
3355  };
3356  // Start a captured region for 'target' with no implicit parameters.
3357  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3358  ParamsTarget, /*OpenMPCaptureLevel=*/1);
3359  Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
3360  std::make_pair(".global_tid.", KmpInt32PtrTy),
3361  std::make_pair(".bound_tid.", KmpInt32PtrTy),
3362  std::make_pair(StringRef(), QualType()) // __context with shared vars
3363  };
3364  // Start a captured region for 'teams' or 'parallel'. Both regions have
3365  // the same implicit parameters.
3366  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3367  ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
3368  break;
3369  }
3370  case OMPD_target:
3371  case OMPD_target_simd: {
3372  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3373  QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3374  QualType KmpInt32PtrTy =
3375  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3376  QualType Args[] = {VoidPtrTy};
3378  EPI.Variadic = true;
3379  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3380  Sema::CapturedParamNameType Params[] = {
3381  std::make_pair(".global_tid.", KmpInt32Ty),
3382  std::make_pair(".part_id.", KmpInt32PtrTy),
3383  std::make_pair(".privates.", VoidPtrTy),
3384  std::make_pair(
3385  ".copy_fn.",
3386  Context.getPointerType(CopyFnType).withConst().withRestrict()),
3387  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3388  std::make_pair(StringRef(), QualType()) // __context with shared vars
3389  };
3390  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3391  Params, /*OpenMPCaptureLevel=*/0);
3392  // Mark this captured region as inlined, because we don't use outlined
3393  // function directly.
3394  getCurCapturedRegion()->TheCapturedDecl->addAttr(
3395  AlwaysInlineAttr::CreateImplicit(
3396  Context, {}, AttributeCommonInfo::AS_Keyword,
3397  AlwaysInlineAttr::Keyword_forceinline));
3398  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3399  std::make_pair(StringRef(), QualType()),
3400  /*OpenMPCaptureLevel=*/1);
3401  break;
3402  }
3403  case OMPD_simd:
3404  case OMPD_for:
3405  case OMPD_for_simd:
3406  case OMPD_sections:
3407  case OMPD_section:
3408  case OMPD_single:
3409  case OMPD_master:
3410  case OMPD_critical:
3411  case OMPD_taskgroup:
3412  case OMPD_distribute:
3413  case OMPD_distribute_simd:
3414  case OMPD_ordered:
3415  case OMPD_atomic:
3416  case OMPD_target_data: {
3417  Sema::CapturedParamNameType Params[] = {
3418  std::make_pair(StringRef(), QualType()) // __context with shared vars
3419  };
3420  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3421  Params);
3422  break;
3423  }
3424  case OMPD_task: {
3425  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3426  QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3427  QualType KmpInt32PtrTy =
3428  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3429  QualType Args[] = {VoidPtrTy};
3431  EPI.Variadic = true;
3432  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3433  Sema::CapturedParamNameType Params[] = {
3434  std::make_pair(".global_tid.", KmpInt32Ty),
3435  std::make_pair(".part_id.", KmpInt32PtrTy),
3436  std::make_pair(".privates.", VoidPtrTy),
3437  std::make_pair(
3438  ".copy_fn.",
3439  Context.getPointerType(CopyFnType).withConst().withRestrict()),
3440  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3441  std::make_pair(StringRef(), QualType()) // __context with shared vars
3442  };
3443  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3444  Params);
3445  // Mark this captured region as inlined, because we don't use outlined
3446  // function directly.
3447  getCurCapturedRegion()->TheCapturedDecl->addAttr(
3448  AlwaysInlineAttr::CreateImplicit(
3449  Context, {}, AttributeCommonInfo::AS_Keyword,
3450  AlwaysInlineAttr::Keyword_forceinline));
3451  break;
3452  }
3453  case OMPD_taskloop:
3454  case OMPD_taskloop_simd:
3455  case OMPD_master_taskloop:
3456  case OMPD_master_taskloop_simd: {
3457  QualType KmpInt32Ty =
3458  Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
3459  .withConst();
3460  QualType KmpUInt64Ty =
3461  Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
3462  .withConst();
3463  QualType KmpInt64Ty =
3464  Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
3465  .withConst();
3466  QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3467  QualType KmpInt32PtrTy =
3468  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3469  QualType Args[] = {VoidPtrTy};
3471  EPI.Variadic = true;
3472  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3473  Sema::CapturedParamNameType Params[] = {
3474  std::make_pair(".global_tid.", KmpInt32Ty),
3475  std::make_pair(".part_id.", KmpInt32PtrTy),
3476  std::make_pair(".privates.", VoidPtrTy),
3477  std::make_pair(
3478  ".copy_fn.",
3479  Context.getPointerType(CopyFnType).withConst().withRestrict()),
3480  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3481  std::make_pair(".lb.", KmpUInt64Ty),
3482  std::make_pair(".ub.", KmpUInt64Ty),
3483  std::make_pair(".st.", KmpInt64Ty),
3484  std::make_pair(".liter.", KmpInt32Ty),
3485  std::make_pair(".reductions.", VoidPtrTy),
3486  std::make_pair(StringRef(), QualType()) // __context with shared vars
3487  };
3488  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3489  Params);
3490  // Mark this captured region as inlined, because we don't use outlined
3491  // function directly.
3492  getCurCapturedRegion()->TheCapturedDecl->addAttr(
3493  AlwaysInlineAttr::CreateImplicit(
3494  Context, {}, AttributeCommonInfo::AS_Keyword,
3495  AlwaysInlineAttr::Keyword_forceinline));
3496  break;
3497  }
3498  case OMPD_parallel_master_taskloop:
3499  case OMPD_parallel_master_taskloop_simd: {
3500  QualType KmpInt32Ty =
3501  Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
3502  .withConst();
3503  QualType KmpUInt64Ty =
3504  Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
3505  .withConst();
3506  QualType KmpInt64Ty =
3507  Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
3508  .withConst();
3509  QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3510  QualType KmpInt32PtrTy =
3511  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3512  Sema::CapturedParamNameType ParamsParallel[] = {
3513  std::make_pair(".global_tid.", KmpInt32PtrTy),
3514  std::make_pair(".bound_tid.", KmpInt32PtrTy),
3515  std::make_pair(StringRef(), QualType()) // __context with shared vars
3516  };
3517  // Start a captured region for 'parallel'.
3518  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3519  ParamsParallel, /*OpenMPCaptureLevel=*/1);
3520  QualType Args[] = {VoidPtrTy};
3522  EPI.Variadic = true;
3523  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3524  Sema::CapturedParamNameType Params[] = {
3525  std::make_pair(".global_tid.", KmpInt32Ty),
3526  std::make_pair(".part_id.", KmpInt32PtrTy),
3527  std::make_pair(".privates.", VoidPtrTy),
3528  std::make_pair(
3529  ".copy_fn.",
3530  Context.getPointerType(CopyFnType).withConst().withRestrict()),
3531  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3532  std::make_pair(".lb.", KmpUInt64Ty),
3533  std::make_pair(".ub.", KmpUInt64Ty),
3534  std::make_pair(".st.", KmpInt64Ty),
3535  std::make_pair(".liter.", KmpInt32Ty),
3536  std::make_pair(".reductions.", VoidPtrTy),
3537  std::make_pair(StringRef(), QualType()) // __context with shared vars
3538  };
3539  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3540  Params, /*OpenMPCaptureLevel=*/2);
3541  // Mark this captured region as inlined, because we don't use outlined
3542  // function directly.
3543  getCurCapturedRegion()->TheCapturedDecl->addAttr(
3544  AlwaysInlineAttr::CreateImplicit(
3545  Context, {}, AttributeCommonInfo::AS_Keyword,
3546  AlwaysInlineAttr::Keyword_forceinline));
3547  break;
3548  }
3549  case OMPD_distribute_parallel_for_simd:
3550  case OMPD_distribute_parallel_for: {
3551  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3552  QualType KmpInt32PtrTy =
3553  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3554  Sema::CapturedParamNameType Params[] = {
3555  std::make_pair(".global_tid.", KmpInt32PtrTy),
3556  std::make_pair(".bound_tid.", KmpInt32PtrTy),
3557  std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
3558  std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
3559  std::make_pair(StringRef(), QualType()) // __context with shared vars
3560  };
3561  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3562  Params);
3563  break;
3564  }
3565  case OMPD_target_teams_distribute_parallel_for:
3566  case OMPD_target_teams_distribute_parallel_for_simd: {
3567  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3568  QualType KmpInt32PtrTy =
3569  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3570  QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3571 
3572  QualType Args[] = {VoidPtrTy};
3574  EPI.Variadic = true;
3575  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3576  Sema::CapturedParamNameType Params[] = {
3577  std::make_pair(".global_tid.", KmpInt32Ty),
3578  std::make_pair(".part_id.", KmpInt32PtrTy),
3579  std::make_pair(".privates.", VoidPtrTy),
3580  std::make_pair(
3581  ".copy_fn.",
3582  Context.getPointerType(CopyFnType).withConst().withRestrict()),
3583  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3584  std::make_pair(StringRef(), QualType()) // __context with shared vars
3585  };
3586  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3587  Params, /*OpenMPCaptureLevel=*/0);
3588  // Mark this captured region as inlined, because we don't use outlined
3589  // function directly.
3590  getCurCapturedRegion()->TheCapturedDecl->addAttr(
3591  AlwaysInlineAttr::CreateImplicit(
3592  Context, {}, AttributeCommonInfo::AS_Keyword,
3593  AlwaysInlineAttr::Keyword_forceinline));
3594  Sema::CapturedParamNameType ParamsTarget[] = {
3595  std::make_pair(StringRef(), QualType()) // __context with shared vars
3596  };
3597  // Start a captured region for 'target' with no implicit parameters.
3598  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3599  ParamsTarget, /*OpenMPCaptureLevel=*/1);
3600 
3601  Sema::CapturedParamNameType ParamsTeams[] = {
3602  std::make_pair(".global_tid.", KmpInt32PtrTy),
3603  std::make_pair(".bound_tid.", KmpInt32PtrTy),
3604  std::make_pair(StringRef(), QualType()) // __context with shared vars
3605  };
3606  // Start a captured region for 'target' with no implicit parameters.
3607  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3608  ParamsTeams, /*OpenMPCaptureLevel=*/2);
3609 
3610  Sema::CapturedParamNameType ParamsParallel[] = {
3611  std::make_pair(".global_tid.", KmpInt32PtrTy),
3612  std::make_pair(".bound_tid.", KmpInt32PtrTy),
3613  std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
3614  std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
3615  std::make_pair(StringRef(), QualType()) // __context with shared vars
3616  };
3617  // Start a captured region for 'teams' or 'parallel'. Both regions have
3618  // the same implicit parameters.
3619  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3620  ParamsParallel, /*OpenMPCaptureLevel=*/3);
3621  break;
3622  }
3623 
3624  case OMPD_teams_distribute_parallel_for:
3625  case OMPD_teams_distribute_parallel_for_simd: {
3626  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3627  QualType KmpInt32PtrTy =
3628  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3629 
3630  Sema::CapturedParamNameType ParamsTeams[] = {
3631  std::make_pair(".global_tid.", KmpInt32PtrTy),
3632  std::make_pair(".bound_tid.", KmpInt32PtrTy),
3633  std::make_pair(StringRef(), QualType()) // __context with shared vars
3634  };
3635  // Start a captured region for 'target' with no implicit parameters.
3636  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3637  ParamsTeams, /*OpenMPCaptureLevel=*/0);
3638 
3639  Sema::CapturedParamNameType ParamsParallel[] = {
3640  std::make_pair(".global_tid.", KmpInt32PtrTy),
3641  std::make_pair(".bound_tid.", KmpInt32PtrTy),
3642  std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
3643  std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
3644  std::make_pair(StringRef(), QualType()) // __context with shared vars
3645  };
3646  // Start a captured region for 'teams' or 'parallel'. Both regions have
3647  // the same implicit parameters.
3648  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3649  ParamsParallel, /*OpenMPCaptureLevel=*/1);
3650  break;
3651  }
3652  case OMPD_target_update:
3653  case OMPD_target_enter_data:
3654  case OMPD_target_exit_data: {
3655  QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3656  QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3657  QualType KmpInt32PtrTy =
3658  Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3659  QualType Args[] = {VoidPtrTy};
3661  EPI.Variadic = true;
3662  QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3663  Sema::CapturedParamNameType Params[] = {
3664  std::make_pair(".global_tid.", KmpInt32Ty),
3665  std::make_pair(".part_id.", KmpInt32PtrTy),
3666  std::make_pair(".privates.", VoidPtrTy),
3667  std::make_pair(
3668  ".copy_fn.",
3669  Context.getPointerType(CopyFnType).withConst().withRestrict()),
3670  std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3671  std::make_pair(StringRef(), QualType()) // __context with shared vars
3672  };
3673  ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3674  Params);
3675  // Mark this captured region as inlined, because we don't use outlined
3676  // function directly.
3677  getCurCapturedRegion()->TheCapturedDecl->addAttr(
3678  AlwaysInlineAttr::CreateImplicit(
3679  Context, {}, AttributeCommonInfo::AS_Keyword,
3680  AlwaysInlineAttr::Keyword_forceinline));
3681  break;
3682  }
3683  case OMPD_threadprivate:
3684  case OMPD_allocate:
3685  case OMPD_taskyield:
3686  case OMPD_barrier:
3687  case OMPD_taskwait:
3688  case OMPD_cancellation_point:
3689  case OMPD_cancel:
3690  case OMPD_flush:
3691  case OMPD_declare_reduction:
3692  case OMPD_declare_mapper:
3693  case OMPD_declare_simd:
3694  case OMPD_declare_target:
3695  case OMPD_end_declare_target:
3696  case OMPD_requires:
3697  case OMPD_declare_variant:
3698  llvm_unreachable("OpenMP Directive is not allowed");
3699  case OMPD_unknown:
3700  llvm_unreachable("Unknown OpenMP directive");
3701  }
3702 }
3703 
3704 int Sema::getNumberOfConstructScopes(unsigned Level) const {
3705  return getOpenMPCaptureLevels(DSAStack->getDirective(Level));
3706 }
3707 
3709  SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
3710  getOpenMPCaptureRegions(CaptureRegions, DKind);
3711  return CaptureRegions.size();
3712 }
3713 
3715  Expr *CaptureExpr, bool WithInit,
3716  bool AsExpression) {
3717  assert(CaptureExpr);
3718  ASTContext &C = S.getASTContext();
3719  Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
3720  QualType Ty = Init->getType();
3721  if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
3722  if (S.getLangOpts().CPlusPlus) {
3723  Ty = C.getLValueReferenceType(Ty);
3724  } else {
3725  Ty = C.getPointerType(Ty);
3726  ExprResult Res =
3727  S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
3728  if (!Res.isUsable())
3729  return nullptr;
3730  Init = Res.get();
3731  }
3732  WithInit = true;
3733  }
3734  auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
3735  CaptureExpr->getBeginLoc());
3736  if (!WithInit)
3737  CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
3738  S.CurContext->addHiddenDecl(CED);
3739  S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
3740  return CED;
3741 }
3742 
3743 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
3744  bool WithInit) {
3745  OMPCapturedExprDecl *CD;
3746  if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
3747  CD = cast<OMPCapturedExprDecl>(VD);
3748  else
3749  CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
3750  /*AsExpression=*/false);
3751  return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
3752  CaptureExpr->getExprLoc());
3753 }
3754 
3755 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
3756  CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
3757  if (!Ref) {
3759  S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
3760  /*WithInit=*/true, /*AsExpression=*/true);
3761  Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
3762  CaptureExpr->getExprLoc());
3763  }
3764  ExprResult Res = Ref;
3765  if (!S.getLangOpts().CPlusPlus &&
3766  CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
3767  Ref->getType()->isPointerType()) {
3768  Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
3769  if (!Res.isUsable())
3770  return ExprError();
3771  }
3772  return S.DefaultLvalueConversion(Res.get());
3773 }
3774 
3775 namespace {
3776 // OpenMP directives parsed in this section are represented as a
3777 // CapturedStatement with an associated statement. If a syntax error
3778 // is detected during the parsing of the associated statement, the
3779 // compiler must abort processing and close the CapturedStatement.
3780 //
3781 // Combined directives such as 'target parallel' have more than one
3782 // nested CapturedStatements. This RAII ensures that we unwind out
3783 // of all the nested CapturedStatements when an error is found.
3784 class CaptureRegionUnwinderRAII {
3785 private:
3786  Sema &S;
3787  bool &ErrorFound;
3788  OpenMPDirectiveKind DKind = OMPD_unknown;
3789 
3790 public:
3791  CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
3792  OpenMPDirectiveKind DKind)
3793  : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
3794  ~CaptureRegionUnwinderRAII() {
3795  if (ErrorFound) {
3796  int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
3797  while (--ThisCaptureLevel >= 0)
3799  }
3800  }
3801 };
3802 } // namespace
3803 
3805  // Capture variables captured by reference in lambdas for target-based
3806  // directives.
3807  if (!CurContext->isDependentContext() &&
3808  (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) ||
3810  DSAStack->getCurrentDirective()))) {
3811  QualType Type = V->getType();
3812  if (const auto *RD = Type.getCanonicalType()
3814  ->getAsCXXRecordDecl()) {
3815  bool SavedForceCaptureByReferenceInTargetExecutable =
3816  DSAStack->isForceCaptureByReferenceInTargetExecutable();
3817  DSAStack->setForceCaptureByReferenceInTargetExecutable(
3818  /*V=*/true);
3819  if (RD->isLambda()) {
3820  llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
3821  FieldDecl *ThisCapture;
3822  RD->getCaptureFields(Captures, ThisCapture);
3823  for (const LambdaCapture &LC : RD->captures()) {
3824  if (LC.getCaptureKind() == LCK_ByRef) {
3825  VarDecl *VD = LC.getCapturedVar();
3826  DeclContext *VDC = VD->getDeclContext();
3827  if (!VDC->Encloses(CurContext))
3828  continue;
3829  MarkVariableReferenced(LC.getLocation(), VD);
3830  } else if (LC.getCaptureKind() == LCK_This) {
3831  QualType ThisTy = getCurrentThisType();
3832  if (!ThisTy.isNull() &&
3833  Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
3834  CheckCXXThisCapture(LC.getLocation());
3835  }
3836  }
3837  }
3838  DSAStack->setForceCaptureByReferenceInTargetExecutable(
3839  SavedForceCaptureByReferenceInTargetExecutable);
3840  }
3841  }
3842 }
3843 
3845  ArrayRef<OMPClause *> Clauses) {
3846  bool ErrorFound = false;
3847  CaptureRegionUnwinderRAII CaptureRegionUnwinder(
3848  *this, ErrorFound, DSAStack->getCurrentDirective());
3849  if (!S.isUsable()) {
3850  ErrorFound = true;
3851  return StmtError();
3852  }
3853 
3854  SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
3855  getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective());
3856  OMPOrderedClause *OC = nullptr;
3857  OMPScheduleClause *SC = nullptr;
3860  // This is required for proper codegen.
3861  for (OMPClause *Clause : Clauses) {
3862  if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
3863  Clause->getClauseKind() == OMPC_in_reduction) {
3864  // Capture taskgroup task_reduction descriptors inside the tasking regions
3865  // with the corresponding in_reduction items.
3866  auto *IRC = cast<OMPInReductionClause>(Clause);
3867  for (Expr *E : IRC->taskgroup_descriptors())
3868  if (E)
3869  MarkDeclarationsReferencedInExpr(E);
3870  }
3871  if (isOpenMPPrivate(Clause->getClauseKind()) ||
3872  Clause->getClauseKind() == OMPC_copyprivate ||
3873  (getLangOpts().OpenMPUseTLS &&
3874  getASTContext().getTargetInfo().isTLSSupported() &&
3875  Clause->getClauseKind() == OMPC_copyin)) {
3876  DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
3877  // Mark all variables in private list clauses as used in inner region.
3878  for (Stmt *VarRef : Clause->children()) {
3879  if (auto *E = cast_or_null<Expr>(VarRef)) {
3880  MarkDeclarationsReferencedInExpr(E);
3881  }
3882  }
3883  DSAStack->setForceVarCapturing(/*V=*/false);
3884  } else if (CaptureRegions.size() > 1 ||
3885  CaptureRegions.back() != OMPD_unknown) {
3886  if (auto *C = OMPClauseWithPreInit::get(Clause))
3887  PICs.push_back(C);
3888  if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
3889  if (Expr *E = C->getPostUpdateExpr())
3890  MarkDeclarationsReferencedInExpr(E);
3891  }
3892  }
3893  if (Clause->getClauseKind() == OMPC_schedule)
3894  SC = cast<OMPScheduleClause>(Clause);
3895  else if (Clause->getClauseKind() == OMPC_ordered)
3896  OC = cast<OMPOrderedClause>(Clause);
3897  else if (Clause->getClauseKind() == OMPC_linear)
3898  LCs.push_back(cast<OMPLinearClause>(Clause));
3899  }
3900  // OpenMP, 2.7.1 Loop Construct, Restrictions
3901  // The nonmonotonic modifier cannot be specified if an ordered clause is
3902  // specified.
3903  if (SC &&
3904  (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
3905  SC->getSecondScheduleModifier() ==
3906  OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
3907  OC) {
3908  Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
3911  diag::err_omp_schedule_nonmonotonic_ordered)
3912  << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
3913  ErrorFound = true;
3914  }
3915  if (!LCs.empty() && OC && OC->getNumForLoops()) {
3916  for (const OMPLinearClause *C : LCs) {
3917  Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
3918  << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
3919  }
3920  ErrorFound = true;
3921  }
3922  if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
3923  isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
3924  OC->getNumForLoops()) {
3925  Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
3926  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
3927  ErrorFound = true;
3928  }
3929  if (ErrorFound) {
3930  return StmtError();
3931  }
3932  StmtResult SR = S;
3933  unsigned CompletedRegions = 0;
3934  for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
3935  // Mark all variables in private list clauses as used in inner region.
3936  // Required for proper codegen of combined directives.
3937  // TODO: add processing for other clauses.
3938  if (ThisCaptureRegion != OMPD_unknown) {
3939  for (const clang::OMPClauseWithPreInit *C : PICs) {
3940  OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
3941  // Find the particular capture region for the clause if the
3942  // directive is a combined one with multiple capture regions.
3943  // If the directive is not a combined one, the capture region
3944  // associated with the clause is OMPD_unknown and is generated
3945  // only once.
3946  if (CaptureRegion == ThisCaptureRegion ||
3947  CaptureRegion == OMPD_unknown) {
3948  if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
3949  for (Decl *D : DS->decls())
3950  MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
3951  }
3952  }
3953  }
3954  }
3955  if (++CompletedRegions == CaptureRegions.size())
3956  DSAStack->setBodyComplete();
3957  SR = ActOnCapturedRegionEnd(SR.get());
3958  }
3959  return SR;
3960 }
3961 
3962 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
3963  OpenMPDirectiveKind CancelRegion,
3964  SourceLocation StartLoc) {
3965  // CancelRegion is only needed for cancel and cancellation_point.
3966  if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
3967  return false;
3968 
3969  if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
3970  CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
3971  return false;
3972 
3973  SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
3974  << getOpenMPDirectiveName(CancelRegion);
3975  return true;
3976 }
3977 
3978 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
3979  OpenMPDirectiveKind CurrentRegion,
3980  const DeclarationNameInfo &CurrentName,
3981  OpenMPDirectiveKind CancelRegion,
3982  SourceLocation StartLoc) {
3983  if (Stack->getCurScope()) {
3984  OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
3985  OpenMPDirectiveKind OffendingRegion = ParentRegion;
3986  bool NestingProhibited = false;
3987  bool CloseNesting = true;
3988  bool OrphanSeen = false;
3989  enum {
3990  NoRecommend,
3991  ShouldBeInParallelRegion,
3992  ShouldBeInOrderedRegion,
3993  ShouldBeInTargetRegion,
3994  ShouldBeInTeamsRegion
3995  } Recommend = NoRecommend;
3996  if (isOpenMPSimdDirective(ParentRegion) &&
3997  ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
3998  (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
3999  CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic))) {
4000  // OpenMP [2.16, Nesting of Regions]
4001  // OpenMP constructs may not be nested inside a simd region.
4002  // OpenMP [2.8.1,simd Construct, Restrictions]
4003  // An ordered construct with the simd clause is the only OpenMP
4004  // construct that can appear in the simd region.
4005  // Allowing a SIMD construct nested in another SIMD construct is an
4006  // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
4007  // message.
4008  // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions]
4009  // The only OpenMP constructs that can be encountered during execution of
4010  // a simd region are the atomic construct, the loop construct, the simd
4011  // construct and the ordered construct with the simd clause.
4012  SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
4013  ? diag::err_omp_prohibited_region_simd
4014  : diag::warn_omp_nesting_simd)
4015  << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0);
4016  return CurrentRegion != OMPD_simd;
4017  }
4018  if (ParentRegion == OMPD_atomic) {
4019  // OpenMP [2.16, Nesting of Regions]
4020  // OpenMP constructs may not be nested inside an atomic region.
4021  SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
4022  return true;
4023  }
4024  if (CurrentRegion == OMPD_section) {
4025  // OpenMP [2.7.2, sections Construct, Restrictions]
4026  // Orphaned section directives are prohibited. That is, the section
4027  // directives must appear within the sections construct and must not be
4028  // encountered elsewhere in the sections region.
4029  if (ParentRegion != OMPD_sections &&
4030  ParentRegion != OMPD_parallel_sections) {
4031  SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
4032  << (ParentRegion != OMPD_unknown)
4033  << getOpenMPDirectiveName(ParentRegion);
4034  return true;
4035  }
4036  return false;
4037  }
4038  // Allow some constructs (except teams and cancellation constructs) to be
4039  // orphaned (they could be used in functions, called from OpenMP regions
4040  // with the required preconditions).
4041  if (ParentRegion == OMPD_unknown &&
4042  !isOpenMPNestingTeamsDirective(CurrentRegion) &&
4043  CurrentRegion != OMPD_cancellation_point &&
4044  CurrentRegion != OMPD_cancel)
4045  return false;
4046  if (CurrentRegion == OMPD_cancellation_point ||
4047  CurrentRegion == OMPD_cancel) {
4048  // OpenMP [2.16, Nesting of Regions]
4049  // A cancellation point construct for which construct-type-clause is
4050  // taskgroup must be nested inside a task construct. A cancellation
4051  // point construct for which construct-type-clause is not taskgroup must
4052  // be closely nested inside an OpenMP construct that matches the type
4053  // specified in construct-type-clause.
4054  // A cancel construct for which construct-type-clause is taskgroup must be
4055  // nested inside a task construct. A cancel construct for which
4056  // construct-type-clause is not taskgroup must be closely nested inside an
4057  // OpenMP construct that matches the type specified in
4058  // construct-type-clause.
4059  NestingProhibited =
4060  !((CancelRegion == OMPD_parallel &&
4061  (ParentRegion == OMPD_parallel ||
4062  ParentRegion == OMPD_target_parallel)) ||
4063  (CancelRegion == OMPD_for &&
4064  (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
4065  ParentRegion == OMPD_target_parallel_for ||
4066  ParentRegion == OMPD_distribute_parallel_for ||
4067  ParentRegion == OMPD_teams_distribute_parallel_for ||
4068  ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
4069  (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) ||
4070  (CancelRegion == OMPD_sections &&
4071  (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
4072  ParentRegion == OMPD_parallel_sections)));
4073  OrphanSeen = ParentRegion == OMPD_unknown;
4074  } else if (CurrentRegion == OMPD_master) {
4075  // OpenMP [2.16, Nesting of Regions]
4076  // A master region may not be closely nested inside a worksharing,
4077  // atomic, or explicit task region.
4078  NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4079  isOpenMPTaskingDirective(ParentRegion);
4080  } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
4081  // OpenMP [2.16, Nesting of Regions]
4082  // A critical region may not be nested (closely or otherwise) inside a
4083  // critical region with the same name. Note that this restriction is not
4084  // sufficient to prevent deadlock.
4085  SourceLocation PreviousCriticalLoc;
4086  bool DeadLock = Stack->hasDirective(
4087  [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
4088  const DeclarationNameInfo &DNI,
4089  SourceLocation Loc) {
4090  if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
4091  PreviousCriticalLoc = Loc;
4092  return true;
4093  }
4094  return false;
4095  },
4096  false /* skip top directive */);
4097  if (DeadLock) {
4098  SemaRef.Diag(StartLoc,
4099  diag::err_omp_prohibited_region_critical_same_name)
4100  << CurrentName.getName();
4101  if (PreviousCriticalLoc.isValid())
4102  SemaRef.Diag(PreviousCriticalLoc,
4103  diag::note_omp_previous_critical_region);
4104  return true;
4105  }
4106  } else if (CurrentRegion == OMPD_barrier) {
4107  // OpenMP [2.16, Nesting of Regions]
4108  // A barrier region may not be closely nested inside a worksharing,
4109  // explicit task, critical, ordered, atomic, or master region.
4110  NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4111  isOpenMPTaskingDirective(ParentRegion) ||
4112  ParentRegion == OMPD_master ||
4113  ParentRegion == OMPD_parallel_master ||
4114  ParentRegion == OMPD_critical ||
4115  ParentRegion == OMPD_ordered;
4116  } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
4117  !isOpenMPParallelDirective(CurrentRegion) &&
4118  !isOpenMPTeamsDirective(CurrentRegion)) {
4119  // OpenMP [2.16, Nesting of Regions]
4120  // A worksharing region may not be closely nested inside a worksharing,
4121  // explicit task, critical, ordered, atomic, or master region.
4122  NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4123  isOpenMPTaskingDirective(ParentRegion) ||
4124  ParentRegion == OMPD_master ||
4125  ParentRegion == OMPD_parallel_master ||
4126  ParentRegion == OMPD_critical ||
4127  ParentRegion == OMPD_ordered;
4128  Recommend = ShouldBeInParallelRegion;
4129  } else if (CurrentRegion == OMPD_ordered) {
4130  // OpenMP [2.16, Nesting of Regions]
4131  // An ordered region may not be closely nested inside a critical,
4132  // atomic, or explicit task region.
4133  // An ordered region must be closely nested inside a loop region (or
4134  // parallel loop region) with an ordered clause.
4135  // OpenMP [2.8.1,simd Construct, Restrictions]
4136  // An ordered construct with the simd clause is the only OpenMP construct
4137  // that can appear in the simd region.
4138  NestingProhibited = ParentRegion == OMPD_critical ||
4139  isOpenMPTaskingDirective(ParentRegion) ||
4140  !(isOpenMPSimdDirective(ParentRegion) ||
4141  Stack->isParentOrderedRegion());
4142  Recommend = ShouldBeInOrderedRegion;
4143  } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
4144  // OpenMP [2.16, Nesting of Regions]
4145  // If specified, a teams construct must be contained within a target
4146  // construct.
4147  NestingProhibited =
4148  (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
4149  (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
4150  ParentRegion != OMPD_target);
4151  OrphanSeen = ParentRegion == OMPD_unknown;
4152  Recommend = ShouldBeInTargetRegion;
4153  }
4154  if (!NestingProhibited &&
4155  !isOpenMPTargetExecutionDirective(CurrentRegion) &&
4156  !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
4157  (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
4158  // OpenMP [2.16, Nesting of Regions]
4159  // distribute, parallel, parallel sections, parallel workshare, and the
4160  // parallel loop and parallel loop SIMD constructs are the only OpenMP
4161  // constructs that can be closely nested in the teams region.
4162  NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
4163  !isOpenMPDistributeDirective(CurrentRegion);
4164  Recommend = ShouldBeInParallelRegion;
4165  }
4166  if (!NestingProhibited &&
4167  isOpenMPNestingDistributeDirective(CurrentRegion)) {
4168  // OpenMP 4.5 [2.17 Nesting of Regions]
4169  // The region associated with the distribute construct must be strictly
4170  // nested inside a teams region
4171  NestingProhibited =
4172  (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
4173  Recommend = ShouldBeInTeamsRegion;
4174  }
4175  if (!NestingProhibited &&
4176  (isOpenMPTargetExecutionDirective(CurrentRegion) ||
4177  isOpenMPTargetDataManagementDirective(CurrentRegion))) {
4178  // OpenMP 4.5 [2.17 Nesting of Regions]
4179  // If a target, target update, target data, target enter data, or
4180  // target exit data construct is encountered during execution of a
4181  // target region, the behavior is unspecified.
4182  NestingProhibited = Stack->hasDirective(
4183  [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
4184  SourceLocation) {
4186  OffendingRegion = K;
4187  return true;
4188  }
4189  return false;
4190  },
4191  false /* don't skip top directive */);
4192  CloseNesting = false;
4193  }
4194  if (NestingProhibited) {
4195  if (OrphanSeen) {
4196  SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
4197  << getOpenMPDirectiveName(CurrentRegion) << Recommend;
4198  } else {
4199  SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
4200  << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
4201  << Recommend << getOpenMPDirectiveName(CurrentRegion);
4202  }
4203  return true;
4204  }
4205  }
4206  return false;
4207 }
4208 
4211  unsigned operator()(argument_type DK) { return unsigned(DK); }
4212 };
4214  ArrayRef<OMPClause *> Clauses,
4215  ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
4216  bool ErrorFound = false;
4217  unsigned NamedModifiersNumber = 0;
4218  llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
4219  FoundNameModifiers.resize(unsigned(OMPD_unknown) + 1);
4220  SmallVector<SourceLocation, 4> NameModifierLoc;
4221  for (const OMPClause *C : Clauses) {
4222  if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
4223  // At most one if clause without a directive-name-modifier can appear on
4224  // the directive.
4225  OpenMPDirectiveKind CurNM = IC->getNameModifier();
4226  if (FoundNameModifiers[CurNM]) {
4227  S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
4228  << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
4229  << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
4230  ErrorFound = true;
4231  } else if (CurNM != OMPD_unknown) {
4232  NameModifierLoc.push_back(IC->getNameModifierLoc());
4233  ++NamedModifiersNumber;
4234  }
4235  FoundNameModifiers[CurNM] = IC;
4236  if (CurNM == OMPD_unknown)
4237  continue;
4238  // Check if the specified name modifier is allowed for the current
4239  // directive.
4240  // At most one if clause with the particular directive-name-modifier can
4241  // appear on the directive.
4242  bool MatchFound = false;
4243  for (auto NM : AllowedNameModifiers) {
4244  if (CurNM == NM) {
4245  MatchFound = true;
4246  break;
4247  }
4248  }
4249  if (!MatchFound) {
4250  S.Diag(IC->getNameModifierLoc(),
4251  diag::err_omp_wrong_if_directive_name_modifier)
4252  << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
4253  ErrorFound = true;
4254  }
4255  }
4256  }
4257  // If any if clause on the directive includes a directive-name-modifier then
4258  // all if clauses on the directive must include a directive-name-modifier.
4259  if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
4260  if (NamedModifiersNumber == AllowedNameModifiers.size()) {
4261  S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
4262  diag::err_omp_no_more_if_clause);
4263  } else {
4264  std::string Values;
4265  std::string Sep(", ");
4266  unsigned AllowedCnt = 0;
4267  unsigned TotalAllowedNum =
4268  AllowedNameModifiers.size() - NamedModifiersNumber;
4269  for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
4270  ++Cnt) {
4271  OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
4272  if (!FoundNameModifiers[NM]) {
4273  Values += "'";
4274  Values += getOpenMPDirectiveName(NM);
4275  Values += "'";
4276  if (AllowedCnt + 2 == TotalAllowedNum)
4277  Values += " or ";
4278  else if (AllowedCnt + 1 != TotalAllowedNum)
4279  Values += Sep;
4280  ++AllowedCnt;
4281  }
4282  }
4283  S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
4284  diag::err_omp_unnamed_if_clause)
4285  << (TotalAllowedNum > 1) << Values;
4286  }
4287  for (SourceLocation Loc : NameModifierLoc) {
4288  S.Diag(Loc, diag::note_omp_previous_named_if_clause);
4289  }
4290  ErrorFound = true;
4291  }
4292  return ErrorFound;
4293 }
4294 
4295 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
4296  SourceLocation &ELoc,
4297  SourceRange &ERange,
4298  bool AllowArraySection) {
4299  if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
4301  return std::make_pair(nullptr, true);
4302 
4303  // OpenMP [3.1, C/C++]
4304  // A list item is a variable name.
4305  // OpenMP [2.9.3.3, Restrictions, p.1]
4306  // A variable that is part of another variable (as an array or
4307  // structure element) cannot appear in a private clause.
4308  RefExpr = RefExpr->IgnoreParens();
4309  enum {
4310  NoArrayExpr = -1,
4311  ArraySubscript = 0,
4312  OMPArraySection = 1
4313  } IsArrayExpr = NoArrayExpr;
4314  if (AllowArraySection) {
4315  if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
4316  Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
4317  while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4318  Base = TempASE->getBase()->IgnoreParenImpCasts();
4319  RefExpr = Base;
4320  IsArrayExpr = ArraySubscript;
4321  } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
4322  Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
4323  while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
4324  Base = TempOASE->getBase()->IgnoreParenImpCasts();
4325  while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4326  Base = TempASE->getBase()->IgnoreParenImpCasts();
4327  RefExpr = Base;
4328  IsArrayExpr = OMPArraySection;
4329  }
4330  }
4331  ELoc = RefExpr->getExprLoc();
4332  ERange = RefExpr->getSourceRange();
4333  RefExpr = RefExpr->IgnoreParenImpCasts();
4334  auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
4335  auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
4336  if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
4337  (S.getCurrentThisType().isNull() || !ME ||
4338  !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
4339  !isa<FieldDecl>(ME->getMemberDecl()))) {
4340  if (IsArrayExpr != NoArrayExpr) {
4341  S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
4342  << ERange;
4343  } else {
4344  S.Diag(ELoc,
4345  AllowArraySection
4346  ? diag::err_omp_expected_var_name_member_expr_or_array_item
4347  : diag::err_omp_expected_var_name_member_expr)
4348  << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
4349  }
4350  return std::make_pair(nullptr, false);
4351  }
4352  return std::make_pair(
4353  getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
4354 }
4355 
4356 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
4357  ArrayRef<OMPClause *> Clauses) {
4358  assert(!S.CurContext->isDependentContext() &&
4359  "Expected non-dependent context.");
4360  auto AllocateRange =
4361  llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
4362  llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>>
4363  DeclToCopy;
4364  auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
4365  return isOpenMPPrivate(C->getClauseKind());
4366  });
4367  for (OMPClause *Cl : PrivateRange) {
4368  MutableArrayRef<Expr *>::iterator I, It, Et;
4369  if (Cl->getClauseKind() == OMPC_private) {
4370  auto *PC = cast<OMPPrivateClause>(Cl);
4371  I = PC->private_copies().begin();
4372  It = PC->varlist_begin();
4373  Et = PC->varlist_end();
4374  } else if (Cl->getClauseKind() == OMPC_firstprivate) {
4375  auto *PC = cast<OMPFirstprivateClause>(Cl);
4376  I = PC->private_copies().begin();
4377  It = PC->varlist_begin();
4378  Et = PC->varlist_end();
4379  } else if (Cl->getClauseKind() == OMPC_lastprivate) {
4380  auto *PC = cast<OMPLastprivateClause>(Cl);
4381  I = PC->private_copies().begin();
4382  It = PC->varlist_begin();
4383  Et = PC->varlist_end();
4384  } else if (Cl->getClauseKind() == OMPC_linear) {
4385  auto *PC = cast<OMPLinearClause>(Cl);
4386  I = PC->privates().begin();
4387  It = PC->varlist_begin();
4388  Et = PC->varlist_end();
4389  } else if (Cl->getClauseKind() == OMPC_reduction) {
4390  auto *PC = cast<OMPReductionClause>(Cl);
4391  I = PC->privates().begin();
4392  It = PC->varlist_begin();
4393  Et = PC->varlist_end();
4394  } else if (Cl->getClauseKind() == OMPC_task_reduction) {
4395  auto *PC = cast<OMPTaskReductionClause>(Cl);
4396  I = PC->privates().begin();
4397  It = PC->varlist_begin();
4398  Et = PC->varlist_end();
4399  } else if (Cl->getClauseKind() == OMPC_in_reduction) {
4400  auto *PC = cast<OMPInReductionClause>(Cl);
4401  I = PC->privates().begin();
4402  It = PC->varlist_begin();
4403  Et = PC->varlist_end();
4404  } else {
4405  llvm_unreachable("Expected private clause.");
4406  }
4407  for (Expr *E : llvm::make_range(It, Et)) {
4408  if (!*I) {
4409  ++I;
4410  continue;
4411  }
4412  SourceLocation ELoc;
4413  SourceRange ERange;
4414  Expr *SimpleRefExpr = E;
4415  auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
4416  /*AllowArraySection=*/true);
4417  DeclToCopy.try_emplace(Res.first,
4418  cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
4419  ++I;
4420  }
4421  }
4422  for (OMPClause *C : AllocateRange) {
4423  auto *AC = cast<OMPAllocateClause>(C);
4424  OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
4425  getAllocatorKind(S, Stack, AC->getAllocator());
4426  // OpenMP, 2.11.4 allocate Clause, Restrictions.
4427  // For task, taskloop or target directives, allocation requests to memory
4428  // allocators with the trait access set to thread result in unspecified
4429  // behavior.
4430  if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
4431  (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
4432  isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
4433  S.Diag(AC->getAllocator()->getExprLoc(),
4434  diag::warn_omp_allocate_thread_on_task_target_directive)
4435  << getOpenMPDirectiveName(Stack->getCurrentDirective());
4436  }
4437  for (Expr *E : AC->varlists()) {
4438  SourceLocation ELoc;
4439  SourceRange ERange;
4440  Expr *SimpleRefExpr = E;
4441  auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
4442  ValueDecl *VD = Res.first;
4443  DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
4444  if (!isOpenMPPrivate(Data.CKind)) {
4445  S.Diag(E->getExprLoc(),
4446  diag::err_omp_expected_private_copy_for_allocate);
4447  continue;
4448  }
4449  VarDecl *PrivateVD = DeclToCopy[VD];
4450  if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
4451  AllocatorKind, AC->getAllocator()))
4452  continue;
4453  applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
4454  E->getSourceRange());
4455  }
4456  }
4457 }
4458 
4461  OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
4462  Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
4463  StmtResult Res = StmtError();
4464  // First check CancelRegion which is then used in checkNestingOfRegions.
4465  if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
4466  checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
4467  StartLoc))
4468  return StmtError();
4469 
4470  llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
4471  VarsWithInheritedDSAType VarsWithInheritedDSA;
4472  bool ErrorFound = false;
4473  ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
4474  if (AStmt && !CurContext->isDependentContext()) {
4475  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
4476 
4477  // Check default data sharing attributes for referenced variables.
4478  DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
4479  int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
4480  Stmt *S = AStmt;
4481  while (--ThisCaptureLevel >= 0)
4482  S = cast<CapturedStmt>(S)->getCapturedStmt();
4483  DSAChecker.Visit(S);
4485  !isOpenMPTaskingDirective(Kind)) {
4486  // Visit subcaptures to generate implicit clauses for captured vars.
4487  auto *CS = cast<CapturedStmt>(AStmt);
4488  SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4489  getOpenMPCaptureRegions(CaptureRegions, Kind);
4490  // Ignore outer tasking regions for target directives.
4491  if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
4492  CS = cast<CapturedStmt>(CS->getCapturedStmt());
4493  DSAChecker.visitSubCaptures(CS);
4494  }
4495  if (DSAChecker.isErrorFound())
4496  return StmtError();
4497  // Generate list of implicitly defined firstprivate variables.
4498  VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
4499 
4500  SmallVector<Expr *, 4> ImplicitFirstprivates(
4501  DSAChecker.getImplicitFirstprivate().begin(),
4502  DSAChecker.getImplicitFirstprivate().end());
4503  SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete];
4504  for (unsigned I = 0; I < OMPC_MAP_delete; ++I) {
4505  ArrayRef<Expr *> ImplicitMap =
4506  DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I));
4507  ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end());
4508  }
4509  // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
4510  for (OMPClause *C : Clauses) {
4511  if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
4512  for (Expr *E : IRC->taskgroup_descriptors())
4513  if (E)
4514  ImplicitFirstprivates.emplace_back(E);
4515  }
4516  }
4517  if (!ImplicitFirstprivates.empty()) {
4518  if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
4519  ImplicitFirstprivates, SourceLocation(), SourceLocation(),
4520  SourceLocation())) {
4521  ClausesWithImplicit.push_back(Implicit);
4522  ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
4523  ImplicitFirstprivates.size();
4524  } else {
4525  ErrorFound = true;
4526  }
4527  }
4528  int ClauseKindCnt = -1;
4529  for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) {
4530  ++ClauseKindCnt;
4531  if (ImplicitMap.empty())
4532  continue;
4533  CXXScopeSpec MapperIdScopeSpec;
4534  DeclarationNameInfo MapperId;
4535  auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
4536  if (OMPClause *Implicit = ActOnOpenMPMapClause(
4537  llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind,
4538  /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
4539  ImplicitMap, OMPVarListLocTy())) {
4540  ClausesWithImplicit.emplace_back(Implicit);
4541  ErrorFound |=
4542  cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size();
4543  } else {
4544  ErrorFound = true;
4545  }
4546  }
4547  }
4548 
4549  llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
4550  switch (Kind) {
4551  case OMPD_parallel:
4552  Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
4553  EndLoc);
4554  AllowedNameModifiers.push_back(OMPD_parallel);
4555  break;
4556  case OMPD_simd:
4557  Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
4558  VarsWithInheritedDSA);
4559  if (LangOpts.OpenMP >= 50)
4560  AllowedNameModifiers.push_back(OMPD_simd);
4561  break;
4562  case OMPD_for:
4563  Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
4564  VarsWithInheritedDSA);
4565  break;
4566  case OMPD_for_simd:
4567  Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
4568  EndLoc, VarsWithInheritedDSA);
4569  if (LangOpts.OpenMP >= 50)
4570  AllowedNameModifiers.push_back(OMPD_simd);
4571  break;
4572  case OMPD_sections:
4573  Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
4574  EndLoc);
4575  break;
4576  case OMPD_section:
4577  assert(ClausesWithImplicit.empty() &&
4578  "No clauses are allowed for 'omp section' directive");
4579  Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
4580  break;
4581  case OMPD_single:
4582  Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
4583  EndLoc);
4584  break;
4585  case OMPD_master:
4586  assert(ClausesWithImplicit.empty() &&
4587  "No clauses are allowed for 'omp master' directive");
4588  Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
4589  break;
4590  case OMPD_critical:
4591  Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
4592  StartLoc, EndLoc);
4593  break;
4594  case OMPD_parallel_for:
4595  Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
4596  EndLoc, VarsWithInheritedDSA);
4597  AllowedNameModifiers.push_back(OMPD_parallel);
4598  break;
4599  case OMPD_parallel_for_simd:
4600  Res = ActOnOpenMPParallelForSimdDirective(
4601  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4602  AllowedNameModifiers.push_back(OMPD_parallel);
4603  if (LangOpts.OpenMP >= 50)
4604  AllowedNameModifiers.push_back(OMPD_simd);
4605  break;
4606  case OMPD_parallel_master:
4607  Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
4608  StartLoc, EndLoc);
4609  AllowedNameModifiers.push_back(OMPD_parallel);
4610  break;
4611  case OMPD_parallel_sections:
4612  Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
4613  StartLoc, EndLoc);
4614  AllowedNameModifiers.push_back(OMPD_parallel);
4615  break;
4616  case OMPD_task:
4617  Res =
4618  ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
4619  AllowedNameModifiers.push_back(OMPD_task);
4620  break;
4621  case OMPD_taskyield:
4622  assert(ClausesWithImplicit.empty() &&
4623  "No clauses are allowed for 'omp taskyield' directive");
4624  assert(AStmt == nullptr &&
4625  "No associated statement allowed for 'omp taskyield' directive");
4626  Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
4627  break;
4628  case OMPD_barrier:
4629  assert(ClausesWithImplicit.empty() &&
4630  "No clauses are allowed for 'omp barrier' directive");
4631  assert(AStmt == nullptr &&
4632  "No associated statement allowed for 'omp barrier' directive");
4633  Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
4634  break;
4635  case OMPD_taskwait:
4636  assert(ClausesWithImplicit.empty() &&
4637  "No clauses are allowed for 'omp taskwait' directive");
4638  assert(AStmt == nullptr &&
4639  "No associated statement allowed for 'omp taskwait' directive");
4640  Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
4641  break;
4642  case OMPD_taskgroup:
4643  Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
4644  EndLoc);
4645  break;
4646  case OMPD_flush:
4647  assert(AStmt == nullptr &&
4648  "No associated statement allowed for 'omp flush' directive");
4649  Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
4650  break;
4651  case OMPD_ordered:
4652  Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
4653  EndLoc);
4654  break;
4655  case OMPD_atomic:
4656  Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
4657  EndLoc);
4658  break;
4659  case OMPD_teams:
4660  Res =
4661  ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
4662  break;
4663  case OMPD_target:
4664  Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
4665  EndLoc);
4666  AllowedNameModifiers.push_back(OMPD_target);
4667  break;
4668  case OMPD_target_parallel:
4669  Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
4670  StartLoc, EndLoc);
4671  AllowedNameModifiers.push_back(OMPD_target);
4672  AllowedNameModifiers.push_back(OMPD_parallel);
4673  break;
4674  case OMPD_target_parallel_for:
4675  Res = ActOnOpenMPTargetParallelForDirective(
4676  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4677  AllowedNameModifiers.push_back(OMPD_target);
4678  AllowedNameModifiers.push_back(OMPD_parallel);
4679  break;
4680  case OMPD_cancellation_point:
4681  assert(ClausesWithImplicit.empty() &&
4682  "No clauses are allowed for 'omp cancellation point' directive");
4683  assert(AStmt == nullptr && "No associated statement allowed for 'omp "
4684  "cancellation point' directive");
4685  Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
4686  break;
4687  case OMPD_cancel:
4688  assert(AStmt == nullptr &&
4689  "No associated statement allowed for 'omp cancel' directive");
4690  Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
4691  CancelRegion);
4692  AllowedNameModifiers.push_back(OMPD_cancel);
4693  break;
4694  case OMPD_target_data:
4695  Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
4696  EndLoc);
4697  AllowedNameModifiers.push_back(OMPD_target_data);
4698  break;
4699  case OMPD_target_enter_data:
4700  Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
4701  EndLoc, AStmt);
4702  AllowedNameModifiers.push_back(OMPD_target_enter_data);
4703  break;
4704  case OMPD_target_exit_data:
4705  Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
4706  EndLoc, AStmt);
4707  AllowedNameModifiers.push_back(OMPD_target_exit_data);
4708  break;
4709  case OMPD_taskloop:
4710  Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
4711  EndLoc, VarsWithInheritedDSA);
4712  AllowedNameModifiers.push_back(OMPD_taskloop);
4713  break;
4714  case OMPD_taskloop_simd:
4715  Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
4716  EndLoc, VarsWithInheritedDSA);
4717  AllowedNameModifiers.push_back(OMPD_taskloop);
4718  if (LangOpts.OpenMP >= 50)
4719  AllowedNameModifiers.push_back(OMPD_simd);
4720  break;
4721  case OMPD_master_taskloop:
4722  Res = ActOnOpenMPMasterTaskLoopDirective(
4723  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4724  AllowedNameModifiers.push_back(OMPD_taskloop);
4725  break;
4726  case OMPD_master_taskloop_simd:
4727  Res = ActOnOpenMPMasterTaskLoopSimdDirective(
4728  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4729  AllowedNameModifiers.push_back(OMPD_taskloop);
4730  if (LangOpts.OpenMP >= 50)
4731  AllowedNameModifiers.push_back(OMPD_simd);
4732  break;
4733  case OMPD_parallel_master_taskloop:
4734  Res = ActOnOpenMPParallelMasterTaskLoopDirective(
4735  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4736  AllowedNameModifiers.push_back(OMPD_taskloop);
4737  AllowedNameModifiers.push_back(OMPD_parallel);
4738  break;
4739  case OMPD_parallel_master_taskloop_simd:
4740  Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective(
4741  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4742  AllowedNameModifiers.push_back(OMPD_taskloop);
4743  AllowedNameModifiers.push_back(OMPD_parallel);
4744  if (LangOpts.OpenMP >= 50)
4745  AllowedNameModifiers.push_back(OMPD_simd);
4746  break;
4747  case OMPD_distribute:
4748  Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
4749  EndLoc, VarsWithInheritedDSA);
4750  break;
4751  case OMPD_target_update:
4752  Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
4753  EndLoc, AStmt);
4754  AllowedNameModifiers.push_back(OMPD_target_update);
4755  break;
4756  case OMPD_distribute_parallel_for:
4757  Res = ActOnOpenMPDistributeParallelForDirective(
4758  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4759  AllowedNameModifiers.push_back(OMPD_parallel);
4760  break;
4761  case OMPD_distribute_parallel_for_simd:
4762  Res = ActOnOpenMPDistributeParallelForSimdDirective(
4763  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4764  AllowedNameModifiers.push_back(OMPD_parallel);
4765  if (LangOpts.OpenMP >= 50)
4766  AllowedNameModifiers.push_back(OMPD_simd);
4767  break;
4768  case OMPD_distribute_simd:
4769  Res = ActOnOpenMPDistributeSimdDirective(
4770  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4771  if (LangOpts.OpenMP >= 50)
4772  AllowedNameModifiers.push_back(OMPD_simd);
4773  break;
4774  case OMPD_target_parallel_for_simd:
4775  Res = ActOnOpenMPTargetParallelForSimdDirective(
4776  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4777  AllowedNameModifiers.push_back(OMPD_target);
4778  AllowedNameModifiers.push_back(OMPD_parallel);
4779  if (LangOpts.OpenMP >= 50)
4780  AllowedNameModifiers.push_back(OMPD_simd);
4781  break;
4782  case OMPD_target_simd:
4783  Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
4784  EndLoc, VarsWithInheritedDSA);
4785  AllowedNameModifiers.push_back(OMPD_target);
4786  if (LangOpts.OpenMP >= 50)
4787  AllowedNameModifiers.push_back(OMPD_simd);
4788  break;
4789  case OMPD_teams_distribute:
4790  Res = ActOnOpenMPTeamsDistributeDirective(
4791  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4792  break;
4793  case OMPD_teams_distribute_simd:
4794  Res = ActOnOpenMPTeamsDistributeSimdDirective(
4795  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4796  if (LangOpts.OpenMP >= 50)
4797  AllowedNameModifiers.push_back(OMPD_simd);
4798  break;
4799  case OMPD_teams_distribute_parallel_for_simd:
4800  Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
4801  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4802  AllowedNameModifiers.push_back(OMPD_parallel);
4803  if (LangOpts.OpenMP >= 50)
4804  AllowedNameModifiers.push_back(OMPD_simd);
4805  break;
4806  case OMPD_teams_distribute_parallel_for:
4807  Res = ActOnOpenMPTeamsDistributeParallelForDirective(
4808  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4809  AllowedNameModifiers.push_back(OMPD_parallel);
4810  break;
4811  case OMPD_target_teams:
4812  Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
4813  EndLoc);
4814  AllowedNameModifiers.push_back(OMPD_target);
4815  break;
4816  case OMPD_target_teams_distribute:
4817  Res = ActOnOpenMPTargetTeamsDistributeDirective(
4818  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4819  AllowedNameModifiers.push_back(OMPD_target);
4820  break;
4821  case OMPD_target_teams_distribute_parallel_for:
4822  Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
4823  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4824  AllowedNameModifiers.push_back(OMPD_target);
4825  AllowedNameModifiers.push_back(OMPD_parallel);
4826  break;
4827  case OMPD_target_teams_distribute_parallel_for_simd:
4828  Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
4829  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4830  AllowedNameModifiers.push_back(OMPD_target);
4831  AllowedNameModifiers.push_back(OMPD_parallel);
4832  if (LangOpts.OpenMP >= 50)
4833  AllowedNameModifiers.push_back(OMPD_simd);
4834  break;
4835  case OMPD_target_teams_distribute_simd:
4836  Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
4837  ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
4838  AllowedNameModifiers.push_back(OMPD_target);
4839  if (LangOpts.OpenMP >= 50)
4840  AllowedNameModifiers.push_back(OMPD_simd);
4841  break;
4842  case OMPD_declare_target:
4843  case OMPD_end_declare_target:
4844  case OMPD_threadprivate:
4845  case OMPD_allocate:
4846  case OMPD_declare_reduction:
4847  case OMPD_declare_mapper:
4848  case OMPD_declare_simd:
4849  case OMPD_requires:
4850  case OMPD_declare_variant:
4851  llvm_unreachable("OpenMP Directive is not allowed");
4852  case OMPD_unknown:
4853  llvm_unreachable("Unknown OpenMP directive");
4854  }
4855 
4856  ErrorFound = Res.isInvalid() || ErrorFound;
4857 
4858  // Check variables in the clauses if default(none) was specified.
4859  if (DSAStack->getDefaultDSA() == DSA_none) {
4860  DSAAttrChecker DSAChecker(DSAStack, *this, nullptr);
4861  for (OMPClause *C : Clauses) {
4862  switch (C->getClauseKind()) {
4863  case OMPC_num_threads:
4864  case OMPC_dist_schedule:
4865  // Do not analyse if no parent teams directive.
4866  if (isOpenMPTeamsDirective(Kind))
4867  break;
4868  continue;
4869  case OMPC_if:
4870  if (isOpenMPTeamsDirective(Kind) &&
4871  cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
4872  break;
4873  if (isOpenMPParallelDirective(Kind) &&
4874  isOpenMPTaskLoopDirective(Kind) &&
4875  cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel)
4876  break;
4877  continue;
4878  case OMPC_schedule:
4879  break;
4880  case OMPC_grainsize:
4881  case OMPC_num_tasks:
4882  case OMPC_final:
4883  case OMPC_priority:
4884  // Do not analyze if no parent parallel directive.
4885  if (isOpenMPParallelDirective(Kind))
4886  break;
4887  continue;
4888  case OMPC_ordered:
4889  case OMPC_device:
4890  case OMPC_num_teams:
4891  case OMPC_thread_limit:
4892  case OMPC_hint:
4893  case OMPC_collapse:
4894  case OMPC_safelen:
4895  case OMPC_simdlen:
4896  case OMPC_default:
4897  case OMPC_proc_bind:
4898  case OMPC_private:
4899  case OMPC_firstprivate:
4900  case OMPC_lastprivate:
4901  case OMPC_shared:
4902  case OMPC_reduction:
4903  case OMPC_task_reduction:
4904  case OMPC_in_reduction:
4905  case OMPC_linear:
4906  case OMPC_aligned:
4907  case OMPC_copyin:
4908  case OMPC_copyprivate:
4909  case OMPC_nowait:
4910  case OMPC_untied:
4911  case OMPC_mergeable:
4912  case OMPC_allocate:
4913  case OMPC_read:
4914  case OMPC_write:
4915  case OMPC_update:
4916  case OMPC_capture:
4917  case OMPC_seq_cst:
4918  case OMPC_depend:
4919  case OMPC_threads:
4920  case OMPC_simd:
4921  case OMPC_map:
4922  case OMPC_nogroup:
4923  case OMPC_defaultmap:
4924  case OMPC_to:
4925  case OMPC_from:
4926  case OMPC_use_device_ptr:
4927  case OMPC_is_device_ptr:
4928  case OMPC_nontemporal:
4929  continue;
4930  case OMPC_allocator:
4931  case OMPC_flush:
4932  case OMPC_threadprivate:
4933  case OMPC_uniform:
4934  case OMPC_unknown:
4935  case OMPC_unified_address:
4936  case OMPC_unified_shared_memory:
4937  case OMPC_reverse_offload:
4938  case OMPC_dynamic_allocators:
4939  case OMPC_atomic_default_mem_order:
4940  case OMPC_device_type:
4941  case OMPC_match:
4942  llvm_unreachable("Unexpected clause");
4943  }
4944  for (Stmt *CC : C->children()) {
4945  if (CC)
4946  DSAChecker.Visit(CC);
4947  }
4948  }
4949  for (auto &P : DSAChecker.getVarsWithInheritedDSA())
4950  VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
4951  }
4952  for (const auto &P : VarsWithInheritedDSA) {
4953  if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
4954  continue;
4955  ErrorFound = true;
4956  if (DSAStack->getDefaultDSA() == DSA_none) {
4957  Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
4958  << P.first << P.second->getSourceRange();
4959  Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
4960  } else if (getLangOpts().OpenMP >= 50) {
4961  Diag(P.second->getExprLoc(),
4962  diag::err_omp_defaultmap_no_attr_for_variable)
4963  << P.first << P.second->getSourceRange();
4964  Diag(DSAStack->getDefaultDSALocation(),
4965  diag::note_omp_defaultmap_attr_none);
4966  }
4967  }
4968 
4969  if (!AllowedNameModifiers.empty())
4970  ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
4971  ErrorFound;
4972 
4973  if (ErrorFound)
4974  return StmtError();
4975 
4978  ->getStructuredBlock()
4979  ->setIsOMPStructuredBlock(true);
4980  }
4981 
4982  if (!CurContext->isDependentContext() &&
4984  !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
4985  DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
4986  DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
4987  DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
4988  // Register target to DSA Stack.
4989  DSAStack->addTargetDirLocation(StartLoc);
4990  }
4991 
4992  return Res;
4993 }
4994 
4996  DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
4997  ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
4998  ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
4999  ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
5000  assert(Aligneds.size() == Alignments.size());
5001  assert(Linears.size() == LinModifiers.size());
5002  assert(Linears.size() == Steps.size());
5003  if (!DG || DG.get().isNull())
5004  return DeclGroupPtrTy();
5005 
5006  const int SimdId = 0;
5007  if (!DG.get().isSingleDecl()) {
5008  Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
5009  << SimdId;
5010  return DG;
5011  }
5012  Decl *ADecl = DG.get().getSingleDecl();
5013  if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
5014  ADecl = FTD->getTemplatedDecl();
5015 
5016  auto *FD = dyn_cast<FunctionDecl>(ADecl);
5017  if (!FD) {
5018  Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId;
5019  return DeclGroupPtrTy();
5020  }
5021 
5022  // OpenMP [2.8.2, declare simd construct, Description]
5023  // The parameter of the simdlen clause must be a constant positive integer
5024  // expression.
5025  ExprResult SL;
5026  if (Simdlen)
5027  SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
5028  // OpenMP [2.8.2, declare simd construct, Description]
5029  // The special this pointer can be used as if was one of the arguments to the
5030  // function in any of the linear, aligned, or uniform clauses.
5031  // The uniform clause declares one or more arguments to have an invariant
5032  // value for all concurrent invocations of the function in the execution of a
5033  // single SIMD loop.
5034  llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
5035  const Expr *UniformedLinearThis = nullptr;
5036  for (const Expr *E : Uniforms) {
5037  E = E->IgnoreParenImpCasts();
5038  if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5039  if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
5040  if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5041  FD->getParamDecl(PVD->getFunctionScopeIndex())
5042  ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
5043  UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
5044  continue;
5045  }
5046  if (isa<CXXThisExpr>(E)) {
5047  UniformedLinearThis = E;
5048  continue;
5049  }
5050  Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5051  << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5052  }
5053  // OpenMP [2.8.2, declare simd construct, Description]
5054  // The aligned clause declares that the object to which each list item points
5055  // is aligned to the number of bytes expressed in the optional parameter of
5056  // the aligned clause.
5057  // The special this pointer can be used as if was one of the arguments to the
5058  // function in any of the linear, aligned, or uniform clauses.
5059  // The type of list items appearing in the aligned clause must be array,
5060  // pointer, reference to array, or reference to pointer.
5061  llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
5062  const Expr *AlignedThis = nullptr;
5063  for (const Expr *E : Aligneds) {
5064  E = E->IgnoreParenImpCasts();
5065  if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5066  if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5067  const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5068  if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5069  FD->getParamDecl(PVD->getFunctionScopeIndex())
5070  ->getCanonicalDecl() == CanonPVD) {
5071  // OpenMP [2.8.1, simd construct, Restrictions]
5072  // A list-item cannot appear in more than one aligned clause.
5073  if (AlignedArgs.count(CanonPVD) > 0) {
5074  Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
5075  << 1 << getOpenMPClauseName(OMPC_aligned)
5076  << E->getSourceRange();
5077  Diag(AlignedArgs[CanonPVD]->getExprLoc(),
5078  diag::note_omp_explicit_dsa)
5079  << getOpenMPClauseName(OMPC_aligned);
5080  continue;
5081  }
5082  AlignedArgs[CanonPVD] = E;
5083  QualType QTy = PVD->getType()
5084  .getNonReferenceType()
5085  .getUnqualifiedType()
5086  .getCanonicalType();
5087  const Type *Ty = QTy.getTypePtrOrNull();
5088  if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
5089  Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
5090  << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
5091  Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
5092  }
5093  continue;
5094  }
5095  }
5096  if (isa<CXXThisExpr>(E)) {
5097  if (AlignedThis) {
5098  Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
5099  << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange();
5100  Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
5101  << getOpenMPClauseName(OMPC_aligned);
5102  }
5103  AlignedThis = E;
5104  continue;
5105  }
5106  Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5107  << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5108  }
5109  // The optional parameter of the aligned clause, alignment, must be a constant
5110  // positive integer expression. If no optional parameter is specified,
5111  // implementation-defined default alignments for SIMD instructions on the
5112  // target platforms are assumed.
5113  SmallVector<const Expr *, 4> NewAligns;
5114  for (Expr *E : Alignments) {
5115  ExprResult Align;
5116  if (E)
5117  Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
5118  NewAligns.push_back(Align.get());
5119  }
5120  // OpenMP [2.8.2, declare simd construct, Description]
5121  // The linear clause declares one or more list items to be private to a SIMD
5122  // lane and to have a linear relationship with respect to the iteration space
5123  // of a loop.
5124  // The special this pointer can be used as if was one of the arguments to the
5125  // function in any of the linear, aligned, or uniform clauses.
5126  // When a linear-step expression is specified in a linear clause it must be
5127  // either a constant integer expression or an integer-typed parameter that is
5128  // specified in a uniform clause on the directive.
5129  llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
5130  const bool IsUniformedThis = UniformedLinearThis != nullptr;
5131  auto MI = LinModifiers.begin();
5132  for (const Expr *E : Linears) {
5133  auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
5134  ++MI;
5135  E = E->IgnoreParenImpCasts();
5136  if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
5137  if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5138  const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5139  if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
5140  FD->getParamDecl(PVD->getFunctionScopeIndex())
5141  ->getCanonicalDecl() == CanonPVD) {
5142  // OpenMP [2.15.3.7, linear Clause, Restrictions]
5143  // A list-item cannot appear in more than one linear clause.
5144  if (LinearArgs.count(CanonPVD) > 0) {
5145  Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5146  << getOpenMPClauseName(OMPC_linear)
5147  << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
5148  Diag(LinearArgs[CanonPVD]->getExprLoc(),
5149  diag::note_omp_explicit_dsa)
5150  << getOpenMPClauseName(OMPC_linear);
5151  continue;
5152  }
5153  // Each argument can appear in at most one uniform or linear clause.
5154  if (UniformedArgs.count(CanonPVD) > 0) {
5155  Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5156  << getOpenMPClauseName(OMPC_linear)
5158  Diag(UniformedArgs[CanonPVD]->getExprLoc(),
5159  diag::note_omp_explicit_dsa)
5161  continue;
5162  }
5163  LinearArgs[CanonPVD] = E;
5164  if (E->isValueDependent() || E->isTypeDependent() ||
5165  E->isInstantiationDependent() ||
5167  continue;
5168  (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
5169  PVD->getOriginalType());
5170  continue;
5171  }
5172  }
5173  if (isa<CXXThisExpr>(E)) {
5174  if (UniformedLinearThis) {
5175  Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
5176  << getOpenMPClauseName(OMPC_linear)
5177  << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
5178  << E->getSourceRange();
5179  Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
5180  << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
5181  : OMPC_linear);
5182  continue;
5183  }
5184  UniformedLinearThis = E;
5185  if (E->isValueDependent() || E->isTypeDependent() ||
5187  continue;
5188  (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
5189  E->getType());
5190  continue;
5191  }
5192  Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
5193  << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
5194  }
5195  Expr *Step = nullptr;
5196  Expr *NewStep = nullptr;
5197  SmallVector<Expr *, 4> NewSteps;
5198  for (Expr *E : Steps) {
5199  // Skip the same step expression, it was checked already.
5200  if (Step == E || !E) {
5201  NewSteps.push_back(E ? NewStep : nullptr);
5202  continue;
5203  }
5204  Step = E;
5205  if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
5206  if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
5207  const VarDecl *CanonPVD = PVD->getCanonicalDecl();
5208  if (UniformedArgs.count(CanonPVD) == 0) {
5209  Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
5210  << Step->getSourceRange();
5211  } else if (E->isValueDependent() || E->isTypeDependent() ||
5212  E->isInstantiationDependent() ||
5214  CanonPVD->getType()->hasIntegerRepresentation()) {
5215  NewSteps.push_back(Step);
5216  } else {
5217  Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
5218  << Step->getSourceRange();
5219  }
5220  continue;
5221  }
5222  NewStep = Step;
5223  if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
5224  !Step->isInstantiationDependent() &&
5226  NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
5227  .get();
5228  if (NewStep)
5229  NewStep = VerifyIntegerConstantExpression(NewStep).get();
5230  }
5231  NewSteps.push_back(NewStep);
5232  }
5233  auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
5234  Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
5235  Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
5236  const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
5237  const_cast<Expr **>(Linears.data()), Linears.size(),
5238  const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
5239  NewSteps.data(), NewSteps.size(), SR);
5240  ADecl->addAttr(NewAttr);
5241  return DG;
5242 }
5243 
5244 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
5245  QualType NewType) {
5246  assert(NewType->isFunctionProtoType() &&
5247  "Expected function type with prototype.");
5248  assert(FD->getType()->isFunctionNoProtoType() &&
5249  "Expected function with type with no prototype.");
5250  assert(FDWithProto->getType()->isFunctionProtoType() &&
5251  "Expected function with prototype.");
5252  // Synthesize parameters with the same types.
5253  FD->setType(NewType);
5255  for (const ParmVarDecl *P : FDWithProto->parameters()) {
5256  auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(),
5257  SourceLocation(), nullptr, P->getType(),
5258  /*TInfo=*/nullptr, SC_None, nullptr);
5259  Param->setScopeInfo(0, Params.size());
5260  Param->setImplicit();
5261  Params.push_back(Param);
5262  }
5263 
5264  FD->setParams(Params);
5265 }
5266 
5269  Expr *VariantRef, SourceRange SR) {
5270  if (!DG || DG.get().isNull())
5271  return None;
5272 
5273  const int VariantId = 1;
5274  // Must be applied only to single decl.
5275  if (!DG.get().isSingleDecl()) {
5276  Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
5277  << VariantId << SR;
5278  return None;
5279  }
5280  Decl *ADecl = DG.get().getSingleDecl();
5281  if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
5282  ADecl = FTD->getTemplatedDecl();
5283 
5284  // Decl must be a function.
5285  auto *FD = dyn_cast<FunctionDecl>(ADecl);
5286  if (!FD) {
5287  Diag(ADecl->getLocation(), diag::err_omp_function_expected)
5288  << VariantId << SR;
5289  return None;
5290  }
5291 
5292  auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
5293  return FD->hasAttrs() &&
5294  (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() ||
5295  FD->hasAttr<TargetAttr>());
5296  };
5297  // OpenMP is not compatible with CPU-specific attributes.
5298  if (HasMultiVersionAttributes(FD)) {
5299  Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
5300  << SR;
5301  return None;
5302  }
5303 
5304  // Allow #pragma omp declare variant only if the function is not used.
5305  if (FD->isUsed(false))
5306  Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
5307  << FD->getLocation();
5308 
5309  // Check if the function was emitted already.
5310  const FunctionDecl *Definition;
5311  if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) &&
5312  (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition)))
5313  Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
5314  << FD->getLocation();
5315 
5316  // The VariantRef must point to function.
5317  if (!VariantRef) {
5318  Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
5319  return None;
5320  }
5321 
5322  // Do not check templates, wait until instantiation.
5323  if (VariantRef->isTypeDependent() || VariantRef->isValueDependent() ||
5324  VariantRef->containsUnexpandedParameterPack() ||
5325  VariantRef->isInstantiationDependent() || FD->isDependentContext())
5326  return std::make_pair(FD, VariantRef);
5327 
5328  // Convert VariantRef expression to the type of the original function to
5329  // resolve possible conflicts.
5330  ExprResult VariantRefCast;
5331  if (LangOpts.CPlusPlus) {
5332  QualType FnPtrType;
5333  auto *Method = dyn_cast<CXXMethodDecl>(FD);
5334  if (Method && !Method->isStatic()) {
5335  const Type *ClassType =
5336  Context.getTypeDeclType(Method->getParent()).getTypePtr();
5337  FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType);
5338  ExprResult ER;
5339  {
5340  // Build adrr_of unary op to correctly handle type checks for member
5341  // functions.
5342  Sema::TentativeAnalysisScope Trap(*this);
5343  ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf,
5344  VariantRef);
5345  }
5346  if (!ER.isUsable()) {
5347  Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
5348  << VariantId << VariantRef->getSourceRange();
5349  return None;
5350  }
5351  VariantRef = ER.get();
5352  } else {
5353  FnPtrType = Context.getPointerType(FD->getType());
5354  }
5356  TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(),
5357  /*SuppressUserConversions=*/false,
5358  /*AllowExplicit=*/false,
5359  /*InOverloadResolution=*/false,
5360  /*CStyle=*/false,
5361  /*AllowObjCWritebackConversion=*/false);
5362  if (ICS.isFailure()) {
5363  Diag(VariantRef->getExprLoc(),
5364  diag::err_omp_declare_variant_incompat_types)
5365  << VariantRef->getType()
5366  << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
5367  << VariantRef->getSourceRange();
5368  return None;
5369  }
5370  VariantRefCast = PerformImplicitConversion(
5371  VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
5372  if (!VariantRefCast.isUsable())
5373  return None;
5374  // Drop previously built artificial addr_of unary op for member functions.
5375  if (Method && !Method->isStatic()) {
5376  Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
5377  if (auto *UO = dyn_cast<UnaryOperator>(
5378  PossibleAddrOfVariantRef->IgnoreImplicit()))
5379  VariantRefCast = UO->getSubExpr();
5380  }
5381  } else {
5382  VariantRefCast = VariantRef;
5383  }
5384 
5385  ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get());
5386  if (!ER.isUsable() ||
5387  !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
5388  Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
5389  << VariantId << VariantRef->getSourceRange();
5390  return None;
5391  }
5392 
5393  // The VariantRef must point to function.
5394  auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts());
5395  if (!DRE) {
5396  Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
5397  << VariantId << VariantRef->getSourceRange();
5398  return None;
5399  }
5400  auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
5401  if (!NewFD) {
5402  Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
5403  << VariantId << VariantRef->getSourceRange();
5404  return None;
5405  }
5406 
5407  // Check if function types are compatible in C.
5408  if (!LangOpts.CPlusPlus) {
5409  QualType NewType =
5410  Context.mergeFunctionTypes(FD->getType(), NewFD->getType());
5411  if (NewType.isNull()) {
5412  Diag(VariantRef->getExprLoc(),
5413  diag::err_omp_declare_variant_incompat_types)
5414  << NewFD->getType() << FD->getType() << VariantRef->getSourceRange();
5415  return None;
5416  }
5417  if (NewType->isFunctionProtoType()) {
5418  if (FD->getType()->isFunctionNoProtoType())
5419  setPrototype(*this, FD, NewFD, NewType);
5420  else if (NewFD->getType()->isFunctionNoProtoType())
5421  setPrototype(*this, NewFD, FD, NewType);
5422  }
5423  }
5424 
5425  // Check if variant function is not marked with declare variant directive.
5426  if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
5427  Diag(VariantRef->getExprLoc(),
5428  diag::warn_omp_declare_variant_marked_as_declare_variant)
5429  << VariantRef->getSourceRange();
5430  SourceRange SR =
5431  NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
5432  Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
5433  return None;
5434  }
5435 
5436  enum DoesntSupport {
5437  VirtFuncs = 1,
5438  Constructors = 3,
5439  Destructors = 4,
5440  DeletedFuncs = 5,
5441  DefaultedFuncs = 6,
5442  ConstexprFuncs = 7,
5443  ConstevalFuncs = 8,
5444  };
5445  if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
5446  if (CXXFD->isVirtual()) {
5447  Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5448  << VirtFuncs;
5449  return None;
5450  }
5451 
5452  if (isa<CXXConstructorDecl>(FD)) {
5453  Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5454  << Constructors;
5455  return None;
5456  }
5457 
5458  if (isa<CXXDestructorDecl>(FD)) {
5459  Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5460  << Destructors;
5461  return None;
5462  }
5463  }
5464 
5465  if (FD->isDeleted()) {
5466  Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5467  << DeletedFuncs;
5468  return None;
5469  }
5470 
5471  if (FD->isDefaulted()) {
5472  Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5473  << DefaultedFuncs;
5474  return None;
5475  }
5476 
5477  if (FD->isConstexpr()) {
5478  Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
5479  << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
5480  return None;
5481  }
5482 
5483  // Check general compatibility.
5484  if (areMultiversionVariantFunctionsCompatible(
5485  FD, NewFD, PartialDiagnostic::NullDiagnostic(),
5489  VariantRef->getExprLoc(),
5490  PDiag(diag::err_omp_declare_variant_doesnt_support)),
5491  PartialDiagnosticAt(VariantRef->getExprLoc(),
5492  PDiag(diag::err_omp_declare_variant_diff)
5493  << FD->getLocation()),
5494  /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
5495  /*CLinkageMayDiffer=*/true))
5496  return None;
5497  return std::make_pair(FD, cast<Expr>(DRE));
5498 }
5499 
5501  FunctionDecl *FD, Expr *VariantRef, SourceRange SR,
5503  if (Data.empty())
5504  return;
5505  SmallVector<Expr *, 4> CtxScores;
5506  SmallVector<unsigned, 4> CtxSets;
5508  SmallVector<StringRef, 4> ImplVendors, DeviceKinds;
5509  bool IsError = false;
5510  for (const OMPCtxSelectorData &D : Data) {
5511  OpenMPContextSelectorSetKind CtxSet = D.CtxSet;
5512  OpenMPContextSelectorKind Ctx = D.Ctx;
5513  if (CtxSet == OMP_CTX_SET_unknown || Ctx == OMP_CTX_unknown)
5514  return;
5515  Expr *Score = nullptr;
5516  if (D.Score.isUsable()) {
5517  Score = D.Score.get();
5518  if (!Score->isTypeDependent() && !Score->isValueDependent() &&
5519  !Score->isInstantiationDependent() &&
5520  !Score->containsUnexpandedParameterPack()) {
5521  Score =
5522  PerformOpenMPImplicitIntegerConversion(Score->getExprLoc(), Score)
5523  .get();
5524  if (Score)
5525  Score = VerifyIntegerConstantExpression(Score).get();
5526  }
5527  } else {
5528  // OpenMP 5.0, 2.3.3 Matching and Scoring Context Selectors.
5529  // The kind, arch, and isa selectors are given the values 2^l, 2^(l+1) and
5530  // 2^(l+2), respectively, where l is the number of traits in the construct
5531  // set.
5532  // TODO: implement correct logic for isa and arch traits.
5533  // TODO: take the construct context set into account when it is
5534  // implemented.
5535  int L = 0; // Currently set the number of traits in construct set to 0,
5536  // since the construct trait set in not supported yet.
5537  if (CtxSet == OMP_CTX_SET_device && Ctx == OMP_CTX_kind)
5538  Score = ActOnIntegerConstant(SourceLocation(), std::pow(2, L)).get();
5539  else
5540  Score = ActOnIntegerConstant(SourceLocation(), 0).get();
5541  }
5542  switch (Ctx) {
5543  case OMP_CTX_vendor:
5544  assert(CtxSet == OMP_CTX_SET_implementation &&
5545  "Expected implementation context selector set.");
5546  ImplVendors.append(D.Names.begin(), D.Names.end());
5547  break;
5548  case OMP_CTX_kind:
5549  assert(CtxSet == OMP_CTX_SET_device &&
5550  "Expected device context selector set.");
5551  DeviceKinds.append(D.Names.begin(), D.Names.end());
5552  break;
5553  case OMP_CTX_unknown:
5554  llvm_unreachable("Unknown context selector kind.");
5555  }
5556  IsError = IsError || !Score;
5557  CtxSets.push_back(CtxSet);
5558  Ctxs.push_back(Ctx);
5559  CtxScores.push_back(Score);
5560  }
5561  if (!IsError) {
5562  auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit(
5563  Context, VariantRef, CtxScores.begin(), CtxScores.size(),
5564  CtxSets.begin(), CtxSets.size(), Ctxs.begin(), Ctxs.size(),
5565  ImplVendors.begin(), ImplVendors.size(), DeviceKinds.begin(),
5566  DeviceKinds.size(), SR);
5567  FD->addAttr(NewAttr);
5568  }
5569 }
5570 
5571 void Sema::markOpenMPDeclareVariantFuncsReferenced(SourceLocation Loc,
5572  FunctionDecl *Func,
5573  bool MightBeOdrUse) {
5574  assert(LangOpts.OpenMP && "Expected OpenMP mode.");
5575 
5576  if (!Func->isDependentContext() && Func->hasAttrs()) {
5577  for (OMPDeclareVariantAttr *A :
5578  Func->specific_attrs<OMPDeclareVariantAttr>()) {
5579  // TODO: add checks for active OpenMP context where possible.
5580  Expr *VariantRef = A->getVariantFuncRef();
5581  auto *DRE = cast<DeclRefExpr>(VariantRef->IgnoreParenImpCasts());
5582  auto *F = cast<FunctionDecl>(DRE->getDecl());
5583  if (!F->isDefined() && F->isTemplateInstantiation())
5584  InstantiateFunctionDefinition(Loc, F->getFirstDecl());
5585  MarkFunctionReferenced(Loc, F, MightBeOdrUse);
5586  }
5587  }
5588 }
5589 
5591  Stmt *AStmt,
5592  SourceLocation StartLoc,
5593  SourceLocation EndLoc) {
5594  if (!AStmt)
5595  return StmtError();
5596 
5597  auto *CS = cast<CapturedStmt>(AStmt);
5598  // 1.2.2 OpenMP Language Terminology
5599  // Structured block - An executable statement with a single entry at the
5600  // top and a single exit at the bottom.
5601  // The point of exit cannot be a branch out of the structured block.
5602  // longjmp() and throw() must not violate the entry/exit criteria.
5603  CS->getCapturedDecl()->setNothrow();
5604 
5605  setFunctionHasBranchProtectedScope();
5606 
5607  return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
5608  DSAStack->isCancelRegion());
5609 }
5610 
5611 namespace {
5612 /// Iteration space of a single for loop.
5613 struct LoopIterationSpace final {
5614  /// True if the condition operator is the strict compare operator (<, > or
5615  /// !=).
5616  bool IsStrictCompare = false;
5617  /// Condition of the loop.
5618  Expr *PreCond = nullptr;
5619  /// This expression calculates the number of iterations in the loop.
5620  /// It is always possible to calculate it before starting the loop.
5621  Expr *NumIterations = nullptr;
5622  /// The loop counter variable.
5623  Expr *CounterVar = nullptr;
5624  /// Private loop counter variable.
5625  Expr *PrivateCounterVar = nullptr;
5626  /// This is initializer for the initial value of #CounterVar.
5627  Expr *CounterInit = nullptr;
5628  /// This is step for the #CounterVar used to generate its update:
5629  /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
5630  Expr *CounterStep = nullptr;
5631  /// Should step be subtracted?
5632  bool Subtract = false;
5633  /// Source range of the loop init.
5634  SourceRange InitSrcRange;
5635  /// Source range of the loop condition.
5636  SourceRange CondSrcRange;
5637  /// Source range of the loop increment.
5638  SourceRange IncSrcRange;
5639  /// Minimum value that can have the loop control variable. Used to support
5640  /// non-rectangular loops. Applied only for LCV with the non-iterator types,
5641  /// since only such variables can be used in non-loop invariant expressions.
5642  Expr *MinValue = nullptr;
5643  /// Maximum value that can have the loop control variable. Used to support
5644  /// non-rectangular loops. Applied only for LCV with the non-iterator type,
5645  /// since only such variables can be used in non-loop invariant expressions.
5646  Expr *MaxValue = nullptr;
5647  /// true, if the lower bound depends on the outer loop control var.
5648  bool IsNonRectangularLB = false;
5649  /// true, if the upper bound depends on the outer loop control var.
5650  bool IsNonRectangularUB = false;
5651  /// Index of the loop this loop depends on and forms non-rectangular loop
5652  /// nest.
5653  unsigned LoopDependentIdx = 0;
5654  /// Final condition for the non-rectangular loop nest support. It is used to
5655  /// check that the number of iterations for this particular counter must be
5656  /// finished.
5657  Expr *FinalCondition = nullptr;
5658 };
5659 
5660 /// Helper class for checking canonical form of the OpenMP loops and
5661 /// extracting iteration space of each loop in the loop nest, that will be used
5662 /// for IR generation.
5663 class OpenMPIterationSpaceChecker {
5664  /// Reference to Sema.
5665  Sema &SemaRef;
5666  /// Data-sharing stack.
5667  DSAStackTy &Stack;
5668  /// A location for diagnostics (when there is no some better location).
5669  SourceLocation DefaultLoc;
5670  /// A location for diagnostics (when increment is not compatible).
5671  SourceLocation ConditionLoc;
5672  /// A source location for referring to loop init later.
5673  SourceRange InitSrcRange;
5674  /// A source location for referring to condition later.
5675  SourceRange ConditionSrcRange;
5676  /// A source location for referring to increment later.
5677  SourceRange IncrementSrcRange;
5678  /// Loop variable.
5679  ValueDecl *LCDecl = nullptr;
5680  /// Reference to loop variable.
5681  Expr *LCRef = nullptr;
5682  /// Lower bound (initializer for the var).
5683  Expr *LB = nullptr;
5684  /// Upper bound.
5685  Expr *UB = nullptr;
5686  /// Loop step (increment).
5687  Expr *Step = nullptr;
5688  /// This flag is true when condition is one of:
5689  /// Var < UB
5690  /// Var <= UB
5691  /// UB > Var
5692  /// UB >= Var
5693  /// This will have no value when the condition is !=
5694  llvm::Optional<bool> TestIsLessOp;
5695  /// This flag is true when condition is strict ( < or > ).
5696  bool TestIsStrictOp = false;
5697  /// This flag is true when step is subtracted on each iteration.
5698  bool SubtractStep = false;
5699  /// The outer loop counter this loop depends on (if any).
5700  const ValueDecl *DepDecl = nullptr;
5701  /// Contains number of loop (starts from 1) on which loop counter init
5702  /// expression of this loop depends on.
5703  Optional<unsigned> InitDependOnLC;
5704  /// Contains number of loop (starts from 1) on which loop counter condition
5705  /// expression of this loop depends on.
5706  Optional<unsigned> CondDependOnLC;
5707  /// Checks if the provide statement depends on the loop counter.
5708  Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer);
5709  /// Original condition required for checking of the exit condition for
5710  /// non-rectangular loop.
5711  Expr *Condition = nullptr;
5712 
5713 public:
5714  OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack,
5715  SourceLocation DefaultLoc)
5716  : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc),
5717  ConditionLoc(DefaultLoc) {}
5718  /// Check init-expr for canonical loop form and save loop counter
5719  /// variable - #Var and its initialization value - #LB.
5720  bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
5721  /// Check test-expr for canonical form, save upper-bound (#UB), flags
5722  /// for less/greater and for strict/non-strict comparison.
5723  bool checkAndSetCond(Expr *S);
5724  /// Check incr-expr for canonical loop form and return true if it
5725  /// does not conform, otherwise save loop step (#Step).
5726  bool checkAndSetInc(Expr *S);
5727  /// Return the loop counter variable.
5728  ValueDecl *getLoopDecl() const { return LCDecl; }
5729  /// Return the reference expression to loop counter variable.
5730  Expr *getLoopDeclRefExpr() const { return LCRef; }
5731  /// Source range of the loop init.
5732  SourceRange getInitSrcRange() const { return InitSrcRange; }
5733  /// Source range of the loop condition.
5734  SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
5735  /// Source range of the loop increment.
5736  SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
5737  /// True if the step should be subtracted.
5738  bool shouldSubtractStep() const { return SubtractStep; }
5739  /// True, if the compare operator is strict (<, > or !=).
5740  bool isStrictTestOp() const { return TestIsStrictOp; }
5741  /// Build the expression to calculate the number of iterations.
5742  Expr *buildNumIterations(
5743  Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
5744  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
5745  /// Build the precondition expression for the loops.
5746  Expr *
5747  buildPreCond(Scope *S, Expr *Cond,
5748  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
5749  /// Build reference expression to the counter be used for codegen.
5750  DeclRefExpr *
5751  buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
5752  DSAStackTy &DSA) const;
5753  /// Build reference expression to the private counter be used for
5754  /// codegen.
5755  Expr *buildPrivateCounterVar() const;
5756  /// Build initialization of the counter be used for codegen.
5757  Expr *buildCounterInit() const;
5758  /// Build step of the counter be used for codegen.
5759  Expr *buildCounterStep() const;
5760  /// Build loop data with counter value for depend clauses in ordered
5761  /// directives.
5762  Expr *
5763  buildOrderedLoopData(Scope *S, Expr *Counter,
5764  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
5765  SourceLocation Loc, Expr *Inc = nullptr,
5766  OverloadedOperatorKind OOK = OO_Amp);
5767  /// Builds the minimum value for the loop counter.
5768  std::pair<Expr *, Expr *> buildMinMaxValues(
5769  Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
5770  /// Builds final condition for the non-rectangular loops.
5771  Expr *buildFinalCondition(Scope *S) const;
5772  /// Return true if any expression is dependent.
5773  bool dependent() const;
5774  /// Returns true if the initializer forms non-rectangular loop.
5775  bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); }
5776  /// Returns true if the condition forms non-rectangular loop.
5777  bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); }
5778  /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
5779  unsigned getLoopDependentIdx() const {
5780  return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0));
5781  }
5782 
5783 private:
5784  /// Check the right-hand side of an assignment in the increment
5785  /// expression.
5786  bool checkAndSetIncRHS(Expr *RHS);
5787  /// Helper to set loop counter variable and its initializer.
5788  bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
5789  bool EmitDiags);
5790  /// Helper to set upper bound.
5791  bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp,
5792  SourceRange SR, SourceLocation SL);
5793  /// Helper to set loop increment.
5794  bool setStep(Expr *NewStep, bool Subtract);
5795 };
5796 
5797 bool OpenMPIterationSpaceChecker::dependent() const {
5798  if (!LCDecl) {
5799  assert(!LB && !UB && !Step);
5800  return false;
5801  }
5802  return LCDecl->getType()->isDependentType() ||
5803  (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
5804  (Step && Step->isValueDependent());
5805 }
5806 
5807 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
5808  Expr *NewLCRefExpr,
5809  Expr *NewLB, bool EmitDiags) {
5810  // State consistency checking to ensure correct usage.
5811  assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
5812  UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
5813  if (!NewLCDecl || !NewLB)
5814  return true;
5815  LCDecl = getCanonicalDecl(NewLCDecl);
5816  LCRef = NewLCRefExpr;
5817  if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
5818  if (const CXXConstructorDecl *Ctor = CE->getConstructor())
5819  if ((Ctor->isCopyOrMoveConstructor() ||
5820  Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
5821  CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
5822  NewLB = CE->getArg(0)->IgnoreParenImpCasts();
5823  LB = NewLB;
5824  if (EmitDiags)
5825  InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
5826  return false;
5827 }
5828 
5829 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB,
5830  llvm::Optional<bool> LessOp,
5831  bool StrictOp, SourceRange SR,
5832  SourceLocation SL) {
5833  // State consistency checking to ensure correct usage.
5834  assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&
5835  Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
5836  if (!NewUB)
5837  return true;
5838  UB = NewUB;
5839  if (LessOp)
5840  TestIsLessOp = LessOp;
5841  TestIsStrictOp = StrictOp;
5842  ConditionSrcRange = SR;
5843  ConditionLoc = SL;
5844  CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
5845  return false;
5846 }
5847 
5848 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
5849  // State consistency checking to ensure correct usage.
5850  assert(LCDecl != nullptr && LB != nullptr && Step == nullptr);
5851  if (!NewStep)
5852  return true;
5853  if (!NewStep->isValueDependent()) {
5854  // Check that the step is integer expression.
5855  SourceLocation StepLoc = NewStep->getBeginLoc();
5857  StepLoc, getExprAsWritten(NewStep));
5858  if (Val.isInvalid())
5859  return true;
5860  NewStep = Val.get();
5861 
5862  // OpenMP [2.6, Canonical Loop Form, Restrictions]
5863  // If test-expr is of form var relational-op b and relational-op is < or
5864  // <= then incr-expr must cause var to increase on each iteration of the
5865  // loop. If test-expr is of form var relational-op b and relational-op is
5866  // > or >= then incr-expr must cause var to decrease on each iteration of
5867  // the loop.
5868  // If test-expr is of form b relational-op var and relational-op is < or
5869  // <= then incr-expr must cause var to decrease on each iteration of the
5870  // loop. If test-expr is of form b relational-op var and relational-op is
5871  // > or >= then incr-expr must cause var to increase on each iteration of
5872  // the loop.
5874  bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context);
5875  bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
5876  bool IsConstNeg =
5877  IsConstant && Result.isSigned() && (Subtract != Result.isNegative());
5878  bool IsConstPos =
5879  IsConstant && Result.isSigned() && (Subtract == Result.isNegative());
5880  bool IsConstZero = IsConstant && !Result.getBoolValue();
5881 
5882  // != with increment is treated as <; != with decrement is treated as >
5883  if (!TestIsLessOp.hasValue())
5884  TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
5885  if (UB && (IsConstZero ||
5886  (TestIsLessOp.getValue() ?
5887  (IsConstNeg || (IsUnsigned && Subtract)) :
5888  (IsConstPos || (IsUnsigned && !Subtract))))) {
5889  SemaRef.Diag(NewStep->getExprLoc(),
5890  diag::err_omp_loop_incr_not_compatible)
5891  << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange();
5892  SemaRef.Diag(ConditionLoc,
5893  diag::note_omp_loop_cond_requres_compatible_incr)
5894  << TestIsLessOp.getValue() << ConditionSrcRange;
5895  return true;
5896  }
5897  if (TestIsLessOp.getValue() == Subtract) {
5898  NewStep =
5899  SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
5900  .get();
5901  Subtract = !Subtract;
5902  }
5903  }
5904 
5905  Step = NewStep;
5906  SubtractStep = Subtract;
5907  return false;
5908 }
5909 
5910 namespace {
5911 /// Checker for the non-rectangular loops. Checks if the initializer or
5912 /// condition expression references loop counter variable.
5913 class LoopCounterRefChecker final
5914  : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
5915  Sema &SemaRef;
5916  DSAStackTy &Stack;
5917  const ValueDecl *CurLCDecl = nullptr;
5918  const ValueDecl *DepDecl = nullptr;
5919  const ValueDecl *PrevDepDecl = nullptr;
5920  bool IsInitializer = true;
5921  unsigned BaseLoopId = 0;
5922  bool checkDecl(const Expr *E, const ValueDecl *VD) {
5923  if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
5924  SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
5925  << (IsInitializer ? 0 : 1);
5926  return false;
5927  }
5928  const auto &&Data = Stack.isLoopControlVariable(VD);
5929  // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
5930  // The type of the loop iterator on which we depend may not have a random
5931  // access iterator type.
5932  if (Data.first && VD->getType()->isRecordType()) {
5933  SmallString<128> Name;
5934  llvm::raw_svector_ostream OS(Name);
5935  VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
5936  /*Qualified=*/true);
5937  SemaRef.Diag(E->getExprLoc(),
5938  diag::err_omp_wrong_dependency_iterator_type)
5939  << OS.str();
5940  SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
5941  return false;
5942  }
5943  if (Data.first &&
5944  (DepDecl || (PrevDepDecl &&
5945  getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
5946  if (!DepDecl && PrevDepDecl)
5947  DepDecl = PrevDepDecl;
5948  SmallString<128> Name;
5949  llvm::raw_svector_ostream OS(Name);
5950  DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
5951  /*Qualified=*/true);
5952  SemaRef.Diag(E->getExprLoc(),
5953  diag::err_omp_invariant_or_linear_dependency)
5954  << OS.str();
5955  return false;
5956  }
5957  if (Data.first) {
5958  DepDecl = VD;
5959  BaseLoopId = Data.first;
5960  }
5961  return Data.first;
5962  }
5963 
5964 public:
5965  bool VisitDeclRefExpr(const DeclRefExpr *E) {
5966  const ValueDecl *VD = E->getDecl();
5967  if (isa<VarDecl>(VD))
5968  return checkDecl(E, VD);
5969  return false;
5970  }
5971  bool VisitMemberExpr(const MemberExpr *E) {
5972  if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
5973  const ValueDecl *VD = E->getMemberDecl();
5974  if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
5975  return checkDecl(E, VD);
5976  }
5977  return false;
5978  }
5979  bool VisitStmt(const Stmt *S) {
5980  bool Res = false;
5981  for (const Stmt *Child : S->children())
5982  Res = (Child && Visit(Child)) || Res;
5983  return Res;
5984  }
5985  explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
5986  const ValueDecl *CurLCDecl, bool IsInitializer,
5987  const ValueDecl *PrevDepDecl = nullptr)
5988  : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
5989  PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {}
5990  unsigned getBaseLoopId() const {
5991  assert(CurLCDecl && "Expected loop dependency.");
5992  return BaseLoopId;
5993  }
5994  const ValueDecl *getDepDecl() const {
5995  assert(CurLCDecl && "Expected loop dependency.");
5996  return DepDecl;
5997  }
5998 };
5999 } // namespace
6000 
6002 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
6003  bool IsInitializer) {
6004  // Check for the non-rectangular loops.
6005  LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
6006  DepDecl);
6007  if (LoopStmtChecker.Visit(S)) {
6008  DepDecl = LoopStmtChecker.getDepDecl();
6009  return LoopStmtChecker.getBaseLoopId();
6010  }
6011  return llvm::None;
6012 }
6013 
6014 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
6015  // Check init-expr for canonical loop form and save loop counter
6016  // variable - #Var and its initialization value - #LB.
6017  // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
6018  // var = lb
6019  // integer-type var = lb
6020  // random-access-iterator-type var = lb
6021  // pointer-type var = lb
6022  //
6023  if (!S) {
6024  if (EmitDiags) {
6025  SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
6026  }
6027  return true;
6028  }
6029  if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
6030  if (!ExprTemp->cleanupsHaveSideEffects())
6031  S = ExprTemp->getSubExpr();
6032 
6033  InitSrcRange = S->getSourceRange();
6034  if (Expr *E = dyn_cast<Expr>(S))
6035  S = E->IgnoreParens();
6036  if (auto *BO = dyn_cast<BinaryOperator>(S)) {
6037  if (BO->getOpcode() == BO_Assign) {
6038  Expr *LHS = BO->getLHS()->IgnoreParens();
6039  if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
6040  if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
6041  if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
6042  return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6043  EmitDiags);
6044  return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
6045  }
6046  if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
6047  if (ME->isArrow() &&
6048  isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
6049  return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6050  EmitDiags);
6051  }
6052  }
6053  } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
6054  if (DS->isSingleDecl()) {
6055  if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
6056  if (Var->hasInit() && !Var->getType()->isReferenceType()) {
6057  // Accept non-canonical init form here but emit ext. warning.
6058  if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
6059  SemaRef.Diag(S->getBeginLoc(),
6060  diag::ext_omp_loop_not_canonical_init)
6061  << S->getSourceRange();
6062  return setLCDeclAndLB(
6063  Var,
6064  buildDeclRefExpr(SemaRef, Var,
6065  Var->getType().getNonReferenceType(),
6066  DS->getBeginLoc()),
6067  Var->getInit(), EmitDiags);
6068  }
6069  }
6070  }
6071  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
6072  if (CE->getOperator() == OO_Equal) {
6073  Expr *LHS = CE->getArg(0);
6074  if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
6075  if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
6076  if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
6077  return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6078  EmitDiags);
6079  return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
6080  }
6081  if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
6082  if (ME->isArrow() &&
6083  isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
6084  return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
6085  EmitDiags);
6086  }
6087  }
6088  }
6089 
6090  if (dependent() || SemaRef.CurContext->isDependentContext())
6091  return false;
6092  if (EmitDiags) {
6093  SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
6094  << S->getSourceRange();
6095  }
6096  return true;
6097 }
6098 
6099 /// Ignore parenthesizes, implicit casts, copy constructor and return the
6100 /// variable (which may be the loop variable) if possible.
6101 static const ValueDecl *getInitLCDecl(const Expr *E) {
6102  if (!E)
6103  return nullptr;
6104  E = getExprAsWritten(E);
6105  if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
6106  if (const CXXConstructorDecl *Ctor = CE->getConstructor())
6107  if ((Ctor->isCopyOrMoveConstructor() ||
6108  Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
6109  CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
6110  E = CE->getArg(0)->IgnoreParenImpCasts();
6111  if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
6112  if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
6113  return getCanonicalDecl(VD);
6114  }
6115  if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
6116  if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
6117  return getCanonicalDecl(ME->getMemberDecl());
6118  return nullptr;
6119 }
6120 
6121 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
6122  // Check test-expr for canonical form, save upper-bound UB, flags for
6123  // less/greater and for strict/non-strict comparison.
6124  // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following:
6125  // var relational-op b
6126  // b relational-op var
6127  //
6128  bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
6129  if (!S) {
6130  SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
6131  << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
6132  return true;
6133  }
6134  Condition = S;
6135  S = getExprAsWritten(S);
6136  SourceLocation CondLoc = S->getBeginLoc();
6137  if (auto *BO = dyn_cast<BinaryOperator>(S)) {
6138  if (BO->isRelationalOp()) {
6139  if (getInitLCDecl(BO->getLHS()) == LCDecl)
6140  return setUB(BO->getRHS(),
6141  (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
6142  (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
6143  BO->getSourceRange(), BO->getOperatorLoc());
6144  if (getInitLCDecl(BO->getRHS()) == LCDecl)
6145  return setUB(BO->getLHS(),
6146  (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
6147  (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
6148  BO->getSourceRange(), BO->getOperatorLoc());
6149  } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE)
6150  return setUB(
6151  getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(),
6152  /*LessOp=*/llvm::None,
6153  /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc());
6154  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
6155  if (CE->getNumArgs() == 2) {
6156  auto Op = CE->getOperator();
6157  switch (Op) {
6158  case OO_Greater:
6159  case OO_GreaterEqual:
6160  case OO_Less:
6161  case OO_LessEqual:
6162  if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6163  return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
6164  Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
6165  CE->getOperatorLoc());
6166  if (getInitLCDecl(CE->getArg(1)) == LCDecl)
6167  return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
6168  Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
6169  CE->getOperatorLoc());
6170  break;
6171  case OO_ExclaimEqual:
6172  if (IneqCondIsCanonical)
6173  return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1)
6174  : CE->getArg(0),
6175  /*LessOp=*/llvm::None,
6176  /*StrictOp=*/true, CE->getSourceRange(),
6177  CE->getOperatorLoc());
6178  break;
6179  default:
6180  break;
6181  }
6182  }
6183  }
6184  if (dependent() || SemaRef.CurContext->isDependentContext())
6185  return false;
6186  SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
6187  << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
6188  return true;
6189 }
6190 
6191 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
6192  // RHS of canonical loop form increment can be:
6193  // var + incr
6194  // incr + var
6195  // var - incr
6196  //
6197  RHS = RHS->IgnoreParenImpCasts();
6198  if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
6199  if (BO->isAdditiveOp()) {
6200  bool IsAdd = BO->getOpcode() == BO_Add;
6201  if (getInitLCDecl(BO->getLHS()) == LCDecl)
6202  return setStep(BO->getRHS(), !IsAdd);
6203  if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
6204  return setStep(BO->getLHS(), /*Subtract=*/false);
6205  }
6206  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
6207  bool IsAdd = CE->getOperator() == OO_Plus;
6208  if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
6209  if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6210  return setStep(CE->getArg(1), !IsAdd);
6211  if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
6212  return setStep(CE->getArg(0), /*Subtract=*/false);
6213  }
6214  }
6215  if (dependent() || SemaRef.CurContext->isDependentContext())
6216  return false;
6217  SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
6218  << RHS->getSourceRange() << LCDecl;
6219  return true;
6220 }
6221 
6222 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
6223  // Check incr-expr for canonical loop form and return true if it
6224  // does not conform.
6225  // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
6226  // ++var
6227  // var++
6228  // --var
6229  // var--
6230  // var += incr
6231  // var -= incr
6232  // var = var + incr
6233  // var = incr + var
6234  // var = var - incr
6235  //
6236  if (!S) {
6237  SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
6238  return true;
6239  }
6240  if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
6241  if (!ExprTemp->cleanupsHaveSideEffects())
6242  S = ExprTemp->getSubExpr();
6243 
6244  IncrementSrcRange = S->getSourceRange();
6245  S = S->IgnoreParens();
6246  if (auto *UO = dyn_cast<UnaryOperator>(S)) {
6247  if (UO->isIncrementDecrementOp() &&
6248  getInitLCDecl(UO->getSubExpr()) == LCDecl)
6249  return setStep(SemaRef
6250  .ActOnIntegerConstant(UO->getBeginLoc(),
6251  (UO->isDecrementOp() ? -1 : 1))
6252  .get(),
6253  /*Subtract=*/false);
6254  } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
6255  switch (BO->getOpcode()) {
6256  case BO_AddAssign:
6257  case BO_SubAssign:
6258  if (getInitLCDecl(BO->getLHS()) == LCDecl)
6259  return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
6260  break;
6261  case BO_Assign:
6262  if (getInitLCDecl(BO->getLHS()) == LCDecl)
6263  return checkAndSetIncRHS(BO->getRHS());
6264  break;
6265  default:
6266  break;
6267  }
6268  } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
6269  switch (CE->getOperator()) {
6270  case OO_PlusPlus:
6271  case OO_MinusMinus:
6272  if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6273  return setStep(SemaRef
6274  .ActOnIntegerConstant(
6275  CE->getBeginLoc(),
6276  ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
6277  .get(),
6278  /*Subtract=*/false);
6279  break;
6280  case OO_PlusEqual:
6281  case OO_MinusEqual:
6282  if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6283  return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
6284  break;
6285  case OO_Equal:
6286  if (getInitLCDecl(CE->getArg(0)) == LCDecl)
6287  return checkAndSetIncRHS(CE->getArg(1));
6288  break;
6289  default:
6290  break;
6291  }
6292  }
6293  if (dependent() || SemaRef.CurContext->isDependentContext())
6294  return false;
6295  SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
6296  << S->getSourceRange() << LCDecl;
6297  return true;
6298 }
6299 
6300 static ExprResult
6301 tryBuildCapture(Sema &SemaRef, Expr *Capture,
6302  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
6303  if (SemaRef.CurContext->isDependentContext())
6304  return ExprResult(Capture);
6305  if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
6306  return SemaRef.PerformImplicitConversion(
6307  Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
6308  /*AllowExplicit=*/true);
6309  auto I = Captures.find(Capture);
6310  if (I != Captures.end())
6311  return buildCapture(SemaRef, Capture, I->second);
6312  DeclRefExpr *Ref = nullptr;
6313  ExprResult Res = buildCapture(SemaRef, Capture, Ref);
6314  Captures[Capture] = Ref;
6315  return Res;
6316 }
6317 
6318 /// Build the expression to calculate the number of iterations.
6319 Expr *OpenMPIterationSpaceChecker::buildNumIterations(
6320  Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
6321  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
6322  ExprResult Diff;
6323  QualType VarType = LCDecl->getType().getNonReferenceType();
6324  if (VarType->isIntegerType() || VarType->isPointerType() ||
6325  SemaRef.getLangOpts().CPlusPlus) {
6326  Expr *LBVal = LB;
6327  Expr *UBVal = UB;
6328  // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
6329  // max(LB(MinVal), LB(MaxVal))
6330  if (InitDependOnLC) {
6331  const LoopIterationSpace &IS =
6332  ResultIterSpaces[ResultIterSpaces.size() - 1 -
6333  InitDependOnLC.getValueOr(
6334  CondDependOnLC.getValueOr(0))];
6335  if (!IS.MinValue || !IS.MaxValue)
6336  return nullptr;
6337  // OuterVar = Min
6338  ExprResult MinValue =
6339  SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
6340  if (!MinValue.isUsable())
6341  return nullptr;
6342 
6343  ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
6344  IS.CounterVar, MinValue.get());
6345  if (!LBMinVal.isUsable())
6346  return nullptr;
6347  // OuterVar = Min, LBVal
6348  LBMinVal =
6349  SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal);
6350  if (!LBMinVal.isUsable())
6351  return nullptr;
6352  // (OuterVar = Min, LBVal)
6353  LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get());
6354  if (!LBMinVal.isUsable())
6355  return nullptr;
6356 
6357  // OuterVar = Max
6358  ExprResult MaxValue =
6359  SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
6360  if (!MaxValue.isUsable())
6361  return nullptr;
6362 
6363  ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
6364  IS.CounterVar, MaxValue.get());
6365  if (!LBMaxVal.isUsable())
6366  return nullptr;
6367  // OuterVar = Max, LBVal
6368  LBMaxVal =
6369  SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal);
6370  if (!LBMaxVal.isUsable())
6371  return nullptr;
6372  // (OuterVar = Max, LBVal)
6373  LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get());
6374  if (!LBMaxVal.isUsable())
6375  return nullptr;
6376 
6377  Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get();
6378  Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get();
6379  if (!LBMin || !LBMax)
6380  return nullptr;
6381  // LB(MinVal) < LB(MaxVal)
6382  ExprResult MinLessMaxRes =
6383  SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
6384  if (!MinLessMaxRes.isUsable())
6385  return nullptr;
6386  Expr *MinLessMax =
6387  tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get();
6388  if (!MinLessMax)
6389  return nullptr;
6390  if (TestIsLessOp.getValue()) {
6391  // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
6392  // LB(MaxVal))
6393  ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
6394  MinLessMax, LBMin, LBMax);
6395  if (!MinLB.isUsable())
6396  return nullptr;
6397  LBVal = MinLB.get();
6398  } else {
6399  // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
6400  // LB(MaxVal))
6401  ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
6402  MinLessMax, LBMax, LBMin);
6403  if (!MaxLB.isUsable())
6404  return nullptr;
6405  LBVal = MaxLB.get();
6406  }
6407  }
6408  // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
6409  // min(UB(MinVal), UB(MaxVal))
6410  if (CondDependOnLC) {
6411  const LoopIterationSpace &IS =
6412  ResultIterSpaces[ResultIterSpaces.size() - 1 -
6413  InitDependOnLC.getValueOr(
6414  CondDependOnLC.getValueOr(0))];
6415  if (!IS.MinValue || !IS.MaxValue)
6416  return nullptr;
6417  // OuterVar = Min
6418  ExprResult MinValue =
6419  SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
6420  if (!MinValue.isUsable())
6421  return nullptr;
6422 
6423  ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
6424  IS.CounterVar, MinValue.get());
6425  if (!UBMinVal.isUsable())
6426  return nullptr;
6427  // OuterVar = Min, UBVal
6428  UBMinVal =
6429  SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal);
6430  if (!UBMinVal.isUsable())
6431  return nullptr;
6432  // (OuterVar = Min, UBVal)
6433  UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get());
6434  if (!UBMinVal.isUsable())
6435  return nullptr;
6436 
6437  // OuterVar = Max
6438  ExprResult MaxValue =
6439  SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
6440  if (!MaxValue.isUsable())
6441  return nullptr;
6442 
6443  ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
6444  IS.CounterVar, MaxValue.get());
6445  if (!UBMaxVal.isUsable())
6446  return nullptr;
6447  // OuterVar = Max, UBVal
6448  UBMaxVal =
6449  SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal);
6450  if (!UBMaxVal.isUsable())
6451  return nullptr;
6452  // (OuterVar = Max, UBVal)
6453  UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get());
6454  if (!UBMaxVal.isUsable())
6455  return nullptr;
6456 
6457  Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get();
6458  Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get();
6459  if (!UBMin || !UBMax)
6460  return nullptr;
6461  // UB(MinVal) > UB(MaxVal)
6462  ExprResult MinGreaterMaxRes =
6463  SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
6464  if (!MinGreaterMaxRes.isUsable())
6465  return nullptr;
6466  Expr *MinGreaterMax =
6467  tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get();
6468  if (!MinGreaterMax)
6469  return nullptr;
6470  if (TestIsLessOp.getValue()) {
6471  // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
6472  // UB(MaxVal))
6473  ExprResult MaxUB = SemaRef.ActOnConditionalOp(
6474  DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
6475  if (!MaxUB.isUsable())
6476  return nullptr;
6477  UBVal = MaxUB.get();
6478  } else {
6479  // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
6480  // UB(MaxVal))
6481  ExprResult MinUB = SemaRef.ActOnConditionalOp(
6482  DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
6483  if (!MinUB.isUsable())
6484  return nullptr;
6485  UBVal = MinUB.get();
6486  }
6487  }
6488  // Upper - Lower
6489  Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal;
6490  Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal;
6491  Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
6492  Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
6493  if (!Upper || !Lower)
6494  return nullptr;
6495 
6496  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
6497 
6498  if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) {
6499  // BuildBinOp already emitted error, this one is to point user to upper
6500  // and lower bound, and to tell what is passed to 'operator-'.
6501  SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
6502  << Upper->getSourceRange() << Lower->getSourceRange();
6503  return nullptr;
6504  }
6505  }
6506 
6507  if (!Diff.isUsable())
6508  return nullptr;
6509 
6510  // Upper - Lower [- 1]
6511  if (TestIsStrictOp)
6512  Diff = SemaRef.BuildBinOp(
6513  S, DefaultLoc, BO_Sub, Diff.get(),
6514  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
6515  if (!Diff.isUsable())
6516  return nullptr;
6517 
6518  // Upper - Lower [- 1] + Step
6519  ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
6520  if (!NewStep.isUsable())
6521  return nullptr;
6522  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
6523  if (!Diff.isUsable())
6524  return nullptr;
6525 
6526  // Parentheses (for dumping/debugging purposes only).
6527  Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
6528  if (!Diff.isUsable())
6529  return nullptr;
6530 
6531  // (Upper - Lower [- 1] + Step) / Step
6532  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
6533  if (!Diff.isUsable())
6534  return nullptr;
6535 
6536  // OpenMP runtime requires 32-bit or 64-bit loop variables.
6537  QualType Type = Diff.get()->getType();
6538  ASTContext &C = SemaRef.Context;
6539  bool UseVarType = VarType->hasIntegerRepresentation() &&
6540  C.getTypeSize(Type) > C.getTypeSize(VarType);
6541  if (!Type->isIntegerType() || UseVarType) {
6542  unsigned NewSize =
6543  UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
6544  bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
6546  Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
6547  if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
6548  Diff = SemaRef.PerformImplicitConversion(
6549  Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
6550  if (!Diff.isUsable())
6551  return nullptr;
6552  }
6553  }
6554  if (LimitedType) {
6555  unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
6556  if (NewSize != C.getTypeSize(Type)) {
6557  if (NewSize < C.getTypeSize(Type)) {
6558  assert(NewSize == 64 && "incorrect loop var size");
6559  SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
6560  << InitSrcRange << ConditionSrcRange;
6561  }
6562  QualType NewType = C.getIntTypeForBitwidth(
6563  NewSize, Type->hasSignedIntegerRepresentation() ||
6564  C.getTypeSize(Type) < NewSize);
6565  if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
6566  Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
6567  Sema::AA_Converting, true);
6568  if (!Diff.isUsable())
6569  return nullptr;
6570  }
6571  }
6572  }
6573 
6574  return Diff.get();
6575 }
6576 
6577 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
6578  Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
6579  // Do not build for iterators, they cannot be used in non-rectangular loop
6580  // nests.
6581  if (LCDecl->getType()->isRecordType())
6582  return std::make_pair(nullptr, nullptr);
6583  // If we subtract, the min is in the condition, otherwise the min is in the
6584  // init value.
6585  Expr *MinExpr = nullptr;
6586  Expr *MaxExpr = nullptr;
6587  Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB;
6588  Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB;
6589  bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue()
6590  : CondDependOnLC.hasValue();
6591  bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue()
6592  : InitDependOnLC.hasValue();
6593  Expr *Lower =
6594  LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
6595  Expr *Upper =
6596  UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
6597  if (!Upper || !Lower)
6598  return std::make_pair(nullptr, nullptr);
6599 
6600  if (TestIsLessOp.getValue())
6601  MinExpr = Lower;
6602  else
6603  MaxExpr = Upper;
6604 
6605  // Build minimum/maximum value based on number of iterations.
6606  ExprResult Diff;
6607  QualType VarType = LCDecl->getType().getNonReferenceType();
6608 
6609  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
6610  if (!Diff.isUsable())
6611  return std::make_pair(nullptr, nullptr);
6612 
6613  // Upper - Lower [- 1]
6614  if (TestIsStrictOp)
6615  Diff = SemaRef.BuildBinOp(
6616  S, DefaultLoc, BO_Sub, Diff.get(),
6617  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
6618  if (!Diff.isUsable())
6619  return std::make_pair(nullptr, nullptr);
6620 
6621  // Upper - Lower [- 1] + Step
6622  ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
6623  if (!NewStep.isUsable())
6624  return std::make_pair(nullptr, nullptr);
6625 
6626  // Parentheses (for dumping/debugging purposes only).
6627  Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
6628  if (!Diff.isUsable())
6629  return std::make_pair(nullptr, nullptr);
6630 
6631  // (Upper - Lower [- 1]) / Step
6632  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
6633  if (!Diff.isUsable())
6634  return std::make_pair(nullptr, nullptr);
6635 
6636  // ((Upper - Lower [- 1]) / Step) * Step
6637  // Parentheses (for dumping/debugging purposes only).
6638  Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
6639  if (!Diff.isUsable())
6640  return std::make_pair(nullptr, nullptr);
6641 
6642  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get());
6643  if (!Diff.isUsable())
6644  return std::make_pair(nullptr, nullptr);
6645 
6646  // Convert to the original type or ptrdiff_t, if original type is pointer.
6647  if (!VarType->isAnyPointerType() &&
6648  !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) {
6649  Diff = SemaRef.PerformImplicitConversion(
6650  Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true);
6651  } else if (VarType->isAnyPointerType() &&
6652  !SemaRef.Context.hasSameType(
6653  Diff.get()->getType(),
6654  SemaRef.Context.getUnsignedPointerDiffType())) {
6655  Diff = SemaRef.PerformImplicitConversion(
6656  Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(),
6657  Sema::AA_Converting, /*AllowExplicit=*/true);
6658  }
6659  if (!Diff.isUsable())
6660  return std::make_pair(nullptr, nullptr);
6661 
6662  // Parentheses (for dumping/debugging purposes only).
6663  Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
6664  if (!Diff.isUsable())
6665  return std::make_pair(nullptr, nullptr);
6666 
6667  if (TestIsLessOp.getValue()) {
6668  // MinExpr = Lower;
6669  // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
6670  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get());
6671  if (!Diff.isUsable())
6672  return std::make_pair(nullptr, nullptr);
6673  Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false);
6674  if (!Diff.isUsable())
6675  return std::make_pair(nullptr, nullptr);
6676  MaxExpr = Diff.get();
6677  } else {
6678  // MaxExpr = Upper;
6679  // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
6680  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get());
6681  if (!Diff.isUsable())
6682  return std::make_pair(nullptr, nullptr);
6683  Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false);
6684  if (!Diff.isUsable())
6685  return std::make_pair(nullptr, nullptr);
6686  MinExpr = Diff.get();
6687  }
6688 
6689  return std::make_pair(MinExpr, MaxExpr);
6690 }
6691 
6692 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const {
6693  if (InitDependOnLC || CondDependOnLC)
6694  return Condition;
6695  return nullptr;
6696 }
6697 
6698 Expr *OpenMPIterationSpaceChecker::buildPreCond(
6699  Scope *S, Expr *Cond,
6700  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
6701  // Do not build a precondition when the condition/initialization is dependent
6702  // to prevent pessimistic early loop exit.
6703  // TODO: this can be improved by calculating min/max values but not sure that
6704  // it will be very effective.
6705  if (CondDependOnLC || InitDependOnLC)
6706  return SemaRef.PerformImplicitConversion(
6707  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(),
6708  SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
6709  /*AllowExplicit=*/true).get();
6710 
6711  // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
6712  Sema::TentativeAnalysisScope Trap(SemaRef);
6713 
6714  ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
6715  ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
6716  if (!NewLB.isUsable() || !NewUB.isUsable())
6717  return nullptr;
6718 
6719  ExprResult CondExpr =
6720  SemaRef.BuildBinOp(S, DefaultLoc,
6721  TestIsLessOp.getValue() ?
6722  (TestIsStrictOp ? BO_LT : BO_LE) :
6723  (TestIsStrictOp ? BO_GT : BO_GE),
6724  NewLB.get(), NewUB.get());
6725  if (CondExpr.isUsable()) {
6726  if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
6727  SemaRef.Context.BoolTy))
6728  CondExpr = SemaRef.PerformImplicitConversion(
6729  CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
6730  /*AllowExplicit=*/true);
6731  }
6732 
6733  // Otherwise use original loop condition and evaluate it in runtime.
6734  return CondExpr.isUsable() ? CondExpr.get() : Cond;
6735 }
6736 
6737 /// Build reference expression to the counter be used for codegen.
6738 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
6739  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
6740  DSAStackTy &DSA) const {
6741  auto *VD = dyn_cast<VarDecl>(LCDecl);
6742  if (!VD) {
6743  VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
6745  SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
6746  const DSAStackTy::DSAVarData Data =
6747  DSA.getTopDSA(LCDecl, /*FromParent=*/false);
6748  // If the loop control decl is explicitly marked as private, do not mark it
6749  // as captured again.
6750  if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
6751  Captures.insert(std::make_pair(LCRef, Ref));
6752  return Ref;
6753  }
6754  return cast<DeclRefExpr>(LCRef);
6755 }
6756 
6757 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
6758  if (LCDecl && !LCDecl->isInvalidDecl()) {
6759  QualType Type = LCDecl->getType().getNonReferenceType();
6760  VarDecl *PrivateVar = buildVarDecl(
6761  SemaRef, DefaultLoc, Type, LCDecl->getName(),
6762  LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
6763  isa<VarDecl>(LCDecl)
6764  ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
6765  : nullptr);
6766  if (PrivateVar->isInvalidDecl())
6767  return nullptr;
6768  return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
6769  }
6770  return nullptr;
6771 }
6772 
6773 /// Build initialization of the counter to be used for codegen.
6775 
6776 /// Build step of the counter be used for codegen.
6777 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
6778 
6779 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
6780  Scope *S, Expr *Counter,
6781  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
6782  Expr *Inc, OverloadedOperatorKind OOK) {
6783  Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
6784  if (!Cnt)
6785  return nullptr;
6786  if (Inc) {
6787  assert((OOK == OO_Plus || OOK == OO_Minus) &&
6788  "Expected only + or - operations for depend clauses.");
6789  BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
6790  Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
6791  if (!Cnt)
6792  return nullptr;
6793  }
6794  ExprResult Diff;
6795  QualType VarType = LCDecl->getType().getNonReferenceType();
6796  if (VarType->isIntegerType() || VarType->isPointerType() ||
6797  SemaRef.getLangOpts().CPlusPlus) {
6798  // Upper - Lower
6799  Expr *Upper = TestIsLessOp.getValue()
6800  ? Cnt
6801  : tryBuildCapture(SemaRef, UB, Captures).get();
6802  Expr *Lower = TestIsLessOp.getValue()
6803  ? tryBuildCapture(SemaRef, LB, Captures).get()
6804  : Cnt;
6805  if (!Upper || !Lower)
6806  return nullptr;
6807 
6808  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
6809 
6810  if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) {
6811  // BuildBinOp already emitted error, this one is to point user to upper
6812  // and lower bound, and to tell what is passed to 'operator-'.
6813  SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
6814  << Upper->getSourceRange() << Lower->getSourceRange();
6815  return nullptr;
6816  }
6817  }
6818 
6819  if (!Diff.isUsable())
6820  return nullptr;
6821 
6822  // Parentheses (for dumping/debugging purposes only).
6823  Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
6824  if (!Diff.isUsable())
6825  return nullptr;
6826 
6827  ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
6828  if (!NewStep.isUsable())
6829  return nullptr;
6830  // (Upper - Lower) / Step
6831  Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
6832  if (!Diff.isUsable())
6833  return nullptr;
6834 
6835  return Diff.get();
6836 }
6837 } // namespace
6838 
6840  assert(getLangOpts().OpenMP && "OpenMP is not active.");
6841  assert(Init && "Expected loop in canonical form.");
6842  unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
6843  if (AssociatedLoops > 0 &&
6844  isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
6845  DSAStack->loopStart();
6846  OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc);
6847  if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
6848  if (ValueDecl *D = ISC.getLoopDecl()) {
6849  auto *VD = dyn_cast<VarDecl>(D);
6850  DeclRefExpr *PrivateRef = nullptr;
6851  if (!VD) {
6852  if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
6853  VD = Private;
6854  } else {
6855  PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
6856  /*WithInit=*/false);
6857  VD = cast<VarDecl>(PrivateRef->getDecl());
6858  }
6859  }
6860  DSAStack->addLoopControlVariable(D, VD);
6861  const Decl *LD = DSAStack->getPossiblyLoopCunter();
6862  if (LD != D->getCanonicalDecl()) {
6863  DSAStack->resetPossibleLoopCounter();
6864  if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
6865  MarkDeclarationsReferencedInExpr(
6866  buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
6867  Var->getType().getNonLValueExprType(Context),
6868  ForLoc, /*RefersToCapture=*/true));
6869  }
6870  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
6871  // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
6872  // Referenced in a Construct, C/C++]. The loop iteration variable in the
6873  // associated for-loop of a simd construct with just one associated
6874  // for-loop may be listed in a linear clause with a constant-linear-step
6875  // that is the increment of the associated for-loop. The loop iteration
6876  // variable(s) in the associated for-loop(s) of a for or parallel for
6877  // construct may be listed in a private or lastprivate clause.
6878  DSAStackTy::DSAVarData DVar =
6879  DSAStack->getTopDSA(D, /*FromParent=*/false);
6880  // If LoopVarRefExpr is nullptr it means the corresponding loop variable
6881  // is declared in the loop and it is predetermined as a private.
6882  Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
6883  OpenMPClauseKind PredeterminedCKind =
6884  isOpenMPSimdDirective(DKind)
6885  ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
6886  : OMPC_private;
6887  if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
6888  DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
6889  (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
6890  DVar.CKind != OMPC_private))) ||
6891  ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
6892  DKind == OMPD_master_taskloop ||
6893  DKind == OMPD_parallel_master_taskloop ||
6894  isOpenMPDistributeDirective(DKind)) &&
6895  !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
6896  DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
6897  (DVar.CKind != OMPC_private || DVar.RefExpr)) {
6898  Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
6899  << getOpenMPClauseName(DVar.CKind)
6900  << getOpenMPDirectiveName(DKind)
6901  << getOpenMPClauseName(PredeterminedCKind);
6902  if (DVar.RefExpr == nullptr)
6903  DVar.CKind = PredeterminedCKind;
6904  reportOriginalDsa(*this, DSAStack, D, DVar,
6905  /*IsLoopIterVar=*/true);
6906  } else if (LoopDeclRefExpr) {
6907  // Make the loop iteration variable private (for worksharing
6908  // constructs), linear (for simd directives with the only one
6909  // associated loop) or lastprivate (for simd directives with several
6910  // collapsed or ordered loops).
6911  if (DVar.CKind == OMPC_unknown)
6912  DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
6913  PrivateRef);
6914  }
6915  }
6916  }
6917  DSAStack->setAssociatedLoops(AssociatedLoops - 1);
6918  }
6919 }
6920 
6921 /// Called on a for stmt to check and extract its iteration space
6922 /// for further processing (such as collapsing).
6924  OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
6925  unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
6926  unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
6927  Expr *OrderedLoopCountExpr,
6928  Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
6930  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
6931  // OpenMP [2.9.1, Canonical Loop Form]
6932  // for (init-expr; test-expr; incr-expr) structured-block
6933  // for (range-decl: range-expr) structured-block
6934  auto *For = dyn_cast_or_null<ForStmt>(S);
6935  auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
6936  // Ranged for is supported only in OpenMP 5.0.
6937  if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) {
6938  SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
6939  << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
6940  << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
6941  << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
6942  if (TotalNestedLoopCount > 1) {
6943  if (CollapseLoopCountExpr && OrderedLoopCountExpr)
6944  SemaRef.Diag(DSA.getConstructLoc(),
6945  diag::note_omp_collapse_ordered_expr)
6946  << 2 << CollapseLoopCountExpr->getSourceRange()
6947  << OrderedLoopCountExpr->getSourceRange();
6948  else if (CollapseLoopCountExpr)
6949  SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
6950  diag::note_omp_collapse_ordered_expr)
6951  << 0 << CollapseLoopCountExpr->getSourceRange();
6952  else
6953  SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
6954  diag::note_omp_collapse_ordered_expr)
6955  << 1 << OrderedLoopCountExpr->getSourceRange();
6956  }
6957  return true;
6958  }
6959  assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&
6960  "No loop body.");
6961 
6962  OpenMPIterationSpaceChecker ISC(SemaRef, DSA,
6963  For ? For->getForLoc() : CXXFor->getForLoc());
6964 
6965  // Check init.
6966  Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt();
6967  if (ISC.checkAndSetInit(Init))
6968  return true;
6969 
6970  bool HasErrors = false;
6971 
6972  // Check loop variable's type.
6973  if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
6974  // OpenMP [2.6, Canonical Loop Form]
6975  // Var is one of the following:
6976  // A variable of signed or unsigned integer type.
6977  // For C++, a variable of a random access iterator type.
6978  // For C, a variable of a pointer type.
6979  QualType VarType = LCDecl->getType().getNonReferenceType();
6980  if (!VarType->isDependentType() && !VarType->isIntegerType() &&
6981  !VarType->isPointerType() &&
6982  !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
6983  SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
6984  << SemaRef.getLangOpts().CPlusPlus;
6985  HasErrors = true;
6986  }
6987 
6988  // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
6989  // a Construct
6990  // The loop iteration variable(s) in the associated for-loop(s) of a for or
6991  // parallel for construct is (are) private.
6992  // The loop iteration variable in the associated for-loop of a simd
6993  // construct with just one associated for-loop is linear with a
6994  // constant-linear-step that is the increment of the associated for-loop.
6995  // Exclude loop var from the list of variables with implicitly defined data
6996  // sharing attributes.
6997  VarsWithImplicitDSA.erase(LCDecl);
6998 
6999  assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
7000 
7001  // Check test-expr.
7002  HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
7003 
7004  // Check incr-expr.
7005  HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
7006  }
7007 
7008  if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
7009  return HasErrors;
7010 
7011  // Build the loop's iteration space representation.
7012  ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
7013  DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
7014  ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
7015  ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
7016  (isOpenMPWorksharingDirective(DKind) ||
7017  isOpenMPTaskLoopDirective(DKind) ||
7019  Captures);
7020  ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
7021  ISC.buildCounterVar(Captures, DSA);
7022  ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
7023  ISC.buildPrivateCounterVar();
7024  ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
7025  ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
7026  ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
7027  ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
7028  ISC.getConditionSrcRange();
7029  ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
7030  ISC.getIncrementSrcRange();
7031  ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
7032  ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
7033  ISC.isStrictTestOp();
7034  std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
7035  ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
7036  ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
7037  ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
7038  ISC.buildFinalCondition(DSA.getCurScope());
7039  ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
7040  ISC.doesInitDependOnLC();
7041  ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
7042  ISC.doesCondDependOnLC();
7043  ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
7044  ISC.getLoopDependentIdx();
7045 
7046  HasErrors |=
7047  (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr ||
7048  ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr ||
7049  ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr ||
7050  ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr ||
7051  ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr ||
7052  ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr);
7053  if (!HasErrors && DSA.isOrderedRegion()) {
7054  if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
7055  if (CurrentNestedLoopCount <
7056  DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
7057  DSA.getOrderedRegionParam().second->setLoopNumIterations(
7058  CurrentNestedLoopCount,
7059  ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
7060  DSA.getOrderedRegionParam().second->setLoopCounter(
7061  CurrentNestedLoopCount,
7062  ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
7063  }
7064  }
7065  for (auto &Pair : DSA.getDoacrossDependClauses()) {
7066  if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
7067  // Erroneous case - clause has some problems.
7068  continue;
7069  }
7070  if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
7071  Pair.second.size() <= CurrentNestedLoopCount) {
7072  // Erroneous case - clause has some problems.
7073  Pair.first->setLoopData(CurrentNestedLoopCount, nullptr);
7074  continue;
7075  }
7076  Expr *CntValue;
7077  if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
7078  CntValue = ISC.buildOrderedLoopData(
7079  DSA.getCurScope(),
7080  ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
7081  Pair.first->getDependencyLoc());
7082  else
7083  CntValue = ISC.buildOrderedLoopData(
7084  DSA.getCurScope(),
7085  ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
7086  Pair.first->getDependencyLoc(),
7087  Pair.second[CurrentNestedLoopCount].first,
7088  Pair.second[CurrentNestedLoopCount].second);
7089  Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
7090  }
7091  }
7092 
7093  return HasErrors;
7094 }
7095 
7096 /// Build 'VarRef = Start.
7097 static ExprResult
7099  ExprResult Start, bool IsNonRectangularLB,
7100  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7101  // Build 'VarRef = Start.
7102  ExprResult NewStart = IsNonRectangularLB
7103  ? Start.get()
7104  : tryBuildCapture(SemaRef, Start.get(), Captures);
7105  if (!NewStart.isUsable())
7106  return ExprError();
7107  if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
7108  VarRef.get()->getType())) {
7109  NewStart = SemaRef.PerformImplicitConversion(
7110  NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
7111  /*AllowExplicit=*/true);
7112  if (!NewStart.isUsable())
7113  return ExprError();
7114  }
7115 
7116  ExprResult Init =
7117  SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
7118  return Init;
7119 }
7120 
7121 /// Build 'VarRef = Start + Iter * Step'.
7123  Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
7124  ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
7125  bool IsNonRectangularLB,
7126  llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
7127  // Add parentheses (for debugging purposes only).
7128  Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
7129  if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
7130  !Step.isUsable())
7131  return ExprError();
7132 
7133  ExprResult NewStep = Step;
7134  if (Captures)
7135  NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
7136  if (NewStep.isInvalid())
7137  return ExprError();
7138  ExprResult Update =
7139  SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
7140  if (!Update.isUsable())
7141  return ExprError();
7142 
7143  // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
7144  // 'VarRef = Start (+|-) Iter * Step'.
7145  if (!Start.isUsable())
7146  return ExprError();
7147  ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get());
7148  if (!NewStart.isUsable())
7149  return ExprError();
7150  if (Captures && !IsNonRectangularLB)
7151  NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
7152  if (NewStart.isInvalid())
7153  return ExprError();
7154 
7155  // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
7156  ExprResult SavedUpdate = Update;
7157  ExprResult UpdateVal;
7158  if (VarRef.get()->getType()->isOverloadableType() ||
7159  NewStart.get()->getType()->isOverloadableType() ||
7160  Update.get()->getType()->isOverloadableType()) {
7161  Sema::TentativeAnalysisScope Trap(SemaRef);
7162 
7163  Update =
7164  SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
7165  if (Update.isUsable()) {
7166  UpdateVal =
7167  SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
7168  VarRef.get(), SavedUpdate.get());
7169  if (UpdateVal.isUsable()) {
7170  Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
7171  UpdateVal.get());
7172  }
7173  }
7174  }
7175 
7176  // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
7177  if (!Update.isUsable() || !UpdateVal.isUsable()) {
7178  Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
7179  NewStart.get(), SavedUpdate.get());
7180  if (!Update.isUsable())
7181  return ExprError();
7182 
7183  if (!SemaRef.Context.hasSameType(Update.get()->getType(),
7184  VarRef.get()->getType())) {
7185  Update = SemaRef.PerformImplicitConversion(
7186  Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
7187  if (!Update.isUsable())
7188  return ExprError();
7189  }
7190 
7191  Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
7192  }
7193  return Update;
7194 }
7195 
7196 /// Convert integer expression \a E to make it have at least \a Bits
7197 /// bits.
7198 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
7199  if (E == nullptr)
7200  return ExprError();
7201  ASTContext &C = SemaRef.Context;
7202  QualType OldType = E->getType();
7203  unsigned HasBits = C.getTypeSize(OldType);
7204  if (HasBits >= Bits)
7205  return ExprResult(E);
7206  // OK to convert to signed, because new type has more bits than old.
7207  QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
7208  return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
7209  true);
7210 }
7211 
7212 /// Check if the given expression \a E is a constant integer that fits
7213 /// into \a Bits bits.
7214 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
7215  if (E == nullptr)
7216  return false;
7218  if (E->isIntegerConstantExpr(Result, SemaRef.Context))
7219  return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits);
7220  return false;
7221 }
7222 
7223 /// Build preinits statement for the given declarations.
7224 static Stmt *buildPreInits(ASTContext &Context,
7225  MutableArrayRef<Decl *> PreInits) {
7226  if (!PreInits.empty()) {
7227  return new (Context) DeclStmt(
7228  DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
7230  }
7231  return nullptr;
7232 }
7233 
7234 /// Build preinits statement for the given declarations.
7235 static Stmt *
7237  const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7238  if (!Captures.empty()) {
7239  SmallVector<Decl *, 16> PreInits;
7240  for (const auto &Pair : Captures)
7241  PreInits.push_back(Pair.second->getDecl());
7242  return buildPreInits(Context, PreInits);
7243  }
7244  return nullptr;
7245 }
7246 
7247 /// Build postupdate expression for the given list of postupdates expressions.
7248 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
7249  Expr *PostUpdate = nullptr;
7250  if (!PostUpdates.empty()) {
7251  for (Expr *E : PostUpdates) {
7252  Expr *ConvE = S.BuildCStyleCastExpr(
7253  E->getExprLoc(),
7255  E->getExprLoc(), E)
7256  .get();
7257  PostUpdate = PostUpdate
7258  ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
7259  PostUpdate, ConvE)
7260  .get()
7261  : ConvE;
7262  }
7263  }
7264  return PostUpdate;
7265 }
7266 
7267 /// Called on a for stmt to check itself and nested loops (if any).
7268 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
7269 /// number of collapsed loops otherwise.
7270 static unsigned
7271 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
7272  Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
7273  DSAStackTy &DSA,
7274  Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
7276  unsigned NestedLoopCount = 1;
7277  if (CollapseLoopCountExpr) {
7278  // Found 'collapse' clause - calculate collapse number.
7280  if (!CollapseLoopCountExpr->isValueDependent() &&
7281  CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
7282  NestedLoopCount = Result.Val.getInt().getLimitedValue();
7283  } else {
7284  Built.clear(/*Size=*/1);
7285  return 1;
7286  }
7287  }
7288  unsigned OrderedLoopCount = 1;
7289  if (OrderedLoopCountExpr) {
7290  // Found 'ordered' clause - calculate collapse number.
7291  Expr::EvalResult EVResult;
7292  if (!OrderedLoopCountExpr->isValueDependent() &&
7293  OrderedLoopCountExpr->EvaluateAsInt(EVResult,
7294  SemaRef.getASTContext())) {
7295  llvm::APSInt Result = EVResult.Val.getInt();
7296  if (Result.getLimitedValue() < NestedLoopCount) {
7297  SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
7298  diag::err_omp_wrong_ordered_loop_count)
7299  << OrderedLoopCountExpr->getSourceRange();
7300  SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
7301  diag::note_collapse_loop_count)
7302  << CollapseLoopCountExpr->getSourceRange();
7303  }
7304  OrderedLoopCount = Result.getLimitedValue();
7305  } else {
7306  Built.clear(/*Size=*/1);
7307  return 1;
7308  }
7309  }
7310  // This is helper routine for loop directives (e.g., 'for', 'simd',
7311  // 'for simd', etc.).
7312  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
7314  std::max(OrderedLoopCount, NestedLoopCount));
7315  Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true);
7316  for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
7318  DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
7319  std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
7320  OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures))
7321  return 0;
7322  // Move on to the next nested for loop, or to the loop body.
7323  // OpenMP [2.8.1, simd construct, Restrictions]
7324  // All loops associated with the construct must be perfectly nested; that
7325  // is, there must be no intervening code nor any OpenMP directive between
7326  // any two loops.
7327  if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
7328  CurStmt = For->getBody();
7329  } else {
7330  assert(isa<CXXForRangeStmt>(CurStmt) &&
7331  "Expected canonical for or range-based for loops.");
7332  CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody();
7333  }
7335  CurStmt, SemaRef.LangOpts.OpenMP >= 50);
7336  }
7337  for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) {
7339  DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
7340  std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr,
7341  OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures))
7342  return 0;
7343  if (Cnt > 0 && IterSpaces[Cnt].CounterVar) {
7344  // Handle initialization of captured loop iterator variables.
7345  auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
7346  if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
7347  Captures[DRE] = DRE;
7348  }
7349  }
7350  // Move on to the next nested for loop, or to the loop body.
7351  // OpenMP [2.8.1, simd construct, Restrictions]
7352  // All loops associated with the construct must be perfectly nested; that
7353  // is, there must be no intervening code nor any OpenMP directive between
7354  // any two loops.
7355  if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
7356  CurStmt = For->getBody();
7357  } else {
7358  assert(isa<CXXForRangeStmt>(CurStmt) &&
7359  "Expected canonical for or range-based for loops.");
7360  CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody();
7361  }
7363  CurStmt, SemaRef.LangOpts.OpenMP >= 50);
7364  }
7365 
7366  Built.clear(/* size */ NestedLoopCount);
7367 
7368  if (SemaRef.CurContext->isDependentContext())
7369  return NestedLoopCount;
7370 
7371  // An example of what is generated for the following code:
7372  //
7373  // #pragma omp simd collapse(2) ordered(2)
7374  // for (i = 0; i < NI; ++i)
7375  // for (k = 0; k < NK; ++k)
7376  // for (j = J0; j < NJ; j+=2) {
7377  // <loop body>
7378  // }
7379  //
7380  // We generate the code below.
7381  // Note: the loop body may be outlined in CodeGen.
7382  // Note: some counters may be C++ classes, operator- is used to find number of
7383  // iterations and operator+= to calculate counter value.
7384  // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
7385  // or i64 is currently supported).
7386  //
7387  // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
7388  // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
7389  // .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
7390  // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
7391  // // similar updates for vars in clauses (e.g. 'linear')
7392  // <loop body (using local i and j)>
7393  // }
7394  // i = NI; // assign final values of counters
7395  // j = NJ;
7396  //
7397 
7398  // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
7399  // the iteration counts of the collapsed for loops.
7400  // Precondition tests if there is at least one iteration (all conditions are
7401  // true).
7402  auto PreCond = ExprResult(IterSpaces[0].PreCond);
7403  Expr *N0 = IterSpaces[0].NumIterations;
7404  ExprResult LastIteration32 =
7405  widenIterationCount(/*Bits=*/32,
7406  SemaRef
7407  .PerformImplicitConversion(
7408  N0->IgnoreImpCasts(), N0->getType(),
7409  Sema::AA_Converting, /*AllowExplicit=*/true)
7410  .get(),
7411  SemaRef);
7412  ExprResult LastIteration64 = widenIterationCount(
7413  /*Bits=*/64,
7414  SemaRef
7415  .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
7417  /*AllowExplicit=*/true)
7418  .get(),
7419  SemaRef);
7420 
7421  if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
7422  return NestedLoopCount;
7423 
7424  ASTContext &C = SemaRef.Context;
7425  bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
7426 
7427  Scope *CurScope = DSA.getCurScope();
7428  for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
7429  if (PreCond.isUsable()) {
7430  PreCond =
7431  SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
7432  PreCond.get(), IterSpaces[Cnt].PreCond);
7433  }
7434  Expr *N = IterSpaces[Cnt].NumIterations;
7435  SourceLocation Loc = N->getExprLoc();
7436  AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
7437  if (LastIteration32.isUsable())
7438  LastIteration32 = SemaRef.BuildBinOp(
7439  CurScope, Loc, BO_Mul, LastIteration32.get(),
7440  SemaRef
7443  /*AllowExplicit=*/true)
7444  .get());
7445  if (LastIteration64.isUsable())
7446  LastIteration64 = SemaRef.BuildBinOp(
7447  CurScope, Loc, BO_Mul, LastIteration64.get(),
7448  SemaRef
7451  /*AllowExplicit=*/true)
7452  .get());
7453  }
7454 
7455  // Choose either the 32-bit or 64-bit version.
7456  ExprResult LastIteration = LastIteration64;
7457  if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
7458  (LastIteration32.isUsable() &&
7459  C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
7460  (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
7461  fitsInto(
7462  /*Bits=*/32,
7463  LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
7464  LastIteration64.get(), SemaRef))))
7465  LastIteration = LastIteration32;
7466  QualType VType = LastIteration.get()->getType();
7467  QualType RealVType = VType;
7468  QualType StrideVType = VType;
7469  if (isOpenMPTaskLoopDirective(DKind)) {
7470  VType =
7471  SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
7472  StrideVType =
7473  SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
7474  }
7475 
7476  if (!LastIteration.isUsable())
7477  return 0;
7478 
7479  // Save the number of iterations.
7480  ExprResult NumIterations = LastIteration;
7481  {
7482  LastIteration = SemaRef.BuildBinOp(
7483  CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
7484  LastIteration.get(),
7485  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7486  if (!LastIteration.isUsable())
7487  return 0;
7488  }
7489 
7490  // Calculate the last iteration number beforehand instead of doing this on
7491  // each iteration. Do not do this if the number of iterations may be kfold-ed.
7493  bool IsConstant =
7494  LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context);
7495  ExprResult CalcLastIteration;
7496  if (!IsConstant) {
7497  ExprResult SaveRef =
7498  tryBuildCapture(SemaRef, LastIteration.get(), Captures);
7499  LastIteration = SaveRef;
7500 
7501  // Prepare SaveRef + 1.
7502  NumIterations = SemaRef.BuildBinOp(
7503  CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
7504  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7505  if (!NumIterations.isUsable())
7506  return 0;
7507  }
7508 
7509  SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
7510 
7511  // Build variables passed into runtime, necessary for worksharing directives.
7512  ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
7514  isOpenMPDistributeDirective(DKind)) {
7515  // Lower bound variable, initialized with zero.
7516  VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
7517  LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
7518  SemaRef.AddInitializerToDecl(LBDecl,
7519  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
7520  /*DirectInit*/ false);
7521 
7522  // Upper bound variable, initialized with last iteration number.
7523  VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
7524  UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
7525  SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
7526  /*DirectInit*/ false);
7527 
7528  // A 32-bit variable-flag where runtime returns 1 for the last iteration.
7529  // This will be used to implement clause 'lastprivate'.
7530  QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
7531  VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
7532  IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
7533  SemaRef.AddInitializerToDecl(ILDecl,
7534  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
7535  /*DirectInit*/ false);
7536 
7537  // Stride variable returned by runtime (we initialize it to 1 by default).
7538  VarDecl *STDecl =
7539  buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
7540  ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
7541  SemaRef.AddInitializerToDecl(STDecl,
7542  SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
7543  /*DirectInit*/ false);
7544 
7545  // Build expression: UB = min(UB, LastIteration)
7546  // It is necessary for CodeGen of directives with static scheduling.
7547  ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
7548  UB.get(), LastIteration.get());
7549  ExprResult CondOp = SemaRef.ActOnConditionalOp(
7550  LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
7551  LastIteration.get(), UB.get());
7552  EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
7553  CondOp.get());
7554  EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
7555 
7556  // If we have a combined directive that combines 'distribute', 'for' or
7557  // 'simd' we need to be able to access the bounds of the schedule of the
7558  // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
7559  // by scheduling 'distribute' have to be passed to the schedule of 'for'.
7560  if (isOpenMPLoopBoundSharingDirective(DKind)) {
7561  // Lower bound variable, initialized with zero.
7562  VarDecl *CombLBDecl =
7563  buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
7564  CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
7565  SemaRef.AddInitializerToDecl(
7566  CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
7567  /*DirectInit*/ false);
7568 
7569  // Upper bound variable, initialized with last iteration number.
7570  VarDecl *CombUBDecl =
7571  buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
7572  CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
7573  SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
7574  /*DirectInit*/ false);
7575 
7576  ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
7577  CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
7578  ExprResult CombCondOp =
7579  SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
7580  LastIteration.get(), CombUB.get());
7581  CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
7582  CombCondOp.get());
7583  CombEUB =
7584  SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
7585 
7586  const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
7587  // We expect to have at least 2 more parameters than the 'parallel'
7588  // directive does - the lower and upper bounds of the previous schedule.
7589  assert(CD->getNumParams() >= 4 &&
7590  "Unexpected number of parameters in loop combined directive");
7591 
7592  // Set the proper type for the bounds given what we learned from the
7593  // enclosed loops.
7594  ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
7595  ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
7596 
7597  // Previous lower and upper bounds are obtained from the region
7598  // parameters.
7599  PrevLB =
7600  buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
7601  PrevUB =
7602  buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
7603  }
7604  }
7605 
7606  // Build the iteration variable and its initialization before loop.
7607  ExprResult IV;
7608  ExprResult Init, CombInit;
7609  {
7610  VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
7611  IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
7612  Expr *RHS =
7613  (isOpenMPWorksharingDirective(DKind) ||
7615  ? LB.get()
7616  : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
7617  Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
7618  Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
7619 
7620  if (isOpenMPLoopBoundSharingDirective(DKind)) {
7621  Expr *CombRHS =
7622  (isOpenMPWorksharingDirective(DKind) ||
7623  isOpenMPTaskLoopDirective(DKind) ||
7625  ? CombLB.get()
7626  : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
7627  CombInit =
7628  SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
7629  CombInit =
7630  SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
7631  }
7632  }
7633 
7634  bool UseStrictCompare =
7635  RealVType->hasUnsignedIntegerRepresentation() &&
7636  llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
7637  return LIS.IsStrictCompare;
7638  });
7639  // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
7640  // unsigned IV)) for worksharing loops.
7641  SourceLocation CondLoc = AStmt->getBeginLoc();
7642  Expr *BoundUB = UB.get();
7643  if (UseStrictCompare) {
7644  BoundUB =
7645  SemaRef
7646  .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
7647  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
7648  .get();
7649  BoundUB =
7650  SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
7651  }
7652  ExprResult Cond =
7653  (isOpenMPWorksharingDirective(DKind) ||
7655  ? SemaRef.BuildBinOp(CurScope, CondLoc,
7656  UseStrictCompare ? BO_LT : BO_LE, IV.get(),
7657  BoundUB)
7658  : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
7659  NumIterations.get());
7660  ExprResult CombDistCond;
7661  if (isOpenMPLoopBoundSharingDirective(DKind)) {
7662  CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
7663  NumIterations.get());
7664  }
7665 
7666  ExprResult CombCond;
7667  if (isOpenMPLoopBoundSharingDirective(DKind)) {
7668  Expr *BoundCombUB = CombUB.get();
7669  if (UseStrictCompare) {
7670  BoundCombUB =
7671  SemaRef
7672  .BuildBinOp(
7673  CurScope, CondLoc, BO_Add, BoundCombUB,
7674  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
7675  .get();
7676  BoundCombUB =
7677  SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
7678  .get();
7679  }
7680  CombCond =
7681  SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
7682  IV.get(), BoundCombUB);
7683  }
7684  // Loop increment (IV = IV + 1)
7685  SourceLocation IncLoc = AStmt->getBeginLoc();
7686  ExprResult Inc =
7687  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
7688  SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
7689  if (!Inc.isUsable())
7690  return 0;
7691  Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
7692  Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
7693  if (!Inc.isUsable())
7694  return 0;
7695 
7696  // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
7697  // Used for directives with static scheduling.
7698  // In combined construct, add combined version that use CombLB and CombUB
7699  // base variables for the update
7700  ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
7702  isOpenMPDistributeDirective(DKind)) {
7703  // LB + ST
7704  NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
7705  if (!NextLB.isUsable())
7706  return 0;
7707  // LB = LB + ST
7708  NextLB =
7709  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
7710  NextLB =
7711  SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
7712  if (!NextLB.isUsable())
7713  return 0;
7714  // UB + ST
7715  NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
7716  if (!NextUB.isUsable())
7717  return 0;
7718  // UB = UB + ST
7719  NextUB =
7720  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
7721  NextUB =
7722  SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
7723  if (!NextUB.isUsable())
7724  return 0;
7725  if (isOpenMPLoopBoundSharingDirective(DKind)) {
7726  CombNextLB =
7727  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
7728  if (!NextLB.isUsable())
7729  return 0;
7730  // LB = LB + ST
7731  CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
7732  CombNextLB.get());
7733  CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
7734  /*DiscardedValue*/ false);
7735  if (!CombNextLB.isUsable())
7736  return 0;
7737  // UB + ST
7738  CombNextUB =
7739  SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
7740  if (!CombNextUB.isUsable())
7741  return 0;
7742  // UB = UB + ST
7743  CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
7744  CombNextUB.get());
7745  CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
7746  /*DiscardedValue*/ false);
7747  if (!CombNextUB.isUsable())
7748  return 0;
7749  }
7750  }
7751 
7752  // Create increment expression for distribute loop when combined in a same
7753  // directive with for as IV = IV + ST; ensure upper bound expression based
7754  // on PrevUB instead of NumIterations - used to implement 'for' when found
7755  // in combination with 'distribute', like in 'distribute parallel for'
7756  SourceLocation DistIncLoc = AStmt->getBeginLoc();
7757  ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
7758  if (isOpenMPLoopBoundSharingDirective(DKind)) {
7759  DistCond = SemaRef.BuildBinOp(
7760  CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
7761  assert(DistCond.isUsable() && "distribute cond expr was not built");
7762 
7763  DistInc =
7764  SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
7765  assert(DistInc.isUsable() && "distribute inc expr was not built");
7766  DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
7767  DistInc.get());
7768  DistInc =
7769  SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
7770  assert(DistInc.isUsable() && "distribute inc expr was not built");
7771 
7772  // Build expression: UB = min(UB, prevUB) for #for in composite or combined
7773  // construct
7774  SourceLocation DistEUBLoc = AStmt->getBeginLoc();
7775  ExprResult IsUBGreater =
7776  SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get());
7777  ExprResult CondOp = SemaRef.ActOnConditionalOp(
7778  DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
7779  PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
7780  CondOp.get());
7781  PrevEUB =
7782  SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
7783 
7784  // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
7785  // parallel for is in combination with a distribute directive with
7786  // schedule(static, 1)
7787  Expr *BoundPrevUB = PrevUB.get();
7788  if (UseStrictCompare) {
7789  BoundPrevUB =
7790  SemaRef
7791  .BuildBinOp(
7792  CurScope, CondLoc, BO_Add, BoundPrevUB,
7793  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
7794  .get();
7795  BoundPrevUB =
7796  SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
7797  .get();
7798  }
7799  ParForInDistCond =
7800  SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
7801  IV.get(), BoundPrevUB);
7802  }
7803 
7804  // Build updates and final values of the loop counters.
7805  bool HasErrors = false;
7806  Built.Counters.resize(NestedLoopCount);
7807  Built.Inits.resize(NestedLoopCount);
7808  Built.Updates.resize(NestedLoopCount);
7809  Built.Finals.resize(NestedLoopCount);
7810  Built.DependentCounters.resize(NestedLoopCount);
7811  Built.DependentInits.resize(NestedLoopCount);
7812  Built.FinalsConditions.resize(NestedLoopCount);
7813  {
7814  // We implement the following algorithm for obtaining the
7815  // original loop iteration variable values based on the
7816  // value of the collapsed loop iteration variable IV.
7817  //
7818  // Let n+1 be the number of collapsed loops in the nest.
7819  // Iteration variables (I0, I1, .... In)
7820  // Iteration counts (N0, N1, ... Nn)
7821  //
7822  // Acc = IV;
7823  //
7824  // To compute Ik for loop k, 0 <= k <= n, generate:
7825  // Prod = N(k+1) * N(k+2) * ... * Nn;
7826  // Ik = Acc / Prod;
7827  // Acc -= Ik * Prod;
7828  //
7829  ExprResult Acc = IV;
7830  for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
7831  LoopIterationSpace &IS = IterSpaces[Cnt];
7832  SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
7833  ExprResult Iter;
7834 
7835  // Compute prod
7836  ExprResult Prod =
7837  SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
7838  for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K)
7839  Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
7840  IterSpaces[K].NumIterations);
7841 
7842  // Iter = Acc / Prod
7843  // If there is at least one more inner loop to avoid
7844  // multiplication by 1.
7845  if (Cnt + 1 < NestedLoopCount)
7846  Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div,
7847  Acc.get(), Prod.get());
7848  else
7849  Iter = Acc;
7850  if (!Iter.isUsable()) {
7851  HasErrors = true;
7852  break;
7853  }
7854 
7855  // Update Acc:
7856  // Acc -= Iter * Prod
7857  // Check if there is at least one more inner loop to avoid
7858  // multiplication by 1.
7859  if (Cnt + 1 < NestedLoopCount)
7860  Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul,
7861  Iter.get(), Prod.get());
7862  else
7863  Prod = Iter;
7864  Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub,
7865  Acc.get(), Prod.get());
7866 
7867  // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
7868  auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
7869  DeclRefExpr *CounterVar = buildDeclRefExpr(
7870  SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
7871  /*RefersToCapture=*/true);
7872  ExprResult Init =
7873  buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
7874  IS.CounterInit, IS.IsNonRectangularLB, Captures);
7875  if (!Init.isUsable()) {
7876  HasErrors = true;
7877  break;
7878  }
7880  SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
7881  IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
7882  if (!Update.isUsable()) {
7883  HasErrors = true;
7884  break;
7885  }
7886 
7887  // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
7888  ExprResult Final =
7889  buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
7890  IS.CounterInit, IS.NumIterations, IS.CounterStep,
7891  IS.Subtract, IS.IsNonRectangularLB, &Captures);
7892  if (!Final.isUsable()) {
7893  HasErrors = true;
7894  break;
7895  }
7896 
7897  if (!Update.isUsable() || !Final.isUsable()) {
7898  HasErrors = true;
7899  break;
7900  }
7901  // Save results
7902  Built.Counters[Cnt] = IS.CounterVar;
7903  Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
7904  Built.Inits[Cnt] = Init.get();
7905  Built.Updates[Cnt] = Update.get();
7906  Built.Finals[Cnt] = Final.get();
7907  Built.DependentCounters[Cnt] = nullptr;
7908  Built.DependentInits[Cnt] = nullptr;
7909  Built.FinalsConditions[Cnt] = nullptr;
7910  if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
7911  Built.DependentCounters[Cnt] =
7912  Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx];
7913  Built.DependentInits[Cnt] =
7914  Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx];
7915  Built.FinalsConditions[Cnt] = IS.FinalCondition;
7916  }
7917  }
7918  }
7919 
7920  if (HasErrors)
7921  return 0;
7922 
7923  // Save results
7924  Built.IterationVarRef = IV.get();
7925  Built.LastIteration = LastIteration.get();
7926  Built.NumIterations = NumIterations.get();
7927  Built.CalcLastIteration = SemaRef
7928  .ActOnFinishFullExpr(CalcLastIteration.get(),
7929  /*DiscardedValue=*/false)
7930  .get();
7931  Built.PreCond = PreCond.get();
7932  Built.PreInits = buildPreInits(C, Captures);
7933  Built.Cond = Cond.get();
7934  Built.Init = Init.get();
7935  Built.Inc = Inc.get();
7936  Built.LB = LB.get();
7937  Built.UB = UB.get();
7938  Built.IL = IL.get();
7939  Built.ST = ST.get();
7940  Built.EUB = EUB.get();
7941  Built.NLB = NextLB.get();
7942  Built.NUB = NextUB.get();
7943  Built.PrevLB = PrevLB.get();
7944  Built.PrevUB = PrevUB.get();
7945  Built.DistInc = DistInc.get();
7946  Built.PrevEUB = PrevEUB.get();
7947  Built.DistCombinedFields.LB = CombLB.get();
7948  Built.DistCombinedFields.UB = CombUB.get();
7949  Built.DistCombinedFields.EUB = CombEUB.get();
7950  Built.DistCombinedFields.Init = CombInit.get();
7951  Built.DistCombinedFields.Cond = CombCond.get();
7952  Built.DistCombinedFields.NLB = CombNextLB.get();
7953  Built.DistCombinedFields.NUB = CombNextUB.get();
7954  Built.DistCombinedFields.DistCond = CombDistCond.get();
7955  Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
7956 
7957  return NestedLoopCount;
7958 }
7959 
7960 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
7961  auto CollapseClauses =
7962  OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
7963  if (CollapseClauses.begin() != CollapseClauses.end())
7964  return (*CollapseClauses.begin())->getNumForLoops();
7965  return nullptr;
7966 }
7967 
7968 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
7969  auto OrderedClauses =
7970  OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
7971  if (OrderedClauses.begin() != OrderedClauses.end())
7972  return (*OrderedClauses.begin())->getNumForLoops();
7973  return nullptr;
7974 }
7975 
7977  const ArrayRef<OMPClause *> Clauses) {
7978  const OMPSafelenClause *Safelen = nullptr;
7979  const OMPSimdlenClause *Simdlen = nullptr;
7980 
7981  for (const OMPClause *Clause : Clauses) {
7982  if (Clause->getClauseKind() == OMPC_safelen)
7983  Safelen = cast<OMPSafelenClause>(Clause);
7984  else if (Clause->getClauseKind() == OMPC_simdlen)
7985  Simdlen = cast<OMPSimdlenClause>(Clause);
7986  if (Safelen && Simdlen)
7987  break;
7988  }
7989 
7990  if (Simdlen && Safelen) {
7991  const Expr *SimdlenLength = Simdlen->getSimdlen();
7992  const Expr *SafelenLength = Safelen->getSafelen();
7993  if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
7994  SimdlenLength->isInstantiationDependent() ||
7995  SimdlenLength->containsUnexpandedParameterPack())
7996  return false;
7997  if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
7998  SafelenLength->isInstantiationDependent() ||
7999  SafelenLength->containsUnexpandedParameterPack())
8000  return false;
8001  Expr::EvalResult SimdlenResult, SafelenResult;
8002  SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
8003  SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
8004  llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
8005  llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
8006  // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
8007  // If both simdlen and safelen clauses are specified, the value of the
8008  // simdlen parameter must be less than or equal to the value of the safelen
8009  // parameter.
8010  if (SimdlenRes > SafelenRes) {
8011  S.Diag(SimdlenLength->getExprLoc(),
8012  diag::err_omp_wrong_simdlen_safelen_values)
8013  << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
8014  return true;
8015  }
8016  }
8017  return false;
8018 }
8019 
8020 StmtResult
8022  SourceLocation StartLoc, SourceLocation EndLoc,
8023  VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8024  if (!AStmt)
8025  return StmtError();
8026 
8027  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8029  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
8030  // define the nested loops number.
8031  unsigned NestedLoopCount = checkOpenMPLoop(
8032  OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
8033  AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
8034  if (NestedLoopCount == 0)
8035  return StmtError();
8036 
8037  assert((CurContext->isDependentContext() || B.builtAll()) &&
8038  "omp simd loop exprs were not built");
8039 
8040  if (!CurContext->isDependentContext()) {
8041  // Finalize the clauses that need pre-built expressions for CodeGen.
8042  for (OMPClause *C : Clauses) {
8043  if (auto *LC = dyn_cast<OMPLinearClause>(C))
8044  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8045  B.NumIterations, *this, CurScope,
8046  DSAStack))
8047  return StmtError();
8048  }
8049  }
8050 
8051  if (checkSimdlenSafelenSpecified(*this, Clauses))
8052  return StmtError();
8053 
8054  setFunctionHasBranchProtectedScope();
8055  return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
8056  Clauses, AStmt, B);
8057 }
8058 
8059 StmtResult
8061  SourceLocation StartLoc, SourceLocation EndLoc,
8062  VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8063  if (!AStmt)
8064  return StmtError();
8065 
8066  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8068  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
8069  // define the nested loops number.
8070  unsigned NestedLoopCount = checkOpenMPLoop(
8071  OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
8072  AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
8073  if (NestedLoopCount == 0)
8074  return StmtError();
8075 
8076  assert((CurContext->isDependentContext() || B.builtAll()) &&
8077  "omp for loop exprs were not built");
8078 
8079  if (!CurContext->isDependentContext()) {
8080  // Finalize the clauses that need pre-built expressions for CodeGen.
8081  for (OMPClause *C : Clauses) {
8082  if (auto *LC = dyn_cast<OMPLinearClause>(C))
8083  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8084  B.NumIterations, *this, CurScope,
8085  DSAStack))
8086  return StmtError();
8087  }
8088  }
8089 
8090  setFunctionHasBranchProtectedScope();
8091  return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
8092  Clauses, AStmt, B, DSAStack->isCancelRegion());
8093 }
8094 
8096  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
8097  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8098  if (!AStmt)
8099  return StmtError();
8100 
8101  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8103  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
8104  // define the nested loops number.
8105  unsigned NestedLoopCount =
8106  checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
8107  getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
8108  VarsWithImplicitDSA, B);
8109  if (NestedLoopCount == 0)
8110  return StmtError();
8111 
8112  assert((CurContext->isDependentContext() || B.builtAll()) &&
8113  "omp for simd loop exprs were not built");
8114 
8115  if (!CurContext->isDependentContext()) {
8116  // Finalize the clauses that need pre-built expressions for CodeGen.
8117  for (OMPClause *C : Clauses) {
8118  if (auto *LC = dyn_cast<OMPLinearClause>(C))
8119  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8120  B.NumIterations, *this, CurScope,
8121  DSAStack))
8122  return StmtError();
8123  }
8124  }
8125 
8126  if (checkSimdlenSafelenSpecified(*this, Clauses))
8127  return StmtError();
8128 
8129  setFunctionHasBranchProtectedScope();
8130  return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
8131  Clauses, AStmt, B);
8132 }
8133 
8135  Stmt *AStmt,
8136  SourceLocation StartLoc,
8137  SourceLocation EndLoc) {
8138  if (!AStmt)
8139  return StmtError();
8140 
8141  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8142  auto BaseStmt = AStmt;
8143  while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
8144  BaseStmt = CS->getCapturedStmt();
8145  if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
8146  auto S = C->children();
8147  if (S.begin() == S.end())
8148  return StmtError();
8149  // All associated statements must be '#pragma omp section' except for
8150  // the first one.
8151  for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
8152  if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
8153  if (SectionStmt)
8154  Diag(SectionStmt->getBeginLoc(),
8155  diag::err_omp_sections_substmt_not_section);
8156  return StmtError();
8157  }
8158  cast<OMPSectionDirective>(SectionStmt)
8159  ->setHasCancel(DSAStack->isCancelRegion());
8160  }
8161  } else {
8162  Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
8163  return StmtError();
8164  }
8165 
8166  setFunctionHasBranchProtectedScope();
8167 
8168  return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
8169  DSAStack->isCancelRegion());
8170 }
8171 
8173  SourceLocation StartLoc,
8174  SourceLocation EndLoc) {
8175  if (!AStmt)
8176  return StmtError();
8177 
8178  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8179 
8180  setFunctionHasBranchProtectedScope();
8181  DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
8182 
8183  return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
8184  DSAStack->isCancelRegion());
8185 }
8186 
8188  Stmt *AStmt,
8189  SourceLocation StartLoc,
8190  SourceLocation EndLoc) {
8191  if (!AStmt)
8192  return StmtError();
8193 
8194  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8195 
8196  setFunctionHasBranchProtectedScope();
8197 
8198  // OpenMP [2.7.3, single Construct, Restrictions]
8199  // The copyprivate clause must not be used with the nowait clause.
8200  const OMPClause *Nowait = nullptr;
8201  const OMPClause *Copyprivate = nullptr;
8202  for (const OMPClause *Clause : Clauses) {
8203  if (Clause->getClauseKind() == OMPC_nowait)
8204  Nowait = Clause;
8205  else if (Clause->getClauseKind() == OMPC_copyprivate)
8206  Copyprivate = Clause;
8207  if (Copyprivate && Nowait) {
8208  Diag(Copyprivate->getBeginLoc(),
8209  diag::err_omp_single_copyprivate_with_nowait);
8210  Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
8211  return StmtError();
8212  }
8213  }
8214 
8215  return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
8216 }
8217 
8219  SourceLocation StartLoc,
8220  SourceLocation EndLoc) {
8221  if (!AStmt)
8222  return StmtError();
8223 
8224  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8225 
8226  setFunctionHasBranchProtectedScope();
8227 
8228  return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
8229 }
8230 
8232  const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
8233  Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
8234  if (!AStmt)
8235  return StmtError();
8236 
8237  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8238 
8239  bool ErrorFound = false;
8240  llvm::APSInt Hint;
8241  SourceLocation HintLoc;
8242  bool DependentHint = false;
8243  for (const OMPClause *C : Clauses) {
8244  if (C->getClauseKind() == OMPC_hint) {
8245  if (!DirName.getName()) {
8246  Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
8247  ErrorFound = true;
8248  }
8249  Expr *E = cast<OMPHintClause>(C)->getHint();
8250  if (E->isTypeDependent() || E->isValueDependent() ||
8251  E->isInstantiationDependent()) {
8252  DependentHint = true;
8253  } else {
8254  Hint = E->EvaluateKnownConstInt(Context);
8255  HintLoc = C->getBeginLoc();
8256  }
8257  }
8258  }
8259  if (ErrorFound)
8260  return StmtError();
8261  const auto Pair = DSAStack->getCriticalWithHint(DirName);
8262  if (Pair.first && DirName.getName() && !DependentHint) {
8263  if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
8264  Diag(StartLoc, diag::err_omp_critical_with_hint);
8265  if (HintLoc.isValid())
8266  Diag(HintLoc, diag::note_omp_critical_hint_here)
8267  << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false);
8268  else
8269  Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
8270  if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
8271  Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
8272  << 1
8273  << C->getHint()->EvaluateKnownConstInt(Context).toString(
8274  /*Radix=*/10, /*Signed=*/false);
8275  } else {
8276  Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
8277  }
8278  }
8279  }
8280 
8281  setFunctionHasBranchProtectedScope();
8282 
8283  auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
8284  Clauses, AStmt);
8285  if (!Pair.first && DirName.getName() && !DependentHint)
8286  DSAStack->addCriticalWithHint(Dir, Hint);
8287  return Dir;
8288 }
8289 
8291  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
8292  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8293  if (!AStmt)
8294  return StmtError();
8295 
8296  auto *CS = cast<CapturedStmt>(AStmt);
8297  // 1.2.2 OpenMP Language Terminology
8298  // Structured block - An executable statement with a single entry at the
8299  // top and a single exit at the bottom.
8300  // The point of exit cannot be a branch out of the structured block.
8301  // longjmp() and throw() must not violate the entry/exit criteria.
8302  CS->getCapturedDecl()->setNothrow();
8303 
8305  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
8306  // define the nested loops number.
8307  unsigned NestedLoopCount =
8308  checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
8309  getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
8310  VarsWithImplicitDSA, B);
8311  if (NestedLoopCount == 0)
8312  return StmtError();
8313 
8314  assert((CurContext->isDependentContext() || B.builtAll()) &&
8315  "omp parallel for loop exprs were not built");
8316 
8317  if (!CurContext->isDependentContext()) {
8318  // Finalize the clauses that need pre-built expressions for CodeGen.
8319  for (OMPClause *C : Clauses) {
8320  if (auto *LC = dyn_cast<OMPLinearClause>(C))
8321  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8322  B.NumIterations, *this, CurScope,
8323  DSAStack))
8324  return StmtError();
8325  }
8326  }
8327 
8328  setFunctionHasBranchProtectedScope();
8329  return OMPParallelForDirective::Create(Context, StartLoc, EndLoc,
8330  NestedLoopCount, Clauses, AStmt, B,
8331  DSAStack->isCancelRegion());
8332 }
8333 
8335  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
8336  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
8337  if (!AStmt)
8338  return StmtError();
8339 
8340  auto *CS = cast<CapturedStmt>(AStmt);
8341  // 1.2.2 OpenMP Language Terminology
8342  // Structured block - An executable statement with a single entry at the
8343  // top and a single exit at the bottom.
8344  // The point of exit cannot be a branch out of the structured block.
8345  // longjmp() and throw() must not violate the entry/exit criteria.
8346  CS->getCapturedDecl()->setNothrow();
8347 
8349  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
8350  // define the nested loops number.
8351  unsigned NestedLoopCount =
8352  checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
8353  getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
8354  VarsWithImplicitDSA, B);
8355  if (NestedLoopCount == 0)
8356  return StmtError();
8357 
8358  if (!CurContext->isDependentContext()) {
8359  // Finalize the clauses that need pre-built expressions for CodeGen.
8360  for (OMPClause *C : Clauses) {
8361  if (auto *LC = dyn_cast<OMPLinearClause>(C))
8362  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
8363  B.NumIterations, *this, CurScope,
8364  DSAStack))
8365  return StmtError();
8366  }
8367  }
8368 
8369  if (checkSimdlenSafelenSpecified(*this, Clauses))
8370  return StmtError();
8371 
8372  setFunctionHasBranchProtectedScope();
8374  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
8375 }
8376 
8377 StmtResult
8379  Stmt *AStmt, SourceLocation StartLoc,
8380  SourceLocation EndLoc) {
8381  if (!AStmt)
8382  return StmtError();
8383 
8384  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8385  auto *CS = cast<CapturedStmt>(AStmt);
8386  // 1.2.2 OpenMP Language Terminology
8387  // Structured block - An executable statement with a single entry at the
8388  // top and a single exit at the bottom.
8389  // The point of exit cannot be a branch out of the structured block.
8390  // longjmp() and throw() must not violate the entry/exit criteria.
8391  CS->getCapturedDecl()->setNothrow();
8392 
8393  setFunctionHasBranchProtectedScope();
8394 
8395  return OMPParallelMasterDirective::Create(Context, StartLoc, EndLoc, Clauses,
8396  AStmt);
8397 }
8398 
8399 StmtResult
8401  Stmt *AStmt, SourceLocation StartLoc,
8402  SourceLocation EndLoc) {
8403  if (!AStmt)
8404  return StmtError();
8405 
8406  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8407  auto BaseStmt = AStmt;
8408  while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
8409  BaseStmt = CS->getCapturedStmt();
8410  if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
8411  auto S = C->children();
8412  if (S.begin() == S.end())
8413  return StmtError();
8414  // All associated statements must be '#pragma omp section' except for
8415  // the first one.
8416  for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
8417  if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
8418  if (SectionStmt)
8419  Diag(SectionStmt->getBeginLoc(),
8420  diag::err_omp_parallel_sections_substmt_not_section);
8421  return StmtError();
8422  }
8423  cast<OMPSectionDirective>(SectionStmt)
8424  ->setHasCancel(DSAStack->isCancelRegion());
8425  }
8426  } else {
8427  Diag(AStmt->getBeginLoc(),
8428  diag::err_omp_parallel_sections_not_compound_stmt);
8429  return StmtError();
8430  }
8431 
8432  setFunctionHasBranchProtectedScope();
8433 
8435  Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion());
8436 }
8437 
8439  Stmt *AStmt, SourceLocation StartLoc,
8440  SourceLocation EndLoc) {
8441  if (!AStmt)
8442  return StmtError();
8443 
8444  auto *CS = cast<CapturedStmt>(AStmt);
8445  // 1.2.2 OpenMP Language Terminology
8446  // Structured block - An executable statement with a single entry at the
8447  // top and a single exit at the bottom.
8448  // The point of exit cannot be a branch out of the structured block.
8449  // longjmp() and throw() must not violate the entry/exit criteria.
8450  CS->getCapturedDecl()->setNothrow();
8451 
8452  setFunctionHasBranchProtectedScope();
8453 
8454  return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
8455  DSAStack->isCancelRegion());
8456 }
8457 
8459  SourceLocation EndLoc) {
8460  return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
8461 }
8462 
8464  SourceLocation EndLoc) {
8465  return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
8466 }
8467 
8469  SourceLocation EndLoc) {
8470  return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
8471 }
8472 
8474  Stmt *AStmt,
8475  SourceLocation StartLoc,
8476  SourceLocation EndLoc) {
8477  if (!AStmt)
8478  return StmtError();
8479 
8480  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8481 
8482  setFunctionHasBranchProtectedScope();
8483 
8484  return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
8485  AStmt,
8486  DSAStack->getTaskgroupReductionRef());
8487 }
8488 
8490  SourceLocation StartLoc,
8491  SourceLocation EndLoc) {
8492  assert(Clauses.size() <= 1 && "Extra clauses in flush directive");
8493  return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
8494 }
8495 
8497  Stmt *AStmt,
8498  SourceLocation StartLoc,
8499  SourceLocation EndLoc) {
8500  const OMPClause *DependFound = nullptr;
8501  const OMPClause *DependSourceClause = nullptr;
8502  const OMPClause *DependSinkClause = nullptr;
8503  bool ErrorFound = false;
8504  const OMPThreadsClause *TC = nullptr;
8505  const OMPSIMDClause *SC = nullptr;
8506  for (const OMPClause *C : Clauses) {
8507  if (auto *DC = dyn_cast<OMPDependClause>(C)) {
8508  DependFound = C;
8509  if (DC->getDependencyKind() == OMPC_DEPEND_source) {
8510  if (DependSourceClause) {
8511  Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
8512  << getOpenMPDirectiveName(OMPD_ordered)
8513  << getOpenMPClauseName(OMPC_depend) << 2;
8514  ErrorFound = true;
8515  } else {
8516  DependSourceClause = C;
8517  }
8518  if (DependSinkClause) {
8519  Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
8520  << 0;
8521  ErrorFound = true;
8522  }
8523  } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
8524  if (DependSourceClause) {
8525  Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
8526  << 1;
8527  ErrorFound = true;
8528  }
8529  DependSinkClause = C;
8530  }
8531  } else if (C->getClauseKind() == OMPC_threads) {
8532  TC = cast<OMPThreadsClause>(C);
8533  } else if (C->getClauseKind() == OMPC_simd) {
8534  SC = cast<OMPSIMDClause>(C);
8535  }
8536  }
8537  if (!ErrorFound && !SC &&
8538  isOpenMPSimdDirective(DSAStack->getParentDirective())) {
8539  // OpenMP [2.8.1,simd Construct, Restrictions]
8540  // An ordered construct with the simd clause is the only OpenMP construct
8541  // that can appear in the simd region.
8542  Diag(StartLoc, diag::err_omp_prohibited_region_simd)
8543  << (LangOpts.OpenMP >= 50 ? 1 : 0);
8544  ErrorFound = true;
8545  } else if (DependFound && (TC || SC)) {
8546  Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
8547  << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
8548  ErrorFound = true;
8549  } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) {
8550  Diag(DependFound->getBeginLoc(),
8551  diag::err_omp_ordered_directive_without_param);
8552  ErrorFound = true;
8553  } else if (TC || Clauses.empty()) {
8554  if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) {
8555  SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
8556  Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
8557  << (TC != nullptr);
8558  Diag(Param->getBeginLoc(), diag::note_omp_ordered_param);
8559  ErrorFound = true;
8560  }
8561  }
8562  if ((!AStmt && !DependFound) || ErrorFound)
8563  return StmtError();
8564 
8565  if (AStmt) {
8566  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
8567 
8568  setFunctionHasBranchProtectedScope();
8569  }
8570 
8571  return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
8572 }
8573 
8574 namespace {
8575 /// Helper class for checking expression in 'omp atomic [update]'
8576 /// construct.
8577 class OpenMPAtomicUpdateChecker {
8578  /// Error results for atomic update expressions.
8579  enum ExprAnalysisErrorCode {
8580  /// A statement is not an expression statement.
8581  NotAnExpression,
8582  /// Expression is not builtin binary or unary operation.
8583  NotABinaryOrUnaryExpression,
8584  /// Unary operation is not post-/pre- increment/decrement operation.
8585  NotAnUnaryIncDecExpression,
8586  /// An expression is not of scalar type.
8587  NotAScalarType,
8588  /// A binary operation is not an assignment operation.
8589  NotAnAssignmentOp,
8590  /// RHS part of the binary operation is not a binary expression.
8591  NotABinaryExpression,
8592  /// RHS part is not additive/multiplicative/shift/biwise binary
8593  /// expression.
8594  NotABinaryOperator,
8595  /// RHS binary operation does not have reference to the updated LHS
8596  /// part.
8597  NotAnUpdateExpression,
8598  /// No errors is found.
8599  NoError
8600  };
8601  /// Reference to Sema.
8602  Sema &SemaRef;
8603  /// A location for note diagnostics (when error is found).
8604  SourceLocation NoteLoc;
8605  /// 'x' lvalue part of the source atomic expression.
8606  Expr *X;
8607  /// 'expr' rvalue part of the source atomic expression.
8608  Expr *E;
8609  /// Helper expression of the form
8610  /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
8611  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
8612  Expr *UpdateExpr;
8613  /// Is 'x' a LHS in a RHS part of full update expression. It is
8614  /// important for non-associative operations.
8615  bool IsXLHSInRHSPart;
8616  BinaryOperatorKind Op;
8617  SourceLocation OpLoc;
8618  /// true if the source expression is a postfix unary operation, false
8619  /// if it is a prefix unary operation.
8620  bool IsPostfixUpdate;
8621 
8622 public:
8623  OpenMPAtomicUpdateChecker(Sema &SemaRef)
8624  : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
8625  IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
8626  /// Check specified statement that it is suitable for 'atomic update'
8627  /// constructs and extract 'x', 'expr' and Operation from the original
8628  /// expression. If DiagId and NoteId == 0, then only check is performed
8629  /// without error notification.
8630  /// \param DiagId Diagnostic which should be emitted if error is found.
8631  /// \param NoteId Diagnostic note for the main error message.
8632  /// \return true if statement is not an update expression, false otherwise.
8633  bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
8634  /// Return the 'x' lvalue part of the source atomic expression.
8635  Expr *getX() const { return X; }
8636  /// Return the 'expr' rvalue part of the source atomic expression.
8637  Expr *getExpr() const { return E; }
8638  /// Return the update expression used in calculation of the updated
8639  /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
8640  /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
8641  Expr *getUpdateExpr() const { return UpdateExpr; }
8642  /// Return true if 'x' is LHS in RHS part of full update expression,
8643  /// false otherwise.
8644  bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
8645 
8646  /// true if the source expression is a postfix unary operation, false
8647  /// if it is a prefix unary operation.
8648  bool isPostfixUpdate() const { return IsPostfixUpdate; }
8649 
8650 private:
8651  bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
8652  unsigned NoteId = 0);
8653 };
8654 } // namespace
8655 
8656 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
8657  BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
8658  ExprAnalysisErrorCode ErrorFound = NoError;
8659  SourceLocation ErrorLoc, NoteLoc;
8660  SourceRange ErrorRange, NoteRange;
8661  // Allowed constructs are:
8662  // x = x binop expr;
8663  // x = expr binop x;
8664  if (AtomicBinOp->getOpcode() == BO_Assign) {
8665  X = AtomicBinOp->getLHS();
8666  if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
8667  AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
8668  if (AtomicInnerBinOp->isMultiplicativeOp() ||
8669  AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
8670  AtomicInnerBinOp->isBitwiseOp()) {
8671  Op = AtomicInnerBinOp->getOpcode();
8672  OpLoc = AtomicInnerBinOp->getOperatorLoc();
8673  Expr *LHS = AtomicInnerBinOp->getLHS();
8674  Expr *RHS = AtomicInnerBinOp->getRHS();
8675  llvm::FoldingSetNodeID XId, LHSId, RHSId;
8676  X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
8677  /*Canonical=*/true);
8678  LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
8679  /*Canonical=*/true);
8680  RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
8681  /*Canonical=*/true);
8682  if (XId == LHSId) {
8683  E = RHS;
8684  IsXLHSInRHSPart = true;
8685  } else if (XId == RHSId) {
8686  E = LHS;
8687  IsXLHSInRHSPart = false;
8688  } else {
8689  ErrorLoc = AtomicInnerBinOp->getExprLoc();
8690  ErrorRange = AtomicInnerBinOp->getSourceRange();
8691  NoteLoc = X->getExprLoc();
8692  NoteRange = X->getSourceRange();
8693  ErrorFound = NotAnUpdateExpression;
8694  }
8695  } else {
8696  ErrorLoc = AtomicInnerBinOp->getExprLoc();
8697  ErrorRange = AtomicInnerBinOp->getSourceRange();
8698  NoteLoc = AtomicInnerBinOp->getOperatorLoc();
8699  NoteRange = SourceRange(NoteLoc, NoteLoc);
8700  ErrorFound = NotABinaryOperator;
8701  }
8702  } else {
8703  NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
8704  NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
8705  ErrorFound = NotABinaryExpression;
8706  }
8707  } else {
8708  ErrorLoc = AtomicBinOp->getExprLoc();
8709  ErrorRange = AtomicBinOp->getSourceRange();
8710  NoteLoc = AtomicBinOp->getOperatorLoc();
8711  NoteRange = SourceRange(NoteLoc, NoteLoc);
8712  ErrorFound = NotAnAssignmentOp;
8713  }
8714  if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
8715  SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
8716  SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
8717  return true;
8718  }
8719  if (SemaRef.CurContext->isDependentContext())
8720  E = X = UpdateExpr = nullptr;
8721  return ErrorFound != NoError;
8722 }
8723 
8724 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
8725  unsigned NoteId) {
8726  ExprAnalysisErrorCode ErrorFound = NoError;
8727  SourceLocation ErrorLoc, NoteLoc;
8728  SourceRange ErrorRange, NoteRange;
8729  // Allowed constructs are:
8730  // x++;
8731  // x--;
8732  // ++x;
8733  // --x;
8734  // x binop= expr;
8735  // x = x binop expr;
8736  // x = expr binop x;
8737  if (auto *AtomicBody = dyn_cast<Expr>(S)) {
8738  AtomicBody = AtomicBody->IgnoreParenImpCasts();
8739  if (AtomicBody->getType()->isScalarType() ||
8740  AtomicBody->isInstantiationDependent()) {
8741  if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
8742  AtomicBody->IgnoreParenImpCasts())) {
8743  // Check for Compound Assignment Operation
8745  AtomicCompAssignOp->getOpcode());
8746  OpLoc = AtomicCompAssignOp->getOperatorLoc();
8747  E = AtomicCompAssignOp->getRHS();
8748  X = AtomicCompAssignOp->getLHS()->IgnoreParens();
8749  IsXLHSInRHSPart = true;
8750  } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
8751  AtomicBody->IgnoreParenImpCasts())) {
8752  // Check for Binary Operation
8753  if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
8754  return true;
8755  } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
8756  AtomicBody->IgnoreParenImpCasts())) {
8757  // Check for Unary Operation
8758  if (AtomicUnaryOp->isIncrementDecrementOp()) {
8759  IsPostfixUpdate = AtomicUnaryOp->isPostfix();
8760  Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
8761  OpLoc = AtomicUnaryOp->getOperatorLoc();
8762  X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
8763  E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
8764  IsXLHSInRHSPart = true;
8765  } else {
8766  ErrorFound = NotAnUnaryIncDecExpression;
8767  ErrorLoc = AtomicUnaryOp->getExprLoc();
8768  ErrorRange = AtomicUnaryOp->getSourceRange();
8769  NoteLoc = AtomicUnaryOp->getOperatorLoc();
8770  NoteRange = SourceRange(NoteLoc, NoteLoc);
8771  }
8772  } else if (!AtomicBody->isInstantiationDependent()) {
8773  ErrorFound = NotABinaryOrUnaryExpression;
8774  NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
8775  NoteRange = ErrorRange = AtomicBody->getSourceRange();
8776  }
8777  } else {
8778  ErrorFound = NotAScalarType;
8779  NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
8780  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
8781  }
8782  } else {
8783  ErrorFound = NotAnExpression;
8784  NoteLoc = ErrorLoc = S->getBeginLoc();
8785  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
8786  }
8787  if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
8788  SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
8789  SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
8790  return true;
8791  }
8792  if (SemaRef.CurContext->isDependentContext())
8793  E = X = UpdateExpr = nullptr;
8794  if (ErrorFound == NoError && E && X) {
8795  // Build an update expression of form 'OpaqueValueExpr(x) binop
8796  // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
8797  // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
8798  auto *OVEX = new (SemaRef.getASTContext())
8799  OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue);
8800  auto *OVEExpr = new (SemaRef.getASTContext())
8802  ExprResult Update =
8803  SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
8804  IsXLHSInRHSPart ? OVEExpr : OVEX);
8805  if (Update.isInvalid())
8806  return true;
8807  Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
8809  if (Update.isInvalid())
8810  return true;
8811  UpdateExpr = Update.get();
8812  }
8813  return ErrorFound != NoError;
8814 }
8815 
8817  Stmt *AStmt,
8818  SourceLocation StartLoc,
8819  SourceLocation EndLoc) {
8820  if (!AStmt)
8821  return StmtError();
8822 
8823  auto *CS = cast<CapturedStmt>(AStmt);
8824  // 1.2.2 OpenMP Language Terminology
8825  // Structured block - An executable statement with a single entry at the
8826  // top and a single exit at the bottom.
8827  // The point of exit cannot be a branch out of the structured block.
8828  // longjmp() and throw() must not violate the entry/exit criteria.
8829  OpenMPClauseKind AtomicKind = OMPC_unknown;
8830  SourceLocation AtomicKindLoc;
8831  for (const OMPClause *C : Clauses) {
8832  if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
8833  C->getClauseKind() == OMPC_update ||
8834  C->getClauseKind() == OMPC_capture) {
8835  if (AtomicKind != OMPC_unknown) {
8836  Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
8837  << SourceRange(C->getBeginLoc(), C->getEndLoc());
8838  Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause)
8839  << getOpenMPClauseName(AtomicKind);
8840  } else {
8841  AtomicKind = C->getClauseKind();
8842  AtomicKindLoc = C->getBeginLoc();
8843  }
8844  }
8845  }
8846 
8847  Stmt *Body = CS->getCapturedStmt();
8848  if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
8849  Body = EWC->getSubExpr();
8850 
8851  Expr *X = nullptr;
8852  Expr *V = nullptr;
8853  Expr *E = nullptr;
8854  Expr *UE = nullptr;
8855  bool IsXLHSInRHSPart = false;
8856  bool IsPostfixUpdate = false;
8857  // OpenMP [2.12.6, atomic Construct]
8858  // In the next expressions:
8859  // * x and v (as applicable) are both l-value expressions with scalar type.
8860  // * During the execution of an atomic region, multiple syntactic
8861  // occurrences of x must designate the same storage location.
8862  // * Neither of v and expr (as applicable) may access the storage location
8863  // designated by x.
8864  // * Neither of x and expr (as applicable) may access the storage location
8865  // designated by v.
8866  // * expr is an expression with scalar type.
8867  // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
8868  // * binop, binop=, ++, and -- are not overloaded operators.
8869  // * The expression x binop expr must be numerically equivalent to x binop
8870  // (expr). This requirement is satisfied if the operators in expr have
8871  // precedence greater than binop, or by using parentheses around expr or
8872  // subexpressions of expr.
8873  // * The expression expr binop x must be numerically equivalent to (expr)
8874  // binop x. This requirement is satisfied if the operators in expr have
8875  // precedence equal to or greater than binop, or by using parentheses around
8876  // expr or subexpressions of expr.
8877  // * For forms that allow multiple occurrences of x, the number of times
8878  // that x is evaluated is unspecified.
8879  if (AtomicKind == OMPC_read) {
8880  enum {
8881  NotAnExpression,
8882  NotAnAssignmentOp,
8883  NotAScalarType,
8884  NotAnLValue,
8885  NoError
8886  } ErrorFound = NoError;
8887  SourceLocation ErrorLoc, NoteLoc;
8888  SourceRange ErrorRange, NoteRange;
8889  // If clause is read:
8890  // v = x;
8891  if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
8892  const auto *AtomicBinOp =
8893  dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
8894  if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
8895  X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
8896  V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
8897  if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
8898  (V->isInstantiationDependent() || V->getType()->isScalarType())) {
8899  if (!X->isLValue() || !V->isLValue()) {
8900  const Expr *NotLValueExpr = X->isLValue() ? V : X;
8901  ErrorFound = NotAnLValue;
8902  ErrorLoc = AtomicBinOp->getExprLoc();
8903  ErrorRange = AtomicBinOp->getSourceRange();
8904  NoteLoc = NotLValueExpr->getExprLoc();
8905  NoteRange = NotLValueExpr->getSourceRange();
8906  }
8907  } else if (!X->isInstantiationDependent() ||
8908  !V->isInstantiationDependent()) {
8909  const Expr *NotScalarExpr =
8911  ? V
8912  : X;
8913  ErrorFound = NotAScalarType;
8914  ErrorLoc = AtomicBinOp->getExprLoc();
8915  ErrorRange = AtomicBinOp->getSourceRange();
8916  NoteLoc = NotScalarExpr->getExprLoc();
8917  NoteRange = NotScalarExpr->getSourceRange();
8918  }
8919  } else if (!AtomicBody->isInstantiationDependent()) {
8920  ErrorFound = NotAnAssignmentOp;
8921  ErrorLoc = AtomicBody->getExprLoc();
8922  ErrorRange = AtomicBody->getSourceRange();
8923  NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
8924  : AtomicBody->getExprLoc();
8925  NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
8926  : AtomicBody->getSourceRange();
8927  }
8928  } else {
8929  ErrorFound = NotAnExpression;
8930  NoteLoc = ErrorLoc = Body->getBeginLoc();
8931  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
8932  }
8933  if (ErrorFound != NoError) {
8934  Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
8935  << ErrorRange;
8936  Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
8937  << NoteRange;
8938  return StmtError();
8939  }
8940  if (CurContext->isDependentContext())
8941  V = X = nullptr;
8942  } else if (AtomicKind == OMPC_write) {
8943  enum {
8944  NotAnExpression,
8945  NotAnAssignmentOp,
8946  NotAScalarType,
8947  NotAnLValue,
8948  NoError
8949  } ErrorFound = NoError;
8950  SourceLocation ErrorLoc, NoteLoc;
8951  SourceRange ErrorRange, NoteRange;
8952  // If clause is write:
8953  // x = expr;
8954  if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
8955  const auto *AtomicBinOp =
8956  dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
8957  if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
8958  X = AtomicBinOp->getLHS();
8959  E = AtomicBinOp->getRHS();
8960  if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
8961  (E->isInstantiationDependent() || E->getType()->isScalarType())) {
8962  if (!X->isLValue()) {
8963  ErrorFound = NotAnLValue;
8964  ErrorLoc = AtomicBinOp->getExprLoc();
8965  ErrorRange = AtomicBinOp->getSourceRange();
8966  NoteLoc = X->getExprLoc();
8967  NoteRange = X->getSourceRange();
8968  }
8969  } else if (!X->isInstantiationDependent() ||
8970  !E->isInstantiationDependent()) {
8971  const Expr *NotScalarExpr =
8973  ? E
8974  : X;
8975  ErrorFound = NotAScalarType;
8976  ErrorLoc = AtomicBinOp->getExprLoc();
8977  ErrorRange = AtomicBinOp->getSourceRange();
8978  NoteLoc = NotScalarExpr->getExprLoc();
8979  NoteRange = NotScalarExpr->getSourceRange();
8980  }
8981  } else if (!AtomicBody->isInstantiationDependent()) {
8982  ErrorFound = NotAnAssignmentOp;
8983  ErrorLoc = AtomicBody->getExprLoc();
8984  ErrorRange = AtomicBody->getSourceRange();
8985  NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
8986  : AtomicBody->getExprLoc();
8987  NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
8988  : AtomicBody->getSourceRange();
8989  }
8990  } else {
8991  ErrorFound = NotAnExpression;
8992  NoteLoc = ErrorLoc = Body->getBeginLoc();
8993  NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
8994  }
8995  if (ErrorFound != NoError) {
8996  Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
8997  << ErrorRange;
8998  Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
8999  << NoteRange;
9000  return StmtError();
9001  }
9002  if (CurContext->isDependentContext())
9003  E = X = nullptr;
9004  } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
9005  // If clause is update:
9006  // x++;
9007  // x--;
9008  // ++x;
9009  // --x;
9010  // x binop= expr;
9011  // x = x binop expr;
9012  // x = expr binop x;
9013  OpenMPAtomicUpdateChecker Checker(*this);
9014  if (Checker.checkStatement(
9015  Body, (AtomicKind == OMPC_update)
9016  ? diag::err_omp_atomic_update_not_expression_statement
9017  : diag::err_omp_atomic_not_expression_statement,
9018  diag::note_omp_atomic_update))
9019  return StmtError();
9020  if (!CurContext->isDependentContext()) {
9021  E = Checker.getExpr();
9022  X = Checker.getX();
9023  UE = Checker.getUpdateExpr();
9024  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
9025  }
9026  } else if (AtomicKind == OMPC_capture) {
9027  enum {
9028  NotAnAssignmentOp,
9029  NotACompoundStatement,
9030  NotTwoSubstatements,
9031  NotASpecificExpression,
9032  NoError
9033  } ErrorFound = NoError;
9034  SourceLocation ErrorLoc, NoteLoc;
9035  SourceRange ErrorRange, NoteRange;
9036  if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
9037  // If clause is a capture:
9038  // v = x++;
9039  // v = x--;
9040  // v = ++x;
9041  // v = --x;
9042  // v = x binop= expr;
9043  // v = x = x binop expr;
9044  // v = x = expr binop x;
9045  const auto *AtomicBinOp =
9046  dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
9047  if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
9048  V = AtomicBinOp->getLHS();
9049  Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
9050  OpenMPAtomicUpdateChecker Checker(*this);
9051  if (Checker.checkStatement(
9052  Body, diag::err_omp_atomic_capture_not_expression_statement,
9053  diag::note_omp_atomic_update))
9054  return StmtError();
9055  E = Checker.getExpr();
9056  X = Checker.getX();
9057  UE = Checker.getUpdateExpr();
9058  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
9059  IsPostfixUpdate = Checker.isPostfixUpdate();
9060  } else if (!AtomicBody->isInstantiationDependent()) {
9061  ErrorLoc = AtomicBody->getExprLoc();
9062  ErrorRange = AtomicBody->getSourceRange();
9063  NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
9064  : AtomicBody->getExprLoc();
9065  NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
9066  : AtomicBody->getSourceRange();
9067  ErrorFound = NotAnAssignmentOp;
9068  }
9069  if (ErrorFound != NoError) {
9070  Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
9071  << ErrorRange;
9072  Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
9073  return StmtError();
9074  }
9075  if (CurContext->isDependentContext())
9076  UE = V = E = X = nullptr;
9077  } else {
9078  // If clause is a capture:
9079  // { v = x; x = expr; }
9080  // { v = x; x++; }
9081  // { v = x; x--; }
9082  // { v = x; ++x; }
9083  // { v = x; --x; }
9084  // { v = x; x binop= expr; }
9085  // { v = x; x = x binop expr; }
9086  // { v = x; x = expr binop x; }
9087  // { x++; v = x; }
9088  // { x--; v = x; }
9089  // { ++x; v = x; }
9090  // { --x; v = x; }
9091  // { x binop= expr; v = x; }
9092  // { x = x binop expr; v = x; }
9093  // { x = expr binop x; v = x; }
9094  if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
9095  // Check that this is { expr1; expr2; }
9096  if (CS->size() == 2) {
9097  Stmt *First = CS->body_front();
9098  Stmt *Second = CS->body_back();
9099  if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
9100  First = EWC->getSubExpr()->IgnoreParenImpCasts();
9101  if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
9102  Second = EWC->getSubExpr()->IgnoreParenImpCasts();
9103  // Need to find what subexpression is 'v' and what is 'x'.
9104  OpenMPAtomicUpdateChecker Checker(*this);
9105  bool IsUpdateExprFound = !Checker.checkStatement(Second);
9106  BinaryOperator *BinOp = nullptr;
9107  if (IsUpdateExprFound) {
9108  BinOp = dyn_cast<BinaryOperator>(First);
9109  IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
9110  }
9111  if (IsUpdateExprFound && !CurContext->isDependentContext()) {
9112  // { v = x; x++; }
9113  // { v = x; x--; }
9114  // { v = x; ++x; }
9115  // { v = x; --x; }
9116  // { v = x; x binop= expr; }
9117  // { v = x; x = x binop expr; }
9118  // { v = x; x = expr binop x; }
9119  // Check that the first expression has form v = x.
9120  Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
9121  llvm::FoldingSetNodeID XId, PossibleXId;
9122  Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
9123  PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
9124  IsUpdateExprFound = XId == PossibleXId;
9125  if (IsUpdateExprFound) {
9126  V = BinOp->getLHS();
9127  X = Checker.getX();
9128  E = Checker.getExpr();
9129  UE = Checker.getUpdateExpr();
9130  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
9131  IsPostfixUpdate = true;
9132  }
9133  }
9134  if (!IsUpdateExprFound) {
9135  IsUpdateExprFound = !Checker.checkStatement(First);
9136  BinOp = nullptr;
9137  if (IsUpdateExprFound) {
9138  BinOp = dyn_cast<BinaryOperator>(Second);
9139  IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
9140  }
9141  if (IsUpdateExprFound && !CurContext->isDependentContext()) {
9142  // { x++; v = x; }
9143  // { x--; v = x; }
9144  // { ++x; v = x; }
9145  // { --x; v = x; }
9146  // { x binop= expr; v = x; }
9147  // { x = x binop expr; v = x; }
9148  // { x = expr binop x; v = x; }
9149  // Check that the second expression has form v = x.
9150  Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
9151  llvm::FoldingSetNodeID XId, PossibleXId;
9152  Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
9153  PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
9154  IsUpdateExprFound = XId == PossibleXId;
9155  if (IsUpdateExprFound) {
9156  V = BinOp->getLHS();
9157  X = Checker.getX();
9158  E = Checker.getExpr();
9159  UE = Checker.getUpdateExpr();
9160  IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
9161  IsPostfixUpdate = false;
9162  }
9163  }
9164  }
9165  if (!IsUpdateExprFound) {
9166  // { v = x; x = expr; }
9167  auto *FirstExpr = dyn_cast<Expr>(First);
9168  auto *SecondExpr = dyn_cast<Expr>(Second);
9169  if (!FirstExpr || !SecondExpr ||
9170  !(FirstExpr->isInstantiationDependent() ||
9171  SecondExpr->isInstantiationDependent())) {
9172  auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
9173  if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
9174  ErrorFound = NotAnAssignmentOp;
9175  NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
9176  : First->getBeginLoc();
9177  NoteRange = ErrorRange = FirstBinOp
9178  ? FirstBinOp->getSourceRange()
9179  : SourceRange(ErrorLoc, ErrorLoc);
9180  } else {
9181  auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
9182  if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
9183  ErrorFound = NotAnAssignmentOp;
9184  NoteLoc = ErrorLoc = SecondBinOp
9185  ? SecondBinOp->getOperatorLoc()
9186  : Second->getBeginLoc();
9187  NoteRange = ErrorRange =
9188  SecondBinOp ? SecondBinOp->getSourceRange()
9189  : SourceRange(ErrorLoc, ErrorLoc);
9190  } else {
9191  Expr *PossibleXRHSInFirst =
9192  FirstBinOp->getRHS()->IgnoreParenImpCasts();
9193  Expr *PossibleXLHSInSecond =
9194  SecondBinOp->getLHS()->IgnoreParenImpCasts();
9195  llvm::FoldingSetNodeID X1Id, X2Id;
9196  PossibleXRHSInFirst->Profile(X1Id, Context,
9197  /*Canonical=*/true);
9198  PossibleXLHSInSecond->Profile(X2Id, Context,
9199  /*Canonical=*/true);
9200  IsUpdateExprFound = X1Id == X2Id;
9201  if (IsUpdateExprFound) {
9202  V = FirstBinOp->getLHS();
9203  X = SecondBinOp->getLHS();
9204  E = SecondBinOp->getRHS();
9205  UE = nullptr;
9206  IsXLHSInRHSPart = false;
9207  IsPostfixUpdate = true;
9208  } else {
9209  ErrorFound = NotASpecificExpression;
9210  ErrorLoc = FirstBinOp->getExprLoc();
9211  ErrorRange = FirstBinOp->getSourceRange();
9212  NoteLoc = SecondBinOp->getLHS()->getExprLoc();
9213  NoteRange = SecondBinOp->getRHS()->getSourceRange();
9214  }
9215  }
9216  }
9217  }
9218  }
9219  } else {
9220  NoteLoc = ErrorLoc = Body->getBeginLoc();
9221  NoteRange = ErrorRange =
9222  SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
9223  ErrorFound = NotTwoSubstatements;
9224  }
9225  } else {
9226  NoteLoc = ErrorLoc = Body->getBeginLoc();
9227  NoteRange = ErrorRange =
9228  SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
9229  ErrorFound = NotACompoundStatement;
9230  }
9231  if (ErrorFound != NoError) {
9232  Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
9233  << ErrorRange;
9234  Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
9235  return StmtError();
9236  }
9237  if (CurContext->isDependentContext())
9238  UE = V = E = X = nullptr;
9239  }
9240  }
9241 
9242  setFunctionHasBranchProtectedScope();
9243 
9244  return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
9245  X, V, E, UE, IsXLHSInRHSPart,
9246  IsPostfixUpdate);
9247 }
9248 
9250  Stmt *AStmt,
9251  SourceLocation StartLoc,
9252  SourceLocation EndLoc) {
9253  if (!AStmt)
9254  return StmtError();
9255 
9256  auto *CS = cast<CapturedStmt>(AStmt);
9257  // 1.2.2 OpenMP Language Terminology
9258  // Structured block - An executable statement with a single entry at the
9259  // top and a single exit at the bottom.
9260  // The point of exit cannot be a branch out of the structured block.
9261  // longjmp() and throw() must not violate the entry/exit criteria.
9262  CS->getCapturedDecl()->setNothrow();
9263  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
9264  ThisCaptureLevel > 1; --ThisCaptureLevel) {
9265  CS = cast<CapturedStmt>(CS->getCapturedStmt());
9266  // 1.2.2 OpenMP Language Terminology
9267  // Structured block - An executable statement with a single entry at the
9268  // top and a single exit at the bottom.
9269  // The point of exit cannot be a branch out of the structured block.
9270  // longjmp() and throw() must not violate the entry/exit criteria.
9271  CS->getCapturedDecl()->setNothrow();
9272  }
9273 
9274  // OpenMP [2.16, Nesting of Regions]
9275  // If specified, a teams construct must be contained within a target
9276  // construct. That target construct must contain no statements or directives
9277  // outside of the teams construct.
9278  if (DSAStack->hasInnerTeamsRegion()) {
9279  const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
9280  bool OMPTeamsFound = true;
9281  if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
9282  auto I = CS->body_begin();
9283  while (I != CS->body_end()) {
9284  const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
9285  if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) ||
9286  OMPTeamsFound) {
9287 
9288  OMPTeamsFound = false;
9289  break;
9290  }
9291  ++I;
9292  }
9293  assert(I != CS->body_end() && "Not found statement");
9294  S = *I;
9295  } else {
9296  const auto *OED = dyn_cast<OMPExecutableDirective>(S);
9297  OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
9298  }
9299  if (!OMPTeamsFound) {
9300  Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
9301  Diag(DSAStack->getInnerTeamsRegionLoc(),
9302  diag::note_omp_nested_teams_construct_here);
9303  Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
9304  << isa<OMPExecutableDirective>(S);
9305  return StmtError();
9306  }
9307  }
9308 
9309  setFunctionHasBranchProtectedScope();
9310 
9311  return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9312 }
9313 
9314 StmtResult
9316  Stmt *AStmt, SourceLocation StartLoc,
9317  SourceLocation EndLoc) {
9318  if (!AStmt)
9319  return StmtError();
9320 
9321  auto *CS = cast<CapturedStmt>(AStmt);
9322  // 1.2.2 OpenMP Language Terminology
9323  // Structured block - An executable statement with a single entry at the
9324  // top and a single exit at the bottom.
9325  // The point of exit cannot be a branch out of the structured block.
9326  // longjmp() and throw() must not violate the entry/exit criteria.
9327  CS->getCapturedDecl()->setNothrow();
9328  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
9329  ThisCaptureLevel > 1; --ThisCaptureLevel) {
9330  CS = cast<CapturedStmt>(CS->getCapturedStmt());
9331  // 1.2.2 OpenMP Language Terminology
9332  // Structured block - An executable statement with a single entry at the
9333  // top and a single exit at the bottom.
9334  // The point of exit cannot be a branch out of the structured block.
9335  // longjmp() and throw() must not violate the entry/exit criteria.
9336  CS->getCapturedDecl()->setNothrow();
9337  }
9338 
9339  setFunctionHasBranchProtectedScope();
9340 
9341  return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses,
9342  AStmt);
9343 }
9344 
9346  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9347  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9348  if (!AStmt)
9349  return StmtError();
9350 
9351  auto *CS = cast<CapturedStmt>(AStmt);
9352  // 1.2.2 OpenMP Language Terminology
9353  // Structured block - An executable statement with a single entry at the
9354  // top and a single exit at the bottom.
9355  // The point of exit cannot be a branch out of the structured block.
9356  // longjmp() and throw() must not violate the entry/exit criteria.
9357  CS->getCapturedDecl()->setNothrow();
9358  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
9359  ThisCaptureLevel > 1; --ThisCaptureLevel) {
9360  CS = cast<CapturedStmt>(CS->getCapturedStmt());
9361  // 1.2.2 OpenMP Language Terminology
9362  // Structured block - An executable statement with a single entry at the
9363  // top and a single exit at the bottom.
9364  // The point of exit cannot be a branch out of the structured block.
9365  // longjmp() and throw() must not violate the entry/exit criteria.
9366  CS->getCapturedDecl()->setNothrow();
9367  }
9368 
9370  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9371  // define the nested loops number.
9372  unsigned NestedLoopCount =
9373  checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
9374  getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
9375  VarsWithImplicitDSA, B);
9376  if (NestedLoopCount == 0)
9377  return StmtError();
9378 
9379  assert((CurContext->isDependentContext() || B.builtAll()) &&
9380  "omp target parallel for loop exprs were not built");
9381 
9382  if (!CurContext->isDependentContext()) {
9383  // Finalize the clauses that need pre-built expressions for CodeGen.
9384  for (OMPClause *C : Clauses) {
9385  if (auto *LC = dyn_cast<OMPLinearClause>(C))
9386  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9387  B.NumIterations, *this, CurScope,
9388  DSAStack))
9389  return StmtError();
9390  }
9391  }
9392 
9393  setFunctionHasBranchProtectedScope();
9394  return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc,
9395  NestedLoopCount, Clauses, AStmt,
9396  B, DSAStack->isCancelRegion());
9397 }
9398 
9399 /// Check for existence of a map clause in the list of clauses.
9400 static bool hasClauses(ArrayRef<OMPClause *> Clauses,
9401  const OpenMPClauseKind K) {
9402  return llvm::any_of(
9403  Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
9404 }
9405 
9406 template <typename... Params>
9407 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
9408  const Params... ClauseTypes) {
9409  return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
9410 }
9411 
9413  Stmt *AStmt,
9414  SourceLocation StartLoc,
9415  SourceLocation EndLoc) {
9416  if (!AStmt)
9417  return StmtError();
9418 
9419  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9420 
9421  // OpenMP [2.10.1, Restrictions, p. 97]
9422  // At least one map clause must appear on the directive.
9423  if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) {
9424  Diag(StartLoc, diag::err_omp_no_clause_for_directive)
9425  << "'map' or 'use_device_ptr'"
9426  << getOpenMPDirectiveName(OMPD_target_data);
9427  return StmtError();
9428  }
9429 
9430  setFunctionHasBranchProtectedScope();
9431 
9432  return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
9433  AStmt);
9434 }
9435 
9436 StmtResult
9438  SourceLocation StartLoc,
9439  SourceLocation EndLoc, Stmt *AStmt) {
9440  if (!AStmt)
9441  return StmtError();
9442 
9443  auto *CS = cast<CapturedStmt>(AStmt);
9444  // 1.2.2 OpenMP Language Terminology
9445  // Structured block - An executable statement with a single entry at the
9446  // top and a single exit at the bottom.
9447  // The point of exit cannot be a branch out of the structured block.
9448  // longjmp() and throw() must not violate the entry/exit criteria.
9449  CS->getCapturedDecl()->setNothrow();
9450  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
9451  ThisCaptureLevel > 1; --ThisCaptureLevel) {
9452  CS = cast<CapturedStmt>(CS->getCapturedStmt());
9453  // 1.2.2 OpenMP Language Terminology
9454  // Structured block - An executable statement with a single entry at the
9455  // top and a single exit at the bottom.
9456  // The point of exit cannot be a branch out of the structured block.
9457  // longjmp() and throw() must not violate the entry/exit criteria.
9458  CS->getCapturedDecl()->setNothrow();
9459  }
9460 
9461  // OpenMP [2.10.2, Restrictions, p. 99]
9462  // At least one map clause must appear on the directive.
9463  if (!hasClauses(Clauses, OMPC_map)) {
9464  Diag(StartLoc, diag::err_omp_no_clause_for_directive)
9465  << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
9466  return StmtError();
9467  }
9468 
9469  return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
9470  AStmt);
9471 }
9472 
9473 StmtResult
9475  SourceLocation StartLoc,
9476  SourceLocation EndLoc, Stmt *AStmt) {
9477  if (!AStmt)
9478  return StmtError();
9479 
9480  auto *CS = cast<CapturedStmt>(AStmt);
9481  // 1.2.2 OpenMP Language Terminology
9482  // Structured block - An executable statement with a single entry at the
9483  // top and a single exit at the bottom.
9484  // The point of exit cannot be a branch out of the structured block.
9485  // longjmp() and throw() must not violate the entry/exit criteria.
9486  CS->getCapturedDecl()->setNothrow();
9487  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
9488  ThisCaptureLevel > 1; --ThisCaptureLevel) {
9489  CS = cast<CapturedStmt>(CS->getCapturedStmt());
9490  // 1.2.2 OpenMP Language Terminology
9491  // Structured block - An executable statement with a single entry at the
9492  // top and a single exit at the bottom.
9493  // The point of exit cannot be a branch out of the structured block.
9494  // longjmp() and throw() must not violate the entry/exit criteria.
9495  CS->getCapturedDecl()->setNothrow();
9496  }
9497 
9498  // OpenMP [2.10.3, Restrictions, p. 102]
9499  // At least one map clause must appear on the directive.
9500  if (!hasClauses(Clauses, OMPC_map)) {
9501  Diag(StartLoc, diag::err_omp_no_clause_for_directive)
9502  << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
9503  return StmtError();
9504  }
9505 
9506  return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
9507  AStmt);
9508 }
9509 
9511  SourceLocation StartLoc,
9512  SourceLocation EndLoc,
9513  Stmt *AStmt) {
9514  if (!AStmt)
9515  return StmtError();
9516 
9517  auto *CS = cast<CapturedStmt>(AStmt);
9518  // 1.2.2 OpenMP Language Terminology
9519  // Structured block - An executable statement with a single entry at the
9520  // top and a single exit at the bottom.
9521  // The point of exit cannot be a branch out of the structured block.
9522  // longjmp() and throw() must not violate the entry/exit criteria.
9523  CS->getCapturedDecl()->setNothrow();
9524  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
9525  ThisCaptureLevel > 1; --ThisCaptureLevel) {
9526  CS = cast<CapturedStmt>(CS->getCapturedStmt());
9527  // 1.2.2 OpenMP Language Terminology
9528  // Structured block - An executable statement with a single entry at the
9529  // top and a single exit at the bottom.
9530  // The point of exit cannot be a branch out of the structured block.
9531  // longjmp() and throw() must not violate the entry/exit criteria.
9532  CS->getCapturedDecl()->setNothrow();
9533  }
9534 
9535  if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
9536  Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
9537  return StmtError();
9538  }
9539  return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
9540  AStmt);
9541 }
9542 
9544  Stmt *AStmt, SourceLocation StartLoc,
9545  SourceLocation EndLoc) {
9546  if (!AStmt)
9547  return StmtError();
9548 
9549  auto *CS = cast<CapturedStmt>(AStmt);
9550  // 1.2.2 OpenMP Language Terminology
9551  // Structured block - An executable statement with a single entry at the
9552  // top and a single exit at the bottom.
9553  // The point of exit cannot be a branch out of the structured block.
9554  // longjmp() and throw() must not violate the entry/exit criteria.
9555  CS->getCapturedDecl()->setNothrow();
9556 
9557  setFunctionHasBranchProtectedScope();
9558 
9559  DSAStack->setParentTeamsRegionLoc(StartLoc);
9560 
9561  return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9562 }
9563 
9564 StmtResult
9566  SourceLocation EndLoc,
9567  OpenMPDirectiveKind CancelRegion) {
9568  if (DSAStack->isParentNowaitRegion()) {
9569  Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
9570  return StmtError();
9571  }
9572  if (DSAStack->isParentOrderedRegion()) {
9573  Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
9574  return StmtError();
9575  }
9576  return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
9577  CancelRegion);
9578 }
9579 
9581  SourceLocation StartLoc,
9582  SourceLocation EndLoc,
9583  OpenMPDirectiveKind CancelRegion) {
9584  if (DSAStack->isParentNowaitRegion()) {
9585  Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
9586  return StmtError();
9587  }
9588  if (DSAStack->isParentOrderedRegion()) {
9589  Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
9590  return StmtError();
9591  }
9592  DSAStack->setParentCancelRegion(/*Cancel=*/true);
9593  return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
9594  CancelRegion);
9595 }
9596 
9598  ArrayRef<OMPClause *> Clauses) {
9599  const OMPClause *PrevClause = nullptr;
9600  bool ErrorFound = false;
9601  for (const OMPClause *C : Clauses) {
9602  if (C->getClauseKind() == OMPC_grainsize ||
9603  C->getClauseKind() == OMPC_num_tasks) {
9604  if (!PrevClause)
9605  PrevClause = C;
9606  else if (PrevClause->getClauseKind() != C->getClauseKind()) {
9607  S.Diag(C->getBeginLoc(),
9608  diag::err_omp_grainsize_num_tasks_mutually_exclusive)
9609  << getOpenMPClauseName(C->getClauseKind())
9610  << getOpenMPClauseName(PrevClause->getClauseKind());
9611  S.Diag(PrevClause->getBeginLoc(),
9612  diag::note_omp_previous_grainsize_num_tasks)
9613  << getOpenMPClauseName(PrevClause->getClauseKind());
9614  ErrorFound = true;
9615  }
9616  }
9617  }
9618  return ErrorFound;
9619 }
9620 
9622  ArrayRef<OMPClause *> Clauses) {
9623  const OMPClause *ReductionClause = nullptr;
9624  const OMPClause *NogroupClause = nullptr;
9625  for (const OMPClause *C : Clauses) {
9626  if (C->getClauseKind() == OMPC_reduction) {
9627  ReductionClause = C;
9628  if (NogroupClause)
9629  break;
9630  continue;
9631  }
9632  if (C->getClauseKind() == OMPC_nogroup) {
9633  NogroupClause = C;
9634  if (ReductionClause)
9635  break;
9636  continue;
9637  }
9638  }
9639  if (ReductionClause && NogroupClause) {
9640  S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
9641  << SourceRange(NogroupClause->getBeginLoc(),
9642  NogroupClause->getEndLoc());
9643  return true;
9644  }
9645  return false;
9646 }
9647 
9649  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9650  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9651  if (!AStmt)
9652  return StmtError();
9653 
9654  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9656  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9657  // define the nested loops number.
9658  unsigned NestedLoopCount =
9659  checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
9660  /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
9661  VarsWithImplicitDSA, B);
9662  if (NestedLoopCount == 0)
9663  return StmtError();
9664 
9665  assert((CurContext->isDependentContext() || B.builtAll()) &&
9666  "omp for loop exprs were not built");
9667 
9668  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9669  // The grainsize clause and num_tasks clause are mutually exclusive and may
9670  // not appear on the same taskloop directive.
9671  if (checkGrainsizeNumTasksClauses(*this, Clauses))
9672  return StmtError();
9673  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9674  // If a reduction clause is present on the taskloop directive, the nogroup
9675  // clause must not be specified.
9676  if (checkReductionClauseWithNogroup(*this, Clauses))
9677  return StmtError();
9678 
9679  setFunctionHasBranchProtectedScope();
9680  return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
9681  NestedLoopCount, Clauses, AStmt, B);
9682 }
9683 
9685  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9686  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9687  if (!AStmt)
9688  return StmtError();
9689 
9690  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9692  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9693  // define the nested loops number.
9694  unsigned NestedLoopCount =
9695  checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
9696  /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
9697  VarsWithImplicitDSA, B);
9698  if (NestedLoopCount == 0)
9699  return StmtError();
9700 
9701  assert((CurContext->isDependentContext() || B.builtAll()) &&
9702  "omp for loop exprs were not built");
9703 
9704  if (!CurContext->isDependentContext()) {
9705  // Finalize the clauses that need pre-built expressions for CodeGen.
9706  for (OMPClause *C : Clauses) {
9707  if (auto *LC = dyn_cast<OMPLinearClause>(C))
9708  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9709  B.NumIterations, *this, CurScope,
9710  DSAStack))
9711  return StmtError();
9712  }
9713  }
9714 
9715  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9716  // The grainsize clause and num_tasks clause are mutually exclusive and may
9717  // not appear on the same taskloop directive.
9718  if (checkGrainsizeNumTasksClauses(*this, Clauses))
9719  return StmtError();
9720  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9721  // If a reduction clause is present on the taskloop directive, the nogroup
9722  // clause must not be specified.
9723  if (checkReductionClauseWithNogroup(*this, Clauses))
9724  return StmtError();
9725  if (checkSimdlenSafelenSpecified(*this, Clauses))
9726  return StmtError();
9727 
9728  setFunctionHasBranchProtectedScope();
9729  return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
9730  NestedLoopCount, Clauses, AStmt, B);
9731 }
9732 
9734  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9735  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9736  if (!AStmt)
9737  return StmtError();
9738 
9739  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9741  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9742  // define the nested loops number.
9743  unsigned NestedLoopCount =
9744  checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses),
9745  /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
9746  VarsWithImplicitDSA, B);
9747  if (NestedLoopCount == 0)
9748  return StmtError();
9749 
9750  assert((CurContext->isDependentContext() || B.builtAll()) &&
9751  "omp for loop exprs were not built");
9752 
9753  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9754  // The grainsize clause and num_tasks clause are mutually exclusive and may
9755  // not appear on the same taskloop directive.
9756  if (checkGrainsizeNumTasksClauses(*this, Clauses))
9757  return StmtError();
9758  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9759  // If a reduction clause is present on the taskloop directive, the nogroup
9760  // clause must not be specified.
9761  if (checkReductionClauseWithNogroup(*this, Clauses))
9762  return StmtError();
9763 
9764  setFunctionHasBranchProtectedScope();
9765  return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc,
9766  NestedLoopCount, Clauses, AStmt, B);
9767 }
9768 
9770  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9771  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9772  if (!AStmt)
9773  return StmtError();
9774 
9775  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9777  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9778  // define the nested loops number.
9779  unsigned NestedLoopCount =
9780  checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses),
9781  /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
9782  VarsWithImplicitDSA, B);
9783  if (NestedLoopCount == 0)
9784  return StmtError();
9785 
9786  assert((CurContext->isDependentContext() || B.builtAll()) &&
9787  "omp for loop exprs were not built");
9788 
9789  if (!CurContext->isDependentContext()) {
9790  // Finalize the clauses that need pre-built expressions for CodeGen.
9791  for (OMPClause *C : Clauses) {
9792  if (auto *LC = dyn_cast<OMPLinearClause>(C))
9793  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9794  B.NumIterations, *this, CurScope,
9795  DSAStack))
9796  return StmtError();
9797  }
9798  }
9799 
9800  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9801  // The grainsize clause and num_tasks clause are mutually exclusive and may
9802  // not appear on the same taskloop directive.
9803  if (checkGrainsizeNumTasksClauses(*this, Clauses))
9804  return StmtError();
9805  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9806  // If a reduction clause is present on the taskloop directive, the nogroup
9807  // clause must not be specified.
9808  if (checkReductionClauseWithNogroup(*this, Clauses))
9809  return StmtError();
9810  if (checkSimdlenSafelenSpecified(*this, Clauses))
9811  return StmtError();
9812 
9813  setFunctionHasBranchProtectedScope();
9815  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
9816 }
9817 
9819  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9820  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9821  if (!AStmt)
9822  return StmtError();
9823 
9824  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9825  auto *CS = cast<CapturedStmt>(AStmt);
9826  // 1.2.2 OpenMP Language Terminology
9827  // Structured block - An executable statement with a single entry at the
9828  // top and a single exit at the bottom.
9829  // The point of exit cannot be a branch out of the structured block.
9830  // longjmp() and throw() must not violate the entry/exit criteria.
9831  CS->getCapturedDecl()->setNothrow();
9832  for (int ThisCaptureLevel =
9833  getOpenMPCaptureLevels(OMPD_parallel_master_taskloop);
9834  ThisCaptureLevel > 1; --ThisCaptureLevel) {
9835  CS = cast<CapturedStmt>(CS->getCapturedStmt());
9836  // 1.2.2 OpenMP Language Terminology
9837  // Structured block - An executable statement with a single entry at the
9838  // top and a single exit at the bottom.
9839  // The point of exit cannot be a branch out of the structured block.
9840  // longjmp() and throw() must not violate the entry/exit criteria.
9841  CS->getCapturedDecl()->setNothrow();
9842  }
9843 
9845  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9846  // define the nested loops number.
9847  unsigned NestedLoopCount = checkOpenMPLoop(
9848  OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses),
9849  /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
9850  VarsWithImplicitDSA, B);
9851  if (NestedLoopCount == 0)
9852  return StmtError();
9853 
9854  assert((CurContext->isDependentContext() || B.builtAll()) &&
9855  "omp for loop exprs were not built");
9856 
9857  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9858  // The grainsize clause and num_tasks clause are mutually exclusive and may
9859  // not appear on the same taskloop directive.
9860  if (checkGrainsizeNumTasksClauses(*this, Clauses))
9861  return StmtError();
9862  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9863  // If a reduction clause is present on the taskloop directive, the nogroup
9864  // clause must not be specified.
9865  if (checkReductionClauseWithNogroup(*this, Clauses))
9866  return StmtError();
9867 
9868  setFunctionHasBranchProtectedScope();
9870  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
9871 }
9872 
9874  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9875  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9876  if (!AStmt)
9877  return StmtError();
9878 
9879  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9880  auto *CS = cast<CapturedStmt>(AStmt);
9881  // 1.2.2 OpenMP Language Terminology
9882  // Structured block - An executable statement with a single entry at the
9883  // top and a single exit at the bottom.
9884  // The point of exit cannot be a branch out of the structured block.
9885  // longjmp() and throw() must not violate the entry/exit criteria.
9886  CS->getCapturedDecl()->setNothrow();
9887  for (int ThisCaptureLevel =
9888  getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd);
9889  ThisCaptureLevel > 1; --ThisCaptureLevel) {
9890  CS = cast<CapturedStmt>(CS->getCapturedStmt());
9891  // 1.2.2 OpenMP Language Terminology
9892  // Structured block - An executable statement with a single entry at the
9893  // top and a single exit at the bottom.
9894  // The point of exit cannot be a branch out of the structured block.
9895  // longjmp() and throw() must not violate the entry/exit criteria.
9896  CS->getCapturedDecl()->setNothrow();
9897  }
9898 
9900  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9901  // define the nested loops number.
9902  unsigned NestedLoopCount = checkOpenMPLoop(
9903  OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses),
9904  /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
9905  VarsWithImplicitDSA, B);
9906  if (NestedLoopCount == 0)
9907  return StmtError();
9908 
9909  assert((CurContext->isDependentContext() || B.builtAll()) &&
9910  "omp for loop exprs were not built");
9911 
9912  if (!CurContext->isDependentContext()) {
9913  // Finalize the clauses that need pre-built expressions for CodeGen.
9914  for (OMPClause *C : Clauses) {
9915  if (auto *LC = dyn_cast<OMPLinearClause>(C))
9916  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9917  B.NumIterations, *this, CurScope,
9918  DSAStack))
9919  return StmtError();
9920  }
9921  }
9922 
9923  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9924  // The grainsize clause and num_tasks clause are mutually exclusive and may
9925  // not appear on the same taskloop directive.
9926  if (checkGrainsizeNumTasksClauses(*this, Clauses))
9927  return StmtError();
9928  // OpenMP, [2.9.2 taskloop Construct, Restrictions]
9929  // If a reduction clause is present on the taskloop directive, the nogroup
9930  // clause must not be specified.
9931  if (checkReductionClauseWithNogroup(*this, Clauses))
9932  return StmtError();
9933  if (checkSimdlenSafelenSpecified(*this, Clauses))
9934  return StmtError();
9935 
9936  setFunctionHasBranchProtectedScope();
9938  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
9939 }
9940 
9942  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9943  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9944  if (!AStmt)
9945  return StmtError();
9946 
9947  assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9949  // In presence of clause 'collapse' with number of loops, it will
9950  // define the nested loops number.
9951  unsigned NestedLoopCount =
9952  checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
9953  nullptr /*ordered not a clause on distribute*/, AStmt,
9954  *this, *DSAStack, VarsWithImplicitDSA, B);
9955  if (NestedLoopCount == 0)
9956  return StmtError();
9957 
9958  assert((CurContext->isDependentContext() || B.builtAll()) &&
9959  "omp for loop exprs were not built");
9960 
9961  setFunctionHasBranchProtectedScope();
9962  return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
9963  NestedLoopCount, Clauses, AStmt, B);
9964 }
9965 
9967  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9968  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9969  if (!AStmt)
9970  return StmtError();
9971 
9972  auto *CS = cast<CapturedStmt>(AStmt);
9973  // 1.2.2 OpenMP Language Terminology
9974  // Structured block - An executable statement with a single entry at the
9975  // top and a single exit at the bottom.
9976  // The point of exit cannot be a branch out of the structured block.
9977  // longjmp() and throw() must not violate the entry/exit criteria.
9978  CS->getCapturedDecl()->setNothrow();
9979  for (int ThisCaptureLevel =
9980  getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
9981  ThisCaptureLevel > 1; --ThisCaptureLevel) {
9982  CS = cast<CapturedStmt>(CS->getCapturedStmt());
9983  // 1.2.2 OpenMP Language Terminology
9984  // Structured block - An executable statement with a single entry at the
9985  // top and a single exit at the bottom.
9986  // The point of exit cannot be a branch out of the structured block.
9987  // longjmp() and throw() must not violate the entry/exit criteria.
9988  CS->getCapturedDecl()->setNothrow();
9989  }
9990 
9992  // In presence of clause 'collapse' with number of loops, it will
9993  // define the nested loops number.
9994  unsigned NestedLoopCount = checkOpenMPLoop(
9995  OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
9996  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
9997  VarsWithImplicitDSA, B);
9998  if (NestedLoopCount == 0)
9999  return StmtError();
10000 
10001  assert((CurContext->isDependentContext() || B.builtAll()) &&
10002  "omp for loop exprs were not built");
10003 
10004  setFunctionHasBranchProtectedScope();
10006  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10007  DSAStack->isCancelRegion());
10008 }
10009 
10011  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10012  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10013  if (!AStmt)
10014  return StmtError();
10015 
10016  auto *CS = cast<CapturedStmt>(AStmt);
10017  // 1.2.2 OpenMP Language Terminology
10018  // Structured block - An executable statement with a single entry at the
10019  // top and a single exit at the bottom.
10020  // The point of exit cannot be a branch out of the structured block.
10021  // longjmp() and throw() must not violate the entry/exit criteria.
10022  CS->getCapturedDecl()->setNothrow();
10023  for (int ThisCaptureLevel =
10024  getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
10025  ThisCaptureLevel > 1; --ThisCaptureLevel) {
10026  CS = cast<CapturedStmt>(CS->getCapturedStmt());
10027  // 1.2.2 OpenMP Language Terminology
10028  // Structured block - An executable statement with a single entry at the
10029  // top and a single exit at the bottom.
10030  // The point of exit cannot be a branch out of the structured block.
10031  // longjmp() and throw() must not violate the entry/exit criteria.
10032  CS->getCapturedDecl()->setNothrow();
10033  }
10034 
10036  // In presence of clause 'collapse' with number of loops, it will
10037  // define the nested loops number.
10038  unsigned NestedLoopCount = checkOpenMPLoop(
10039  OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
10040  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
10041  VarsWithImplicitDSA, B);
10042  if (NestedLoopCount == 0)
10043  return StmtError();
10044 
10045  assert((CurContext->isDependentContext() || B.builtAll()) &&
10046  "omp for loop exprs were not built");
10047 
10048  if (!CurContext->isDependentContext()) {
10049  // Finalize the clauses that need pre-built expressions for CodeGen.
10050  for (OMPClause *C : Clauses) {
10051  if (auto *LC = dyn_cast<OMPLinearClause>(C))
10052  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10053  B.NumIterations, *this, CurScope,
10054  DSAStack))
10055  return StmtError();
10056  }
10057  }
10058 
10059  if (checkSimdlenSafelenSpecified(*this, Clauses))
10060  return StmtError();
10061 
10062  setFunctionHasBranchProtectedScope();
10064  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10065 }
10066 
10068  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10069  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10070  if (!AStmt)
10071  return StmtError();
10072 
10073  auto *CS = cast<CapturedStmt>(AStmt);
10074  // 1.2.2 OpenMP Language Terminology
10075  // Structured block - An executable statement with a single entry at the
10076  // top and a single exit at the bottom.
10077  // The point of exit cannot be a branch out of the structured block.
10078  // longjmp() and throw() must not violate the entry/exit criteria.
10079  CS->getCapturedDecl()->setNothrow();
10080  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
10081  ThisCaptureLevel > 1; --ThisCaptureLevel) {
10082  CS = cast<CapturedStmt>(CS->getCapturedStmt());
10083  // 1.2.2 OpenMP Language Terminology
10084  // Structured block - An executable statement with a single entry at the
10085  // top and a single exit at the bottom.
10086  // The point of exit cannot be a branch out of the structured block.
10087  // longjmp() and throw() must not violate the entry/exit criteria.
10088  CS->getCapturedDecl()->setNothrow();
10089  }
10090 
10092  // In presence of clause 'collapse' with number of loops, it will
10093  // define the nested loops number.
10094  unsigned NestedLoopCount =
10095  checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
10096  nullptr /*ordered not a clause on distribute*/, CS, *this,
10097  *DSAStack, VarsWithImplicitDSA, B);
10098  if (NestedLoopCount == 0)
10099  return StmtError();
10100 
10101  assert((CurContext->isDependentContext() || B.builtAll()) &&
10102  "omp for loop exprs were not built");
10103 
10104  if (!CurContext->isDependentContext()) {
10105  // Finalize the clauses that need pre-built expressions for CodeGen.
10106  for (OMPClause *C : Clauses) {
10107  if (auto *LC = dyn_cast<OMPLinearClause>(C))
10108  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10109  B.NumIterations, *this, CurScope,
10110  DSAStack))
10111  return StmtError();
10112  }
10113  }
10114 
10115  if (checkSimdlenSafelenSpecified(*this, Clauses))
10116  return StmtError();
10117 
10118  setFunctionHasBranchProtectedScope();
10119  return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
10120  NestedLoopCount, Clauses, AStmt, B);
10121 }
10122 
10124  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10125  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10126  if (!AStmt)
10127  return StmtError();
10128 
10129  auto *CS = cast<CapturedStmt>(AStmt);
10130  // 1.2.2 OpenMP Language Terminology
10131  // Structured block - An executable statement with a single entry at the
10132  // top and a single exit at the bottom.
10133  // The point of exit cannot be a branch out of the structured block.
10134  // longjmp() and throw() must not violate the entry/exit criteria.
10135  CS->getCapturedDecl()->setNothrow();
10136  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
10137  ThisCaptureLevel > 1; --ThisCaptureLevel) {
10138  CS = cast<CapturedStmt>(CS->getCapturedStmt());
10139  // 1.2.2 OpenMP Language Terminology
10140  // Structured block - An executable statement with a single entry at the
10141  // top and a single exit at the bottom.
10142  // The point of exit cannot be a branch out of the structured block.
10143  // longjmp() and throw() must not violate the entry/exit criteria.
10144  CS->getCapturedDecl()->setNothrow();
10145  }
10146 
10148  // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10149  // define the nested loops number.
10150  unsigned NestedLoopCount = checkOpenMPLoop(
10151  OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
10152  getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
10153  VarsWithImplicitDSA, B);
10154  if (NestedLoopCount == 0)
10155  return StmtError();
10156 
10157  assert((CurContext->isDependentContext() || B.builtAll()) &&
10158  "omp target parallel for simd loop exprs were not built");
10159 
10160  if (!CurContext->isDependentContext()) {
10161  // Finalize the clauses that need pre-built expressions for CodeGen.
10162  for (OMPClause *C : Clauses) {
10163  if (auto *LC = dyn_cast<OMPLinearClause>(C))
10164  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10165  B.NumIterations, *this, CurScope,
10166  DSAStack))
10167  return StmtError();
10168  }
10169  }
10170  if (checkSimdlenSafelenSpecified(*this, Clauses))
10171  return StmtError();
10172 
10173  setFunctionHasBranchProtectedScope();
10175  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10176 }
10177 
10179  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10180  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10181  if (!AStmt)
10182  return StmtError();
10183 
10184  auto *CS = cast<CapturedStmt>(AStmt);
10185  // 1.2.2 OpenMP Language Terminology
10186  // Structured block - An executable statement with a single entry at the
10187  // top and a single exit at the bottom.
10188  // The point of exit cannot be a branch out of the structured block.
10189  // longjmp() and throw() must not violate the entry/exit criteria.
10190  CS->getCapturedDecl()->setNothrow();
10191  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
10192  ThisCaptureLevel > 1; --ThisCaptureLevel) {
10193  CS = cast<CapturedStmt>(CS->getCapturedStmt());
10194  // 1.2.2 OpenMP Language Terminology
10195  // Structured block - An executable statement with a single entry at the
10196  // top and a single exit at the bottom.
10197  // The point of exit cannot be a branch out of the structured block.
10198  // longjmp() and throw() must not violate the entry/exit criteria.
10199  CS->getCapturedDecl()->setNothrow();
10200  }
10201 
10203  // In presence of clause 'collapse' with number of loops, it will define the
10204  // nested loops number.
10205  unsigned NestedLoopCount =
10206  checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
10207  getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
10208  VarsWithImplicitDSA, B);
10209  if (NestedLoopCount == 0)
10210  return StmtError();
10211 
10212  assert((CurContext->isDependentContext() || B.builtAll()) &&
10213  "omp target simd loop exprs were not built");
10214 
10215  if (!CurContext->isDependentContext()) {
10216  // Finalize the clauses that need pre-built expressions for CodeGen.
10217  for (OMPClause *C : Clauses) {
10218  if (auto *LC = dyn_cast<OMPLinearClause>(C))
10219  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10220  B.NumIterations, *this, CurScope,
10221  DSAStack))
10222  return StmtError();
10223  }
10224  }
10225 
10226  if (checkSimdlenSafelenSpecified(*this, Clauses))
10227  return StmtError();
10228 
10229  setFunctionHasBranchProtectedScope();
10230  return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
10231  NestedLoopCount, Clauses, AStmt, B);
10232 }
10233 
10235  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10236  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10237  if (!AStmt)
10238  return StmtError();
10239 
10240  auto *CS = cast<CapturedStmt>(AStmt);
10241  // 1.2.2 OpenMP Language Terminology
10242  // Structured block - An executable statement with a single entry at the
10243  // top and a single exit at the bottom.
10244  // The point of exit cannot be a branch out of the structured block.
10245  // longjmp() and throw() must not violate the entry/exit criteria.
10246  CS->getCapturedDecl()->setNothrow();
10247  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
10248  ThisCaptureLevel > 1; --ThisCaptureLevel) {
10249  CS = cast<CapturedStmt>(CS->getCapturedStmt());
10250  // 1.2.2 OpenMP Language Terminology
10251  // Structured block - An executable statement with a single entry at the
10252  // top and a single exit at the bottom.
10253  // The point of exit cannot be a branch out of the structured block.
10254  // longjmp() and throw() must not violate the entry/exit criteria.
10255  CS->getCapturedDecl()->setNothrow();
10256  }
10257 
10259  // In presence of clause 'collapse' with number of loops, it will
10260  // define the nested loops number.
10261  unsigned NestedLoopCount =
10262  checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
10263  nullptr /*ordered not a clause on distribute*/, CS, *this,
10264  *DSAStack, VarsWithImplicitDSA, B);
10265  if (NestedLoopCount == 0)
10266  return StmtError();
10267 
10268  assert((CurContext->isDependentContext() || B.builtAll()) &&
10269  "omp teams distribute loop exprs were not built");
10270 
10271  setFunctionHasBranchProtectedScope();
10272 
10273  DSAStack->setParentTeamsRegionLoc(StartLoc);
10274 
10276  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10277 }
10278 
10280  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10281  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10282  if (!AStmt)
10283  return StmtError();
10284 
10285  auto *CS = cast<CapturedStmt>(AStmt);
10286  // 1.2.2 OpenMP Language Terminology
10287  // Structured block - An executable statement with a single entry at the
10288  // top and a single exit at the bottom.
10289  // The point of exit cannot be a branch out of the structured block.
10290  // longjmp() and throw() must not violate the entry/exit criteria.
10291  CS->getCapturedDecl()->setNothrow();
10292  for (int ThisCaptureLevel =
10293  getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
10294  ThisCaptureLevel > 1; --ThisCaptureLevel) {
10295  CS = cast<CapturedStmt>(CS->getCapturedStmt());
10296  // 1.2.2 OpenMP Language Terminology
10297  // Structured block - An executable statement with a single entry at the
10298  // top and a single exit at the bottom.
10299  // The point of exit cannot be a branch out of the structured block.
10300  // longjmp() and throw() must not violate the entry/exit criteria.
10301  CS->getCapturedDecl()->setNothrow();
10302  }
10303 
10304 
10306  // In presence of clause 'collapse' with number of loops, it will
10307  // define the nested loops number.
10308  unsigned NestedLoopCount = checkOpenMPLoop(
10309  OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
10310  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
10311  VarsWithImplicitDSA, B);
10312 
10313  if (NestedLoopCount == 0)
10314  return StmtError();
10315 
10316  assert((CurContext->isDependentContext() || B.builtAll()) &&
10317  "omp teams distribute simd loop exprs were not built");
10318 
10319  if (!CurContext->isDependentContext()) {
10320  // Finalize the clauses that need pre-built expressions for CodeGen.
10321  for (OMPClause *C : Clauses) {
10322  if (auto *LC = dyn_cast<OMPLinearClause>(C))
10323  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10324  B.NumIterations, *this, CurScope,
10325  DSAStack))
10326  return StmtError();
10327  }
10328  }
10329 
10330  if (checkSimdlenSafelenSpecified(*this, Clauses))
10331  return StmtError();
10332 
10333  setFunctionHasBranchProtectedScope();
10334 
10335  DSAStack->setParentTeamsRegionLoc(StartLoc);
10336 
10338  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10339 }
10340 
10342  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10343  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10344  if (!AStmt)
10345  return StmtError();
10346 
10347  auto *CS = cast<CapturedStmt>(AStmt);
10348  // 1.2.2 OpenMP Language Terminology
10349  // Structured block - An executable statement with a single entry at the
10350  // top and a single exit at the bottom.
10351  // The point of exit cannot be a branch out of the structured block.
10352  // longjmp() and throw() must not violate the entry/exit criteria.
10353  CS->getCapturedDecl()->setNothrow();
10354 
10355  for (int ThisCaptureLevel =
10356  getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
10357  ThisCaptureLevel > 1; --ThisCaptureLevel) {
10358  CS = cast<CapturedStmt>(CS->getCapturedStmt());
10359  // 1.2.2 OpenMP Language Terminology
10360  // Structured block - An executable statement with a single entry at the
10361  // top and a single exit at the bottom.
10362  // The point of exit cannot be a branch out of the structured block.
10363  // longjmp() and throw() must not violate the entry/exit criteria.
10364  CS->getCapturedDecl()->setNothrow();
10365  }
10366 
10368  // In presence of clause 'collapse' with number of loops, it will
10369  // define the nested loops number.
10370  unsigned NestedLoopCount = checkOpenMPLoop(
10371  OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
10372  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
10373  VarsWithImplicitDSA, B);
10374 
10375  if (NestedLoopCount == 0)
10376  return StmtError();
10377 
10378  assert((CurContext->isDependentContext() || B.builtAll()) &&
10379  "omp for loop exprs were not built");
10380 
10381  if (!CurContext->isDependentContext()) {
10382  // Finalize the clauses that need pre-built expressions for CodeGen.
10383  for (OMPClause *C : Clauses) {
10384  if (auto *LC = dyn_cast<OMPLinearClause>(C))
10385  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10386  B.NumIterations, *this, CurScope,
10387  DSAStack))
10388  return StmtError();
10389  }
10390  }
10391 
10392  if (checkSimdlenSafelenSpecified(*this, Clauses))
10393  return StmtError();
10394 
10395  setFunctionHasBranchProtectedScope();
10396 
10397  DSAStack->setParentTeamsRegionLoc(StartLoc);
10398 
10400  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10401 }
10402 
10404  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10405  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10406  if (!AStmt)
10407  return StmtError();
10408 
10409  auto *CS = cast<CapturedStmt>(AStmt);
10410  // 1.2.2 OpenMP Language Terminology
10411  // Structured block - An executable statement with a single entry at the
10412  // top and a single exit at the bottom.
10413  // The point of exit cannot be a branch out of the structured block.
10414  // longjmp() and throw() must not violate the entry/exit criteria.
10415  CS->getCapturedDecl()->setNothrow();
10416 
10417  for (int ThisCaptureLevel =
10418  getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
10419  ThisCaptureLevel > 1; --ThisCaptureLevel) {
10420  CS = cast<CapturedStmt>(CS->getCapturedStmt());
10421  // 1.2.2 OpenMP Language Terminology
10422  // Structured block - An executable statement with a single entry at the
10423  // top and a single exit at the bottom.
10424  // The point of exit cannot be a branch out of the structured block.
10425  // longjmp() and throw() must not violate the entry/exit criteria.
10426  CS->getCapturedDecl()->setNothrow();
10427  }
10428 
10430  // In presence of clause 'collapse' with number of loops, it will
10431  // define the nested loops number.
10432  unsigned NestedLoopCount = checkOpenMPLoop(
10433  OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
10434  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
10435  VarsWithImplicitDSA, B);
10436 
10437  if (NestedLoopCount == 0)
10438  return StmtError();
10439 
10440  assert((CurContext->isDependentContext() || B.builtAll()) &&
10441  "omp for loop exprs were not built");
10442 
10443  setFunctionHasBranchProtectedScope();
10444 
10445  DSAStack->setParentTeamsRegionLoc(StartLoc);
10446 
10448  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10449  DSAStack->isCancelRegion());
10450 }
10451 
10453  Stmt *AStmt,
10454  SourceLocation StartLoc,
10455  SourceLocation EndLoc) {
10456  if (!AStmt)
10457  return StmtError();
10458 
10459  auto *CS = cast<CapturedStmt>(AStmt);
10460  // 1.2.2 OpenMP Language Terminology
10461  // Structured block - An executable statement with a single entry at the
10462  // top and a single exit at the bottom.
10463  // The point of exit cannot be a branch out of the structured block.
10464  // longjmp() and throw() must not violate the entry/exit criteria.
10465  CS->getCapturedDecl()->setNothrow();
10466 
10467  for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
10468  ThisCaptureLevel > 1; --ThisCaptureLevel) {
10469  CS = cast<CapturedStmt>(CS->getCapturedStmt());
10470  // 1.2.2 OpenMP Language Terminology
10471  // Structured block - An executable statement with a single entry at the
10472  // top and a single exit at the bottom.
10473  // The point of exit cannot be a branch out of the structured block.
10474  // longjmp() and throw() must not violate the entry/exit criteria.
10475  CS->getCapturedDecl()->setNothrow();
10476  }
10477  setFunctionHasBranchProtectedScope();
10478 
10479  return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
10480  AStmt);
10481 }
10482 
10484  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10485  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10486  if (!AStmt)
10487  return StmtError();
10488 
10489  auto *CS = cast<CapturedStmt>(AStmt);
10490  // 1.2.2 OpenMP Language Terminology
10491  // Structured block - An executable statement with a single entry at the
10492  // top and a single exit at the bottom.
10493  // The point of exit cannot be a branch out of the structured block.
10494  // longjmp() and throw() must not violate the entry/exit criteria.
10495  CS->getCapturedDecl()->setNothrow();
10496  for (int ThisCaptureLevel =
10497  getOpenMPCaptureLevels(OMPD_target_teams_distribute);
10498  ThisCaptureLevel > 1; --ThisCaptureLevel) {
10499  CS = cast<CapturedStmt>(CS->getCapturedStmt());
10500  // 1.2.2 OpenMP Language Terminology
10501  // Structured block - An executable statement with a single entry at the
10502  // top and a single exit at the bottom.
10503  // The point of exit cannot be a branch out of the structured block.
10504  // longjmp() and throw() must not violate the entry/exit criteria.
10505  CS->getCapturedDecl()->setNothrow();
10506  }
10507 
10509  // In presence of clause 'collapse' with number of loops, it will
10510  // define the nested loops number.
10511  unsigned NestedLoopCount = checkOpenMPLoop(
10512  OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
10513  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
10514  VarsWithImplicitDSA, B);
10515  if (NestedLoopCount == 0)
10516  return StmtError();
10517 
10518  assert((CurContext->isDependentContext() || B.builtAll()) &&
10519  "omp target teams distribute loop exprs were not built");
10520 
10521  setFunctionHasBranchProtectedScope();
10523  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10524 }
10525 
10527  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10528  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10529  if (!AStmt)
10530  return StmtError();
10531 
10532  auto *CS = cast<CapturedStmt>(AStmt);
10533  // 1.2.2 OpenMP Language Terminology
10534  // Structured block - An executable statement with a single entry at the
10535  // top and a single exit at the bottom.
10536  // The point of exit cannot be a branch out of the structured block.
10537  // longjmp() and throw() must not violate the entry/exit criteria.
10538  CS->getCapturedDecl()->setNothrow();
10539  for (int ThisCaptureLevel =
10540  getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
10541  ThisCaptureLevel > 1; --ThisCaptureLevel) {
10542  CS = cast<CapturedStmt>(CS->getCapturedStmt());
10543  // 1.2.2 OpenMP Language Terminology
10544  // Structured block - An executable statement with a single entry at the
10545  // top and a single exit at the bottom.
10546  // The point of exit cannot be a branch out of the structured block.
10547  // longjmp() and throw() must not violate the entry/exit criteria.
10548  CS->getCapturedDecl()->setNothrow();
10549  }
10550 
10552  // In presence of clause 'collapse' with number of loops, it will
10553  // define the nested loops number.
10554  unsigned NestedLoopCount = checkOpenMPLoop(
10555  OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
10556  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
10557  VarsWithImplicitDSA, B);
10558  if (NestedLoopCount == 0)
10559  return StmtError();
10560 
10561  assert((CurContext->isDependentContext() || B.builtAll()) &&
10562  "omp target teams distribute parallel for loop exprs were not built");
10563 
10564  if (!CurContext->isDependentContext()) {
10565  // Finalize the clauses that need pre-built expressions for CodeGen.
10566  for (OMPClause *C : Clauses) {
10567  if (auto *LC = dyn_cast<OMPLinearClause>(C))
10568  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10569  B.NumIterations, *this, CurScope,
10570  DSAStack))
10571  return StmtError();
10572  }
10573  }
10574 
10575  setFunctionHasBranchProtectedScope();
10577  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10578  DSAStack->isCancelRegion());
10579 }
10580 
10582  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10583  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10584  if (!AStmt)
10585  return StmtError();
10586 
10587  auto *CS = cast<CapturedStmt>(AStmt);
10588  // 1.2.2 OpenMP Language Terminology
10589  // Structured block - An executable statement with a single entry at the
10590  // top and a single exit at the bottom.
10591  // The point of exit cannot be a branch out of the structured block.
10592  // longjmp() and throw() must not violate the entry/exit criteria.
10593  CS->getCapturedDecl()->setNothrow();
10594  for (int ThisCaptureLevel = getOpenMPCaptureLevels(
10595  OMPD_target_teams_distribute_parallel_for_simd);
10596  ThisCaptureLevel > 1; --ThisCaptureLevel) {
10597  CS = cast<CapturedStmt>(CS->getCapturedStmt());
10598  // 1.2.2 OpenMP Language Terminology
10599  // Structured block - An executable statement with a single entry at the
10600  // top and a single exit at the bottom.
10601  // The point of exit cannot be a branch out of the structured block.
10602  // longjmp() and throw() must not violate the entry/exit criteria.
10603  CS->getCapturedDecl()->setNothrow();
10604  }
10605 
10607  // In presence of clause 'collapse' with number of loops, it will
10608  // define the nested loops number.
10609  unsigned NestedLoopCount =
10610  checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
10611  getCollapseNumberExpr(Clauses),
10612  nullptr /*ordered not a clause on distribute*/, CS, *this,
10613  *DSAStack, VarsWithImplicitDSA, B);
10614  if (NestedLoopCount == 0)
10615  return StmtError();
10616 
10617  assert((CurContext->isDependentContext() || B.builtAll()) &&
10618  "omp target teams distribute parallel for simd loop exprs were not "
10619  "built");
10620 
10621  if (!CurContext->isDependentContext()) {
10622  // Finalize the clauses that need pre-built expressions for CodeGen.
10623  for (OMPClause *C : Clauses) {
10624  if (auto *LC = dyn_cast<OMPLinearClause>(C))
10625  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10626  B.NumIterations, *this, CurScope,
10627  DSAStack))
10628  return StmtError();
10629  }
10630  }
10631 
10632  if (checkSimdlenSafelenSpecified(*this, Clauses))
10633  return StmtError();
10634 
10635  setFunctionHasBranchProtectedScope();
10637  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10638 }
10639 
10641  ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10642  SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10643  if (!AStmt)
10644  return StmtError();
10645 
10646  auto *CS = cast<CapturedStmt>(AStmt);
10647  // 1.2.2 OpenMP Language Terminology
10648  // Structured block - An executable statement with a single entry at the
10649  // top and a single exit at the bottom.
10650  // The point of exit cannot be a branch out of the structured block.
10651  // longjmp() and throw() must not violate the entry/exit criteria.
10652  CS->getCapturedDecl()->setNothrow();
10653  for (int ThisCaptureLevel =
10654  getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
10655  ThisCaptureLevel > 1; --ThisCaptureLevel) {
10656  CS = cast<CapturedStmt>(CS->getCapturedStmt());
10657  // 1.2.2 OpenMP Language Terminology
10658  // Structured block - An executable statement with a single entry at the
10659  // top and a single exit at the bottom.
10660  // The point of exit cannot be a branch out of the structured block.
10661  // longjmp() and throw() must not violate the entry/exit criteria.
10662  CS->getCapturedDecl()->setNothrow();
10663  }
10664 
10666  // In presence of clause 'collapse' with number of loops, it will
10667  // define the nested loops number.
10668  unsigned NestedLoopCount = checkOpenMPLoop(
10669  OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
10670  nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
10671  VarsWithImplicitDSA, B);
10672  if (NestedLoopCount == 0)
10673  return StmtError();
10674 
10675  assert((CurContext->isDependentContext() || B.builtAll()) &&
10676  "omp target teams distribute simd loop exprs were not built");
10677 
10678  if (!CurContext->isDependentContext()) {
10679  // Finalize the clauses that need pre-built expressions for CodeGen.
10680  for (OMPClause *C : Clauses) {
10681  if (auto *LC = dyn_cast<OMPLinearClause>(C))
10682  if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10683  B.NumIterations, *this, CurScope,
10684  DSAStack))
10685  return StmtError();
10686  }
10687  }
10688 
10689  if (checkSimdlenSafelenSpecified(*this, Clauses))
10690  return StmtError();
10691 
10692  setFunctionHasBranchProtectedScope();
10694  Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10695 }
10696 
10698  SourceLocation StartLoc,
10699  SourceLocation LParenLoc,
10700  SourceLocation EndLoc) {
10701  OMPClause *Res = nullptr;
10702  switch (Kind) {
10703  case OMPC_final:
10704  Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
10705  break;
10706  case OMPC_num_threads:
10707  Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
10708  break;
10709  case OMPC_safelen:
10710  Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
10711  break;
10712  case OMPC_simdlen:
10713  Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
10714  break;
10715  case OMPC_allocator:
10716  Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
10717  break;
10718  case OMPC_collapse:
10719  Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
10720  break;
10721  case OMPC_ordered:
10722  Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
10723  break;
10724  case OMPC_device:
10725  Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc);
10726  break;
10727  case OMPC_num_teams:
10728  Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
10729  break;
10730  case OMPC_thread_limit:
10731  Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
10732  break;
10733  case OMPC_priority:
10734  Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
10735  break;
10736  case OMPC_grainsize:
10737  Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
10738  break;
10739  case OMPC_num_tasks:
10740  Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
10741  break;
10742  case OMPC_hint:
10743  Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
10744  break;
10745  case OMPC_if:
10746  case OMPC_default:
10747  case OMPC_proc_bind:
10748  case OMPC_schedule:
10749  case OMPC_private:
10750  case OMPC_firstprivate:
10751  case OMPC_lastprivate:
10752  case OMPC_shared:
10753  case OMPC_reduction:
10754  case OMPC_task_reduction:
10755  case OMPC_in_reduction:
10756  case OMPC_linear:
10757  case OMPC_aligned:
10758  case OMPC_copyin:
10759  case OMPC_copyprivate:
10760  case OMPC_nowait:
10761  case OMPC_untied:
10762  case OMPC_mergeable:
10763  case OMPC_threadprivate:
10764  case OMPC_allocate:
10765  case OMPC_flush:
10766  case OMPC_read:
10767  case OMPC_write:
10768  case OMPC_update:
10769  case OMPC_capture:
10770  case OMPC_seq_cst:
10771  case OMPC_depend:
10772  case OMPC_threads:
10773  case OMPC_simd:
10774  case OMPC_map:
10775  case OMPC_nogroup:
10776  case OMPC_dist_schedule:
10777  case OMPC_defaultmap:
10778  case OMPC_unknown:
10779  case OMPC_uniform:
10780  case OMPC_to:
10781  case OMPC_from:
10782  case OMPC_use_device_ptr:
10783  case OMPC_is_device_ptr:
10784  case OMPC_unified_address:
10785  case OMPC_unified_shared_memory:
10786  case OMPC_reverse_offload:
10787  case OMPC_dynamic_allocators:
10788  case OMPC_atomic_default_mem_order:
10789  case OMPC_device_type:
10790  case OMPC_match:
10791  case OMPC_nontemporal:
10792  llvm_unreachable("Clause is not allowed.");
10793  }
10794  return Res;
10795 }
10796 
10797 // An OpenMP directive such as 'target parallel' has two captured regions:
10798 // for the 'target' and 'parallel' respectively. This function returns
10799 // the region in which to capture expressions associated with a clause.
10800 // A return value of OMPD_unknown signifies that the expression should not
10801 // be captured.
10803  OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion,
10804  OpenMPDirectiveKind NameModifier = OMPD_unknown) {
10805  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
10806  switch (CKind) {
10807  case OMPC_if:
10808  switch (DKind) {
10809  case OMPD_target_parallel_for_simd:
10810  if (OpenMPVersion >= 50 &&
10811  (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
10812  CaptureRegion = OMPD_parallel;
10813  break;
10814  }
10815  LLVM_FALLTHROUGH;
10816  case OMPD_target_parallel:
10817  case OMPD_target_parallel_for:
10818  // If this clause applies to the nested 'parallel' region, capture within
10819  // the 'target' region, otherwise do not capture.
10820  if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
10821  CaptureRegion = OMPD_target;
10822  break;
10823  case OMPD_target_teams_distribute_parallel_for_simd:
10824  if (OpenMPVersion >= 50 &&
10825  (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
10826  CaptureRegion = OMPD_parallel;
10827  break;
10828  }
10829  LLVM_FALLTHROUGH;
10830  case OMPD_target_teams_distribute_parallel_for:
10831  // If this clause applies to the nested 'parallel' region, capture within
10832  // the 'teams' region, otherwise do not capture.
10833  if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
10834  CaptureRegion = OMPD_teams;
10835  break;
10836  case OMPD_teams_distribute_parallel_for_simd:
10837  if (OpenMPVersion >= 50 &&
10838  (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
10839  CaptureRegion = OMPD_parallel;
10840  break;
10841  }
10842  LLVM_FALLTHROUGH;
10843  case OMPD_teams_distribute_parallel_for:
10844  CaptureRegion = OMPD_teams;
10845  break;
10846  case OMPD_target_update:
10847  case OMPD_target_enter_data:
10848  case OMPD_target_exit_data:
10849  CaptureRegion = OMPD_task;
10850  break;
10851  case OMPD_parallel_master_taskloop:
10852  if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
10853  CaptureRegion = OMPD_parallel;
10854  break;
10855  case OMPD_parallel_master_taskloop_simd:
10856  if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
10857  NameModifier == OMPD_taskloop) {
10858  CaptureRegion = OMPD_parallel;
10859  break;
10860  }
10861  if (OpenMPVersion <= 45)
10862  break;
10863  if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
10864  CaptureRegion = OMPD_taskloop;
10865  break;
10866  case OMPD_parallel_for_simd:
10867  if (OpenMPVersion <= 45)
10868  break;
10869  if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
10870  CaptureRegion = OMPD_parallel;
10871  break;
10872  case OMPD_taskloop_simd:
10873  case OMPD_master_taskloop_simd:
10874  if (OpenMPVersion <= 45)
10875  break;
10876  if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
10877  CaptureRegion = OMPD_taskloop;
10878  break;
10879  case OMPD_distribute_parallel_for_simd:
10880  if (OpenMPVersion <= 45)
10881  break;
10882  if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
10883  CaptureRegion = OMPD_parallel;
10884  break;
10885  case OMPD_target_simd:
10886  if (OpenMPVersion >= 50 &&
10887  (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
10888  CaptureRegion = OMPD_target;
10889  break;
10890  case OMPD_teams_distribute_simd:
10891  case OMPD_target_teams_distribute_simd:
10892  if (OpenMPVersion >= 50 &&
10893  (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
10894  CaptureRegion = OMPD_teams;
10895  break;
10896  case OMPD_cancel:
10897  case OMPD_parallel:
10898  case OMPD_parallel_master:
10899  case OMPD_parallel_sections:
10900  case OMPD_parallel_for:
10901  case OMPD_target:
10902  case OMPD_target_teams:
10903  case OMPD_target_teams_distribute:
10904  case OMPD_distribute_parallel_for:
10905  case OMPD_task:
10906  case OMPD_taskloop:
10907  case OMPD_master_taskloop:
10908  case OMPD_target_data:
10909  case OMPD_simd:
10910  case OMPD_for_simd:
10911  case OMPD_distribute_simd:
10912  // Do not capture if-clause expressions.
10913  break;
10914  case OMPD_threadprivate:
10915  case OMPD_allocate:
10916  case OMPD_taskyield:
10917  case OMPD_barrier:
10918  case OMPD_taskwait:
10919  case OMPD_cancellation_point:
10920  case OMPD_flush:
10921  case OMPD_declare_reduction:
10922  case OMPD_declare_mapper:
10923  case OMPD_declare_simd:
10924  case OMPD_declare_variant:
10925  case OMPD_declare_target:
10926  case OMPD_end_declare_target:
10927  case OMPD_teams:
10928  case OMPD_for:
10929  case OMPD_sections:
10930  case OMPD_section:
10931  case OMPD_single:
10932  case OMPD_master:
10933  case OMPD_critical:
10934  case OMPD_taskgroup:
10935  case OMPD_distribute:
10936  case OMPD_ordered:
10937  case OMPD_atomic:
10938  case OMPD_teams_distribute:
10939  case OMPD_requires:
10940  llvm_unreachable("Unexpected OpenMP directive with if-clause");
10941  case OMPD_unknown:
10942  llvm_unreachable("Unknown OpenMP directive");
10943  }
10944  break;
10945  case OMPC_num_threads:
10946  switch (DKind) {
10947  case OMPD_target_parallel:
10948  case OMPD_target_parallel_for:
10949  case OMPD_target_parallel_for_simd:
10950  CaptureRegion = OMPD_target;
10951  break;
10952  case OMPD_teams_distribute_parallel_for:
10953  case OMPD_teams_distribute_parallel_for_simd:
10954  case OMPD_target_teams_distribute_parallel_for:
10955  case OMPD_target_teams_distribute_parallel_for_simd:
10956  CaptureRegion = OMPD_teams;
10957  break;
10958  case OMPD_parallel:
10959  case OMPD_parallel_master:
10960  case OMPD_parallel_sections:
10961  case OMPD_parallel_for:
10962  case OMPD_parallel_for_simd:
10963  case OMPD_distribute_parallel_for:
10964  case OMPD_distribute_parallel_for_simd:
10965  case OMPD_parallel_master_taskloop:
10966  case OMPD_parallel_master_taskloop_simd:
10967  // Do not capture num_threads-clause expressions.
10968  break;
10969  case OMPD_target_data:
10970  case OMPD_target_enter_data:
10971  case OMPD_target_exit_data:
10972  case OMPD_target_update:
10973  case OMPD_target:
10974  case OMPD_target_simd:
10975  case OMPD_target_teams:
10976  case OMPD_target_teams_distribute:
10977  case OMPD_target_teams_distribute_simd:
10978  case OMPD_cancel:
10979  case OMPD_task:
10980  case OMPD_taskloop:
10981  case OMPD_taskloop_simd:
10982  case OMPD_master_taskloop:
10983  case OMPD_master_taskloop_simd:
10984  case OMPD_threadprivate:
10985  case OMPD_allocate:
10986  case OMPD_taskyield:
10987  case OMPD_barrier:
10988  case OMPD_taskwait:
10989  case OMPD_cancellation_point:
10990  case OMPD_flush:
10991  case OMPD_declare_reduction:
10992  case OMPD_declare_mapper:
10993  case OMPD_declare_simd:
10994  case OMPD_declare_variant:
10995  case OMPD_declare_target:
10996  case OMPD_end_declare_target:
10997  case OMPD_teams:
10998  case OMPD_simd:
10999  case OMPD_for:
11000  case OMPD_for_simd:
11001  case OMPD_sections:
11002  case OMPD_section:
11003  case OMPD_single:
11004  case OMPD_master:
11005  case OMPD_critical:
11006  case OMPD_taskgroup:
11007  case OMPD_distribute:
11008  case OMPD_ordered:
11009  case OMPD_atomic:
11010  case OMPD_distribute_simd:
11011  case OMPD_teams_distribute:
11012  case OMPD_teams_distribute_simd:
11013  case OMPD_requires:
11014  llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
11015  case OMPD_unknown:
11016  llvm_unreachable("Unknown OpenMP directive");
11017  }
11018  break;
11019  case OMPC_num_teams:
11020  switch (DKind) {
11021  case OMPD_target_teams:
11022  case OMPD_target_teams_distribute:
11023  case OMPD_target_teams_distribute_simd:
11024  case OMPD_target_teams_distribute_parallel_for:
11025  case OMPD_target_teams_distribute_parallel_for_simd:
11026  CaptureRegion = OMPD_target;
11027  break;
11028  case OMPD_teams_distribute_parallel_for:
11029  case OMPD_teams_distribute_parallel_for_simd:
11030  case OMPD_teams:
11031  case OMPD_teams_distribute:
11032  case OMPD_teams_distribute_simd:
11033  // Do not capture num_teams-clause expressions.
11034  break;
11035  case OMPD_distribute_parallel_for:
11036  case OMPD_distribute_parallel_for_simd:
11037  case OMPD_task:
11038  case OMPD_taskloop:
11039  case OMPD_taskloop_simd:
11040  case OMPD_master_taskloop:
11041  case OMPD_master_taskloop_simd:
11042  case OMPD_parallel_master_taskloop:
11043  case OMPD_parallel_master_taskloop_simd:
11044  case OMPD_target_data:
11045  case OMPD_target_enter_data:
11046  case OMPD_target_exit_data:
11047  case OMPD_target_update:
11048  case OMPD_cancel:
11049  case OMPD_parallel:
11050  case OMPD_parallel_master:
11051  case OMPD_parallel_sections:
11052  case OMPD_parallel_for:
11053  case OMPD_parallel_for_simd:
11054  case OMPD_target:
11055  case OMPD_target_simd:
11056  case OMPD_target_parallel:
11057  case OMPD_target_parallel_for:
11058  case OMPD_target_parallel_for_simd:
11059  case OMPD_threadprivate:
11060  case OMPD_allocate:
11061  case OMPD_taskyield:
11062  case OMPD_barrier:
11063  case OMPD_taskwait:
11064  case OMPD_cancellation_point:
11065  case OMPD_flush:
11066  case OMPD_declare_reduction:
11067  case OMPD_declare_mapper:
11068  case OMPD_declare_simd:
11069  case OMPD_declare_variant:
11070  case OMPD_declare_target:
11071  case OMPD_end_declare_target:
11072  case OMPD_simd:
11073  case OMPD_for:
11074  case OMPD_for_simd:
11075  case OMPD_sections:
11076  case OMPD_section:
11077  case OMPD_single:
11078  case OMPD_master:
11079  case OMPD_critical:
11080  case OMPD_taskgroup:
11081  case OMPD_distribute:
11082  case OMPD_ordered:
11083  case OMPD_atomic:
11084  case OMPD_distribute_simd:
11085  case OMPD_requires:
11086  llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
11087  case OMPD_unknown:
11088  llvm_unreachable("Unknown OpenMP directive");
11089  }
11090  break;
11091  case OMPC_thread_limit:
11092  switch (DKind) {
11093  case OMPD_target_teams:
11094  case OMPD_target_teams_distribute:
11095  case OMPD_target_teams_distribute_simd:
11096  case OMPD_target_teams_distribute_parallel_for:
11097  case OMPD_target_teams_distribute_parallel_for_simd:
11098  CaptureRegion = OMPD_target;
11099  break;
11100  case OMPD_teams_distribute_parallel_for:
11101  case OMPD_teams_distribute_parallel_for_simd:
11102  case OMPD_teams:
11103  case OMPD_teams_distribute:
11104  case OMPD_teams_distribute_simd:
11105  // Do not capture thread_limit-clause expressions.
11106  break;
11107  case OMPD_distribute_parallel_for:
11108  case OMPD_distribute_parallel_for_simd:
11109  case OMPD_task:
11110  case OMPD_taskloop:
11111  case OMPD_taskloop_simd:
11112  case OMPD_master_taskloop:
11113  case OMPD_master_taskloop_simd:
11114  case OMPD_parallel_master_taskloop:
11115  case OMPD_parallel_master_taskloop_simd:
11116  case OMPD_target_data:
11117  case OMPD_target_enter_data:
11118  case OMPD_target_exit_data:
11119  case OMPD_target_update:
11120  case OMPD_cancel:
11121  case OMPD_parallel:
11122  case OMPD_parallel_master:
11123  case OMPD_parallel_sections:
11124  case OMPD_parallel_for:
11125  case OMPD_parallel_for_simd:
11126  case OMPD_target:
11127  case OMPD_target_simd:
11128  case OMPD_target_parallel:
11129  case OMPD_target_parallel_for:
11130  case OMPD_target_parallel_for_simd:
11131  case OMPD_threadprivate:
11132  case OMPD_allocate:
11133  case OMPD_taskyield:
11134  case OMPD_barrier:
11135  case OMPD_taskwait:
11136  case OMPD_cancellation_point:
11137  case OMPD_flush:
11138  case OMPD_declare_reduction:
11139  case OMPD_declare_mapper:
11140  case OMPD_declare_simd:
11141  case OMPD_declare_variant:
11142  case OMPD_declare_target:
11143  case OMPD_end_declare_target:
11144  case OMPD_simd:
11145  case OMPD_for:
11146  case OMPD_for_simd:
11147  case OMPD_sections:
11148  case OMPD_section:
11149  case OMPD_single:
11150  case OMPD_master:
11151  case OMPD_critical:
11152  case OMPD_taskgroup:
11153  case OMPD_distribute:
11154  case OMPD_ordered:
11155  case OMPD_atomic:
11156  case OMPD_distribute_simd:
11157  case OMPD_requires:
11158  llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
11159  case OMPD_unknown:
11160  llvm_unreachable("Unknown OpenMP directive");
11161  }
11162  break;
11163  case OMPC_schedule:
11164  switch (DKind) {
11165  case OMPD_parallel_for:
11166  case OMPD_parallel_for_simd:
11167  case OMPD_distribute_parallel_for:
11168  case OMPD_distribute_parallel_for_simd:
11169  case OMPD_teams_distribute_parallel_for:
11170  case OMPD_teams_distribute_parallel_for_simd:
11171  case OMPD_target_parallel_for:
11172  case OMPD_target_parallel_for_simd:
11173  case OMPD_target_teams_distribute_parallel_for:
11174  case OMPD_target_teams_distribute_parallel_for_simd:
11175  CaptureRegion = OMPD_parallel;
11176  break;
11177  case OMPD_for:
11178  case OMPD_for_simd:
11179  // Do not capture schedule-clause expressions.
11180  break;
11181  case OMPD_task:
11182  case OMPD_taskloop:
11183  case OMPD_taskloop_simd:
11184  case OMPD_master_taskloop:
11185  case OMPD_master_taskloop_simd:
11186  case OMPD_parallel_master_taskloop:
11187  case OMPD_parallel_master_taskloop_simd:
11188  case OMPD_target_data:
11189  case OMPD_target_enter_data:
11190  case OMPD_target_exit_data:
11191  case OMPD_target_update:
11192  case OMPD_teams:
11193  case OMPD_teams_distribute:
11194  case OMPD_teams_distribute_simd:
11195  case OMPD_target_teams_distribute:
11196  case OMPD_target_teams_distribute_simd:
11197  case OMPD_target:
11198  case OMPD_target_simd:
11199  case OMPD_target_parallel:
11200  case OMPD_cancel:
11201  case OMPD_parallel:
11202  case OMPD_parallel_master:
11203  case OMPD_parallel_sections:
11204  case OMPD_threadprivate:
11205  case OMPD_allocate:
11206  case OMPD_taskyield:
11207  case OMPD_barrier:
11208  case OMPD_taskwait:
11209  case OMPD_cancellation_point:
11210  case OMPD_flush:
11211  case OMPD_declare_reduction:
11212  case OMPD_declare_mapper:
11213  case OMPD_declare_simd:
11214  case OMPD_declare_variant:
11215  case OMPD_declare_target:
11216  case OMPD_end_declare_target:
11217  case OMPD_simd:
11218  case OMPD_sections:
11219  case OMPD_section:
11220  case OMPD_single:
11221  case OMPD_master:
11222  case OMPD_critical:
11223  case OMPD_taskgroup:
11224  case OMPD_distribute:
11225  case OMPD_ordered:
11226  case OMPD_atomic:
11227  case OMPD_distribute_simd:
11228  case OMPD_target_teams:
11229  case OMPD_requires:
11230  llvm_unreachable("Unexpected OpenMP directive with schedule clause");
11231  case OMPD_unknown:
11232  llvm_unreachable("Unknown OpenMP directive");
11233  }
11234  break;
11235  case OMPC_dist_schedule:
11236  switch (DKind) {
11237  case OMPD_teams_distribute_parallel_for:
11238  case OMPD_teams_distribute_parallel_for_simd:
11239  case OMPD_teams_distribute:
11240  case OMPD_teams_distribute_simd:
11241  case OMPD_target_teams_distribute_parallel_for:
11242  case OMPD_target_teams_distribute_parallel_for_simd:
11243  case OMPD_target_teams_distribute:
11244  case OMPD_target_teams_distribute_simd:
11245  CaptureRegion = OMPD_teams;
11246  break;
11247  case OMPD_distribute_parallel_for:
11248  case OMPD_distribute_parallel_for_simd:
11249  case OMPD_distribute:
11250  case OMPD_distribute_simd:
11251  // Do not capture thread_limit-clause expressions.
11252  break;
11253  case OMPD_parallel_for:
11254  case OMPD_parallel_for_simd:
11255  case OMPD_target_parallel_for_simd:
11256  case OMPD_target_parallel_for:
11257  case OMPD_task:
11258  case OMPD_taskloop:
11259  case OMPD_taskloop_simd:
11260  case OMPD_master_taskloop:
11261  case OMPD_master_taskloop_simd:
11262  case OMPD_parallel_master_taskloop:
11263  case OMPD_parallel_master_taskloop_simd:
11264  case OMPD_target_data:
11265  case OMPD_target_enter_data:
11266  case OMPD_target_exit_data:
11267  case OMPD_target_update:
11268  case OMPD_teams:
11269  case OMPD_target:
11270  case OMPD_target_simd:
11271  case OMPD_target_parallel:
11272  case OMPD_cancel:
11273  case OMPD_parallel:
11274  case OMPD_parallel_master:
11275  case OMPD_parallel_sections:
11276  case OMPD_threadprivate:
11277  case OMPD_allocate:
11278  case OMPD_taskyield:
11279  case OMPD_barrier:
11280  case OMPD_taskwait:
11281  case OMPD_cancellation_point:
11282  case OMPD_flush:
11283  case OMPD_declare_reduction:
11284  case OMPD_declare_mapper:
11285  case OMPD_declare_simd:
11286  case OMPD_declare_variant:
11287  case OMPD_declare_target:
11288  case OMPD_end_declare_target:
11289  case OMPD_simd:
11290  case OMPD_for:
11291  case OMPD_for_simd:
11292  case OMPD_sections:
11293  case OMPD_section:
11294  case OMPD_single:
11295  case OMPD_master:
11296  case OMPD_critical:
11297  case OMPD_taskgroup:
11298  case OMPD_ordered:
11299  case OMPD_atomic:
11300  case OMPD_target_teams:
11301  case OMPD_requires:
11302  llvm_unreachable("Unexpected OpenMP directive with schedule clause");
11303  case OMPD_unknown:
11304  llvm_unreachable("Unknown OpenMP directive");
11305  }
11306  break;
11307  case OMPC_device:
11308  switch (DKind) {
11309  case OMPD_target_update:
11310  case OMPD_target_enter_data:
11311  case OMPD_target_exit_data:
11312  case OMPD_target:
11313  case OMPD_target_simd:
11314  case OMPD_target_teams:
11315  case OMPD_target_parallel:
11316  case OMPD_target_teams_distribute:
11317  case OMPD_target_teams_distribute_simd:
11318  case OMPD_target_parallel_for:
11319  case OMPD_target_parallel_for_simd:
11320  case OMPD_target_teams_distribute_parallel_for:
11321  case OMPD_target_teams_distribute_parallel_for_simd:
11322  CaptureRegion = OMPD_task;
11323  break;
11324  case OMPD_target_data:
11325  // Do not capture device-clause expressions.
11326  break;
11327  case OMPD_teams_distribute_parallel_for:
11328  case OMPD_teams_distribute_parallel_for_simd:
11329  case OMPD_teams:
11330  case OMPD_teams_distribute:
11331  case OMPD_teams_distribute_simd:
11332  case OMPD_distribute_parallel_for:
11333  case OMPD_distribute_parallel_for_simd:
11334  case OMPD_task:
11335  case OMPD_taskloop:
11336  case OMPD_taskloop_simd:
11337  case OMPD_master_taskloop:
11338  case OMPD_master_taskloop_simd:
11339  case OMPD_parallel_master_taskloop:
11340  case OMPD_parallel_master_taskloop_simd:
11341  case OMPD_cancel:
11342  case OMPD_parallel:
11343  case OMPD_parallel_master:
11344  case OMPD_parallel_sections:
11345  case OMPD_parallel_for:
11346  case OMPD_parallel_for_simd:
11347  case OMPD_threadprivate:
11348  case OMPD_allocate:
11349  case OMPD_taskyield:
11350  case OMPD_barrier:
11351  case OMPD_taskwait:
11352  case OMPD_cancellation_point:
11353  case OMPD_flush:
11354  case OMPD_declare_reduction:
11355  case OMPD_declare_mapper:
11356  case OMPD_declare_simd:
11357  case OMPD_declare_variant:
11358  case OMPD_declare_target:
11359  case OMPD_end_declare_target:
11360  case OMPD_simd:
11361  case OMPD_for:
11362  case OMPD_for_simd:
11363  case OMPD_sections:
11364  case OMPD_section:
11365  case OMPD_single:
11366  case OMPD_master:
11367  case OMPD_critical:
11368  case OMPD_taskgroup:
11369  case OMPD_distribute:
11370  case OMPD_ordered:
11371  case OMPD_atomic:
11372  case OMPD_distribute_simd:
11373  case OMPD_requires:
11374  llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
11375  case OMPD_unknown:
11376  llvm_unreachable("Unknown OpenMP directive");
11377  }
11378  break;
11379  case OMPC_grainsize:
11380  case OMPC_num_tasks:
11381  case OMPC_final:
11382  case OMPC_priority:
11383  switch (DKind) {
11384  case OMPD_task:
11385  case OMPD_taskloop:
11386  case OMPD_taskloop_simd:
11387  case OMPD_master_taskloop:
11388  case OMPD_master_taskloop_simd:
11389  break;
11390  case OMPD_parallel_master_taskloop:
11391  case OMPD_parallel_master_taskloop_simd:
11392  CaptureRegion = OMPD_parallel;
11393  break;
11394  case OMPD_target_update:
11395  case OMPD_target_enter_data:
11396  case OMPD_target_exit_data:
11397  case OMPD_target:
11398  case OMPD_target_simd:
11399  case OMPD_target_teams:
11400  case OMPD_target_parallel:
11401  case OMPD_target_teams_distribute:
11402  case OMPD_target_teams_distribute_simd:
11403  case OMPD_target_parallel_for:
11404  case OMPD_target_parallel_for_simd:
11405  case OMPD_target_teams_distribute_parallel_for:
11406  case OMPD_target_teams_distribute_parallel_for_simd:
11407  case OMPD_target_data:
11408  case OMPD_teams_distribute_parallel_for:
11409  case OMPD_teams_distribute_parallel_for_simd:
11410  case OMPD_teams:
11411  case OMPD_teams_distribute:
11412  case OMPD_teams_distribute_simd:
11413  case OMPD_distribute_parallel_for:
11414  case OMPD_distribute_parallel_for_simd:
11415  case OMPD_cancel:
11416  case OMPD_parallel:
11417  case OMPD_parallel_master:
11418  case OMPD_parallel_sections:
11419  case OMPD_parallel_for:
11420  case OMPD_parallel_for_simd:
11421  case OMPD_threadprivate:
11422  case OMPD_allocate:
11423  case OMPD_taskyield:
11424  case OMPD_barrier:
11425  case OMPD_taskwait:
11426  case OMPD_cancellation_point:
11427  case OMPD_flush:
11428  case OMPD_declare_reduction:
11429  case OMPD_declare_mapper:
11430  case OMPD_declare_simd:
11431  case OMPD_declare_variant:
11432  case OMPD_declare_target:
11433  case OMPD_end_declare_target:
11434  case OMPD_simd:
11435  case OMPD_for:
11436  case OMPD_for_simd:
11437  case OMPD_sections:
11438  case OMPD_section:
11439  case OMPD_single:
11440  case OMPD_master:
11441  case OMPD_critical:
11442  case OMPD_taskgroup:
11443  case OMPD_distribute:
11444  case OMPD_ordered:
11445  case OMPD_atomic:
11446  case OMPD_distribute_simd:
11447  case OMPD_requires:
11448  llvm_unreachable("Unexpected OpenMP directive with grainsize-clause");
11449  case OMPD_unknown:
11450  llvm_unreachable("Unknown OpenMP directive");
11451  }
11452  break;
11453  case OMPC_firstprivate:
11454  case OMPC_lastprivate:
11455  case OMPC_reduction:
11456  case OMPC_task_reduction:
11457  case OMPC_in_reduction:
11458  case OMPC_linear:
11459  case OMPC_default:
11460  case OMPC_proc_bind:
11461  case OMPC_safelen:
11462  case OMPC_simdlen:
11463  case OMPC_allocator:
11464  case OMPC_collapse:
11465  case OMPC_private:
11466  case OMPC_shared:
11467  case OMPC_aligned:
11468  case OMPC_copyin:
11469  case OMPC_copyprivate:
11470  case OMPC_ordered:
11471  case OMPC_nowait:
11472  case OMPC_untied:
11473  case OMPC_mergeable:
11474  case OMPC_threadprivate:
11475  case OMPC_allocate:
11476  case OMPC_flush:
11477  case OMPC_read:
11478  case OMPC_write:
11479  case OMPC_update:
11480  case OMPC_capture:
11481  case OMPC_seq_cst:
11482  case OMPC_depend:
11483  case OMPC_threads:
11484  case OMPC_simd:
11485  case OMPC_map:
11486  case OMPC_nogroup:
11487  case OMPC_hint:
11488  case OMPC_defaultmap:
11489  case OMPC_unknown:
11490  case OMPC_uniform:
11491  case OMPC_to:
11492  case OMPC_from:
11493  case OMPC_use_device_ptr:
11494  case OMPC_is_device_ptr:
11495  case OMPC_unified_address:
11496  case OMPC_unified_shared_memory:
11497  case OMPC_reverse_offload:
11498  case OMPC_dynamic_allocators:
11499  case OMPC_atomic_default_mem_order:
11500  case OMPC_device_type:
11501  case OMPC_match:
11502  case OMPC_nontemporal:
11503  llvm_unreachable("Unexpected OpenMP clause.");
11504  }
11505  return CaptureRegion;
11506 }
11507 
11509  Expr *Condition, SourceLocation StartLoc,
11510  SourceLocation LParenLoc,
11511  SourceLocation NameModifierLoc,
11513  SourceLocation EndLoc) {
11514  Expr *ValExpr = Condition;
11515  Stmt *HelperValStmt = nullptr;
11516  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
11517  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
11518  !Condition->isInstantiationDependent() &&
11519  !Condition->containsUnexpandedParameterPack()) {
11520  ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
11521  if (Val.isInvalid())
11522  return nullptr;
11523 
11524  ValExpr = Val.get();
11525 
11526  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
11527  CaptureRegion = getOpenMPCaptureRegionForClause(
11528  DKind, OMPC_if, LangOpts.OpenMP, NameModifier);
11529  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
11530  ValExpr = MakeFullExpr(ValExpr).get();
11531  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
11532  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
11533  HelperValStmt = buildPreInits(Context, Captures);
11534  }
11535  }
11536 
11537  return new (Context)
11538  OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
11539  LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
11540 }
11541 
11543  SourceLocation StartLoc,
11544  SourceLocation LParenLoc,
11545  SourceLocation EndLoc) {
11546  Expr *ValExpr = Condition;
11547  Stmt *HelperValStmt = nullptr;
11548  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
11549  if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
11550  !Condition->isInstantiationDependent() &&
11551  !Condition->containsUnexpandedParameterPack()) {
11552  ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
11553  if (Val.isInvalid())
11554  return nullptr;
11555 
11556  ValExpr = MakeFullExpr(Val.get()).get();
11557 
11558  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
11559  CaptureRegion =
11560  getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP);
11561  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
11562  ValExpr = MakeFullExpr(ValExpr).get();
11563  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
11564  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
11565  HelperValStmt = buildPreInits(Context, Captures);
11566  }
11567  }
11568 
11569  return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion,
11570  StartLoc, LParenLoc, EndLoc);
11571 }
11572 
11574  Expr *Op) {
11575  if (!Op)
11576  return ExprError();
11577 
11578  class IntConvertDiagnoser : public ICEConvertDiagnoser {
11579  public:
11580  IntConvertDiagnoser()
11581  : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
11582  SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
11583  QualType T) override {
11584  return S.Diag(Loc, diag::err_omp_not_integral) << T;
11585  }
11586  SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
11587  QualType T) override {
11588  return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
11589  }
11590  SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
11591  QualType T,
11592  QualType ConvTy) override {
11593  return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
11594  }
11595  SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
11596  QualType ConvTy) override {
11597  return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
11598  << ConvTy->isEnumeralType() << ConvTy;
11599  }
11600  SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
11601  QualType T) override {
11602  return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
11603  }
11604  SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
11605  QualType ConvTy) override {
11606  return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
11607  << ConvTy->isEnumeralType() << ConvTy;
11608  }
11609  SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
11610  QualType) override {
11611  llvm_unreachable("conversion functions are permitted");
11612  }
11613  } ConvertDiagnoser;
11614  return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
11615 }
11616 
11617 static bool
11619  bool StrictlyPositive, bool BuildCapture = false,
11620  OpenMPDirectiveKind DKind = OMPD_unknown,
11621  OpenMPDirectiveKind *CaptureRegion = nullptr,
11622  Stmt **HelperValStmt = nullptr) {
11623  if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
11624  !ValExpr->isInstantiationDependent()) {
11625  SourceLocation Loc = ValExpr->getExprLoc();
11626  ExprResult Value =
11627  SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
11628  if (Value.isInvalid())
11629  return false;
11630 
11631  ValExpr = Value.get();
11632  // The expression must evaluate to a non-negative integer value.
11634  if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) &&
11635  Result.isSigned() &&
11636  !((!StrictlyPositive && Result.isNonNegative()) ||
11637  (StrictlyPositive && Result.isStrictlyPositive()))) {
11638  SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
11639  << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
11640  << ValExpr->getSourceRange();
11641  return false;
11642  }
11643  if (!BuildCapture)
11644  return true;
11645  *CaptureRegion =
11646  getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP);
11647  if (*CaptureRegion != OMPD_unknown &&
11648  !SemaRef.CurContext->isDependentContext()) {
11649  ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
11650  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
11651  ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
11652  *HelperValStmt = buildPreInits(SemaRef.Context, Captures);
11653  }
11654  }
11655  return true;
11656 }
11657 
11659  SourceLocation StartLoc,
11660  SourceLocation LParenLoc,
11661  SourceLocation EndLoc) {
11662  Expr *ValExpr = NumThreads;
11663  Stmt *HelperValStmt = nullptr;
11664 
11665  // OpenMP [2.5, Restrictions]
11666  // The num_threads expression must evaluate to a positive integer value.
11667  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
11668  /*StrictlyPositive=*/true))
11669  return nullptr;
11670 
11671  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
11672  OpenMPDirectiveKind CaptureRegion =
11673  getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP);
11674  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
11675  ValExpr = MakeFullExpr(ValExpr).get();
11676  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
11677  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
11678  HelperValStmt = buildPreInits(Context, Captures);
11679  }
11680 
11681  return new (Context) OMPNumThreadsClause(
11682  ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
11683 }
11684 
11685 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
11686  OpenMPClauseKind CKind,
11687  bool StrictlyPositive) {
11688  if (!E)
11689  return ExprError();
11690  if (E->isValueDependent() || E->isTypeDependent() ||
11692  return E;
11694  ExprResult ICE = VerifyIntegerConstantExpression(E, &Result);
11695  if (ICE.isInvalid())
11696  return ExprError();
11697  if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
11698  (!StrictlyPositive && !Result.isNonNegative())) {
11699  Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
11700  << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
11701  << E->getSourceRange();
11702  return ExprError();
11703  }
11704  if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
11705  Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
11706  << E->getSourceRange();
11707  return ExprError();
11708  }
11709  if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
11710  DSAStack->setAssociatedLoops(Result.getExtValue());
11711  else if (CKind == OMPC_ordered)
11712  DSAStack->setAssociatedLoops(Result.getExtValue());
11713  return ICE;
11714 }
11715 
11717  SourceLocation LParenLoc,
11718  SourceLocation EndLoc) {
11719  // OpenMP [2.8.1, simd construct, Description]
11720  // The parameter of the safelen clause must be a constant
11721  // positive integer expression.
11722  ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
11723  if (Safelen.isInvalid())
11724  return nullptr;
11725  return new (Context)
11726  OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
11727 }
11728 
11730  SourceLocation LParenLoc,
11731  SourceLocation EndLoc) {
11732  // OpenMP [2.8.1, simd construct, Description]
11733  // The parameter of the simdlen clause must be a constant
11734  // positive integer expression.
11735  ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
11736  if (Simdlen.isInvalid())
11737  return nullptr;
11738  return new (Context)
11739  OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
11740 }
11741 
11742 /// Tries to find omp_allocator_handle_t type.
11744  DSAStackTy *Stack) {
11745  QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
11746  if (!OMPAllocatorHandleT.isNull())
11747  return true;
11748  // Build the predefined allocator expressions.
11749  bool ErrorFound = false;
11750  for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc;
11751  I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
11752  auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
11753  StringRef Allocator =
11754  OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
11755  DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
11756  auto *VD = dyn_cast_or_null<ValueDecl>(
11757  S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
11758  if (!VD) {
11759  ErrorFound = true;
11760  break;
11761  }
11762  QualType AllocatorType =
11763  VD->getType().getNonLValueExprType(S.getASTContext());
11764  ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
11765  if (!Res.isUsable()) {
11766  ErrorFound = true;
11767  break;
11768  }
11769  if (OMPAllocatorHandleT.isNull())
11770  OMPAllocatorHandleT = AllocatorType;
11771  if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) {
11772  ErrorFound = true;
11773  break;
11774  }
11775  Stack->setAllocator(AllocatorKind, Res.get());
11776  }
11777  if (ErrorFound) {
11778  S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found);
11779  return false;
11780  }
11781  OMPAllocatorHandleT.addConst();
11782  Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
11783  return true;
11784 }
11785 
11787  SourceLocation LParenLoc,
11788  SourceLocation EndLoc) {
11789  // OpenMP [2.11.3, allocate Directive, Description]
11790  // allocator is an expression of omp_allocator_handle_t type.
11791  if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack))
11792  return nullptr;
11793 
11794  ExprResult Allocator = DefaultLvalueConversion(A);
11795  if (Allocator.isInvalid())
11796  return nullptr;
11797  Allocator = PerformImplicitConversion(Allocator.get(),
11798  DSAStack->getOMPAllocatorHandleT(),
11800  /*AllowExplicit=*/true);
11801  if (Allocator.isInvalid())
11802  return nullptr;
11803  return new (Context)
11804  OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
11805 }
11806 
11808  SourceLocation StartLoc,
11809  SourceLocation LParenLoc,
11810  SourceLocation EndLoc) {
11811  // OpenMP [2.7.1, loop construct, Description]
11812  // OpenMP [2.8.1, simd construct, Description]
11813  // OpenMP [2.9.6, distribute construct, Description]
11814  // The parameter of the collapse clause must be a constant
11815  // positive integer expression.
11816  ExprResult NumForLoopsResult =
11817  VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
11818  if (NumForLoopsResult.isInvalid())
11819  return nullptr;
11820  return new (Context)
11821  OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
11822 }
11823 
11825  SourceLocation EndLoc,
11826  SourceLocation LParenLoc,
11827  Expr *NumForLoops) {
11828  // OpenMP [2.7.1, loop construct, Description]
11829  // OpenMP [2.8.1, simd construct, Description]
11830  // OpenMP [2.9.6, distribute construct, Description]
11831  // The parameter of the ordered clause must be a constant
11832  // positive integer expression if any.
11833  if (NumForLoops && LParenLoc.isValid()) {
11834  ExprResult NumForLoopsResult =
11835  VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
11836  if (NumForLoopsResult.isInvalid())
11837  return nullptr;
11838  NumForLoops = NumForLoopsResult.get();
11839  } else {
11840  NumForLoops = nullptr;
11841  }
11842  auto *Clause = OMPOrderedClause::Create(
11843  Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0,
11844  StartLoc, LParenLoc, EndLoc);
11845  DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
11846  return Clause;
11847 }
11848 
11850  OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
11851  SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
11852  OMPClause *Res = nullptr;
11853  switch (Kind) {
11854  case OMPC_default:
11855  Res =
11856  ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument),
11857  ArgumentLoc, StartLoc, LParenLoc, EndLoc);
11858  break;
11859  case OMPC_proc_bind:
11860  Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument),
11861  ArgumentLoc, StartLoc, LParenLoc, EndLoc);
11862  break;
11863  case OMPC_atomic_default_mem_order:
11864  Res = ActOnOpenMPAtomicDefaultMemOrderClause(
11865  static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
11866  ArgumentLoc, StartLoc, LParenLoc, EndLoc);
11867  break;
11868  case OMPC_if:
11869  case OMPC_final:
11870  case OMPC_num_threads:
11871  case OMPC_safelen:
11872  case OMPC_simdlen:
11873  case OMPC_allocator:
11874  case OMPC_collapse:
11875  case OMPC_schedule:
11876  case OMPC_private:
11877  case OMPC_firstprivate:
11878  case OMPC_lastprivate:
11879  case OMPC_shared:
11880  case OMPC_reduction:
11881  case OMPC_task_reduction:
11882  case OMPC_in_reduction:
11883  case OMPC_linear:
11884  case OMPC_aligned:
11885  case OMPC_copyin:
11886  case OMPC_copyprivate:
11887  case OMPC_ordered:
11888  case OMPC_nowait:
11889  case OMPC_untied:
11890  case OMPC_mergeable:
11891  case OMPC_threadprivate:
11892  case OMPC_allocate:
11893  case OMPC_flush:
11894  case OMPC_read:
11895  case OMPC_write:
11896  case OMPC_update:
11897  case OMPC_capture:
11898  case OMPC_seq_cst:
11899  case OMPC_depend:
11900  case OMPC_device:
11901  case OMPC_threads:
11902  case OMPC_simd:
11903  case OMPC_map:
11904  case OMPC_num_teams:
11905  case OMPC_thread_limit:
11906  case OMPC_priority:
11907  case OMPC_grainsize:
11908  case OMPC_nogroup:
11909  case OMPC_num_tasks:
11910  case OMPC_hint:
11911  case OMPC_dist_schedule:
11912  case OMPC_defaultmap:
11913  case OMPC_unknown:
11914  case OMPC_uniform:
11915  case OMPC_to:
11916  case OMPC_from:
11917  case OMPC_use_device_ptr:
11918  case OMPC_is_device_ptr:
11919  case OMPC_unified_address:
11920  case OMPC_unified_shared_memory:
11921  case OMPC_reverse_offload:
11922  case OMPC_dynamic_allocators:
11923  case OMPC_device_type:
11924  case OMPC_match:
11925  case OMPC_nontemporal:
11926  llvm_unreachable("Clause is not allowed.");
11927  }
11928  return Res;
11929 }
11930 
11931 static std::string
11933  ArrayRef<unsigned> Exclude = llvm::None) {
11934  SmallString<256> Buffer;
11935  llvm::raw_svector_ostream Out(Buffer);
11936  unsigned Skipped = Exclude.size();
11937  auto S = Exclude.begin(), E = Exclude.end();
11938  for (unsigned I = First; I < Last; ++I) {
11939  if (std::find(S, E, I) != E) {
11940  --Skipped;
11941  continue;
11942  }
11943  Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
11944  if (I + Skipped + 2 == Last)
11945  Out << " or ";
11946  else if (I + Skipped + 1 != Last)
11947  Out << ", ";
11948  }
11949  return Out.str();
11950 }
11951 
11953  SourceLocation KindKwLoc,
11954  SourceLocation StartLoc,
11955  SourceLocation LParenLoc,
11956  SourceLocation EndLoc) {
11957  if (Kind == OMPC_DEFAULT_unknown) {
11958  static_assert(OMPC_DEFAULT_unknown > 0,
11959  "OMPC_DEFAULT_unknown not greater than 0");
11960  Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
11961  << getListOfPossibleValues(OMPC_default, /*First=*/0,
11962  /*Last=*/OMPC_DEFAULT_unknown)
11963  << getOpenMPClauseName(OMPC_default);
11964  return nullptr;
11965  }
11966  switch (Kind) {
11967  case OMPC_DEFAULT_none:
11968  DSAStack->setDefaultDSANone(KindKwLoc);
11969  break;
11970  case OMPC_DEFAULT_shared:
11971  DSAStack->setDefaultDSAShared(KindKwLoc);
11972  break;
11973  case OMPC_DEFAULT_unknown:
11974  llvm_unreachable("Clause kind is not allowed.");
11975  break;
11976  }
11977  return new (Context)
11978  OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
11979 }
11980 
11982  SourceLocation KindKwLoc,
11983  SourceLocation StartLoc,
11984  SourceLocation LParenLoc,
11985  SourceLocation EndLoc) {
11986  if (Kind == OMP_PROC_BIND_unknown) {
11987  Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
11988  << getListOfPossibleValues(OMPC_proc_bind,
11989  /*First=*/unsigned(OMP_PROC_BIND_master),
11990  /*Last=*/5)
11991  << getOpenMPClauseName(OMPC_proc_bind);
11992  return nullptr;
11993  }
11994  return new (Context)
11995  OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
11996 }
11997 
12000  SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
12002  Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
12004  OMPC_atomic_default_mem_order, /*First=*/0,
12006  << getOpenMPClauseName(OMPC_atomic_default_mem_order);
12007  return nullptr;
12008  }
12009  return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
12010  LParenLoc, EndLoc);
12011 }
12012 
12015  SourceLocation StartLoc, SourceLocation LParenLoc,
12016  ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
12017  SourceLocation EndLoc) {
12018  OMPClause *Res = nullptr;
12019  switch (Kind) {
12020  case OMPC_schedule:
12021  enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
12022  assert(Argument.size() == NumberOfElements &&
12023  ArgumentLoc.size() == NumberOfElements);
12024  Res = ActOnOpenMPScheduleClause(
12025  static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
12026  static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
12027  static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
12028  StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
12029  ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
12030  break;
12031  case OMPC_if:
12032  assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
12033  Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
12034  Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
12035  DelimLoc, EndLoc);
12036  break;
12037  case OMPC_dist_schedule:
12038  Res = ActOnOpenMPDistScheduleClause(
12039  static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
12040  StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
12041  break;
12042  case OMPC_defaultmap:
12043  enum { Modifier, DefaultmapKind };
12044  Res = ActOnOpenMPDefaultmapClause(
12045  static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
12046  static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
12047  StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
12048  EndLoc);
12049  break;
12050  case OMPC_final:
12051  case OMPC_num_threads:
12052  case OMPC_safelen:
12053  case OMPC_simdlen:
12054  case OMPC_allocator:
12055  case OMPC_collapse:
12056  case OMPC_default:
12057  case OMPC_proc_bind:
12058  case OMPC_private:
12059  case OMPC_firstprivate:
12060  case OMPC_lastprivate:
12061  case OMPC_shared:
12062  case OMPC_reduction:
12063  case OMPC_task_reduction:
12064  case OMPC_in_reduction:
12065  case OMPC_linear:
12066  case OMPC_aligned:
12067  case OMPC_copyin:
12068  case OMPC_copyprivate:
12069  case OMPC_ordered:
12070  case OMPC_nowait:
12071  case OMPC_untied:
12072  case OMPC_mergeable:
12073  case OMPC_threadprivate:
12074  case OMPC_allocate:
12075  case OMPC_flush:
12076  case OMPC_read:
12077  case OMPC_write:
12078  case OMPC_update:
12079  case OMPC_capture:
12080  case OMPC_seq_cst:
12081  case OMPC_depend:
12082  case OMPC_device:
12083  case OMPC_threads:
12084  case OMPC_simd:
12085  case OMPC_map:
12086  case OMPC_num_teams:
12087  case OMPC_thread_limit:
12088  case OMPC_priority:
12089  case OMPC_grainsize:
12090  case OMPC_nogroup:
12091  case OMPC_num_tasks:
12092  case OMPC_hint:
12093  case OMPC_unknown:
12094  case OMPC_uniform:
12095  case OMPC_to:
12096  case OMPC_from:
12097  case OMPC_use_device_ptr:
12098  case OMPC_is_device_ptr:
12099  case OMPC_unified_address:
12100  case OMPC_unified_shared_memory:
12101  case OMPC_reverse_offload:
12102  case OMPC_dynamic_allocators:
12103  case OMPC_atomic_default_mem_order:
12104  case OMPC_device_type:
12105  case OMPC_match:
12106  case OMPC_nontemporal:
12107  llvm_unreachable("Clause is not allowed.");
12108  }
12109  return Res;
12110 }
12111 
12114  SourceLocation M1Loc, SourceLocation M2Loc) {
12115  if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
12116  SmallVector<unsigned, 2> Excluded;
12118  Excluded.push_back(M2);
12119  if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
12120  Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
12121  if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
12122  Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
12123  S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
12124  << getListOfPossibleValues(OMPC_schedule,
12125  /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
12126  /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
12127  Excluded)
12128  << getOpenMPClauseName(OMPC_schedule);
12129  return true;
12130  }
12131  return false;
12132 }
12133 
12136  OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
12137  SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
12138  SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
12139  if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
12140  checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
12141  return nullptr;
12142  // OpenMP, 2.7.1, Loop Construct, Restrictions
12143  // Either the monotonic modifier or the nonmonotonic modifier can be specified
12144  // but not both.
12145  if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
12146  (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
12147  M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
12148  (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
12149  M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
12150  Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
12151  << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
12152  << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
12153  return nullptr;
12154  }
12155  if (Kind == OMPC_SCHEDULE_unknown) {
12156  std::string Values;
12157  if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
12158  unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
12159  Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
12160  /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
12161  Exclude);
12162  } else {
12163  Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
12164  /*Last=*/OMPC_SCHEDULE_unknown);
12165  }
12166  Diag(KindLoc, diag::err_omp_unexpected_clause_value)
12167  << Values << getOpenMPClauseName(OMPC_schedule);
12168  return nullptr;
12169  }
12170  // OpenMP, 2.7.1, Loop Construct, Restrictions
12171  // The nonmonotonic modifier can only be specified with schedule(dynamic) or
12172  // schedule(guided).
12173  if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
12174  M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
12175  Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
12176  Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
12177  diag::err_omp_schedule_nonmonotonic_static);
12178  return nullptr;
12179  }
12180  Expr *ValExpr = ChunkSize;
12181  Stmt *HelperValStmt = nullptr;
12182  if (ChunkSize) {
12183  if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
12184  !ChunkSize->isInstantiationDependent() &&
12185  !ChunkSize->containsUnexpandedParameterPack()) {
12186  SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
12187  ExprResult Val =
12188  PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
12189  if (Val.isInvalid())
12190  return nullptr;
12191 
12192  ValExpr = Val.get();
12193 
12194  // OpenMP [2.7.1, Restrictions]
12195  // chunk_size must be a loop invariant integer expression with a positive
12196  // value.
12198  if (ValExpr->isIntegerConstantExpr(Result, Context)) {
12199  if (Result.isSigned() && !Result.isStrictlyPositive()) {
12200  Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
12201  << "schedule" << 1 << ChunkSize->getSourceRange();
12202  return nullptr;
12203  }
12205  DSAStack->getCurrentDirective(), OMPC_schedule,
12206  LangOpts.OpenMP) != OMPD_unknown &&
12207  !CurContext->isDependentContext()) {
12208  ValExpr = MakeFullExpr(ValExpr).get();
12209  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
12210  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
12211  HelperValStmt = buildPreInits(Context, Captures);
12212  }
12213  }
12214  }
12215 
12216  return new (Context)
12217  OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
12218  ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
12219 }
12220 
12222  SourceLocation StartLoc,
12223  SourceLocation EndLoc) {
12224  OMPClause *Res = nullptr;
12225  switch (Kind) {
12226  case OMPC_ordered:
12227  Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
12228  break;
12229  case OMPC_nowait:
12230  Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
12231  break;
12232  case OMPC_untied:
12233  Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
12234  break;
12235  case OMPC_mergeable:
12236  Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
12237  break;
12238  case OMPC_read:
12239  Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
12240  break;
12241  case OMPC_write:
12242  Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
12243  break;
12244  case OMPC_update:
12245  Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
12246  break;
12247  case OMPC_capture:
12248  Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
12249  break;
12250  case OMPC_seq_cst:
12251  Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
12252  break;
12253  case OMPC_threads:
12254  Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
12255  break;
12256  case OMPC_simd:
12257  Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
12258  break;
12259  case OMPC_nogroup:
12260  Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
12261  break;
12262  case OMPC_unified_address:
12263  Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
12264  break;
12265  case OMPC_unified_shared_memory:
12266  Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
12267  break;
12268  case OMPC_reverse_offload:
12269  Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
12270  break;
12271  case OMPC_dynamic_allocators:
12272  Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
12273  break;
12274  case OMPC_if:
12275  case OMPC_final:
12276  case OMPC_num_threads:
12277  case OMPC_safelen:
12278  case OMPC_simdlen:
12279  case OMPC_allocator:
12280  case OMPC_collapse:
12281  case OMPC_schedule:
12282  case OMPC_private:
12283  case OMPC_firstprivate:
12284  case OMPC_lastprivate:
12285  case OMPC_shared:
12286  case OMPC_reduction:
12287  case OMPC_task_reduction:
12288  case OMPC_in_reduction:
12289  case OMPC_linear:
12290  case OMPC_aligned:
12291  case OMPC_copyin:
12292  case OMPC_copyprivate:
12293  case OMPC_default:
12294  case OMPC_proc_bind:
12295  case OMPC_threadprivate:
12296  case OMPC_allocate:
12297  case OMPC_flush:
12298  case OMPC_depend:
12299  case OMPC_device:
12300  case OMPC_map:
12301  case OMPC_num_teams:
12302  case OMPC_thread_limit:
12303  case OMPC_priority:
12304  case OMPC_grainsize:
12305  case OMPC_num_tasks:
12306  case OMPC_hint:
12307  case OMPC_dist_schedule:
12308  case OMPC_defaultmap:
12309  case OMPC_unknown:
12310  case OMPC_uniform:
12311  case OMPC_to:
12312  case OMPC_from:
12313  case OMPC_use_device_ptr:
12314  case OMPC_is_device_ptr:
12315  case OMPC_atomic_default_mem_order:
12316  case OMPC_device_type:
12317  case OMPC_match:
12318  case OMPC_nontemporal:
12319  llvm_unreachable("Clause is not allowed.");
12320  }
12321  return Res;
12322 }
12323 
12325  SourceLocation EndLoc) {
12326  DSAStack->setNowaitRegion();
12327  return new (Context) OMPNowaitClause(StartLoc, EndLoc);
12328 }
12329 
12331  SourceLocation EndLoc) {
12332  return new (Context) OMPUntiedClause(StartLoc, EndLoc);
12333 }
12334 
12336  SourceLocation EndLoc) {
12337  return new (Context) OMPMergeableClause(StartLoc, EndLoc);
12338 }
12339 
12341  SourceLocation EndLoc) {
12342  return new (Context) OMPReadClause(StartLoc, EndLoc);
12343 }
12344 
12346  SourceLocation EndLoc) {
12347  return new (Context) OMPWriteClause(StartLoc, EndLoc);
12348 }
12349 
12351  SourceLocation EndLoc) {
12352  return new (Context) OMPUpdateClause(StartLoc, EndLoc);
12353 }
12354 
12356  SourceLocation EndLoc) {
12357  return new (Context) OMPCaptureClause(StartLoc, EndLoc);
12358 }
12359 
12361  SourceLocation EndLoc) {
12362  return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
12363 }
12364 
12366  SourceLocation EndLoc) {
12367  return new (Context) OMPThreadsClause(StartLoc, EndLoc);
12368 }
12369 
12371  SourceLocation EndLoc) {
12372  return new (Context) OMPSIMDClause(StartLoc, EndLoc);
12373 }
12374 
12376  SourceLocation EndLoc) {
12377  return new (Context) OMPNogroupClause(StartLoc, EndLoc);
12378 }
12379 
12381  SourceLocation EndLoc) {
12382  return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
12383 }
12384 
12386  SourceLocation EndLoc) {
12387  return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
12388 }
12389 
12391  SourceLocation EndLoc) {
12392  return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
12393 }
12394 
12396  SourceLocation EndLoc) {
12397  return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
12398 }
12399 
12401  OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr,
12403  CXXScopeSpec &ReductionOrMapperIdScopeSpec,
12404  DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier,
12405  ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
12406  ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit,
12407  SourceLocation DepLinMapLastLoc) {
12408  SourceLocation StartLoc = Locs.StartLoc;
12409  SourceLocation LParenLoc = Locs.LParenLoc;
12410  SourceLocation EndLoc = Locs.EndLoc;
12411  OMPClause *Res = nullptr;
12412  switch (Kind) {
12413  case OMPC_private:
12414  Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
12415  break;
12416  case OMPC_firstprivate:
12417  Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
12418  break;
12419  case OMPC_lastprivate:
12420  assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown &&
12421  "Unexpected lastprivate modifier.");
12422  Res = ActOnOpenMPLastprivateClause(
12423  VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier),
12424  DepLinMapLastLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
12425  break;
12426  case OMPC_shared:
12427  Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
12428  break;
12429  case OMPC_reduction:
12430  Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
12431  EndLoc, ReductionOrMapperIdScopeSpec,
12432  ReductionOrMapperId);
12433  break;
12434  case OMPC_task_reduction:
12435  Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
12436  EndLoc, ReductionOrMapperIdScopeSpec,
12437  ReductionOrMapperId);
12438  break;
12439  case OMPC_in_reduction:
12440  Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
12441  EndLoc, ReductionOrMapperIdScopeSpec,
12442  ReductionOrMapperId);
12443  break;
12444  case OMPC_linear:
12445  assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown &&
12446  "Unexpected linear modifier.");
12447  Res = ActOnOpenMPLinearClause(
12448  VarList, TailExpr, StartLoc, LParenLoc,
12449  static_cast<OpenMPLinearClauseKind>(ExtraModifier), DepLinMapLastLoc,
12450  ColonLoc, EndLoc);
12451  break;
12452  case OMPC_aligned:
12453  Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc,
12454  ColonLoc, EndLoc);
12455  break;
12456  case OMPC_copyin:
12457  Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
12458  break;
12459  case OMPC_copyprivate:
12460  Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
12461  break;
12462  case OMPC_flush:
12463  Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
12464  break;
12465  case OMPC_depend:
12466  assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown &&
12467  "Unexpected depend modifier.");
12468  Res = ActOnOpenMPDependClause(
12469  static_cast<OpenMPDependClauseKind>(ExtraModifier), DepLinMapLastLoc,
12470  ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
12471  break;
12472  case OMPC_map:
12473  assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown &&
12474  "Unexpected map modifier.");
12475  Res = ActOnOpenMPMapClause(
12476  MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec,
12477  ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier),
12478  IsMapTypeImplicit, DepLinMapLastLoc, ColonLoc, VarList, Locs);
12479  break;
12480  case OMPC_to:
12481  Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec,
12482  ReductionOrMapperId, Locs);
12483  break;
12484  case OMPC_from:
12485  Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec,
12486  ReductionOrMapperId, Locs);
12487  break;
12488  case OMPC_use_device_ptr:
12489  Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
12490  break;
12491  case OMPC_is_device_ptr:
12492  Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
12493  break;
12494  case OMPC_allocate:
12495  Res = ActOnOpenMPAllocateClause(TailExpr, VarList, StartLoc, LParenLoc,
12496  ColonLoc, EndLoc);
12497  break;
12498  case OMPC_nontemporal:
12499  Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc);
12500  break;
12501  case OMPC_if:
12502  case OMPC_final:
12503  case OMPC_num_threads:
12504  case OMPC_safelen:
12505  case OMPC_simdlen:
12506  case OMPC_allocator:
12507  case OMPC_collapse:
12508  case OMPC_default:
12509  case OMPC_proc_bind:
12510  case OMPC_schedule:
12511  case OMPC_ordered:
12512  case OMPC_nowait:
12513  case OMPC_untied:
12514  case OMPC_mergeable:
12515  case OMPC_threadprivate:
12516  case OMPC_read:
12517  case OMPC_write:
12518  case OMPC_update:
12519  case OMPC_capture:
12520  case OMPC_seq_cst:
12521  case OMPC_device:
12522  case OMPC_threads:
12523  case OMPC_simd:
12524  case OMPC_num_teams:
12525  case OMPC_thread_limit:
12526  case OMPC_priority:
12527  case OMPC_grainsize:
12528  case OMPC_nogroup:
12529  case OMPC_num_tasks:
12530  case OMPC_hint:
12531  case OMPC_dist_schedule:
12532  case OMPC_defaultmap:
12533  case OMPC_unknown:
12534  case OMPC_uniform:
12535  case OMPC_unified_address:
12536  case OMPC_unified_shared_memory:
12537  case OMPC_reverse_offload:
12538  case OMPC_dynamic_allocators:
12539  case OMPC_atomic_default_mem_order:
12540  case OMPC_device_type:
12541  case OMPC_match:
12542  llvm_unreachable("Clause is not allowed.");
12543  }
12544  return Res;
12545 }
12546 
12548  ExprObjectKind OK, SourceLocation Loc) {
12549  ExprResult Res = BuildDeclRefExpr(
12550  Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
12551  if (!Res.isUsable())
12552  return ExprError();
12553  if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
12554  Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
12555  if (!Res.isUsable())
12556  return ExprError();
12557  }
12558  if (VK != VK_LValue && Res.get()->isGLValue()) {
12559  Res = DefaultLvalueConversion(Res.get());
12560  if (!Res.isUsable())
12561  return ExprError();
12562  }
12563  return Res;
12564 }
12565 
12567  SourceLocation StartLoc,
12568  SourceLocation LParenLoc,
12569  SourceLocation EndLoc) {
12571  SmallVector<Expr *, 8> PrivateCopies;
12572  for (Expr *RefExpr : VarList) {
12573  assert(RefExpr && "NULL expr in OpenMP private clause.");
12574  SourceLocation ELoc;
12575  SourceRange ERange;
12576  Expr *SimpleRefExpr = RefExpr;
12577  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
12578  if (Res.second) {
12579  // It will be analyzed later.
12580  Vars.push_back(RefExpr);
12581  PrivateCopies.push_back(nullptr);
12582  }
12583  ValueDecl *D = Res.first;
12584  if (!D)
12585  continue;
12586 
12587  QualType Type = D->getType();
12588  auto *VD = dyn_cast<VarDecl>(D);
12589 
12590  // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
12591  // A variable that appears in a private clause must not have an incomplete
12592  // type or a reference type.
12593  if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
12594  continue;
12595  Type = Type.getNonReferenceType();
12596 
12597  // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
12598  // A variable that is privatized must not have a const-qualified type
12599  // unless it is of class type with a mutable member. This restriction does
12600  // not apply to the firstprivate clause.
12601  //
12602  // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
12603  // A variable that appears in a private clause must not have a
12604  // const-qualified type unless it is of class type with a mutable member.
12605  if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
12606  continue;
12607 
12608  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
12609  // in a Construct]
12610  // Variables with the predetermined data-sharing attributes may not be
12611  // listed in data-sharing attributes clauses, except for the cases
12612  // listed below. For these exceptions only, listing a predetermined
12613  // variable in a data-sharing attribute clause is allowed and overrides
12614  // the variable's predetermined data-sharing attributes.
12615  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
12616  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
12617  Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
12618  << getOpenMPClauseName(OMPC_private);
12619  reportOriginalDsa(*this, DSAStack, D, DVar);
12620  continue;
12621  }
12622 
12623  OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
12624  // Variably modified types are not supported for tasks.
12625  if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
12626  isOpenMPTaskingDirective(CurrDir)) {
12627  Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
12628  << getOpenMPClauseName(OMPC_private) << Type
12629  << getOpenMPDirectiveName(CurrDir);
12630  bool IsDecl =
12631  !VD ||
12632  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
12633  Diag(D->getLocation(),
12634  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
12635  << D;
12636  continue;
12637  }
12638 
12639  // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
12640  // A list item cannot appear in both a map clause and a data-sharing
12641  // attribute clause on the same construct
12642  //
12643  // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
12644  // A list item cannot appear in both a map clause and a data-sharing
12645  // attribute clause on the same construct unless the construct is a
12646  // combined construct.
12647  if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) ||
12648  CurrDir == OMPD_target) {
12649  OpenMPClauseKind ConflictKind;
12650  if (DSAStack->checkMappableExprComponentListsForDecl(
12651  VD, /*CurrentRegionOnly=*/true,
12653  OpenMPClauseKind WhereFoundClauseKind) -> bool {
12654  ConflictKind = WhereFoundClauseKind;
12655  return true;
12656  })) {
12657  Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
12658  << getOpenMPClauseName(OMPC_private)
12659  << getOpenMPClauseName(ConflictKind)
12660  << getOpenMPDirectiveName(CurrDir);
12661  reportOriginalDsa(*this, DSAStack, D, DVar);
12662  continue;
12663  }
12664  }
12665 
12666  // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
12667  // A variable of class type (or array thereof) that appears in a private
12668  // clause requires an accessible, unambiguous default constructor for the
12669  // class type.
12670  // Generate helper private variable and initialize it with the default
12671  // value. The address of the original variable is replaced by the address of
12672  // the new private variable in CodeGen. This new variable is not added to
12673  // IdResolver, so the code in the OpenMP region uses original variable for
12674  // proper diagnostics.
12675  Type = Type.getUnqualifiedType();
12676  VarDecl *VDPrivate =
12677  buildVarDecl(*this, ELoc, Type, D->getName(),
12678  D->hasAttrs() ? &D->getAttrs() : nullptr,
12679  VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
12680  ActOnUninitializedDecl(VDPrivate);
12681  if (VDPrivate->isInvalidDecl())
12682  continue;
12683  DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
12684  *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
12685 
12686  DeclRefExpr *Ref = nullptr;
12687  if (!VD && !CurContext->isDependentContext())
12688  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
12689  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
12690  Vars.push_back((VD || CurContext->isDependentContext())
12691  ? RefExpr->IgnoreParens()
12692  : Ref);
12693  PrivateCopies.push_back(VDPrivateRefExpr);
12694  }
12695 
12696  if (Vars.empty())
12697  return nullptr;
12698 
12699  return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
12700  PrivateCopies);
12701 }
12702 
12703 namespace {
12704 class DiagsUninitializedSeveretyRAII {
12705 private:
12706  DiagnosticsEngine &Diags;
12707  SourceLocation SavedLoc;
12708  bool IsIgnored = false;
12709 
12710 public:
12711  DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
12712  bool IsIgnored)
12713  : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
12714  if (!IsIgnored) {
12715  Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
12716  /*Map*/ diag::Severity::Ignored, Loc);
12717  }
12718  }
12719  ~DiagsUninitializedSeveretyRAII() {
12720  if (!IsIgnored)
12721  Diags.popMappings(SavedLoc);
12722  }
12723 };
12724 }
12725 
12727  SourceLocation StartLoc,
12728  SourceLocation LParenLoc,
12729  SourceLocation EndLoc) {
12731  SmallVector<Expr *, 8> PrivateCopies;
12733  SmallVector<Decl *, 4> ExprCaptures;
12734  bool IsImplicitClause =
12735  StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
12736  SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc();
12737 
12738  for (Expr *RefExpr : VarList) {
12739  assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
12740  SourceLocation ELoc;
12741  SourceRange ERange;
12742  Expr *SimpleRefExpr = RefExpr;
12743  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
12744  if (Res.second) {
12745  // It will be analyzed later.
12746  Vars.push_back(RefExpr);
12747  PrivateCopies.push_back(nullptr);
12748  Inits.push_back(nullptr);
12749  }
12750  ValueDecl *D = Res.first;
12751  if (!D)
12752  continue;
12753 
12754  ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
12755  QualType Type = D->getType();
12756  auto *VD = dyn_cast<VarDecl>(D);
12757 
12758  // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
12759  // A variable that appears in a private clause must not have an incomplete
12760  // type or a reference type.
12761  if (RequireCompleteType(ELoc, Type,
12762  diag::err_omp_firstprivate_incomplete_type))
12763  continue;
12764  Type = Type.getNonReferenceType();
12765 
12766  // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
12767  // A variable of class type (or array thereof) that appears in a private
12768  // clause requires an accessible, unambiguous copy constructor for the
12769  // class type.
12770  QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
12771 
12772  // If an implicit firstprivate variable found it was checked already.
12773  DSAStackTy::DSAVarData TopDVar;
12774  if (!IsImplicitClause) {
12775  DSAStackTy::DSAVarData DVar =
12776  DSAStack->getTopDSA(D, /*FromParent=*/false);
12777  TopDVar = DVar;
12778  OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
12779  bool IsConstant = ElemType.isConstant(Context);
12780  // OpenMP [2.4.13, Data-sharing Attribute Clauses]
12781  // A list item that specifies a given variable may not appear in more
12782  // than one clause on the same directive, except that a variable may be
12783  // specified in both firstprivate and lastprivate clauses.
12784  // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
12785  // A list item may appear in a firstprivate or lastprivate clause but not
12786  // both.
12787  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
12788  (isOpenMPDistributeDirective(CurrDir) ||
12789  DVar.CKind != OMPC_lastprivate) &&
12790  DVar.RefExpr) {
12791  Diag(ELoc, diag::err_omp_wrong_dsa)
12792  << getOpenMPClauseName(DVar.CKind)
12793  << getOpenMPClauseName(OMPC_firstprivate);
12794  reportOriginalDsa(*this, DSAStack, D, DVar);
12795  continue;
12796  }
12797 
12798  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
12799  // in a Construct]
12800  // Variables with the predetermined data-sharing attributes may not be
12801  // listed in data-sharing attributes clauses, except for the cases
12802  // listed below. For these exceptions only, listing a predetermined
12803  // variable in a data-sharing attribute clause is allowed and overrides
12804  // the variable's predetermined data-sharing attributes.
12805  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
12806  // in a Construct, C/C++, p.2]
12807  // Variables with const-qualified type having no mutable member may be
12808  // listed in a firstprivate clause, even if they are static data members.
12809  if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
12810  DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
12811  Diag(ELoc, diag::err_omp_wrong_dsa)
12812  << getOpenMPClauseName(DVar.CKind)
12813  << getOpenMPClauseName(OMPC_firstprivate);
12814  reportOriginalDsa(*this, DSAStack, D, DVar);
12815  continue;
12816  }
12817 
12818  // OpenMP [2.9.3.4, Restrictions, p.2]
12819  // A list item that is private within a parallel region must not appear
12820  // in a firstprivate clause on a worksharing construct if any of the
12821  // worksharing regions arising from the worksharing construct ever bind
12822  // to any of the parallel regions arising from the parallel construct.
12823  // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
12824  // A list item that is private within a teams region must not appear in a
12825  // firstprivate clause on a distribute construct if any of the distribute
12826  // regions arising from the distribute construct ever bind to any of the
12827  // teams regions arising from the teams construct.
12828  // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
12829  // A list item that appears in a reduction clause of a teams construct
12830  // must not appear in a firstprivate clause on a distribute construct if
12831  // any of the distribute regions arising from the distribute construct
12832  // ever bind to any of the teams regions arising from the teams construct.
12833  if ((isOpenMPWorksharingDirective(CurrDir) ||
12834  isOpenMPDistributeDirective(CurrDir)) &&
12835  !isOpenMPParallelDirective(CurrDir) &&
12836  !isOpenMPTeamsDirective(CurrDir)) {
12837  DVar = DSAStack->getImplicitDSA(D, true);
12838  if (DVar.CKind != OMPC_shared &&
12839  (isOpenMPParallelDirective(DVar.DKind) ||
12840  isOpenMPTeamsDirective(DVar.DKind) ||
12841  DVar.DKind == OMPD_unknown)) {
12842  Diag(ELoc, diag::err_omp_required_access)
12843  << getOpenMPClauseName(OMPC_firstprivate)
12844  << getOpenMPClauseName(OMPC_shared);
12845  reportOriginalDsa(*this, DSAStack, D, DVar);
12846  continue;
12847  }
12848  }
12849  // OpenMP [2.9.3.4, Restrictions, p.3]
12850  // A list item that appears in a reduction clause of a parallel construct
12851  // must not appear in a firstprivate clause on a worksharing or task
12852  // construct if any of the worksharing or task regions arising from the
12853  // worksharing or task construct ever bind to any of the parallel regions
12854  // arising from the parallel construct.
12855  // OpenMP [2.9.3.4, Restrictions, p.4]
12856  // A list item that appears in a reduction clause in worksharing
12857  // construct must not appear in a firstprivate clause in a task construct
12858  // encountered during execution of any of the worksharing regions arising
12859  // from the worksharing construct.
12860  if (isOpenMPTaskingDirective(CurrDir)) {
12861  DVar = DSAStack->hasInnermostDSA(
12862  D, [](OpenMPClauseKind C) { return C == OMPC_reduction; },
12863  [](OpenMPDirectiveKind K) {
12864  return isOpenMPParallelDirective(K) ||
12867  },
12868  /*FromParent=*/true);
12869  if (DVar.CKind == OMPC_reduction &&
12870  (isOpenMPParallelDirective(DVar.DKind) ||
12871  isOpenMPWorksharingDirective(DVar.DKind) ||
12872  isOpenMPTeamsDirective(DVar.DKind))) {
12873  Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
12874  << getOpenMPDirectiveName(DVar.DKind);
12875  reportOriginalDsa(*this, DSAStack, D, DVar);
12876  continue;
12877  }
12878  }
12879 
12880  // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
12881  // A list item cannot appear in both a map clause and a data-sharing
12882  // attribute clause on the same construct
12883  //
12884  // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
12885  // A list item cannot appear in both a map clause and a data-sharing
12886  // attribute clause on the same construct unless the construct is a
12887  // combined construct.
12888  if ((LangOpts.OpenMP <= 45 &&
12890  CurrDir == OMPD_target) {
12891  OpenMPClauseKind ConflictKind;
12892  if (DSAStack->checkMappableExprComponentListsForDecl(
12893  VD, /*CurrentRegionOnly=*/true,
12894  [&ConflictKind](
12896  OpenMPClauseKind WhereFoundClauseKind) {
12897  ConflictKind = WhereFoundClauseKind;
12898  return true;
12899  })) {
12900  Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
12901  << getOpenMPClauseName(OMPC_firstprivate)
12902  << getOpenMPClauseName(ConflictKind)
12903  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
12904  reportOriginalDsa(*this, DSAStack, D, DVar);
12905  continue;
12906  }
12907  }
12908  }
12909 
12910  // Variably modified types are not supported for tasks.
12911  if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
12912  isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
12913  Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
12914  << getOpenMPClauseName(OMPC_firstprivate) << Type
12915  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
12916  bool IsDecl =
12917  !VD ||
12918  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
12919  Diag(D->getLocation(),
12920  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
12921  << D;
12922  continue;
12923  }
12924 
12925  Type = Type.getUnqualifiedType();
12926  VarDecl *VDPrivate =
12927  buildVarDecl(*this, ELoc, Type, D->getName(),
12928  D->hasAttrs() ? &D->getAttrs() : nullptr,
12929  VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
12930  // Generate helper private variable and initialize it with the value of the
12931  // original variable. The address of the original variable is replaced by
12932  // the address of the new private variable in the CodeGen. This new variable
12933  // is not added to IdResolver, so the code in the OpenMP region uses
12934  // original variable for proper diagnostics and variable capturing.
12935  Expr *VDInitRefExpr = nullptr;
12936  // For arrays generate initializer for single element and replace it by the
12937  // original array element in CodeGen.
12938  if (Type->isArrayType()) {
12939  VarDecl *VDInit =
12940  buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
12941  VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
12942  Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
12943  ElemType = ElemType.getUnqualifiedType();
12944  VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
12945  ".firstprivate.temp");
12946  InitializedEntity Entity =
12949 
12950  InitializationSequence InitSeq(*this, Entity, Kind, Init);
12951  ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
12952  if (Result.isInvalid())
12953  VDPrivate->setInvalidDecl();
12954  else
12955  VDPrivate->setInit(Result.getAs<Expr>());
12956  // Remove temp variable declaration.
12957  Context.Deallocate(VDInitTemp);
12958  } else {
12959  VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
12960  ".firstprivate.temp");
12961  VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
12962  RefExpr->getExprLoc());
12963  AddInitializerToDecl(VDPrivate,
12964  DefaultLvalueConversion(VDInitRefExpr).get(),
12965  /*DirectInit=*/false);
12966  }
12967  if (VDPrivate->isInvalidDecl()) {
12968  if (IsImplicitClause) {
12969  Diag(RefExpr->getExprLoc(),
12970  diag::note_omp_task_predetermined_firstprivate_here);
12971  }
12972  continue;
12973  }
12974  CurContext->addDecl(VDPrivate);
12975  DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
12976  *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
12977  RefExpr->getExprLoc());
12978  DeclRefExpr *Ref = nullptr;
12979  if (!VD && !CurContext->isDependentContext()) {
12980  if (TopDVar.CKind == OMPC_lastprivate) {
12981  Ref = TopDVar.PrivateCopy;
12982  } else {
12983  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
12984  if (!isOpenMPCapturedDecl(D))
12985  ExprCaptures.push_back(Ref->getDecl());
12986  }
12987  }
12988  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
12989  Vars.push_back((VD || CurContext->isDependentContext())
12990  ? RefExpr->IgnoreParens()
12991  : Ref);
12992  PrivateCopies.push_back(VDPrivateRefExpr);
12993  Inits.push_back(VDInitRefExpr);
12994  }
12995 
12996  if (Vars.empty())
12997  return nullptr;
12998 
12999  return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
13000  Vars, PrivateCopies, Inits,
13001  buildPreInits(Context, ExprCaptures));
13002 }
13003 
13007  SourceLocation LParenLoc, SourceLocation EndLoc) {
13008  if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) {
13009  assert(ColonLoc.isValid() && "Colon location must be valid.");
13010  Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
13011  << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0,
13012  /*Last=*/OMPC_LASTPRIVATE_unknown)
13013  << getOpenMPClauseName(OMPC_lastprivate);
13014  return nullptr;
13015  }
13016 
13018  SmallVector<Expr *, 8> SrcExprs;
13019  SmallVector<Expr *, 8> DstExprs;
13020  SmallVector<Expr *, 8> AssignmentOps;
13021  SmallVector<Decl *, 4> ExprCaptures;
13022  SmallVector<Expr *, 4> ExprPostUpdates;
13023  for (Expr *RefExpr : VarList) {
13024  assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
13025  SourceLocation ELoc;
13026  SourceRange ERange;
13027  Expr *SimpleRefExpr = RefExpr;
13028  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
13029  if (Res.second) {
13030  // It will be analyzed later.
13031  Vars.push_back(RefExpr);
13032  SrcExprs.push_back(nullptr);
13033  DstExprs.push_back(nullptr);
13034  AssignmentOps.push_back(nullptr);
13035  }
13036  ValueDecl *D = Res.first;
13037  if (!D)
13038  continue;
13039 
13040  QualType Type = D->getType();
13041  auto *VD = dyn_cast<VarDecl>(D);
13042 
13043  // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
13044  // A variable that appears in a lastprivate clause must not have an
13045  // incomplete type or a reference type.
13046  if (RequireCompleteType(ELoc, Type,
13047  diag::err_omp_lastprivate_incomplete_type))
13048  continue;
13049  Type = Type.getNonReferenceType();
13050 
13051  // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
13052  // A variable that is privatized must not have a const-qualified type
13053  // unless it is of class type with a mutable member. This restriction does
13054  // not apply to the firstprivate clause.
13055  //
13056  // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
13057  // A variable that appears in a lastprivate clause must not have a
13058  // const-qualified type unless it is of class type with a mutable member.
13059  if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
13060  continue;
13061 
13062  // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions]
13063  // A list item that appears in a lastprivate clause with the conditional
13064  // modifier must be a scalar variable.
13065  if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) {
13066  Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
13067  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
13069  Diag(D->getLocation(),
13070  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
13071  << D;
13072  continue;
13073  }
13074 
13075  OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
13076  // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
13077  // in a Construct]
13078  // Variables with the predetermined data-sharing attributes may not be
13079  // listed in data-sharing attributes clauses, except for the cases
13080  // listed below.
13081  // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
13082  // A list item may appear in a firstprivate or lastprivate clause but not
13083  // both.
13084  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
13085  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
13086  (isOpenMPDistributeDirective(CurrDir) ||
13087  DVar.CKind != OMPC_firstprivate) &&
13088  (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
13089  Diag(ELoc, diag::err_omp_wrong_dsa)
13090  << getOpenMPClauseName(DVar.CKind)
13091  << getOpenMPClauseName(OMPC_lastprivate);
13092  reportOriginalDsa(*this, DSAStack, D, DVar);
13093  continue;
13094  }
13095 
13096  // OpenMP [2.14.3.5, Restrictions, p.2]
13097  // A list item that is private within a parallel region, or that appears in
13098  // the reduction clause of a parallel construct, must not appear in a
13099  // lastprivate clause on a worksharing construct if any of the corresponding
13100  // worksharing regions ever binds to any of the corresponding parallel
13101  // regions.
13102  DSAStackTy::DSAVarData TopDVar = DVar;
13103  if (isOpenMPWorksharingDirective(CurrDir) &&
13104  !isOpenMPParallelDirective(CurrDir) &&
13105  !isOpenMPTeamsDirective(CurrDir)) {
13106  DVar = DSAStack->getImplicitDSA(D, true);
13107  if (DVar.CKind != OMPC_shared) {
13108  Diag(ELoc, diag::err_omp_required_access)
13109  << getOpenMPClauseName(OMPC_lastprivate)
13110  << getOpenMPClauseName(OMPC_shared);
13111  reportOriginalDsa(*this, DSAStack, D, DVar);
13112  continue;
13113  }
13114  }
13115 
13116  // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
13117  // A variable of class type (or array thereof) that appears in a
13118  // lastprivate clause requires an accessible, unambiguous default
13119  // constructor for the class type, unless the list item is also specified
13120  // in a firstprivate clause.
13121  // A variable of class type (or array thereof) that appears in a
13122  // lastprivate clause requires an accessible, unambiguous copy assignment
13123  // operator for the class type.
13124  Type = Context.getBaseElementType(Type).getNonReferenceType();
13125  VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
13126  Type.getUnqualifiedType(), ".lastprivate.src",
13127  D->hasAttrs() ? &D->getAttrs() : nullptr);
13128  DeclRefExpr *PseudoSrcExpr =
13129  buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
13130  VarDecl *DstVD =
13131  buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
13132  D->hasAttrs() ? &D->getAttrs() : nullptr);
13133  DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
13134  // For arrays generate assignment operation for single element and replace
13135  // it by the original array element in CodeGen.
13136  ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
13137  PseudoDstExpr, PseudoSrcExpr);
13138  if (AssignmentOp.isInvalid())
13139  continue;
13140  AssignmentOp =
13141  ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
13142  if (AssignmentOp.isInvalid())
13143  continue;
13144 
13145  DeclRefExpr *Ref = nullptr;
13146  if (!VD && !CurContext->isDependentContext()) {
13147  if (TopDVar.CKind == OMPC_firstprivate) {
13148  Ref = TopDVar.PrivateCopy;
13149  } else {
13150  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
13151  if (!isOpenMPCapturedDecl(D))
13152  ExprCaptures.push_back(Ref->getDecl());
13153  }
13154  if (TopDVar.CKind == OMPC_firstprivate ||
13155  (!isOpenMPCapturedDecl(D) &&
13156  Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
13157  ExprResult RefRes = DefaultLvalueConversion(Ref);
13158  if (!RefRes.isUsable())
13159  continue;
13160  ExprResult PostUpdateRes =
13161  BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
13162  RefRes.get());
13163  if (!PostUpdateRes.isUsable())
13164  continue;
13165  ExprPostUpdates.push_back(
13166  IgnoredValueConversions(PostUpdateRes.get()).get());
13167  }
13168  }
13169  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
13170  Vars.push_back((VD || CurContext->isDependentContext())
13171  ? RefExpr->IgnoreParens()
13172  : Ref);
13173  SrcExprs.push_back(PseudoSrcExpr);
13174  DstExprs.push_back(PseudoDstExpr);
13175  AssignmentOps.push_back(AssignmentOp.get());
13176  }
13177 
13178  if (Vars.empty())
13179  return nullptr;
13180 
13181  return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
13182  Vars, SrcExprs, DstExprs, AssignmentOps,
13183  LPKind, LPKindLoc, ColonLoc,
13184  buildPreInits(Context, ExprCaptures),
13185  buildPostUpdate(*this, ExprPostUpdates));
13186 }
13187 
13189  SourceLocation StartLoc,
13190  SourceLocation LParenLoc,
13191  SourceLocation EndLoc) {
13193  for (Expr *RefExpr : VarList) {
13194  assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
13195  SourceLocation ELoc;
13196  SourceRange ERange;
13197  Expr *SimpleRefExpr = RefExpr;
13198  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
13199  if (Res.second) {
13200  // It will be analyzed later.
13201  Vars.push_back(RefExpr);
13202  }
13203  ValueDecl *D = Res.first;
13204  if (!D)
13205  continue;
13206 
13207  auto *VD = dyn_cast<VarDecl>(D);
13208  // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
13209  // in a Construct]
13210  // Variables with the predetermined data-sharing attributes may not be
13211  // listed in data-sharing attributes clauses, except for the cases
13212  // listed below. For these exceptions only, listing a predetermined
13213  // variable in a data-sharing attribute clause is allowed and overrides
13214  // the variable's predetermined data-sharing attributes.
13215  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
13216  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
13217  DVar.RefExpr) {
13218  Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
13219  << getOpenMPClauseName(OMPC_shared);
13220  reportOriginalDsa(*this, DSAStack, D, DVar);
13221  continue;
13222  }
13223 
13224  DeclRefExpr *Ref = nullptr;
13225  if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
13226  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
13227  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
13228  Vars.push_back((VD || !Ref || CurContext->isDependentContext())
13229  ? RefExpr->IgnoreParens()
13230  : Ref);
13231  }
13232 
13233  if (Vars.empty())
13234  return nullptr;
13235 
13236  return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
13237 }
13238 
13239 namespace {
13240 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
13241  DSAStackTy *Stack;
13242 
13243 public:
13244  bool VisitDeclRefExpr(DeclRefExpr *E) {
13245  if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
13246  DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
13247  if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
13248  return false;
13249  if (DVar.CKind != OMPC_unknown)
13250  return true;
13251  DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
13252  VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; },
13253  /*FromParent=*/true);
13254  return DVarPrivate.CKind != OMPC_unknown;
13255  }
13256  return false;
13257  }
13258  bool VisitStmt(Stmt *S) {
13259  for (Stmt *Child : S->children()) {
13260  if (Child && Visit(Child))
13261  return true;
13262  }
13263  return false;
13264  }
13265  explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
13266 };
13267 } // namespace
13268 
13269 namespace {
13270 // Transform MemberExpression for specified FieldDecl of current class to
13271 // DeclRefExpr to specified OMPCapturedExprDecl.
13272 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
13273  typedef TreeTransform<TransformExprToCaptures> BaseTransform;
13274  ValueDecl *Field = nullptr;
13275  DeclRefExpr *CapturedExpr = nullptr;
13276 
13277 public:
13278  TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
13279  : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
13280 
13281  ExprResult TransformMemberExpr(MemberExpr *E) {
13282  if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
13283  E->getMemberDecl() == Field) {
13284  CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
13285  return CapturedExpr;
13286  }
13287  return BaseTransform::TransformMemberExpr(E);
13288  }
13289  DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
13290 };
13291 } // namespace
13292 
13293 template <typename T, typename U>
13295  SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
13296  for (U &Set : Lookups) {
13297  for (auto *D : Set) {
13298  if (T Res = Gen(cast<ValueDecl>(D)))
13299  return Res;
13300  }
13301  }
13302  return T();
13303 }
13304 
13306  assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case");
13307 
13308  for (auto RD : D->redecls()) {
13309  // Don't bother with extra checks if we already know this one isn't visible.
13310  if (RD == D)
13311  continue;
13312 
13313  auto ND = cast<NamedDecl>(RD);
13314  if (LookupResult::isVisible(SemaRef, ND))
13315  return ND;
13316  }
13317 
13318  return nullptr;
13319 }
13320 
13321 static void
13323  SourceLocation Loc, QualType Ty,
13324  SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
13325  // Find all of the associated namespaces and classes based on the
13326  // arguments we have.
13327  Sema::AssociatedNamespaceSet AssociatedNamespaces;
13328  Sema::AssociatedClassSet AssociatedClasses;
13329  OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
13330  SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
13331  AssociatedClasses);
13332 
13333  // C++ [basic.lookup.argdep]p3:
13334  // Let X be the lookup set produced by unqualified lookup (3.4.1)
13335  // and let Y be the lookup set produced by argument dependent
13336  // lookup (defined as follows). If X contains [...] then Y is
13337  // empty. Otherwise Y is the set of declarations found in the
13338  // namespaces associated with the argument types as described
13339  // below. The set of declarations found by the lookup of the name
13340  // is the union of X and Y.
13341  //
13342  // Here, we compute Y and add its members to the overloaded
13343  // candidate set.
13344  for (auto *NS : AssociatedNamespaces) {
13345  // When considering an associated namespace, the lookup is the
13346  // same as the lookup performed when the associated namespace is
13347  // used as a qualifier (3.4.3.2) except that:
13348  //
13349  // -- Any using-directives in the associated namespace are
13350  // ignored.
13351  //
13352  // -- Any namespace-scope friend functions declared in
13353  // associated classes are visible within their respective
13354  // namespaces even if they are not visible during an ordinary
13355  // lookup (11.4).
13356  DeclContext::lookup_result R = NS->lookup(Id.getName());
13357  for (auto *D : R) {
13358  auto *Underlying = D;
13359  if (auto *USD = dyn_cast<UsingShadowDecl>(D))
13360  Underlying = USD->getTargetDecl();
13361 
13362  if (!isa<OMPDeclareReductionDecl>(Underlying) &&
13363  !isa<OMPDeclareMapperDecl>(Underlying))
13364  continue;
13365 
13366  if (!SemaRef.isVisible(D)) {
13367  D = findAcceptableDecl(SemaRef, D);
13368  if (!D)
13369  continue;
13370  if (auto *USD = dyn_cast<UsingShadowDecl>(D))
13371  Underlying = USD->getTargetDecl();
13372  }
13373  Lookups.emplace_back();
13374  Lookups.back().addDecl(Underlying);
13375  }
13376  }
13377 }
13378 
13379 static ExprResult
13381  Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
13382  const DeclarationNameInfo &ReductionId, QualType Ty,
13383  CXXCastPath &BasePath, Expr *UnresolvedReduction) {
13384  if (ReductionIdScopeSpec.isInvalid())
13385  return ExprError();
13386  SmallVector<UnresolvedSet<8>, 4> Lookups;
13387  if (S) {
13388  LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
13389  Lookup.suppressDiagnostics();
13390  while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
13391  NamedDecl *D = Lookup.getRepresentativeDecl();
13392  do {
13393  S = S->getParent();
13394  } while (S && !S->isDeclScope(D));
13395  if (S)
13396  S = S->getParent();
13397  Lookups.emplace_back();
13398  Lookups.back().append(Lookup.begin(), Lookup.end());
13399  Lookup.clear();
13400  }
13401  } else if (auto *ULE =
13402  cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
13403  Lookups.push_back(UnresolvedSet<8>());
13404  Decl *PrevD = nullptr;
13405  for (NamedDecl *D : ULE->decls()) {
13406  if (D == PrevD)
13407  Lookups.push_back(UnresolvedSet<8>());
13408  else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
13409  Lookups.back().addDecl(DRD);
13410  PrevD = D;
13411  }
13412  }
13413  if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
13416  filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
13417  return !D->isInvalidDecl() &&
13418  (D->getType()->isDependentType() ||
13421  })) {
13422  UnresolvedSet<8> ResSet;
13423  for (const UnresolvedSet<8> &Set : Lookups) {
13424  if (Set.empty())
13425  continue;
13426  ResSet.append(Set.begin(), Set.end());
13427  // The last item marks the end of all declarations at the specified scope.
13428  ResSet.addDecl(Set[Set.size() - 1]);
13429  }
13431  SemaRef.Context, /*NamingClass=*/nullptr,
13432  ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
13433  /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
13434  }
13435  // Lookup inside the classes.
13436  // C++ [over.match.oper]p3:
13437  // For a unary operator @ with an operand of a type whose
13438  // cv-unqualified version is T1, and for a binary operator @ with
13439  // a left operand of a type whose cv-unqualified version is T1 and
13440  // a right operand of a type whose cv-unqualified version is T2,
13441  // three sets of candidate functions, designated member
13442  // candidates, non-member candidates and built-in candidates, are
13443  // constructed as follows:
13444  // -- If T1 is a complete class type or a class currently being
13445  // defined, the set of member candidates is the result of the
13446  // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
13447  // the set of member candidates is empty.
13448  LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
13449  Lookup.suppressDiagnostics();
13450  if (const auto *TyRec = Ty->getAs<RecordType>()) {
13451  // Complete the type if it can be completed.
13452  // If the type is neither complete nor being defined, bail out now.
13453  if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
13454  TyRec->getDecl()->getDefinition()) {
13455  Lookup.clear();
13456  SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
13457  if (Lookup.empty()) {
13458  Lookups.emplace_back();
13459  Lookups.back().append(Lookup.begin(), Lookup.end());
13460  }
13461  }
13462  }
13463  // Perform ADL.
13464  if (SemaRef.getLangOpts().CPlusPlus)
13465  argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
13466  if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
13467  Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
13468  if (!D->isInvalidDecl() &&
13469  SemaRef.Context.hasSameType(D->getType(), Ty))
13470  return D;
13471  return nullptr;
13472  }))
13473  return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
13474  VK_LValue, Loc);
13475  if (SemaRef.getLangOpts().CPlusPlus) {
13476  if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
13477  Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
13478  if (!D->isInvalidDecl() &&
13479  SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
13480  !Ty.isMoreQualifiedThan(D->getType()))
13481  return D;
13482  return nullptr;
13483  })) {
13484  CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
13485  /*DetectVirtual=*/false);
13486  if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
13487  if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
13488  VD->getType().getUnqualifiedType()))) {
13489  if (SemaRef.CheckBaseClassAccess(
13490  Loc, VD->getType(), Ty, Paths.front(),
13491  /*DiagID=*/0) != Sema::AR_inaccessible) {
13492  SemaRef.BuildBasePathArray(Paths, BasePath);
13493  return SemaRef.BuildDeclRefExpr(
13494  VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
13495  }
13496  }
13497  }
13498  }
13499  }
13500  if (ReductionIdScopeSpec.isSet()) {
13501  SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
13502  << Ty << Range;
13503  return ExprError();
13504  }
13505  return ExprEmpty();
13506 }
13507 
13508 namespace {
13509 /// Data for the reduction-based clauses.
13510 struct ReductionData {
13511  /// List of original reduction items.
13513  /// List of private copies of the reduction items.
13515  /// LHS expressions for the reduction_op expressions.
13517  /// RHS expressions for the reduction_op expressions.
13519  /// Reduction operation expression.
13520  SmallVector<Expr *, 8> ReductionOps;
13521  /// Taskgroup descriptors for the corresponding reduction items in
13522  /// in_reduction clauses.
13523  SmallVector<Expr *, 8> TaskgroupDescriptors;
13524  /// List of captures for clause.
13525  SmallVector<Decl *, 4> ExprCaptures;
13526  /// List of postupdate expressions.
13527  SmallVector<Expr *, 4> ExprPostUpdates;
13528  ReductionData() = delete;
13529  /// Reserves required memory for the reduction data.
13530  ReductionData(unsigned Size) {
13531  Vars.reserve(Size);
13532  Privates.reserve(Size);
13533  LHSs.reserve(Size);
13534  RHSs.reserve(Size);
13535  ReductionOps.reserve(Size);
13536  TaskgroupDescriptors.reserve(Size);
13537  ExprCaptures.reserve(Size);
13538  ExprPostUpdates.reserve(Size);
13539  }
13540  /// Stores reduction item and reduction operation only (required for dependent
13541  /// reduction item).
13542  void push(Expr *Item, Expr *ReductionOp) {
13543  Vars.emplace_back(Item);
13544  Privates.emplace_back(nullptr);
13545  LHSs.emplace_back(nullptr);
13546  RHSs.emplace_back(nullptr);
13547  ReductionOps.emplace_back(ReductionOp);
13548  TaskgroupDescriptors.emplace_back(nullptr);
13549  }
13550  /// Stores reduction data.
13551  void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
13552  Expr *TaskgroupDescriptor) {
13553  Vars.emplace_back(Item);
13554  Privates.emplace_back(Private);
13555  LHSs.emplace_back(LHS);
13556  RHSs.emplace_back(RHS);
13557  ReductionOps.emplace_back(ReductionOp);
13558  TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
13559  }
13560 };
13561 } // namespace
13562 
13564  ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
13565  SmallVectorImpl<llvm::APSInt> &ArraySizes) {
13566  const Expr *Length = OASE->getLength();
13567  if (Length == nullptr) {
13568  // For array sections of the form [1:] or [:], we would need to analyze
13569  // the lower bound...
13570  if (OASE->getColonLoc().isValid())
13571  return false;
13572 
13573  // This is an array subscript which has implicit length 1!
13574  SingleElement = true;
13575  ArraySizes.push_back(llvm::APSInt::get(1));
13576  } else {
13578  if (!Length->EvaluateAsInt(Result, Context))
13579  return false;
13580 
13581  llvm::APSInt ConstantLengthValue = Result.Val.getInt();
13582  SingleElement = (ConstantLengthValue.getSExtValue() == 1);
13583  ArraySizes.push_back(ConstantLengthValue);
13584  }
13585 
13586  // Get the base of this array section and walk up from there.
13587  const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
13588 
13589  // We require length = 1 for all array sections except the right-most to
13590  // guarantee that the memory region is contiguous and has no holes in it.
13591  while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
13592  Length = TempOASE->getLength();
13593  if (Length == nullptr) {
13594  // For array sections of the form [1:] or [:], we would need to analyze
13595  // the lower bound...
13596  if (OASE->getColonLoc().isValid())
13597  return false;
13598 
13599  // This is an array subscript which has implicit length 1!
13600  ArraySizes.push_back(llvm::APSInt::get(1));
13601  } else {
13603  if (!Length->EvaluateAsInt(Result, Context))
13604  return false;
13605 
13606  llvm::APSInt ConstantLengthValue = Result.Val.getInt();
13607  if (ConstantLengthValue.getSExtValue() != 1)
13608  return false;
13609 
13610  ArraySizes.push_back(ConstantLengthValue);
13611  }
13612  Base = TempOASE->getBase()->IgnoreParenImpCasts();
13613  }
13614 
13615  // If we have a single element, we don't need to add the implicit lengths.
13616  if (!SingleElement) {
13617  while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
13618  // Has implicit length 1!
13619  ArraySizes.push_back(llvm::APSInt::get(1));
13620  Base = TempASE->getBase()->IgnoreParenImpCasts();
13621  }
13622  }
13623 
13624  // This array section can be privatized as a single value or as a constant
13625  // sized array.
13626  return true;
13627 }
13628 
13630  Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
13631  ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
13633  CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
13634  ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
13635  DeclarationName DN = ReductionId.getName();
13637  BinaryOperatorKind BOK = BO_Comma;
13638 
13639  ASTContext &Context = S.Context;
13640  // OpenMP [2.14.3.6, reduction clause]
13641  // C
13642  // reduction-identifier is either an identifier or one of the following
13643  // operators: +, -, *, &, |, ^, && and ||
13644  // C++
13645  // reduction-identifier is either an id-expression or one of the following
13646  // operators: +, -, *, &, |, ^, && and ||
13647  switch (OOK) {
13648  case OO_Plus:
13649  case OO_Minus:
13650  BOK = BO_Add;
13651  break;
13652  case OO_Star:
13653  BOK = BO_Mul;
13654  break;
13655  case OO_Amp:
13656  BOK = BO_And;
13657  break;
13658  case OO_Pipe:
13659  BOK = BO_Or;
13660  break;
13661  case OO_Caret:
13662  BOK = BO_Xor;
13663  break;
13664  case OO_AmpAmp:
13665  BOK = BO_LAnd;
13666  break;
13667  case OO_PipePipe:
13668  BOK = BO_LOr;
13669  break;
13670  case OO_New:
13671  case OO_Delete:
13672  case OO_Array_New:
13673  case OO_Array_Delete:
13674  case OO_Slash:
13675  case OO_Percent:
13676  case OO_Tilde:
13677  case OO_Exclaim:
13678  case OO_Equal:
13679  case OO_Less:
13680  case OO_Greater:
13681  case OO_LessEqual:
13682  case OO_GreaterEqual:
13683  case OO_PlusEqual:
13684  case OO_MinusEqual:
13685  case OO_StarEqual:
13686  case OO_SlashEqual:
13687  case OO_PercentEqual:
13688  case OO_CaretEqual:
13689  case OO_AmpEqual:
13690  case OO_PipeEqual:
13691  case OO_LessLess:
13692  case OO_GreaterGreater:
13693  case OO_LessLessEqual:
13694  case OO_GreaterGreaterEqual:
13695  case OO_EqualEqual:
13696  case OO_ExclaimEqual:
13697  case OO_Spaceship:
13698  case OO_PlusPlus:
13699  case OO_MinusMinus:
13700  case OO_Comma:
13701  case OO_ArrowStar:
13702  case OO_Arrow:
13703  case OO_Call:
13704  case OO_Subscript:
13705  case OO_Conditional:
13706  case OO_Coawait:
13708  llvm_unreachable("Unexpected reduction identifier");
13709  case OO_None:
13710  if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
13711  if (II->isStr("max"))
13712  BOK = BO_GT;
13713  else if (II->isStr("min"))
13714  BOK = BO_LT;
13715  }
13716  break;
13717  }
13718  SourceRange ReductionIdRange;
13719  if (ReductionIdScopeSpec.isValid())
13720  ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
13721  else
13722  ReductionIdRange.setBegin(ReductionId.getBeginLoc());
13723  ReductionIdRange.setEnd(ReductionId.getEndLoc());
13724 
13725  auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
13726  bool FirstIter = true;
13727  for (Expr *RefExpr : VarList) {
13728  assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
13729  // OpenMP [2.1, C/C++]
13730  // A list item is a variable or array section, subject to the restrictions
13731  // specified in Section 2.4 on page 42 and in each of the sections
13732  // describing clauses and directives for which a list appears.
13733  // OpenMP [2.14.3.3, Restrictions, p.1]
13734  // A variable that is part of another variable (as an array or
13735  // structure element) cannot appear in a private clause.
13736  if (!FirstIter && IR != ER)
13737  ++IR;
13738  FirstIter = false;
13739  SourceLocation ELoc;
13740  SourceRange ERange;
13741  Expr *SimpleRefExpr = RefExpr;
13742  auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
13743  /*AllowArraySection=*/true);
13744  if (Res.second) {
13745  // Try to find 'declare reduction' corresponding construct before using
13746  // builtin/overloaded operators.
13747  QualType Type = Context.DependentTy;
13748  CXXCastPath BasePath;
13749  ExprResult DeclareReductionRef = buildDeclareReductionRef(
13750  S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
13751  ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
13752  Expr *ReductionOp = nullptr;
13753  if (S.CurContext->isDependentContext() &&
13754  (DeclareReductionRef.isUnset() ||
13755  isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
13756  ReductionOp = DeclareReductionRef.get();
13757  // It will be analyzed later.
13758  RD.push(RefExpr, ReductionOp);
13759  }
13760  ValueDecl *D = Res.first;
13761  if (!D)
13762  continue;
13763 
13764  Expr *TaskgroupDescriptor = nullptr;
13765  QualType Type;
13766  auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
13767  auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
13768  if (ASE) {
13769  Type = ASE->getType().getNonReferenceType();
13770  } else if (OASE) {
13771  QualType BaseType =
13773  if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
13774  Type = ATy->getElementType();
13775  else
13776  Type = BaseType->getPointeeType();
13777  Type = Type.getNonReferenceType();
13778  } else {
13779  Type = Context.getBaseElementType(D->getType().getNonReferenceType());
13780  }
13781  auto *VD = dyn_cast<VarDecl>(D);
13782 
13783  // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
13784  // A variable that appears in a private clause must not have an incomplete
13785  // type or a reference type.
13786  if (S.RequireCompleteType(ELoc, D->getType(),
13787  diag::err_omp_reduction_incomplete_type))
13788  continue;
13789  // OpenMP [2.14.3.6, reduction clause, Restrictions]
13790  // A list item that appears in a reduction clause must not be
13791  // const-qualified.
13792  if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
13793  /*AcceptIfMutable*/ false, ASE || OASE))
13794  continue;
13795 
13796  OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
13797  // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
13798  // If a list-item is a reference type then it must bind to the same object
13799  // for all threads of the team.
13800  if (!ASE && !OASE) {
13801  if (VD) {
13802  VarDecl *VDDef = VD->getDefinition();
13803  if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
13804  DSARefChecker Check(Stack);
13805  if (Check.Visit(VDDef->getInit())) {
13806  S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
13807  << getOpenMPClauseName(ClauseKind) << ERange;
13808  S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
13809  continue;
13810  }
13811  }
13812  }
13813 
13814  // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
13815  // in a Construct]
13816  // Variables with the predetermined data-sharing attributes may not be
13817  // listed in data-sharing attributes clauses, except for the cases
13818  // listed below. For these exceptions only, listing a predetermined
13819  // variable in a data-sharing attribute clause is allowed and overrides
13820  // the variable's predetermined data-sharing attributes.
13821  // OpenMP [2.14.3.6, Restrictions, p.3]
13822  // Any number of reduction clauses can be specified on the directive,
13823  // but a list item can appear only once in the reduction clauses for that
13824  // directive.
13825  DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
13826  if (DVar.CKind == OMPC_reduction) {
13827  S.Diag(ELoc, diag::err_omp_once_referenced)
13828  << getOpenMPClauseName(ClauseKind);
13829  if (DVar.RefExpr)
13830  S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
13831  continue;
13832  }
13833  if (DVar.CKind != OMPC_unknown) {
13834  S.Diag(ELoc, diag::err_omp_wrong_dsa)
13835  << getOpenMPClauseName(DVar.CKind)
13836  << getOpenMPClauseName(OMPC_reduction);
13837  reportOriginalDsa(S, Stack, D, DVar);
13838  continue;
13839  }
13840 
13841  // OpenMP [2.14.3.6, Restrictions, p.1]
13842  // A list item that appears in a reduction clause of a worksharing
13843  // construct must be shared in the parallel regions to which any of the
13844  // worksharing regions arising from the worksharing construct bind.
13845  if (isOpenMPWorksharingDirective(CurrDir) &&
13846  !isOpenMPParallelDirective(CurrDir) &&
13847  !isOpenMPTeamsDirective(CurrDir)) {
13848  DVar = Stack->getImplicitDSA(D, true);
13849  if (DVar.CKind != OMPC_shared) {
13850  S.Diag(ELoc, diag::err_omp_required_access)
13851  << getOpenMPClauseName(OMPC_reduction)
13852  << getOpenMPClauseName(OMPC_shared);
13853  reportOriginalDsa(S, Stack, D, DVar);
13854  continue;
13855  }
13856  }
13857  }
13858 
13859  // Try to find 'declare reduction' corresponding construct before using
13860  // builtin/overloaded operators.
13861  CXXCastPath BasePath;
13862  ExprResult DeclareReductionRef = buildDeclareReductionRef(
13863  S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
13864  ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
13865  if (DeclareReductionRef.isInvalid())
13866  continue;
13867  if (S.CurContext->isDependentContext() &&
13868  (DeclareReductionRef.isUnset() ||
13869  isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
13870  RD.push(RefExpr, DeclareReductionRef.get());
13871  continue;
13872  }
13873  if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
13874  // Not allowed reduction identifier is found.
13875  S.Diag(ReductionId.getBeginLoc(),
13876  diag::err_omp_unknown_reduction_identifier)
13877  << Type << ReductionIdRange;
13878  continue;
13879  }
13880 
13881  // OpenMP [2.14.3.6, reduction clause, Restrictions]
13882  // The type of a list item that appears in a reduction clause must be valid
13883  // for the reduction-identifier. For a max or min reduction in C, the type
13884  // of the list item must be an allowed arithmetic data type: char, int,
13885  // float, double, or _Bool, possibly modified with long, short, signed, or
13886  // unsigned. For a max or min reduction in C++, the type of the list item
13887  // must be an allowed arithmetic data type: char, wchar_t, int, float,
13888  // double, or bool, possibly modified with long, short, signed, or unsigned.
13889  if (DeclareReductionRef.isUnset()) {
13890  if ((BOK == BO_GT || BOK == BO_LT) &&
13891  !(Type->isScalarType() ||
13892  (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
13893  S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
13894  << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
13895  if (!ASE && !OASE) {
13896  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
13898  S.Diag(D->getLocation(),
13899  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
13900  << D;
13901  }
13902  continue;
13903  }
13904  if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
13905  !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
13906  S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
13907  << getOpenMPClauseName(ClauseKind);
13908  if (!ASE && !OASE) {
13909  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
13911  S.Diag(D->getLocation(),
13912  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
13913  << D;
13914  }
13915  continue;
13916  }
13917  }
13918 
13919  Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
13920  VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
13921  D->hasAttrs() ? &D->getAttrs() : nullptr);
13922  VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
13923  D->hasAttrs() ? &D->getAttrs() : nullptr);
13924  QualType PrivateTy = Type;
13925 
13926  // Try if we can determine constant lengths for all array sections and avoid
13927  // the VLA.
13928  bool ConstantLengthOASE = false;
13929  if (OASE) {
13930  bool SingleElement;
13932  ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
13933  Context, OASE, SingleElement, ArraySizes);
13934 
13935  // If we don't have a single element, we must emit a constant array type.
13936  if (ConstantLengthOASE && !SingleElement) {
13937  for (llvm::APSInt &Size : ArraySizes)
13938  PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr,
13940  /*IndexTypeQuals=*/0);
13941  }
13942  }
13943 
13944  if ((OASE && !ConstantLengthOASE) ||
13945  (!OASE && !ASE &&
13947  if (!Context.getTargetInfo().isVLASupported()) {
13948  if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) {
13949  S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
13950  S.Diag(ELoc, diag::note_vla_unsupported);
13951  } else {
13952  S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
13953  S.targetDiag(ELoc, diag::note_vla_unsupported);
13954  }
13955  continue;
13956  }
13957  // For arrays/array sections only:
13958  // Create pseudo array type for private copy. The size for this array will
13959  // be generated during codegen.
13960  // For array subscripts or single variables Private Ty is the same as Type
13961  // (type of the variable or single array element).
13962  PrivateTy = Context.getVariableArrayType(
13963  Type,
13964  new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue),
13965  ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
13966  } else if (!ASE && !OASE &&
13967  Context.getAsArrayType(D->getType().getNonReferenceType())) {
13968  PrivateTy = D->getType().getNonReferenceType();
13969  }
13970  // Private copy.
13971  VarDecl *PrivateVD =
13972  buildVarDecl(S, ELoc, PrivateTy, D->getName(),
13973  D->hasAttrs() ? &D->getAttrs() : nullptr,
13974  VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
13975  // Add initializer for private variable.
13976  Expr *Init = nullptr;
13977  DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
13978  DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
13979  if (DeclareReductionRef.isUsable()) {
13980  auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
13981  auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
13982  if (DRD->getInitializer()) {
13983  Init = DRDRef;
13984  RHSVD->setInit(DRDRef);
13985  RHSVD->setInitStyle(VarDecl::CallInit);
13986  }
13987  } else {
13988  switch (BOK) {
13989  case BO_Add:
13990  case BO_Xor:
13991  case BO_Or:
13992  case BO_LOr:
13993  // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
13994  if (Type->isScalarType() || Type->isAnyComplexType())
13995  Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
13996  break;
13997  case BO_Mul:
13998  case BO_LAnd:
13999  if (Type->isScalarType() || Type->isAnyComplexType()) {
14000  // '*' and '&&' reduction ops - initializer is '1'.
14001  Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
14002  }
14003  break;
14004  case BO_And: {
14005  // '&' reduction op - initializer is '~0'.
14006  QualType OrigType = Type;
14007  if (auto *ComplexTy = OrigType->getAs<ComplexType>())
14008  Type = ComplexTy->getElementType();
14009  if (Type->isRealFloatingType()) {
14010  llvm::APFloat InitValue =
14011  llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type),
14012  /*isIEEE=*/true);
14013  Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
14014  Type, ELoc);
14015  } else if (Type->isScalarType()) {
14016  uint64_t Size = Context.getTypeSize(Type);
14017  QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
14018  llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
14019  Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
14020  }
14021  if (Init && OrigType->isAnyComplexType()) {
14022  // Init = 0xFFFF + 0xFFFFi;
14023  auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
14024  Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
14025  }
14026  Type = OrigType;
14027  break;
14028  }
14029  case BO_LT:
14030  case BO_GT: {
14031  // 'min' reduction op - initializer is 'Largest representable number in
14032  // the reduction list item type'.
14033  // 'max' reduction op - initializer is 'Least representable number in
14034  // the reduction list item type'.
14035  if (Type->isIntegerType() || Type->isPointerType()) {
14036  bool IsSigned = Type->hasSignedIntegerRepresentation();
14037  uint64_t Size = Context.getTypeSize(Type);
14038  QualType IntTy =
14039  Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
14040  llvm::APInt InitValue =
14041  (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
14042  : llvm::APInt::getMinValue(Size)
14043  : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
14044  : llvm::APInt::getMaxValue(Size);
14045  Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
14046  if (Type->isPointerType()) {
14047  // Cast to pointer type.
14049  ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
14050  if (CastExpr.isInvalid())
14051  continue;
14052  Init = CastExpr.get();
14053  }
14054  } else if (Type->isRealFloatingType()) {
14055  llvm::APFloat InitValue = llvm::APFloat::getLargest(
14056  Context.getFloatTypeSemantics(Type), BOK != BO_LT);
14057  Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
14058  Type, ELoc);
14059  }
14060  break;
14061  }
14062  case BO_PtrMemD:
14063  case BO_PtrMemI:
14064  case BO_MulAssign:
14065  case BO_Div:
14066  case BO_Rem:
14067  case BO_Sub:
14068  case BO_Shl:
14069  case BO_Shr:
14070  case BO_LE:
14071  case BO_GE:
14072  case BO_EQ:
14073  case BO_NE:
14074  case BO_Cmp:
14075  case BO_AndAssign:
14076  case BO_XorAssign:
14077  case BO_OrAssign:
14078  case BO_Assign:
14079  case BO_AddAssign:
14080  case BO_SubAssign:
14081  case BO_DivAssign:
14082  case BO_RemAssign:
14083  case BO_ShlAssign:
14084  case BO_ShrAssign:
14085  case BO_Comma:
14086  llvm_unreachable("Unexpected reduction operation");
14087  }
14088  }
14089  if (Init && DeclareReductionRef.isUnset())
14090  S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
14091  else if (!Init)
14092  S.ActOnUninitializedDecl(RHSVD);
14093  if (RHSVD->isInvalidDecl())
14094  continue;
14095  if (!RHSVD->hasInit() &&
14096  (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) {
14097  S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
14098  << Type << ReductionIdRange;
14099  bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
14101  S.Diag(D->getLocation(),
14102  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14103  << D;
14104  continue;
14105  }
14106  // Store initializer for single element in private copy. Will be used during
14107  // codegen.
14108  PrivateVD->setInit(RHSVD->getInit());
14109  PrivateVD->setInitStyle(RHSVD->getInitStyle());
14110  DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
14111  ExprResult ReductionOp;
14112  if (DeclareReductionRef.isUsable()) {
14113  QualType RedTy = DeclareReductionRef.get()->getType();
14114  QualType PtrRedTy = Context.getPointerType(RedTy);
14115  ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
14116  ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
14117  if (!BasePath.empty()) {
14118  LHS = S.DefaultLvalueConversion(LHS.get());
14119  RHS = S.DefaultLvalueConversion(RHS.get());
14120  LHS = ImplicitCastExpr::Create(Context, PtrRedTy,
14121  CK_UncheckedDerivedToBase, LHS.get(),
14122  &BasePath, LHS.get()->getValueKind());
14123  RHS = ImplicitCastExpr::Create(Context, PtrRedTy,
14124  CK_UncheckedDerivedToBase, RHS.get(),
14125  &BasePath, RHS.get()->getValueKind());
14126  }
14128  QualType Params[] = {PtrRedTy, PtrRedTy};
14129  QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
14130  auto *OVE = new (Context) OpaqueValueExpr(
14131  ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary,
14132  S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
14133  Expr *Args[] = {LHS.get(), RHS.get()};
14134  ReductionOp =
14135  CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc);
14136  } else {
14137  ReductionOp = S.BuildBinOp(
14138  Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE);
14139  if (ReductionOp.isUsable()) {
14140  if (BOK != BO_LT && BOK != BO_GT) {
14141  ReductionOp =
14142  S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
14143  BO_Assign, LHSDRE, ReductionOp.get());
14144  } else {
14145  auto *ConditionalOp = new (Context)
14146  ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE,
14147  Type, VK_LValue, OK_Ordinary);
14148  ReductionOp =
14149  S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
14150  BO_Assign, LHSDRE, ConditionalOp);
14151  }
14152  if (ReductionOp.isUsable())
14153  ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
14154  /*DiscardedValue*/ false);
14155  }
14156  if (!ReductionOp.isUsable())
14157  continue;
14158  }
14159 
14160  // OpenMP [2.15.4.6, Restrictions, p.2]
14161  // A list item that appears in an in_reduction clause of a task construct
14162  // must appear in a task_reduction clause of a construct associated with a
14163  // taskgroup region that includes the participating task in its taskgroup
14164  // set. The construct associated with the innermost region that meets this
14165  // condition must specify the same reduction-identifier as the in_reduction
14166  // clause.
14167  if (ClauseKind == OMPC_in_reduction) {
14168  SourceRange ParentSR;
14169  BinaryOperatorKind ParentBOK;
14170  const Expr *ParentReductionOp;
14171  Expr *ParentBOKTD, *ParentReductionOpTD;
14172  DSAStackTy::DSAVarData ParentBOKDSA =
14173  Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
14174  ParentBOKTD);
14175  DSAStackTy::DSAVarData ParentReductionOpDSA =
14176  Stack->getTopMostTaskgroupReductionData(
14177  D, ParentSR, ParentReductionOp, ParentReductionOpTD);
14178  bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
14179  bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
14180  if (!IsParentBOK && !IsParentReductionOp) {
14181  S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction);
14182  continue;
14183  }
14184  if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
14185  (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK ||
14186  IsParentReductionOp) {
14187  bool EmitError = true;
14188  if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
14189  llvm::FoldingSetNodeID RedId, ParentRedId;
14190  ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
14191  DeclareReductionRef.get()->Profile(RedId, Context,
14192  /*Canonical=*/true);
14193  EmitError = RedId != ParentRedId;
14194  }
14195  if (EmitError) {
14196  S.Diag(ReductionId.getBeginLoc(),
14197  diag::err_omp_reduction_identifier_mismatch)
14198  << ReductionIdRange << RefExpr->getSourceRange();
14199  S.Diag(ParentSR.getBegin(),
14200  diag::note_omp_previous_reduction_identifier)
14201  << ParentSR
14202  << (IsParentBOK ? ParentBOKDSA.RefExpr
14203  : ParentReductionOpDSA.RefExpr)
14204  ->getSourceRange();
14205  continue;
14206  }
14207  }
14208  TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
14209  assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined.");
14210  }
14211 
14212  DeclRefExpr *Ref = nullptr;
14213  Expr *VarsExpr = RefExpr->IgnoreParens();
14214  if (!VD && !S.CurContext->isDependentContext()) {
14215  if (ASE || OASE) {
14216  TransformExprToCaptures RebuildToCapture(S, D);
14217  VarsExpr =
14218  RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
14219  Ref = RebuildToCapture.getCapturedExpr();
14220  } else {
14221  VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
14222  }
14223  if (!S.isOpenMPCapturedDecl(D)) {
14224  RD.ExprCaptures.emplace_back(Ref->getDecl());
14225  if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
14226  ExprResult RefRes = S.DefaultLvalueConversion(Ref);
14227  if (!RefRes.isUsable())
14228  continue;
14229  ExprResult PostUpdateRes =
14230  S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
14231  RefRes.get());
14232  if (!PostUpdateRes.isUsable())
14233  continue;
14234  if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
14235  Stack->getCurrentDirective() == OMPD_taskgroup) {
14236  S.Diag(RefExpr->getExprLoc(),
14237  diag::err_omp_reduction_non_addressable_expression)
14238  << RefExpr->getSourceRange();
14239  continue;
14240  }
14241  RD.ExprPostUpdates.emplace_back(
14242  S.IgnoredValueConversions(PostUpdateRes.get()).get());
14243  }
14244  }
14245  }
14246  // All reduction items are still marked as reduction (to do not increase
14247  // code base size).
14248  Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref);
14249  if (CurrDir == OMPD_taskgroup) {
14250  if (DeclareReductionRef.isUsable())
14251  Stack->addTaskgroupReductionData(D, ReductionIdRange,
14252  DeclareReductionRef.get());
14253  else
14254  Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
14255  }
14256  RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
14257  TaskgroupDescriptor);
14258  }
14259  return RD.Vars.empty();
14260 }
14261 
14263  ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
14265  CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
14266  ArrayRef<Expr *> UnresolvedReductions) {
14267  ReductionData RD(VarList.size());
14268  if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList,
14269  StartLoc, LParenLoc, ColonLoc, EndLoc,
14270  ReductionIdScopeSpec, ReductionId,
14271  UnresolvedReductions, RD))
14272  return nullptr;
14273 
14275  Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
14276  ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
14277  RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
14278  buildPreInits(Context, RD.ExprCaptures),
14279  buildPostUpdate(*this, RD.ExprPostUpdates));
14280 }
14281 
14283  ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
14285  CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
14286  ArrayRef<Expr *> UnresolvedReductions) {
14287  ReductionData RD(VarList.size());
14288  if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList,
14289  StartLoc, LParenLoc, ColonLoc, EndLoc,
14290  ReductionIdScopeSpec, ReductionId,
14291  UnresolvedReductions, RD))
14292  return nullptr;
14293 
14295  Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
14296  ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
14297  RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
14298  buildPreInits(Context, RD.ExprCaptures),
14299  buildPostUpdate(*this, RD.ExprPostUpdates));
14300 }
14301 
14303  ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
14305  CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
14306  ArrayRef<Expr *> UnresolvedReductions) {
14307  ReductionData RD(VarList.size());
14308  if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList,
14309  StartLoc, LParenLoc, ColonLoc, EndLoc,
14310  ReductionIdScopeSpec, ReductionId,
14311  UnresolvedReductions, RD))
14312  return nullptr;
14313 
14315  Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
14316  ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
14317  RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
14318  buildPreInits(Context, RD.ExprCaptures),
14319  buildPostUpdate(*this, RD.ExprPostUpdates));
14320 }
14321 
14323  SourceLocation LinLoc) {
14324  if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
14325  LinKind == OMPC_LINEAR_unknown) {
14326  Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
14327  return true;
14328  }
14329  return false;
14330 }
14331 
14333  OpenMPLinearClauseKind LinKind,
14334  QualType Type) {
14335  const auto *VD = dyn_cast_or_null<VarDecl>(D);
14336  // A variable must not have an incomplete type or a reference type.
14337  if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
14338  return true;
14339  if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
14340  !Type->isReferenceType()) {
14341  Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
14342  << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
14343  return true;
14344  }
14345  Type = Type.getNonReferenceType();
14346 
14347  // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
14348  // A variable that is privatized must not have a const-qualified type
14349  // unless it is of class type with a mutable member. This restriction does
14350  // not apply to the firstprivate clause.
14351  if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
14352  return true;
14353 
14354  // A list item must be of integral or pointer type.
14355  Type = Type.getUnqualifiedType().getCanonicalType();
14356  const auto *Ty = Type.getTypePtrOrNull();
14357  if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
14358  !Ty->isIntegralType(Context) && !Ty->isPointerType())) {
14359  Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
14360  if (D) {
14361  bool IsDecl =
14362  !VD ||
14363  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
14364  Diag(D->getLocation(),
14365  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14366  << D;
14367  }
14368  return true;
14369  }
14370  return false;
14371 }
14372 
14374  ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
14375  SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
14380  SmallVector<Decl *, 4> ExprCaptures;
14381  SmallVector<Expr *, 4> ExprPostUpdates;
14382  if (CheckOpenMPLinearModifier(LinKind, LinLoc))
14383  LinKind = OMPC_LINEAR_val;
14384  for (Expr *RefExpr : VarList) {
14385  assert(RefExpr && "NULL expr in OpenMP linear clause.");
14386  SourceLocation ELoc;
14387  SourceRange ERange;
14388  Expr *SimpleRefExpr = RefExpr;
14389  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14390  if (Res.second) {
14391  // It will be analyzed later.
14392  Vars.push_back(RefExpr);
14393  Privates.push_back(nullptr);
14394  Inits.push_back(nullptr);
14395  }
14396  ValueDecl *D = Res.first;
14397  if (!D)
14398  continue;
14399 
14400  QualType Type = D->getType();
14401  auto *VD = dyn_cast<VarDecl>(D);
14402 
14403  // OpenMP [2.14.3.7, linear clause]
14404  // A list-item cannot appear in more than one linear clause.
14405  // A list-item that appears in a linear clause cannot appear in any
14406  // other data-sharing attribute clause.
14407  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
14408  if (DVar.RefExpr) {
14409  Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
14410  << getOpenMPClauseName(OMPC_linear);
14411  reportOriginalDsa(*this, DSAStack, D, DVar);
14412  continue;
14413  }
14414 
14415  if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
14416  continue;
14418 
14419  // Build private copy of original var.
14420  VarDecl *Private =
14421  buildVarDecl(*this, ELoc, Type, D->getName(),
14422  D->hasAttrs() ? &D->getAttrs() : nullptr,
14423  VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
14424  DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
14425  // Build var to save initial value.
14426  VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
14427  Expr *InitExpr;
14428  DeclRefExpr *Ref = nullptr;
14429  if (!VD && !CurContext->isDependentContext()) {
14430  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
14431  if (!isOpenMPCapturedDecl(D)) {
14432  ExprCaptures.push_back(Ref->getDecl());
14433  if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
14434  ExprResult RefRes = DefaultLvalueConversion(Ref);
14435  if (!RefRes.isUsable())
14436  continue;
14437  ExprResult PostUpdateRes =
14438  BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
14439  SimpleRefExpr, RefRes.get());
14440  if (!PostUpdateRes.isUsable())
14441  continue;
14442  ExprPostUpdates.push_back(
14443  IgnoredValueConversions(PostUpdateRes.get()).get());
14444  }
14445  }
14446  }
14447  if (LinKind == OMPC_LINEAR_uval)
14448  InitExpr = VD ? VD->getInit() : SimpleRefExpr;
14449  else
14450  InitExpr = VD ? SimpleRefExpr : Ref;
14451  AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
14452  /*DirectInit=*/false);
14453  DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
14454 
14455  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
14456  Vars.push_back((VD || CurContext->isDependentContext())
14457  ? RefExpr->IgnoreParens()
14458  : Ref);
14459  Privates.push_back(PrivateRef);
14460  Inits.push_back(InitRef);
14461  }
14462 
14463  if (Vars.empty())
14464  return nullptr;
14465 
14466  Expr *StepExpr = Step;
14467  Expr *CalcStepExpr = nullptr;
14468  if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
14469  !Step->isInstantiationDependent() &&
14471  SourceLocation StepLoc = Step->getBeginLoc();
14472  ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
14473  if (Val.isInvalid())
14474  return nullptr;
14475  StepExpr = Val.get();
14476 
14477  // Build var to save the step value.
14478  VarDecl *SaveVar =
14479  buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
14480  ExprResult SaveRef =
14481  buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
14483  BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
14484  CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
14485 
14486  // Warn about zero linear step (it would be probably better specified as
14487  // making corresponding variables 'const').
14489  bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context);
14490  if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive())
14491  Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0]
14492  << (Vars.size() > 1);
14493  if (!IsConstant && CalcStep.isUsable()) {
14494  // Calculate the step beforehand instead of doing this on each iteration.
14495  // (This is not used if the number of iterations may be kfold-ed).
14496  CalcStepExpr = CalcStep.get();
14497  }
14498  }
14499 
14500  return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
14501  ColonLoc, EndLoc, Vars, Privates, Inits,
14502  StepExpr, CalcStepExpr,
14503  buildPreInits(Context, ExprCaptures),
14504  buildPostUpdate(*this, ExprPostUpdates));
14505 }
14506 
14508  Expr *NumIterations, Sema &SemaRef,
14509  Scope *S, DSAStackTy *Stack) {
14510  // Walk the vars and build update/final expressions for the CodeGen.
14513  SmallVector<Expr *, 8> UsedExprs;
14514  Expr *Step = Clause.getStep();
14515  Expr *CalcStep = Clause.getCalcStep();
14516  // OpenMP [2.14.3.7, linear clause]
14517  // If linear-step is not specified it is assumed to be 1.
14518  if (!Step)
14519  Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
14520  else if (CalcStep)
14521  Step = cast<BinaryOperator>(CalcStep)->getLHS();
14522  bool HasErrors = false;
14523  auto CurInit = Clause.inits().begin();
14524  auto CurPrivate = Clause.privates().begin();
14525  OpenMPLinearClauseKind LinKind = Clause.getModifier();
14526  for (Expr *RefExpr : Clause.varlists()) {
14527  SourceLocation ELoc;
14528  SourceRange ERange;
14529  Expr *SimpleRefExpr = RefExpr;
14530  auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
14531  ValueDecl *D = Res.first;
14532  if (Res.second || !D) {
14533  Updates.push_back(nullptr);
14534  Finals.push_back(nullptr);
14535  HasErrors = true;
14536  continue;
14537  }
14538  auto &&Info = Stack->isLoopControlVariable(D);
14539  // OpenMP [2.15.11, distribute simd Construct]
14540  // A list item may not appear in a linear clause, unless it is the loop
14541  // iteration variable.
14542  if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
14543  isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
14544  SemaRef.Diag(ELoc,
14545  diag::err_omp_linear_distribute_var_non_loop_iteration);
14546  Updates.push_back(nullptr);
14547  Finals.push_back(nullptr);
14548  HasErrors = true;
14549  continue;
14550  }
14551  Expr *InitExpr = *CurInit;
14552 
14553  // Build privatized reference to the current linear var.
14554  auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
14555  Expr *CapturedRef;
14556  if (LinKind == OMPC_LINEAR_uval)
14557  CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
14558  else
14559  CapturedRef =
14560  buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
14561  DE->getType().getUnqualifiedType(), DE->getExprLoc(),
14562  /*RefersToCapture=*/true);
14563 
14564  // Build update: Var = InitExpr + IV * Step
14566  if (!Info.first)
14567  Update = buildCounterUpdate(
14568  SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
14569  /*Subtract=*/false, /*IsNonRectangularLB=*/false);
14570  else
14571  Update = *CurPrivate;
14572  Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
14573  /*DiscardedValue*/ false);
14574 
14575  // Build final: Var = InitExpr + NumIterations * Step
14576  ExprResult Final;
14577  if (!Info.first)
14578  Final =
14579  buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
14580  InitExpr, NumIterations, Step, /*Subtract=*/false,
14581  /*IsNonRectangularLB=*/false);
14582  else
14583  Final = *CurPrivate;
14584  Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
14585  /*DiscardedValue*/ false);
14586 
14587  if (!Update.isUsable() || !Final.isUsable()) {
14588  Updates.push_back(nullptr);
14589  Finals.push_back(nullptr);
14590  UsedExprs.push_back(nullptr);
14591  HasErrors = true;
14592  } else {
14593  Updates.push_back(Update.get());
14594  Finals.push_back(Final.get());
14595  if (!Info.first)
14596  UsedExprs.push_back(SimpleRefExpr);
14597  }
14598  ++CurInit;
14599  ++CurPrivate;
14600  }
14601  if (Expr *S = Clause.getStep())
14602  UsedExprs.push_back(S);
14603  // Fill the remaining part with the nullptr.
14604  UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr);
14605  Clause.setUpdates(Updates);
14606  Clause.setFinals(Finals);
14607  Clause.setUsedExprs(UsedExprs);
14608  return HasErrors;
14609 }
14610 
14612  ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
14615  for (Expr *RefExpr : VarList) {
14616  assert(RefExpr && "NULL expr in OpenMP linear clause.");
14617  SourceLocation ELoc;
14618  SourceRange ERange;
14619  Expr *SimpleRefExpr = RefExpr;
14620  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14621  if (Res.second) {
14622  // It will be analyzed later.
14623  Vars.push_back(RefExpr);
14624  }
14625  ValueDecl *D = Res.first;
14626  if (!D)
14627  continue;
14628 
14629  QualType QType = D->getType();
14630  auto *VD = dyn_cast<VarDecl>(D);
14631 
14632  // OpenMP [2.8.1, simd construct, Restrictions]
14633  // The type of list items appearing in the aligned clause must be
14634  // array, pointer, reference to array, or reference to pointer.
14636  const Type *Ty = QType.getTypePtrOrNull();
14637  if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
14638  Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
14639  << QType << getLangOpts().CPlusPlus << ERange;
14640  bool IsDecl =
14641  !VD ||
14642  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
14643  Diag(D->getLocation(),
14644  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14645  << D;
14646  continue;
14647  }
14648 
14649  // OpenMP [2.8.1, simd construct, Restrictions]
14650  // A list-item cannot appear in more than one aligned clause.
14651  if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
14652  Diag(ELoc, diag::err_omp_used_in_clause_twice)
14653  << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
14654  Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
14655  << getOpenMPClauseName(OMPC_aligned);
14656  continue;
14657  }
14658 
14659  DeclRefExpr *Ref = nullptr;
14660  if (!VD && isOpenMPCapturedDecl(D))
14661  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
14662  Vars.push_back(DefaultFunctionArrayConversion(
14663  (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
14664  .get());
14665  }
14666 
14667  // OpenMP [2.8.1, simd construct, Description]
14668  // The parameter of the aligned clause, alignment, must be a constant
14669  // positive integer expression.
14670  // If no optional parameter is specified, implementation-defined default
14671  // alignments for SIMD instructions on the target platforms are assumed.
14672  if (Alignment != nullptr) {
14673  ExprResult AlignResult =
14674  VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
14675  if (AlignResult.isInvalid())
14676  return nullptr;
14677  Alignment = AlignResult.get();
14678  }
14679  if (Vars.empty())
14680  return nullptr;
14681 
14682  return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
14683  EndLoc, Vars, Alignment);
14684 }
14685 
14687  SourceLocation StartLoc,
14688  SourceLocation LParenLoc,
14689  SourceLocation EndLoc) {
14691  SmallVector<Expr *, 8> SrcExprs;
14692  SmallVector<Expr *, 8> DstExprs;
14693  SmallVector<Expr *, 8> AssignmentOps;
14694  for (Expr *RefExpr : VarList) {
14695  assert(RefExpr && "NULL expr in OpenMP copyin clause.");
14696  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
14697  // It will be analyzed later.
14698  Vars.push_back(RefExpr);
14699  SrcExprs.push_back(nullptr);
14700  DstExprs.push_back(nullptr);
14701  AssignmentOps.push_back(nullptr);
14702  continue;
14703  }
14704 
14705  SourceLocation ELoc = RefExpr->getExprLoc();
14706  // OpenMP [2.1, C/C++]
14707  // A list item is a variable name.
14708  // OpenMP [2.14.4.1, Restrictions, p.1]
14709  // A list item that appears in a copyin clause must be threadprivate.
14710  auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
14711  if (!DE || !isa<VarDecl>(DE->getDecl())) {
14712  Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
14713  << 0 << RefExpr->getSourceRange();
14714  continue;
14715  }
14716 
14717  Decl *D = DE->getDecl();
14718  auto *VD = cast<VarDecl>(D);
14719 
14720  QualType Type = VD->getType();
14721  if (Type->isDependentType() || Type->isInstantiationDependentType()) {
14722  // It will be analyzed later.
14723  Vars.push_back(DE);
14724  SrcExprs.push_back(nullptr);
14725  DstExprs.push_back(nullptr);
14726  AssignmentOps.push_back(nullptr);
14727  continue;
14728  }
14729 
14730  // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
14731  // A list item that appears in a copyin clause must be threadprivate.
14732  if (!DSAStack->isThreadPrivate(VD)) {
14733  Diag(ELoc, diag::err_omp_required_access)
14734  << getOpenMPClauseName(OMPC_copyin)
14735  << getOpenMPDirectiveName(OMPD_threadprivate);
14736  continue;
14737  }
14738 
14739  // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
14740  // A variable of class type (or array thereof) that appears in a
14741  // copyin clause requires an accessible, unambiguous copy assignment
14742  // operator for the class type.
14743  QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
14744  VarDecl *SrcVD =
14745  buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
14746  ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
14747  DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
14748  *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
14749  VarDecl *DstVD =
14750  buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
14751  VD->hasAttrs() ? &VD->getAttrs() : nullptr);
14752  DeclRefExpr *PseudoDstExpr =
14753  buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
14754  // For arrays generate assignment operation for single element and replace
14755  // it by the original array element in CodeGen.
14756  ExprResult AssignmentOp =
14757  BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
14758  PseudoSrcExpr);
14759  if (AssignmentOp.isInvalid())
14760  continue;
14761  AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
14762  /*DiscardedValue*/ false);
14763  if (AssignmentOp.isInvalid())
14764  continue;
14765 
14766  DSAStack->addDSA(VD, DE, OMPC_copyin);
14767  Vars.push_back(DE);
14768  SrcExprs.push_back(PseudoSrcExpr);
14769  DstExprs.push_back(PseudoDstExpr);
14770  AssignmentOps.push_back(AssignmentOp.get());
14771  }
14772 
14773  if (Vars.empty())
14774  return nullptr;
14775 
14776  return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
14777  SrcExprs, DstExprs, AssignmentOps);
14778 }
14779 
14781  SourceLocation StartLoc,
14782  SourceLocation LParenLoc,
14783  SourceLocation EndLoc) {
14785  SmallVector<Expr *, 8> SrcExprs;
14786  SmallVector<Expr *, 8> DstExprs;
14787  SmallVector<Expr *, 8> AssignmentOps;
14788  for (Expr *RefExpr : VarList) {
14789  assert(RefExpr && "NULL expr in OpenMP linear clause.");
14790  SourceLocation ELoc;
14791  SourceRange ERange;
14792  Expr *SimpleRefExpr = RefExpr;
14793  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
14794  if (Res.second) {
14795  // It will be analyzed later.
14796  Vars.push_back(RefExpr);
14797  SrcExprs.push_back(nullptr);
14798  DstExprs.push_back(nullptr);
14799  AssignmentOps.push_back(nullptr);
14800  }
14801  ValueDecl *D = Res.first;
14802  if (!D)
14803  continue;
14804 
14805  QualType Type = D->getType();
14806  auto *VD = dyn_cast<VarDecl>(D);
14807 
14808  // OpenMP [2.14.4.2, Restrictions, p.2]
14809  // A list item that appears in a copyprivate clause may not appear in a
14810  // private or firstprivate clause on the single construct.
14811  if (!VD || !DSAStack->isThreadPrivate(VD)) {
14812  DSAStackTy::DSAVarData DVar =
14813  DSAStack->getTopDSA(D, /*FromParent=*/false);
14814  if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
14815  DVar.RefExpr) {
14816  Diag(ELoc, diag::err_omp_wrong_dsa)
14817  << getOpenMPClauseName(DVar.CKind)
14818  << getOpenMPClauseName(OMPC_copyprivate);
14819  reportOriginalDsa(*this, DSAStack, D, DVar);
14820  continue;
14821  }
14822 
14823  // OpenMP [2.11.4.2, Restrictions, p.1]
14824  // All list items that appear in a copyprivate clause must be either
14825  // threadprivate or private in the enclosing context.
14826  if (DVar.CKind == OMPC_unknown) {
14827  DVar = DSAStack->getImplicitDSA(D, false);
14828  if (DVar.CKind == OMPC_shared) {
14829  Diag(ELoc, diag::err_omp_required_access)
14830  << getOpenMPClauseName(OMPC_copyprivate)
14831  << "threadprivate or private in the enclosing context";
14832  reportOriginalDsa(*this, DSAStack, D, DVar);
14833  continue;
14834  }
14835  }
14836  }
14837 
14838  // Variably modified types are not supported.
14839  if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
14840  Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
14841  << getOpenMPClauseName(OMPC_copyprivate) << Type
14842  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
14843  bool IsDecl =
14844  !VD ||
14845  VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
14846  Diag(D->getLocation(),
14847  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
14848  << D;
14849  continue;
14850  }
14851 
14852  // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
14853  // A variable of class type (or array thereof) that appears in a
14854  // copyin clause requires an accessible, unambiguous copy assignment
14855  // operator for the class type.
14856  Type = Context.getBaseElementType(Type.getNonReferenceType())
14857  .getUnqualifiedType();
14858  VarDecl *SrcVD =
14859  buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
14860  D->hasAttrs() ? &D->getAttrs() : nullptr);
14861  DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
14862  VarDecl *DstVD =
14863  buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
14864  D->hasAttrs() ? &D->getAttrs() : nullptr);
14865  DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
14866  ExprResult AssignmentOp = BuildBinOp(
14867  DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
14868  if (AssignmentOp.isInvalid())
14869  continue;
14870  AssignmentOp =
14871  ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
14872  if (AssignmentOp.isInvalid())
14873  continue;
14874 
14875  // No need to mark vars as copyprivate, they are already threadprivate or
14876  // implicitly private.
14877  assert(VD || isOpenMPCapturedDecl(D));
14878  Vars.push_back(
14879  VD ? RefExpr->IgnoreParens()
14880  : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
14881  SrcExprs.push_back(PseudoSrcExpr);
14882  DstExprs.push_back(PseudoDstExpr);
14883  AssignmentOps.push_back(AssignmentOp.get());
14884  }
14885 
14886  if (Vars.empty())
14887  return nullptr;
14888 
14889  return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
14890  Vars, SrcExprs, DstExprs, AssignmentOps);
14891 }
14892 
14894  SourceLocation StartLoc,
14895  SourceLocation LParenLoc,
14896  SourceLocation EndLoc) {
14897  if (VarList.empty())
14898  return nullptr;
14899 
14900  return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
14901 }
14902 
14903 OMPClause *
14906  ArrayRef<Expr *> VarList, SourceLocation StartLoc,
14907  SourceLocation LParenLoc, SourceLocation EndLoc) {
14908  if (DSAStack->getCurrentDirective() == OMPD_ordered &&
14909  DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
14910  Diag(DepLoc, diag::err_omp_unexpected_clause_value)
14911  << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
14912  return nullptr;
14913  }
14914  if (DSAStack->getCurrentDirective() != OMPD_ordered &&
14915  (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
14916  DepKind == OMPC_DEPEND_sink)) {
14917  unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink};
14918  Diag(DepLoc, diag::err_omp_unexpected_clause_value)
14919  << getListOfPossibleValues(OMPC_depend, /*First=*/0,
14920  /*Last=*/OMPC_DEPEND_unknown, Except)
14921  << getOpenMPClauseName(OMPC_depend);
14922  return nullptr;
14923  }
14926  llvm::APSInt DepCounter(/*BitWidth=*/32);
14927  llvm::APSInt TotalDepCount(/*BitWidth=*/32);
14928  if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
14929  if (const Expr *OrderedCountExpr =
14930  DSAStack->getParentOrderedRegionParam().first) {
14931  TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
14932  TotalDepCount.setIsUnsigned(/*Val=*/true);
14933  }
14934  }
14935  for (Expr *RefExpr : VarList) {
14936  assert(RefExpr && "NULL expr in OpenMP shared clause.");
14937  if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
14938  // It will be analyzed later.
14939  Vars.push_back(RefExpr);
14940  continue;
14941  }
14942 
14943  SourceLocation ELoc = RefExpr->getExprLoc();
14944  Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
14945  if (DepKind == OMPC_DEPEND_sink) {
14946  if (DSAStack->getParentOrderedRegionParam().first &&
14947  DepCounter >= TotalDepCount) {
14948  Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
14949  continue;
14950  }
14951  ++DepCounter;
14952  // OpenMP [2.13.9, Summary]
14953  // depend(dependence-type : vec), where dependence-type is:
14954  // 'sink' and where vec is the iteration vector, which has the form:
14955  // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
14956  // where n is the value specified by the ordered clause in the loop
14957  // directive, xi denotes the loop iteration variable of the i-th nested
14958  // loop associated with the loop directive, and di is a constant
14959  // non-negative integer.
14960  if (CurContext->isDependentContext()) {
14961  // It will be analyzed later.
14962  Vars.push_back(RefExpr);
14963  continue;
14964  }
14965  SimpleExpr = SimpleExpr->IgnoreImplicit();
14967  SourceLocation OOLoc;
14968  Expr *LHS = SimpleExpr;
14969  Expr *RHS = nullptr;
14970  if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
14971  OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
14972  OOLoc = BO->getOperatorLoc();
14973  LHS = BO->getLHS()->IgnoreParenImpCasts();
14974  RHS = BO->getRHS()->IgnoreParenImpCasts();
14975  } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
14976  OOK = OCE->getOperator();
14977  OOLoc = OCE->getOperatorLoc();
14978  LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
14979  RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
14980  } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
14981  OOK = MCE->getMethodDecl()
14982  ->getNameInfo()
14983  .getName()
14984  .getCXXOverloadedOperator();
14985  OOLoc = MCE->getCallee()->getExprLoc();
14986  LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
14987  RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
14988  }
14989  SourceLocation ELoc;
14990  SourceRange ERange;
14991  auto Res = getPrivateItem(*this, LHS, ELoc, ERange);
14992  if (Res.second) {
14993  // It will be analyzed later.
14994  Vars.push_back(RefExpr);
14995  }
14996  ValueDecl *D = Res.first;
14997  if (!D)
14998  continue;
14999 
15000  if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
15001  Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
15002  continue;
15003  }
15004  if (RHS) {
15005  ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
15006  RHS, OMPC_depend, /*StrictlyPositive=*/false);
15007  if (RHSRes.isInvalid())
15008  continue;
15009  }
15010  if (!CurContext->isDependentContext() &&
15011  DSAStack->getParentOrderedRegionParam().first &&
15012  DepCounter != DSAStack->isParentLoopControlVariable(D).first) {
15013  const ValueDecl *VD =
15014  DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue());
15015  if (VD)
15016  Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
15017  << 1 << VD;
15018  else
15019  Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
15020  continue;
15021  }
15022  OpsOffs.emplace_back(RHS, OOK);
15023  } else {
15024  // OpenMP 5.0 [2.17.11, Restrictions]
15025  // List items used in depend clauses cannot be zero-length array sections.
15026  const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
15027  if (OASE) {
15028  const Expr *Length = OASE->getLength();
15030  if (Length && !Length->isValueDependent() &&
15031  Length->EvaluateAsInt(Result, Context) &&
15032  Result.Val.getInt().isNullValue()) {
15033  Diag(ELoc,
15034  diag::err_omp_depend_zero_length_array_section_not_allowed)
15035  << SimpleExpr->getSourceRange();
15036  continue;
15037  }
15038  }
15039 
15040  auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
15041  if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
15042  (ASE &&
15043  !ASE->getBase()->getType().getNonReferenceType()->isPointerType() &&
15044  !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
15045  Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
15046  << RefExpr->getSourceRange();
15047  continue;
15048  }
15049 
15050  ExprResult Res;
15051  {
15052  Sema::TentativeAnalysisScope Trap(*this);
15053  Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
15054  RefExpr->IgnoreParenImpCasts());
15055  }
15056  if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) {
15057  Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
15058  << RefExpr->getSourceRange();
15059  continue;
15060  }
15061  }
15062  Vars.push_back(RefExpr->IgnoreParenImpCasts());
15063  }
15064 
15065  if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
15066  TotalDepCount > VarList.size() &&
15067  DSAStack->getParentOrderedRegionParam().first &&
15068  DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
15069  Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
15070  << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1);
15071  }
15072  if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
15073  Vars.empty())
15074  return nullptr;
15075 
15076  auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
15077  DepKind, DepLoc, ColonLoc, Vars,
15078  TotalDepCount.getZExtValue());
15079  if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
15080  DSAStack->isParentOrderedRegion())
15081  DSAStack->addDoacrossDependClause(C, OpsOffs);
15082  return C;
15083 }
15084 
15086  SourceLocation LParenLoc,
15087  SourceLocation EndLoc) {
15088  Expr *ValExpr = Device;
15089  Stmt *HelperValStmt = nullptr;
15090 
15091  // OpenMP [2.9.1, Restrictions]
15092  // The device expression must evaluate to a non-negative integer value.
15093  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
15094  /*StrictlyPositive=*/false))
15095  return nullptr;
15096 
15097  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
15098  OpenMPDirectiveKind CaptureRegion =
15099  getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP);
15100  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
15101  ValExpr = MakeFullExpr(ValExpr).get();
15102  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15103  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
15104  HelperValStmt = buildPreInits(Context, Captures);
15105  }
15106 
15107  return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion,
15108  StartLoc, LParenLoc, EndLoc);
15109 }
15110 
15111 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
15112  DSAStackTy *Stack, QualType QTy,
15113  bool FullCheck = true) {
15114  NamedDecl *ND;
15115  if (QTy->isIncompleteType(&ND)) {
15116  SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR;
15117  return false;
15118  }
15119  if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
15120  !QTy.isTriviallyCopyableType(SemaRef.Context))
15121  SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
15122  return true;
15123 }
15124 
15125 /// Return true if it can be proven that the provided array expression
15126 /// (array section or array subscript) does NOT specify the whole size of the
15127 /// array whose base type is \a BaseQTy.
15129  const Expr *E,
15130  QualType BaseQTy) {
15131  const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
15132 
15133  // If this is an array subscript, it refers to the whole size if the size of
15134  // the dimension is constant and equals 1. Also, an array section assumes the
15135  // format of an array subscript if no colon is used.
15136  if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) {
15137  if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
15138  return ATy->getSize().getSExtValue() != 1;
15139  // Size can't be evaluated statically.
15140  return false;
15141  }
15142 
15143  assert(OASE && "Expecting array section if not an array subscript.");
15144  const Expr *LowerBound = OASE->getLowerBound();
15145  const Expr *Length = OASE->getLength();
15146 
15147  // If there is a lower bound that does not evaluates to zero, we are not
15148  // covering the whole dimension.
15149  if (LowerBound) {
15151  if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
15152  return false; // Can't get the integer value as a constant.
15153 
15154  llvm::APSInt ConstLowerBound = Result.Val.getInt();
15155  if (ConstLowerBound.getSExtValue())
15156  return true;
15157  }
15158 
15159  // If we don't have a length we covering the whole dimension.
15160  if (!Length)
15161  return false;
15162 
15163  // If the base is a pointer, we don't have a way to get the size of the
15164  // pointee.
15165  if (BaseQTy->isPointerType())
15166  return false;
15167 
15168  // We can only check if the length is the same as the size of the dimension
15169  // if we have a constant array.
15170  const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
15171  if (!CATy)
15172  return false;
15173 
15175  if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
15176  return false; // Can't get the integer value as a constant.
15177 
15178  llvm::APSInt ConstLength = Result.Val.getInt();
15179  return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
15180 }
15181 
15182 // Return true if it can be proven that the provided array expression (array
15183 // section or array subscript) does NOT specify a single element of the array
15184 // whose base type is \a BaseQTy.
15186  const Expr *E,
15187  QualType BaseQTy) {
15188  const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
15189 
15190  // An array subscript always refer to a single element. Also, an array section
15191  // assumes the format of an array subscript if no colon is used.
15192  if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid()))
15193  return false;
15194 
15195  assert(OASE && "Expecting array section if not an array subscript.");
15196  const Expr *Length = OASE->getLength();
15197 
15198  // If we don't have a length we have to check if the array has unitary size
15199  // for this dimension. Also, we should always expect a length if the base type
15200  // is pointer.
15201  if (!Length) {
15202  if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
15203  return ATy->getSize().getSExtValue() != 1;
15204  // We cannot assume anything.
15205  return false;
15206  }
15207 
15208  // Check if the length evaluates to 1.
15210  if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
15211  return false; // Can't get the integer value as a constant.
15212 
15213  llvm::APSInt ConstLength = Result.Val.getInt();
15214  return ConstLength.getSExtValue() != 1;
15215 }
15216 
15217 // Return the expression of the base of the mappable expression or null if it
15218 // cannot be determined and do all the necessary checks to see if the expression
15219 // is valid as a standalone mappable expression. In the process, record all the
15220 // components of the expression.
15222  Sema &SemaRef, Expr *E,
15224  OpenMPClauseKind CKind, bool NoDiagnose) {
15225  SourceLocation ELoc = E->getExprLoc();
15226  SourceRange ERange = E->getSourceRange();
15227 
15228  // The base of elements of list in a map clause have to be either:
15229  // - a reference to variable or field.
15230  // - a member expression.
15231  // - an array expression.
15232  //
15233  // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
15234  // reference to 'r'.
15235  //
15236  // If we have:
15237  //
15238  // struct SS {
15239  // Bla S;
15240  // foo() {
15241  // #pragma omp target map (S.Arr[:12]);
15242  // }
15243  // }
15244  //
15245  // We want to retrieve the member expression 'this->S';
15246 
15247  const Expr *RelevantExpr = nullptr;
15248 
15249  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2]
15250  // If a list item is an array section, it must specify contiguous storage.
15251  //
15252  // For this restriction it is sufficient that we make sure only references
15253  // to variables or fields and array expressions, and that no array sections
15254  // exist except in the rightmost expression (unless they cover the whole
15255  // dimension of the array). E.g. these would be invalid:
15256  //
15257  // r.ArrS[3:5].Arr[6:7]
15258  //
15259  // r.ArrS[3:5].x
15260  //
15261  // but these would be valid:
15262  // r.ArrS[3].Arr[6:7]
15263  //
15264  // r.ArrS[3].x
15265 
15266  bool AllowUnitySizeArraySection = true;
15267  bool AllowWholeSizeArraySection = true;
15268 
15269  while (!RelevantExpr) {
15270  E = E->IgnoreParenImpCasts();
15271 
15272  if (auto *CurE = dyn_cast<DeclRefExpr>(E)) {
15273  if (!isa<VarDecl>(CurE->getDecl()))
15274  return nullptr;
15275 
15276  RelevantExpr = CurE;
15277 
15278  // If we got a reference to a declaration, we should not expect any array
15279  // section before that.
15280  AllowUnitySizeArraySection = false;
15281  AllowWholeSizeArraySection = false;
15282 
15283  // Record the component.
15284  CurComponents.emplace_back(CurE, CurE->getDecl());
15285  } else if (auto *CurE = dyn_cast<MemberExpr>(E)) {
15286  Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts();
15287 
15288  if (isa<CXXThisExpr>(BaseE))
15289  // We found a base expression: this->Val.
15290  RelevantExpr = CurE;
15291  else
15292  E = BaseE;
15293 
15294  if (!isa<FieldDecl>(CurE->getMemberDecl())) {
15295  if (!NoDiagnose) {
15296  SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
15297  << CurE->getSourceRange();
15298  return nullptr;
15299  }
15300  if (RelevantExpr)
15301  return nullptr;
15302  continue;
15303  }
15304 
15305  auto *FD = cast<FieldDecl>(CurE->getMemberDecl());
15306 
15307  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
15308  // A bit-field cannot appear in a map clause.
15309  //
15310  if (FD->isBitField()) {
15311  if (!NoDiagnose) {
15312  SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
15313  << CurE->getSourceRange() << getOpenMPClauseName(CKind);
15314  return nullptr;
15315  }
15316  if (RelevantExpr)
15317  return nullptr;
15318  continue;
15319  }
15320 
15321  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
15322  // If the type of a list item is a reference to a type T then the type
15323  // will be considered to be T for all purposes of this clause.
15324  QualType CurType = BaseE->getType().getNonReferenceType();
15325 
15326  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
15327  // A list item cannot be a variable that is a member of a structure with
15328  // a union type.
15329  //
15330  if (CurType->isUnionType()) {
15331  if (!NoDiagnose) {
15332  SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
15333  << CurE->getSourceRange();
15334  return nullptr;
15335  }
15336  continue;
15337  }
15338 
15339  // If we got a member expression, we should not expect any array section
15340  // before that:
15341  //
15342  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
15343  // If a list item is an element of a structure, only the rightmost symbol
15344  // of the variable reference can be an array section.
15345  //
15346  AllowUnitySizeArraySection = false;
15347  AllowWholeSizeArraySection = false;
15348 
15349  // Record the component.
15350  CurComponents.emplace_back(CurE, FD);
15351  } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) {
15352  E = CurE->getBase()->IgnoreParenImpCasts();
15353 
15354  if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
15355  if (!NoDiagnose) {
15356  SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
15357  << 0 << CurE->getSourceRange();
15358  return nullptr;
15359  }
15360  continue;
15361  }
15362 
15363  // If we got an array subscript that express the whole dimension we
15364  // can have any array expressions before. If it only expressing part of
15365  // the dimension, we can only have unitary-size array expressions.
15367  E->getType()))
15368  AllowWholeSizeArraySection = false;
15369 
15370  if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
15372  if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) {
15373  if (!Result.Val.getInt().isNullValue()) {
15374  SemaRef.Diag(CurE->getIdx()->getExprLoc(),
15375  diag::err_omp_invalid_map_this_expr);
15376  SemaRef.Diag(CurE->getIdx()->getExprLoc(),
15377  diag::note_omp_invalid_subscript_on_this_ptr_map);
15378  }
15379  }
15380  RelevantExpr = TE;
15381  }
15382 
15383  // Record the component - we don't have any declaration associated.
15384  CurComponents.emplace_back(CurE, nullptr);
15385  } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) {
15386  assert(!NoDiagnose && "Array sections cannot be implicitly mapped.");
15387  E = CurE->getBase()->IgnoreParenImpCasts();
15388 
15389  QualType CurType =
15391 
15392  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
15393  // If the type of a list item is a reference to a type T then the type
15394  // will be considered to be T for all purposes of this clause.
15395  if (CurType->isReferenceType())
15396  CurType = CurType->getPointeeType();
15397 
15398  bool IsPointer = CurType->isAnyPointerType();
15399 
15400  if (!IsPointer && !CurType->isArrayType()) {
15401  SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
15402  << 0 << CurE->getSourceRange();
15403  return nullptr;
15404  }
15405 
15406  bool NotWhole =
15407  checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType);
15408  bool NotUnity =
15409  checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType);
15410 
15411  if (AllowWholeSizeArraySection) {
15412  // Any array section is currently allowed. Allowing a whole size array
15413  // section implies allowing a unity array section as well.
15414  //
15415  // If this array section refers to the whole dimension we can still
15416  // accept other array sections before this one, except if the base is a
15417  // pointer. Otherwise, only unitary sections are accepted.
15418  if (NotWhole || IsPointer)
15419  AllowWholeSizeArraySection = false;
15420  } else if (AllowUnitySizeArraySection && NotUnity) {
15421  // A unity or whole array section is not allowed and that is not
15422  // compatible with the properties of the current array section.
15423  SemaRef.Diag(
15424  ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
15425  << CurE->getSourceRange();
15426  return nullptr;
15427  }
15428 
15429  if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
15430  Expr::EvalResult ResultR;
15431  Expr::EvalResult ResultL;
15432  if (CurE->getLength()->EvaluateAsInt(ResultR,
15433  SemaRef.getASTContext())) {
15434  if (!ResultR.Val.getInt().isOneValue()) {
15435  SemaRef.Diag(CurE->getLength()->getExprLoc(),
15436  diag::err_omp_invalid_map_this_expr);
15437  SemaRef.Diag(CurE->getLength()->getExprLoc(),
15438  diag::note_omp_invalid_length_on_this_ptr_mapping);
15439  }
15440  }
15441  if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt(
15442  ResultL, SemaRef.getASTContext())) {
15443  if (!ResultL.Val.getInt().isNullValue()) {
15444  SemaRef.Diag(CurE->getLowerBound()->getExprLoc(),
15445  diag::err_omp_invalid_map_this_expr);
15446  SemaRef.Diag(CurE->getLowerBound()->getExprLoc(),
15447  diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
15448  }
15449  }
15450  RelevantExpr = TE;
15451  }
15452 
15453  // Record the component - we don't have any declaration associated.
15454  CurComponents.emplace_back(CurE, nullptr);
15455  } else {
15456  if (!NoDiagnose) {
15457  // If nothing else worked, this is not a valid map clause expression.
15458  SemaRef.Diag(
15459  ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
15460  << ERange;
15461  }
15462  return nullptr;
15463  }
15464  }
15465 
15466  return RelevantExpr;
15467 }
15468 
15469 // Return true if expression E associated with value VD has conflicts with other
15470 // map information.
15471 static bool checkMapConflicts(
15472  Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
15473  bool CurrentRegionOnly,
15475  OpenMPClauseKind CKind) {
15476  assert(VD && E);
15477  SourceLocation ELoc = E->getExprLoc();
15478  SourceRange ERange = E->getSourceRange();
15479 
15480  // In order to easily check the conflicts we need to match each component of
15481  // the expression under test with the components of the expressions that are
15482  // already in the stack.
15483 
15484  assert(!CurComponents.empty() && "Map clause expression with no components!");
15485  assert(CurComponents.back().getAssociatedDeclaration() == VD &&
15486  "Map clause expression with unexpected base!");
15487 
15488  // Variables to help detecting enclosing problems in data environment nests.
15489  bool IsEnclosedByDataEnvironmentExpr = false;
15490  const Expr *EnclosingExpr = nullptr;
15491 
15492  bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
15493  VD, CurrentRegionOnly,
15494  [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
15495  ERange, CKind, &EnclosingExpr,
15497  StackComponents,
15498  OpenMPClauseKind) {
15499  assert(!StackComponents.empty() &&
15500  "Map clause expression with no components!");
15501  assert(StackComponents.back().getAssociatedDeclaration() == VD &&
15502  "Map clause expression with unexpected base!");
15503  (void)VD;
15504 
15505  // The whole expression in the stack.
15506  const Expr *RE = StackComponents.front().getAssociatedExpression();
15507 
15508  // Expressions must start from the same base. Here we detect at which
15509  // point both expressions diverge from each other and see if we can
15510  // detect if the memory referred to both expressions is contiguous and
15511  // do not overlap.
15512  auto CI = CurComponents.rbegin();
15513  auto CE = CurComponents.rend();
15514  auto SI = StackComponents.rbegin();
15515  auto SE = StackComponents.rend();
15516  for (; CI != CE && SI != SE; ++CI, ++SI) {
15517 
15518  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
15519  // At most one list item can be an array item derived from a given
15520  // variable in map clauses of the same construct.
15521  if (CurrentRegionOnly &&
15522  (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
15523  isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) &&
15524  (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
15525  isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) {
15526  SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
15527  diag::err_omp_multiple_array_items_in_map_clause)
15528  << CI->getAssociatedExpression()->getSourceRange();
15529  SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
15530  diag::note_used_here)
15531  << SI->getAssociatedExpression()->getSourceRange();
15532  return true;
15533  }
15534 
15535  // Do both expressions have the same kind?
15536  if (CI->getAssociatedExpression()->getStmtClass() !=
15537  SI->getAssociatedExpression()->getStmtClass())
15538  break;
15539 
15540  // Are we dealing with different variables/fields?
15541  if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
15542  break;
15543  }
15544  // Check if the extra components of the expressions in the enclosing
15545  // data environment are redundant for the current base declaration.
15546  // If they are, the maps completely overlap, which is legal.
15547  for (; SI != SE; ++SI) {
15548  QualType Type;
15549  if (const auto *ASE =
15550  dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
15551  Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
15552  } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
15553  SI->getAssociatedExpression())) {
15554  const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
15555  Type =
15557  }
15558  if (Type.isNull() || Type->isAnyPointerType() ||
15560  SemaRef, SI->getAssociatedExpression(), Type))
15561  break;
15562  }
15563 
15564  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
15565  // List items of map clauses in the same construct must not share
15566  // original storage.
15567  //
15568  // If the expressions are exactly the same or one is a subset of the
15569  // other, it means they are sharing storage.
15570  if (CI == CE && SI == SE) {
15571  if (CurrentRegionOnly) {
15572  if (CKind == OMPC_map) {
15573  SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
15574  } else {
15575  assert(CKind == OMPC_to || CKind == OMPC_from);
15576  SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
15577  << ERange;
15578  }
15579  SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
15580  << RE->getSourceRange();
15581  return true;
15582  }
15583  // If we find the same expression in the enclosing data environment,
15584  // that is legal.
15585  IsEnclosedByDataEnvironmentExpr = true;
15586  return false;
15587  }
15588 
15589  QualType DerivedType =
15590  std::prev(CI)->getAssociatedDeclaration()->getType();
15591  SourceLocation DerivedLoc =
15592  std::prev(CI)->getAssociatedExpression()->getExprLoc();
15593 
15594  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
15595  // If the type of a list item is a reference to a type T then the type
15596  // will be considered to be T for all purposes of this clause.
15597  DerivedType = DerivedType.getNonReferenceType();
15598 
15599  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
15600  // A variable for which the type is pointer and an array section
15601  // derived from that variable must not appear as list items of map
15602  // clauses of the same construct.
15603  //
15604  // Also, cover one of the cases in:
15605  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
15606  // If any part of the original storage of a list item has corresponding
15607  // storage in the device data environment, all of the original storage
15608  // must have corresponding storage in the device data environment.
15609  //
15610  if (DerivedType->isAnyPointerType()) {
15611  if (CI == CE || SI == SE) {
15612  SemaRef.Diag(
15613  DerivedLoc,
15614  diag::err_omp_pointer_mapped_along_with_derived_section)
15615  << DerivedLoc;
15616  SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
15617  << RE->getSourceRange();
15618  return true;
15619  }
15620  if (CI->getAssociatedExpression()->getStmtClass() !=
15621  SI->getAssociatedExpression()->getStmtClass() ||
15622  CI->getAssociatedDeclaration()->getCanonicalDecl() ==
15623  SI->getAssociatedDeclaration()->getCanonicalDecl()) {
15624  assert(CI != CE && SI != SE);
15625  SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
15626  << DerivedLoc;
15627  SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
15628  << RE->getSourceRange();
15629  return true;
15630  }
15631  }
15632 
15633  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
15634  // List items of map clauses in the same construct must not share
15635  // original storage.
15636  //
15637  // An expression is a subset of the other.
15638  if (CurrentRegionOnly && (CI == CE || SI == SE)) {
15639  if (CKind == OMPC_map) {
15640  if (CI != CE || SI != SE) {
15641  // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
15642  // a pointer.
15643  auto Begin =
15644  CI != CE ? CurComponents.begin() : StackComponents.begin();
15645  auto End = CI != CE ? CurComponents.end() : StackComponents.end();
15646  auto It = Begin;
15647  while (It != End && !It->getAssociatedDeclaration())
15648  std::advance(It, 1);
15649  assert(It != End &&
15650  "Expected at least one component with the declaration.");
15651  if (It != Begin && It->getAssociatedDeclaration()
15652  ->getType()
15653  .getCanonicalType()
15654  ->isAnyPointerType()) {
15655  IsEnclosedByDataEnvironmentExpr = false;
15656  EnclosingExpr = nullptr;
15657  return false;
15658  }
15659  }
15660  SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
15661  } else {
15662  assert(CKind == OMPC_to || CKind == OMPC_from);
15663  SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
15664  << ERange;
15665  }
15666  SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
15667  << RE->getSourceRange();
15668  return true;
15669  }
15670 
15671  // The current expression uses the same base as other expression in the
15672  // data environment but does not contain it completely.
15673  if (!CurrentRegionOnly && SI != SE)
15674  EnclosingExpr = RE;
15675 
15676  // The current expression is a subset of the expression in the data
15677  // environment.
15678  IsEnclosedByDataEnvironmentExpr |=
15679  (!CurrentRegionOnly && CI != CE && SI == SE);
15680 
15681  return false;
15682  });
15683 
15684  if (CurrentRegionOnly)
15685  return FoundError;
15686 
15687  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
15688  // If any part of the original storage of a list item has corresponding
15689  // storage in the device data environment, all of the original storage must
15690  // have corresponding storage in the device data environment.
15691  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
15692  // If a list item is an element of a structure, and a different element of
15693  // the structure has a corresponding list item in the device data environment
15694  // prior to a task encountering the construct associated with the map clause,
15695  // then the list item must also have a corresponding list item in the device
15696  // data environment prior to the task encountering the construct.
15697  //
15698  if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
15699  SemaRef.Diag(ELoc,
15700  diag::err_omp_original_storage_is_shared_and_does_not_contain)
15701  << ERange;
15702  SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
15703  << EnclosingExpr->getSourceRange();
15704  return true;
15705  }
15706 
15707  return FoundError;
15708 }
15709 
15710 // Look up the user-defined mapper given the mapper name and mapped type, and
15711 // build a reference to it.
15713  CXXScopeSpec &MapperIdScopeSpec,
15714  const DeclarationNameInfo &MapperId,
15715  QualType Type,
15716  Expr *UnresolvedMapper) {
15717  if (MapperIdScopeSpec.isInvalid())
15718  return ExprError();
15719  // Get the actual type for the array type.
15720  if (Type->isArrayType()) {
15721  assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type");
15723  }
15724  // Find all user-defined mappers with the given MapperId.
15725  SmallVector<UnresolvedSet<8>, 4> Lookups;
15726  LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
15727  Lookup.suppressDiagnostics();
15728  if (S) {
15729  while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) {
15730  NamedDecl *D = Lookup.getRepresentativeDecl();
15731  while (S && !S->isDeclScope(D))
15732  S = S->getParent();
15733  if (S)
15734  S = S->getParent();
15735  Lookups.emplace_back();
15736  Lookups.back().append(Lookup.begin(), Lookup.end());
15737  Lookup.clear();
15738  }
15739  } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
15740  // Extract the user-defined mappers with the given MapperId.
15741  Lookups.push_back(UnresolvedSet<8>());
15742  for (NamedDecl *D : ULE->decls()) {
15743  auto *DMD = cast<OMPDeclareMapperDecl>(D);
15744  assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation.");
15745  Lookups.back().addDecl(DMD);
15746  }
15747  }
15748  // Defer the lookup for dependent types. The results will be passed through
15749  // UnresolvedMapper on instantiation.
15750  if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
15751  Type->isInstantiationDependentType() ||
15753  filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
15754  return !D->isInvalidDecl() &&
15755  (D->getType()->isDependentType() ||
15758  })) {
15759  UnresolvedSet<8> URS;
15760  for (const UnresolvedSet<8> &Set : Lookups) {
15761  if (Set.empty())
15762  continue;
15763  URS.append(Set.begin(), Set.end());
15764  }
15766  SemaRef.Context, /*NamingClass=*/nullptr,
15767  MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
15768  /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end());
15769  }
15770  SourceLocation Loc = MapperId.getLoc();
15771  // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
15772  // The type must be of struct, union or class type in C and C++
15773  if (!Type->isStructureOrClassType() && !Type->isUnionType() &&
15774  (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) {
15775  SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type);
15776  return ExprError();
15777  }
15778  // Perform argument dependent lookup.
15779  if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
15780  argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
15781  // Return the first user-defined mapper with the desired type.
15782  if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
15783  Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
15784  if (!D->isInvalidDecl() &&
15785  SemaRef.Context.hasSameType(D->getType(), Type))
15786  return D;
15787  return nullptr;
15788  }))
15789  return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
15790  // Find the first user-defined mapper with a type derived from the desired
15791  // type.
15792  if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
15793  Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
15794  if (!D->isInvalidDecl() &&
15795  SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
15796  !Type.isMoreQualifiedThan(D->getType()))
15797  return D;
15798  return nullptr;
15799  })) {
15800  CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
15801  /*DetectVirtual=*/false);
15802  if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
15803  if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
15804  VD->getType().getUnqualifiedType()))) {
15805  if (SemaRef.CheckBaseClassAccess(
15806  Loc, VD->getType(), Type, Paths.front(),
15807  /*DiagID=*/0) != Sema::AR_inaccessible) {
15808  return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
15809  }
15810  }
15811  }
15812  }
15813  // Report error if a mapper is specified, but cannot be found.
15814  if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
15815  SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
15816  << Type << MapperId.getName();
15817  return ExprError();
15818  }
15819  return ExprEmpty();
15820 }
15821 
15822 namespace {
15823 // Utility struct that gathers all the related lists associated with a mappable
15824 // expression.
15825 struct MappableVarListInfo {
15826  // The list of expressions.
15827  ArrayRef<Expr *> VarList;
15828  // The list of processed expressions.
15829  SmallVector<Expr *, 16> ProcessedVarList;
15830  // The mappble components for each expression.
15832  // The base declaration of the variable.
15833  SmallVector<ValueDecl *, 16> VarBaseDeclarations;
15834  // The reference to the user-defined mapper associated with every expression.
15835  SmallVector<Expr *, 16> UDMapperList;
15836 
15837  MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
15838  // We have a list of components and base declarations for each entry in the
15839  // variable list.
15840  VarComponents.reserve(VarList.size());
15841  VarBaseDeclarations.reserve(VarList.size());
15842  }
15843 };
15844 }
15845 
15846 // Check the validity of the provided variable list for the provided clause kind
15847 // \a CKind. In the check process the valid expressions, mappable expression
15848 // components, variables, and user-defined mappers are extracted and used to
15849 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
15850 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
15851 // and \a MapperId are expected to be valid if the clause kind is 'map'.
15853  Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
15854  MappableVarListInfo &MVLI, SourceLocation StartLoc,
15855  CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
15856  ArrayRef<Expr *> UnresolvedMappers,
15858  bool IsMapTypeImplicit = false) {
15859  // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
15860  assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
15861  "Unexpected clause kind with mappable expressions!");
15862 
15863  // If the identifier of user-defined mapper is not specified, it is "default".
15864  // We do not change the actual name in this clause to distinguish whether a
15865  // mapper is specified explicitly, i.e., it is not explicitly specified when
15866  // MapperId.getName() is empty.
15867  if (!MapperId.getName() || MapperId.getName().isEmpty()) {
15868  auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
15869  MapperId.setName(DeclNames.getIdentifier(
15870  &SemaRef.getASTContext().Idents.get("default")));
15871  }
15872 
15873  // Iterators to find the current unresolved mapper expression.
15874  auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
15875  bool UpdateUMIt = false;
15876  Expr *UnresolvedMapper = nullptr;
15877 
15878  // Keep track of the mappable components and base declarations in this clause.
15879  // Each entry in the list is going to have a list of components associated. We
15880  // record each set of the components so that we can build the clause later on.
15881  // In the end we should have the same amount of declarations and component
15882  // lists.
15883 
15884  for (Expr *RE : MVLI.VarList) {
15885  assert(RE && "Null expr in omp to/from/map clause");
15886  SourceLocation ELoc = RE->getExprLoc();
15887 
15888  // Find the current unresolved mapper expression.
15889  if (UpdateUMIt && UMIt != UMEnd) {
15890  UMIt++;
15891  assert(
15892  UMIt != UMEnd &&
15893  "Expect the size of UnresolvedMappers to match with that of VarList");
15894  }
15895  UpdateUMIt = true;
15896  if (UMIt != UMEnd)
15897  UnresolvedMapper = *UMIt;
15898 
15899  const Expr *VE = RE->IgnoreParenLValueCasts();
15900 
15901  if (VE->isValueDependent() || VE->isTypeDependent() ||
15902  VE->isInstantiationDependent() ||
15904  // Try to find the associated user-defined mapper.
15906  SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
15907  VE->getType().getCanonicalType(), UnresolvedMapper);
15908  if (ER.isInvalid())
15909  continue;
15910  MVLI.UDMapperList.push_back(ER.get());
15911  // We can only analyze this information once the missing information is
15912  // resolved.
15913  MVLI.ProcessedVarList.push_back(RE);
15914  continue;
15915  }
15916 
15917  Expr *SimpleExpr = RE->IgnoreParenCasts();
15918 
15919  if (!RE->IgnoreParenImpCasts()->isLValue()) {
15920  SemaRef.Diag(ELoc,
15921  diag::err_omp_expected_named_var_member_or_array_expression)
15922  << RE->getSourceRange();
15923  continue;
15924  }
15925 
15927  ValueDecl *CurDeclaration = nullptr;
15928 
15929  // Obtain the array or member expression bases if required. Also, fill the
15930  // components array with all the components identified in the process.
15931  const Expr *BE = checkMapClauseExpressionBase(
15932  SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false);
15933  if (!BE)
15934  continue;
15935 
15936  assert(!CurComponents.empty() &&
15937  "Invalid mappable expression information.");
15938 
15939  if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
15940  // Add store "this" pointer to class in DSAStackTy for future checking
15941  DSAS->addMappedClassesQualTypes(TE->getType());
15942  // Try to find the associated user-defined mapper.
15944  SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
15945  VE->getType().getCanonicalType(), UnresolvedMapper);
15946  if (ER.isInvalid())
15947  continue;
15948  MVLI.UDMapperList.push_back(ER.get());
15949  // Skip restriction checking for variable or field declarations
15950  MVLI.ProcessedVarList.push_back(RE);
15951  MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
15952  MVLI.VarComponents.back().append(CurComponents.begin(),
15953  CurComponents.end());
15954  MVLI.VarBaseDeclarations.push_back(nullptr);
15955  continue;
15956  }
15957 
15958  // For the following checks, we rely on the base declaration which is
15959  // expected to be associated with the last component. The declaration is
15960  // expected to be a variable or a field (if 'this' is being mapped).
15961  CurDeclaration = CurComponents.back().getAssociatedDeclaration();
15962  assert(CurDeclaration && "Null decl on map clause.");
15963  assert(
15964  CurDeclaration->isCanonicalDecl() &&
15965  "Expecting components to have associated only canonical declarations.");
15966 
15967  auto *VD = dyn_cast<VarDecl>(CurDeclaration);
15968  const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
15969 
15970  assert((VD || FD) && "Only variables or fields are expected here!");
15971  (void)FD;
15972 
15973  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
15974  // threadprivate variables cannot appear in a map clause.
15975  // OpenMP 4.5 [2.10.5, target update Construct]
15976  // threadprivate variables cannot appear in a from clause.
15977  if (VD && DSAS->isThreadPrivate(VD)) {
15978  DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
15979  SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
15980  << getOpenMPClauseName(CKind);
15981  reportOriginalDsa(SemaRef, DSAS, VD, DVar);
15982  continue;
15983  }
15984 
15985  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
15986  // A list item cannot appear in both a map clause and a data-sharing
15987  // attribute clause on the same construct.
15988 
15989  // Check conflicts with other map clause expressions. We check the conflicts
15990  // with the current construct separately from the enclosing data
15991  // environment, because the restrictions are different. We only have to
15992  // check conflicts across regions for the map clauses.
15993  if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
15994  /*CurrentRegionOnly=*/true, CurComponents, CKind))
15995  break;
15996  if (CKind == OMPC_map &&
15997  checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
15998  /*CurrentRegionOnly=*/false, CurComponents, CKind))
15999  break;
16000 
16001  // OpenMP 4.5 [2.10.5, target update Construct]
16002  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
16003  // If the type of a list item is a reference to a type T then the type will
16004  // be considered to be T for all purposes of this clause.
16005  auto I = llvm::find_if(
16006  CurComponents,
16008  return MC.getAssociatedDeclaration();
16009  });
16010  assert(I != CurComponents.end() && "Null decl on map clause.");
16011  QualType Type;
16012  auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens());
16013  auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens());
16014  if (ASE) {
16015  Type = ASE->getType().getNonReferenceType();
16016  } else if (OASE) {
16017  QualType BaseType =
16019  if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
16020  Type = ATy->getElementType();
16021  else
16022  Type = BaseType->getPointeeType();
16023  Type = Type.getNonReferenceType();
16024  } else {
16025  Type = VE->getType();
16026  }
16027 
16028  // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
16029  // A list item in a to or from clause must have a mappable type.
16030  // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
16031  // A list item must have a mappable type.
16032  if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
16033  DSAS, Type))
16034  continue;
16035 
16036  Type = I->getAssociatedDeclaration()->getType().getNonReferenceType();
16037 
16038  if (CKind == OMPC_map) {
16039  // target enter data
16040  // OpenMP [2.10.2, Restrictions, p. 99]
16041  // A map-type must be specified in all map clauses and must be either
16042  // to or alloc.
16043  OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
16044  if (DKind == OMPD_target_enter_data &&
16045  !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
16046  SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
16047  << (IsMapTypeImplicit ? 1 : 0)
16048  << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
16049  << getOpenMPDirectiveName(DKind);
16050  continue;
16051  }
16052 
16053  // target exit_data
16054  // OpenMP [2.10.3, Restrictions, p. 102]
16055  // A map-type must be specified in all map clauses and must be either
16056  // from, release, or delete.
16057  if (DKind == OMPD_target_exit_data &&
16058  !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
16059  MapType == OMPC_MAP_delete)) {
16060  SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
16061  << (IsMapTypeImplicit ? 1 : 0)
16062  << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
16063  << getOpenMPDirectiveName(DKind);
16064  continue;
16065  }
16066 
16067  // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
16068  // A list item cannot appear in both a map clause and a data-sharing
16069  // attribute clause on the same construct
16070  //
16071  // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
16072  // A list item cannot appear in both a map clause and a data-sharing
16073  // attribute clause on the same construct unless the construct is a
16074  // combined construct.
16075  if (VD && ((SemaRef.LangOpts.OpenMP <= 45 &&
16077  DKind == OMPD_target)) {
16078  DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
16079  if (isOpenMPPrivate(DVar.CKind)) {
16080  SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
16081  << getOpenMPClauseName(DVar.CKind)
16082  << getOpenMPClauseName(OMPC_map)
16083  << getOpenMPDirectiveName(DSAS->getCurrentDirective());
16084  reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
16085  continue;
16086  }
16087  }
16088  }
16089 
16090  // Try to find the associated user-defined mapper.
16092  SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
16093  Type.getCanonicalType(), UnresolvedMapper);
16094  if (ER.isInvalid())
16095  continue;
16096  MVLI.UDMapperList.push_back(ER.get());
16097 
16098  // Save the current expression.
16099  MVLI.ProcessedVarList.push_back(RE);
16100 
16101  // Store the components in the stack so that they can be used to check
16102  // against other clauses later on.
16103  DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
16104  /*WhereFoundClauseKind=*/OMPC_map);
16105 
16106  // Save the components and declaration to create the clause. For purposes of
16107  // the clause creation, any component list that has has base 'this' uses
16108  // null as base declaration.
16109  MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
16110  MVLI.VarComponents.back().append(CurComponents.begin(),
16111  CurComponents.end());
16112  MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
16113  : CurDeclaration);
16114  }
16115 }
16116 
16118  ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
16119  ArrayRef<SourceLocation> MapTypeModifiersLoc,
16120  CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
16121  OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
16123  const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
16126  OMPC_MAP_MODIFIER_unknown};
16128 
16129  // Process map-type-modifiers, flag errors for duplicate modifiers.
16130  unsigned Count = 0;
16131  for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
16132  if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
16133  llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) {
16134  Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
16135  continue;
16136  }
16137  assert(Count < OMPMapClause::NumberOfModifiers &&
16138  "Modifiers exceed the allowed number of map type modifiers");
16139  Modifiers[Count] = MapTypeModifiers[I];
16140  ModifiersLoc[Count] = MapTypeModifiersLoc[I];
16141  ++Count;
16142  }
16143 
16144  MappableVarListInfo MVLI(VarList);
16145  checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc,
16146  MapperIdScopeSpec, MapperId, UnresolvedMappers,
16147  MapType, IsMapTypeImplicit);
16148 
16149  // We need to produce a map clause even if we don't have variables so that
16150  // other diagnostics related with non-existing map clauses are accurate.
16151  return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList,
16152  MVLI.VarBaseDeclarations, MVLI.VarComponents,
16153  MVLI.UDMapperList, Modifiers, ModifiersLoc,
16154  MapperIdScopeSpec.getWithLocInContext(Context),
16155  MapperId, MapType, IsMapTypeImplicit, MapLoc);
16156 }
16157 
16160  assert(ParsedType.isUsable());
16161 
16162  QualType ReductionType = GetTypeFromParser(ParsedType.get());
16163  if (ReductionType.isNull())
16164  return QualType();
16165 
16166  // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
16167  // A type name in a declare reduction directive cannot be a function type, an
16168  // array type, a reference type, or a type qualified with const, volatile or
16169  // restrict.
16170  if (ReductionType.hasQualifiers()) {
16171  Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
16172  return QualType();
16173  }
16174 
16175  if (ReductionType->isFunctionType()) {
16176  Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
16177  return QualType();
16178  }
16179  if (ReductionType->isReferenceType()) {
16180  Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
16181  return QualType();
16182  }
16183  if (ReductionType->isArrayType()) {
16184  Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
16185  return QualType();
16186  }
16187  return ReductionType;
16188 }
16189 
16191  Scope *S, DeclContext *DC, DeclarationName Name,
16192  ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
16193  AccessSpecifier AS, Decl *PrevDeclInScope) {
16194  SmallVector<Decl *, 8> Decls;
16195  Decls.reserve(ReductionTypes.size());
16196 
16197  LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
16198  forRedeclarationInCurContext());
16199  // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
16200  // A reduction-identifier may not be re-declared in the current scope for the
16201  // same type or for a type that is compatible according to the base language
16202  // rules.
16203  llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
16204  OMPDeclareReductionDecl *PrevDRD = nullptr;
16205  bool InCompoundScope = true;
16206  if (S != nullptr) {
16207  // Find previous declaration with the same name not referenced in other
16208  // declarations.
16209  FunctionScopeInfo *ParentFn = getEnclosingFunction();
16210  InCompoundScope =
16211  (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
16212  LookupName(Lookup, S);
16213  FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
16214  /*AllowInlineNamespace=*/false);
16215  llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
16217  while (Filter.hasNext()) {
16218  auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
16219  if (InCompoundScope) {
16220  auto I = UsedAsPrevious.find(PrevDecl);
16221  if (I == UsedAsPrevious.end())
16222  UsedAsPrevious[PrevDecl] = false;
16223  if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
16224  UsedAsPrevious[D] = true;
16225  }
16226  PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
16227  PrevDecl->getLocation();
16228  }
16229  Filter.done();
16230  if (InCompoundScope) {
16231  for (const auto &PrevData : UsedAsPrevious) {
16232  if (!PrevData.second) {
16233  PrevDRD = PrevData.first;
16234  break;
16235  }
16236  }
16237  }
16238  } else if (PrevDeclInScope != nullptr) {
16239  auto *PrevDRDInScope = PrevDRD =
16240  cast<OMPDeclareReductionDecl>(PrevDeclInScope);
16241  do {
16242  PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
16243  PrevDRDInScope->getLocation();
16244  PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
16245  } while (PrevDRDInScope != nullptr);
16246  }
16247  for (const auto &TyData : ReductionTypes) {
16248  const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
16249  bool Invalid = false;
16250  if (I != PreviousRedeclTypes.end()) {
16251  Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
16252  << TyData.first;
16253  Diag(I->second, diag::note_previous_definition);
16254  Invalid = true;
16255  }
16256  PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
16257  auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
16258  Name, TyData.first, PrevDRD);
16259  DC->addDecl(DRD);
16260  DRD->setAccess(AS);
16261  Decls.push_back(DRD);
16262  if (Invalid)
16263  DRD->setInvalidDecl();
16264  else
16265  PrevDRD = DRD;
16266  }
16267 
16268  return DeclGroupPtrTy::make(
16269  DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
16270 }
16271 
16273  auto *DRD = cast<OMPDeclareReductionDecl>(D);
16274 
16275  // Enter new function scope.
16276  PushFunctionScope();
16277  setFunctionHasBranchProtectedScope();
16278  getCurFunction()->setHasOMPDeclareReductionCombiner();
16279 
16280  if (S != nullptr)
16281  PushDeclContext(S, DRD);
16282  else
16283  CurContext = DRD;
16284 
16285  PushExpressionEvaluationContext(
16286  ExpressionEvaluationContext::PotentiallyEvaluated);
16287 
16288  QualType ReductionType = DRD->getType();
16289  // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
16290  // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
16291  // uses semantics of argument handles by value, but it should be passed by
16292  // reference. C lang does not support references, so pass all parameters as
16293  // pointers.
16294  // Create 'T omp_in;' variable.
16295  VarDecl *OmpInParm =
16296  buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
16297  // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
16298  // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
16299  // uses semantics of argument handles by value, but it should be passed by
16300  // reference. C lang does not support references, so pass all parameters as
16301  // pointers.
16302  // Create 'T omp_out;' variable.
16303  VarDecl *OmpOutParm =
16304  buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
16305  if (S != nullptr) {
16306  PushOnScopeChains(OmpInParm, S);
16307  PushOnScopeChains(OmpOutParm, S);
16308  } else {
16309  DRD->addDecl(OmpInParm);
16310  DRD->addDecl(OmpOutParm);
16311  }
16312  Expr *InE =
16313  ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
16314  Expr *OutE =
16315  ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
16316  DRD->setCombinerData(InE, OutE);
16317 }
16318 
16320  auto *DRD = cast<OMPDeclareReductionDecl>(D);
16321  DiscardCleanupsInEvaluationContext();
16322  PopExpressionEvaluationContext();
16323 
16324  PopDeclContext();
16325  PopFunctionScopeInfo();
16326 
16327  if (Combiner != nullptr)
16328  DRD->setCombiner(Combiner);
16329  else
16330  DRD->setInvalidDecl();
16331 }
16332 
16334  auto *DRD = cast<OMPDeclareReductionDecl>(D);
16335 
16336  // Enter new function scope.
16337  PushFunctionScope();
16338  setFunctionHasBranchProtectedScope();
16339 
16340  if (S != nullptr)
16341  PushDeclContext(S, DRD);
16342  else
16343  CurContext = DRD;
16344 
16345  PushExpressionEvaluationContext(
16346  ExpressionEvaluationContext::PotentiallyEvaluated);
16347 
16348  QualType ReductionType = DRD->getType();
16349  // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
16350  // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
16351  // uses semantics of argument handles by value, but it should be passed by
16352  // reference. C lang does not support references, so pass all parameters as
16353  // pointers.
16354  // Create 'T omp_priv;' variable.
16355  VarDecl *OmpPrivParm =
16356  buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
16357  // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
16358  // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
16359  // uses semantics of argument handles by value, but it should be passed by
16360  // reference. C lang does not support references, so pass all parameters as
16361  // pointers.
16362  // Create 'T omp_orig;' variable.
16363  VarDecl *OmpOrigParm =
16364  buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
16365  if (S != nullptr) {
16366  PushOnScopeChains(OmpPrivParm, S);
16367  PushOnScopeChains(OmpOrigParm, S);
16368  } else {
16369  DRD->addDecl(OmpPrivParm);
16370  DRD->addDecl(OmpOrigParm);
16371  }
16372  Expr *OrigE =
16373  ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
16374  Expr *PrivE =
16375  ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
16376  DRD->setInitializerData(OrigE, PrivE);
16377  return OmpPrivParm;
16378 }
16379 
16381  VarDecl *OmpPrivParm) {
16382  auto *DRD = cast<OMPDeclareReductionDecl>(D);
16383  DiscardCleanupsInEvaluationContext();
16384  PopExpressionEvaluationContext();
16385 
16386  PopDeclContext();
16387  PopFunctionScopeInfo();
16388 
16389  if (Initializer != nullptr) {
16390  DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
16391  } else if (OmpPrivParm->hasInit()) {
16392  DRD->setInitializer(OmpPrivParm->getInit(),
16393  OmpPrivParm->isDirectInit()
16396  } else {
16397  DRD->setInvalidDecl();
16398  }
16399 }
16400 
16402  Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
16403  for (Decl *D : DeclReductions.get()) {
16404  if (IsValid) {
16405  if (S)
16406  PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
16407  /*AddToContext=*/false);
16408  } else {
16409  D->setInvalidDecl();
16410  }
16411  }
16412  return DeclReductions;
16413 }
16414 
16416  TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
16417  QualType T = TInfo->getType();
16418  if (D.isInvalidType())
16419  return true;
16420 
16421  if (getLangOpts().CPlusPlus) {
16422  // Check that there are no default arguments (C++ only).
16423  CheckExtraCXXDefaultArguments(D);
16424  }
16425 
16426  return CreateParsedType(T, TInfo);
16427 }
16428 
16431  assert(ParsedType.isUsable() && "Expect usable parsed mapper type");
16432 
16433  QualType MapperType = GetTypeFromParser(ParsedType.get());
16434  assert(!MapperType.isNull() && "Expect valid mapper type");
16435 
16436  // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
16437  // The type must be of struct, union or class type in C and C++
16438  if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
16439  Diag(TyLoc, diag::err_omp_mapper_wrong_type);
16440  return QualType();
16441  }
16442  return MapperType;
16443 }
16444 
16446  Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
16448  Decl *PrevDeclInScope) {
16449  LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
16450  forRedeclarationInCurContext());
16451  // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
16452  // A mapper-identifier may not be redeclared in the current scope for the
16453  // same type or for a type that is compatible according to the base language
16454  // rules.
16455  llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
16456  OMPDeclareMapperDecl *PrevDMD = nullptr;
16457  bool InCompoundScope = true;
16458  if (S != nullptr) {
16459  // Find previous declaration with the same name not referenced in other
16460  // declarations.
16461  FunctionScopeInfo *ParentFn = getEnclosingFunction();
16462  InCompoundScope =
16463  (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
16464  LookupName(Lookup, S);
16465  FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
16466  /*AllowInlineNamespace=*/false);
16467  llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
16469  while (Filter.hasNext()) {
16470  auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
16471  if (InCompoundScope) {
16472  auto I = UsedAsPrevious.find(PrevDecl);
16473  if (I == UsedAsPrevious.end())
16474  UsedAsPrevious[PrevDecl] = false;
16475  if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
16476  UsedAsPrevious[D] = true;
16477  }
16478  PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
16479  PrevDecl->getLocation();
16480  }
16481  Filter.done();
16482  if (InCompoundScope) {
16483  for (const auto &PrevData : UsedAsPrevious) {
16484  if (!PrevData.second) {
16485  PrevDMD = PrevData.first;
16486  break;
16487  }
16488  }
16489  }
16490  } else if (PrevDeclInScope) {
16491  auto *PrevDMDInScope = PrevDMD =
16492  cast<OMPDeclareMapperDecl>(PrevDeclInScope);
16493  do {
16494  PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
16495  PrevDMDInScope->getLocation();
16496  PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
16497  } while (PrevDMDInScope != nullptr);
16498  }
16499  const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
16500  bool Invalid = false;
16501  if (I != PreviousRedeclTypes.end()) {
16502  Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
16503  << MapperType << Name;
16504  Diag(I->second, diag::note_previous_definition);
16505  Invalid = true;
16506  }
16507  auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name,
16508  MapperType, VN, PrevDMD);
16509  DC->addDecl(DMD);
16510  DMD->setAccess(AS);
16511  if (Invalid)
16512  DMD->setInvalidDecl();
16513 
16514  // Enter new function scope.
16515  PushFunctionScope();
16516  setFunctionHasBranchProtectedScope();
16517 
16518  CurContext = DMD;
16519 
16520  return DMD;
16521 }
16522 
16524  Scope *S,
16525  QualType MapperType,
16526  SourceLocation StartLoc,
16527  DeclarationName VN) {
16528  VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString());
16529  if (S)
16530  PushOnScopeChains(VD, S);
16531  else
16532  DMD->addDecl(VD);
16533  Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
16534  DMD->setMapperVarRef(MapperVarRefExpr);
16535 }
16536 
16539  ArrayRef<OMPClause *> ClauseList) {
16540  PopDeclContext();
16541  PopFunctionScopeInfo();
16542 
16543  if (D) {
16544  if (S)
16545  PushOnScopeChains(D, S, /*AddToContext=*/false);
16546  D->CreateClauses(Context, ClauseList);
16547  }
16548 
16549  return DeclGroupPtrTy::make(DeclGroupRef(D));
16550 }
16551 
16553  SourceLocation StartLoc,
16554  SourceLocation LParenLoc,
16555  SourceLocation EndLoc) {
16556  Expr *ValExpr = NumTeams;
16557  Stmt *HelperValStmt = nullptr;
16558 
16559  // OpenMP [teams Constrcut, Restrictions]
16560  // The num_teams expression must evaluate to a positive integer value.
16561  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
16562  /*StrictlyPositive=*/true))
16563  return nullptr;
16564 
16565  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16566  OpenMPDirectiveKind CaptureRegion =
16567  getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP);
16568  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16569  ValExpr = MakeFullExpr(ValExpr).get();
16570  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16571  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16572  HelperValStmt = buildPreInits(Context, Captures);
16573  }
16574 
16575  return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
16576  StartLoc, LParenLoc, EndLoc);
16577 }
16578 
16580  SourceLocation StartLoc,
16581  SourceLocation LParenLoc,
16582  SourceLocation EndLoc) {
16583  Expr *ValExpr = ThreadLimit;
16584  Stmt *HelperValStmt = nullptr;
16585 
16586  // OpenMP [teams Constrcut, Restrictions]
16587  // The thread_limit expression must evaluate to a positive integer value.
16588  if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
16589  /*StrictlyPositive=*/true))
16590  return nullptr;
16591 
16592  OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16594  DKind, OMPC_thread_limit, LangOpts.OpenMP);
16595  if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16596  ValExpr = MakeFullExpr(ValExpr).get();
16597  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16598  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16599  HelperValStmt = buildPreInits(Context, Captures);
16600  }
16601 
16602  return new (Context) OMPThreadLimitClause(
16603  ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
16604 }
16605 
16607  SourceLocation StartLoc,
16608  SourceLocation LParenLoc,
16609  SourceLocation EndLoc) {
16610  Expr *ValExpr = Priority;
16611  Stmt *HelperValStmt = nullptr;
16612  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
16613 
16614  // OpenMP [2.9.1, task Constrcut]
16615  // The priority-value is a non-negative numerical scalar expression.
16617  ValExpr, *this, OMPC_priority,
16618  /*StrictlyPositive=*/false, /*BuildCapture=*/true,
16619  DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
16620  return nullptr;
16621 
16622  return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion,
16623  StartLoc, LParenLoc, EndLoc);
16624 }
16625 
16627  SourceLocation StartLoc,
16628  SourceLocation LParenLoc,
16629  SourceLocation EndLoc) {
16630  Expr *ValExpr = Grainsize;
16631  Stmt *HelperValStmt = nullptr;
16632  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
16633 
16634  // OpenMP [2.9.2, taskloop Constrcut]
16635  // The parameter of the grainsize clause must be a positive integer
16636  // expression.
16638  ValExpr, *this, OMPC_grainsize,
16639  /*StrictlyPositive=*/true, /*BuildCapture=*/true,
16640  DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
16641  return nullptr;
16642 
16643  return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion,
16644  StartLoc, LParenLoc, EndLoc);
16645 }
16646 
16648  SourceLocation StartLoc,
16649  SourceLocation LParenLoc,
16650  SourceLocation EndLoc) {
16651  Expr *ValExpr = NumTasks;
16652  Stmt *HelperValStmt = nullptr;
16653  OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
16654 
16655  // OpenMP [2.9.2, taskloop Constrcut]
16656  // The parameter of the num_tasks clause must be a positive integer
16657  // expression.
16659  ValExpr, *this, OMPC_num_tasks,
16660  /*StrictlyPositive=*/true, /*BuildCapture=*/true,
16661  DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
16662  return nullptr;
16663 
16664  return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion,
16665  StartLoc, LParenLoc, EndLoc);
16666 }
16667 
16669  SourceLocation LParenLoc,
16670  SourceLocation EndLoc) {
16671  // OpenMP [2.13.2, critical construct, Description]
16672  // ... where hint-expression is an integer constant expression that evaluates
16673  // to a valid lock hint.
16674  ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
16675  if (HintExpr.isInvalid())
16676  return nullptr;
16677  return new (Context)
16678  OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
16679 }
16680 
16682  OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
16683  SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
16684  SourceLocation EndLoc) {
16685  if (Kind == OMPC_DIST_SCHEDULE_unknown) {
16686  std::string Values;
16687  Values += "'";
16688  Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
16689  Values += "'";
16690  Diag(KindLoc, diag::err_omp_unexpected_clause_value)
16691  << Values << getOpenMPClauseName(OMPC_dist_schedule);
16692  return nullptr;
16693  }
16694  Expr *ValExpr = ChunkSize;
16695  Stmt *HelperValStmt = nullptr;
16696  if (ChunkSize) {
16697  if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
16698  !ChunkSize->isInstantiationDependent() &&
16699  !ChunkSize->containsUnexpandedParameterPack()) {
16700  SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
16701  ExprResult Val =
16702  PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
16703  if (Val.isInvalid())
16704  return nullptr;
16705 
16706  ValExpr = Val.get();
16707 
16708  // OpenMP [2.7.1, Restrictions]
16709  // chunk_size must be a loop invariant integer expression with a positive
16710  // value.
16712  if (ValExpr->isIntegerConstantExpr(Result, Context)) {
16713  if (Result.isSigned() && !Result.isStrictlyPositive()) {
16714  Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
16715  << "dist_schedule" << ChunkSize->getSourceRange();
16716  return nullptr;
16717  }
16719  DSAStack->getCurrentDirective(), OMPC_dist_schedule,
16720  LangOpts.OpenMP) != OMPD_unknown &&
16721  !CurContext->isDependentContext()) {
16722  ValExpr = MakeFullExpr(ValExpr).get();
16723  llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16724  ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16725  HelperValStmt = buildPreInits(Context, Captures);
16726  }
16727  }
16728  }
16729 
16730  return new (Context)
16731  OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
16732  Kind, ValExpr, HelperValStmt);
16733 }
16734 
16737  SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
16738  SourceLocation KindLoc, SourceLocation EndLoc) {
16739  if (getLangOpts().OpenMP < 50) {
16740  if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
16741  Kind != OMPC_DEFAULTMAP_scalar) {
16742  std::string Value;
16743  SourceLocation Loc;
16744  Value += "'";
16745  if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
16746  Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
16747  OMPC_DEFAULTMAP_MODIFIER_tofrom);
16748  Loc = MLoc;
16749  } else {
16750  Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
16751  OMPC_DEFAULTMAP_scalar);
16752  Loc = KindLoc;
16753  }
16754  Value += "'";
16755  Diag(Loc, diag::err_omp_unexpected_clause_value)
16756  << Value << getOpenMPClauseName(OMPC_defaultmap);
16757  return nullptr;
16758  }
16759  } else {
16760  bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown);
16761  bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown);
16762  if (!isDefaultmapKind || !isDefaultmapModifier) {
16763  std::string ModifierValue = "'alloc', 'from', 'to', 'tofrom', "
16764  "'firstprivate', 'none', 'default'";
16765  std::string KindValue = "'scalar', 'aggregate', 'pointer'";
16766  if (!isDefaultmapKind && isDefaultmapModifier) {
16767  Diag(KindLoc, diag::err_omp_unexpected_clause_value)
16768  << KindValue << getOpenMPClauseName(OMPC_defaultmap);
16769  } else if (isDefaultmapKind && !isDefaultmapModifier) {
16770  Diag(MLoc, diag::err_omp_unexpected_clause_value)
16771  << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
16772  } else {
16773  Diag(MLoc, diag::err_omp_unexpected_clause_value)
16774  << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
16775  Diag(KindLoc, diag::err_omp_unexpected_clause_value)
16776  << KindValue << getOpenMPClauseName(OMPC_defaultmap);
16777  }
16778  return nullptr;
16779  }
16780 
16781  // OpenMP [5.0, 2.12.5, Restrictions, p. 174]
16782  // At most one defaultmap clause for each category can appear on the
16783  // directive.
16784  if (DSAStack->checkDefaultmapCategory(Kind)) {
16785  Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
16786  return nullptr;
16787  }
16788  }
16789  DSAStack->setDefaultDMAAttr(M, Kind, StartLoc);
16790 
16791  return new (Context)
16792  OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
16793 }
16794 
16796  DeclContext *CurLexicalContext = getCurLexicalContext();
16797  if (!CurLexicalContext->isFileContext() &&
16798  !CurLexicalContext->isExternCContext() &&
16799  !CurLexicalContext->isExternCXXContext() &&
16800  !isa<CXXRecordDecl>(CurLexicalContext) &&
16801  !isa<ClassTemplateDecl>(CurLexicalContext) &&
16802  !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
16803  !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
16804  Diag(Loc, diag::err_omp_region_not_file_context);
16805  return false;
16806  }
16807  ++DeclareTargetNestingLevel;
16808  return true;
16809 }
16810 
16812  assert(DeclareTargetNestingLevel > 0 &&
16813  "Unexpected ActOnFinishOpenMPDeclareTargetDirective");
16814  --DeclareTargetNestingLevel;
16815 }
16816 
16817 NamedDecl *
16819  const DeclarationNameInfo &Id,
16820  NamedDeclSetType &SameDirectiveDecls) {
16821  LookupResult Lookup(*this, Id, LookupOrdinaryName);
16822  LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
16823 
16824  if (Lookup.isAmbiguous())
16825  return nullptr;
16826  Lookup.suppressDiagnostics();
16827 
16828  if (!Lookup.isSingleResult()) {
16829  VarOrFuncDeclFilterCCC CCC(*this);
16830  if (TypoCorrection Corrected =
16831  CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
16832  CTK_ErrorRecovery)) {
16833  diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
16834  << Id.getName());
16835  checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
16836  return nullptr;
16837  }
16838 
16839  Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
16840  return nullptr;
16841  }
16842 
16843  NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
16844  if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
16845  !isa<FunctionTemplateDecl>(ND)) {
16846  Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
16847  return nullptr;
16848  }
16849  if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl())))
16850  Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName();
16851  return ND;
16852 }
16853 
16855  NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT,
16856  OMPDeclareTargetDeclAttr::DevTypeTy DT) {
16857  assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
16858  isa<FunctionTemplateDecl>(ND)) &&
16859  "Expected variable, function or function template.");
16860 
16861  // Diagnose marking after use as it may lead to incorrect diagnosis and
16862  // codegen.
16863  if (LangOpts.OpenMP >= 50 &&
16864  (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced()))
16865  Diag(Loc, diag::warn_omp_declare_target_after_first_use);
16866 
16868  OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND));
16869  if (DevTy.hasValue() && *DevTy != DT) {
16870  Diag(Loc, diag::err_omp_device_type_mismatch)
16871  << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT)
16872  << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy);
16873  return;
16874  }
16876  OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND));
16877  if (!Res) {
16878  auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT,
16879  SourceRange(Loc, Loc));
16880  ND->addAttr(A);
16881  if (ASTMutationListener *ML = Context.getASTMutationListener())
16882  ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
16883  checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc);
16884  } else if (*Res != MT) {
16885  Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
16886  }
16887 }
16888 
16890  Sema &SemaRef, Decl *D) {
16891  if (!D || !isa<VarDecl>(D))
16892  return;
16893  auto *VD = cast<VarDecl>(D);
16895  OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
16896  if (SemaRef.LangOpts.OpenMP >= 50 &&
16897  (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) ||
16898  SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) &&
16899  VD->hasGlobalStorage()) {
16901  OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
16902  if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) {
16903  // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
16904  // If a lambda declaration and definition appears between a
16905  // declare target directive and the matching end declare target
16906  // directive, all variables that are captured by the lambda
16907  // expression must also appear in a to clause.
16908  SemaRef.Diag(VD->getLocation(),
16909  diag::err_omp_lambda_capture_in_declare_target_not_to);
16910  SemaRef.Diag(SL, diag::note_var_explicitly_captured_here)
16911  << VD << 0 << SR;
16912  return;
16913  }
16914  }
16915  if (MapTy.hasValue())
16916  return;
16917  SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
16918  SemaRef.Diag(SL, diag::note_used_here) << SR;
16919 }
16920 
16922  Sema &SemaRef, DSAStackTy *Stack,
16923  ValueDecl *VD) {
16924  return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
16925  checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
16926  /*FullCheck=*/false);
16927 }
16928 
16930  SourceLocation IdLoc) {
16931  if (!D || D->isInvalidDecl())
16932  return;
16933  SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
16934  SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
16935  if (auto *VD = dyn_cast<VarDecl>(D)) {
16936  // Only global variables can be marked as declare target.
16937  if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
16938  !VD->isStaticDataMember())
16939  return;
16940  // 2.10.6: threadprivate variable cannot appear in a declare target
16941  // directive.
16942  if (DSAStack->isThreadPrivate(VD)) {
16943  Diag(SL, diag::err_omp_threadprivate_in_target);
16944  reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false));
16945  return;
16946  }
16947  }
16948  if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
16949  D = FTD->getTemplatedDecl();
16950  if (auto *FD = dyn_cast<FunctionDecl>(D)) {
16952  OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
16953  if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
16954  Diag(IdLoc, diag::err_omp_function_in_link_clause);
16955  Diag(FD->getLocation(), diag::note_defined_here) << FD;
16956  return;
16957  }
16958  // Mark the function as must be emitted for the device.
16960  OMPDeclareTargetDeclAttr::getDeviceType(FD);
16961  if (LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() &&
16962  *DevTy != OMPDeclareTargetDeclAttr::DT_Host)
16963  checkOpenMPDeviceFunction(IdLoc, FD, /*CheckForDelayedContext=*/false);
16964  if (!LangOpts.OpenMPIsDevice && Res.hasValue() && IdLoc.isValid() &&
16965  *DevTy != OMPDeclareTargetDeclAttr::DT_NoHost)
16966  checkOpenMPHostFunction(IdLoc, FD, /*CheckCaller=*/false);
16967  }
16968  if (auto *VD = dyn_cast<ValueDecl>(D)) {
16969  // Problem if any with var declared with incomplete type will be reported
16970  // as normal, so no need to check it here.
16971  if ((E || !VD->getType()->isIncompleteType()) &&
16972  !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD))
16973  return;
16974  if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) {
16975  // Checking declaration inside declare target region.
16976  if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
16977  isa<FunctionTemplateDecl>(D)) {
16978  auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
16979  Context, OMPDeclareTargetDeclAttr::MT_To,
16980  OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc));
16981  D->addAttr(A);
16982  if (ASTMutationListener *ML = Context.getASTMutationListener())
16983  ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
16984  }
16985  return;
16986  }
16987  }
16988  if (!E)
16989  return;
16990  checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
16991 }
16992 
16994  CXXScopeSpec &MapperIdScopeSpec,
16995  DeclarationNameInfo &MapperId,
16996  const OMPVarListLocTy &Locs,
16997  ArrayRef<Expr *> UnresolvedMappers) {
16998  MappableVarListInfo MVLI(VarList);
16999  checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc,
17000  MapperIdScopeSpec, MapperId, UnresolvedMappers);
17001  if (MVLI.ProcessedVarList.empty())
17002  return nullptr;
17003 
17004  return OMPToClause::Create(
17005  Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
17006  MVLI.VarComponents, MVLI.UDMapperList,
17007  MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
17008 }
17009 
17011  CXXScopeSpec &MapperIdScopeSpec,
17012  DeclarationNameInfo &MapperId,
17013  const OMPVarListLocTy &Locs,
17014  ArrayRef<Expr *> UnresolvedMappers) {
17015  MappableVarListInfo MVLI(VarList);
17016  checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc,
17017  MapperIdScopeSpec, MapperId, UnresolvedMappers);
17018  if (MVLI.ProcessedVarList.empty())
17019  return nullptr;
17020 
17021  return OMPFromClause::Create(
17022  Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
17023  MVLI.VarComponents, MVLI.UDMapperList,
17024  MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
17025 }
17026 
17028  const OMPVarListLocTy &Locs) {
17029  MappableVarListInfo MVLI(VarList);
17030  SmallVector<Expr *, 8> PrivateCopies;
17032 
17033  for (Expr *RefExpr : VarList) {
17034  assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
17035  SourceLocation ELoc;
17036  SourceRange ERange;
17037  Expr *SimpleRefExpr = RefExpr;
17038  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17039  if (Res.second) {
17040  // It will be analyzed later.
17041  MVLI.ProcessedVarList.push_back(RefExpr);
17042  PrivateCopies.push_back(nullptr);
17043  Inits.push_back(nullptr);
17044  }
17045  ValueDecl *D = Res.first;
17046  if (!D)
17047  continue;
17048 
17049  QualType Type = D->getType();
17050  Type = Type.getNonReferenceType().getUnqualifiedType();
17051 
17052  auto *VD = dyn_cast<VarDecl>(D);
17053 
17054  // Item should be a pointer or reference to pointer.
17055  if (!Type->isPointerType()) {
17056  Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
17057  << 0 << RefExpr->getSourceRange();
17058  continue;
17059  }
17060 
17061  // Build the private variable and the expression that refers to it.
17062  auto VDPrivate =
17063  buildVarDecl(*this, ELoc, Type, D->getName(),
17064  D->hasAttrs() ? &D->getAttrs() : nullptr,
17065  VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
17066  if (VDPrivate->isInvalidDecl())
17067  continue;
17068 
17069  CurContext->addDecl(VDPrivate);
17070  DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
17071  *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
17072 
17073  // Add temporary variable to initialize the private copy of the pointer.
17074  VarDecl *VDInit =
17075  buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
17076  DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
17077  *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
17078  AddInitializerToDecl(VDPrivate,
17079  DefaultLvalueConversion(VDInitRefExpr).get(),
17080  /*DirectInit=*/false);
17081 
17082  // If required, build a capture to implement the privatization initialized
17083  // with the current list item value.
17084  DeclRefExpr *Ref = nullptr;
17085  if (!VD)
17086  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
17087  MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
17088  PrivateCopies.push_back(VDPrivateRefExpr);
17089  Inits.push_back(VDInitRefExpr);
17090 
17091  // We need to add a data sharing attribute for this variable to make sure it
17092  // is correctly captured. A variable that shows up in a use_device_ptr has
17093  // similar properties of a first private variable.
17094  DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
17095 
17096  // Create a mappable component for the list item. List items in this clause
17097  // only need a component.
17098  MVLI.VarBaseDeclarations.push_back(D);
17099  MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
17100  MVLI.VarComponents.back().push_back(
17102  }
17103 
17104  if (MVLI.ProcessedVarList.empty())
17105  return nullptr;
17106 
17108  Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
17109  MVLI.VarBaseDeclarations, MVLI.VarComponents);
17110 }
17111 
17113  const OMPVarListLocTy &Locs) {
17114  MappableVarListInfo MVLI(VarList);
17115  for (Expr *RefExpr : VarList) {
17116  assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
17117  SourceLocation ELoc;
17118  SourceRange ERange;
17119  Expr *SimpleRefExpr = RefExpr;
17120  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17121  if (Res.second) {
17122  // It will be analyzed later.
17123  MVLI.ProcessedVarList.push_back(RefExpr);
17124  }
17125  ValueDecl *D = Res.first;
17126  if (!D)
17127  continue;
17128 
17129  QualType Type = D->getType();
17130  // item should be a pointer or array or reference to pointer or array
17131  if (!Type.getNonReferenceType()->isPointerType() &&
17132  !Type.getNonReferenceType()->isArrayType()) {
17133  Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
17134  << 0 << RefExpr->getSourceRange();
17135  continue;
17136  }
17137 
17138  // Check if the declaration in the clause does not show up in any data
17139  // sharing attribute.
17140  DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
17141  if (isOpenMPPrivate(DVar.CKind)) {
17142  Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
17143  << getOpenMPClauseName(DVar.CKind)
17144  << getOpenMPClauseName(OMPC_is_device_ptr)
17145  << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
17146  reportOriginalDsa(*this, DSAStack, D, DVar);
17147  continue;
17148  }
17149 
17150  const Expr *ConflictExpr;
17151  if (DSAStack->checkMappableExprComponentListsForDecl(
17152  D, /*CurrentRegionOnly=*/true,
17153  [&ConflictExpr](
17155  OpenMPClauseKind) -> bool {
17156  ConflictExpr = R.front().getAssociatedExpression();
17157  return true;
17158  })) {
17159  Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
17160  Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
17161  << ConflictExpr->getSourceRange();
17162  continue;
17163  }
17164 
17165  // Store the components in the stack so that they can be used to check
17166  // against other clauses later on.
17168  DSAStack->addMappableExpressionComponents(
17169  D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
17170 
17171  // Record the expression we've just processed.
17172  MVLI.ProcessedVarList.push_back(SimpleRefExpr);
17173 
17174  // Create a mappable component for the list item. List items in this clause
17175  // only need a component. We use a null declaration to signal fields in
17176  // 'this'.
17177  assert((isa<DeclRefExpr>(SimpleRefExpr) ||
17178  isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
17179  "Unexpected device pointer expression!");
17180  MVLI.VarBaseDeclarations.push_back(
17181  isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
17182  MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
17183  MVLI.VarComponents.back().push_back(MC);
17184  }
17185 
17186  if (MVLI.ProcessedVarList.empty())
17187  return nullptr;
17188 
17189  return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
17190  MVLI.VarBaseDeclarations,
17191  MVLI.VarComponents);
17192 }
17193 
17195  Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
17197  if (Allocator) {
17198  // OpenMP [2.11.4 allocate Clause, Description]
17199  // allocator is an expression of omp_allocator_handle_t type.
17200  if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack))
17201  return nullptr;
17202 
17203  ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
17204  if (AllocatorRes.isInvalid())
17205  return nullptr;
17206  AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
17207  DSAStack->getOMPAllocatorHandleT(),
17209  /*AllowExplicit=*/true);
17210  if (AllocatorRes.isInvalid())
17211  return nullptr;
17212  Allocator = AllocatorRes.get();
17213  } else {
17214  // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
17215  // allocate clauses that appear on a target construct or on constructs in a
17216  // target region must specify an allocator expression unless a requires
17217  // directive with the dynamic_allocators clause is present in the same
17218  // compilation unit.
17219  if (LangOpts.OpenMPIsDevice &&
17220  !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
17221  targetDiag(StartLoc, diag::err_expected_allocator_expression);
17222  }
17223  // Analyze and build list of variables.
17225  for (Expr *RefExpr : VarList) {
17226  assert(RefExpr && "NULL expr in OpenMP private clause.");
17227  SourceLocation ELoc;
17228  SourceRange ERange;
17229  Expr *SimpleRefExpr = RefExpr;
17230  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17231  if (Res.second) {
17232  // It will be analyzed later.
17233  Vars.push_back(RefExpr);
17234  }
17235  ValueDecl *D = Res.first;
17236  if (!D)
17237  continue;
17238 
17239  auto *VD = dyn_cast<VarDecl>(D);
17240  DeclRefExpr *Ref = nullptr;
17241  if (!VD && !CurContext->isDependentContext())
17242  Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
17243  Vars.push_back((VD || CurContext->isDependentContext())
17244  ? RefExpr->IgnoreParens()
17245  : Ref);
17246  }
17247 
17248  if (Vars.empty())
17249  return nullptr;
17250 
17251  return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
17252  ColonLoc, EndLoc, Vars);
17253 }
17254 
17256  SourceLocation StartLoc,
17257  SourceLocation LParenLoc,
17258  SourceLocation EndLoc) {
17260  for (Expr *RefExpr : VarList) {
17261  assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
17262  SourceLocation ELoc;
17263  SourceRange ERange;
17264  Expr *SimpleRefExpr = RefExpr;
17265  auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17266  if (Res.second)
17267  // It will be analyzed later.
17268  Vars.push_back(RefExpr);
17269  ValueDecl *D = Res.first;
17270  if (!D)
17271  continue;
17272 
17273  // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions.
17274  // A list-item cannot appear in more than one nontemporal clause.
17275  if (const Expr *PrevRef =
17276  DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) {
17277  Diag(ELoc, diag::err_omp_used_in_clause_twice)
17278  << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
17279  Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
17280  << getOpenMPClauseName(OMPC_nontemporal);
17281  continue;
17282  }
17283 
17284  Vars.push_back(RefExpr);
17285  }
17286 
17287  if (Vars.empty())
17288  return nullptr;
17289 
17290  return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc,
17291  Vars);
17292 }
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:804
SourceLocation getLoc() const
getLoc - Returns the main location of the declaration name.
Defines the clang::ASTContext interface.
void setIsOMPStructuredBlock(bool IsOMPStructuredBlock)
Definition: Stmt.h:1116
static OMPToClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr *> Vars, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists, ArrayRef< Expr *> UDMapperRefs, NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId)
Creates clause with a list of variables Vars.
SmallVector< Expr *, 4 > Finals
Final loop counter values for GodeGen.
Definition: StmtOpenMP.h:832
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Expr.cpp:601
void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex)
Definition: Decl.h:1628
Expr * NUB
Update of UpperBound for statically scheduled omp loops for outer loop in combined constructs (e...
Definition: StmtOpenMP.h:764
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:830
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.
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:559
Represents a function declaration or definition.
Definition: Decl.h:1783
OMPClause * ActOnOpenMPSimdlenClause(Expr *Length, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;simdlen&#39; clause.
This represents &#39;thread_limit&#39; clause in the &#39;#pragma omp ...&#39; directive.
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
StmtResult ActOnOpenMPSectionDirective(Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp section&#39; after parsing of the associated statement.
OMPClause * ActOnOpenMPTaskReductionClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, ArrayRef< Expr *> UnresolvedReductions=llvm::None)
Called on well-formed &#39;task_reduction&#39; clause.
static OMPDistributeParallelForDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, unsigned CollapsedNum, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, const HelperExprs &Exprs, bool HasCancel)
Creates directive with a list of Clauses.
OMPDeclareMapperDecl * ActOnOpenMPDeclareMapperDirectiveStart(Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, Decl *PrevDeclInScope=nullptr)
Called on start of &#39;#pragma omp declare mapper&#39;.
PtrTy get() const
Definition: Ownership.h:80
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T -> getSizeExpr()))
QualType mergeFunctionTypes(QualType, QualType, bool OfBlockPointer=false, bool Unqualified=false)
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;.
Struct to store the context selectors info.
Definition: OpenMPKinds.h:43
A (possibly-)qualified type.
Definition: Type.h:654
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:788
StmtResult ActOnOpenMPParallelMasterTaskLoopSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp parallel master taskloop simd&#39; after parsing of the associated sta...
bool isArrayType() const
Definition: Type.h:6570
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
Definition: Expr.h:2919
ArrayRef< OMPClause * > clauses()
Definition: StmtOpenMP.h:325
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:3571
SourceLocation getExprLoc() const
Definition: Expr.h:3465
ExprResult ActOnConditionalOp(SourceLocation QuestionLoc, SourceLocation ColonLoc, Expr *CondExpr, Expr *LHSExpr, Expr *RHSExpr)
ActOnConditionalOp - Parse a ?: operation.
Definition: SemaExpr.cpp:7912
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:3445
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.
static bool isOpenMPDeviceDelayedContext(Sema &S)
static OMPParallelMasterTaskLoopDirective * 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.
OpenMPDefaultmapClauseKind
OpenMP attributes for &#39;defaultmap&#39; clause.
Definition: OpenMPKinds.h:158
This represents &#39;atomic_default_mem_order&#39; clause in the &#39;#pragma omp requires&#39; directive.
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.
FunctionEmissionStatus getEmissionStatus(FunctionDecl *Decl)
Definition: SemaDecl.cpp:17810
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:988
static bool checkPreviousOMPAllocateAttribute(Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator)
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.
static OMPClauseWithPreInit * get(OMPClause *C)
Stmt - This represents one statement.
Definition: Stmt.h:66
bool isStandaloneDirective() const
Returns whether or not this is a Standalone directive.
Definition: StmtOpenMP.cpp:26
Filter makeFilter()
Create a filter for this result set.
Definition: Lookup.h:682
static OMPTaskgroupDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt, Expr *ReductionRef)
Creates directive.
Definition: StmtOpenMP.cpp:670
FullExprArg MakeFullExpr(Expr *Arg)
Definition: Sema.h:4088
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:557
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Definition: TargetInfo.h:994
Class that handles pre-initialization statement for some clauses, like &#39;shedule&#39;, &#39;firstprivate&#39; etc...
Definition: OpenMPClause.h:108
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.
bool isRealFloatingType() const
Floating point categories.
Definition: Type.cpp:2021
Optional< std::pair< FunctionDecl *, Expr * > > checkOpenMPDeclareVariantFunction(DeclGroupPtrTy DG, Expr *VariantRef, SourceRange SR)
Checks &#39;#pragma omp declare variant&#39; variant function and original functions after parsing of the ass...
static OMPAllocateDeclAttr::AllocatorTypeTy getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator)
void addConst()
Add the const type qualifier to this QualType.
Definition: Type.h:823
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:802
StmtResult ActOnOpenMPMasterTaskLoopSimdDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp master taskloop simd&#39; after parsing of the associated statement...
bool isRecordType() const
Definition: Type.h:6594
Expr * DistInc
DistInc - increment expression for distribute loop when found combined with a further loop level (e...
Definition: StmtOpenMP.h:816
Expr * getBase() const
Definition: Expr.h:2913
static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, ArrayRef< OMPClause *> Clauses)
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:1411
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:88
specific_attr_iterator - Iterates over a subrange of an AttrVec, only providing attributes that are o...
Definition: AttrIterator.h:34
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:361
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:2194
static Expr * getOrderedNumberExpr(ArrayRef< OMPClause *> Clauses)
This represents &#39;if&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:425
OMPClause * ActOnOpenMPThreadsClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;threads&#39; clause.
Opcode getOpcode() const
Definition: Expr.h:3469
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...
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
Definition: Sema.h:906
CapturedStmt * getInnermostCapturedStmt()
Get innermost captured statement for the construct.
Definition: StmtOpenMP.h:283
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:6452
This represents &#39;priority&#39; clause in the &#39;#pragma omp ...&#39; directive.
static bool classof(const OMPClause *T)
Definition: OpenMPClause.h:413
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:1450
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:144
void ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, Scope *S, QualType MapperType, SourceLocation StartLoc, DeclarationName VN)
Build the mapper variable of &#39;#pragma omp declare mapper&#39;.
SourceLocation getEndLoc() const LLVM_READONLY
QualType withConst() const
Definition: Type.h:826
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:707
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
Definition: Specifiers.h:113
static OMPMasterTaskLoopDirective * 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.
A container of type source information.
Definition: Type.h:6227
This represents &#39;update&#39; clause in the &#39;#pragma omp atomic&#39; directive.
Wrapper for void* pointer.
Definition: Ownership.h:50
llvm::DenseMap< Stmt *, Stmt * > MapTy
Definition: ParentMap.cpp:22
bool isEmpty() const
Evaluates true when this declaration name is empty.
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.
static DeclRefExpr * buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, bool WithInit)
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:1295
bool hasNext() const
Definition: Lookup.h:639
Describes the capture of a variable or of this, or of a C++1y init-capture.
Definition: LambdaCapture.h:25
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:2383
LLVM_ATTRIBUTE_REINITIALIZES void clear()
Clears out any current state.
Definition: Lookup.h:554
OpenMPDefaultmapClauseModifier
OpenMP modifiers for &#39;defaultmap&#39; clause.
Definition: OpenMPKinds.h:166
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:934
QualType getElementType() const
Definition: Type.h:2910
OMPClause * ActOnOpenMPVarListClause(OpenMPClauseKind Kind, ArrayRef< Expr *> Vars, Expr *TailExpr, const OMPVarListLocTy &Locs, SourceLocation ColonLoc, CXXScopeSpec &ReductionOrMapperIdScopeSpec, DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, ArrayRef< OpenMPMapModifierKind > MapTypeModifiers, ArrayRef< SourceLocation > MapTypeModifiersLoc, bool IsMapTypeImplicit, SourceLocation DepLinMapLastLoc)
bool capturesVariable(const VarDecl *Var) const
True if this variable has been captured.
Definition: Stmt.cpp:1322
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...
Expr * PrevLB
PreviousLowerBound - local variable passed to runtime in the enclosing schedule or null if that does ...
Definition: StmtOpenMP.h:809
Retains information about a function, method, or block that is currently being parsed.
Definition: ScopeInfo.h:98
void setNothrow(bool Nothrow=true)
Definition: Decl.cpp:4752
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.
static OMPUseDevicePtrClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr *> Vars, ArrayRef< Expr *> PrivateVars, ArrayRef< Expr *> Inits, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
Represents a variable declaration or definition.
Definition: Decl.h:820
ActionResult< Stmt * > StmtResult
Definition: Ownership.h:264
static bool checkOpenMPIterationSpace(OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, llvm::MutableArrayRef< LoopIterationSpace > ResultIterSpaces, llvm::MapVector< const Expr *, DeclRefExpr *> &Captures)
Called on a for stmt to check and extract its iteration space for further processing (such as collaps...
Information about one declarator, including the parsed type information and the identifier.
Definition: DeclSpec.h:1792
This represents &#39;num_threads&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:594
bool isEnumeralType() const
Definition: Type.h:6598
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:7002
bool isOverloadableType() const
Determines whether this is a type for which one can define an overloaded operator.
Definition: Type.h:6907
varlist_range varlists()
Definition: OpenMPClause.h:232
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
Definition: Sema.h:2487
Extra information about a function prototype.
Definition: Type.h:3837
static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, QualType NewType)
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:1142
ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue)
Definition: Sema.h:5849
bool isAmbiguous() const
Definition: Lookup.h:301
QualType getMemberPointerType(QualType T, const Type *Cls) const
Return the uniqued reference to the type for a member pointer to the specified type in the specified ...
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:553
void setBegin(SourceLocation b)
Not a TLS variable.
Definition: Decl.h:837
static const Expr * getExprAsWritten(const Expr *E)
Definition: SemaOpenMP.cpp:915
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)
static OpenMPDefaultmapClauseKind getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD)
bool hasDefinition() const
Definition: DeclCXX.h:540
This represents &#39;reverse_offload&#39; clause in the &#39;#pragma omp requires&#39; directive. ...
Represents a parameter to a function.
Definition: Decl.h:1595
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.
bool isUnset() const
Definition: Ownership.h:168
This represents &#39;nogroup&#39; clause in the &#39;#pragma omp ...&#39; directive.
This represents &#39;allocator&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:266
static OMPMasterTaskLoopSimdDirective * 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.
This represents &#39;safelen&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:670
Expr * LastIteration
Loop last iteration number.
Definition: StmtOpenMP.h:780
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:244
void ActOnUninitializedDecl(Decl *dcl)
Definition: SemaDecl.cpp:12170
OpenMPMapModifierKind
OpenMP modifier kind for &#39;map&#39; clause.
Definition: OpenMPKinds.h:126
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:99
clauselist_range clauselists()
Definition: DeclOpenMP.h:390
unsigned varlist_size() const
Definition: OpenMPClause.h:229
const char * getOpenMPClauseName(OpenMPClauseKind Kind)
Definition: OpenMPKinds.cpp:82
bool Encloses(const DeclContext *DC) const
Determine whether this declaration context encloses the declaration context DC.
Definition: DeclBase.cpp:1161
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:151
FieldDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
Definition: Decl.h:2929
Step
Definition: OpenMPClause.h:151
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)
#define pow(__x, __y)
Definition: tgmath.h:490
OMPClause * ActOnOpenMPIsDevicePtrClause(ArrayRef< Expr *> VarList, const OMPVarListLocTy &Locs)
Called on well-formed &#39;is_device_ptr&#39; clause.
OMPClause * ActOnOpenMPFirstprivateClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;firstprivate&#39; clause.
DeclGroupPtrTy ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, ArrayRef< OMPClause *> ClauseList)
Called at the end of &#39;#pragma omp declare mapper&#39;.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:168
A C++ nested-name-specifier augmented with source location information.
ExprResult ExprEmpty()
Definition: Ownership.h:285
The results of name lookup within a DeclContext.
Definition: DeclBase.h:1195
This represents &#39;simd&#39; clause in the &#39;#pragma omp ...&#39; directive.
void CreateClauses(ASTContext &C, ArrayRef< OMPClause *> CL)
Creates an array of clauses to this mapper declaration and intializes them.
Definition: DeclOpenMP.cpp:201
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:944
DeviceDiagBuilder diagIfOpenMPHostCode(SourceLocation Loc, unsigned DiagID)
Creates a DeviceDiagBuilder that emits the diagnostic if the current context is "used as host code"...
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.
sema::BlockScopeInfo * getCurBlock()
Retrieve the current block, if any.
Definition: Sema.cpp:1839
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: Stmt.cpp:275
bool isOpenMPTaskingDirective(OpenMPDirectiveKind Kind)
Checks if the specified directive kind is one of tasking directives - task, taskloop, taksloop simd, master taskloop, parallel master taskloop, master taskloop simd, or parallel master taskloop simd.
OpenMPLinearClauseKind
OpenMP attributes for &#39;linear&#39; clause.
Definition: OpenMPKinds.h:110
Represents a member of a struct/union/class.
Definition: Decl.h:2729
static OpenMPMapClauseKind getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, bool IsAggregateOrDeclareTarget)
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:1868
OpenMPContextSelectorKind
OpenMP context selectors.
Definition: OpenMPKinds.h:30
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:3031
void setName(DeclarationName N)
setName - Sets the embedded declaration name.
bool isReferenceType() const
Definition: Type.h:6516
TypeResult ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D)
Check variable declaration in &#39;omp declare mapper&#39; construct.
virtual SourceRange getSourceRange() const LLVM_READONLY
Source range that this declaration covers.
Definition: DeclBase.h:417
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:604
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC...
Definition: DeclBase.h:1908
bool isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, unsigned OpenMPCaptureLevel) const
Return true if the provided declaration VD should be captured by reference.
QualType ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, TypeResult ParsedType)
Check if the specified type is allowed to be used in &#39;omp declare mapper&#39; construct.
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:704
__DEVICE__ int max(int __a, int __b)
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.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:53
QualType getUnsignedPointerDiffType() const
Return the unique unsigned counterpart of "ptrdiff_t" integer type.
This represents &#39;#pragma omp critical&#39; directive.
Definition: StmtOpenMP.h:1640
void EndOpenMPClause()
End analysis of clauses.
IdentifierTable & Idents
Definition: ASTContext.h:580
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:125
bool isInvalidType() const
Definition: DeclSpec.h:2530
ArrayRef< ParmVarDecl * > parameters() const
Definition: Decl.h:2399
DeclClass * getAsSingle() const
Definition: Lookup.h:507
OpenMPDistScheduleClauseKind
OpenMP attributes for &#39;dist_schedule&#39; clause.
Definition: OpenMPKinds.h:151
bool isGLValue() const
Definition: Expr.h:261
static void applyOMPAllocateAttribute(Sema &S, VarDecl *VD, OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator, SourceRange SR)
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:1817
OMPClause * ActOnOpenMPToClause(ArrayRef< Expr *> VarList, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, const OMPVarListLocTy &Locs, ArrayRef< Expr *> UnresolvedMappers=llvm::None)
Called on well-formed &#39;to&#39; clause.
Represents the results of name lookup.
Definition: Lookup.h:46
PtrTy get() const
Definition: Ownership.h:170
OpenMPContextSelectorSetKind
OpenMP context selector sets.
Definition: OpenMPKinds.h:23
DeviceDiagBuilder targetDiag(SourceLocation Loc, unsigned DiagID)
Definition: Sema.cpp:1609
void startOpenMPCXXRangeFor()
If the current region is a range loop-based region, mark the start of the loop construct.
RAII class used to indicate that we are performing provisional semantic analysis to determine the val...
Definition: Sema.h:8490
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.
bool isReferenced() const
Whether any declaration of this entity was referenced.
Definition: DeclBase.cpp:423
Expr * LB
DistributeLowerBound - used when composing &#39;omp distribute&#39; with &#39;omp for&#39; in a same construct...
Definition: StmtOpenMP.h:745
Expr * EUB
DistributeEnsureUpperBound - used when composing &#39;omp distribute&#39; with &#39;omp for&#39; in a same construct...
Definition: StmtOpenMP.h:751
DeclRefExpr * BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, SourceLocation Loc, const CXXScopeSpec *SS=nullptr)
Definition: SemaExpr.cpp:1866
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:588
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...
bool isTriviallyCopyableType(const ASTContext &Context) const
Return true if this is a trivially copyable type (C++0x [basic.types]p9)
Definition: Type.cpp:2289
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.
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type...
Definition: Type.h:7053
static DeclRefExpr * buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, SourceLocation Loc, bool RefersToCapture=false)
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:224
Concrete class used by the front-end to report problems and issues.
Definition: Diagnostic.h:149
StmtResult StmtError()
Definition: Ownership.h:280
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:1896
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:3434
Look up the name of an OpenMP user-defined reduction operation.
Definition: Sema.h:3473
OMPClause * ActOnOpenMPClause(OpenMPClauseKind Kind, SourceLocation StartLoc, SourceLocation EndLoc)
std::pair< StringRef, QualType > CapturedParamNameType
Definition: Sema.h:4235
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
SmallVector< MappableComponent, 8 > MappableExprComponentList
This represents &#39;default&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:862
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
Definition: Expr.cpp:3000
Scope - A scope is a transient data structure that is used while parsing the program.
Definition: Scope.h:40
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:7750
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:6256
ExprResult ActOnOpenMPIdExpression(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id, OpenMPDirectiveKind Kind)
Called on correct id-expression from the &#39;#pragma omp threadprivate&#39;.
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.
OMPClause * ActOnOpenMPProcBindClause(llvm::omp::ProcBindKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;proc_bind&#39; clause.
This represents &#39;final&#39; clause in the &#39;#pragma omp ...&#39; directive.
Definition: OpenMPClause.h:525
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:740
void append(iterator I, iterator E)
Expr * CalcLastIteration
Calculation of last iteration.
Definition: StmtOpenMP.h:784
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:3150
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.
SmallVector< Expr *, 4 > FinalsConditions
List of final conditions required for the generation of the non-rectangular loops.
Definition: StmtOpenMP.h:841
bool isOpenMPWorksharingDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a worksharing directive.
Preprocessor & PP
Definition: Sema.h:384
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
Definition: Decl.cpp:1980
const LangOptions & getLangOpts() const
Definition: Sema.h:1324
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:928
bool isFloat128Type() const
Definition: Type.h:6796
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:176
bool isScalarType() const
Definition: Type.h:6866
An ordinary object is located at an address in memory.
Definition: Specifiers.h:141
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...
static OMPMapClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr *> Vars, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists, ArrayRef< Expr *> UDMapperRefs, ArrayRef< OpenMPMapModifierKind > MapModifiers, ArrayRef< SourceLocation > MapModifiersLoc, NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId, OpenMPMapClauseKind Type, bool TypeIsImplicit, SourceLocation TypeLoc)
Creates clause with a list of variables VL.
Represents the body of a CapturedStmt, and serves as its DeclContext.
Definition: Decl.h:4226
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:502
llvm::omp::Directive OpenMPDirectiveKind
OpenMP directives.
Definition: OpenMPKinds.h:62
static UnresolvedLookupExpr * Create(const ASTContext &Context, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, bool RequiresADL, bool Overloaded, UnresolvedSetIterator Begin, UnresolvedSetIterator End)
Definition: ExprCXX.cpp:404
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const
Retrieve a nested-name-specifier with location information, copied into the given AST context...
Definition: DeclSpec.cpp:142
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.
const LangOptions & LangOpts
Definition: Sema.h:383
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclBase.h:877
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 * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point...
Definition: Expr.cpp:2975
Expr * NUB
Update of UpperBound for statically scheduled &#39;omp for&#39; loops.
Definition: StmtOpenMP.h:806
static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, ArrayRef< OMPClause *> Clauses, ArrayRef< OpenMPDirectiveKind > AllowedNameModifiers)
bool hasUnsignedIntegerRepresentation() const
Determine whether this type has an unsigned integer representation of some sort, e.g., it is an unsigned integer type or a vector.
Definition: Type.cpp:1998
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:788
VarDecl * ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D)
Initialize declare reduction construct initializer.
static OMPIsDevicePtrClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr *> Vars, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists)
Creates clause with a list of variables Vars.
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:869
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:845
Expr * PreCond
Loop pre-condition.
Definition: StmtOpenMP.h:786
child_range children()
NodeId Parent
Definition: ASTDiff.cpp:191
OpenMP 4.0 [2.4, Array Sections].
Definition: ExprOpenMP.h:44
The expressions built for the OpenMP loop CodeGen for the whole collapsed loop nest.
Definition: StmtOpenMP.h:776
This represents &#39;dynamic_allocators&#39; clause in the &#39;#pragma omp requires&#39; directive.
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:542
ConditionalOperator - The ?: ternary operator.
Definition: Expr.h:3732
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:336
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition: Type.cpp:1690
Describes the capture of either a variable, or &#39;this&#39;, or variable-length array type.
Definition: Stmt.h:3389
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:12918
Expr * getSimdlen() const
Return safe iteration space distance.
Definition: OpenMPClause.h:769
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:6423
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.
The return type of classify().
Definition: Expr.h:311
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:1998
DeclarationNameTable DeclarationNames
Definition: ASTContext.h:583
unsigned operator()(argument_type DK)
static OMPCriticalDirective * Create(const ASTContext &C, const DeclarationNameInfo &Name, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive.
Definition: StmtOpenMP.cpp:425
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:767
Expr * IterationVarRef
Loop iteration variable.
Definition: StmtOpenMP.h:778
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:755
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:345
Scope * getCurScope() const
Retrieve the parser&#39;s current scope.
Definition: Sema.h:11904
This represents implicit clause &#39;depend&#39; for the &#39;#pragma omp task&#39; directive.
void ActOnOpenMPDeclareTargetName(NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, OMPDeclareTargetDeclAttr::DevTypeTy DT)
Called on correct id-expression from the &#39;#pragma omp declare target&#39;.
Allows QualTypes to be sorted and hence used in maps and sets.
OpenMPLastprivateModifier
OpenMP &#39;lastprivate&#39; clause modifier.
Definition: OpenMPKinds.h:191
bool isCanonicalDecl() const
Whether this particular Decl is a canonical one.
Definition: DeclBase.h:883
const Stmt * getAssociatedStmt() const
Returns statement associated with the directive.
Definition: StmtOpenMP.h:253
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:1384
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:942
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:619
This represents one expression.
Definition: Expr.h:108
void StartOpenMPClause(OpenMPClauseKind K)
Start analysis of clauses.
QualType getPointeeType() const
Definition: Type.h:2771
Allow any unmodeled side effect.
Definition: Expr.h:615
SourceLocation End
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
Definition: Specifiers.h:122
bool isFunctionNoProtoType() const
Definition: Type.h:2012
bool isDeclScope(Decl *D)
isDeclScope - Return true if this is the scope that the specified decl is declared in...
Definition: Scope.h:323
int Id
Definition: ASTDiff.cpp:190
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
Definition: Decl.h:1045
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:735
Look up the name of an OpenMP user-defined mapper.
Definition: Sema.h:3475
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:134
SmallVector< Expr *, 4 > DependentInits
List of initializers required for the generation of the non-rectangular loops.
Definition: StmtOpenMP.h:838
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:7067
OMPClause * ActOnOpenMPMergeableClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;mergeable&#39; clause.
Inits[]
Definition: OpenMPClause.h:150
static InitializedEntity InitializeVariable(VarDecl *Var)
Create the initialization entity for a variable.
unsigned getNumParams() const
Definition: Decl.h:4271
#define V(N, I)
Definition: ASTContext.h:2941
static OMPMasterDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, Stmt *AssociatedStmt)
Creates directive.
Definition: StmtOpenMP.cpp:407
void setInit(Expr *I)
Definition: Decl.cpp:2283
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
Definition: DeclBase.cpp:132
VarDecl * isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo=false, unsigned StopAt=0)
Check if the specified variable is used in one of the private clauses (private, firstprivate, lastprivate, reduction etc.) in OpenMP constructs.
std::string getAsString() const
Retrieve the human-readable string for this name.
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.
StmtResult ActOnOpenMPParallelMasterTaskLoopDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp parallel master taskloop&#39; after parsing of the associated statemen...
OpenMPClauseKind
OpenMP clauses.
Definition: OpenMPKinds.h:65
bool isFileContext() const
Definition: DeclBase.h:1854
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:438
void startOpenMPLoop()
If the current region is a loop-based region, mark the start of the loop construct.
bool isAnyComplexType() const
Definition: Type.h:6602
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:819
static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, OpenMPDirectiveKind CurrentRegion, const DeclarationNameInfo &CurrentName, OpenMPDirectiveKind CancelRegion, SourceLocation StartLoc)
SourceLocation Begin
OMPClause * ActOnOpenMPAllocateClause(Expr *Allocator, ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;allocate&#39; clause.
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:984
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:7919
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:850
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:1761
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:812
static OMPOrderedDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive.
Definition: StmtOpenMP.cpp:762
QualType getType() const
Definition: Expr.h:137
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:621
bool isSingleResult() const
Determines if this names a single result which is not an unresolved value using decl.
Definition: Lookup.h:308
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:771
bool isInvalid() const
Definition: Ownership.h:166
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:1401
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
Definition: DeclBase.cpp:1091
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:800
ValueDecl * getDecl()
Definition: Expr.h:1247
bool isUsable() const
Definition: Ownership.h:167
Represents a C++ conversion function within a class.
Definition: DeclCXX.h:2713
Expr * NLB
Update of LowerBound for statically scheduled omp loops for outer loop in combined constructs (e...
Definition: StmtOpenMP.h:761
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
Definition: ASTContext.h:1417
The result type of a method or function.
NamedDecl * LookupSingleName(Scope *S, DeclarationName Name, SourceLocation Loc, LookupNameKind NameKind, RedeclarationKind Redecl=NotForRedeclaration)
Look up a name, looking for a single declaration.
bool isUnionType() const
Definition: Type.cpp:527
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.
bool isNull() const
Return true if this QualType doesn&#39;t point to a type yet.
Definition: Type.h:719
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.
static Stmt * tryToFindNextInnerLoop(Stmt *CurStmt, bool TryImperfectlyNestedLoops)
Try to find the next loop sub-statement in the specified statement CurStmt.
Definition: StmtOpenMP.cpp:45
VarDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition: Decl.cpp:2088
DefaultDataSharingAttributes
Default data sharing attributes, which can be applied to directive.
Definition: SemaOpenMP.cpp:49
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1...
Definition: Expr.h:1662
bool isDirectInit() const
Whether the initializer is a direct-initializer (list or call).
Definition: Decl.h:1314
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:782
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.
OpenMPDirectiveKind argument_type
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
Definition: Expr.h:421
This represents &#39;seq_cst&#39; clause in the &#39;#pragma omp atomic&#39; directive.
AttrVec & getAttrs()
Definition: DeclBase.h:490
This represents &#39;untied&#39; clause in the &#39;#pragma omp ...&#39; directive.
bool hasAttrs() const
Definition: DeclBase.h:484
ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)
Definition: SemaCast.cpp:2899
ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E)
Definition: SemaExpr.cpp:3848
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:232
Expr * ST
Stride - local variable passed to runtime.
Definition: StmtOpenMP.h:800
This represents &#39;unified_address&#39; clause in the &#39;#pragma omp requires&#39; directive. ...
bool isStructureOrClassType() const
Definition: Type.cpp:513
SmallVector< Expr *, 4 > PrivateCounters
PrivateCounters Loop counters.
Definition: StmtOpenMP.h:826
OMPClause * ActOnOpenMPAtomicDefaultMemOrderClause(OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;atomic_default_mem_order&#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:1075
llvm::cl::opt< std::string > Filter
Kind
This captures a statement into a function.
Definition: Stmt.h:3376
ImplicitConversionSequence - Represents an implicit conversion sequence, which may be a standard conv...
Definition: Overload.h:513
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:6295
void ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, Expr *VariantRef, SourceRange SR, ArrayRef< OMPCtxSelectorData > Data)
Called on well-formed &#39;#pragma omp declare variant&#39; after parsing of the associated method/function...
ActionResult - This structure is used while parsing/acting on expressions, stmts, etc...
Definition: Ownership.h:153
SourceLocation LParenLoc
Location of &#39;(&#39;.
Definition: OpenMPClause.h:176
SmallVector< Expr *, 4 > Counters
Counters Loop counters.
Definition: StmtOpenMP.h:824
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on a template...
Definition: Expr.h:200
ASTContext & getASTContext() const
Definition: Sema.h:1331
llvm::SmallDenseMap< const ValueDecl *, const Expr *, 4 > VarsWithInheritedDSAType
Definition: Sema.h:9863
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:102
SourceLocation getOperatorLoc() const
Definition: Expr.h:3466
llvm::APSInt APSInt
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...
Diagnostic builder for CUDA/OpenMP devices errors which may or may not be deferred.
Definition: Sema.h:11190
This represents &#39;#pragma omp declare reduction ...&#39; directive.
Definition: DeclOpenMP.h:102
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:312
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:2166
This is a basic class for representing single OpenMP executable directive.
Definition: StmtOpenMP.h:33
DeclGroupPtrTy ActOnOpenMPAllocateDirective(SourceLocation Loc, ArrayRef< Expr *> VarList, ArrayRef< OMPClause *> Clauses, DeclContext *Owner=nullptr)
Called on well-formed &#39;#pragma omp allocate&#39;.
static OMPAllocateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef< Expr *> VL, ArrayRef< OMPClause *> CL)
Definition: DeclOpenMP.cpp:61
OMPClause * ActOnOpenMPAllocatorClause(Expr *Allocator, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;allocator&#39; clause.
DeclarationName getName() const
getName - Returns the embedded declaration name.
This represents &#39;schedule&#39; clause in the &#39;#pragma omp ...&#39; directive.
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).
FunctionEmissionStatus
Status of the function emission on the host/device.
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:450
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:1225
void setReferenced(bool R=true)
Definition: DeclBase.h:588
IdentifierTable & getIdentifierTable()
Definition: Preprocessor.h:914
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:139
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:1699
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs. ...
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:1931
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:163
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:966
StmtVisitor - This class implements a simple visitor for Stmt subclasses.
Definition: StmtVisitor.h:183
SourceLocation getColonLoc() const
Definition: ExprOpenMP.h:108
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:101
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
Definition: Decl.h:1087
ExprResult DefaultLvalueConversion(Expr *E)
Definition: SemaExpr.cpp:590
C-style initialization with assignment.
Definition: Decl.h:825
Expr * PrevEUB
PrevEUB - expression similar to EUB but to be used when loop scheduling uses PrevLB and PrevUB (e...
Definition: StmtOpenMP.h:822
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:91
OMPClause * ActOnOpenMPCopyprivateClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;copyprivate&#39; clause.
Describes the kind of initialization being performed, along with location information for tokens rela...
bool isValueDependent() const
isValueDependent - Determines whether this expression is value-dependent (C++ [temp.dep.constexpr]).
Definition: Expr.h:158
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.
Look up any declaration with any name.
Definition: Sema.h:3477
bool isAnyPointerType() const
Definition: Type.h:6508
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:617
This declaration is only a declaration.
Definition: Decl.h:1156
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.
llvm::APInt APInt
Definition: Integral.h:27
void tryCaptureOpenMPLambdas(ValueDecl *V)
Function tries to capture lambda&#39;s captured variables in the OpenMP region before the original lambda...
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.
StmtResult ActOnOpenMPMasterTaskLoopDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA)
Called on well-formed &#39;#pragma omp master taskloop&#39; after parsing of the associated statement...
Stmt * getCapturedStmt()
Retrieve the statement being captured.
Definition: Stmt.h:3477
bool isFunctionProtoType() const
Definition: Type.h:2013
void setMapperVarRef(Expr *MapperVarRefE)
Set the variable declared in the mapper.
Definition: DeclOpenMP.h:285
static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, DSAStackTy *Stack)
Tries to find omp_allocator_handle_t type.
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:258
SourceLocation EndLoc
Ending location of the clause.
Definition: OpenMPClause.h:178
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required...
Definition: DeclBase.cpp:398
Updates[]
Definition: OpenMPClause.h:150
DistCombinedHelperExprs DistCombinedFields
Expressions used when combining OpenMP loop pragmas.
Definition: StmtOpenMP.h:846
static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, CXXScopeSpec &MapperIdScopeSpec, const DeclarationNameInfo &MapperId, QualType Type, Expr *UnresolvedMapper)
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:284
sema::CapturedRegionScopeInfo * getCurCapturedRegion()
Retrieve the current captured region, if any.
Definition: Sema.cpp:2214
Expr * LB
LowerBound - local variable passed to runtime.
Definition: StmtOpenMP.h:796
void clear(unsigned Size)
Initialize all the fields to null.
Definition: StmtOpenMP.h:860
NamedDecl * next()
Definition: Lookup.h:643
Expr * Init
Loop iteration variable init.
Definition: StmtOpenMP.h:790
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:1209
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:2345
bool isInstantiationDependentType() const
Determine whether this type is an instantiation-dependent type, meaning that the type involves a temp...
Definition: Type.h:2156
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:381
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:224
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:3474
static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, OpenMPDirectiveKind NameModifier=OMPD_unknown)
static Expr * getCollapseNumberExpr(ArrayRef< OMPClause *> Clauses)
void setStep(Expr *Step)
Sets the linear step for clause.
Definition: OpenMPClause.h:110
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:68
* Finals[]
Definition: OpenMPClause.h:151
QualType withRestrict() const
Definition: Type.h:842
static OMPCapturedExprDecl * Create(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, QualType T, SourceLocation StartLoc)
Definition: DeclOpenMP.cpp:234
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:93
static OMPDeclareMapperDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, QualType T, DeclarationName VarName, OMPDeclareMapperDecl *PrevDeclInScope)
Creates declare mapper node.
Definition: DeclOpenMP.cpp:175
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
Definition: DeclBase.h:948
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
Definition: Decl.cpp:2672
Dataflow Directional Tag Classes.
std::string getAsString() const
getAsString - Retrieve the human-readable string for this name.
virtual void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy, bool Qualified) const
Appends a human-readable name for this declaration into the given stream.
Definition: Decl.cpp:1672
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.
bool isFloat16Type() const
Definition: Type.h:6790
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1271
EvalResult is a struct with detailed info about an evaluated expression.
Definition: Expr.h:586
static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, const Expr *E, QualType BaseQTy)
Return true if it can be proven that the provided array expression (array section or array subscript)...
static ImplicitConversionSequence TryImplicitConversion(Sema &S, Expr *From, QualType ToType, bool SuppressUserConversions, bool AllowExplicit, bool InOverloadResolution, bool CStyle, bool AllowObjCWritebackConversion, bool AllowObjCConversionOnExplicit)
TryImplicitConversion - Attempt to perform an implicit conversion from the given expression (Expr) to...
SmallVector< Expr *, 4 > Inits
Expressions for loop counters inits for CodeGen.
Definition: StmtOpenMP.h:828
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
Definition: OperatorKinds.h:21
static OMPThreadPrivateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef< Expr *> VL)
Definition: DeclOpenMP.cpp:28
const Scope * getParent() const
getParent - Return the scope that this is nested in.
Definition: Scope.h:228
void ActOnCapturedRegionError()
Definition: SemaStmt.cpp:4426
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:175
SmallVector< Expr *, 4 > DependentCounters
List of counters required for the generation of the non-rectangular loops.
Definition: StmtOpenMP.h:835
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:578
OMPClause * ActOnOpenMPSimpleClause(OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
const Expr * getInit() const
Definition: Decl.h:1229
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:517
static OMPCapturedExprDecl * buildCaptureDecl(Sema &S, IdentifierInfo *Id, Expr *CaptureExpr, bool WithInit, bool AsExpression)
Kind getKind() const
Definition: DeclBase.h:432
This represents &#39;unified_shared_memory&#39; clause in the &#39;#pragma omp requires&#39; directive.
This represents clause &#39;linear&#39; in the &#39;#pragma omp ...&#39; directives.
static ExprResult buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, bool IsNonRectangularLB, llvm::MapVector< const Expr *, DeclRefExpr *> &Captures)
Build &#39;VarRef = Start.
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;.
Expr * get() const
Definition: Sema.h:4072
virtual bool hasFloat16Type() const
Determine whether the _Float16 type is supported on this target.
Definition: TargetInfo.h:534
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;.
DeviceDiagBuilder diagIfOpenMPDeviceCode(SourceLocation Loc, unsigned DiagID)
Creates a DeviceDiagBuilder that emits the diagnostic if the current context is "used as device code"...
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspnd...
FunctionEmissionStatus
Status of the function emission on the CUDA/HIP/OpenMP host/device attrs.
Definition: Sema.h:3642
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 OMPLastprivateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL, ArrayRef< Expr *> SrcExprs, ArrayRef< Expr *> DstExprs, ArrayRef< Expr *> AssignmentOps, OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc, SourceLocation ColonLoc, Stmt *PreInit, Expr *PostUpdate)
Creates clause with a list of variables VL.
void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit)
AddInitializerToDecl - Adds the initializer Init to the declaration dcl.
Definition: SemaDecl.cpp:11689
bool isValid() const
A scope specifier is present, and it refers to a real scope.
Definition: DeclSpec.h:196
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Definition: Expr.cpp:2995
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.
OMPClause * ActOnOpenMPFromClause(ArrayRef< Expr *> VarList, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, const OMPVarListLocTy &Locs, ArrayRef< Expr *> UnresolvedMappers=llvm::None)
Called on well-formed &#39;from&#39; clause.
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...
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point...
Definition: Expr.cpp:2983
Not an overloaded operator.
Definition: OperatorKinds.h:22
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:4495
Complex values, per C99 6.2.5p11.
Definition: Type.h:2554
bool isInOpenMPTargetExecutionDirective() const
Return true inside OpenMP target region.
bool isOpenMPDistributeDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a distribute directive.
Expr::Classification Cl
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Definition: Expr.h:2462
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:6811
T * getAttr() const
Definition: DeclBase.h:538
void setSeverity(diag::kind Diag, diag::Severity Map, SourceLocation Loc)
This allows the client to specify that certain warnings are ignored.
Definition: Diagnostic.cpp:342
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:336
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:1490
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, NonOdrUseReason NOUR=NOUR_None)
Definition: Expr.cpp:545
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:1069
Expr * Inc
Loop increment.
Definition: StmtOpenMP.h:792
DeclContext * getCurLexicalContext() const
Definition: Sema.h:11915
OpenMPScheduleClauseKind
OpenMP attributes for &#39;schedule&#39; clause.
Definition: OpenMPKinds.h:85
Expr * IgnoreParenLValueCasts() LLVM_READONLY
Skip past any parentheses and lvalue casts which might surround this expression until reaching a fixe...
Definition: Expr.cpp:3012
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:109
CXXBasePath & front()
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:2750
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
Definition: ASTContext.h:2321
ImplicitParamDecl * getParam(unsigned i) const
Definition: Decl.h:4273
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.
bool isInOpenMPDeclareTargetContext() const
Return true inside OpenMP declare target region.
Definition: Sema.h:9834
ExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *InputExpr)
Definition: SemaExpr.cpp:13576
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, const Expr *SizeExpr, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type...
OpenMPDefaultClauseKind
OpenMP attributes for &#39;default&#39; clause.
Definition: OpenMPKinds.h:77
virtual bool hasFloat128Type() const
Determine whether the __float128 type is supported on this target.
Definition: TargetInfo.h:531
void addDecl(Decl *D)
Add the declaration D into this context.
Definition: DeclBase.cpp:1524
bool hasAssociatedStmt() const
Returns true if directive has associated statement.
Definition: StmtOpenMP.h:250
Implements a partial diagnostic that can be emitted anwyhere in a DiagnosticBuilder stream...
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:2915
static OMPRequiresDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, ArrayRef< OMPClause *> CL)
Create requires node.
Definition: DeclOpenMP.cpp:104
virtual bool hasInt128Type() const
Determine whether the __int128 type is supported on this target.
Definition: TargetInfo.h:523
Capturing the *this object by reference.
Definition: Lambda.h:34
This represents &#39;write&#39; clause in the &#39;#pragma omp atomic&#39; directive.
const Type * getTypePtrOrNull() const
Definition: Type.h:6260
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:413
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
Definition: ASTContext.h:2104
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.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types...
Definition: Type.cpp:2115
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:1101
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Definition: ASTContext.h:2305
llvm::iterator_range< specific_attr_iterator< T > > specific_attrs() const
Definition: DeclBase.h:524
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:748
static std::pair< ValueDecl *, bool > getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, SourceRange &ERange, bool AllowArraySection=false)
X
Add a minimal nested name specifier fixit hint to allow lookup of a tag name from an outer enclosing ...
Definition: SemaDecl.cpp:14781
bool hasMutableFields() const
Determine whether this class, or any of its class subobjects, contains a mutable field.
Definition: DeclCXX.h:1136
NamedDecl * lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id, NamedDeclSetType &SameDirectiveDecls)
Searches for the provided declaration name for OpenMP declare target directive.
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:1298
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:828
static OMPTaskyieldDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
Definition: StmtOpenMP.cpp:627
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer...
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 printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\, const ASTContext *Context=nullptr) const
void Deallocate(void *Ptr) const
Definition: ASTContext.h:692
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition: Expr.h:2836
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:922
StmtResult ActOnOpenMPTaskgroupDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp taskgroup&#39;.
static ExprResult buildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, bool IsNonRectangularLB, llvm::MapVector< const Expr *, DeclRefExpr *> *Captures=nullptr)
Build &#39;VarRef = Start + Iter * Step&#39;.
Expr * UB
UpperBound - local variable passed to runtime.
Definition: StmtOpenMP.h:798
static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, Sema &SemaRef, Decl *D)
static OMPNontemporalClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL)
Creates clause with a list of variables VL.
Describes the sequence of initializations required to initialize a given object or reference with a s...
ActionResult< Expr * > ExprResult
Definition: Ownership.h:263
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Definition: Type.h:6336
This represents &#39;nowait&#39; clause in the &#39;#pragma omp ...&#39; directive.
void setEnd(SourceLocation e)
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:1958
Represents a C++ struct/union/class.
Definition: DeclCXX.h:253
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:1493
static QualType getBaseOriginalType(const Expr *Base)
Return original type of the base expression for array section.
Definition: Expr.cpp:4712
StmtResult ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp taskwait&#39;.
OMPClause * ActOnOpenMPLastprivateClause(ArrayRef< Expr *> VarList, OpenMPLastprivateModifier LPKind, SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;lastprivate&#39; clause.
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:1818
static OMPBarrierDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
Definition: StmtOpenMP.cpp:642
int Priority
Definition: Format.cpp:1829
Privates[]
Gets the list of initial values for linear variables.
Definition: OpenMPClause.h:150
void addHiddenDecl(Decl *D)
Add the declaration D to this context without modifying any lookup tables.
Definition: DeclBase.cpp:1498
OpenMPMapClauseKind
OpenMP mapping kind for &#39;map&#39; clause.
Definition: OpenMPKinds.h:118
StmtResult ActOnOpenMPParallelMasterDirective(ArrayRef< OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;#pragma omp parallel master&#39; after parsing of the associated statement...
SourceLocation getFirstScheduleModifierLoc() const
Get the first modifier location.
Do not present this diagnostic, ignore it.
Capturing by reference.
Definition: Lambda.h:37
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.
static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, bool StrictlyPositive, bool BuildCapture=false, OpenMPDirectiveKind DKind=OMPD_unknown, OpenMPDirectiveKind *CaptureRegion=nullptr, Stmt **HelperValStmt=nullptr)
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:397
bool containsUnexpandedParameterPack() const
Whether this expression contains an unexpanded parameter pack (for C++11 variadic templates)...
Definition: Expr.h:223
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:189
void addAttr(Attr *A)
Definition: DeclBase.cpp:832
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:336
This represents &#39;#pragma omp declare mapper ...&#39; directive.
Definition: DeclOpenMP.h:217
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition: Stmt.cpp:263
__DEVICE__ int min(int __a, int __b)
static void argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, SourceLocation Loc, QualType Ty, SmallVectorImpl< UnresolvedSet< 8 >> &Lookups)
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:250
ExprResult ExprError()
Definition: Ownership.h:279
This represents &#39;dist_schedule&#39; clause in the &#39;#pragma omp ...&#39; directive.
static OMPTaskwaitDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc)
Creates directive.
Definition: StmtOpenMP.cpp:656
static OMPAllocateClause * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc, Expr *Allocator, SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef< Expr *> VL)
Creates clause with a list of variables VL.
Expr * Cond
Distribute Loop condition used when composing &#39;omp distribute&#39; with &#39;omp for&#39; in a same construct...
Definition: StmtOpenMP.h:758
decl_type * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
Definition: Redeclarable.h:225
Stmt * PreInits
Init statement for all captured expressions.
Definition: StmtOpenMP.h:843
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
Definition: Type.h:2150
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:3511
A reference to a declared variable, function, enum, etc.
Definition: Expr.h:1171
Expr * getRHS() const
Definition: Expr.h:3476
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:6504
static OverloadedOperatorKind getOverloadedOperator(Opcode Opc)
Retrieve the overloaded operator kind that corresponds to the given binary opcode.
Definition: Expr.cpp:2094
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:2091
This structure contains most locations needed for by an OMPVarListClause.
Definition: OpenMPClause.h:172
bool isStaticDataMember() const
Determines whether this is a static data member.
Definition: Decl.h:1144
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
Definition: Lookup.h:583
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
Definition: Decl.h:1114
SmallVector< CompoundScopeInfo, 4 > CompoundScopes
The stack of currently active compound stamement scopes in the function.
Definition: ScopeInfo.h:205
QualType getType() const
Definition: Decl.h:630
bool empty() const
Return true if no decls were found.
Definition: Lookup.h:339
An l-value expression is a reference to an object with independent storage.
Definition: Specifiers.h:129
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...
A wrapper class around a pointer that always points to its canonical declaration. ...
Definition: Redeclarable.h:347
static OMPCancelDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, OpenMPDirectiveKind CancelRegion)
Creates directive.
Definition: StmtOpenMP.cpp:716
bool isOpenMPLoopDirective(OpenMPDirectiveKind DKind)
Checks if the specified directive is a directive with an associated loop construct.
Expr * IL
IsLastIteration - local flag variable passed to runtime.
Definition: StmtOpenMP.h:794
A trivial tuple used to represent a source range.
ASTContext & Context
Definition: Sema.h:385
This represents a decl that may have a name.
Definition: Decl.h:223
static OMPCancellationPointDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion)
Creates directive.
Definition: StmtOpenMP.cpp:695
bool isTranslationUnit() const
Definition: DeclBase.h:1859
void setAccess(AccessSpecifier AS)
Definition: DeclBase.h:468
CanQualType BoolTy
Definition: ASTContext.h:1017
OMPClause * ActOnOpenMPOrderedClause(SourceLocation StartLoc, SourceLocation EndLoc, SourceLocation LParenLoc=SourceLocation(), Expr *NumForLoops=nullptr)
Called on well-formed &#39;ordered&#39; clause.
bool DeclMustBeEmitted(const Decl *D)
Determines if the decl can be CodeGen&#39;ed or deserialized from PCH lazily, only when used; this is onl...
Directive - Abstract class representing a parsed verify directive.
QualType getVariableArrayType(QualType EltTy, Expr *NumElts, ArrayType::ArraySizeModifier ASM, unsigned IndexTypeQuals, SourceRange Brackets) const
Return a non-unique reference to the type for a variable array of the specified element type...
OMPClause * ActOnOpenMPCollapseClause(Expr *NumForLoops, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;collapse&#39; clause.
bool isConstant(const ASTContext &Ctx) const
Definition: Type.h:789
sema::LambdaScopeInfo * getCurLambda(bool IgnoreNonLambdaCapturingScope=false)
Retrieve the current lambda scope info, if any.
Definition: Sema.cpp:1882
ExprResult BuildBinOp(Scope *S, SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr)
Definition: SemaExpr.cpp:13460
APSInt & getInt()
Definition: APValue.h:380
static OMPClauseWithPostUpdate * get(OMPClause *C)
iterator begin() const
Definition: Lookup.h:335
OMPClause * ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, SourceLocation EndLoc)
Called on well-formed &#39;reverse_offload&#39; clause.
Describes an entity that is being initialized.
static OMPFromClause * Create(const ASTContext &C, const OMPVarListLocTy &Locs, ArrayRef< Expr *> Vars, ArrayRef< ValueDecl *> Declarations, MappableExprComponentListsRef ComponentLists, ArrayRef< Expr *> UDMapperRefs, NestedNameSpecifierLoc UDMQualifierLoc, DeclarationNameInfo MapperId)
Creates clause with a list of variables Vars.
OMPClause * ActOnOpenMPNontemporalClause(ArrayRef< Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
Called on well-formed &#39;nontemporal&#39; clause.
NamedDecl * getRepresentativeDecl() const
Fetches a representative decl. Useful for lazy diagnostics.
Definition: Lookup.h:524
static T filterLookupForUDReductionAndMapper(SmallVectorImpl< U > &Lookups, const llvm::function_ref< T(ValueDecl *)> Gen)
void setType(QualType newType)
Definition: Decl.h:631
static void checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, MappableVarListInfo &MVLI, SourceLocation StartLoc, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, ArrayRef< Expr *> UnresolvedMappers, OpenMPMapClauseKind MapType=OMPC_MAP_unknown, bool IsMapTypeImplicit=false)
bool hasInit() const
Definition: Decl.cpp:2226
SourceLocation getBegin() const
SourceLocation ColonLoc
Location of &#39;:&#39;.
Definition: OpenMPClause.h:107
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.
This represents &#39;#pragma omp threadprivate ...&#39; directive.
Definition: DeclOpenMP.h:39
static OMPParallelMasterTaskLoopSimdDirective * 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.
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:1157
Represents the canonical version of C arrays with a specified constant size.
Definition: Type.h:2935
OMPClause * ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc)
OMPClause * ActOnOpenMPUseDevicePtrClause(ArrayRef< Expr *> VarList, const OMPVarListLocTy &Locs)
Called on well-formed &#39;use_device_ptr&#39; clause.
SourceLocation getLocation() const
Definition: DeclBase.h:429
QualType getType() const
Return the type wrapped by this type source info.
Definition: Type.h:6238
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:98
static OMPParallelMasterDirective * Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc, ArrayRef< OMPClause *> Clauses, Stmt *AssociatedStmt)
Creates directive with a list of Clauses.
Definition: StmtOpenMP.cpp:554
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:1364
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point...
Definition: Expr.cpp:2991
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.
OMPClause * ActOnOpenMPMapClause(ArrayRef< OpenMPMapModifierKind > MapTypeModifiers, ArrayRef< SourceLocation > MapTypeModifiersLoc, CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, SourceLocation ColonLoc, ArrayRef< Expr *> VarList, const OMPVarListLocTy &Locs, ArrayRef< Expr *> UnresolvedMappers=llvm::None)
Called on well-formed &#39;map&#39; clause.
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:81
static bool isVisible(Sema &SemaRef, NamedDecl *D)
Determine whether the given declaration is visible to the program.
Definition: Lookup.h:349
SourceLocation StartLoc
Starting location of the clause (the clause keyword).
Definition: OpenMPClause.h:174