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