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"
16 #include "clang/AST/ASTMutationListener.h"
17 #include "clang/AST/CXXInheritance.h"
18 #include "clang/AST/Decl.h"
19 #include "clang/AST/DeclCXX.h"
20 #include "clang/AST/DeclOpenMP.h"
21 #include "clang/AST/OpenMPClause.h"
22 #include "clang/AST/StmtCXX.h"
23 #include "clang/AST/StmtOpenMP.h"
24 #include "clang/AST/StmtVisitor.h"
25 #include "clang/AST/TypeOrdering.h"
26 #include "clang/Basic/DiagnosticSema.h"
27 #include "clang/Basic/OpenMPKinds.h"
28 #include "clang/Basic/PartialDiagnostic.h"
29 #include "clang/Basic/TargetInfo.h"
30 #include "clang/Sema/EnterExpressionEvaluationContext.h"
31 #include "clang/Sema/Initialization.h"
32 #include "clang/Sema/Lookup.h"
33 #include "clang/Sema/Scope.h"
34 #include "clang/Sema/ScopeInfo.h"
35 #include "clang/Sema/SemaInternal.h"
36 #include "llvm/ADT/IndexedMap.h"
37 #include "llvm/ADT/PointerEmbeddedInt.h"
38 #include "llvm/ADT/STLExtras.h"
39 #include "llvm/ADT/SmallSet.h"
40 #include "llvm/ADT/StringExtras.h"
41 #include "llvm/Frontend/OpenMP/OMPAssume.h"
42 #include "llvm/Frontend/OpenMP/OMPConstants.h"
43 #include <optional>
44 #include <set>
45 
46 using namespace clang;
47 using namespace llvm::omp;
48 
49 //===----------------------------------------------------------------------===//
50 // Stack of data-sharing attributes for variables
51 //===----------------------------------------------------------------------===//
52 
53 static const Expr *checkMapClauseExpressionBase(
54     Sema &SemaRef, Expr *E,
55     OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
56     OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose);
57 
58 namespace {
59 /// Default data sharing attributes, which can be applied to directive.
60 enum DefaultDataSharingAttributes {
61   DSA_unspecified = 0,       /// Data sharing attribute not specified.
62   DSA_none = 1 << 0,         /// Default data sharing attribute 'none'.
63   DSA_shared = 1 << 1,       /// Default data sharing attribute 'shared'.
64   DSA_private = 1 << 2,      /// Default data sharing attribute 'private'.
65   DSA_firstprivate = 1 << 3, /// Default data sharing attribute 'firstprivate'.
66 };
67 
68 /// Stack for tracking declarations used in OpenMP directives and
69 /// clauses and their data-sharing attributes.
70 class DSAStackTy {
71 public:
72   struct DSAVarData {
73     OpenMPDirectiveKind DKind = OMPD_unknown;
74     OpenMPClauseKind CKind = OMPC_unknown;
75     unsigned Modifier = 0;
76     const Expr *RefExpr = nullptr;
77     DeclRefExpr *PrivateCopy = nullptr;
78     SourceLocation ImplicitDSALoc;
79     bool AppliedToPointee = false;
80     DSAVarData() = default;
81     DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
82                const Expr *RefExpr, DeclRefExpr *PrivateCopy,
83                SourceLocation ImplicitDSALoc, unsigned Modifier,
84                bool AppliedToPointee)
85         : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr),
86           PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc),
87           AppliedToPointee(AppliedToPointee) {}
88   };
89   using OperatorOffsetTy =
90       llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>;
91   using DoacrossClauseMapTy = llvm::DenseMap<OMPClause *, OperatorOffsetTy>;
92   /// Kind of the declaration used in the uses_allocators clauses.
93   enum class UsesAllocatorsDeclKind {
94     /// Predefined allocator
95     PredefinedAllocator,
96     /// User-defined allocator
97     UserDefinedAllocator,
98     /// The declaration that represent allocator trait
99     AllocatorTrait,
100   };
101 
102 private:
103   struct DSAInfo {
104     OpenMPClauseKind Attributes = OMPC_unknown;
105     unsigned Modifier = 0;
106     /// Pointer to a reference expression and a flag which shows that the
107     /// variable is marked as lastprivate(true) or not (false).
108     llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
109     DeclRefExpr *PrivateCopy = nullptr;
110     /// true if the attribute is applied to the pointee, not the variable
111     /// itself.
112     bool AppliedToPointee = false;
113   };
114   using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
115   using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
116   using LCDeclInfo = std::pair<unsigned, VarDecl *>;
117   using LoopControlVariablesMapTy =
118       llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
119   /// Struct that associates a component with the clause kind where they are
120   /// found.
121   struct MappedExprComponentTy {
122     OMPClauseMappableExprCommon::MappableExprComponentLists Components;
123     OpenMPClauseKind Kind = OMPC_unknown;
124   };
125   using MappedExprComponentsTy =
126       llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
127   using CriticalsWithHintsTy =
128       llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
129   struct ReductionData {
130     using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
131     SourceRange ReductionRange;
132     llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
133     ReductionData() = default;
134     void set(BinaryOperatorKind BO, SourceRange RR) {
135       ReductionRange = RR;
136       ReductionOp = BO;
137     }
138     void set(const Expr *RefExpr, SourceRange RR) {
139       ReductionRange = RR;
140       ReductionOp = RefExpr;
141     }
142   };
143   using DeclReductionMapTy =
144       llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
145   struct DefaultmapInfo {
146     OpenMPDefaultmapClauseModifier ImplicitBehavior =
147         OMPC_DEFAULTMAP_MODIFIER_unknown;
148     SourceLocation SLoc;
149     DefaultmapInfo() = default;
150     DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc)
151         : ImplicitBehavior(M), SLoc(Loc) {}
152   };
153 
154   struct SharingMapTy {
155     DeclSAMapTy SharingMap;
156     DeclReductionMapTy ReductionMap;
157     UsedRefMapTy AlignedMap;
158     UsedRefMapTy NontemporalMap;
159     MappedExprComponentsTy MappedExprComponents;
160     LoopControlVariablesMapTy LCVMap;
161     DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
162     SourceLocation DefaultAttrLoc;
163     DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown];
164     OpenMPDirectiveKind Directive = OMPD_unknown;
165     DeclarationNameInfo DirectiveName;
166     Scope *CurScope = nullptr;
167     DeclContext *Context = nullptr;
168     SourceLocation ConstructLoc;
169     /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
170     /// get the data (loop counters etc.) about enclosing loop-based construct.
171     /// This data is required during codegen.
172     DoacrossClauseMapTy DoacrossDepends;
173     /// First argument (Expr *) contains optional argument of the
174     /// 'ordered' clause, the second one is true if the regions has 'ordered'
175     /// clause, false otherwise.
176     std::optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
177     bool RegionHasOrderConcurrent = false;
178     unsigned AssociatedLoops = 1;
179     bool HasMutipleLoops = false;
180     const Decl *PossiblyLoopCounter = nullptr;
181     bool NowaitRegion = false;
182     bool UntiedRegion = false;
183     bool CancelRegion = false;
184     bool LoopStart = false;
185     bool BodyComplete = false;
186     SourceLocation PrevScanLocation;
187     SourceLocation PrevOrderedLocation;
188     SourceLocation InnerTeamsRegionLoc;
189     /// Reference to the taskgroup task_reduction reference expression.
190     Expr *TaskgroupReductionRef = nullptr;
191     llvm::DenseSet<QualType> MappedClassesQualTypes;
192     SmallVector<Expr *, 4> InnerUsedAllocators;
193     llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates;
194     /// List of globals marked as declare target link in this target region
195     /// (isOpenMPTargetExecutionDirective(Directive) == true).
196     llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls;
197     /// List of decls used in inclusive/exclusive clauses of the scan directive.
198     llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective;
199     llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind>
200         UsesAllocatorsDecls;
201     /// Data is required on creating capture fields for implicit
202     /// default first|private clause.
203     struct ImplicitDefaultFDInfoTy {
204       /// Field decl.
205       const FieldDecl *FD = nullptr;
206       /// Nesting stack level
207       size_t StackLevel = 0;
208       /// Capture variable decl.
209       VarDecl *VD = nullptr;
210       ImplicitDefaultFDInfoTy(const FieldDecl *FD, size_t StackLevel,
211                               VarDecl *VD)
212           : FD(FD), StackLevel(StackLevel), VD(VD) {}
213     };
214     /// List of captured fields
215     llvm::SmallVector<ImplicitDefaultFDInfoTy, 8>
216         ImplicitDefaultFirstprivateFDs;
217     Expr *DeclareMapperVar = nullptr;
218     SmallVector<VarDecl *, 16> IteratorVarDecls;
219     SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
220                  Scope *CurScope, SourceLocation Loc)
221         : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
222           ConstructLoc(Loc) {}
223     SharingMapTy() = default;
224   };
225 
226   using StackTy = SmallVector<SharingMapTy, 4>;
227 
228   /// Stack of used declaration and their data-sharing attributes.
229   DeclSAMapTy Threadprivates;
230   const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
231   SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack;
232   /// true, if check for DSA must be from parent directive, false, if
233   /// from current directive.
234   OpenMPClauseKind ClauseKindMode = OMPC_unknown;
235   Sema &SemaRef;
236   bool ForceCapturing = false;
237   /// true if all the variables in the target executable directives must be
238   /// captured by reference.
239   bool ForceCaptureByReferenceInTargetExecutable = false;
240   CriticalsWithHintsTy Criticals;
241   unsigned IgnoredStackElements = 0;
242 
243   /// Iterators over the stack iterate in order from innermost to outermost
244   /// directive.
245   using const_iterator = StackTy::const_reverse_iterator;
246   const_iterator begin() const {
247     return Stack.empty() ? const_iterator()
248                          : Stack.back().first.rbegin() + IgnoredStackElements;
249   }
250   const_iterator end() const {
251     return Stack.empty() ? const_iterator() : Stack.back().first.rend();
252   }
253   using iterator = StackTy::reverse_iterator;
254   iterator begin() {
255     return Stack.empty() ? iterator()
256                          : Stack.back().first.rbegin() + IgnoredStackElements;
257   }
258   iterator end() {
259     return Stack.empty() ? iterator() : Stack.back().first.rend();
260   }
261 
262   // Convenience operations to get at the elements of the stack.
263 
264   bool isStackEmpty() const {
265     return Stack.empty() ||
266            Stack.back().second != CurrentNonCapturingFunctionScope ||
267            Stack.back().first.size() <= IgnoredStackElements;
268   }
269   size_t getStackSize() const {
270     return isStackEmpty() ? 0
271                           : Stack.back().first.size() - IgnoredStackElements;
272   }
273 
274   SharingMapTy *getTopOfStackOrNull() {
275     size_t Size = getStackSize();
276     if (Size == 0)
277       return nullptr;
278     return &Stack.back().first[Size - 1];
279   }
280   const SharingMapTy *getTopOfStackOrNull() const {
281     return const_cast<DSAStackTy &>(*this).getTopOfStackOrNull();
282   }
283   SharingMapTy &getTopOfStack() {
284     assert(!isStackEmpty() && "no current directive");
285     return *getTopOfStackOrNull();
286   }
287   const SharingMapTy &getTopOfStack() const {
288     return const_cast<DSAStackTy &>(*this).getTopOfStack();
289   }
290 
291   SharingMapTy *getSecondOnStackOrNull() {
292     size_t Size = getStackSize();
293     if (Size <= 1)
294       return nullptr;
295     return &Stack.back().first[Size - 2];
296   }
297   const SharingMapTy *getSecondOnStackOrNull() const {
298     return const_cast<DSAStackTy &>(*this).getSecondOnStackOrNull();
299   }
300 
301   /// Get the stack element at a certain level (previously returned by
302   /// \c getNestingLevel).
303   ///
304   /// Note that nesting levels count from outermost to innermost, and this is
305   /// the reverse of our iteration order where new inner levels are pushed at
306   /// the front of the stack.
307   SharingMapTy &getStackElemAtLevel(unsigned Level) {
308     assert(Level < getStackSize() && "no such stack element");
309     return Stack.back().first[Level];
310   }
311   const SharingMapTy &getStackElemAtLevel(unsigned Level) const {
312     return const_cast<DSAStackTy &>(*this).getStackElemAtLevel(Level);
313   }
314 
315   DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const;
316 
317   /// Checks if the variable is a local for OpenMP region.
318   bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const;
319 
320   /// Vector of previously declared requires directives
321   SmallVector<const OMPRequiresDecl *, 2> RequiresDecls;
322   /// omp_allocator_handle_t type.
323   QualType OMPAllocatorHandleT;
324   /// omp_depend_t type.
325   QualType OMPDependT;
326   /// omp_event_handle_t type.
327   QualType OMPEventHandleT;
328   /// omp_alloctrait_t type.
329   QualType OMPAlloctraitT;
330   /// Expression for the predefined allocators.
331   Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
332       nullptr};
333   /// Vector of previously encountered target directives
334   SmallVector<SourceLocation, 2> TargetLocations;
335   SourceLocation AtomicLocation;
336   /// Vector of declare variant construct traits.
337   SmallVector<llvm::omp::TraitProperty, 8> ConstructTraits;
338 
339 public:
340   explicit DSAStackTy(Sema &S) : SemaRef(S) {}
341 
342   /// Sets omp_allocator_handle_t type.
343   void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; }
344   /// Gets omp_allocator_handle_t type.
345   QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; }
346   /// Sets omp_alloctrait_t type.
347   void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; }
348   /// Gets omp_alloctrait_t type.
349   QualType getOMPAlloctraitT() const { return OMPAlloctraitT; }
350   /// Sets the given default allocator.
351   void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
352                     Expr *Allocator) {
353     OMPPredefinedAllocators[AllocatorKind] = Allocator;
354   }
355   /// Returns the specified default allocator.
356   Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const {
357     return OMPPredefinedAllocators[AllocatorKind];
358   }
359   /// Sets omp_depend_t type.
360   void setOMPDependT(QualType Ty) { OMPDependT = Ty; }
361   /// Gets omp_depend_t type.
362   QualType getOMPDependT() const { return OMPDependT; }
363 
364   /// Sets omp_event_handle_t type.
365   void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; }
366   /// Gets omp_event_handle_t type.
367   QualType getOMPEventHandleT() const { return OMPEventHandleT; }
368 
369   bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
370   OpenMPClauseKind getClauseParsingMode() const {
371     assert(isClauseParsingMode() && "Must be in clause parsing mode.");
372     return ClauseKindMode;
373   }
374   void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
375 
376   bool isBodyComplete() const {
377     const SharingMapTy *Top = getTopOfStackOrNull();
378     return Top && Top->BodyComplete;
379   }
380   void setBodyComplete() { getTopOfStack().BodyComplete = true; }
381 
382   bool isForceVarCapturing() const { return ForceCapturing; }
383   void setForceVarCapturing(bool V) { ForceCapturing = V; }
384 
385   void setForceCaptureByReferenceInTargetExecutable(bool V) {
386     ForceCaptureByReferenceInTargetExecutable = V;
387   }
388   bool isForceCaptureByReferenceInTargetExecutable() const {
389     return ForceCaptureByReferenceInTargetExecutable;
390   }
391 
392   void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
393             Scope *CurScope, SourceLocation Loc) {
394     assert(!IgnoredStackElements &&
395            "cannot change stack while ignoring elements");
396     if (Stack.empty() ||
397         Stack.back().second != CurrentNonCapturingFunctionScope)
398       Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
399     Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
400     Stack.back().first.back().DefaultAttrLoc = Loc;
401   }
402 
403   void pop() {
404     assert(!IgnoredStackElements &&
405            "cannot change stack while ignoring elements");
406     assert(!Stack.back().first.empty() &&
407            "Data-sharing attributes stack is empty!");
408     Stack.back().first.pop_back();
409   }
410 
411   /// RAII object to temporarily leave the scope of a directive when we want to
412   /// logically operate in its parent.
413   class ParentDirectiveScope {
414     DSAStackTy &Self;
415     bool Active;
416 
417   public:
418     ParentDirectiveScope(DSAStackTy &Self, bool Activate)
419         : Self(Self), Active(false) {
420       if (Activate)
421         enable();
422     }
423     ~ParentDirectiveScope() { disable(); }
424     void disable() {
425       if (Active) {
426         --Self.IgnoredStackElements;
427         Active = false;
428       }
429     }
430     void enable() {
431       if (!Active) {
432         ++Self.IgnoredStackElements;
433         Active = true;
434       }
435     }
436   };
437 
438   /// Marks that we're started loop parsing.
439   void loopInit() {
440     assert(isOpenMPLoopDirective(getCurrentDirective()) &&
441            "Expected loop-based directive.");
442     getTopOfStack().LoopStart = true;
443   }
444   /// Start capturing of the variables in the loop context.
445   void loopStart() {
446     assert(isOpenMPLoopDirective(getCurrentDirective()) &&
447            "Expected loop-based directive.");
448     getTopOfStack().LoopStart = false;
449   }
450   /// true, if variables are captured, false otherwise.
451   bool isLoopStarted() const {
452     assert(isOpenMPLoopDirective(getCurrentDirective()) &&
453            "Expected loop-based directive.");
454     return !getTopOfStack().LoopStart;
455   }
456   /// Marks (or clears) declaration as possibly loop counter.
457   void resetPossibleLoopCounter(const Decl *D = nullptr) {
458     getTopOfStack().PossiblyLoopCounter = D ? D->getCanonicalDecl() : D;
459   }
460   /// Gets the possible loop counter decl.
461   const Decl *getPossiblyLoopCunter() const {
462     return getTopOfStack().PossiblyLoopCounter;
463   }
464   /// Start new OpenMP region stack in new non-capturing function.
465   void pushFunction() {
466     assert(!IgnoredStackElements &&
467            "cannot change stack while ignoring elements");
468     const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
469     assert(!isa<CapturingScopeInfo>(CurFnScope));
470     CurrentNonCapturingFunctionScope = CurFnScope;
471   }
472   /// Pop region stack for non-capturing function.
473   void popFunction(const FunctionScopeInfo *OldFSI) {
474     assert(!IgnoredStackElements &&
475            "cannot change stack while ignoring elements");
476     if (!Stack.empty() && Stack.back().second == OldFSI) {
477       assert(Stack.back().first.empty());
478       Stack.pop_back();
479     }
480     CurrentNonCapturingFunctionScope = nullptr;
481     for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
482       if (!isa<CapturingScopeInfo>(FSI)) {
483         CurrentNonCapturingFunctionScope = FSI;
484         break;
485       }
486     }
487   }
488 
489   void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) {
490     Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
491   }
492   const std::pair<const OMPCriticalDirective *, llvm::APSInt>
493   getCriticalWithHint(const DeclarationNameInfo &Name) const {
494     auto I = Criticals.find(Name.getAsString());
495     if (I != Criticals.end())
496       return I->second;
497     return std::make_pair(nullptr, llvm::APSInt());
498   }
499   /// If 'aligned' declaration for given variable \a D was not seen yet,
500   /// add it and return NULL; otherwise return previous occurrence's expression
501   /// for diagnostics.
502   const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE);
503   /// If 'nontemporal' declaration for given variable \a D was not seen yet,
504   /// add it and return NULL; otherwise return previous occurrence's expression
505   /// for diagnostics.
506   const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE);
507 
508   /// Register specified variable as loop control variable.
509   void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture);
510   /// Check if the specified variable is a loop control variable for
511   /// current region.
512   /// \return The index of the loop control variable in the list of associated
513   /// for-loops (from outer to inner).
514   const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const;
515   /// Check if the specified variable is a loop control variable for
516   /// parent region.
517   /// \return The index of the loop control variable in the list of associated
518   /// for-loops (from outer to inner).
519   const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const;
520   /// Check if the specified variable is a loop control variable for
521   /// current region.
522   /// \return The index of the loop control variable in the list of associated
523   /// for-loops (from outer to inner).
524   const LCDeclInfo isLoopControlVariable(const ValueDecl *D,
525                                          unsigned Level) const;
526   /// Get the loop control variable for the I-th loop (or nullptr) in
527   /// parent directive.
528   const ValueDecl *getParentLoopControlVariable(unsigned I) const;
529 
530   /// Marks the specified decl \p D as used in scan directive.
531   void markDeclAsUsedInScanDirective(ValueDecl *D) {
532     if (SharingMapTy *Stack = getSecondOnStackOrNull())
533       Stack->UsedInScanDirective.insert(D);
534   }
535 
536   /// Checks if the specified declaration was used in the inner scan directive.
537   bool isUsedInScanDirective(ValueDecl *D) const {
538     if (const SharingMapTy *Stack = getTopOfStackOrNull())
539       return Stack->UsedInScanDirective.contains(D);
540     return false;
541   }
542 
543   /// Adds explicit data sharing attribute to the specified declaration.
544   void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
545               DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0,
546               bool AppliedToPointee = false);
547 
548   /// Adds additional information for the reduction items with the reduction id
549   /// represented as an operator.
550   void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
551                                  BinaryOperatorKind BOK);
552   /// Adds additional information for the reduction items with the reduction id
553   /// represented as reduction identifier.
554   void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
555                                  const Expr *ReductionRef);
556   /// Returns the location and reduction operation from the innermost parent
557   /// region for the given \p D.
558   const DSAVarData
559   getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
560                                    BinaryOperatorKind &BOK,
561                                    Expr *&TaskgroupDescriptor) const;
562   /// Returns the location and reduction operation from the innermost parent
563   /// region for the given \p D.
564   const DSAVarData
565   getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
566                                    const Expr *&ReductionRef,
567                                    Expr *&TaskgroupDescriptor) const;
568   /// Return reduction reference expression for the current taskgroup or
569   /// parallel/worksharing directives with task reductions.
570   Expr *getTaskgroupReductionRef() const {
571     assert((getTopOfStack().Directive == OMPD_taskgroup ||
572             ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
573               isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
574              !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
575            "taskgroup reference expression requested for non taskgroup or "
576            "parallel/worksharing directive.");
577     return getTopOfStack().TaskgroupReductionRef;
578   }
579   /// Checks if the given \p VD declaration is actually a taskgroup reduction
580   /// descriptor variable at the \p Level of OpenMP regions.
581   bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
582     return getStackElemAtLevel(Level).TaskgroupReductionRef &&
583            cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
584                    ->getDecl() == VD;
585   }
586 
587   /// Returns data sharing attributes from top of the stack for the
588   /// specified declaration.
589   const DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
590   /// Returns data-sharing attributes for the specified declaration.
591   const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const;
592   /// Returns data-sharing attributes for the specified declaration.
593   const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const;
594   /// Checks if the specified variables has data-sharing attributes which
595   /// match specified \a CPred predicate in any directive which matches \a DPred
596   /// predicate.
597   const DSAVarData
598   hasDSA(ValueDecl *D,
599          const llvm::function_ref<bool(OpenMPClauseKind, bool,
600                                        DefaultDataSharingAttributes)>
601              CPred,
602          const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
603          bool FromParent) const;
604   /// Checks if the specified variables has data-sharing attributes which
605   /// match specified \a CPred predicate in any innermost directive which
606   /// matches \a DPred predicate.
607   const DSAVarData
608   hasInnermostDSA(ValueDecl *D,
609                   const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
610                   const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
611                   bool FromParent) const;
612   /// Checks if the specified variables has explicit data-sharing
613   /// attributes which match specified \a CPred predicate at the specified
614   /// OpenMP region.
615   bool
616   hasExplicitDSA(const ValueDecl *D,
617                  const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
618                  unsigned Level, bool NotLastprivate = false) const;
619 
620   /// Returns true if the directive at level \Level matches in the
621   /// specified \a DPred predicate.
622   bool hasExplicitDirective(
623       const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
624       unsigned Level) const;
625 
626   /// Finds a directive which matches specified \a DPred predicate.
627   bool hasDirective(
628       const llvm::function_ref<bool(
629           OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)>
630           DPred,
631       bool FromParent) const;
632 
633   /// Returns currently analyzed directive.
634   OpenMPDirectiveKind getCurrentDirective() const {
635     const SharingMapTy *Top = getTopOfStackOrNull();
636     return Top ? Top->Directive : OMPD_unknown;
637   }
638   /// Returns directive kind at specified level.
639   OpenMPDirectiveKind getDirective(unsigned Level) const {
640     assert(!isStackEmpty() && "No directive at specified level.");
641     return getStackElemAtLevel(Level).Directive;
642   }
643   /// Returns the capture region at the specified level.
644   OpenMPDirectiveKind getCaptureRegion(unsigned Level,
645                                        unsigned OpenMPCaptureLevel) const {
646     SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
647     getOpenMPCaptureRegions(CaptureRegions, getDirective(Level));
648     return CaptureRegions[OpenMPCaptureLevel];
649   }
650   /// Returns parent directive.
651   OpenMPDirectiveKind getParentDirective() const {
652     const SharingMapTy *Parent = getSecondOnStackOrNull();
653     return Parent ? Parent->Directive : OMPD_unknown;
654   }
655 
656   /// Add requires decl to internal vector
657   void addRequiresDecl(OMPRequiresDecl *RD) { RequiresDecls.push_back(RD); }
658 
659   /// Checks if the defined 'requires' directive has specified type of clause.
660   template <typename ClauseType> bool hasRequiresDeclWithClause() const {
661     return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
662       return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
663         return isa<ClauseType>(C);
664       });
665     });
666   }
667 
668   /// Checks for a duplicate clause amongst previously declared requires
669   /// directives
670   bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const {
671     bool IsDuplicate = false;
672     for (OMPClause *CNew : ClauseList) {
673       for (const OMPRequiresDecl *D : RequiresDecls) {
674         for (const OMPClause *CPrev : D->clauselists()) {
675           if (CNew->getClauseKind() == CPrev->getClauseKind()) {
676             SemaRef.Diag(CNew->getBeginLoc(),
677                          diag::err_omp_requires_clause_redeclaration)
678                 << getOpenMPClauseName(CNew->getClauseKind());
679             SemaRef.Diag(CPrev->getBeginLoc(),
680                          diag::note_omp_requires_previous_clause)
681                 << getOpenMPClauseName(CPrev->getClauseKind());
682             IsDuplicate = true;
683           }
684         }
685       }
686     }
687     return IsDuplicate;
688   }
689 
690   /// Add location of previously encountered target to internal vector
691   void addTargetDirLocation(SourceLocation LocStart) {
692     TargetLocations.push_back(LocStart);
693   }
694 
695   /// Add location for the first encountered atomicc directive.
696   void addAtomicDirectiveLoc(SourceLocation Loc) {
697     if (AtomicLocation.isInvalid())
698       AtomicLocation = Loc;
699   }
700 
701   /// Returns the location of the first encountered atomic directive in the
702   /// module.
703   SourceLocation getAtomicDirectiveLoc() const { return AtomicLocation; }
704 
705   // Return previously encountered target region locations.
706   ArrayRef<SourceLocation> getEncounteredTargetLocs() const {
707     return TargetLocations;
708   }
709 
710   /// Set default data sharing attribute to none.
711   void setDefaultDSANone(SourceLocation Loc) {
712     getTopOfStack().DefaultAttr = DSA_none;
713     getTopOfStack().DefaultAttrLoc = Loc;
714   }
715   /// Set default data sharing attribute to shared.
716   void setDefaultDSAShared(SourceLocation Loc) {
717     getTopOfStack().DefaultAttr = DSA_shared;
718     getTopOfStack().DefaultAttrLoc = Loc;
719   }
720   /// Set default data sharing attribute to private.
721   void setDefaultDSAPrivate(SourceLocation Loc) {
722     getTopOfStack().DefaultAttr = DSA_private;
723     getTopOfStack().DefaultAttrLoc = Loc;
724   }
725   /// Set default data sharing attribute to firstprivate.
726   void setDefaultDSAFirstPrivate(SourceLocation Loc) {
727     getTopOfStack().DefaultAttr = DSA_firstprivate;
728     getTopOfStack().DefaultAttrLoc = Loc;
729   }
730   /// Set default data mapping attribute to Modifier:Kind
731   void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,
732                          OpenMPDefaultmapClauseKind Kind, SourceLocation Loc) {
733     DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind];
734     DMI.ImplicitBehavior = M;
735     DMI.SLoc = Loc;
736   }
737   /// Check whether the implicit-behavior has been set in defaultmap
738   bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) {
739     if (VariableCategory == OMPC_DEFAULTMAP_unknown)
740       return getTopOfStack()
741                      .DefaultmapMap[OMPC_DEFAULTMAP_aggregate]
742                      .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
743              getTopOfStack()
744                      .DefaultmapMap[OMPC_DEFAULTMAP_scalar]
745                      .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
746              getTopOfStack()
747                      .DefaultmapMap[OMPC_DEFAULTMAP_pointer]
748                      .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown;
749     return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
750            OMPC_DEFAULTMAP_MODIFIER_unknown;
751   }
752 
753   ArrayRef<llvm::omp::TraitProperty> getConstructTraits() {
754     return ConstructTraits;
755   }
756   void handleConstructTrait(ArrayRef<llvm::omp::TraitProperty> Traits,
757                             bool ScopeEntry) {
758     if (ScopeEntry)
759       ConstructTraits.append(Traits.begin(), Traits.end());
760     else
761       for (llvm::omp::TraitProperty Trait : llvm::reverse(Traits)) {
762         llvm::omp::TraitProperty Top = ConstructTraits.pop_back_val();
763         assert(Top == Trait && "Something left a trait on the stack!");
764         (void)Trait;
765         (void)Top;
766       }
767   }
768 
769   DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const {
770     return getStackSize() <= Level ? DSA_unspecified
771                                    : getStackElemAtLevel(Level).DefaultAttr;
772   }
773   DefaultDataSharingAttributes getDefaultDSA() const {
774     return isStackEmpty() ? DSA_unspecified : getTopOfStack().DefaultAttr;
775   }
776   SourceLocation getDefaultDSALocation() const {
777     return isStackEmpty() ? SourceLocation() : getTopOfStack().DefaultAttrLoc;
778   }
779   OpenMPDefaultmapClauseModifier
780   getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const {
781     return isStackEmpty()
782                ? OMPC_DEFAULTMAP_MODIFIER_unknown
783                : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior;
784   }
785   OpenMPDefaultmapClauseModifier
786   getDefaultmapModifierAtLevel(unsigned Level,
787                                OpenMPDefaultmapClauseKind Kind) const {
788     return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior;
789   }
790   bool isDefaultmapCapturedByRef(unsigned Level,
791                                  OpenMPDefaultmapClauseKind Kind) const {
792     OpenMPDefaultmapClauseModifier M =
793         getDefaultmapModifierAtLevel(Level, Kind);
794     if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) {
795       return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
796              (M == OMPC_DEFAULTMAP_MODIFIER_to) ||
797              (M == OMPC_DEFAULTMAP_MODIFIER_from) ||
798              (M == OMPC_DEFAULTMAP_MODIFIER_tofrom);
799     }
800     return true;
801   }
802   static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M,
803                                      OpenMPDefaultmapClauseKind Kind) {
804     switch (Kind) {
805     case OMPC_DEFAULTMAP_scalar:
806     case OMPC_DEFAULTMAP_pointer:
807       return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) ||
808              (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) ||
809              (M == OMPC_DEFAULTMAP_MODIFIER_default);
810     case OMPC_DEFAULTMAP_aggregate:
811       return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
812     default:
813       break;
814     }
815     llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum");
816   }
817   bool mustBeFirstprivateAtLevel(unsigned Level,
818                                  OpenMPDefaultmapClauseKind Kind) const {
819     OpenMPDefaultmapClauseModifier M =
820         getDefaultmapModifierAtLevel(Level, Kind);
821     return mustBeFirstprivateBase(M, Kind);
822   }
823   bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const {
824     OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind);
825     return mustBeFirstprivateBase(M, Kind);
826   }
827 
828   /// Checks if the specified variable is a threadprivate.
829   bool isThreadPrivate(VarDecl *D) {
830     const DSAVarData DVar = getTopDSA(D, false);
831     return isOpenMPThreadPrivate(DVar.CKind);
832   }
833 
834   /// Marks current region as ordered (it has an 'ordered' clause).
835   void setOrderedRegion(bool IsOrdered, const Expr *Param,
836                         OMPOrderedClause *Clause) {
837     if (IsOrdered)
838       getTopOfStack().OrderedRegion.emplace(Param, Clause);
839     else
840       getTopOfStack().OrderedRegion.reset();
841   }
842   /// Returns true, if region is ordered (has associated 'ordered' clause),
843   /// false - otherwise.
844   bool isOrderedRegion() const {
845     if (const SharingMapTy *Top = getTopOfStackOrNull())
846       return Top->OrderedRegion.has_value();
847     return false;
848   }
849   /// Returns optional parameter for the ordered region.
850   std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
851     if (const SharingMapTy *Top = getTopOfStackOrNull())
852       if (Top->OrderedRegion)
853         return *Top->OrderedRegion;
854     return std::make_pair(nullptr, nullptr);
855   }
856   /// Returns true, if parent region is ordered (has associated
857   /// 'ordered' clause), false - otherwise.
858   bool isParentOrderedRegion() const {
859     if (const SharingMapTy *Parent = getSecondOnStackOrNull())
860       return Parent->OrderedRegion.has_value();
861     return false;
862   }
863   /// Returns optional parameter for the ordered region.
864   std::pair<const Expr *, OMPOrderedClause *>
865   getParentOrderedRegionParam() const {
866     if (const SharingMapTy *Parent = getSecondOnStackOrNull())
867       if (Parent->OrderedRegion)
868         return *Parent->OrderedRegion;
869     return std::make_pair(nullptr, nullptr);
870   }
871   /// Marks current region as having an 'order' clause.
872   void setRegionHasOrderConcurrent(bool HasOrderConcurrent) {
873     getTopOfStack().RegionHasOrderConcurrent = HasOrderConcurrent;
874   }
875   /// Returns true, if parent region is order (has associated
876   /// 'order' clause), false - otherwise.
877   bool isParentOrderConcurrent() const {
878     if (const SharingMapTy *Parent = getSecondOnStackOrNull())
879       return Parent->RegionHasOrderConcurrent;
880     return false;
881   }
882   /// Marks current region as nowait (it has a 'nowait' clause).
883   void setNowaitRegion(bool IsNowait = true) {
884     getTopOfStack().NowaitRegion = IsNowait;
885   }
886   /// Returns true, if parent region is nowait (has associated
887   /// 'nowait' clause), false - otherwise.
888   bool isParentNowaitRegion() const {
889     if (const SharingMapTy *Parent = getSecondOnStackOrNull())
890       return Parent->NowaitRegion;
891     return false;
892   }
893   /// Marks current region as untied (it has a 'untied' clause).
894   void setUntiedRegion(bool IsUntied = true) {
895     getTopOfStack().UntiedRegion = IsUntied;
896   }
897   /// Return true if current region is untied.
898   bool isUntiedRegion() const {
899     const SharingMapTy *Top = getTopOfStackOrNull();
900     return Top ? Top->UntiedRegion : false;
901   }
902   /// Marks parent region as cancel region.
903   void setParentCancelRegion(bool Cancel = true) {
904     if (SharingMapTy *Parent = getSecondOnStackOrNull())
905       Parent->CancelRegion |= Cancel;
906   }
907   /// Return true if current region has inner cancel construct.
908   bool isCancelRegion() const {
909     const SharingMapTy *Top = getTopOfStackOrNull();
910     return Top ? Top->CancelRegion : false;
911   }
912 
913   /// Mark that parent region already has scan directive.
914   void setParentHasScanDirective(SourceLocation Loc) {
915     if (SharingMapTy *Parent = getSecondOnStackOrNull())
916       Parent->PrevScanLocation = Loc;
917   }
918   /// Return true if current region has inner cancel construct.
919   bool doesParentHasScanDirective() const {
920     const SharingMapTy *Top = getSecondOnStackOrNull();
921     return Top ? Top->PrevScanLocation.isValid() : false;
922   }
923   /// Return true if current region has inner cancel construct.
924   SourceLocation getParentScanDirectiveLoc() const {
925     const SharingMapTy *Top = getSecondOnStackOrNull();
926     return Top ? Top->PrevScanLocation : SourceLocation();
927   }
928   /// Mark that parent region already has ordered directive.
929   void setParentHasOrderedDirective(SourceLocation Loc) {
930     if (SharingMapTy *Parent = getSecondOnStackOrNull())
931       Parent->PrevOrderedLocation = Loc;
932   }
933   /// Return true if current region has inner ordered construct.
934   bool doesParentHasOrderedDirective() const {
935     const SharingMapTy *Top = getSecondOnStackOrNull();
936     return Top ? Top->PrevOrderedLocation.isValid() : false;
937   }
938   /// Returns the location of the previously specified ordered directive.
939   SourceLocation getParentOrderedDirectiveLoc() const {
940     const SharingMapTy *Top = getSecondOnStackOrNull();
941     return Top ? Top->PrevOrderedLocation : SourceLocation();
942   }
943 
944   /// Set collapse value for the region.
945   void setAssociatedLoops(unsigned Val) {
946     getTopOfStack().AssociatedLoops = Val;
947     if (Val > 1)
948       getTopOfStack().HasMutipleLoops = true;
949   }
950   /// Return collapse value for region.
951   unsigned getAssociatedLoops() const {
952     const SharingMapTy *Top = getTopOfStackOrNull();
953     return Top ? Top->AssociatedLoops : 0;
954   }
955   /// Returns true if the construct is associated with multiple loops.
956   bool hasMutipleLoops() const {
957     const SharingMapTy *Top = getTopOfStackOrNull();
958     return Top ? Top->HasMutipleLoops : false;
959   }
960 
961   /// Marks current target region as one with closely nested teams
962   /// region.
963   void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
964     if (SharingMapTy *Parent = getSecondOnStackOrNull())
965       Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
966   }
967   /// Returns true, if current region has closely nested teams region.
968   bool hasInnerTeamsRegion() const {
969     return getInnerTeamsRegionLoc().isValid();
970   }
971   /// Returns location of the nested teams region (if any).
972   SourceLocation getInnerTeamsRegionLoc() const {
973     const SharingMapTy *Top = getTopOfStackOrNull();
974     return Top ? Top->InnerTeamsRegionLoc : SourceLocation();
975   }
976 
977   Scope *getCurScope() const {
978     const SharingMapTy *Top = getTopOfStackOrNull();
979     return Top ? Top->CurScope : nullptr;
980   }
981   void setContext(DeclContext *DC) { getTopOfStack().Context = DC; }
982   SourceLocation getConstructLoc() const {
983     const SharingMapTy *Top = getTopOfStackOrNull();
984     return Top ? Top->ConstructLoc : SourceLocation();
985   }
986 
987   /// Do the check specified in \a Check to all component lists and return true
988   /// if any issue is found.
989   bool checkMappableExprComponentListsForDecl(
990       const ValueDecl *VD, bool CurrentRegionOnly,
991       const llvm::function_ref<
992           bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
993                OpenMPClauseKind)>
994           Check) const {
995     if (isStackEmpty())
996       return false;
997     auto SI = begin();
998     auto SE = end();
999 
1000     if (SI == SE)
1001       return false;
1002 
1003     if (CurrentRegionOnly)
1004       SE = std::next(SI);
1005     else
1006       std::advance(SI, 1);
1007 
1008     for (; SI != SE; ++SI) {
1009       auto MI = SI->MappedExprComponents.find(VD);
1010       if (MI != SI->MappedExprComponents.end())
1011         for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
1012              MI->second.Components)
1013           if (Check(L, MI->second.Kind))
1014             return true;
1015     }
1016     return false;
1017   }
1018 
1019   /// Do the check specified in \a Check to all component lists at a given level
1020   /// and return true if any issue is found.
1021   bool checkMappableExprComponentListsForDeclAtLevel(
1022       const ValueDecl *VD, unsigned Level,
1023       const llvm::function_ref<
1024           bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
1025                OpenMPClauseKind)>
1026           Check) const {
1027     if (getStackSize() <= Level)
1028       return false;
1029 
1030     const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1031     auto MI = StackElem.MappedExprComponents.find(VD);
1032     if (MI != StackElem.MappedExprComponents.end())
1033       for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
1034            MI->second.Components)
1035         if (Check(L, MI->second.Kind))
1036           return true;
1037     return false;
1038   }
1039 
1040   /// Create a new mappable expression component list associated with a given
1041   /// declaration and initialize it with the provided list of components.
1042   void addMappableExpressionComponents(
1043       const ValueDecl *VD,
1044       OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
1045       OpenMPClauseKind WhereFoundClauseKind) {
1046     MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
1047     // Create new entry and append the new components there.
1048     MEC.Components.resize(MEC.Components.size() + 1);
1049     MEC.Components.back().append(Components.begin(), Components.end());
1050     MEC.Kind = WhereFoundClauseKind;
1051   }
1052 
1053   unsigned getNestingLevel() const {
1054     assert(!isStackEmpty());
1055     return getStackSize() - 1;
1056   }
1057   void addDoacrossDependClause(OMPClause *C, const OperatorOffsetTy &OpsOffs) {
1058     SharingMapTy *Parent = getSecondOnStackOrNull();
1059     assert(Parent && isOpenMPWorksharingDirective(Parent->Directive));
1060     Parent->DoacrossDepends.try_emplace(C, OpsOffs);
1061   }
1062   llvm::iterator_range<DoacrossClauseMapTy::const_iterator>
1063   getDoacrossDependClauses() const {
1064     const SharingMapTy &StackElem = getTopOfStack();
1065     if (isOpenMPWorksharingDirective(StackElem.Directive)) {
1066       const DoacrossClauseMapTy &Ref = StackElem.DoacrossDepends;
1067       return llvm::make_range(Ref.begin(), Ref.end());
1068     }
1069     return llvm::make_range(StackElem.DoacrossDepends.end(),
1070                             StackElem.DoacrossDepends.end());
1071   }
1072 
1073   // Store types of classes which have been explicitly mapped
1074   void addMappedClassesQualTypes(QualType QT) {
1075     SharingMapTy &StackElem = getTopOfStack();
1076     StackElem.MappedClassesQualTypes.insert(QT);
1077   }
1078 
1079   // Return set of mapped classes types
1080   bool isClassPreviouslyMapped(QualType QT) const {
1081     const SharingMapTy &StackElem = getTopOfStack();
1082     return StackElem.MappedClassesQualTypes.contains(QT);
1083   }
1084 
1085   /// Adds global declare target to the parent target region.
1086   void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) {
1087     assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
1088                E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
1089            "Expected declare target link global.");
1090     for (auto &Elem : *this) {
1091       if (isOpenMPTargetExecutionDirective(Elem.Directive)) {
1092         Elem.DeclareTargetLinkVarDecls.push_back(E);
1093         return;
1094       }
1095     }
1096   }
1097 
1098   /// Returns the list of globals with declare target link if current directive
1099   /// is target.
1100   ArrayRef<DeclRefExpr *> getLinkGlobals() const {
1101     assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) &&
1102            "Expected target executable directive.");
1103     return getTopOfStack().DeclareTargetLinkVarDecls;
1104   }
1105 
1106   /// Adds list of allocators expressions.
1107   void addInnerAllocatorExpr(Expr *E) {
1108     getTopOfStack().InnerUsedAllocators.push_back(E);
1109   }
1110   /// Return list of used allocators.
1111   ArrayRef<Expr *> getInnerAllocators() const {
1112     return getTopOfStack().InnerUsedAllocators;
1113   }
1114   /// Marks the declaration as implicitly firstprivate nin the task-based
1115   /// regions.
1116   void addImplicitTaskFirstprivate(unsigned Level, Decl *D) {
1117     getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D);
1118   }
1119   /// Checks if the decl is implicitly firstprivate in the task-based region.
1120   bool isImplicitTaskFirstprivate(Decl *D) const {
1121     return getTopOfStack().ImplicitTaskFirstprivates.contains(D);
1122   }
1123 
1124   /// Marks decl as used in uses_allocators clause as the allocator.
1125   void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) {
1126     getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind);
1127   }
1128   /// Checks if specified decl is used in uses allocator clause as the
1129   /// allocator.
1130   std::optional<UsesAllocatorsDeclKind>
1131   isUsesAllocatorsDecl(unsigned Level, const Decl *D) const {
1132     const SharingMapTy &StackElem = getTopOfStack();
1133     auto I = StackElem.UsesAllocatorsDecls.find(D);
1134     if (I == StackElem.UsesAllocatorsDecls.end())
1135       return std::nullopt;
1136     return I->getSecond();
1137   }
1138   std::optional<UsesAllocatorsDeclKind>
1139   isUsesAllocatorsDecl(const Decl *D) const {
1140     const SharingMapTy &StackElem = getTopOfStack();
1141     auto I = StackElem.UsesAllocatorsDecls.find(D);
1142     if (I == StackElem.UsesAllocatorsDecls.end())
1143       return std::nullopt;
1144     return I->getSecond();
1145   }
1146 
1147   void addDeclareMapperVarRef(Expr *Ref) {
1148     SharingMapTy &StackElem = getTopOfStack();
1149     StackElem.DeclareMapperVar = Ref;
1150   }
1151   const Expr *getDeclareMapperVarRef() const {
1152     const SharingMapTy *Top = getTopOfStackOrNull();
1153     return Top ? Top->DeclareMapperVar : nullptr;
1154   }
1155 
1156   /// Add a new iterator variable.
1157   void addIteratorVarDecl(VarDecl *VD) {
1158     SharingMapTy &StackElem = getTopOfStack();
1159     StackElem.IteratorVarDecls.push_back(VD->getCanonicalDecl());
1160   }
1161   /// Check if variable declaration is an iterator VarDecl.
1162   bool isIteratorVarDecl(const VarDecl *VD) const {
1163     const SharingMapTy *Top = getTopOfStackOrNull();
1164     if (!Top)
1165       return false;
1166 
1167     return llvm::any_of(Top->IteratorVarDecls, [VD](const VarDecl *IteratorVD) {
1168       return IteratorVD == VD->getCanonicalDecl();
1169     });
1170   }
1171   /// get captured field from ImplicitDefaultFirstprivateFDs
1172   VarDecl *getImplicitFDCapExprDecl(const FieldDecl *FD) const {
1173     const_iterator I = begin();
1174     const_iterator EndI = end();
1175     size_t StackLevel = getStackSize();
1176     for (; I != EndI; ++I) {
1177       if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private)
1178         break;
1179       StackLevel--;
1180     }
1181     assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI));
1182     if (I == EndI)
1183       return nullptr;
1184     for (const auto &IFD : I->ImplicitDefaultFirstprivateFDs)
1185       if (IFD.FD == FD && IFD.StackLevel == StackLevel)
1186         return IFD.VD;
1187     return nullptr;
1188   }
1189   /// Check if capture decl is field captured in ImplicitDefaultFirstprivateFDs
1190   bool isImplicitDefaultFirstprivateFD(VarDecl *VD) const {
1191     const_iterator I = begin();
1192     const_iterator EndI = end();
1193     for (; I != EndI; ++I)
1194       if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private)
1195         break;
1196     if (I == EndI)
1197       return false;
1198     for (const auto &IFD : I->ImplicitDefaultFirstprivateFDs)
1199       if (IFD.VD == VD)
1200         return true;
1201     return false;
1202   }
1203   /// Store capture FD info in ImplicitDefaultFirstprivateFDs
1204   void addImplicitDefaultFirstprivateFD(const FieldDecl *FD, VarDecl *VD) {
1205     iterator I = begin();
1206     const_iterator EndI = end();
1207     size_t StackLevel = getStackSize();
1208     for (; I != EndI; ++I) {
1209       if (I->DefaultAttr == DSA_private || I->DefaultAttr == DSA_firstprivate) {
1210         I->ImplicitDefaultFirstprivateFDs.emplace_back(FD, StackLevel, VD);
1211         break;
1212       }
1213       StackLevel--;
1214     }
1215     assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI));
1216   }
1217 };
1218 
1219 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1220   return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
1221 }
1222 
1223 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1224   return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) ||
1225          DKind == OMPD_unknown;
1226 }
1227 
1228 } // namespace
1229 
1230 static const Expr *getExprAsWritten(const Expr *E) {
1231   if (const auto *FE = dyn_cast<FullExpr>(E))
1232     E = FE->getSubExpr();
1233 
1234   if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
1235     E = MTE->getSubExpr();
1236 
1237   while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
1238     E = Binder->getSubExpr();
1239 
1240   if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
1241     E = ICE->getSubExprAsWritten();
1242   return E->IgnoreParens();
1243 }
1244 
1245 static Expr *getExprAsWritten(Expr *E) {
1246   return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
1247 }
1248 
1249 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
1250   if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
1251     if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
1252       D = ME->getMemberDecl();
1253   const auto *VD = dyn_cast<VarDecl>(D);
1254   const auto *FD = dyn_cast<FieldDecl>(D);
1255   if (VD != nullptr) {
1256     VD = VD->getCanonicalDecl();
1257     D = VD;
1258   } else {
1259     assert(FD);
1260     FD = FD->getCanonicalDecl();
1261     D = FD;
1262   }
1263   return D;
1264 }
1265 
1266 static ValueDecl *getCanonicalDecl(ValueDecl *D) {
1267   return const_cast<ValueDecl *>(
1268       getCanonicalDecl(const_cast<const ValueDecl *>(D)));
1269 }
1270 
1271 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
1272                                           ValueDecl *D) const {
1273   D = getCanonicalDecl(D);
1274   auto *VD = dyn_cast<VarDecl>(D);
1275   const auto *FD = dyn_cast<FieldDecl>(D);
1276   DSAVarData DVar;
1277   if (Iter == end()) {
1278     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1279     // in a region but not in construct]
1280     //  File-scope or namespace-scope variables referenced in called routines
1281     //  in the region are shared unless they appear in a threadprivate
1282     //  directive.
1283     if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
1284       DVar.CKind = OMPC_shared;
1285 
1286     // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
1287     // in a region but not in construct]
1288     //  Variables with static storage duration that are declared in called
1289     //  routines in the region are shared.
1290     if (VD && VD->hasGlobalStorage())
1291       DVar.CKind = OMPC_shared;
1292 
1293     // Non-static data members are shared by default.
1294     if (FD)
1295       DVar.CKind = OMPC_shared;
1296 
1297     return DVar;
1298   }
1299 
1300   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1301   // in a Construct, C/C++, predetermined, p.1]
1302   // Variables with automatic storage duration that are declared in a scope
1303   // inside the construct are private.
1304   if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
1305       (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
1306     DVar.CKind = OMPC_private;
1307     return DVar;
1308   }
1309 
1310   DVar.DKind = Iter->Directive;
1311   // Explicitly specified attributes and local variables with predetermined
1312   // attributes.
1313   if (Iter->SharingMap.count(D)) {
1314     const DSAInfo &Data = Iter->SharingMap.lookup(D);
1315     DVar.RefExpr = Data.RefExpr.getPointer();
1316     DVar.PrivateCopy = Data.PrivateCopy;
1317     DVar.CKind = Data.Attributes;
1318     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1319     DVar.Modifier = Data.Modifier;
1320     DVar.AppliedToPointee = Data.AppliedToPointee;
1321     return DVar;
1322   }
1323 
1324   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1325   // in a Construct, C/C++, implicitly determined, p.1]
1326   //  In a parallel or task construct, the data-sharing attributes of these
1327   //  variables are determined by the default clause, if present.
1328   switch (Iter->DefaultAttr) {
1329   case DSA_shared:
1330     DVar.CKind = OMPC_shared;
1331     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1332     return DVar;
1333   case DSA_none:
1334     return DVar;
1335   case DSA_firstprivate:
1336     if (VD && VD->getStorageDuration() == SD_Static &&
1337         VD->getDeclContext()->isFileContext()) {
1338       DVar.CKind = OMPC_unknown;
1339     } else {
1340       DVar.CKind = OMPC_firstprivate;
1341     }
1342     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1343     return DVar;
1344   case DSA_private:
1345     // each variable with static storage duration that is declared
1346     // in a namespace or global scope and referenced in the construct,
1347     // and that does not have a predetermined data-sharing attribute
1348     if (VD && VD->getStorageDuration() == SD_Static &&
1349         VD->getDeclContext()->isFileContext()) {
1350       DVar.CKind = OMPC_unknown;
1351     } else {
1352       DVar.CKind = OMPC_private;
1353     }
1354     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1355     return DVar;
1356   case DSA_unspecified:
1357     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1358     // in a Construct, implicitly determined, p.2]
1359     //  In a parallel construct, if no default clause is present, these
1360     //  variables are shared.
1361     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1362     if ((isOpenMPParallelDirective(DVar.DKind) &&
1363          !isOpenMPTaskLoopDirective(DVar.DKind)) ||
1364         isOpenMPTeamsDirective(DVar.DKind)) {
1365       DVar.CKind = OMPC_shared;
1366       return DVar;
1367     }
1368 
1369     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1370     // in a Construct, implicitly determined, p.4]
1371     //  In a task construct, if no default clause is present, a variable that in
1372     //  the enclosing context is determined to be shared by all implicit tasks
1373     //  bound to the current team is shared.
1374     if (isOpenMPTaskingDirective(DVar.DKind)) {
1375       DSAVarData DVarTemp;
1376       const_iterator I = Iter, E = end();
1377       do {
1378         ++I;
1379         // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
1380         // Referenced in a Construct, implicitly determined, p.6]
1381         //  In a task construct, if no default clause is present, a variable
1382         //  whose data-sharing attribute is not determined by the rules above is
1383         //  firstprivate.
1384         DVarTemp = getDSA(I, D);
1385         if (DVarTemp.CKind != OMPC_shared) {
1386           DVar.RefExpr = nullptr;
1387           DVar.CKind = OMPC_firstprivate;
1388           return DVar;
1389         }
1390       } while (I != E && !isImplicitTaskingRegion(I->Directive));
1391       DVar.CKind =
1392           (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1393       return DVar;
1394     }
1395   }
1396   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1397   // in a Construct, implicitly determined, p.3]
1398   //  For constructs other than task, if no default clause is present, these
1399   //  variables inherit their data-sharing attributes from the enclosing
1400   //  context.
1401   return getDSA(++Iter, D);
1402 }
1403 
1404 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
1405                                          const Expr *NewDE) {
1406   assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1407   D = getCanonicalDecl(D);
1408   SharingMapTy &StackElem = getTopOfStack();
1409   auto It = StackElem.AlignedMap.find(D);
1410   if (It == StackElem.AlignedMap.end()) {
1411     assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1412     StackElem.AlignedMap[D] = NewDE;
1413     return nullptr;
1414   }
1415   assert(It->second && "Unexpected nullptr expr in the aligned map");
1416   return It->second;
1417 }
1418 
1419 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D,
1420                                              const Expr *NewDE) {
1421   assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1422   D = getCanonicalDecl(D);
1423   SharingMapTy &StackElem = getTopOfStack();
1424   auto It = StackElem.NontemporalMap.find(D);
1425   if (It == StackElem.NontemporalMap.end()) {
1426     assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1427     StackElem.NontemporalMap[D] = NewDE;
1428     return nullptr;
1429   }
1430   assert(It->second && "Unexpected nullptr expr in the aligned map");
1431   return It->second;
1432 }
1433 
1434 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
1435   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1436   D = getCanonicalDecl(D);
1437   SharingMapTy &StackElem = getTopOfStack();
1438   StackElem.LCVMap.try_emplace(
1439       D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
1440 }
1441 
1442 const DSAStackTy::LCDeclInfo
1443 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
1444   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1445   D = getCanonicalDecl(D);
1446   const SharingMapTy &StackElem = getTopOfStack();
1447   auto It = StackElem.LCVMap.find(D);
1448   if (It != StackElem.LCVMap.end())
1449     return It->second;
1450   return {0, nullptr};
1451 }
1452 
1453 const DSAStackTy::LCDeclInfo
1454 DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const {
1455   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1456   D = getCanonicalDecl(D);
1457   for (unsigned I = Level + 1; I > 0; --I) {
1458     const SharingMapTy &StackElem = getStackElemAtLevel(I - 1);
1459     auto It = StackElem.LCVMap.find(D);
1460     if (It != StackElem.LCVMap.end())
1461       return It->second;
1462   }
1463   return {0, nullptr};
1464 }
1465 
1466 const DSAStackTy::LCDeclInfo
1467 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
1468   const SharingMapTy *Parent = getSecondOnStackOrNull();
1469   assert(Parent && "Data-sharing attributes stack is empty");
1470   D = getCanonicalDecl(D);
1471   auto It = Parent->LCVMap.find(D);
1472   if (It != Parent->LCVMap.end())
1473     return It->second;
1474   return {0, nullptr};
1475 }
1476 
1477 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
1478   const SharingMapTy *Parent = getSecondOnStackOrNull();
1479   assert(Parent && "Data-sharing attributes stack is empty");
1480   if (Parent->LCVMap.size() < I)
1481     return nullptr;
1482   for (const auto &Pair : Parent->LCVMap)
1483     if (Pair.second.first == I)
1484       return Pair.first;
1485   return nullptr;
1486 }
1487 
1488 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
1489                         DeclRefExpr *PrivateCopy, unsigned Modifier,
1490                         bool AppliedToPointee) {
1491   D = getCanonicalDecl(D);
1492   if (A == OMPC_threadprivate) {
1493     DSAInfo &Data = Threadprivates[D];
1494     Data.Attributes = A;
1495     Data.RefExpr.setPointer(E);
1496     Data.PrivateCopy = nullptr;
1497     Data.Modifier = Modifier;
1498   } else {
1499     DSAInfo &Data = getTopOfStack().SharingMap[D];
1500     assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
1501            (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
1502            (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
1503            (isLoopControlVariable(D).first && A == OMPC_private));
1504     Data.Modifier = Modifier;
1505     if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
1506       Data.RefExpr.setInt(/*IntVal=*/true);
1507       return;
1508     }
1509     const bool IsLastprivate =
1510         A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
1511     Data.Attributes = A;
1512     Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1513     Data.PrivateCopy = PrivateCopy;
1514     Data.AppliedToPointee = AppliedToPointee;
1515     if (PrivateCopy) {
1516       DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()];
1517       Data.Modifier = Modifier;
1518       Data.Attributes = A;
1519       Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1520       Data.PrivateCopy = nullptr;
1521       Data.AppliedToPointee = AppliedToPointee;
1522     }
1523   }
1524 }
1525 
1526 /// Build a variable declaration for OpenMP loop iteration variable.
1527 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
1528                              StringRef Name, const AttrVec *Attrs = nullptr,
1529                              DeclRefExpr *OrigRef = nullptr) {
1530   DeclContext *DC = SemaRef.CurContext;
1531   IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
1532   TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
1533   auto *Decl =
1534       VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
1535   if (Attrs) {
1536     for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
1537          I != E; ++I)
1538       Decl->addAttr(*I);
1539   }
1540   Decl->setImplicit();
1541   if (OrigRef) {
1542     Decl->addAttr(
1543         OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
1544   }
1545   return Decl;
1546 }
1547 
1548 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
1549                                      SourceLocation Loc,
1550                                      bool RefersToCapture = false) {
1551   D->setReferenced();
1552   D->markUsed(S.Context);
1553   return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
1554                              SourceLocation(), D, RefersToCapture, Loc, Ty,
1555                              VK_LValue);
1556 }
1557 
1558 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1559                                            BinaryOperatorKind BOK) {
1560   D = getCanonicalDecl(D);
1561   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1562   assert(
1563       getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1564       "Additional reduction info may be specified only for reduction items.");
1565   ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1566   assert(ReductionData.ReductionRange.isInvalid() &&
1567          (getTopOfStack().Directive == OMPD_taskgroup ||
1568           ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1569             isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1570            !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1571          "Additional reduction info may be specified only once for reduction "
1572          "items.");
1573   ReductionData.set(BOK, SR);
1574   Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1575   if (!TaskgroupReductionRef) {
1576     VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1577                                SemaRef.Context.VoidPtrTy, ".task_red.");
1578     TaskgroupReductionRef =
1579         buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1580   }
1581 }
1582 
1583 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1584                                            const Expr *ReductionRef) {
1585   D = getCanonicalDecl(D);
1586   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1587   assert(
1588       getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1589       "Additional reduction info may be specified only for reduction items.");
1590   ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1591   assert(ReductionData.ReductionRange.isInvalid() &&
1592          (getTopOfStack().Directive == OMPD_taskgroup ||
1593           ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1594             isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1595            !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1596          "Additional reduction info may be specified only once for reduction "
1597          "items.");
1598   ReductionData.set(ReductionRef, SR);
1599   Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1600   if (!TaskgroupReductionRef) {
1601     VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1602                                SemaRef.Context.VoidPtrTy, ".task_red.");
1603     TaskgroupReductionRef =
1604         buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1605   }
1606 }
1607 
1608 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1609     const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
1610     Expr *&TaskgroupDescriptor) const {
1611   D = getCanonicalDecl(D);
1612   assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1613   for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1614     const DSAInfo &Data = I->SharingMap.lookup(D);
1615     if (Data.Attributes != OMPC_reduction ||
1616         Data.Modifier != OMPC_REDUCTION_task)
1617       continue;
1618     const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1619     if (!ReductionData.ReductionOp ||
1620         ReductionData.ReductionOp.is<const Expr *>())
1621       return DSAVarData();
1622     SR = ReductionData.ReductionRange;
1623     BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1624     assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1625                                        "expression for the descriptor is not "
1626                                        "set.");
1627     TaskgroupDescriptor = I->TaskgroupReductionRef;
1628     return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1629                       Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1630                       /*AppliedToPointee=*/false);
1631   }
1632   return DSAVarData();
1633 }
1634 
1635 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1636     const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
1637     Expr *&TaskgroupDescriptor) const {
1638   D = getCanonicalDecl(D);
1639   assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1640   for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1641     const DSAInfo &Data = I->SharingMap.lookup(D);
1642     if (Data.Attributes != OMPC_reduction ||
1643         Data.Modifier != OMPC_REDUCTION_task)
1644       continue;
1645     const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1646     if (!ReductionData.ReductionOp ||
1647         !ReductionData.ReductionOp.is<const Expr *>())
1648       return DSAVarData();
1649     SR = ReductionData.ReductionRange;
1650     ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
1651     assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1652                                        "expression for the descriptor is not "
1653                                        "set.");
1654     TaskgroupDescriptor = I->TaskgroupReductionRef;
1655     return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1656                       Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1657                       /*AppliedToPointee=*/false);
1658   }
1659   return DSAVarData();
1660 }
1661 
1662 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const {
1663   D = D->getCanonicalDecl();
1664   for (const_iterator E = end(); I != E; ++I) {
1665     if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1666         isOpenMPTargetExecutionDirective(I->Directive)) {
1667       if (I->CurScope) {
1668         Scope *TopScope = I->CurScope->getParent();
1669         Scope *CurScope = getCurScope();
1670         while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D))
1671           CurScope = CurScope->getParent();
1672         return CurScope != TopScope;
1673       }
1674       for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent())
1675         if (I->Context == DC)
1676           return true;
1677       return false;
1678     }
1679   }
1680   return false;
1681 }
1682 
1683 static bool isConstNotMutableType(Sema &SemaRef, QualType Type,
1684                                   bool AcceptIfMutable = true,
1685                                   bool *IsClassType = nullptr) {
1686   ASTContext &Context = SemaRef.getASTContext();
1687   Type = Type.getNonReferenceType().getCanonicalType();
1688   bool IsConstant = Type.isConstant(Context);
1689   Type = Context.getBaseElementType(Type);
1690   const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus
1691                                 ? Type->getAsCXXRecordDecl()
1692                                 : nullptr;
1693   if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1694     if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1695       RD = CTD->getTemplatedDecl();
1696   if (IsClassType)
1697     *IsClassType = RD;
1698   return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD &&
1699                          RD->hasDefinition() && RD->hasMutableFields());
1700 }
1701 
1702 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D,
1703                                       QualType Type, OpenMPClauseKind CKind,
1704                                       SourceLocation ELoc,
1705                                       bool AcceptIfMutable = true,
1706                                       bool ListItemNotVar = false) {
1707   ASTContext &Context = SemaRef.getASTContext();
1708   bool IsClassType;
1709   if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) {
1710     unsigned Diag = ListItemNotVar ? diag::err_omp_const_list_item
1711                     : IsClassType  ? diag::err_omp_const_not_mutable_variable
1712                                    : diag::err_omp_const_variable;
1713     SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind);
1714     if (!ListItemNotVar && D) {
1715       const VarDecl *VD = dyn_cast<VarDecl>(D);
1716       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
1717                                VarDecl::DeclarationOnly;
1718       SemaRef.Diag(D->getLocation(),
1719                    IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1720           << D;
1721     }
1722     return true;
1723   }
1724   return false;
1725 }
1726 
1727 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1728                                                    bool FromParent) {
1729   D = getCanonicalDecl(D);
1730   DSAVarData DVar;
1731 
1732   auto *VD = dyn_cast<VarDecl>(D);
1733   auto TI = Threadprivates.find(D);
1734   if (TI != Threadprivates.end()) {
1735     DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1736     DVar.CKind = OMPC_threadprivate;
1737     DVar.Modifier = TI->getSecond().Modifier;
1738     return DVar;
1739   }
1740   if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1741     DVar.RefExpr = buildDeclRefExpr(
1742         SemaRef, VD, D->getType().getNonReferenceType(),
1743         VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1744     DVar.CKind = OMPC_threadprivate;
1745     addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1746     return DVar;
1747   }
1748   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1749   // in a Construct, C/C++, predetermined, p.1]
1750   //  Variables appearing in threadprivate directives are threadprivate.
1751   if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1752        !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1753          SemaRef.getLangOpts().OpenMPUseTLS &&
1754          SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1755       (VD && VD->getStorageClass() == SC_Register &&
1756        VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1757     DVar.RefExpr = buildDeclRefExpr(
1758         SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1759     DVar.CKind = OMPC_threadprivate;
1760     addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1761     return DVar;
1762   }
1763   if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1764       VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1765       !isLoopControlVariable(D).first) {
1766     const_iterator IterTarget =
1767         std::find_if(begin(), end(), [](const SharingMapTy &Data) {
1768           return isOpenMPTargetExecutionDirective(Data.Directive);
1769         });
1770     if (IterTarget != end()) {
1771       const_iterator ParentIterTarget = IterTarget + 1;
1772       for (const_iterator Iter = begin(); Iter != ParentIterTarget; ++Iter) {
1773         if (isOpenMPLocal(VD, Iter)) {
1774           DVar.RefExpr =
1775               buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1776                                D->getLocation());
1777           DVar.CKind = OMPC_threadprivate;
1778           return DVar;
1779         }
1780       }
1781       if (!isClauseParsingMode() || IterTarget != begin()) {
1782         auto DSAIter = IterTarget->SharingMap.find(D);
1783         if (DSAIter != IterTarget->SharingMap.end() &&
1784             isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1785           DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1786           DVar.CKind = OMPC_threadprivate;
1787           return DVar;
1788         }
1789         const_iterator End = end();
1790         if (!SemaRef.isOpenMPCapturedByRef(D,
1791                                            std::distance(ParentIterTarget, End),
1792                                            /*OpenMPCaptureLevel=*/0)) {
1793           DVar.RefExpr =
1794               buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1795                                IterTarget->ConstructLoc);
1796           DVar.CKind = OMPC_threadprivate;
1797           return DVar;
1798         }
1799       }
1800     }
1801   }
1802 
1803   if (isStackEmpty())
1804     // Not in OpenMP execution region and top scope was already checked.
1805     return DVar;
1806 
1807   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1808   // in a Construct, C/C++, predetermined, p.4]
1809   //  Static data members are shared.
1810   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1811   // in a Construct, C/C++, predetermined, p.7]
1812   //  Variables with static storage duration that are declared in a scope
1813   //  inside the construct are shared.
1814   if (VD && VD->isStaticDataMember()) {
1815     // Check for explicitly specified attributes.
1816     const_iterator I = begin();
1817     const_iterator EndI = end();
1818     if (FromParent && I != EndI)
1819       ++I;
1820     if (I != EndI) {
1821       auto It = I->SharingMap.find(D);
1822       if (It != I->SharingMap.end()) {
1823         const DSAInfo &Data = It->getSecond();
1824         DVar.RefExpr = Data.RefExpr.getPointer();
1825         DVar.PrivateCopy = Data.PrivateCopy;
1826         DVar.CKind = Data.Attributes;
1827         DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1828         DVar.DKind = I->Directive;
1829         DVar.Modifier = Data.Modifier;
1830         DVar.AppliedToPointee = Data.AppliedToPointee;
1831         return DVar;
1832       }
1833     }
1834 
1835     DVar.CKind = OMPC_shared;
1836     return DVar;
1837   }
1838 
1839   auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
1840   // The predetermined shared attribute for const-qualified types having no
1841   // mutable members was removed after OpenMP 3.1.
1842   if (SemaRef.LangOpts.OpenMP <= 31) {
1843     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1844     // in a Construct, C/C++, predetermined, p.6]
1845     //  Variables with const qualified type having no mutable member are
1846     //  shared.
1847     if (isConstNotMutableType(SemaRef, D->getType())) {
1848       // Variables with const-qualified type having no mutable member may be
1849       // listed in a firstprivate clause, even if they are static data members.
1850       DSAVarData DVarTemp = hasInnermostDSA(
1851           D,
1852           [](OpenMPClauseKind C, bool) {
1853             return C == OMPC_firstprivate || C == OMPC_shared;
1854           },
1855           MatchesAlways, FromParent);
1856       if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1857         return DVarTemp;
1858 
1859       DVar.CKind = OMPC_shared;
1860       return DVar;
1861     }
1862   }
1863 
1864   // Explicitly specified attributes and local variables with predetermined
1865   // attributes.
1866   const_iterator I = begin();
1867   const_iterator EndI = end();
1868   if (FromParent && I != EndI)
1869     ++I;
1870   if (I == EndI)
1871     return DVar;
1872   auto It = I->SharingMap.find(D);
1873   if (It != I->SharingMap.end()) {
1874     const DSAInfo &Data = It->getSecond();
1875     DVar.RefExpr = Data.RefExpr.getPointer();
1876     DVar.PrivateCopy = Data.PrivateCopy;
1877     DVar.CKind = Data.Attributes;
1878     DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1879     DVar.DKind = I->Directive;
1880     DVar.Modifier = Data.Modifier;
1881     DVar.AppliedToPointee = Data.AppliedToPointee;
1882   }
1883 
1884   return DVar;
1885 }
1886 
1887 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1888                                                         bool FromParent) const {
1889   if (isStackEmpty()) {
1890     const_iterator I;
1891     return getDSA(I, D);
1892   }
1893   D = getCanonicalDecl(D);
1894   const_iterator StartI = begin();
1895   const_iterator EndI = end();
1896   if (FromParent && StartI != EndI)
1897     ++StartI;
1898   return getDSA(StartI, D);
1899 }
1900 
1901 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1902                                                         unsigned Level) const {
1903   if (getStackSize() <= Level)
1904     return DSAVarData();
1905   D = getCanonicalDecl(D);
1906   const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level);
1907   return getDSA(StartI, D);
1908 }
1909 
1910 const DSAStackTy::DSAVarData
1911 DSAStackTy::hasDSA(ValueDecl *D,
1912                    const llvm::function_ref<bool(OpenMPClauseKind, bool,
1913                                                  DefaultDataSharingAttributes)>
1914                        CPred,
1915                    const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1916                    bool FromParent) const {
1917   if (isStackEmpty())
1918     return {};
1919   D = getCanonicalDecl(D);
1920   const_iterator I = begin();
1921   const_iterator EndI = end();
1922   if (FromParent && I != EndI)
1923     ++I;
1924   for (; I != EndI; ++I) {
1925     if (!DPred(I->Directive) &&
1926         !isImplicitOrExplicitTaskingRegion(I->Directive))
1927       continue;
1928     const_iterator NewI = I;
1929     DSAVarData DVar = getDSA(NewI, D);
1930     if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee, I->DefaultAttr))
1931       return DVar;
1932   }
1933   return {};
1934 }
1935 
1936 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1937     ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1938     const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1939     bool FromParent) const {
1940   if (isStackEmpty())
1941     return {};
1942   D = getCanonicalDecl(D);
1943   const_iterator StartI = begin();
1944   const_iterator EndI = end();
1945   if (FromParent && StartI != EndI)
1946     ++StartI;
1947   if (StartI == EndI || !DPred(StartI->Directive))
1948     return {};
1949   const_iterator NewI = StartI;
1950   DSAVarData DVar = getDSA(NewI, D);
1951   return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee))
1952              ? DVar
1953              : DSAVarData();
1954 }
1955 
1956 bool DSAStackTy::hasExplicitDSA(
1957     const ValueDecl *D,
1958     const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1959     unsigned Level, bool NotLastprivate) const {
1960   if (getStackSize() <= Level)
1961     return false;
1962   D = getCanonicalDecl(D);
1963   const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1964   auto I = StackElem.SharingMap.find(D);
1965   if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() &&
1966       CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) &&
1967       (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1968     return true;
1969   // Check predetermined rules for the loop control variables.
1970   auto LI = StackElem.LCVMap.find(D);
1971   if (LI != StackElem.LCVMap.end())
1972     return CPred(OMPC_private, /*AppliedToPointee=*/false);
1973   return false;
1974 }
1975 
1976 bool DSAStackTy::hasExplicitDirective(
1977     const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1978     unsigned Level) const {
1979   if (getStackSize() <= Level)
1980     return false;
1981   const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1982   return DPred(StackElem.Directive);
1983 }
1984 
1985 bool DSAStackTy::hasDirective(
1986     const llvm::function_ref<bool(OpenMPDirectiveKind,
1987                                   const DeclarationNameInfo &, SourceLocation)>
1988         DPred,
1989     bool FromParent) const {
1990   // We look only in the enclosing region.
1991   size_t Skip = FromParent ? 2 : 1;
1992   for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
1993        I != E; ++I) {
1994     if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1995       return true;
1996   }
1997   return false;
1998 }
1999 
2000 void Sema::InitDataSharingAttributesStack() {
2001   VarDataSharingAttributesStack = new DSAStackTy(*this);
2002 }
2003 
2004 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
2005 
2006 void Sema::pushOpenMPFunctionRegion() { DSAStack->pushFunction(); }
2007 
2008 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
2009   DSAStack->popFunction(OldFSI);
2010 }
2011 
2012 static bool isOpenMPDeviceDelayedContext(Sema &S) {
2013   assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsTargetDevice &&
2014          "Expected OpenMP device compilation.");
2015   return !S.isInOpenMPTargetExecutionDirective();
2016 }
2017 
2018 namespace {
2019 /// Status of the function emission on the host/device.
2020 enum class FunctionEmissionStatus {
2021   Emitted,
2022   Discarded,
2023   Unknown,
2024 };
2025 } // anonymous namespace
2026 
2027 Sema::SemaDiagnosticBuilder
2028 Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, unsigned DiagID,
2029                              const FunctionDecl *FD) {
2030   assert(LangOpts.OpenMP && LangOpts.OpenMPIsTargetDevice &&
2031          "Expected OpenMP device compilation.");
2032 
2033   SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
2034   if (FD) {
2035     FunctionEmissionStatus FES = getEmissionStatus(FD);
2036     switch (FES) {
2037     case FunctionEmissionStatus::Emitted:
2038       Kind = SemaDiagnosticBuilder::K_Immediate;
2039       break;
2040     case FunctionEmissionStatus::Unknown:
2041       // TODO: We should always delay diagnostics here in case a target
2042       //       region is in a function we do not emit. However, as the
2043       //       current diagnostics are associated with the function containing
2044       //       the target region and we do not emit that one, we would miss out
2045       //       on diagnostics for the target region itself. We need to anchor
2046       //       the diagnostics with the new generated function *or* ensure we
2047       //       emit diagnostics associated with the surrounding function.
2048       Kind = isOpenMPDeviceDelayedContext(*this)
2049                  ? SemaDiagnosticBuilder::K_Deferred
2050                  : SemaDiagnosticBuilder::K_Immediate;
2051       break;
2052     case FunctionEmissionStatus::TemplateDiscarded:
2053     case FunctionEmissionStatus::OMPDiscarded:
2054       Kind = SemaDiagnosticBuilder::K_Nop;
2055       break;
2056     case FunctionEmissionStatus::CUDADiscarded:
2057       llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation");
2058       break;
2059     }
2060   }
2061 
2062   return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this);
2063 }
2064 
2065 Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc,
2066                                                        unsigned DiagID,
2067                                                        const FunctionDecl *FD) {
2068   assert(LangOpts.OpenMP && !LangOpts.OpenMPIsTargetDevice &&
2069          "Expected OpenMP host compilation.");
2070 
2071   SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
2072   if (FD) {
2073     FunctionEmissionStatus FES = getEmissionStatus(FD);
2074     switch (FES) {
2075     case FunctionEmissionStatus::Emitted:
2076       Kind = SemaDiagnosticBuilder::K_Immediate;
2077       break;
2078     case FunctionEmissionStatus::Unknown:
2079       Kind = SemaDiagnosticBuilder::K_Deferred;
2080       break;
2081     case FunctionEmissionStatus::TemplateDiscarded:
2082     case FunctionEmissionStatus::OMPDiscarded:
2083     case FunctionEmissionStatus::CUDADiscarded:
2084       Kind = SemaDiagnosticBuilder::K_Nop;
2085       break;
2086     }
2087   }
2088 
2089   return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this);
2090 }
2091 
2092 static OpenMPDefaultmapClauseKind
2093 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) {
2094   if (LO.OpenMP <= 45) {
2095     if (VD->getType().getNonReferenceType()->isScalarType())
2096       return OMPC_DEFAULTMAP_scalar;
2097     return OMPC_DEFAULTMAP_aggregate;
2098   }
2099   if (VD->getType().getNonReferenceType()->isAnyPointerType())
2100     return OMPC_DEFAULTMAP_pointer;
2101   if (VD->getType().getNonReferenceType()->isScalarType())
2102     return OMPC_DEFAULTMAP_scalar;
2103   return OMPC_DEFAULTMAP_aggregate;
2104 }
2105 
2106 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
2107                                  unsigned OpenMPCaptureLevel) const {
2108   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2109 
2110   ASTContext &Ctx = getASTContext();
2111   bool IsByRef = true;
2112 
2113   // Find the directive that is associated with the provided scope.
2114   D = cast<ValueDecl>(D->getCanonicalDecl());
2115   QualType Ty = D->getType();
2116 
2117   bool IsVariableUsedInMapClause = false;
2118   if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
2119     // This table summarizes how a given variable should be passed to the device
2120     // given its type and the clauses where it appears. This table is based on
2121     // the description in OpenMP 4.5 [2.10.4, target Construct] and
2122     // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
2123     //
2124     // =========================================================================
2125     // | type |  defaultmap   | pvt | first | is_device_ptr |    map   | res.  |
2126     // |      |(tofrom:scalar)|     |  pvt  |               |has_dv_adr|       |
2127     // =========================================================================
2128     // | scl  |               |     |       |       -       |          | bycopy|
2129     // | scl  |               |  -  |   x   |       -       |     -    | bycopy|
2130     // | scl  |               |  x  |   -   |       -       |     -    | null  |
2131     // | scl  |       x       |     |       |       -       |          | byref |
2132     // | scl  |       x       |  -  |   x   |       -       |     -    | bycopy|
2133     // | scl  |       x       |  x  |   -   |       -       |     -    | null  |
2134     // | scl  |               |  -  |   -   |       -       |     x    | byref |
2135     // | scl  |       x       |  -  |   -   |       -       |     x    | byref |
2136     //
2137     // | agg  |      n.a.     |     |       |       -       |          | byref |
2138     // | agg  |      n.a.     |  -  |   x   |       -       |     -    | byref |
2139     // | agg  |      n.a.     |  x  |   -   |       -       |     -    | null  |
2140     // | agg  |      n.a.     |  -  |   -   |       -       |     x    | byref |
2141     // | agg  |      n.a.     |  -  |   -   |       -       |    x[]   | byref |
2142     //
2143     // | ptr  |      n.a.     |     |       |       -       |          | bycopy|
2144     // | ptr  |      n.a.     |  -  |   x   |       -       |     -    | bycopy|
2145     // | ptr  |      n.a.     |  x  |   -   |       -       |     -    | null  |
2146     // | ptr  |      n.a.     |  -  |   -   |       -       |     x    | byref |
2147     // | ptr  |      n.a.     |  -  |   -   |       -       |    x[]   | bycopy|
2148     // | ptr  |      n.a.     |  -  |   -   |       x       |          | bycopy|
2149     // | ptr  |      n.a.     |  -  |   -   |       x       |     x    | bycopy|
2150     // | ptr  |      n.a.     |  -  |   -   |       x       |    x[]   | bycopy|
2151     // =========================================================================
2152     // Legend:
2153     //  scl - scalar
2154     //  ptr - pointer
2155     //  agg - aggregate
2156     //  x - applies
2157     //  - - invalid in this combination
2158     //  [] - mapped with an array section
2159     //  byref - should be mapped by reference
2160     //  byval - should be mapped by value
2161     //  null - initialize a local variable to null on the device
2162     //
2163     // Observations:
2164     //  - All scalar declarations that show up in a map clause have to be passed
2165     //    by reference, because they may have been mapped in the enclosing data
2166     //    environment.
2167     //  - If the scalar value does not fit the size of uintptr, it has to be
2168     //    passed by reference, regardless the result in the table above.
2169     //  - For pointers mapped by value that have either an implicit map or an
2170     //    array section, the runtime library may pass the NULL value to the
2171     //    device instead of the value passed to it by the compiler.
2172 
2173     if (Ty->isReferenceType())
2174       Ty = Ty->castAs<ReferenceType>()->getPointeeType();
2175 
2176     // Locate map clauses and see if the variable being captured is referred to
2177     // in any of those clauses. Here we only care about variables, not fields,
2178     // because fields are part of aggregates.
2179     bool IsVariableAssociatedWithSection = false;
2180 
2181     DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2182         D, Level,
2183         [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection,
2184          D](OMPClauseMappableExprCommon::MappableExprComponentListRef
2185                 MapExprComponents,
2186             OpenMPClauseKind WhereFoundClauseKind) {
2187           // Both map and has_device_addr clauses information influences how a
2188           // variable is captured. E.g. is_device_ptr does not require changing
2189           // the default behavior.
2190           if (WhereFoundClauseKind != OMPC_map &&
2191               WhereFoundClauseKind != OMPC_has_device_addr)
2192             return false;
2193 
2194           auto EI = MapExprComponents.rbegin();
2195           auto EE = MapExprComponents.rend();
2196 
2197           assert(EI != EE && "Invalid map expression!");
2198 
2199           if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2200             IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
2201 
2202           ++EI;
2203           if (EI == EE)
2204             return false;
2205           auto Last = std::prev(EE);
2206           const auto *UO =
2207               dyn_cast<UnaryOperator>(Last->getAssociatedExpression());
2208           if ((UO && UO->getOpcode() == UO_Deref) ||
2209               isa<ArraySubscriptExpr>(Last->getAssociatedExpression()) ||
2210               isa<OMPArraySectionExpr>(Last->getAssociatedExpression()) ||
2211               isa<MemberExpr>(EI->getAssociatedExpression()) ||
2212               isa<OMPArrayShapingExpr>(Last->getAssociatedExpression())) {
2213             IsVariableAssociatedWithSection = true;
2214             // There is nothing more we need to know about this variable.
2215             return true;
2216           }
2217 
2218           // Keep looking for more map info.
2219           return false;
2220         });
2221 
2222     if (IsVariableUsedInMapClause) {
2223       // If variable is identified in a map clause it is always captured by
2224       // reference except if it is a pointer that is dereferenced somehow.
2225       IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
2226     } else {
2227       // By default, all the data that has a scalar type is mapped by copy
2228       // (except for reduction variables).
2229       // Defaultmap scalar is mutual exclusive to defaultmap pointer
2230       IsByRef = (DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
2231                  !Ty->isAnyPointerType()) ||
2232                 !Ty->isScalarType() ||
2233                 DSAStack->isDefaultmapCapturedByRef(
2234                     Level, getVariableCategoryFromDecl(LangOpts, D)) ||
2235                 DSAStack->hasExplicitDSA(
2236                     D,
2237                     [](OpenMPClauseKind K, bool AppliedToPointee) {
2238                       return K == OMPC_reduction && !AppliedToPointee;
2239                     },
2240                     Level);
2241     }
2242   }
2243 
2244   if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
2245     IsByRef =
2246         ((IsVariableUsedInMapClause &&
2247           DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) ==
2248               OMPD_target) ||
2249          !(DSAStack->hasExplicitDSA(
2250                D,
2251                [](OpenMPClauseKind K, bool AppliedToPointee) -> bool {
2252                  return K == OMPC_firstprivate ||
2253                         (K == OMPC_reduction && AppliedToPointee);
2254                },
2255                Level, /*NotLastprivate=*/true) ||
2256            DSAStack->isUsesAllocatorsDecl(Level, D))) &&
2257         // If the variable is artificial and must be captured by value - try to
2258         // capture by value.
2259         !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
2260           !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) &&
2261         // If the variable is implicitly firstprivate and scalar - capture by
2262         // copy
2263         !((DSAStack->getDefaultDSA() == DSA_firstprivate ||
2264            DSAStack->getDefaultDSA() == DSA_private) &&
2265           !DSAStack->hasExplicitDSA(
2266               D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; },
2267               Level) &&
2268           !DSAStack->isLoopControlVariable(D, Level).first);
2269   }
2270 
2271   // When passing data by copy, we need to make sure it fits the uintptr size
2272   // and alignment, because the runtime library only deals with uintptr types.
2273   // If it does not fit the uintptr size, we need to pass the data by reference
2274   // instead.
2275   if (!IsByRef && (Ctx.getTypeSizeInChars(Ty) >
2276                        Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
2277                    Ctx.getAlignOfGlobalVarInChars(Ty) >
2278                        Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
2279     IsByRef = true;
2280   }
2281 
2282   return IsByRef;
2283 }
2284 
2285 unsigned Sema::getOpenMPNestingLevel() const {
2286   assert(getLangOpts().OpenMP);
2287   return DSAStack->getNestingLevel();
2288 }
2289 
2290 bool Sema::isInOpenMPTaskUntiedContext() const {
2291   return isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
2292          DSAStack->isUntiedRegion();
2293 }
2294 
2295 bool Sema::isInOpenMPTargetExecutionDirective() const {
2296   return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) &&
2297           !DSAStack->isClauseParsingMode()) ||
2298          DSAStack->hasDirective(
2299              [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2300                 SourceLocation) -> bool {
2301                return isOpenMPTargetExecutionDirective(K);
2302              },
2303              false);
2304 }
2305 
2306 bool Sema::isOpenMPRebuildMemberExpr(ValueDecl *D) {
2307   // Only rebuild for Field.
2308   if (!dyn_cast<FieldDecl>(D))
2309     return false;
2310   DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2311       D,
2312       [](OpenMPClauseKind C, bool AppliedToPointee,
2313          DefaultDataSharingAttributes DefaultAttr) {
2314         return isOpenMPPrivate(C) && !AppliedToPointee &&
2315                (DefaultAttr == DSA_firstprivate || DefaultAttr == DSA_private);
2316       },
2317       [](OpenMPDirectiveKind) { return true; },
2318       DSAStack->isClauseParsingMode());
2319   if (DVarPrivate.CKind != OMPC_unknown)
2320     return true;
2321   return false;
2322 }
2323 
2324 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
2325                                              Expr *CaptureExpr, bool WithInit,
2326                                              DeclContext *CurContext,
2327                                              bool AsExpression);
2328 
2329 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
2330                                     unsigned StopAt) {
2331   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2332   D = getCanonicalDecl(D);
2333 
2334   auto *VD = dyn_cast<VarDecl>(D);
2335   // Do not capture constexpr variables.
2336   if (VD && VD->isConstexpr())
2337     return nullptr;
2338 
2339   // If we want to determine whether the variable should be captured from the
2340   // perspective of the current capturing scope, and we've already left all the
2341   // capturing scopes of the top directive on the stack, check from the
2342   // perspective of its parent directive (if any) instead.
2343   DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2344       *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete());
2345 
2346   // If we are attempting to capture a global variable in a directive with
2347   // 'target' we return true so that this global is also mapped to the device.
2348   //
2349   if (VD && !VD->hasLocalStorage() &&
2350       (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
2351     if (isInOpenMPTargetExecutionDirective()) {
2352       DSAStackTy::DSAVarData DVarTop =
2353           DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
2354       if (DVarTop.CKind != OMPC_unknown && DVarTop.RefExpr)
2355         return VD;
2356       // If the declaration is enclosed in a 'declare target' directive,
2357       // then it should not be captured.
2358       //
2359       if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2360         return nullptr;
2361       CapturedRegionScopeInfo *CSI = nullptr;
2362       for (FunctionScopeInfo *FSI : llvm::drop_begin(
2363                llvm::reverse(FunctionScopes),
2364                CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) {
2365         if (!isa<CapturingScopeInfo>(FSI))
2366           return nullptr;
2367         if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2368           if (RSI->CapRegionKind == CR_OpenMP) {
2369             CSI = RSI;
2370             break;
2371           }
2372       }
2373       assert(CSI && "Failed to find CapturedRegionScopeInfo");
2374       SmallVector<OpenMPDirectiveKind, 4> Regions;
2375       getOpenMPCaptureRegions(Regions,
2376                               DSAStack->getDirective(CSI->OpenMPLevel));
2377       if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task)
2378         return VD;
2379     }
2380     if (isInOpenMPDeclareTargetContext()) {
2381       // Try to mark variable as declare target if it is used in capturing
2382       // regions.
2383       if (LangOpts.OpenMP <= 45 &&
2384           !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2385         checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
2386       return nullptr;
2387     }
2388   }
2389 
2390   if (CheckScopeInfo) {
2391     bool OpenMPFound = false;
2392     for (unsigned I = StopAt + 1; I > 0; --I) {
2393       FunctionScopeInfo *FSI = FunctionScopes[I - 1];
2394       if (!isa<CapturingScopeInfo>(FSI))
2395         return nullptr;
2396       if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2397         if (RSI->CapRegionKind == CR_OpenMP) {
2398           OpenMPFound = true;
2399           break;
2400         }
2401     }
2402     if (!OpenMPFound)
2403       return nullptr;
2404   }
2405 
2406   if (DSAStack->getCurrentDirective() != OMPD_unknown &&
2407       (!DSAStack->isClauseParsingMode() ||
2408        DSAStack->getParentDirective() != OMPD_unknown)) {
2409     auto &&Info = DSAStack->isLoopControlVariable(D);
2410     if (Info.first ||
2411         (VD && VD->hasLocalStorage() &&
2412          isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) ||
2413         (VD && DSAStack->isForceVarCapturing()))
2414       return VD ? VD : Info.second;
2415     DSAStackTy::DSAVarData DVarTop =
2416         DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
2417     if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) &&
2418         (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee))
2419       return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
2420     // Threadprivate variables must not be captured.
2421     if (isOpenMPThreadPrivate(DVarTop.CKind))
2422       return nullptr;
2423     // The variable is not private or it is the variable in the directive with
2424     // default(none) clause and not used in any clause.
2425     DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2426         D,
2427         [](OpenMPClauseKind C, bool AppliedToPointee, bool) {
2428           return isOpenMPPrivate(C) && !AppliedToPointee;
2429         },
2430         [](OpenMPDirectiveKind) { return true; },
2431         DSAStack->isClauseParsingMode());
2432     // Global shared must not be captured.
2433     if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2434         ((DSAStack->getDefaultDSA() != DSA_none &&
2435           DSAStack->getDefaultDSA() != DSA_private &&
2436           DSAStack->getDefaultDSA() != DSA_firstprivate) ||
2437          DVarTop.CKind == OMPC_shared))
2438       return nullptr;
2439     auto *FD = dyn_cast<FieldDecl>(D);
2440     if (DVarPrivate.CKind != OMPC_unknown && !VD && FD &&
2441         !DVarPrivate.PrivateCopy) {
2442       DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2443           D,
2444           [](OpenMPClauseKind C, bool AppliedToPointee,
2445              DefaultDataSharingAttributes DefaultAttr) {
2446             return isOpenMPPrivate(C) && !AppliedToPointee &&
2447                    (DefaultAttr == DSA_firstprivate ||
2448                     DefaultAttr == DSA_private);
2449           },
2450           [](OpenMPDirectiveKind) { return true; },
2451           DSAStack->isClauseParsingMode());
2452       if (DVarPrivate.CKind == OMPC_unknown)
2453         return nullptr;
2454 
2455       VarDecl *VD = DSAStack->getImplicitFDCapExprDecl(FD);
2456       if (VD)
2457         return VD;
2458       if (getCurrentThisType().isNull())
2459         return nullptr;
2460       Expr *ThisExpr = BuildCXXThisExpr(SourceLocation(), getCurrentThisType(),
2461                                         /*IsImplicit=*/true);
2462       const CXXScopeSpec CS = CXXScopeSpec();
2463       Expr *ME = BuildMemberExpr(ThisExpr, /*IsArrow=*/true, SourceLocation(),
2464                                  NestedNameSpecifierLoc(), SourceLocation(), FD,
2465                                  DeclAccessPair::make(FD, FD->getAccess()),
2466                                  /*HadMultipleCandidates=*/false,
2467                                  DeclarationNameInfo(), FD->getType(),
2468                                  VK_LValue, OK_Ordinary);
2469       OMPCapturedExprDecl *CD = buildCaptureDecl(
2470           *this, FD->getIdentifier(), ME, DVarPrivate.CKind != OMPC_private,
2471           CurContext->getParent(), /*AsExpression=*/false);
2472       DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
2473           *this, CD, CD->getType().getNonReferenceType(), SourceLocation());
2474       VD = cast<VarDecl>(VDPrivateRefExpr->getDecl());
2475       DSAStack->addImplicitDefaultFirstprivateFD(FD, VD);
2476       return VD;
2477     }
2478     if (DVarPrivate.CKind != OMPC_unknown ||
2479         (VD && (DSAStack->getDefaultDSA() == DSA_none ||
2480                 DSAStack->getDefaultDSA() == DSA_private ||
2481                 DSAStack->getDefaultDSA() == DSA_firstprivate)))
2482       return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2483   }
2484   return nullptr;
2485 }
2486 
2487 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
2488                                         unsigned Level) const {
2489   FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2490 }
2491 
2492 void Sema::startOpenMPLoop() {
2493   assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2494   if (isOpenMPLoopDirective(DSAStack->getCurrentDirective()))
2495     DSAStack->loopInit();
2496 }
2497 
2498 void Sema::startOpenMPCXXRangeFor() {
2499   assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2500   if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2501     DSAStack->resetPossibleLoopCounter();
2502     DSAStack->loopStart();
2503   }
2504 }
2505 
2506 OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level,
2507                                            unsigned CapLevel) const {
2508   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2509   if (DSAStack->getCurrentDirective() != OMPD_unknown &&
2510       (!DSAStack->isClauseParsingMode() ||
2511        DSAStack->getParentDirective() != OMPD_unknown)) {
2512     DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2513         D,
2514         [](OpenMPClauseKind C, bool AppliedToPointee,
2515            DefaultDataSharingAttributes DefaultAttr) {
2516           return isOpenMPPrivate(C) && !AppliedToPointee &&
2517                  DefaultAttr == DSA_private;
2518         },
2519         [](OpenMPDirectiveKind) { return true; },
2520         DSAStack->isClauseParsingMode());
2521     if (DVarPrivate.CKind == OMPC_private && isa<OMPCapturedExprDecl>(D) &&
2522         DSAStack->isImplicitDefaultFirstprivateFD(cast<VarDecl>(D)) &&
2523         !DSAStack->isLoopControlVariable(D).first)
2524       return OMPC_private;
2525   }
2526   if (DSAStack->hasExplicitDirective(isOpenMPTaskingDirective, Level)) {
2527     bool IsTriviallyCopyable =
2528         D->getType().getNonReferenceType().isTriviallyCopyableType(Context) &&
2529         !D->getType()
2530              .getNonReferenceType()
2531              .getCanonicalType()
2532              ->getAsCXXRecordDecl();
2533     OpenMPDirectiveKind DKind = DSAStack->getDirective(Level);
2534     SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2535     getOpenMPCaptureRegions(CaptureRegions, DKind);
2536     if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) &&
2537         (IsTriviallyCopyable ||
2538          !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) {
2539       if (DSAStack->hasExplicitDSA(
2540               D,
2541               [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; },
2542               Level, /*NotLastprivate=*/true))
2543         return OMPC_firstprivate;
2544       DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2545       if (DVar.CKind != OMPC_shared &&
2546           !DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) {
2547         DSAStack->addImplicitTaskFirstprivate(Level, D);
2548         return OMPC_firstprivate;
2549       }
2550     }
2551   }
2552   if (isOpenMPLoopDirective(DSAStack->getCurrentDirective()) &&
2553       !isOpenMPLoopTransformationDirective(DSAStack->getCurrentDirective())) {
2554     if (DSAStack->getAssociatedLoops() > 0 && !DSAStack->isLoopStarted()) {
2555       DSAStack->resetPossibleLoopCounter(D);
2556       DSAStack->loopStart();
2557       return OMPC_private;
2558     }
2559     if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
2560          DSAStack->isLoopControlVariable(D).first) &&
2561         !DSAStack->hasExplicitDSA(
2562             D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; },
2563             Level) &&
2564         !isOpenMPSimdDirective(DSAStack->getCurrentDirective()))
2565       return OMPC_private;
2566   }
2567   if (const auto *VD = dyn_cast<VarDecl>(D)) {
2568     if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2569         DSAStack->isForceVarCapturing() &&
2570         !DSAStack->hasExplicitDSA(
2571             D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; },
2572             Level))
2573       return OMPC_private;
2574   }
2575   // User-defined allocators are private since they must be defined in the
2576   // context of target region.
2577   if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) &&
2578       DSAStack->isUsesAllocatorsDecl(Level, D).value_or(
2579           DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2580           DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2581     return OMPC_private;
2582   return (DSAStack->hasExplicitDSA(
2583               D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; },
2584               Level) ||
2585           (DSAStack->isClauseParsingMode() &&
2586            DSAStack->getClauseParsingMode() == OMPC_private) ||
2587           // Consider taskgroup reduction descriptor variable a private
2588           // to avoid possible capture in the region.
2589           (DSAStack->hasExplicitDirective(
2590                [](OpenMPDirectiveKind K) {
2591                  return K == OMPD_taskgroup ||
2592                         ((isOpenMPParallelDirective(K) ||
2593                           isOpenMPWorksharingDirective(K)) &&
2594                          !isOpenMPSimdDirective(K));
2595                },
2596                Level) &&
2597            DSAStack->isTaskgroupReductionRef(D, Level)))
2598              ? OMPC_private
2599              : OMPC_unknown;
2600 }
2601 
2602 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
2603                                 unsigned Level) {
2604   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2605   D = getCanonicalDecl(D);
2606   OpenMPClauseKind OMPC = OMPC_unknown;
2607   for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) {
2608     const unsigned NewLevel = I - 1;
2609     if (DSAStack->hasExplicitDSA(
2610             D,
2611             [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) {
2612               if (isOpenMPPrivate(K) && !AppliedToPointee) {
2613                 OMPC = K;
2614                 return true;
2615               }
2616               return false;
2617             },
2618             NewLevel))
2619       break;
2620     if (DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2621             D, NewLevel,
2622             [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
2623                OpenMPClauseKind) { return true; })) {
2624       OMPC = OMPC_map;
2625       break;
2626     }
2627     if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2628                                        NewLevel)) {
2629       OMPC = OMPC_map;
2630       if (DSAStack->mustBeFirstprivateAtLevel(
2631               NewLevel, getVariableCategoryFromDecl(LangOpts, D)))
2632         OMPC = OMPC_firstprivate;
2633       break;
2634     }
2635   }
2636   if (OMPC != OMPC_unknown)
2637     FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC)));
2638 }
2639 
2640 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level,
2641                                       unsigned CaptureLevel) const {
2642   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2643   // Return true if the current level is no longer enclosed in a target region.
2644 
2645   SmallVector<OpenMPDirectiveKind, 4> Regions;
2646   getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level));
2647   const auto *VD = dyn_cast<VarDecl>(D);
2648   return VD && !VD->hasLocalStorage() &&
2649          DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2650                                         Level) &&
2651          Regions[CaptureLevel] != OMPD_task;
2652 }
2653 
2654 bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level,
2655                                       unsigned CaptureLevel) const {
2656   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2657   // Return true if the current level is no longer enclosed in a target region.
2658 
2659   if (const auto *VD = dyn_cast<VarDecl>(D)) {
2660     if (!VD->hasLocalStorage()) {
2661       if (isInOpenMPTargetExecutionDirective())
2662         return true;
2663       DSAStackTy::DSAVarData TopDVar =
2664           DSAStack->getTopDSA(D, /*FromParent=*/false);
2665       unsigned NumLevels =
2666           getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2667       if (Level == 0)
2668         // non-file scope static variale with default(firstprivate)
2669         // should be gloabal captured.
2670         return (NumLevels == CaptureLevel + 1 &&
2671                 (TopDVar.CKind != OMPC_shared ||
2672                  DSAStack->getDefaultDSA() == DSA_firstprivate));
2673       do {
2674         --Level;
2675         DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2676         if (DVar.CKind != OMPC_shared)
2677           return true;
2678       } while (Level > 0);
2679     }
2680   }
2681   return true;
2682 }
2683 
2684 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
2685 
2686 void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,
2687                                           OMPTraitInfo &TI) {
2688   OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2689 }
2690 
2691 void Sema::ActOnOpenMPEndDeclareVariant() {
2692   assert(isInOpenMPDeclareVariantScope() &&
2693          "Not in OpenMP declare variant scope!");
2694 
2695   OMPDeclareVariantScopes.pop_back();
2696 }
2697 
2698 void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller,
2699                                          const FunctionDecl *Callee,
2700                                          SourceLocation Loc) {
2701   assert(LangOpts.OpenMP && "Expected OpenMP compilation mode.");
2702   std::optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2703       OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl());
2704   // Ignore host functions during device analyzis.
2705   if (LangOpts.OpenMPIsTargetDevice &&
2706       (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host))
2707     return;
2708   // Ignore nohost functions during host analyzis.
2709   if (!LangOpts.OpenMPIsTargetDevice && DevTy &&
2710       *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2711     return;
2712   const FunctionDecl *FD = Callee->getMostRecentDecl();
2713   DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2714   if (LangOpts.OpenMPIsTargetDevice && DevTy &&
2715       *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2716     // Diagnose host function called during device codegen.
2717     StringRef HostDevTy =
2718         getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host);
2719     Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2720     Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2721          diag::note_omp_marked_device_type_here)
2722         << HostDevTy;
2723     return;
2724   }
2725   if (!LangOpts.OpenMPIsTargetDevice && !LangOpts.OpenMPOffloadMandatory &&
2726       DevTy && *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2727     // In OpenMP 5.2 or later, if the function has a host variant then allow
2728     // that to be called instead
2729     auto &&HasHostAttr = [](const FunctionDecl *Callee) {
2730       for (OMPDeclareVariantAttr *A :
2731            Callee->specific_attrs<OMPDeclareVariantAttr>()) {
2732         auto *DeclRefVariant = cast<DeclRefExpr>(A->getVariantFuncRef());
2733         auto *VariantFD = cast<FunctionDecl>(DeclRefVariant->getDecl());
2734         std::optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2735             OMPDeclareTargetDeclAttr::getDeviceType(
2736                 VariantFD->getMostRecentDecl());
2737         if (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host)
2738           return true;
2739       }
2740       return false;
2741     };
2742     if (getLangOpts().OpenMP >= 52 &&
2743         Callee->hasAttr<OMPDeclareVariantAttr>() && HasHostAttr(Callee))
2744       return;
2745     // Diagnose nohost function called during host codegen.
2746     StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
2747         OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2748     Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
2749     Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2750          diag::note_omp_marked_device_type_here)
2751         << NoHostDevTy;
2752   }
2753 }
2754 
2755 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
2756                                const DeclarationNameInfo &DirName,
2757                                Scope *CurScope, SourceLocation Loc) {
2758   DSAStack->push(DKind, DirName, CurScope, Loc);
2759   PushExpressionEvaluationContext(
2760       ExpressionEvaluationContext::PotentiallyEvaluated);
2761 }
2762 
2763 void Sema::StartOpenMPClause(OpenMPClauseKind K) {
2764   DSAStack->setClauseParsingMode(K);
2765 }
2766 
2767 void Sema::EndOpenMPClause() {
2768   DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
2769   CleanupVarDeclMarking();
2770 }
2771 
2772 static std::pair<ValueDecl *, bool>
2773 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
2774                SourceRange &ERange, bool AllowArraySection = false,
2775                StringRef DiagType = "");
2776 
2777 /// Check consistency of the reduction clauses.
2778 static void checkReductionClauses(Sema &S, DSAStackTy *Stack,
2779                                   ArrayRef<OMPClause *> Clauses) {
2780   bool InscanFound = false;
2781   SourceLocation InscanLoc;
2782   // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions.
2783   // A reduction clause without the inscan reduction-modifier may not appear on
2784   // a construct on which a reduction clause with the inscan reduction-modifier
2785   // appears.
2786   for (OMPClause *C : Clauses) {
2787     if (C->getClauseKind() != OMPC_reduction)
2788       continue;
2789     auto *RC = cast<OMPReductionClause>(C);
2790     if (RC->getModifier() == OMPC_REDUCTION_inscan) {
2791       InscanFound = true;
2792       InscanLoc = RC->getModifierLoc();
2793       continue;
2794     }
2795     if (RC->getModifier() == OMPC_REDUCTION_task) {
2796       // OpenMP 5.0, 2.19.5.4 reduction Clause.
2797       // A reduction clause with the task reduction-modifier may only appear on
2798       // a parallel construct, a worksharing construct or a combined or
2799       // composite construct for which any of the aforementioned constructs is a
2800       // constituent construct and simd or loop are not constituent constructs.
2801       OpenMPDirectiveKind CurDir = Stack->getCurrentDirective();
2802       if (!(isOpenMPParallelDirective(CurDir) ||
2803             isOpenMPWorksharingDirective(CurDir)) ||
2804           isOpenMPSimdDirective(CurDir))
2805         S.Diag(RC->getModifierLoc(),
2806                diag::err_omp_reduction_task_not_parallel_or_worksharing);
2807       continue;
2808     }
2809   }
2810   if (InscanFound) {
2811     for (OMPClause *C : Clauses) {
2812       if (C->getClauseKind() != OMPC_reduction)
2813         continue;
2814       auto *RC = cast<OMPReductionClause>(C);
2815       if (RC->getModifier() != OMPC_REDUCTION_inscan) {
2816         S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown
2817                    ? RC->getBeginLoc()
2818                    : RC->getModifierLoc(),
2819                diag::err_omp_inscan_reduction_expected);
2820         S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction);
2821         continue;
2822       }
2823       for (Expr *Ref : RC->varlists()) {
2824         assert(Ref && "NULL expr in OpenMP nontemporal clause.");
2825         SourceLocation ELoc;
2826         SourceRange ERange;
2827         Expr *SimpleRefExpr = Ref;
2828         auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
2829                                   /*AllowArraySection=*/true);
2830         ValueDecl *D = Res.first;
2831         if (!D)
2832           continue;
2833         if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) {
2834           S.Diag(Ref->getExprLoc(),
2835                  diag::err_omp_reduction_not_inclusive_exclusive)
2836               << Ref->getSourceRange();
2837         }
2838       }
2839     }
2840   }
2841 }
2842 
2843 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
2844                                  ArrayRef<OMPClause *> Clauses);
2845 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2846                                  bool WithInit);
2847 
2848 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2849                               const ValueDecl *D,
2850                               const DSAStackTy::DSAVarData &DVar,
2851                               bool IsLoopIterVar = false);
2852 
2853 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
2854   // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
2855   //  A variable of class type (or array thereof) that appears in a lastprivate
2856   //  clause requires an accessible, unambiguous default constructor for the
2857   //  class type, unless the list item is also specified in a firstprivate
2858   //  clause.
2859   if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2860     for (OMPClause *C : D->clauses()) {
2861       if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2862         SmallVector<Expr *, 8> PrivateCopies;
2863         for (Expr *DE : Clause->varlists()) {
2864           if (DE->isValueDependent() || DE->isTypeDependent()) {
2865             PrivateCopies.push_back(nullptr);
2866             continue;
2867           }
2868           auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2869           auto *VD = cast<VarDecl>(DRE->getDecl());
2870           QualType Type = VD->getType().getNonReferenceType();
2871           const DSAStackTy::DSAVarData DVar =
2872               DSAStack->getTopDSA(VD, /*FromParent=*/false);
2873           if (DVar.CKind == OMPC_lastprivate) {
2874             // Generate helper private variable and initialize it with the
2875             // default value. The address of the original variable is replaced
2876             // by the address of the new private variable in CodeGen. This new
2877             // variable is not added to IdResolver, so the code in the OpenMP
2878             // region uses original variable for proper diagnostics.
2879             VarDecl *VDPrivate = buildVarDecl(
2880                 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
2881                 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
2882             ActOnUninitializedDecl(VDPrivate);
2883             if (VDPrivate->isInvalidDecl()) {
2884               PrivateCopies.push_back(nullptr);
2885               continue;
2886             }
2887             PrivateCopies.push_back(buildDeclRefExpr(
2888                 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
2889           } else {
2890             // The variable is also a firstprivate, so initialization sequence
2891             // for private copy is generated already.
2892             PrivateCopies.push_back(nullptr);
2893           }
2894         }
2895         Clause->setPrivateCopies(PrivateCopies);
2896         continue;
2897       }
2898       // Finalize nontemporal clause by handling private copies, if any.
2899       if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) {
2900         SmallVector<Expr *, 8> PrivateRefs;
2901         for (Expr *RefExpr : Clause->varlists()) {
2902           assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
2903           SourceLocation ELoc;
2904           SourceRange ERange;
2905           Expr *SimpleRefExpr = RefExpr;
2906           auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
2907           if (Res.second)
2908             // It will be analyzed later.
2909             PrivateRefs.push_back(RefExpr);
2910           ValueDecl *D = Res.first;
2911           if (!D)
2912             continue;
2913 
2914           const DSAStackTy::DSAVarData DVar =
2915               DSAStack->getTopDSA(D, /*FromParent=*/false);
2916           PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2917                                                  : SimpleRefExpr);
2918         }
2919         Clause->setPrivateRefs(PrivateRefs);
2920         continue;
2921       }
2922       if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) {
2923         for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) {
2924           OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I);
2925           auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts());
2926           if (!DRE)
2927             continue;
2928           ValueDecl *VD = DRE->getDecl();
2929           if (!VD || !isa<VarDecl>(VD))
2930             continue;
2931           DSAStackTy::DSAVarData DVar =
2932               DSAStack->getTopDSA(VD, /*FromParent=*/false);
2933           // OpenMP [2.12.5, target Construct]
2934           // Memory allocators that appear in a uses_allocators clause cannot
2935           // appear in other data-sharing attribute clauses or data-mapping
2936           // attribute clauses in the same construct.
2937           Expr *MapExpr = nullptr;
2938           if (DVar.RefExpr ||
2939               DSAStack->checkMappableExprComponentListsForDecl(
2940                   VD, /*CurrentRegionOnly=*/true,
2941                   [VD, &MapExpr](
2942                       OMPClauseMappableExprCommon::MappableExprComponentListRef
2943                           MapExprComponents,
2944                       OpenMPClauseKind C) {
2945                     auto MI = MapExprComponents.rbegin();
2946                     auto ME = MapExprComponents.rend();
2947                     if (MI != ME &&
2948                         MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2949                             VD->getCanonicalDecl()) {
2950                       MapExpr = MI->getAssociatedExpression();
2951                       return true;
2952                     }
2953                     return false;
2954                   })) {
2955             Diag(D.Allocator->getExprLoc(),
2956                  diag::err_omp_allocator_used_in_clauses)
2957                 << D.Allocator->getSourceRange();
2958             if (DVar.RefExpr)
2959               reportOriginalDsa(*this, DSAStack, VD, DVar);
2960             else
2961               Diag(MapExpr->getExprLoc(), diag::note_used_here)
2962                   << MapExpr->getSourceRange();
2963           }
2964         }
2965         continue;
2966       }
2967     }
2968     // Check allocate clauses.
2969     if (!CurContext->isDependentContext())
2970       checkAllocateClauses(*this, DSAStack, D->clauses());
2971     checkReductionClauses(*this, DSAStack, D->clauses());
2972   }
2973 
2974   DSAStack->pop();
2975   DiscardCleanupsInEvaluationContext();
2976   PopExpressionEvaluationContext();
2977 }
2978 
2979 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
2980                                      Expr *NumIterations, Sema &SemaRef,
2981                                      Scope *S, DSAStackTy *Stack);
2982 
2983 namespace {
2984 
2985 class VarDeclFilterCCC final : public CorrectionCandidateCallback {
2986 private:
2987   Sema &SemaRef;
2988 
2989 public:
2990   explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
2991   bool ValidateCandidate(const TypoCorrection &Candidate) override {
2992     NamedDecl *ND = Candidate.getCorrectionDecl();
2993     if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
2994       return VD->hasGlobalStorage() &&
2995              SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2996                                    SemaRef.getCurScope());
2997     }
2998     return false;
2999   }
3000 
3001   std::unique_ptr<CorrectionCandidateCallback> clone() override {
3002     return std::make_unique<VarDeclFilterCCC>(*this);
3003   }
3004 };
3005 
3006 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
3007 private:
3008   Sema &SemaRef;
3009 
3010 public:
3011   explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
3012   bool ValidateCandidate(const TypoCorrection &Candidate) override {
3013     NamedDecl *ND = Candidate.getCorrectionDecl();
3014     if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
3015                isa<FunctionDecl>(ND))) {
3016       return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
3017                                    SemaRef.getCurScope());
3018     }
3019     return false;
3020   }
3021 
3022   std::unique_ptr<CorrectionCandidateCallback> clone() override {
3023     return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
3024   }
3025 };
3026 
3027 } // namespace
3028 
3029 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
3030                                          CXXScopeSpec &ScopeSpec,
3031                                          const DeclarationNameInfo &Id,
3032                                          OpenMPDirectiveKind Kind) {
3033   LookupResult Lookup(*this, Id, LookupOrdinaryName);
3034   LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
3035 
3036   if (Lookup.isAmbiguous())
3037     return ExprError();
3038 
3039   VarDecl *VD;
3040   if (!Lookup.isSingleResult()) {
3041     VarDeclFilterCCC CCC(*this);
3042     if (TypoCorrection Corrected =
3043             CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
3044                         CTK_ErrorRecovery)) {
3045       diagnoseTypo(Corrected,
3046                    PDiag(Lookup.empty()
3047                              ? diag::err_undeclared_var_use_suggest
3048                              : diag::err_omp_expected_var_arg_suggest)
3049                        << Id.getName());
3050       VD = Corrected.getCorrectionDeclAs<VarDecl>();
3051     } else {
3052       Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
3053                                        : diag::err_omp_expected_var_arg)
3054           << Id.getName();
3055       return ExprError();
3056     }
3057   } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
3058     Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
3059     Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
3060     return ExprError();
3061   }
3062   Lookup.suppressDiagnostics();
3063 
3064   // OpenMP [2.9.2, Syntax, C/C++]
3065   //   Variables must be file-scope, namespace-scope, or static block-scope.
3066   if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
3067     Diag(Id.getLoc(), diag::err_omp_global_var_arg)
3068         << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
3069     bool IsDecl =
3070         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3071     Diag(VD->getLocation(),
3072          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3073         << VD;
3074     return ExprError();
3075   }
3076 
3077   VarDecl *CanonicalVD = VD->getCanonicalDecl();
3078   NamedDecl *ND = CanonicalVD;
3079   // OpenMP [2.9.2, Restrictions, C/C++, p.2]
3080   //   A threadprivate directive for file-scope variables must appear outside
3081   //   any definition or declaration.
3082   if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
3083       !getCurLexicalContext()->isTranslationUnit()) {
3084     Diag(Id.getLoc(), diag::err_omp_var_scope)
3085         << getOpenMPDirectiveName(Kind) << VD;
3086     bool IsDecl =
3087         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3088     Diag(VD->getLocation(),
3089          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3090         << VD;
3091     return ExprError();
3092   }
3093   // OpenMP [2.9.2, Restrictions, C/C++, p.3]
3094   //   A threadprivate directive for static class member variables must appear
3095   //   in the class definition, in the same scope in which the member
3096   //   variables are declared.
3097   if (CanonicalVD->isStaticDataMember() &&
3098       !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
3099     Diag(Id.getLoc(), diag::err_omp_var_scope)
3100         << getOpenMPDirectiveName(Kind) << VD;
3101     bool IsDecl =
3102         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3103     Diag(VD->getLocation(),
3104          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3105         << VD;
3106     return ExprError();
3107   }
3108   // OpenMP [2.9.2, Restrictions, C/C++, p.4]
3109   //   A threadprivate directive for namespace-scope variables must appear
3110   //   outside any definition or declaration other than the namespace
3111   //   definition itself.
3112   if (CanonicalVD->getDeclContext()->isNamespace() &&
3113       (!getCurLexicalContext()->isFileContext() ||
3114        !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
3115     Diag(Id.getLoc(), diag::err_omp_var_scope)
3116         << getOpenMPDirectiveName(Kind) << VD;
3117     bool IsDecl =
3118         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3119     Diag(VD->getLocation(),
3120          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3121         << VD;
3122     return ExprError();
3123   }
3124   // OpenMP [2.9.2, Restrictions, C/C++, p.6]
3125   //   A threadprivate directive for static block-scope variables must appear
3126   //   in the scope of the variable and not in a nested scope.
3127   if (CanonicalVD->isLocalVarDecl() && CurScope &&
3128       !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
3129     Diag(Id.getLoc(), diag::err_omp_var_scope)
3130         << getOpenMPDirectiveName(Kind) << VD;
3131     bool IsDecl =
3132         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3133     Diag(VD->getLocation(),
3134          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3135         << VD;
3136     return ExprError();
3137   }
3138 
3139   // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
3140   //   A threadprivate directive must lexically precede all references to any
3141   //   of the variables in its list.
3142   if (Kind == OMPD_threadprivate && VD->isUsed() &&
3143       !DSAStack->isThreadPrivate(VD)) {
3144     Diag(Id.getLoc(), diag::err_omp_var_used)
3145         << getOpenMPDirectiveName(Kind) << VD;
3146     return ExprError();
3147   }
3148 
3149   QualType ExprType = VD->getType().getNonReferenceType();
3150   return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
3151                              SourceLocation(), VD,
3152                              /*RefersToEnclosingVariableOrCapture=*/false,
3153                              Id.getLoc(), ExprType, VK_LValue);
3154 }
3155 
3156 Sema::DeclGroupPtrTy
3157 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
3158                                         ArrayRef<Expr *> VarList) {
3159   if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
3160     CurContext->addDecl(D);
3161     return DeclGroupPtrTy::make(DeclGroupRef(D));
3162   }
3163   return nullptr;
3164 }
3165 
3166 namespace {
3167 class LocalVarRefChecker final
3168     : public ConstStmtVisitor<LocalVarRefChecker, bool> {
3169   Sema &SemaRef;
3170 
3171 public:
3172   bool VisitDeclRefExpr(const DeclRefExpr *E) {
3173     if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3174       if (VD->hasLocalStorage()) {
3175         SemaRef.Diag(E->getBeginLoc(),
3176                      diag::err_omp_local_var_in_threadprivate_init)
3177             << E->getSourceRange();
3178         SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
3179             << VD << VD->getSourceRange();
3180         return true;
3181       }
3182     }
3183     return false;
3184   }
3185   bool VisitStmt(const Stmt *S) {
3186     for (const Stmt *Child : S->children()) {
3187       if (Child && Visit(Child))
3188         return true;
3189     }
3190     return false;
3191   }
3192   explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
3193 };
3194 } // namespace
3195 
3196 OMPThreadPrivateDecl *
3197 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
3198   SmallVector<Expr *, 8> Vars;
3199   for (Expr *RefExpr : VarList) {
3200     auto *DE = cast<DeclRefExpr>(RefExpr);
3201     auto *VD = cast<VarDecl>(DE->getDecl());
3202     SourceLocation ILoc = DE->getExprLoc();
3203 
3204     // Mark variable as used.
3205     VD->setReferenced();
3206     VD->markUsed(Context);
3207 
3208     QualType QType = VD->getType();
3209     if (QType->isDependentType() || QType->isInstantiationDependentType()) {
3210       // It will be analyzed later.
3211       Vars.push_back(DE);
3212       continue;
3213     }
3214 
3215     // OpenMP [2.9.2, Restrictions, C/C++, p.10]
3216     //   A threadprivate variable must not have an incomplete type.
3217     if (RequireCompleteType(ILoc, VD->getType(),
3218                             diag::err_omp_threadprivate_incomplete_type)) {
3219       continue;
3220     }
3221 
3222     // OpenMP [2.9.2, Restrictions, C/C++, p.10]
3223     //   A threadprivate variable must not have a reference type.
3224     if (VD->getType()->isReferenceType()) {
3225       Diag(ILoc, diag::err_omp_ref_type_arg)
3226           << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
3227       bool IsDecl =
3228           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3229       Diag(VD->getLocation(),
3230            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3231           << VD;
3232       continue;
3233     }
3234 
3235     // Check if this is a TLS variable. If TLS is not being supported, produce
3236     // the corresponding diagnostic.
3237     if ((VD->getTLSKind() != VarDecl::TLS_None &&
3238          !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
3239            getLangOpts().OpenMPUseTLS &&
3240            getASTContext().getTargetInfo().isTLSSupported())) ||
3241         (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3242          !VD->isLocalVarDecl())) {
3243       Diag(ILoc, diag::err_omp_var_thread_local)
3244           << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
3245       bool IsDecl =
3246           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3247       Diag(VD->getLocation(),
3248            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3249           << VD;
3250       continue;
3251     }
3252 
3253     // Check if initial value of threadprivate variable reference variable with
3254     // local storage (it is not supported by runtime).
3255     if (const Expr *Init = VD->getAnyInitializer()) {
3256       LocalVarRefChecker Checker(*this);
3257       if (Checker.Visit(Init))
3258         continue;
3259     }
3260 
3261     Vars.push_back(RefExpr);
3262     DSAStack->addDSA(VD, DE, OMPC_threadprivate);
3263     VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3264         Context, SourceRange(Loc, Loc)));
3265     if (ASTMutationListener *ML = Context.getASTMutationListener())
3266       ML->DeclarationMarkedOpenMPThreadPrivate(VD);
3267   }
3268   OMPThreadPrivateDecl *D = nullptr;
3269   if (!Vars.empty()) {
3270     D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
3271                                      Vars);
3272     D->setAccess(AS_public);
3273   }
3274   return D;
3275 }
3276 
3277 static OMPAllocateDeclAttr::AllocatorTypeTy
3278 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
3279   if (!Allocator)
3280     return OMPAllocateDeclAttr::OMPNullMemAlloc;
3281   if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3282       Allocator->isInstantiationDependent() ||
3283       Allocator->containsUnexpandedParameterPack())
3284     return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3285   auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3286   llvm::FoldingSetNodeID AEId;
3287   const Expr *AE = Allocator->IgnoreParenImpCasts();
3288   AE->IgnoreImpCasts()->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
3289   for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
3290     auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
3291     const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
3292     llvm::FoldingSetNodeID DAEId;
3293     DefAllocator->IgnoreImpCasts()->Profile(DAEId, S.getASTContext(),
3294                                             /*Canonical=*/true);
3295     if (AEId == DAEId) {
3296       AllocatorKindRes = AllocatorKind;
3297       break;
3298     }
3299   }
3300   return AllocatorKindRes;
3301 }
3302 
3303 static bool checkPreviousOMPAllocateAttribute(
3304     Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
3305     OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
3306   if (!VD->hasAttr<OMPAllocateDeclAttr>())
3307     return false;
3308   const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
3309   Expr *PrevAllocator = A->getAllocator();
3310   OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3311       getAllocatorKind(S, Stack, PrevAllocator);
3312   bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3313   if (AllocatorsMatch &&
3314       AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3315       Allocator && PrevAllocator) {
3316     const Expr *AE = Allocator->IgnoreParenImpCasts();
3317     const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
3318     llvm::FoldingSetNodeID AEId, PAEId;
3319     AE->Profile(AEId, S.Context, /*Canonical=*/true);
3320     PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
3321     AllocatorsMatch = AEId == PAEId;
3322   }
3323   if (!AllocatorsMatch) {
3324     SmallString<256> AllocatorBuffer;
3325     llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3326     if (Allocator)
3327       Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
3328     SmallString<256> PrevAllocatorBuffer;
3329     llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3330     if (PrevAllocator)
3331       PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
3332                                  S.getPrintingPolicy());
3333 
3334     SourceLocation AllocatorLoc =
3335         Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
3336     SourceRange AllocatorRange =
3337         Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
3338     SourceLocation PrevAllocatorLoc =
3339         PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3340     SourceRange PrevAllocatorRange =
3341         PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3342     S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3343         << (Allocator ? 1 : 0) << AllocatorStream.str()
3344         << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3345         << AllocatorRange;
3346     S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3347         << PrevAllocatorRange;
3348     return true;
3349   }
3350   return false;
3351 }
3352 
3353 static void
3354 applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
3355                           OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3356                           Expr *Allocator, Expr *Alignment, SourceRange SR) {
3357   if (VD->hasAttr<OMPAllocateDeclAttr>())
3358     return;
3359   if (Alignment &&
3360       (Alignment->isTypeDependent() || Alignment->isValueDependent() ||
3361        Alignment->isInstantiationDependent() ||
3362        Alignment->containsUnexpandedParameterPack()))
3363     // Apply later when we have a usable value.
3364     return;
3365   if (Allocator &&
3366       (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3367        Allocator->isInstantiationDependent() ||
3368        Allocator->containsUnexpandedParameterPack()))
3369     return;
3370   auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
3371                                                 Allocator, Alignment, SR);
3372   VD->addAttr(A);
3373   if (ASTMutationListener *ML = S.Context.getASTMutationListener())
3374     ML->DeclarationMarkedOpenMPAllocate(VD, A);
3375 }
3376 
3377 Sema::DeclGroupPtrTy
3378 Sema::ActOnOpenMPAllocateDirective(SourceLocation Loc, ArrayRef<Expr *> VarList,
3379                                    ArrayRef<OMPClause *> Clauses,
3380                                    DeclContext *Owner) {
3381   assert(Clauses.size() <= 2 && "Expected at most two clauses.");
3382   Expr *Alignment = nullptr;
3383   Expr *Allocator = nullptr;
3384   if (Clauses.empty()) {
3385     // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
3386     // allocate directives that appear in a target region must specify an
3387     // allocator clause unless a requires directive with the dynamic_allocators
3388     // clause is present in the same compilation unit.
3389     if (LangOpts.OpenMPIsTargetDevice &&
3390         !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
3391       targetDiag(Loc, diag::err_expected_allocator_clause);
3392   } else {
3393     for (const OMPClause *C : Clauses)
3394       if (const auto *AC = dyn_cast<OMPAllocatorClause>(C))
3395         Allocator = AC->getAllocator();
3396       else if (const auto *AC = dyn_cast<OMPAlignClause>(C))
3397         Alignment = AC->getAlignment();
3398       else
3399         llvm_unreachable("Unexpected clause on allocate directive");
3400   }
3401   OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3402       getAllocatorKind(*this, DSAStack, Allocator);
3403   SmallVector<Expr *, 8> Vars;
3404   for (Expr *RefExpr : VarList) {
3405     auto *DE = cast<DeclRefExpr>(RefExpr);
3406     auto *VD = cast<VarDecl>(DE->getDecl());
3407 
3408     // Check if this is a TLS variable or global register.
3409     if (VD->getTLSKind() != VarDecl::TLS_None ||
3410         VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
3411         (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3412          !VD->isLocalVarDecl()))
3413       continue;
3414 
3415     // If the used several times in the allocate directive, the same allocator
3416     // must be used.
3417     if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD,
3418                                           AllocatorKind, Allocator))
3419       continue;
3420 
3421     // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
3422     // If a list item has a static storage type, the allocator expression in the
3423     // allocator clause must be a constant expression that evaluates to one of
3424     // the predefined memory allocator values.
3425     if (Allocator && VD->hasGlobalStorage()) {
3426       if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3427         Diag(Allocator->getExprLoc(),
3428              diag::err_omp_expected_predefined_allocator)
3429             << Allocator->getSourceRange();
3430         bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
3431                       VarDecl::DeclarationOnly;
3432         Diag(VD->getLocation(),
3433              IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3434             << VD;
3435         continue;
3436       }
3437     }
3438 
3439     Vars.push_back(RefExpr);
3440     applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, Alignment,
3441                               DE->getSourceRange());
3442   }
3443   if (Vars.empty())
3444     return nullptr;
3445   if (!Owner)
3446     Owner = getCurLexicalContext();
3447   auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
3448   D->setAccess(AS_public);
3449   Owner->addDecl(D);
3450   return DeclGroupPtrTy::make(DeclGroupRef(D));
3451 }
3452 
3453 Sema::DeclGroupPtrTy
3454 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
3455                                    ArrayRef<OMPClause *> ClauseList) {
3456   OMPRequiresDecl *D = nullptr;
3457   if (!CurContext->isFileContext()) {
3458     Diag(Loc, diag::err_omp_invalid_scope) << "requires";
3459   } else {
3460     D = CheckOMPRequiresDecl(Loc, ClauseList);
3461     if (D) {
3462       CurContext->addDecl(D);
3463       DSAStack->addRequiresDecl(D);
3464     }
3465   }
3466   return DeclGroupPtrTy::make(DeclGroupRef(D));
3467 }
3468 
3469 void Sema::ActOnOpenMPAssumesDirective(SourceLocation Loc,
3470                                        OpenMPDirectiveKind DKind,
3471                                        ArrayRef<std::string> Assumptions,
3472                                        bool SkippedClauses) {
3473   if (!SkippedClauses && Assumptions.empty())
3474     Diag(Loc, diag::err_omp_no_clause_for_directive)
3475         << llvm::omp::getAllAssumeClauseOptions()
3476         << llvm::omp::getOpenMPDirectiveName(DKind);
3477 
3478   auto *AA = AssumptionAttr::Create(Context, llvm::join(Assumptions, ","), Loc);
3479   if (DKind == llvm::omp::Directive::OMPD_begin_assumes) {
3480     OMPAssumeScoped.push_back(AA);
3481     return;
3482   }
3483 
3484   // Global assumes without assumption clauses are ignored.
3485   if (Assumptions.empty())
3486     return;
3487 
3488   assert(DKind == llvm::omp::Directive::OMPD_assumes &&
3489          "Unexpected omp assumption directive!");
3490   OMPAssumeGlobal.push_back(AA);
3491 
3492   // The OMPAssumeGlobal scope above will take care of new declarations but
3493   // we also want to apply the assumption to existing ones, e.g., to
3494   // declarations in included headers. To this end, we traverse all existing
3495   // declaration contexts and annotate function declarations here.
3496   SmallVector<DeclContext *, 8> DeclContexts;
3497   auto *Ctx = CurContext;
3498   while (Ctx->getLexicalParent())
3499     Ctx = Ctx->getLexicalParent();
3500   DeclContexts.push_back(Ctx);
3501   while (!DeclContexts.empty()) {
3502     DeclContext *DC = DeclContexts.pop_back_val();
3503     for (auto *SubDC : DC->decls()) {
3504       if (SubDC->isInvalidDecl())
3505         continue;
3506       if (auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) {
3507         DeclContexts.push_back(CTD->getTemplatedDecl());
3508         llvm::append_range(DeclContexts, CTD->specializations());
3509         continue;
3510       }
3511       if (auto *DC = dyn_cast<DeclContext>(SubDC))
3512         DeclContexts.push_back(DC);
3513       if (auto *F = dyn_cast<FunctionDecl>(SubDC)) {
3514         F->addAttr(AA);
3515         continue;
3516       }
3517     }
3518   }
3519 }
3520 
3521 void Sema::ActOnOpenMPEndAssumesDirective() {
3522   assert(isInOpenMPAssumeScope() && "Not in OpenMP assumes scope!");
3523   OMPAssumeScoped.pop_back();
3524 }
3525 
3526 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
3527                                             ArrayRef<OMPClause *> ClauseList) {
3528   /// For target specific clauses, the requires directive cannot be
3529   /// specified after the handling of any of the target regions in the
3530   /// current compilation unit.
3531   ArrayRef<SourceLocation> TargetLocations =
3532       DSAStack->getEncounteredTargetLocs();
3533   SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc();
3534   if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) {
3535     for (const OMPClause *CNew : ClauseList) {
3536       // Check if any of the requires clauses affect target regions.
3537       if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3538           isa<OMPUnifiedAddressClause>(CNew) ||
3539           isa<OMPReverseOffloadClause>(CNew) ||
3540           isa<OMPDynamicAllocatorsClause>(CNew)) {
3541         Diag(Loc, diag::err_omp_directive_before_requires)
3542             << "target" << getOpenMPClauseName(CNew->getClauseKind());
3543         for (SourceLocation TargetLoc : TargetLocations) {
3544           Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3545               << "target";
3546         }
3547       } else if (!AtomicLoc.isInvalid() &&
3548                  isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3549         Diag(Loc, diag::err_omp_directive_before_requires)
3550             << "atomic" << getOpenMPClauseName(CNew->getClauseKind());
3551         Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3552             << "atomic";
3553       }
3554     }
3555   }
3556 
3557   if (!DSAStack->hasDuplicateRequiresClause(ClauseList))
3558     return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
3559                                    ClauseList);
3560   return nullptr;
3561 }
3562 
3563 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
3564                               const ValueDecl *D,
3565                               const DSAStackTy::DSAVarData &DVar,
3566                               bool IsLoopIterVar) {
3567   if (DVar.RefExpr) {
3568     SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3569         << getOpenMPClauseName(DVar.CKind);
3570     return;
3571   }
3572   enum {
3573     PDSA_StaticMemberShared,
3574     PDSA_StaticLocalVarShared,
3575     PDSA_LoopIterVarPrivate,
3576     PDSA_LoopIterVarLinear,
3577     PDSA_LoopIterVarLastprivate,
3578     PDSA_ConstVarShared,
3579     PDSA_GlobalVarShared,
3580     PDSA_TaskVarFirstprivate,
3581     PDSA_LocalVarPrivate,
3582     PDSA_Implicit
3583   } Reason = PDSA_Implicit;
3584   bool ReportHint = false;
3585   auto ReportLoc = D->getLocation();
3586   auto *VD = dyn_cast<VarDecl>(D);
3587   if (IsLoopIterVar) {
3588     if (DVar.CKind == OMPC_private)
3589       Reason = PDSA_LoopIterVarPrivate;
3590     else if (DVar.CKind == OMPC_lastprivate)
3591       Reason = PDSA_LoopIterVarLastprivate;
3592     else
3593       Reason = PDSA_LoopIterVarLinear;
3594   } else if (isOpenMPTaskingDirective(DVar.DKind) &&
3595              DVar.CKind == OMPC_firstprivate) {
3596     Reason = PDSA_TaskVarFirstprivate;
3597     ReportLoc = DVar.ImplicitDSALoc;
3598   } else if (VD && VD->isStaticLocal())
3599     Reason = PDSA_StaticLocalVarShared;
3600   else if (VD && VD->isStaticDataMember())
3601     Reason = PDSA_StaticMemberShared;
3602   else if (VD && VD->isFileVarDecl())
3603     Reason = PDSA_GlobalVarShared;
3604   else if (D->getType().isConstant(SemaRef.getASTContext()))
3605     Reason = PDSA_ConstVarShared;
3606   else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
3607     ReportHint = true;
3608     Reason = PDSA_LocalVarPrivate;
3609   }
3610   if (Reason != PDSA_Implicit) {
3611     SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3612         << Reason << ReportHint
3613         << getOpenMPDirectiveName(Stack->getCurrentDirective());
3614   } else if (DVar.ImplicitDSALoc.isValid()) {
3615     SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3616         << getOpenMPClauseName(DVar.CKind);
3617   }
3618 }
3619 
3620 static OpenMPMapClauseKind
3621 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,
3622                              bool IsAggregateOrDeclareTarget) {
3623   OpenMPMapClauseKind Kind = OMPC_MAP_unknown;
3624   switch (M) {
3625   case OMPC_DEFAULTMAP_MODIFIER_alloc:
3626     Kind = OMPC_MAP_alloc;
3627     break;
3628   case OMPC_DEFAULTMAP_MODIFIER_to:
3629     Kind = OMPC_MAP_to;
3630     break;
3631   case OMPC_DEFAULTMAP_MODIFIER_from:
3632     Kind = OMPC_MAP_from;
3633     break;
3634   case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3635     Kind = OMPC_MAP_tofrom;
3636     break;
3637   case OMPC_DEFAULTMAP_MODIFIER_present:
3638     // OpenMP 5.1 [2.21.7.3] defaultmap clause, Description]
3639     // If implicit-behavior is present, each variable referenced in the
3640     // construct in the category specified by variable-category is treated as if
3641     // it had been listed in a map clause with the map-type of alloc and
3642     // map-type-modifier of present.
3643     Kind = OMPC_MAP_alloc;
3644     break;
3645   case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3646   case OMPC_DEFAULTMAP_MODIFIER_last:
3647     llvm_unreachable("Unexpected defaultmap implicit behavior");
3648   case OMPC_DEFAULTMAP_MODIFIER_none:
3649   case OMPC_DEFAULTMAP_MODIFIER_default:
3650   case OMPC_DEFAULTMAP_MODIFIER_unknown:
3651     // IsAggregateOrDeclareTarget could be true if:
3652     // 1. the implicit behavior for aggregate is tofrom
3653     // 2. it's a declare target link
3654     if (IsAggregateOrDeclareTarget) {
3655       Kind = OMPC_MAP_tofrom;
3656       break;
3657     }
3658     llvm_unreachable("Unexpected defaultmap implicit behavior");
3659   }
3660   assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known");
3661   return Kind;
3662 }
3663 
3664 namespace {
3665 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
3666   DSAStackTy *Stack;
3667   Sema &SemaRef;
3668   bool ErrorFound = false;
3669   bool TryCaptureCXXThisMembers = false;
3670   CapturedStmt *CS = nullptr;
3671   const static unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
3672   llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
3673   llvm::SmallVector<Expr *, 4> ImplicitPrivate;
3674   llvm::SmallVector<Expr *, 4> ImplicitMap[DefaultmapKindNum][OMPC_MAP_delete];
3675   llvm::SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
3676       ImplicitMapModifier[DefaultmapKindNum];
3677   Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
3678   llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3679 
3680   void VisitSubCaptures(OMPExecutableDirective *S) {
3681     // Check implicitly captured variables.
3682     if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
3683       return;
3684     if (S->getDirectiveKind() == OMPD_atomic ||
3685         S->getDirectiveKind() == OMPD_critical ||
3686         S->getDirectiveKind() == OMPD_section ||
3687         S->getDirectiveKind() == OMPD_master ||
3688         S->getDirectiveKind() == OMPD_masked ||
3689         isOpenMPLoopTransformationDirective(S->getDirectiveKind())) {
3690       Visit(S->getAssociatedStmt());
3691       return;
3692     }
3693     visitSubCaptures(S->getInnermostCapturedStmt());
3694     // Try to capture inner this->member references to generate correct mappings
3695     // and diagnostics.
3696     if (TryCaptureCXXThisMembers ||
3697         (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3698          llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3699                       [](const CapturedStmt::Capture &C) {
3700                         return C.capturesThis();
3701                       }))) {
3702       bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3703       TryCaptureCXXThisMembers = true;
3704       Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3705       TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3706     }
3707     // In tasks firstprivates are not captured anymore, need to analyze them
3708     // explicitly.
3709     if (isOpenMPTaskingDirective(S->getDirectiveKind()) &&
3710         !isOpenMPTaskLoopDirective(S->getDirectiveKind())) {
3711       for (OMPClause *C : S->clauses())
3712         if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) {
3713           for (Expr *Ref : FC->varlists())
3714             Visit(Ref);
3715         }
3716     }
3717   }
3718 
3719 public:
3720   void VisitDeclRefExpr(DeclRefExpr *E) {
3721     if (TryCaptureCXXThisMembers || E->isTypeDependent() ||
3722         E->isValueDependent() || E->containsUnexpandedParameterPack() ||
3723         E->isInstantiationDependent())
3724       return;
3725     if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3726       // Check the datasharing rules for the expressions in the clauses.
3727       if (!CS || (isa<OMPCapturedExprDecl>(VD) && !CS->capturesVariable(VD) &&
3728                   !Stack->getTopDSA(VD, /*FromParent=*/false).RefExpr &&
3729                   !Stack->isImplicitDefaultFirstprivateFD(VD))) {
3730         if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3731           if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3732             Visit(CED->getInit());
3733             return;
3734           }
3735       } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
3736         // Do not analyze internal variables and do not enclose them into
3737         // implicit clauses.
3738         if (!Stack->isImplicitDefaultFirstprivateFD(VD))
3739           return;
3740       VD = VD->getCanonicalDecl();
3741       // Skip internally declared variables.
3742       if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) &&
3743           !Stack->isImplicitDefaultFirstprivateFD(VD) &&
3744           !Stack->isImplicitTaskFirstprivate(VD))
3745         return;
3746       // Skip allocators in uses_allocators clauses.
3747       if (Stack->isUsesAllocatorsDecl(VD))
3748         return;
3749 
3750       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
3751       // Check if the variable has explicit DSA set and stop analysis if it so.
3752       if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3753         return;
3754 
3755       // Skip internally declared static variables.
3756       std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3757           OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3758       if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
3759           (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
3760            !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3761           !Stack->isImplicitDefaultFirstprivateFD(VD) &&
3762           !Stack->isImplicitTaskFirstprivate(VD))
3763         return;
3764 
3765       SourceLocation ELoc = E->getExprLoc();
3766       OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3767       // The default(none) clause requires that each variable that is referenced
3768       // in the construct, and does not have a predetermined data-sharing
3769       // attribute, must have its data-sharing attribute explicitly determined
3770       // by being listed in a data-sharing attribute clause.
3771       if (DVar.CKind == OMPC_unknown &&
3772           (Stack->getDefaultDSA() == DSA_none ||
3773            Stack->getDefaultDSA() == DSA_private ||
3774            Stack->getDefaultDSA() == DSA_firstprivate) &&
3775           isImplicitOrExplicitTaskingRegion(DKind) &&
3776           VarsWithInheritedDSA.count(VD) == 0) {
3777         bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3778         if (!InheritedDSA && (Stack->getDefaultDSA() == DSA_firstprivate ||
3779                               Stack->getDefaultDSA() == DSA_private)) {
3780           DSAStackTy::DSAVarData DVar =
3781               Stack->getImplicitDSA(VD, /*FromParent=*/false);
3782           InheritedDSA = DVar.CKind == OMPC_unknown;
3783         }
3784         if (InheritedDSA)
3785           VarsWithInheritedDSA[VD] = E;
3786         if (Stack->getDefaultDSA() == DSA_none)
3787           return;
3788       }
3789 
3790       // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description]
3791       // If implicit-behavior is none, each variable referenced in the
3792       // construct that does not have a predetermined data-sharing attribute
3793       // and does not appear in a to or link clause on a declare target
3794       // directive must be listed in a data-mapping attribute clause, a
3795       // data-sharing attribute clause (including a data-sharing attribute
3796       // clause on a combined construct where target. is one of the
3797       // constituent constructs), or an is_device_ptr clause.
3798       OpenMPDefaultmapClauseKind ClauseKind =
3799           getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD);
3800       if (SemaRef.getLangOpts().OpenMP >= 50) {
3801         bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3802                               OMPC_DEFAULTMAP_MODIFIER_none;
3803         if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3804             VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3805           // Only check for data-mapping attribute and is_device_ptr here
3806           // since we have already make sure that the declaration does not
3807           // have a data-sharing attribute above
3808           if (!Stack->checkMappableExprComponentListsForDecl(
3809                   VD, /*CurrentRegionOnly=*/true,
3810                   [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef
3811                            MapExprComponents,
3812                        OpenMPClauseKind) {
3813                     auto MI = MapExprComponents.rbegin();
3814                     auto ME = MapExprComponents.rend();
3815                     return MI != ME && MI->getAssociatedDeclaration() == VD;
3816                   })) {
3817             VarsWithInheritedDSA[VD] = E;
3818             return;
3819           }
3820         }
3821       }
3822       if (SemaRef.getLangOpts().OpenMP > 50) {
3823         bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) ==
3824                                  OMPC_DEFAULTMAP_MODIFIER_present;
3825         if (IsModifierPresent) {
3826           if (!llvm::is_contained(ImplicitMapModifier[ClauseKind],
3827                                   OMPC_MAP_MODIFIER_present)) {
3828             ImplicitMapModifier[ClauseKind].push_back(
3829                 OMPC_MAP_MODIFIER_present);
3830           }
3831         }
3832       }
3833 
3834       if (isOpenMPTargetExecutionDirective(DKind) &&
3835           !Stack->isLoopControlVariable(VD).first) {
3836         if (!Stack->checkMappableExprComponentListsForDecl(
3837                 VD, /*CurrentRegionOnly=*/true,
3838                 [this](OMPClauseMappableExprCommon::MappableExprComponentListRef
3839                            StackComponents,
3840                        OpenMPClauseKind) {
3841                   if (SemaRef.LangOpts.OpenMP >= 50)
3842                     return !StackComponents.empty();
3843                   // Variable is used if it has been marked as an array, array
3844                   // section, array shaping or the variable iself.
3845                   return StackComponents.size() == 1 ||
3846                          llvm::all_of(
3847                              llvm::drop_begin(llvm::reverse(StackComponents)),
3848                              [](const OMPClauseMappableExprCommon::
3849                                     MappableComponent &MC) {
3850                                return MC.getAssociatedDeclaration() ==
3851                                           nullptr &&
3852                                       (isa<OMPArraySectionExpr>(
3853                                            MC.getAssociatedExpression()) ||
3854                                        isa<OMPArrayShapingExpr>(
3855                                            MC.getAssociatedExpression()) ||
3856                                        isa<ArraySubscriptExpr>(
3857                                            MC.getAssociatedExpression()));
3858                              });
3859                 })) {
3860           bool IsFirstprivate = false;
3861           // By default lambdas are captured as firstprivates.
3862           if (const auto *RD =
3863                   VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
3864             IsFirstprivate = RD->isLambda();
3865           IsFirstprivate =
3866               IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3867           if (IsFirstprivate) {
3868             ImplicitFirstprivate.emplace_back(E);
3869           } else {
3870             OpenMPDefaultmapClauseModifier M =
3871                 Stack->getDefaultmapModifier(ClauseKind);
3872             OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3873                 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3874             ImplicitMap[ClauseKind][Kind].emplace_back(E);
3875           }
3876           return;
3877         }
3878       }
3879 
3880       // OpenMP [2.9.3.6, Restrictions, p.2]
3881       //  A list item that appears in a reduction clause of the innermost
3882       //  enclosing worksharing or parallel construct may not be accessed in an
3883       //  explicit task.
3884       DVar = Stack->hasInnermostDSA(
3885           VD,
3886           [](OpenMPClauseKind C, bool AppliedToPointee) {
3887             return C == OMPC_reduction && !AppliedToPointee;
3888           },
3889           [](OpenMPDirectiveKind K) {
3890             return isOpenMPParallelDirective(K) ||
3891                    isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3892           },
3893           /*FromParent=*/true);
3894       if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3895         ErrorFound = true;
3896         SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3897         reportOriginalDsa(SemaRef, Stack, VD, DVar);
3898         return;
3899       }
3900 
3901       // Define implicit data-sharing attributes for task.
3902       DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
3903       if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) ||
3904            (((Stack->getDefaultDSA() == DSA_firstprivate &&
3905               DVar.CKind == OMPC_firstprivate) ||
3906              (Stack->getDefaultDSA() == DSA_private &&
3907               DVar.CKind == OMPC_private)) &&
3908             !DVar.RefExpr)) &&
3909           !Stack->isLoopControlVariable(VD).first) {
3910         if (Stack->getDefaultDSA() == DSA_private)
3911           ImplicitPrivate.push_back(E);
3912         else
3913           ImplicitFirstprivate.push_back(E);
3914         return;
3915       }
3916 
3917       // Store implicitly used globals with declare target link for parent
3918       // target.
3919       if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
3920           *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3921         Stack->addToParentTargetRegionLinkGlobals(E);
3922         return;
3923       }
3924     }
3925   }
3926   void VisitMemberExpr(MemberExpr *E) {
3927     if (E->isTypeDependent() || E->isValueDependent() ||
3928         E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
3929       return;
3930     auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
3931     OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3932     if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) {
3933       if (!FD)
3934         return;
3935       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
3936       // Check if the variable has explicit DSA set and stop analysis if it
3937       // so.
3938       if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3939         return;
3940 
3941       if (isOpenMPTargetExecutionDirective(DKind) &&
3942           !Stack->isLoopControlVariable(FD).first &&
3943           !Stack->checkMappableExprComponentListsForDecl(
3944               FD, /*CurrentRegionOnly=*/true,
3945               [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3946                      StackComponents,
3947                  OpenMPClauseKind) {
3948                 return isa<CXXThisExpr>(
3949                     cast<MemberExpr>(
3950                         StackComponents.back().getAssociatedExpression())
3951                         ->getBase()
3952                         ->IgnoreParens());
3953               })) {
3954         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
3955         //  A bit-field cannot appear in a map clause.
3956         //
3957         if (FD->isBitField())
3958           return;
3959 
3960         // Check to see if the member expression is referencing a class that
3961         // has already been explicitly mapped
3962         if (Stack->isClassPreviouslyMapped(TE->getType()))
3963           return;
3964 
3965         OpenMPDefaultmapClauseModifier Modifier =
3966             Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3967         OpenMPDefaultmapClauseKind ClauseKind =
3968             getVariableCategoryFromDecl(SemaRef.getLangOpts(), FD);
3969         OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3970             Modifier, /*IsAggregateOrDeclareTarget*/ true);
3971         ImplicitMap[ClauseKind][Kind].emplace_back(E);
3972         return;
3973       }
3974 
3975       SourceLocation ELoc = E->getExprLoc();
3976       // OpenMP [2.9.3.6, Restrictions, p.2]
3977       //  A list item that appears in a reduction clause of the innermost
3978       //  enclosing worksharing or parallel construct may not be accessed in
3979       //  an  explicit task.
3980       DVar = Stack->hasInnermostDSA(
3981           FD,
3982           [](OpenMPClauseKind C, bool AppliedToPointee) {
3983             return C == OMPC_reduction && !AppliedToPointee;
3984           },
3985           [](OpenMPDirectiveKind K) {
3986             return isOpenMPParallelDirective(K) ||
3987                    isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3988           },
3989           /*FromParent=*/true);
3990       if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3991         ErrorFound = true;
3992         SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3993         reportOriginalDsa(SemaRef, Stack, FD, DVar);
3994         return;
3995       }
3996 
3997       // Define implicit data-sharing attributes for task.
3998       DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
3999       if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
4000           !Stack->isLoopControlVariable(FD).first) {
4001         // Check if there is a captured expression for the current field in the
4002         // region. Do not mark it as firstprivate unless there is no captured
4003         // expression.
4004         // TODO: try to make it firstprivate.
4005         if (DVar.CKind != OMPC_unknown)
4006           ImplicitFirstprivate.push_back(E);
4007       }
4008       return;
4009     }
4010     if (isOpenMPTargetExecutionDirective(DKind)) {
4011       OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
4012       if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
4013                                         Stack->getCurrentDirective(),
4014                                         /*NoDiagnose=*/true))
4015         return;
4016       const auto *VD = cast<ValueDecl>(
4017           CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
4018       if (!Stack->checkMappableExprComponentListsForDecl(
4019               VD, /*CurrentRegionOnly=*/true,
4020               [&CurComponents](
4021                   OMPClauseMappableExprCommon::MappableExprComponentListRef
4022                       StackComponents,
4023                   OpenMPClauseKind) {
4024                 auto CCI = CurComponents.rbegin();
4025                 auto CCE = CurComponents.rend();
4026                 for (const auto &SC : llvm::reverse(StackComponents)) {
4027                   // Do both expressions have the same kind?
4028                   if (CCI->getAssociatedExpression()->getStmtClass() !=
4029                       SC.getAssociatedExpression()->getStmtClass())
4030                     if (!((isa<OMPArraySectionExpr>(
4031                                SC.getAssociatedExpression()) ||
4032                            isa<OMPArrayShapingExpr>(
4033                                SC.getAssociatedExpression())) &&
4034                           isa<ArraySubscriptExpr>(
4035                               CCI->getAssociatedExpression())))
4036                       return false;
4037 
4038                   const Decl *CCD = CCI->getAssociatedDeclaration();
4039                   const Decl *SCD = SC.getAssociatedDeclaration();
4040                   CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
4041                   SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
4042                   if (SCD != CCD)
4043                     return false;
4044                   std::advance(CCI, 1);
4045                   if (CCI == CCE)
4046                     break;
4047                 }
4048                 return true;
4049               })) {
4050         Visit(E->getBase());
4051       }
4052     } else if (!TryCaptureCXXThisMembers) {
4053       Visit(E->getBase());
4054     }
4055   }
4056   void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
4057     for (OMPClause *C : S->clauses()) {
4058       // Skip analysis of arguments of private clauses for task|target
4059       // directives.
4060       if (isa_and_nonnull<OMPPrivateClause>(C))
4061         continue;
4062       // Skip analysis of arguments of implicitly defined firstprivate clause
4063       // for task|target directives.
4064       // Skip analysis of arguments of implicitly defined map clause for target
4065       // directives.
4066       if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
4067                  C->isImplicit() &&
4068                  !isOpenMPTaskingDirective(Stack->getCurrentDirective()))) {
4069         for (Stmt *CC : C->children()) {
4070           if (CC)
4071             Visit(CC);
4072         }
4073       }
4074     }
4075     // Check implicitly captured variables.
4076     VisitSubCaptures(S);
4077   }
4078 
4079   void VisitOMPLoopTransformationDirective(OMPLoopTransformationDirective *S) {
4080     // Loop transformation directives do not introduce data sharing
4081     VisitStmt(S);
4082   }
4083 
4084   void VisitCallExpr(CallExpr *S) {
4085     for (Stmt *C : S->arguments()) {
4086       if (C) {
4087         // Check implicitly captured variables in the task-based directives to
4088         // check if they must be firstprivatized.
4089         Visit(C);
4090       }
4091     }
4092     if (Expr *Callee = S->getCallee()) {
4093       auto *CI = Callee->IgnoreParenImpCasts();
4094       if (auto *CE = dyn_cast<MemberExpr>(CI))
4095         Visit(CE->getBase());
4096       else if (auto *CE = dyn_cast<DeclRefExpr>(CI))
4097         Visit(CE);
4098     }
4099   }
4100   void VisitStmt(Stmt *S) {
4101     for (Stmt *C : S->children()) {
4102       if (C) {
4103         // Check implicitly captured variables in the task-based directives to
4104         // check if they must be firstprivatized.
4105         Visit(C);
4106       }
4107     }
4108   }
4109 
4110   void visitSubCaptures(CapturedStmt *S) {
4111     for (const CapturedStmt::Capture &Cap : S->captures()) {
4112       if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
4113         continue;
4114       VarDecl *VD = Cap.getCapturedVar();
4115       // Do not try to map the variable if it or its sub-component was mapped
4116       // already.
4117       if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
4118           Stack->checkMappableExprComponentListsForDecl(
4119               VD, /*CurrentRegionOnly=*/true,
4120               [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
4121                  OpenMPClauseKind) { return true; }))
4122         continue;
4123       DeclRefExpr *DRE = buildDeclRefExpr(
4124           SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
4125           Cap.getLocation(), /*RefersToCapture=*/true);
4126       Visit(DRE);
4127     }
4128   }
4129   bool isErrorFound() const { return ErrorFound; }
4130   ArrayRef<Expr *> getImplicitFirstprivate() const {
4131     return ImplicitFirstprivate;
4132   }
4133   ArrayRef<Expr *> getImplicitPrivate() const { return ImplicitPrivate; }
4134   ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind DK,
4135                                   OpenMPMapClauseKind MK) const {
4136     return ImplicitMap[DK][MK];
4137   }
4138   ArrayRef<OpenMPMapModifierKind>
4139   getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const {
4140     return ImplicitMapModifier[Kind];
4141   }
4142   const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
4143     return VarsWithInheritedDSA;
4144   }
4145 
4146   DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
4147       : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
4148     // Process declare target link variables for the target directives.
4149     if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
4150       for (DeclRefExpr *E : Stack->getLinkGlobals())
4151         Visit(E);
4152     }
4153   }
4154 };
4155 } // namespace
4156 
4157 static void handleDeclareVariantConstructTrait(DSAStackTy *Stack,
4158                                                OpenMPDirectiveKind DKind,
4159                                                bool ScopeEntry) {
4160   SmallVector<llvm::omp::TraitProperty, 8> Traits;
4161   if (isOpenMPTargetExecutionDirective(DKind))
4162     Traits.emplace_back(llvm::omp::TraitProperty::construct_target_target);
4163   if (isOpenMPTeamsDirective(DKind))
4164     Traits.emplace_back(llvm::omp::TraitProperty::construct_teams_teams);
4165   if (isOpenMPParallelDirective(DKind))
4166     Traits.emplace_back(llvm::omp::TraitProperty::construct_parallel_parallel);
4167   if (isOpenMPWorksharingDirective(DKind))
4168     Traits.emplace_back(llvm::omp::TraitProperty::construct_for_for);
4169   if (isOpenMPSimdDirective(DKind))
4170     Traits.emplace_back(llvm::omp::TraitProperty::construct_simd_simd);
4171   Stack->handleConstructTrait(Traits, ScopeEntry);
4172 }
4173 
4174 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
4175   switch (DKind) {
4176   case OMPD_parallel:
4177   case OMPD_parallel_for:
4178   case OMPD_parallel_for_simd:
4179   case OMPD_parallel_sections:
4180   case OMPD_parallel_master:
4181   case OMPD_parallel_masked:
4182   case OMPD_parallel_loop:
4183   case OMPD_teams:
4184   case OMPD_teams_distribute:
4185   case OMPD_teams_distribute_simd: {
4186     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4187     QualType KmpInt32PtrTy =
4188         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4189     Sema::CapturedParamNameType Params[] = {
4190         std::make_pair(".global_tid.", KmpInt32PtrTy),
4191         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4192         std::make_pair(StringRef(), QualType()) // __context with shared vars
4193     };
4194     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4195                              Params);
4196     break;
4197   }
4198   case OMPD_target_teams:
4199   case OMPD_target_parallel:
4200   case OMPD_target_parallel_for:
4201   case OMPD_target_parallel_for_simd:
4202   case OMPD_target_parallel_loop:
4203   case OMPD_target_teams_distribute:
4204   case OMPD_target_teams_distribute_simd: {
4205     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4206     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4207     QualType KmpInt32PtrTy =
4208         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4209     QualType Args[] = {VoidPtrTy};
4210     FunctionProtoType::ExtProtoInfo EPI;
4211     EPI.Variadic = true;
4212     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4213     Sema::CapturedParamNameType Params[] = {
4214         std::make_pair(".global_tid.", KmpInt32Ty),
4215         std::make_pair(".part_id.", KmpInt32PtrTy),
4216         std::make_pair(".privates.", VoidPtrTy),
4217         std::make_pair(
4218             ".copy_fn.",
4219             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4220         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4221         std::make_pair(StringRef(), QualType()) // __context with shared vars
4222     };
4223     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4224                              Params, /*OpenMPCaptureLevel=*/0);
4225     // Mark this captured region as inlined, because we don't use outlined
4226     // function directly.
4227     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4228         AlwaysInlineAttr::CreateImplicit(
4229             Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4230     Sema::CapturedParamNameType ParamsTarget[] = {
4231         std::make_pair(StringRef(), QualType()) // __context with shared vars
4232     };
4233     // Start a captured region for 'target' with no implicit parameters.
4234     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4235                              ParamsTarget, /*OpenMPCaptureLevel=*/1);
4236     Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
4237         std::make_pair(".global_tid.", KmpInt32PtrTy),
4238         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4239         std::make_pair(StringRef(), QualType()) // __context with shared vars
4240     };
4241     // Start a captured region for 'teams' or 'parallel'.  Both regions have
4242     // the same implicit parameters.
4243     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4244                              ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
4245     break;
4246   }
4247   case OMPD_target:
4248   case OMPD_target_simd: {
4249     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4250     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4251     QualType KmpInt32PtrTy =
4252         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4253     QualType Args[] = {VoidPtrTy};
4254     FunctionProtoType::ExtProtoInfo EPI;
4255     EPI.Variadic = true;
4256     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4257     Sema::CapturedParamNameType Params[] = {
4258         std::make_pair(".global_tid.", KmpInt32Ty),
4259         std::make_pair(".part_id.", KmpInt32PtrTy),
4260         std::make_pair(".privates.", VoidPtrTy),
4261         std::make_pair(
4262             ".copy_fn.",
4263             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4264         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4265         std::make_pair(StringRef(), QualType()) // __context with shared vars
4266     };
4267     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4268                              Params, /*OpenMPCaptureLevel=*/0);
4269     // Mark this captured region as inlined, because we don't use outlined
4270     // function directly.
4271     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4272         AlwaysInlineAttr::CreateImplicit(
4273             Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4274     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4275                              std::make_pair(StringRef(), QualType()),
4276                              /*OpenMPCaptureLevel=*/1);
4277     break;
4278   }
4279   case OMPD_atomic:
4280   case OMPD_critical:
4281   case OMPD_section:
4282   case OMPD_master:
4283   case OMPD_masked:
4284   case OMPD_tile:
4285   case OMPD_unroll:
4286     break;
4287   case OMPD_loop:
4288     // TODO: 'loop' may require additional parameters depending on the binding.
4289     // Treat similar to OMPD_simd/OMPD_for for now.
4290   case OMPD_simd:
4291   case OMPD_for:
4292   case OMPD_for_simd:
4293   case OMPD_sections:
4294   case OMPD_single:
4295   case OMPD_taskgroup:
4296   case OMPD_distribute:
4297   case OMPD_distribute_simd:
4298   case OMPD_ordered:
4299   case OMPD_target_data:
4300   case OMPD_dispatch: {
4301     Sema::CapturedParamNameType Params[] = {
4302         std::make_pair(StringRef(), QualType()) // __context with shared vars
4303     };
4304     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4305                              Params);
4306     break;
4307   }
4308   case OMPD_task: {
4309     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4310     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4311     QualType KmpInt32PtrTy =
4312         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4313     QualType Args[] = {VoidPtrTy};
4314     FunctionProtoType::ExtProtoInfo EPI;
4315     EPI.Variadic = true;
4316     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4317     Sema::CapturedParamNameType Params[] = {
4318         std::make_pair(".global_tid.", KmpInt32Ty),
4319         std::make_pair(".part_id.", KmpInt32PtrTy),
4320         std::make_pair(".privates.", VoidPtrTy),
4321         std::make_pair(
4322             ".copy_fn.",
4323             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4324         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4325         std::make_pair(StringRef(), QualType()) // __context with shared vars
4326     };
4327     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4328                              Params);
4329     // Mark this captured region as inlined, because we don't use outlined
4330     // function directly.
4331     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4332         AlwaysInlineAttr::CreateImplicit(
4333             Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4334     break;
4335   }
4336   case OMPD_taskloop:
4337   case OMPD_taskloop_simd:
4338   case OMPD_master_taskloop:
4339   case OMPD_masked_taskloop:
4340   case OMPD_masked_taskloop_simd:
4341   case OMPD_master_taskloop_simd: {
4342     QualType KmpInt32Ty =
4343         Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4344             .withConst();
4345     QualType KmpUInt64Ty =
4346         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4347             .withConst();
4348     QualType KmpInt64Ty =
4349         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4350             .withConst();
4351     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4352     QualType KmpInt32PtrTy =
4353         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4354     QualType Args[] = {VoidPtrTy};
4355     FunctionProtoType::ExtProtoInfo EPI;
4356     EPI.Variadic = true;
4357     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4358     Sema::CapturedParamNameType Params[] = {
4359         std::make_pair(".global_tid.", KmpInt32Ty),
4360         std::make_pair(".part_id.", KmpInt32PtrTy),
4361         std::make_pair(".privates.", VoidPtrTy),
4362         std::make_pair(
4363             ".copy_fn.",
4364             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4365         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4366         std::make_pair(".lb.", KmpUInt64Ty),
4367         std::make_pair(".ub.", KmpUInt64Ty),
4368         std::make_pair(".st.", KmpInt64Ty),
4369         std::make_pair(".liter.", KmpInt32Ty),
4370         std::make_pair(".reductions.", VoidPtrTy),
4371         std::make_pair(StringRef(), QualType()) // __context with shared vars
4372     };
4373     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4374                              Params);
4375     // Mark this captured region as inlined, because we don't use outlined
4376     // function directly.
4377     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4378         AlwaysInlineAttr::CreateImplicit(
4379             Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4380     break;
4381   }
4382   case OMPD_parallel_masked_taskloop:
4383   case OMPD_parallel_masked_taskloop_simd:
4384   case OMPD_parallel_master_taskloop:
4385   case OMPD_parallel_master_taskloop_simd: {
4386     QualType KmpInt32Ty =
4387         Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4388             .withConst();
4389     QualType KmpUInt64Ty =
4390         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4391             .withConst();
4392     QualType KmpInt64Ty =
4393         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4394             .withConst();
4395     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4396     QualType KmpInt32PtrTy =
4397         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4398     Sema::CapturedParamNameType ParamsParallel[] = {
4399         std::make_pair(".global_tid.", KmpInt32PtrTy),
4400         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4401         std::make_pair(StringRef(), QualType()) // __context with shared vars
4402     };
4403     // Start a captured region for 'parallel'.
4404     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4405                              ParamsParallel, /*OpenMPCaptureLevel=*/0);
4406     QualType Args[] = {VoidPtrTy};
4407     FunctionProtoType::ExtProtoInfo EPI;
4408     EPI.Variadic = true;
4409     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4410     Sema::CapturedParamNameType Params[] = {
4411         std::make_pair(".global_tid.", KmpInt32Ty),
4412         std::make_pair(".part_id.", KmpInt32PtrTy),
4413         std::make_pair(".privates.", VoidPtrTy),
4414         std::make_pair(
4415             ".copy_fn.",
4416             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4417         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4418         std::make_pair(".lb.", KmpUInt64Ty),
4419         std::make_pair(".ub.", KmpUInt64Ty),
4420         std::make_pair(".st.", KmpInt64Ty),
4421         std::make_pair(".liter.", KmpInt32Ty),
4422         std::make_pair(".reductions.", VoidPtrTy),
4423         std::make_pair(StringRef(), QualType()) // __context with shared vars
4424     };
4425     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4426                              Params, /*OpenMPCaptureLevel=*/1);
4427     // Mark this captured region as inlined, because we don't use outlined
4428     // function directly.
4429     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4430         AlwaysInlineAttr::CreateImplicit(
4431             Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4432     break;
4433   }
4434   case OMPD_distribute_parallel_for_simd:
4435   case OMPD_distribute_parallel_for: {
4436     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4437     QualType KmpInt32PtrTy =
4438         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4439     Sema::CapturedParamNameType Params[] = {
4440         std::make_pair(".global_tid.", KmpInt32PtrTy),
4441         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4442         std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4443         std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4444         std::make_pair(StringRef(), QualType()) // __context with shared vars
4445     };
4446     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4447                              Params);
4448     break;
4449   }
4450   case OMPD_target_teams_loop:
4451   case OMPD_target_teams_distribute_parallel_for:
4452   case OMPD_target_teams_distribute_parallel_for_simd: {
4453     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4454     QualType KmpInt32PtrTy =
4455         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4456     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4457 
4458     QualType Args[] = {VoidPtrTy};
4459     FunctionProtoType::ExtProtoInfo EPI;
4460     EPI.Variadic = true;
4461     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4462     Sema::CapturedParamNameType Params[] = {
4463         std::make_pair(".global_tid.", KmpInt32Ty),
4464         std::make_pair(".part_id.", KmpInt32PtrTy),
4465         std::make_pair(".privates.", VoidPtrTy),
4466         std::make_pair(
4467             ".copy_fn.",
4468             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4469         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4470         std::make_pair(StringRef(), QualType()) // __context with shared vars
4471     };
4472     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4473                              Params, /*OpenMPCaptureLevel=*/0);
4474     // Mark this captured region as inlined, because we don't use outlined
4475     // function directly.
4476     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4477         AlwaysInlineAttr::CreateImplicit(
4478             Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4479     Sema::CapturedParamNameType ParamsTarget[] = {
4480         std::make_pair(StringRef(), QualType()) // __context with shared vars
4481     };
4482     // Start a captured region for 'target' with no implicit parameters.
4483     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4484                              ParamsTarget, /*OpenMPCaptureLevel=*/1);
4485 
4486     Sema::CapturedParamNameType ParamsTeams[] = {
4487         std::make_pair(".global_tid.", KmpInt32PtrTy),
4488         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4489         std::make_pair(StringRef(), QualType()) // __context with shared vars
4490     };
4491     // Start a captured region for 'target' with no implicit parameters.
4492     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4493                              ParamsTeams, /*OpenMPCaptureLevel=*/2);
4494 
4495     Sema::CapturedParamNameType ParamsParallel[] = {
4496         std::make_pair(".global_tid.", KmpInt32PtrTy),
4497         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4498         std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4499         std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4500         std::make_pair(StringRef(), QualType()) // __context with shared vars
4501     };
4502     // Start a captured region for 'teams' or 'parallel'.  Both regions have
4503     // the same implicit parameters.
4504     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4505                              ParamsParallel, /*OpenMPCaptureLevel=*/3);
4506     break;
4507   }
4508 
4509   case OMPD_teams_loop:
4510   case OMPD_teams_distribute_parallel_for:
4511   case OMPD_teams_distribute_parallel_for_simd: {
4512     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4513     QualType KmpInt32PtrTy =
4514         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4515 
4516     Sema::CapturedParamNameType ParamsTeams[] = {
4517         std::make_pair(".global_tid.", KmpInt32PtrTy),
4518         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4519         std::make_pair(StringRef(), QualType()) // __context with shared vars
4520     };
4521     // Start a captured region for 'target' with no implicit parameters.
4522     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4523                              ParamsTeams, /*OpenMPCaptureLevel=*/0);
4524 
4525     Sema::CapturedParamNameType ParamsParallel[] = {
4526         std::make_pair(".global_tid.", KmpInt32PtrTy),
4527         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4528         std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4529         std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4530         std::make_pair(StringRef(), QualType()) // __context with shared vars
4531     };
4532     // Start a captured region for 'teams' or 'parallel'.  Both regions have
4533     // the same implicit parameters.
4534     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4535                              ParamsParallel, /*OpenMPCaptureLevel=*/1);
4536     break;
4537   }
4538   case OMPD_target_update:
4539   case OMPD_target_enter_data:
4540   case OMPD_target_exit_data: {
4541     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4542     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4543     QualType KmpInt32PtrTy =
4544         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4545     QualType Args[] = {VoidPtrTy};
4546     FunctionProtoType::ExtProtoInfo EPI;
4547     EPI.Variadic = true;
4548     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4549     Sema::CapturedParamNameType Params[] = {
4550         std::make_pair(".global_tid.", KmpInt32Ty),
4551         std::make_pair(".part_id.", KmpInt32PtrTy),
4552         std::make_pair(".privates.", VoidPtrTy),
4553         std::make_pair(
4554             ".copy_fn.",
4555             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4556         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4557         std::make_pair(StringRef(), QualType()) // __context with shared vars
4558     };
4559     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4560                              Params);
4561     // Mark this captured region as inlined, because we don't use outlined
4562     // function directly.
4563     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4564         AlwaysInlineAttr::CreateImplicit(
4565             Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4566     break;
4567   }
4568   case OMPD_threadprivate:
4569   case OMPD_allocate:
4570   case OMPD_taskyield:
4571   case OMPD_error:
4572   case OMPD_barrier:
4573   case OMPD_taskwait:
4574   case OMPD_cancellation_point:
4575   case OMPD_cancel:
4576   case OMPD_flush:
4577   case OMPD_depobj:
4578   case OMPD_scan:
4579   case OMPD_declare_reduction:
4580   case OMPD_declare_mapper:
4581   case OMPD_declare_simd:
4582   case OMPD_declare_target:
4583   case OMPD_end_declare_target:
4584   case OMPD_requires:
4585   case OMPD_declare_variant:
4586   case OMPD_begin_declare_variant:
4587   case OMPD_end_declare_variant:
4588   case OMPD_metadirective:
4589     llvm_unreachable("OpenMP Directive is not allowed");
4590   case OMPD_unknown:
4591   default:
4592     llvm_unreachable("Unknown OpenMP directive");
4593   }
4594   DSAStack->setContext(CurContext);
4595   handleDeclareVariantConstructTrait(DSAStack, DKind, /* ScopeEntry */ true);
4596 }
4597 
4598 int Sema::getNumberOfConstructScopes(unsigned Level) const {
4599   return getOpenMPCaptureLevels(DSAStack->getDirective(Level));
4600 }
4601 
4602 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
4603   SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4604   getOpenMPCaptureRegions(CaptureRegions, DKind);
4605   return CaptureRegions.size();
4606 }
4607 
4608 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
4609                                              Expr *CaptureExpr, bool WithInit,
4610                                              DeclContext *CurContext,
4611                                              bool AsExpression) {
4612   assert(CaptureExpr);
4613   ASTContext &C = S.getASTContext();
4614   Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
4615   QualType Ty = Init->getType();
4616   if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
4617     if (S.getLangOpts().CPlusPlus) {
4618       Ty = C.getLValueReferenceType(Ty);
4619     } else {
4620       Ty = C.getPointerType(Ty);
4621       ExprResult Res =
4622           S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
4623       if (!Res.isUsable())
4624         return nullptr;
4625       Init = Res.get();
4626     }
4627     WithInit = true;
4628   }
4629   auto *CED = OMPCapturedExprDecl::Create(C, CurContext, Id, Ty,
4630                                           CaptureExpr->getBeginLoc());
4631   if (!WithInit)
4632     CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
4633   CurContext->addHiddenDecl(CED);
4634   Sema::TentativeAnalysisScope Trap(S);
4635   S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
4636   return CED;
4637 }
4638 
4639 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
4640                                  bool WithInit) {
4641   OMPCapturedExprDecl *CD;
4642   if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
4643     CD = cast<OMPCapturedExprDecl>(VD);
4644   else
4645     CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
4646                           S.CurContext,
4647                           /*AsExpression=*/false);
4648   return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4649                           CaptureExpr->getExprLoc());
4650 }
4651 
4652 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref,
4653                                StringRef Name) {
4654   CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
4655   if (!Ref) {
4656     OMPCapturedExprDecl *CD = buildCaptureDecl(
4657         S, &S.getASTContext().Idents.get(Name), CaptureExpr,
4658         /*WithInit=*/true, S.CurContext, /*AsExpression=*/true);
4659     Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4660                            CaptureExpr->getExprLoc());
4661   }
4662   ExprResult Res = Ref;
4663   if (!S.getLangOpts().CPlusPlus &&
4664       CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
4665       Ref->getType()->isPointerType()) {
4666     Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
4667     if (!Res.isUsable())
4668       return ExprError();
4669   }
4670   return S.DefaultLvalueConversion(Res.get());
4671 }
4672 
4673 namespace {
4674 // OpenMP directives parsed in this section are represented as a
4675 // CapturedStatement with an associated statement.  If a syntax error
4676 // is detected during the parsing of the associated statement, the
4677 // compiler must abort processing and close the CapturedStatement.
4678 //
4679 // Combined directives such as 'target parallel' have more than one
4680 // nested CapturedStatements.  This RAII ensures that we unwind out
4681 // of all the nested CapturedStatements when an error is found.
4682 class CaptureRegionUnwinderRAII {
4683 private:
4684   Sema &S;
4685   bool &ErrorFound;
4686   OpenMPDirectiveKind DKind = OMPD_unknown;
4687 
4688 public:
4689   CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
4690                             OpenMPDirectiveKind DKind)
4691       : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
4692   ~CaptureRegionUnwinderRAII() {
4693     if (ErrorFound) {
4694       int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
4695       while (--ThisCaptureLevel >= 0)
4696         S.ActOnCapturedRegionError();
4697     }
4698   }
4699 };
4700 } // namespace
4701 
4702 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) {
4703   // Capture variables captured by reference in lambdas for target-based
4704   // directives.
4705   if (!CurContext->isDependentContext() &&
4706       (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) ||
4707        isOpenMPTargetDataManagementDirective(
4708            DSAStack->getCurrentDirective()))) {
4709     QualType Type = V->getType();
4710     if (const auto *RD = Type.getCanonicalType()
4711                              .getNonReferenceType()
4712                              ->getAsCXXRecordDecl()) {
4713       bool SavedForceCaptureByReferenceInTargetExecutable =
4714           DSAStack->isForceCaptureByReferenceInTargetExecutable();
4715       DSAStack->setForceCaptureByReferenceInTargetExecutable(
4716           /*V=*/true);
4717       if (RD->isLambda()) {
4718         llvm::DenseMap<const ValueDecl *, FieldDecl *> Captures;
4719         FieldDecl *ThisCapture;
4720         RD->getCaptureFields(Captures, ThisCapture);
4721         for (const LambdaCapture &LC : RD->captures()) {
4722           if (LC.getCaptureKind() == LCK_ByRef) {
4723             VarDecl *VD = cast<VarDecl>(LC.getCapturedVar());
4724             DeclContext *VDC = VD->getDeclContext();
4725             if (!VDC->Encloses(CurContext))
4726               continue;
4727             MarkVariableReferenced(LC.getLocation(), VD);
4728           } else if (LC.getCaptureKind() == LCK_This) {
4729             QualType ThisTy = getCurrentThisType();
4730             if (!ThisTy.isNull() &&
4731                 Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
4732               CheckCXXThisCapture(LC.getLocation());
4733           }
4734         }
4735       }
4736       DSAStack->setForceCaptureByReferenceInTargetExecutable(
4737           SavedForceCaptureByReferenceInTargetExecutable);
4738     }
4739   }
4740 }
4741 
4742 static bool checkOrderedOrderSpecified(Sema &S,
4743                                        const ArrayRef<OMPClause *> Clauses) {
4744   const OMPOrderedClause *Ordered = nullptr;
4745   const OMPOrderClause *Order = nullptr;
4746 
4747   for (const OMPClause *Clause : Clauses) {
4748     if (Clause->getClauseKind() == OMPC_ordered)
4749       Ordered = cast<OMPOrderedClause>(Clause);
4750     else if (Clause->getClauseKind() == OMPC_order) {
4751       Order = cast<OMPOrderClause>(Clause);
4752       if (Order->getKind() != OMPC_ORDER_concurrent)
4753         Order = nullptr;
4754     }
4755     if (Ordered && Order)
4756       break;
4757   }
4758 
4759   if (Ordered && Order) {
4760     S.Diag(Order->getKindKwLoc(),
4761            diag::err_omp_simple_clause_incompatible_with_ordered)
4762         << getOpenMPClauseName(OMPC_order)
4763         << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent)
4764         << SourceRange(Order->getBeginLoc(), Order->getEndLoc());
4765     S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param)
4766         << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc());
4767     return true;
4768   }
4769   return false;
4770 }
4771 
4772 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
4773                                       ArrayRef<OMPClause *> Clauses) {
4774   handleDeclareVariantConstructTrait(DSAStack, DSAStack->getCurrentDirective(),
4775                                      /* ScopeEntry */ false);
4776   if (DSAStack->getCurrentDirective() == OMPD_atomic ||
4777       DSAStack->getCurrentDirective() == OMPD_critical ||
4778       DSAStack->getCurrentDirective() == OMPD_section ||
4779       DSAStack->getCurrentDirective() == OMPD_master ||
4780       DSAStack->getCurrentDirective() == OMPD_masked)
4781     return S;
4782 
4783   bool ErrorFound = false;
4784   CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4785       *this, ErrorFound, DSAStack->getCurrentDirective());
4786   if (!S.isUsable()) {
4787     ErrorFound = true;
4788     return StmtError();
4789   }
4790 
4791   SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4792   getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective());
4793   OMPOrderedClause *OC = nullptr;
4794   OMPScheduleClause *SC = nullptr;
4795   SmallVector<const OMPLinearClause *, 4> LCs;
4796   SmallVector<const OMPClauseWithPreInit *, 4> PICs;
4797   // This is required for proper codegen.
4798   for (OMPClause *Clause : Clauses) {
4799     if (!LangOpts.OpenMPSimd &&
4800         (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) ||
4801          DSAStack->getCurrentDirective() == OMPD_target) &&
4802         Clause->getClauseKind() == OMPC_in_reduction) {
4803       // Capture taskgroup task_reduction descriptors inside the tasking regions
4804       // with the corresponding in_reduction items.
4805       auto *IRC = cast<OMPInReductionClause>(Clause);
4806       for (Expr *E : IRC->taskgroup_descriptors())
4807         if (E)
4808           MarkDeclarationsReferencedInExpr(E);
4809     }
4810     if (isOpenMPPrivate(Clause->getClauseKind()) ||
4811         Clause->getClauseKind() == OMPC_copyprivate ||
4812         (getLangOpts().OpenMPUseTLS &&
4813          getASTContext().getTargetInfo().isTLSSupported() &&
4814          Clause->getClauseKind() == OMPC_copyin)) {
4815       DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
4816       // Mark all variables in private list clauses as used in inner region.
4817       for (Stmt *VarRef : Clause->children()) {
4818         if (auto *E = cast_or_null<Expr>(VarRef)) {
4819           MarkDeclarationsReferencedInExpr(E);
4820         }
4821       }
4822       DSAStack->setForceVarCapturing(/*V=*/false);
4823     } else if (isOpenMPLoopTransformationDirective(
4824                    DSAStack->getCurrentDirective())) {
4825       assert(CaptureRegions.empty() &&
4826              "No captured regions in loop transformation directives.");
4827     } else if (CaptureRegions.size() > 1 ||
4828                CaptureRegions.back() != OMPD_unknown) {
4829       if (auto *C = OMPClauseWithPreInit::get(Clause))
4830         PICs.push_back(C);
4831       if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
4832         if (Expr *E = C->getPostUpdateExpr())
4833           MarkDeclarationsReferencedInExpr(E);
4834       }
4835     }
4836     if (Clause->getClauseKind() == OMPC_schedule)
4837       SC = cast<OMPScheduleClause>(Clause);
4838     else if (Clause->getClauseKind() == OMPC_ordered)
4839       OC = cast<OMPOrderedClause>(Clause);
4840     else if (Clause->getClauseKind() == OMPC_linear)
4841       LCs.push_back(cast<OMPLinearClause>(Clause));
4842   }
4843   // Capture allocator expressions if used.
4844   for (Expr *E : DSAStack->getInnerAllocators())
4845     MarkDeclarationsReferencedInExpr(E);
4846   // OpenMP, 2.7.1 Loop Construct, Restrictions
4847   // The nonmonotonic modifier cannot be specified if an ordered clause is
4848   // specified.
4849   if (SC &&
4850       (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
4851        SC->getSecondScheduleModifier() ==
4852            OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4853       OC) {
4854     Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
4855              ? SC->getFirstScheduleModifierLoc()
4856              : SC->getSecondScheduleModifierLoc(),
4857          diag::err_omp_simple_clause_incompatible_with_ordered)
4858         << getOpenMPClauseName(OMPC_schedule)
4859         << getOpenMPSimpleClauseTypeName(OMPC_schedule,
4860                                          OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4861         << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4862     ErrorFound = true;
4863   }
4864   // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions.
4865   // If an order(concurrent) clause is present, an ordered clause may not appear
4866   // on the same directive.
4867   if (checkOrderedOrderSpecified(*this, Clauses))
4868     ErrorFound = true;
4869   if (!LCs.empty() && OC && OC->getNumForLoops()) {
4870     for (const OMPLinearClause *C : LCs) {
4871       Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
4872           << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4873     }
4874     ErrorFound = true;
4875   }
4876   if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
4877       isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
4878       OC->getNumForLoops()) {
4879     Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
4880         << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
4881     ErrorFound = true;
4882   }
4883   if (ErrorFound) {
4884     return StmtError();
4885   }
4886   StmtResult SR = S;
4887   unsigned CompletedRegions = 0;
4888   for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
4889     // Mark all variables in private list clauses as used in inner region.
4890     // Required for proper codegen of combined directives.
4891     // TODO: add processing for other clauses.
4892     if (ThisCaptureRegion != OMPD_unknown) {
4893       for (const clang::OMPClauseWithPreInit *C : PICs) {
4894         OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
4895         // Find the particular capture region for the clause if the
4896         // directive is a combined one with multiple capture regions.
4897         // If the directive is not a combined one, the capture region
4898         // associated with the clause is OMPD_unknown and is generated
4899         // only once.
4900         if (CaptureRegion == ThisCaptureRegion ||
4901             CaptureRegion == OMPD_unknown) {
4902           if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
4903             for (Decl *D : DS->decls())
4904               MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
4905           }
4906         }
4907       }
4908     }
4909     if (ThisCaptureRegion == OMPD_target) {
4910       // Capture allocator traits in the target region. They are used implicitly
4911       // and, thus, are not captured by default.
4912       for (OMPClause *C : Clauses) {
4913         if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) {
4914           for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4915                ++I) {
4916             OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I);
4917             if (Expr *E = D.AllocatorTraits)
4918               MarkDeclarationsReferencedInExpr(E);
4919           }
4920           continue;
4921         }
4922       }
4923     }
4924     if (ThisCaptureRegion == OMPD_parallel) {
4925       // Capture temp arrays for inscan reductions and locals in aligned
4926       // clauses.
4927       for (OMPClause *C : Clauses) {
4928         if (auto *RC = dyn_cast<OMPReductionClause>(C)) {
4929           if (RC->getModifier() != OMPC_REDUCTION_inscan)
4930             continue;
4931           for (Expr *E : RC->copy_array_temps())
4932             MarkDeclarationsReferencedInExpr(E);
4933         }
4934         if (auto *AC = dyn_cast<OMPAlignedClause>(C)) {
4935           for (Expr *E : AC->varlists())
4936             MarkDeclarationsReferencedInExpr(E);
4937         }
4938       }
4939     }
4940     if (++CompletedRegions == CaptureRegions.size())
4941       DSAStack->setBodyComplete();
4942     SR = ActOnCapturedRegionEnd(SR.get());
4943   }
4944   return SR;
4945 }
4946 
4947 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
4948                               OpenMPDirectiveKind CancelRegion,
4949                               SourceLocation StartLoc) {
4950   // CancelRegion is only needed for cancel and cancellation_point.
4951   if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4952     return false;
4953 
4954   if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4955       CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4956     return false;
4957 
4958   SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4959       << getOpenMPDirectiveName(CancelRegion);
4960   return true;
4961 }
4962 
4963 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4964                                   OpenMPDirectiveKind CurrentRegion,
4965                                   const DeclarationNameInfo &CurrentName,
4966                                   OpenMPDirectiveKind CancelRegion,
4967                                   OpenMPBindClauseKind BindKind,
4968                                   SourceLocation StartLoc) {
4969   if (Stack->getCurScope()) {
4970     OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
4971     OpenMPDirectiveKind OffendingRegion = ParentRegion;
4972     bool NestingProhibited = false;
4973     bool CloseNesting = true;
4974     bool OrphanSeen = false;
4975     enum {
4976       NoRecommend,
4977       ShouldBeInParallelRegion,
4978       ShouldBeInOrderedRegion,
4979       ShouldBeInTargetRegion,
4980       ShouldBeInTeamsRegion,
4981       ShouldBeInLoopSimdRegion,
4982     } Recommend = NoRecommend;
4983     if (SemaRef.LangOpts.OpenMP >= 51 && Stack->isParentOrderConcurrent() &&
4984         CurrentRegion != OMPD_simd && CurrentRegion != OMPD_loop &&
4985         CurrentRegion != OMPD_parallel &&
4986         !isOpenMPCombinedParallelADirective(CurrentRegion)) {
4987       SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_order)
4988           << getOpenMPDirectiveName(CurrentRegion);
4989       return true;
4990     }
4991     if (isOpenMPSimdDirective(ParentRegion) &&
4992         ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
4993          (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
4994           CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
4995           CurrentRegion != OMPD_scan))) {
4996       // OpenMP [2.16, Nesting of Regions]
4997       // OpenMP constructs may not be nested inside a simd region.
4998       // OpenMP [2.8.1,simd Construct, Restrictions]
4999       // An ordered construct with the simd clause is the only OpenMP
5000       // construct that can appear in the simd region.
5001       // Allowing a SIMD construct nested in another SIMD construct is an
5002       // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
5003       // message.
5004       // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions]
5005       // The only OpenMP constructs that can be encountered during execution of
5006       // a simd region are the atomic construct, the loop construct, the simd
5007       // construct and the ordered construct with the simd clause.
5008       SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
5009                                  ? diag::err_omp_prohibited_region_simd
5010                                  : diag::warn_omp_nesting_simd)
5011           << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0);
5012       return CurrentRegion != OMPD_simd;
5013     }
5014     if (ParentRegion == OMPD_atomic) {
5015       // OpenMP [2.16, Nesting of Regions]
5016       // OpenMP constructs may not be nested inside an atomic region.
5017       SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
5018       return true;
5019     }
5020     if (CurrentRegion == OMPD_section) {
5021       // OpenMP [2.7.2, sections Construct, Restrictions]
5022       // Orphaned section directives are prohibited. That is, the section
5023       // directives must appear within the sections construct and must not be
5024       // encountered elsewhere in the sections region.
5025       if (ParentRegion != OMPD_sections &&
5026           ParentRegion != OMPD_parallel_sections) {
5027         SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
5028             << (ParentRegion != OMPD_unknown)
5029             << getOpenMPDirectiveName(ParentRegion);
5030         return true;
5031       }
5032       return false;
5033     }
5034     // Allow some constructs (except teams and cancellation constructs) to be
5035     // orphaned (they could be used in functions, called from OpenMP regions
5036     // with the required preconditions).
5037     if (ParentRegion == OMPD_unknown &&
5038         !isOpenMPNestingTeamsDirective(CurrentRegion) &&
5039         CurrentRegion != OMPD_cancellation_point &&
5040         CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
5041       return false;
5042     if (CurrentRegion == OMPD_cancellation_point ||
5043         CurrentRegion == OMPD_cancel) {
5044       // OpenMP [2.16, Nesting of Regions]
5045       // A cancellation point construct for which construct-type-clause is
5046       // taskgroup must be nested inside a task construct. A cancellation
5047       // point construct for which construct-type-clause is not taskgroup must
5048       // be closely nested inside an OpenMP construct that matches the type
5049       // specified in construct-type-clause.
5050       // A cancel construct for which construct-type-clause is taskgroup must be
5051       // nested inside a task construct. A cancel construct for which
5052       // construct-type-clause is not taskgroup must be closely nested inside an
5053       // OpenMP construct that matches the type specified in
5054       // construct-type-clause.
5055       NestingProhibited =
5056           !((CancelRegion == OMPD_parallel &&
5057              (ParentRegion == OMPD_parallel ||
5058               ParentRegion == OMPD_target_parallel)) ||
5059             (CancelRegion == OMPD_for &&
5060              (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
5061               ParentRegion == OMPD_target_parallel_for ||
5062               ParentRegion == OMPD_distribute_parallel_for ||
5063               ParentRegion == OMPD_teams_distribute_parallel_for ||
5064               ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
5065             (CancelRegion == OMPD_taskgroup &&
5066              (ParentRegion == OMPD_task ||
5067               (SemaRef.getLangOpts().OpenMP >= 50 &&
5068                (ParentRegion == OMPD_taskloop ||
5069                 ParentRegion == OMPD_master_taskloop ||
5070                 ParentRegion == OMPD_masked_taskloop ||
5071                 ParentRegion == OMPD_parallel_masked_taskloop ||
5072                 ParentRegion == OMPD_parallel_master_taskloop)))) ||
5073             (CancelRegion == OMPD_sections &&
5074              (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
5075               ParentRegion == OMPD_parallel_sections)));
5076       OrphanSeen = ParentRegion == OMPD_unknown;
5077     } else if (CurrentRegion == OMPD_master || CurrentRegion == OMPD_masked) {
5078       // OpenMP 5.1 [2.22, Nesting of Regions]
5079       // A masked region may not be closely nested inside a worksharing, loop,
5080       // atomic, task, or taskloop region.
5081       NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
5082                           isOpenMPGenericLoopDirective(ParentRegion) ||
5083                           isOpenMPTaskingDirective(ParentRegion);
5084     } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
5085       // OpenMP [2.16, Nesting of Regions]
5086       // A critical region may not be nested (closely or otherwise) inside a
5087       // critical region with the same name. Note that this restriction is not
5088       // sufficient to prevent deadlock.
5089       SourceLocation PreviousCriticalLoc;
5090       bool DeadLock = Stack->hasDirective(
5091           [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
5092                                               const DeclarationNameInfo &DNI,
5093                                               SourceLocation Loc) {
5094             if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
5095               PreviousCriticalLoc = Loc;
5096               return true;
5097             }
5098             return false;
5099           },
5100           false /* skip top directive */);
5101       if (DeadLock) {
5102         SemaRef.Diag(StartLoc,
5103                      diag::err_omp_prohibited_region_critical_same_name)
5104             << CurrentName.getName();
5105         if (PreviousCriticalLoc.isValid())
5106           SemaRef.Diag(PreviousCriticalLoc,
5107                        diag::note_omp_previous_critical_region);
5108         return true;
5109       }
5110     } else if (CurrentRegion == OMPD_barrier) {
5111       // OpenMP 5.1 [2.22, Nesting of Regions]
5112       // A barrier region may not be closely nested inside a worksharing, loop,
5113       // task, taskloop, critical, ordered, atomic, or masked region.
5114       NestingProhibited =
5115           isOpenMPWorksharingDirective(ParentRegion) ||
5116           isOpenMPGenericLoopDirective(ParentRegion) ||
5117           isOpenMPTaskingDirective(ParentRegion) ||
5118           ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
5119           ParentRegion == OMPD_parallel_master ||
5120           ParentRegion == OMPD_parallel_masked ||
5121           ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
5122     } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
5123                !isOpenMPParallelDirective(CurrentRegion) &&
5124                !isOpenMPTeamsDirective(CurrentRegion)) {
5125       // OpenMP 5.1 [2.22, Nesting of Regions]
5126       // A loop region that binds to a parallel region or a worksharing region
5127       // may not be closely nested inside a worksharing, loop, task, taskloop,
5128       // critical, ordered, atomic, or masked region.
5129       NestingProhibited =
5130           isOpenMPWorksharingDirective(ParentRegion) ||
5131           isOpenMPGenericLoopDirective(ParentRegion) ||
5132           isOpenMPTaskingDirective(ParentRegion) ||
5133           ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
5134           ParentRegion == OMPD_parallel_master ||
5135           ParentRegion == OMPD_parallel_masked ||
5136           ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
5137       Recommend = ShouldBeInParallelRegion;
5138     } else if (CurrentRegion == OMPD_ordered) {
5139       // OpenMP [2.16, Nesting of Regions]
5140       // An ordered region may not be closely nested inside a critical,
5141       // atomic, or explicit task region.
5142       // An ordered region must be closely nested inside a loop region (or
5143       // parallel loop region) with an ordered clause.
5144       // OpenMP [2.8.1,simd Construct, Restrictions]
5145       // An ordered construct with the simd clause is the only OpenMP construct
5146       // that can appear in the simd region.
5147       NestingProhibited = ParentRegion == OMPD_critical ||
5148                           isOpenMPTaskingDirective(ParentRegion) ||
5149                           !(isOpenMPSimdDirective(ParentRegion) ||
5150                             Stack->isParentOrderedRegion());
5151       Recommend = ShouldBeInOrderedRegion;
5152     } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
5153       // OpenMP [2.16, Nesting of Regions]
5154       // If specified, a teams construct must be contained within a target
5155       // construct.
5156       NestingProhibited =
5157           (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
5158           (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
5159            ParentRegion != OMPD_target);
5160       OrphanSeen = ParentRegion == OMPD_unknown;
5161       Recommend = ShouldBeInTargetRegion;
5162     } else if (CurrentRegion == OMPD_scan) {
5163       // OpenMP [2.16, Nesting of Regions]
5164       // If specified, a teams construct must be contained within a target
5165       // construct.
5166       NestingProhibited =
5167           SemaRef.LangOpts.OpenMP < 50 ||
5168           (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
5169            ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
5170            ParentRegion != OMPD_parallel_for_simd);
5171       OrphanSeen = ParentRegion == OMPD_unknown;
5172       Recommend = ShouldBeInLoopSimdRegion;
5173     }
5174     if (!NestingProhibited &&
5175         !isOpenMPTargetExecutionDirective(CurrentRegion) &&
5176         !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
5177         (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
5178       // OpenMP [5.1, 2.22, Nesting of Regions]
5179       // distribute, distribute simd, distribute parallel worksharing-loop,
5180       // distribute parallel worksharing-loop SIMD, loop, parallel regions,
5181       // including any parallel regions arising from combined constructs,
5182       // omp_get_num_teams() regions, and omp_get_team_num() regions are the
5183       // only OpenMP regions that may be strictly nested inside the teams
5184       // region.
5185       //
5186       // As an extension, we permit atomic within teams as well.
5187       NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
5188                           !isOpenMPDistributeDirective(CurrentRegion) &&
5189                           CurrentRegion != OMPD_loop &&
5190                           !(SemaRef.getLangOpts().OpenMPExtensions &&
5191                             CurrentRegion == OMPD_atomic);
5192       Recommend = ShouldBeInParallelRegion;
5193     }
5194     if (!NestingProhibited && CurrentRegion == OMPD_loop) {
5195       // OpenMP [5.1, 2.11.7, loop Construct, Restrictions]
5196       // If the bind clause is present on the loop construct and binding is
5197       // teams then the corresponding loop region must be strictly nested inside
5198       // a teams region.
5199       NestingProhibited = BindKind == OMPC_BIND_teams &&
5200                           ParentRegion != OMPD_teams &&
5201                           ParentRegion != OMPD_target_teams;
5202       Recommend = ShouldBeInTeamsRegion;
5203     }
5204     if (!NestingProhibited &&
5205         isOpenMPNestingDistributeDirective(CurrentRegion)) {
5206       // OpenMP 4.5 [2.17 Nesting of Regions]
5207       // The region associated with the distribute construct must be strictly
5208       // nested inside a teams region
5209       NestingProhibited =
5210           (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
5211       Recommend = ShouldBeInTeamsRegion;
5212     }
5213     if (!NestingProhibited &&
5214         (isOpenMPTargetExecutionDirective(CurrentRegion) ||
5215          isOpenMPTargetDataManagementDirective(CurrentRegion))) {
5216       // OpenMP 4.5 [2.17 Nesting of Regions]
5217       // If a target, target update, target data, target enter data, or
5218       // target exit data construct is encountered during execution of a
5219       // target region, the behavior is unspecified.
5220       NestingProhibited = Stack->hasDirective(
5221           [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
5222                              SourceLocation) {
5223             if (isOpenMPTargetExecutionDirective(K)) {
5224               OffendingRegion = K;
5225               return true;
5226             }
5227             return false;
5228           },
5229           false /* don't skip top directive */);
5230       CloseNesting = false;
5231     }
5232     if (NestingProhibited) {
5233       if (OrphanSeen) {
5234         SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
5235             << getOpenMPDirectiveName(CurrentRegion) << Recommend;
5236       } else {
5237         SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
5238             << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
5239             << Recommend << getOpenMPDirectiveName(CurrentRegion);
5240       }
5241       return true;
5242     }
5243   }
5244   return false;
5245 }
5246 
5247 struct Kind2Unsigned {
5248   using argument_type = OpenMPDirectiveKind;
5249   unsigned operator()(argument_type DK) { return unsigned(DK); }
5250 };
5251 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
5252                            ArrayRef<OMPClause *> Clauses,
5253                            ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
5254   bool ErrorFound = false;
5255   unsigned NamedModifiersNumber = 0;
5256   llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
5257   FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
5258   SmallVector<SourceLocation, 4> NameModifierLoc;
5259   for (const OMPClause *C : Clauses) {
5260     if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
5261       // At most one if clause without a directive-name-modifier can appear on
5262       // the directive.
5263       OpenMPDirectiveKind CurNM = IC->getNameModifier();
5264       if (FoundNameModifiers[CurNM]) {
5265         S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
5266             << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
5267             << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
5268         ErrorFound = true;
5269       } else if (CurNM != OMPD_unknown) {
5270         NameModifierLoc.push_back(IC->getNameModifierLoc());
5271         ++NamedModifiersNumber;
5272       }
5273       FoundNameModifiers[CurNM] = IC;
5274       if (CurNM == OMPD_unknown)
5275         continue;
5276       // Check if the specified name modifier is allowed for the current
5277       // directive.
5278       // At most one if clause with the particular directive-name-modifier can
5279       // appear on the directive.
5280       if (!llvm::is_contained(AllowedNameModifiers, CurNM)) {
5281         S.Diag(IC->getNameModifierLoc(),
5282                diag::err_omp_wrong_if_directive_name_modifier)
5283             << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
5284         ErrorFound = true;
5285       }
5286     }
5287   }
5288   // If any if clause on the directive includes a directive-name-modifier then
5289   // all if clauses on the directive must include a directive-name-modifier.
5290   if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
5291     if (NamedModifiersNumber == AllowedNameModifiers.size()) {
5292       S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
5293              diag::err_omp_no_more_if_clause);
5294     } else {
5295       std::string Values;
5296       std::string Sep(", ");
5297       unsigned AllowedCnt = 0;
5298       unsigned TotalAllowedNum =
5299           AllowedNameModifiers.size() - NamedModifiersNumber;
5300       for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
5301            ++Cnt) {
5302         OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
5303         if (!FoundNameModifiers[NM]) {
5304           Values += "'";
5305           Values += getOpenMPDirectiveName(NM);
5306           Values += "'";
5307           if (AllowedCnt + 2 == TotalAllowedNum)
5308             Values += " or ";
5309           else if (AllowedCnt + 1 != TotalAllowedNum)
5310             Values += Sep;
5311           ++AllowedCnt;
5312         }
5313       }
5314       S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
5315              diag::err_omp_unnamed_if_clause)
5316           << (TotalAllowedNum > 1) << Values;
5317     }
5318     for (SourceLocation Loc : NameModifierLoc) {
5319       S.Diag(Loc, diag::note_omp_previous_named_if_clause);
5320     }
5321     ErrorFound = true;
5322   }
5323   return ErrorFound;
5324 }
5325 
5326 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
5327                                                    SourceLocation &ELoc,
5328                                                    SourceRange &ERange,
5329                                                    bool AllowArraySection,
5330                                                    StringRef DiagType) {
5331   if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
5332       RefExpr->containsUnexpandedParameterPack())
5333     return std::make_pair(nullptr, true);
5334 
5335   // OpenMP [3.1, C/C++]
5336   //  A list item is a variable name.
5337   // OpenMP  [2.9.3.3, Restrictions, p.1]
5338   //  A variable that is part of another variable (as an array or
5339   //  structure element) cannot appear in a private clause.
5340   RefExpr = RefExpr->IgnoreParens();
5341   enum {
5342     NoArrayExpr = -1,
5343     ArraySubscript = 0,
5344     OMPArraySection = 1
5345   } IsArrayExpr = NoArrayExpr;
5346   if (AllowArraySection) {
5347     if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
5348       Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
5349       while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
5350         Base = TempASE->getBase()->IgnoreParenImpCasts();
5351       RefExpr = Base;
5352       IsArrayExpr = ArraySubscript;
5353     } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
5354       Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
5355       while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
5356         Base = TempOASE->getBase()->IgnoreParenImpCasts();
5357       while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
5358         Base = TempASE->getBase()->IgnoreParenImpCasts();
5359       RefExpr = Base;
5360       IsArrayExpr = OMPArraySection;
5361     }
5362   }
5363   ELoc = RefExpr->getExprLoc();
5364   ERange = RefExpr->getSourceRange();
5365   RefExpr = RefExpr->IgnoreParenImpCasts();
5366   auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
5367   auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
5368   if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
5369       (S.getCurrentThisType().isNull() || !ME ||
5370        !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
5371        !isa<FieldDecl>(ME->getMemberDecl()))) {
5372     if (IsArrayExpr != NoArrayExpr) {
5373       S.Diag(ELoc, diag::err_omp_expected_base_var_name)
5374           << IsArrayExpr << ERange;
5375     } else if (!DiagType.empty()) {
5376       unsigned DiagSelect = S.getLangOpts().CPlusPlus
5377                                 ? (S.getCurrentThisType().isNull() ? 1 : 2)
5378                                 : 0;
5379       S.Diag(ELoc, diag::err_omp_expected_var_name_member_expr_with_type)
5380           << DiagSelect << DiagType << ERange;
5381     } else {
5382       S.Diag(ELoc,
5383              AllowArraySection
5384                  ? diag::err_omp_expected_var_name_member_expr_or_array_item
5385                  : diag::err_omp_expected_var_name_member_expr)
5386           << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
5387     }
5388     return std::make_pair(nullptr, false);
5389   }
5390   return std::make_pair(
5391       getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
5392 }
5393 
5394 namespace {
5395 /// Checks if the allocator is used in uses_allocators clause to be allowed in
5396 /// target regions.
5397 class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> {
5398   DSAStackTy *S = nullptr;
5399 
5400 public:
5401   bool VisitDeclRefExpr(const DeclRefExpr *E) {
5402     return S->isUsesAllocatorsDecl(E->getDecl())
5403                .value_or(DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
5404            DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
5405   }
5406   bool VisitStmt(const Stmt *S) {
5407     for (const Stmt *Child : S->children()) {
5408       if (Child && Visit(Child))
5409         return true;
5410     }
5411     return false;
5412   }
5413   explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
5414 };
5415 } // namespace
5416 
5417 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
5418                                  ArrayRef<OMPClause *> Clauses) {
5419   assert(!S.CurContext->isDependentContext() &&
5420          "Expected non-dependent context.");
5421   auto AllocateRange =
5422       llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
5423   llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> DeclToCopy;
5424   auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
5425     return isOpenMPPrivate(C->getClauseKind());
5426   });
5427   for (OMPClause *Cl : PrivateRange) {
5428     MutableArrayRef<Expr *>::iterator I, It, Et;
5429     if (Cl->getClauseKind() == OMPC_private) {
5430       auto *PC = cast<OMPPrivateClause>(Cl);
5431       I = PC->private_copies().begin();
5432       It = PC->varlist_begin();
5433       Et = PC->varlist_end();
5434     } else if (Cl->getClauseKind() == OMPC_firstprivate) {
5435       auto *PC = cast<OMPFirstprivateClause>(Cl);
5436       I = PC->private_copies().begin();
5437       It = PC->varlist_begin();
5438       Et = PC->varlist_end();
5439     } else if (Cl->getClauseKind() == OMPC_lastprivate) {
5440       auto *PC = cast<OMPLastprivateClause>(Cl);
5441       I = PC->private_copies().begin();
5442       It = PC->varlist_begin();
5443       Et = PC->varlist_end();
5444     } else if (Cl->getClauseKind() == OMPC_linear) {
5445       auto *PC = cast<OMPLinearClause>(Cl);
5446       I = PC->privates().begin();
5447       It = PC->varlist_begin();
5448       Et = PC->varlist_end();
5449     } else if (Cl->getClauseKind() == OMPC_reduction) {
5450       auto *PC = cast<OMPReductionClause>(Cl);
5451       I = PC->privates().begin();
5452       It = PC->varlist_begin();
5453       Et = PC->varlist_end();
5454     } else if (Cl->getClauseKind() == OMPC_task_reduction) {
5455       auto *PC = cast<OMPTaskReductionClause>(Cl);
5456       I = PC->privates().begin();
5457       It = PC->varlist_begin();
5458       Et = PC->varlist_end();
5459     } else if (Cl->getClauseKind() == OMPC_in_reduction) {
5460       auto *PC = cast<OMPInReductionClause>(Cl);
5461       I = PC->privates().begin();
5462       It = PC->varlist_begin();
5463       Et = PC->varlist_end();
5464     } else {
5465       llvm_unreachable("Expected private clause.");
5466     }
5467     for (Expr *E : llvm::make_range(It, Et)) {
5468       if (!*I) {
5469         ++I;
5470         continue;
5471       }
5472       SourceLocation ELoc;
5473       SourceRange ERange;
5474       Expr *SimpleRefExpr = E;
5475       auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
5476                                 /*AllowArraySection=*/true);
5477       DeclToCopy.try_emplace(Res.first,
5478                              cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
5479       ++I;
5480     }
5481   }
5482   for (OMPClause *C : AllocateRange) {
5483     auto *AC = cast<OMPAllocateClause>(C);
5484     if (S.getLangOpts().OpenMP >= 50 &&
5485         !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() &&
5486         isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
5487         AC->getAllocator()) {
5488       Expr *Allocator = AC->getAllocator();
5489       // OpenMP, 2.12.5 target Construct
5490       // Memory allocators that do not appear in a uses_allocators clause cannot
5491       // appear as an allocator in an allocate clause or be used in the target
5492       // region unless a requires directive with the dynamic_allocators clause
5493       // is present in the same compilation unit.
5494       AllocatorChecker Checker(Stack);
5495       if (Checker.Visit(Allocator))
5496         S.Diag(Allocator->getExprLoc(),
5497                diag::err_omp_allocator_not_in_uses_allocators)
5498             << Allocator->getSourceRange();
5499     }
5500     OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
5501         getAllocatorKind(S, Stack, AC->getAllocator());
5502     // OpenMP, 2.11.4 allocate Clause, Restrictions.
5503     // For task, taskloop or target directives, allocation requests to memory
5504     // allocators with the trait access set to thread result in unspecified
5505     // behavior.
5506     if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
5507         (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
5508          isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
5509       S.Diag(AC->getAllocator()->getExprLoc(),
5510              diag::warn_omp_allocate_thread_on_task_target_directive)
5511           << getOpenMPDirectiveName(Stack->getCurrentDirective());
5512     }
5513     for (Expr *E : AC->varlists()) {
5514       SourceLocation ELoc;
5515       SourceRange ERange;
5516       Expr *SimpleRefExpr = E;
5517       auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
5518       ValueDecl *VD = Res.first;
5519       DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
5520       if (!isOpenMPPrivate(Data.CKind)) {
5521         S.Diag(E->getExprLoc(),
5522                diag::err_omp_expected_private_copy_for_allocate);
5523         continue;
5524       }
5525       VarDecl *PrivateVD = DeclToCopy[VD];
5526       if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
5527                                             AllocatorKind, AC->getAllocator()))
5528         continue;
5529       // Placeholder until allocate clause supports align modifier.
5530       Expr *Alignment = nullptr;
5531       applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
5532                                 Alignment, E->getSourceRange());
5533     }
5534   }
5535 }
5536 
5537 namespace {
5538 /// Rewrite statements and expressions for Sema \p Actions CurContext.
5539 ///
5540 /// Used to wrap already parsed statements/expressions into a new CapturedStmt
5541 /// context. DeclRefExpr used inside the new context are changed to refer to the
5542 /// captured variable instead.
5543 class CaptureVars : public TreeTransform<CaptureVars> {
5544   using BaseTransform = TreeTransform<CaptureVars>;
5545 
5546 public:
5547   CaptureVars(Sema &Actions) : BaseTransform(Actions) {}
5548 
5549   bool AlwaysRebuild() { return true; }
5550 };
5551 } // namespace
5552 
5553 static VarDecl *precomputeExpr(Sema &Actions,
5554                                SmallVectorImpl<Stmt *> &BodyStmts, Expr *E,
5555                                StringRef Name) {
5556   Expr *NewE = AssertSuccess(CaptureVars(Actions).TransformExpr(E));
5557   VarDecl *NewVar = buildVarDecl(Actions, {}, NewE->getType(), Name, nullptr,
5558                                  dyn_cast<DeclRefExpr>(E->IgnoreImplicit()));
5559   auto *NewDeclStmt = cast<DeclStmt>(AssertSuccess(
5560       Actions.ActOnDeclStmt(Actions.ConvertDeclToDeclGroup(NewVar), {}, {})));
5561   Actions.AddInitializerToDecl(NewDeclStmt->getSingleDecl(), NewE, false);
5562   BodyStmts.push_back(NewDeclStmt);
5563   return NewVar;
5564 }
5565 
5566 /// Create a closure that computes the number of iterations of a loop.
5567 ///
5568 /// \param Actions   The Sema object.
5569 /// \param LogicalTy Type for the logical iteration number.
5570 /// \param Rel       Comparison operator of the loop condition.
5571 /// \param StartExpr Value of the loop counter at the first iteration.
5572 /// \param StopExpr  Expression the loop counter is compared against in the loop
5573 /// condition. \param StepExpr      Amount of increment after each iteration.
5574 ///
5575 /// \return Closure (CapturedStmt) of the distance calculation.
5576 static CapturedStmt *buildDistanceFunc(Sema &Actions, QualType LogicalTy,
5577                                        BinaryOperator::Opcode Rel,
5578                                        Expr *StartExpr, Expr *StopExpr,
5579                                        Expr *StepExpr) {
5580   ASTContext &Ctx = Actions.getASTContext();
5581   TypeSourceInfo *LogicalTSI = Ctx.getTrivialTypeSourceInfo(LogicalTy);
5582 
5583   // Captured regions currently don't support return values, we use an
5584   // out-parameter instead. All inputs are implicit captures.
5585   // TODO: Instead of capturing each DeclRefExpr occurring in
5586   // StartExpr/StopExpr/Step, these could also be passed as a value capture.
5587   QualType ResultTy = Ctx.getLValueReferenceType(LogicalTy);
5588   Sema::CapturedParamNameType Params[] = {{"Distance", ResultTy},
5589                                           {StringRef(), QualType()}};
5590   Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5591 
5592   Stmt *Body;
5593   {
5594     Sema::CompoundScopeRAII CompoundScope(Actions);
5595     CapturedDecl *CS = cast<CapturedDecl>(Actions.CurContext);
5596 
5597     // Get the LValue expression for the result.
5598     ImplicitParamDecl *DistParam = CS->getParam(0);
5599     DeclRefExpr *DistRef = Actions.BuildDeclRefExpr(
5600         DistParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5601 
5602     SmallVector<Stmt *, 4> BodyStmts;
5603 
5604     // Capture all referenced variable references.
5605     // TODO: Instead of computing NewStart/NewStop/NewStep inside the
5606     // CapturedStmt, we could compute them before and capture the result, to be
5607     // used jointly with the LoopVar function.
5608     VarDecl *NewStart = precomputeExpr(Actions, BodyStmts, StartExpr, ".start");
5609     VarDecl *NewStop = precomputeExpr(Actions, BodyStmts, StopExpr, ".stop");
5610     VarDecl *NewStep = precomputeExpr(Actions, BodyStmts, StepExpr, ".step");
5611     auto BuildVarRef = [&](VarDecl *VD) {
5612       return buildDeclRefExpr(Actions, VD, VD->getType(), {});
5613     };
5614 
5615     IntegerLiteral *Zero = IntegerLiteral::Create(
5616         Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 0), LogicalTy, {});
5617     IntegerLiteral *One = IntegerLiteral::Create(
5618         Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {});
5619     Expr *Dist;
5620     if (Rel == BO_NE) {
5621       // When using a != comparison, the increment can be +1 or -1. This can be
5622       // dynamic at runtime, so we need to check for the direction.
5623       Expr *IsNegStep = AssertSuccess(
5624           Actions.BuildBinOp(nullptr, {}, BO_LT, BuildVarRef(NewStep), Zero));
5625 
5626       // Positive increment.
5627       Expr *ForwardRange = AssertSuccess(Actions.BuildBinOp(
5628           nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5629       ForwardRange = AssertSuccess(
5630           Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, ForwardRange));
5631       Expr *ForwardDist = AssertSuccess(Actions.BuildBinOp(
5632           nullptr, {}, BO_Div, ForwardRange, BuildVarRef(NewStep)));
5633 
5634       // Negative increment.
5635       Expr *BackwardRange = AssertSuccess(Actions.BuildBinOp(
5636           nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5637       BackwardRange = AssertSuccess(
5638           Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, BackwardRange));
5639       Expr *NegIncAmount = AssertSuccess(
5640           Actions.BuildUnaryOp(nullptr, {}, UO_Minus, BuildVarRef(NewStep)));
5641       Expr *BackwardDist = AssertSuccess(
5642           Actions.BuildBinOp(nullptr, {}, BO_Div, BackwardRange, NegIncAmount));
5643 
5644       // Use the appropriate case.
5645       Dist = AssertSuccess(Actions.ActOnConditionalOp(
5646           {}, {}, IsNegStep, BackwardDist, ForwardDist));
5647     } else {
5648       assert((Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT) &&
5649              "Expected one of these relational operators");
5650 
5651       // We can derive the direction from any other comparison operator. It is
5652       // non well-formed OpenMP if Step increments/decrements in the other
5653       // directions. Whether at least the first iteration passes the loop
5654       // condition.
5655       Expr *HasAnyIteration = AssertSuccess(Actions.BuildBinOp(
5656           nullptr, {}, Rel, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5657 
5658       // Compute the range between first and last counter value.
5659       Expr *Range;
5660       if (Rel == BO_GE || Rel == BO_GT)
5661         Range = AssertSuccess(Actions.BuildBinOp(
5662             nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5663       else
5664         Range = AssertSuccess(Actions.BuildBinOp(
5665             nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5666 
5667       // Ensure unsigned range space.
5668       Range =
5669           AssertSuccess(Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, Range));
5670 
5671       if (Rel == BO_LE || Rel == BO_GE) {
5672         // Add one to the range if the relational operator is inclusive.
5673         Range =
5674             AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, Range, One));
5675       }
5676 
5677       // Divide by the absolute step amount. If the range is not a multiple of
5678       // the step size, rounding-up the effective upper bound ensures that the
5679       // last iteration is included.
5680       // Note that the rounding-up may cause an overflow in a temporry that
5681       // could be avoided, but would have occurred in a C-style for-loop as well.
5682       Expr *Divisor = BuildVarRef(NewStep);
5683       if (Rel == BO_GE || Rel == BO_GT)
5684         Divisor =
5685             AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Minus, Divisor));
5686       Expr *DivisorMinusOne =
5687           AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Sub, Divisor, One));
5688       Expr *RangeRoundUp = AssertSuccess(
5689           Actions.BuildBinOp(nullptr, {}, BO_Add, Range, DivisorMinusOne));
5690       Dist = AssertSuccess(
5691           Actions.BuildBinOp(nullptr, {}, BO_Div, RangeRoundUp, Divisor));
5692 
5693       // If there is not at least one iteration, the range contains garbage. Fix
5694       // to zero in this case.
5695       Dist = AssertSuccess(
5696           Actions.ActOnConditionalOp({}, {}, HasAnyIteration, Dist, Zero));
5697     }
5698 
5699     // Assign the result to the out-parameter.
5700     Stmt *ResultAssign = AssertSuccess(Actions.BuildBinOp(
5701         Actions.getCurScope(), {}, BO_Assign, DistRef, Dist));
5702     BodyStmts.push_back(ResultAssign);
5703 
5704     Body = AssertSuccess(Actions.ActOnCompoundStmt({}, {}, BodyStmts, false));
5705   }
5706 
5707   return cast<CapturedStmt>(
5708       AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5709 }
5710 
5711 /// Create a closure that computes the loop variable from the logical iteration
5712 /// number.
5713 ///
5714 /// \param Actions   The Sema object.
5715 /// \param LoopVarTy Type for the loop variable used for result value.
5716 /// \param LogicalTy Type for the logical iteration number.
5717 /// \param StartExpr Value of the loop counter at the first iteration.
5718 /// \param Step      Amount of increment after each iteration.
5719 /// \param Deref     Whether the loop variable is a dereference of the loop
5720 /// counter variable.
5721 ///
5722 /// \return Closure (CapturedStmt) of the loop value calculation.
5723 static CapturedStmt *buildLoopVarFunc(Sema &Actions, QualType LoopVarTy,
5724                                       QualType LogicalTy,
5725                                       DeclRefExpr *StartExpr, Expr *Step,
5726                                       bool Deref) {
5727   ASTContext &Ctx = Actions.getASTContext();
5728 
5729   // Pass the result as an out-parameter. Passing as return value would require
5730   // the OpenMPIRBuilder to know additional C/C++ semantics, such as how to
5731   // invoke a copy constructor.
5732   QualType TargetParamTy = Ctx.getLValueReferenceType(LoopVarTy);
5733   Sema::CapturedParamNameType Params[] = {{"LoopVar", TargetParamTy},
5734                                           {"Logical", LogicalTy},
5735                                           {StringRef(), QualType()}};
5736   Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5737 
5738   // Capture the initial iterator which represents the LoopVar value at the
5739   // zero's logical iteration. Since the original ForStmt/CXXForRangeStmt update
5740   // it in every iteration, capture it by value before it is modified.
5741   VarDecl *StartVar = cast<VarDecl>(StartExpr->getDecl());
5742   bool Invalid = Actions.tryCaptureVariable(StartVar, {},
5743                                             Sema::TryCapture_ExplicitByVal, {});
5744   (void)Invalid;
5745   assert(!Invalid && "Expecting capture-by-value to work.");
5746 
5747   Expr *Body;
5748   {
5749     Sema::CompoundScopeRAII CompoundScope(Actions);
5750     auto *CS = cast<CapturedDecl>(Actions.CurContext);
5751 
5752     ImplicitParamDecl *TargetParam = CS->getParam(0);
5753     DeclRefExpr *TargetRef = Actions.BuildDeclRefExpr(
5754         TargetParam, LoopVarTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5755     ImplicitParamDecl *IndvarParam = CS->getParam(1);
5756     DeclRefExpr *LogicalRef = Actions.BuildDeclRefExpr(
5757         IndvarParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5758 
5759     // Capture the Start expression.
5760     CaptureVars Recap(Actions);
5761     Expr *NewStart = AssertSuccess(Recap.TransformExpr(StartExpr));
5762     Expr *NewStep = AssertSuccess(Recap.TransformExpr(Step));
5763 
5764     Expr *Skip = AssertSuccess(
5765         Actions.BuildBinOp(nullptr, {}, BO_Mul, NewStep, LogicalRef));
5766     // TODO: Explicitly cast to the iterator's difference_type instead of
5767     // relying on implicit conversion.
5768     Expr *Advanced =
5769         AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, NewStart, Skip));
5770 
5771     if (Deref) {
5772       // For range-based for-loops convert the loop counter value to a concrete
5773       // loop variable value by dereferencing the iterator.
5774       Advanced =
5775           AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Deref, Advanced));
5776     }
5777 
5778     // Assign the result to the output parameter.
5779     Body = AssertSuccess(Actions.BuildBinOp(Actions.getCurScope(), {},
5780                                             BO_Assign, TargetRef, Advanced));
5781   }
5782   return cast<CapturedStmt>(
5783       AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5784 }
5785 
5786 StmtResult Sema::ActOnOpenMPCanonicalLoop(Stmt *AStmt) {
5787   ASTContext &Ctx = getASTContext();
5788 
5789   // Extract the common elements of ForStmt and CXXForRangeStmt:
5790   // Loop variable, repeat condition, increment
5791   Expr *Cond, *Inc;
5792   VarDecl *LIVDecl, *LUVDecl;
5793   if (auto *For = dyn_cast<ForStmt>(AStmt)) {
5794     Stmt *Init = For->getInit();
5795     if (auto *LCVarDeclStmt = dyn_cast<DeclStmt>(Init)) {
5796       // For statement declares loop variable.
5797       LIVDecl = cast<VarDecl>(LCVarDeclStmt->getSingleDecl());
5798     } else if (auto *LCAssign = dyn_cast<BinaryOperator>(Init)) {
5799       // For statement reuses variable.
5800       assert(LCAssign->getOpcode() == BO_Assign &&
5801              "init part must be a loop variable assignment");
5802       auto *CounterRef = cast<DeclRefExpr>(LCAssign->getLHS());
5803       LIVDecl = cast<VarDecl>(CounterRef->getDecl());
5804     } else
5805       llvm_unreachable("Cannot determine loop variable");
5806     LUVDecl = LIVDecl;
5807 
5808     Cond = For->getCond();
5809     Inc = For->getInc();
5810   } else if (auto *RangeFor = dyn_cast<CXXForRangeStmt>(AStmt)) {
5811     DeclStmt *BeginStmt = RangeFor->getBeginStmt();
5812     LIVDecl = cast<VarDecl>(BeginStmt->getSingleDecl());
5813     LUVDecl = RangeFor->getLoopVariable();
5814 
5815     Cond = RangeFor->getCond();
5816     Inc = RangeFor->getInc();
5817   } else
5818     llvm_unreachable("unhandled kind of loop");
5819 
5820   QualType CounterTy = LIVDecl->getType();
5821   QualType LVTy = LUVDecl->getType();
5822 
5823   // Analyze the loop condition.
5824   Expr *LHS, *RHS;
5825   BinaryOperator::Opcode CondRel;
5826   Cond = Cond->IgnoreImplicit();
5827   if (auto *CondBinExpr = dyn_cast<BinaryOperator>(Cond)) {
5828     LHS = CondBinExpr->getLHS();
5829     RHS = CondBinExpr->getRHS();
5830     CondRel = CondBinExpr->getOpcode();
5831   } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Cond)) {
5832     assert(CondCXXOp->getNumArgs() == 2 && "Comparison should have 2 operands");
5833     LHS = CondCXXOp->getArg(0);
5834     RHS = CondCXXOp->getArg(1);
5835     switch (CondCXXOp->getOperator()) {
5836     case OO_ExclaimEqual:
5837       CondRel = BO_NE;
5838       break;
5839     case OO_Less:
5840       CondRel = BO_LT;
5841       break;
5842     case OO_LessEqual:
5843       CondRel = BO_LE;
5844       break;
5845     case OO_Greater:
5846       CondRel = BO_GT;
5847       break;
5848     case OO_GreaterEqual:
5849       CondRel = BO_GE;
5850       break;
5851     default:
5852       llvm_unreachable("unexpected iterator operator");
5853     }
5854   } else
5855     llvm_unreachable("unexpected loop condition");
5856 
5857   // Normalize such that the loop counter is on the LHS.
5858   if (!isa<DeclRefExpr>(LHS->IgnoreImplicit()) ||
5859       cast<DeclRefExpr>(LHS->IgnoreImplicit())->getDecl() != LIVDecl) {
5860     std::swap(LHS, RHS);
5861     CondRel = BinaryOperator::reverseComparisonOp(CondRel);
5862   }
5863   auto *CounterRef = cast<DeclRefExpr>(LHS->IgnoreImplicit());
5864 
5865   // Decide the bit width for the logical iteration counter. By default use the
5866   // unsigned ptrdiff_t integer size (for iterators and pointers).
5867   // TODO: For iterators, use iterator::difference_type,
5868   // std::iterator_traits<>::difference_type or decltype(it - end).
5869   QualType LogicalTy = Ctx.getUnsignedPointerDiffType();
5870   if (CounterTy->isIntegerType()) {
5871     unsigned BitWidth = Ctx.getIntWidth(CounterTy);
5872     LogicalTy = Ctx.getIntTypeForBitwidth(BitWidth, false);
5873   }
5874 
5875   // Analyze the loop increment.
5876   Expr *Step;
5877   if (auto *IncUn = dyn_cast<UnaryOperator>(Inc)) {
5878     int Direction;
5879     switch (IncUn->getOpcode()) {
5880     case UO_PreInc:
5881     case UO_PostInc:
5882       Direction = 1;
5883       break;
5884     case UO_PreDec:
5885     case UO_PostDec:
5886       Direction = -1;
5887       break;
5888     default:
5889       llvm_unreachable("unhandled unary increment operator");
5890     }
5891     Step = IntegerLiteral::Create(
5892         Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), Direction), LogicalTy, {});
5893   } else if (auto *IncBin = dyn_cast<BinaryOperator>(Inc)) {
5894     if (IncBin->getOpcode() == BO_AddAssign) {
5895       Step = IncBin->getRHS();
5896     } else if (IncBin->getOpcode() == BO_SubAssign) {
5897       Step =
5898           AssertSuccess(BuildUnaryOp(nullptr, {}, UO_Minus, IncBin->getRHS()));
5899     } else
5900       llvm_unreachable("unhandled binary increment operator");
5901   } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Inc)) {
5902     switch (CondCXXOp->getOperator()) {
5903     case OO_PlusPlus:
5904       Step = IntegerLiteral::Create(
5905           Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {});
5906       break;
5907     case OO_MinusMinus:
5908       Step = IntegerLiteral::Create(
5909           Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), -1), LogicalTy, {});
5910       break;
5911     case OO_PlusEqual:
5912       Step = CondCXXOp->getArg(1);
5913       break;
5914     case OO_MinusEqual:
5915       Step = AssertSuccess(
5916           BuildUnaryOp(nullptr, {}, UO_Minus, CondCXXOp->getArg(1)));
5917       break;
5918     default:
5919       llvm_unreachable("unhandled overloaded increment operator");
5920     }
5921   } else
5922     llvm_unreachable("unknown increment expression");
5923 
5924   CapturedStmt *DistanceFunc =
5925       buildDistanceFunc(*this, LogicalTy, CondRel, LHS, RHS, Step);
5926   CapturedStmt *LoopVarFunc = buildLoopVarFunc(
5927       *this, LVTy, LogicalTy, CounterRef, Step, isa<CXXForRangeStmt>(AStmt));
5928   DeclRefExpr *LVRef = BuildDeclRefExpr(LUVDecl, LUVDecl->getType(), VK_LValue,
5929                                         {}, nullptr, nullptr, {}, nullptr);
5930   return OMPCanonicalLoop::create(getASTContext(), AStmt, DistanceFunc,
5931                                   LoopVarFunc, LVRef);
5932 }
5933 
5934 StmtResult Sema::ActOnOpenMPLoopnest(Stmt *AStmt) {
5935   // Handle a literal loop.
5936   if (isa<ForStmt>(AStmt) || isa<CXXForRangeStmt>(AStmt))
5937     return ActOnOpenMPCanonicalLoop(AStmt);
5938 
5939   // If not a literal loop, it must be the result of a loop transformation.
5940   OMPExecutableDirective *LoopTransform = cast<OMPExecutableDirective>(AStmt);
5941   assert(
5942       isOpenMPLoopTransformationDirective(LoopTransform->getDirectiveKind()) &&
5943       "Loop transformation directive expected");
5944   return LoopTransform;
5945 }
5946 
5947 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
5948                                             CXXScopeSpec &MapperIdScopeSpec,
5949                                             const DeclarationNameInfo &MapperId,
5950                                             QualType Type,
5951                                             Expr *UnresolvedMapper);
5952 
5953 /// Perform DFS through the structure/class data members trying to find
5954 /// member(s) with user-defined 'default' mapper and generate implicit map
5955 /// clauses for such members with the found 'default' mapper.
5956 static void
5957 processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack,
5958                                       SmallVectorImpl<OMPClause *> &Clauses) {
5959   // Check for the deault mapper for data members.
5960   if (S.getLangOpts().OpenMP < 50)
5961     return;
5962   SmallVector<OMPClause *, 4> ImplicitMaps;
5963   for (int Cnt = 0, EndCnt = Clauses.size(); Cnt < EndCnt; ++Cnt) {
5964     auto *C = dyn_cast<OMPMapClause>(Clauses[Cnt]);
5965     if (!C)
5966       continue;
5967     SmallVector<Expr *, 4> SubExprs;
5968     auto *MI = C->mapperlist_begin();
5969     for (auto I = C->varlist_begin(), End = C->varlist_end(); I != End;
5970          ++I, ++MI) {
5971       // Expression is mapped using mapper - skip it.
5972       if (*MI)
5973         continue;
5974       Expr *E = *I;
5975       // Expression is dependent - skip it, build the mapper when it gets
5976       // instantiated.
5977       if (E->isTypeDependent() || E->isValueDependent() ||
5978           E->containsUnexpandedParameterPack())
5979         continue;
5980       // Array section - need to check for the mapping of the array section
5981       // element.
5982       QualType CanonType = E->getType().getCanonicalType();
5983       if (CanonType->isSpecificBuiltinType(BuiltinType::OMPArraySection)) {
5984         const auto *OASE = cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts());
5985         QualType BaseType =
5986             OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
5987         QualType ElemType;
5988         if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
5989           ElemType = ATy->getElementType();
5990         else
5991           ElemType = BaseType->getPointeeType();
5992         CanonType = ElemType;
5993       }
5994 
5995       // DFS over data members in structures/classes.
5996       SmallVector<std::pair<QualType, FieldDecl *>, 4> Types(
5997           1, {CanonType, nullptr});
5998       llvm::DenseMap<const Type *, Expr *> Visited;
5999       SmallVector<std::pair<FieldDecl *, unsigned>, 4> ParentChain(
6000           1, {nullptr, 1});
6001       while (!Types.empty()) {
6002         QualType BaseType;
6003         FieldDecl *CurFD;
6004         std::tie(BaseType, CurFD) = Types.pop_back_val();
6005         while (ParentChain.back().second == 0)
6006           ParentChain.pop_back();
6007         --ParentChain.back().second;
6008         if (BaseType.isNull())
6009           continue;
6010         // Only structs/classes are allowed to have mappers.
6011         const RecordDecl *RD = BaseType.getCanonicalType()->getAsRecordDecl();
6012         if (!RD)
6013           continue;
6014         auto It = Visited.find(BaseType.getTypePtr());
6015         if (It == Visited.end()) {
6016           // Try to find the associated user-defined mapper.
6017           CXXScopeSpec MapperIdScopeSpec;
6018           DeclarationNameInfo DefaultMapperId;
6019           DefaultMapperId.setName(S.Context.DeclarationNames.getIdentifier(
6020               &S.Context.Idents.get("default")));
6021           DefaultMapperId.setLoc(E->getExprLoc());
6022           ExprResult ER = buildUserDefinedMapperRef(
6023               S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId,
6024               BaseType, /*UnresolvedMapper=*/nullptr);
6025           if (ER.isInvalid())
6026             continue;
6027           It = Visited.try_emplace(BaseType.getTypePtr(), ER.get()).first;
6028         }
6029         // Found default mapper.
6030         if (It->second) {
6031           auto *OE = new (S.Context) OpaqueValueExpr(E->getExprLoc(), CanonType,
6032                                                      VK_LValue, OK_Ordinary, E);
6033           OE->setIsUnique(/*V=*/true);
6034           Expr *BaseExpr = OE;
6035           for (const auto &P : ParentChain) {
6036             if (P.first) {
6037               BaseExpr = S.BuildMemberExpr(
6038                   BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
6039                   NestedNameSpecifierLoc(), SourceLocation(), P.first,
6040                   DeclAccessPair::make(P.first, P.first->getAccess()),
6041                   /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
6042                   P.first->getType(), VK_LValue, OK_Ordinary);
6043               BaseExpr = S.DefaultLvalueConversion(BaseExpr).get();
6044             }
6045           }
6046           if (CurFD)
6047             BaseExpr = S.BuildMemberExpr(
6048                 BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
6049                 NestedNameSpecifierLoc(), SourceLocation(), CurFD,
6050                 DeclAccessPair::make(CurFD, CurFD->getAccess()),
6051                 /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
6052                 CurFD->getType(), VK_LValue, OK_Ordinary);
6053           SubExprs.push_back(BaseExpr);
6054           continue;
6055         }
6056         // Check for the "default" mapper for data members.
6057         bool FirstIter = true;
6058         for (FieldDecl *FD : RD->fields()) {
6059           if (!FD)
6060             continue;
6061           QualType FieldTy = FD->getType();
6062           if (FieldTy.isNull() ||
6063               !(FieldTy->isStructureOrClassType() || FieldTy->isUnionType()))
6064             continue;
6065           if (FirstIter) {
6066             FirstIter = false;
6067             ParentChain.emplace_back(CurFD, 1);
6068           } else {
6069             ++ParentChain.back().second;
6070           }
6071           Types.emplace_back(FieldTy, FD);
6072         }
6073       }
6074     }
6075     if (SubExprs.empty())
6076       continue;
6077     CXXScopeSpec MapperIdScopeSpec;
6078     DeclarationNameInfo MapperId;
6079     if (OMPClause *NewClause = S.ActOnOpenMPMapClause(
6080             nullptr, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
6081             MapperIdScopeSpec, MapperId, C->getMapType(),
6082             /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
6083             SubExprs, OMPVarListLocTy()))
6084       Clauses.push_back(NewClause);
6085   }
6086 }
6087 
6088 StmtResult Sema::ActOnOpenMPExecutableDirective(
6089     OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
6090     OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
6091     Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
6092   StmtResult Res = StmtError();
6093   OpenMPBindClauseKind BindKind = OMPC_BIND_unknown;
6094   if (const OMPBindClause *BC =
6095           OMPExecutableDirective::getSingleClause<OMPBindClause>(Clauses))
6096     BindKind = BC->getBindKind();
6097   // First check CancelRegion which is then used in checkNestingOfRegions.
6098   if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
6099       checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
6100                             BindKind, StartLoc))
6101     return StmtError();
6102 
6103   // Report affected OpenMP target offloading behavior when in HIP lang-mode.
6104   if (getLangOpts().HIP && (isOpenMPTargetExecutionDirective(Kind) ||
6105                             isOpenMPTargetDataManagementDirective(Kind)))
6106     Diag(StartLoc, diag::warn_hip_omp_target_directives);
6107 
6108   llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
6109   VarsWithInheritedDSAType VarsWithInheritedDSA;
6110   bool ErrorFound = false;
6111   ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
6112   if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic &&
6113       Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master &&
6114       Kind != OMPD_masked && !isOpenMPLoopTransformationDirective(Kind)) {
6115     assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6116 
6117     // Check default data sharing attributes for referenced variables.
6118     DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
6119     int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
6120     Stmt *S = AStmt;
6121     while (--ThisCaptureLevel >= 0)
6122       S = cast<CapturedStmt>(S)->getCapturedStmt();
6123     DSAChecker.Visit(S);
6124     if (!isOpenMPTargetDataManagementDirective(Kind) &&
6125         !isOpenMPTaskingDirective(Kind)) {
6126       // Visit subcaptures to generate implicit clauses for captured vars.
6127       auto *CS = cast<CapturedStmt>(AStmt);
6128       SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
6129       getOpenMPCaptureRegions(CaptureRegions, Kind);
6130       // Ignore outer tasking regions for target directives.
6131       if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
6132         CS = cast<CapturedStmt>(CS->getCapturedStmt());
6133       DSAChecker.visitSubCaptures(CS);
6134     }
6135     if (DSAChecker.isErrorFound())
6136       return StmtError();
6137     // Generate list of implicitly defined firstprivate variables.
6138     VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
6139 
6140     SmallVector<Expr *, 4> ImplicitFirstprivates(
6141         DSAChecker.getImplicitFirstprivate().begin(),
6142         DSAChecker.getImplicitFirstprivate().end());
6143     SmallVector<Expr *, 4> ImplicitPrivates(
6144         DSAChecker.getImplicitPrivate().begin(),
6145         DSAChecker.getImplicitPrivate().end());
6146     const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
6147     SmallVector<Expr *, 4> ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete];
6148     SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
6149         ImplicitMapModifiers[DefaultmapKindNum];
6150     SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers>
6151         ImplicitMapModifiersLoc[DefaultmapKindNum];
6152     // Get the original location of present modifier from Defaultmap clause.
6153     SourceLocation PresentModifierLocs[DefaultmapKindNum];
6154     for (OMPClause *C : Clauses) {
6155       if (auto *DMC = dyn_cast<OMPDefaultmapClause>(C))
6156         if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present)
6157           PresentModifierLocs[DMC->getDefaultmapKind()] =
6158               DMC->getDefaultmapModifierLoc();
6159     }
6160     for (unsigned VC = 0; VC < DefaultmapKindNum; ++VC) {
6161       auto Kind = static_cast<OpenMPDefaultmapClauseKind>(VC);
6162       for (unsigned I = 0; I < OMPC_MAP_delete; ++I) {
6163         ArrayRef<Expr *> ImplicitMap = DSAChecker.getImplicitMap(
6164             Kind, static_cast<OpenMPMapClauseKind>(I));
6165         ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end());
6166       }
6167       ArrayRef<OpenMPMapModifierKind> ImplicitModifier =
6168           DSAChecker.getImplicitMapModifier(Kind);
6169       ImplicitMapModifiers[VC].append(ImplicitModifier.begin(),
6170                                       ImplicitModifier.end());
6171       std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]),
6172                   ImplicitModifier.size(), PresentModifierLocs[VC]);
6173     }
6174     // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
6175     for (OMPClause *C : Clauses) {
6176       if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
6177         for (Expr *E : IRC->taskgroup_descriptors())
6178           if (E)
6179             ImplicitFirstprivates.emplace_back(E);
6180       }
6181       // OpenMP 5.0, 2.10.1 task Construct
6182       // [detach clause]... The event-handle will be considered as if it was
6183       // specified on a firstprivate clause.
6184       if (auto *DC = dyn_cast<OMPDetachClause>(C))
6185         ImplicitFirstprivates.push_back(DC->getEventHandler());
6186     }
6187     if (!ImplicitFirstprivates.empty()) {
6188       if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
6189               ImplicitFirstprivates, SourceLocation(), SourceLocation(),
6190               SourceLocation())) {
6191         ClausesWithImplicit.push_back(Implicit);
6192         ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
6193                      ImplicitFirstprivates.size();
6194       } else {
6195         ErrorFound = true;
6196       }
6197     }
6198     if (!ImplicitPrivates.empty()) {
6199       if (OMPClause *Implicit =
6200               ActOnOpenMPPrivateClause(ImplicitPrivates, SourceLocation(),
6201                                        SourceLocation(), SourceLocation())) {
6202         ClausesWithImplicit.push_back(Implicit);
6203         ErrorFound = cast<OMPPrivateClause>(Implicit)->varlist_size() !=
6204                      ImplicitPrivates.size();
6205       } else {
6206         ErrorFound = true;
6207       }
6208     }
6209     // OpenMP 5.0 [2.19.7]
6210     // If a list item appears in a reduction, lastprivate or linear
6211     // clause on a combined target construct then it is treated as
6212     // if it also appears in a map clause with a map-type of tofrom
6213     if (getLangOpts().OpenMP >= 50 && Kind != OMPD_target &&
6214         isOpenMPTargetExecutionDirective(Kind)) {
6215       SmallVector<Expr *, 4> ImplicitExprs;
6216       for (OMPClause *C : Clauses) {
6217         if (auto *RC = dyn_cast<OMPReductionClause>(C))
6218           for (Expr *E : RC->varlists())
6219             if (!isa<DeclRefExpr>(E->IgnoreParenImpCasts()))
6220               ImplicitExprs.emplace_back(E);
6221       }
6222       if (!ImplicitExprs.empty()) {
6223         ArrayRef<Expr *> Exprs = ImplicitExprs;
6224         CXXScopeSpec MapperIdScopeSpec;
6225         DeclarationNameInfo MapperId;
6226         if (OMPClause *Implicit = ActOnOpenMPMapClause(
6227                 nullptr, OMPC_MAP_MODIFIER_unknown, SourceLocation(),
6228                 MapperIdScopeSpec, MapperId, OMPC_MAP_tofrom,
6229                 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
6230                 Exprs, OMPVarListLocTy(), /*NoDiagnose=*/true))
6231           ClausesWithImplicit.emplace_back(Implicit);
6232       }
6233     }
6234     for (unsigned I = 0, E = DefaultmapKindNum; I < E; ++I) {
6235       int ClauseKindCnt = -1;
6236       for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps[I]) {
6237         ++ClauseKindCnt;
6238         if (ImplicitMap.empty())
6239           continue;
6240         CXXScopeSpec MapperIdScopeSpec;
6241         DeclarationNameInfo MapperId;
6242         auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
6243         if (OMPClause *Implicit = ActOnOpenMPMapClause(
6244                 nullptr, ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I],
6245                 MapperIdScopeSpec, MapperId, Kind, /*IsMapTypeImplicit=*/true,
6246                 SourceLocation(), SourceLocation(), ImplicitMap,
6247                 OMPVarListLocTy())) {
6248           ClausesWithImplicit.emplace_back(Implicit);
6249           ErrorFound |= cast<OMPMapClause>(Implicit)->varlist_size() !=
6250                         ImplicitMap.size();
6251         } else {
6252           ErrorFound = true;
6253         }
6254       }
6255     }
6256     // Build expressions for implicit maps of data members with 'default'
6257     // mappers.
6258     if (LangOpts.OpenMP >= 50)
6259       processImplicitMapsWithDefaultMappers(*this, DSAStack,
6260                                             ClausesWithImplicit);
6261   }
6262 
6263   llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
6264   switch (Kind) {
6265   case OMPD_parallel:
6266     Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
6267                                        EndLoc);
6268     AllowedNameModifiers.push_back(OMPD_parallel);
6269     break;
6270   case OMPD_simd:
6271     Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
6272                                    VarsWithInheritedDSA);
6273     if (LangOpts.OpenMP >= 50)
6274       AllowedNameModifiers.push_back(OMPD_simd);
6275     break;
6276   case OMPD_tile:
6277     Res =
6278         ActOnOpenMPTileDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6279     break;
6280   case OMPD_unroll:
6281     Res = ActOnOpenMPUnrollDirective(ClausesWithImplicit, AStmt, StartLoc,
6282                                      EndLoc);
6283     break;
6284   case OMPD_for:
6285     Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
6286                                   VarsWithInheritedDSA);
6287     break;
6288   case OMPD_for_simd:
6289     Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6290                                       EndLoc, VarsWithInheritedDSA);
6291     if (LangOpts.OpenMP >= 50)
6292       AllowedNameModifiers.push_back(OMPD_simd);
6293     break;
6294   case OMPD_sections:
6295     Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
6296                                        EndLoc);
6297     break;
6298   case OMPD_section:
6299     assert(ClausesWithImplicit.empty() &&
6300            "No clauses are allowed for 'omp section' directive");
6301     Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
6302     break;
6303   case OMPD_single:
6304     Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
6305                                      EndLoc);
6306     break;
6307   case OMPD_master:
6308     assert(ClausesWithImplicit.empty() &&
6309            "No clauses are allowed for 'omp master' directive");
6310     Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
6311     break;
6312   case OMPD_masked:
6313     Res = ActOnOpenMPMaskedDirective(ClausesWithImplicit, AStmt, StartLoc,
6314                                      EndLoc);
6315     break;
6316   case OMPD_critical:
6317     Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
6318                                        StartLoc, EndLoc);
6319     break;
6320   case OMPD_parallel_for:
6321     Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
6322                                           EndLoc, VarsWithInheritedDSA);
6323     AllowedNameModifiers.push_back(OMPD_parallel);
6324     break;
6325   case OMPD_parallel_for_simd:
6326     Res = ActOnOpenMPParallelForSimdDirective(
6327         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6328     AllowedNameModifiers.push_back(OMPD_parallel);
6329     if (LangOpts.OpenMP >= 50)
6330       AllowedNameModifiers.push_back(OMPD_simd);
6331     break;
6332   case OMPD_parallel_master:
6333     Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
6334                                              StartLoc, EndLoc);
6335     AllowedNameModifiers.push_back(OMPD_parallel);
6336     break;
6337   case OMPD_parallel_masked:
6338     Res = ActOnOpenMPParallelMaskedDirective(ClausesWithImplicit, AStmt,
6339                                              StartLoc, EndLoc);
6340     AllowedNameModifiers.push_back(OMPD_parallel);
6341     break;
6342   case OMPD_parallel_sections:
6343     Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
6344                                                StartLoc, EndLoc);
6345     AllowedNameModifiers.push_back(OMPD_parallel);
6346     break;
6347   case OMPD_task:
6348     Res =
6349         ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6350     AllowedNameModifiers.push_back(OMPD_task);
6351     break;
6352   case OMPD_taskyield:
6353     assert(ClausesWithImplicit.empty() &&
6354            "No clauses are allowed for 'omp taskyield' directive");
6355     assert(AStmt == nullptr &&
6356            "No associated statement allowed for 'omp taskyield' directive");
6357     Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
6358     break;
6359   case OMPD_error:
6360     assert(AStmt == nullptr &&
6361            "No associated statement allowed for 'omp error' directive");
6362     Res = ActOnOpenMPErrorDirective(ClausesWithImplicit, StartLoc, EndLoc);
6363     break;
6364   case OMPD_barrier:
6365     assert(ClausesWithImplicit.empty() &&
6366            "No clauses are allowed for 'omp barrier' directive");
6367     assert(AStmt == nullptr &&
6368            "No associated statement allowed for 'omp barrier' directive");
6369     Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
6370     break;
6371   case OMPD_taskwait:
6372     assert(AStmt == nullptr &&
6373            "No associated statement allowed for 'omp taskwait' directive");
6374     Res = ActOnOpenMPTaskwaitDirective(ClausesWithImplicit, StartLoc, EndLoc);
6375     break;
6376   case OMPD_taskgroup:
6377     Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
6378                                         EndLoc);
6379     break;
6380   case OMPD_flush:
6381     assert(AStmt == nullptr &&
6382            "No associated statement allowed for 'omp flush' directive");
6383     Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
6384     break;
6385   case OMPD_depobj:
6386     assert(AStmt == nullptr &&
6387            "No associated statement allowed for 'omp depobj' directive");
6388     Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc);
6389     break;
6390   case OMPD_scan:
6391     assert(AStmt == nullptr &&
6392            "No associated statement allowed for 'omp scan' directive");
6393     Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc);
6394     break;
6395   case OMPD_ordered:
6396     Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
6397                                       EndLoc);
6398     break;
6399   case OMPD_atomic:
6400     Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
6401                                      EndLoc);
6402     break;
6403   case OMPD_teams:
6404     Res =
6405         ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6406     break;
6407   case OMPD_target:
6408     Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
6409                                      EndLoc);
6410     AllowedNameModifiers.push_back(OMPD_target);
6411     break;
6412   case OMPD_target_parallel:
6413     Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
6414                                              StartLoc, EndLoc);
6415     AllowedNameModifiers.push_back(OMPD_target);
6416     AllowedNameModifiers.push_back(OMPD_parallel);
6417     break;
6418   case OMPD_target_parallel_for:
6419     Res = ActOnOpenMPTargetParallelForDirective(
6420         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6421     AllowedNameModifiers.push_back(OMPD_target);
6422     AllowedNameModifiers.push_back(OMPD_parallel);
6423     break;
6424   case OMPD_cancellation_point:
6425     assert(ClausesWithImplicit.empty() &&
6426            "No clauses are allowed for 'omp cancellation point' directive");
6427     assert(AStmt == nullptr && "No associated statement allowed for 'omp "
6428                                "cancellation point' directive");
6429     Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
6430     break;
6431   case OMPD_cancel:
6432     assert(AStmt == nullptr &&
6433            "No associated statement allowed for 'omp cancel' directive");
6434     Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
6435                                      CancelRegion);
6436     AllowedNameModifiers.push_back(OMPD_cancel);
6437     break;
6438   case OMPD_target_data:
6439     Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
6440                                          EndLoc);
6441     AllowedNameModifiers.push_back(OMPD_target_data);
6442     break;
6443   case OMPD_target_enter_data:
6444     Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
6445                                               EndLoc, AStmt);
6446     AllowedNameModifiers.push_back(OMPD_target_enter_data);
6447     break;
6448   case OMPD_target_exit_data:
6449     Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
6450                                              EndLoc, AStmt);
6451     AllowedNameModifiers.push_back(OMPD_target_exit_data);
6452     break;
6453   case OMPD_taskloop:
6454     Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
6455                                        EndLoc, VarsWithInheritedDSA);
6456     AllowedNameModifiers.push_back(OMPD_taskloop);
6457     break;
6458   case OMPD_taskloop_simd:
6459     Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6460                                            EndLoc, VarsWithInheritedDSA);
6461     AllowedNameModifiers.push_back(OMPD_taskloop);
6462     if (LangOpts.OpenMP >= 50)
6463       AllowedNameModifiers.push_back(OMPD_simd);
6464     break;
6465   case OMPD_master_taskloop:
6466     Res = ActOnOpenMPMasterTaskLoopDirective(
6467         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6468     AllowedNameModifiers.push_back(OMPD_taskloop);
6469     break;
6470   case OMPD_masked_taskloop:
6471     Res = ActOnOpenMPMaskedTaskLoopDirective(
6472         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6473     AllowedNameModifiers.push_back(OMPD_taskloop);
6474     break;
6475   case OMPD_master_taskloop_simd:
6476     Res = ActOnOpenMPMasterTaskLoopSimdDirective(
6477         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6478     AllowedNameModifiers.push_back(OMPD_taskloop);
6479     if (LangOpts.OpenMP >= 50)
6480       AllowedNameModifiers.push_back(OMPD_simd);
6481     break;
6482   case OMPD_masked_taskloop_simd:
6483     Res = ActOnOpenMPMaskedTaskLoopSimdDirective(
6484         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6485     if (LangOpts.OpenMP >= 51) {
6486       AllowedNameModifiers.push_back(OMPD_taskloop);
6487       AllowedNameModifiers.push_back(OMPD_simd);
6488     }
6489     break;
6490   case OMPD_parallel_master_taskloop:
6491     Res = ActOnOpenMPParallelMasterTaskLoopDirective(
6492         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6493     AllowedNameModifiers.push_back(OMPD_taskloop);
6494     AllowedNameModifiers.push_back(OMPD_parallel);
6495     break;
6496   case OMPD_parallel_masked_taskloop:
6497     Res = ActOnOpenMPParallelMaskedTaskLoopDirective(
6498         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6499     if (LangOpts.OpenMP >= 51) {
6500       AllowedNameModifiers.push_back(OMPD_taskloop);
6501       AllowedNameModifiers.push_back(OMPD_parallel);
6502     }
6503     break;
6504   case OMPD_parallel_master_taskloop_simd:
6505     Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective(
6506         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6507     AllowedNameModifiers.push_back(OMPD_taskloop);
6508     AllowedNameModifiers.push_back(OMPD_parallel);
6509     if (LangOpts.OpenMP >= 50)
6510       AllowedNameModifiers.push_back(OMPD_simd);
6511     break;
6512   case OMPD_parallel_masked_taskloop_simd:
6513     Res = ActOnOpenMPParallelMaskedTaskLoopSimdDirective(
6514         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6515     if (LangOpts.OpenMP >= 51) {
6516       AllowedNameModifiers.push_back(OMPD_taskloop);
6517       AllowedNameModifiers.push_back(OMPD_parallel);
6518       AllowedNameModifiers.push_back(OMPD_simd);
6519     }
6520     break;
6521   case OMPD_distribute:
6522     Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
6523                                          EndLoc, VarsWithInheritedDSA);
6524     break;
6525   case OMPD_target_update:
6526     Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
6527                                            EndLoc, AStmt);
6528     AllowedNameModifiers.push_back(OMPD_target_update);
6529     break;
6530   case OMPD_distribute_parallel_for:
6531     Res = ActOnOpenMPDistributeParallelForDirective(
6532         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6533     AllowedNameModifiers.push_back(OMPD_parallel);
6534     break;
6535   case OMPD_distribute_parallel_for_simd:
6536     Res = ActOnOpenMPDistributeParallelForSimdDirective(
6537         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6538     AllowedNameModifiers.push_back(OMPD_parallel);
6539     if (LangOpts.OpenMP >= 50)
6540       AllowedNameModifiers.push_back(OMPD_simd);
6541     break;
6542   case OMPD_distribute_simd:
6543     Res = ActOnOpenMPDistributeSimdDirective(
6544         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6545     if (LangOpts.OpenMP >= 50)
6546       AllowedNameModifiers.push_back(OMPD_simd);
6547     break;
6548   case OMPD_target_parallel_for_simd:
6549     Res = ActOnOpenMPTargetParallelForSimdDirective(
6550         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6551     AllowedNameModifiers.push_back(OMPD_target);
6552     AllowedNameModifiers.push_back(OMPD_parallel);
6553     if (LangOpts.OpenMP >= 50)
6554       AllowedNameModifiers.push_back(OMPD_simd);
6555     break;
6556   case OMPD_target_simd:
6557     Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6558                                          EndLoc, VarsWithInheritedDSA);
6559     AllowedNameModifiers.push_back(OMPD_target);
6560     if (LangOpts.OpenMP >= 50)
6561       AllowedNameModifiers.push_back(OMPD_simd);
6562     break;
6563   case OMPD_teams_distribute:
6564     Res = ActOnOpenMPTeamsDistributeDirective(
6565         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6566     break;
6567   case OMPD_teams_distribute_simd:
6568     Res = ActOnOpenMPTeamsDistributeSimdDirective(
6569         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6570     if (LangOpts.OpenMP >= 50)
6571       AllowedNameModifiers.push_back(OMPD_simd);
6572     break;
6573   case OMPD_teams_distribute_parallel_for_simd:
6574     Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
6575         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6576     AllowedNameModifiers.push_back(OMPD_parallel);
6577     if (LangOpts.OpenMP >= 50)
6578       AllowedNameModifiers.push_back(OMPD_simd);
6579     break;
6580   case OMPD_teams_distribute_parallel_for:
6581     Res = ActOnOpenMPTeamsDistributeParallelForDirective(
6582         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6583     AllowedNameModifiers.push_back(OMPD_parallel);
6584     break;
6585   case OMPD_target_teams:
6586     Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
6587                                           EndLoc);
6588     AllowedNameModifiers.push_back(OMPD_target);
6589     break;
6590   case OMPD_target_teams_distribute:
6591     Res = ActOnOpenMPTargetTeamsDistributeDirective(
6592         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6593     AllowedNameModifiers.push_back(OMPD_target);
6594     break;
6595   case OMPD_target_teams_distribute_parallel_for:
6596     Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
6597         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6598     AllowedNameModifiers.push_back(OMPD_target);
6599     AllowedNameModifiers.push_back(OMPD_parallel);
6600     break;
6601   case OMPD_target_teams_distribute_parallel_for_simd:
6602     Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
6603         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6604     AllowedNameModifiers.push_back(OMPD_target);
6605     AllowedNameModifiers.push_back(OMPD_parallel);
6606     if (LangOpts.OpenMP >= 50)
6607       AllowedNameModifiers.push_back(OMPD_simd);
6608     break;
6609   case OMPD_target_teams_distribute_simd:
6610     Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
6611         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6612     AllowedNameModifiers.push_back(OMPD_target);
6613     if (LangOpts.OpenMP >= 50)
6614       AllowedNameModifiers.push_back(OMPD_simd);
6615     break;
6616   case OMPD_interop:
6617     assert(AStmt == nullptr &&
6618            "No associated statement allowed for 'omp interop' directive");
6619     Res = ActOnOpenMPInteropDirective(ClausesWithImplicit, StartLoc, EndLoc);
6620     break;
6621   case OMPD_dispatch:
6622     Res = ActOnOpenMPDispatchDirective(ClausesWithImplicit, AStmt, StartLoc,
6623                                        EndLoc);
6624     break;
6625   case OMPD_loop:
6626     Res = ActOnOpenMPGenericLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
6627                                           EndLoc, VarsWithInheritedDSA);
6628     break;
6629   case OMPD_teams_loop:
6630     Res = ActOnOpenMPTeamsGenericLoopDirective(
6631         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6632     break;
6633   case OMPD_target_teams_loop:
6634     Res = ActOnOpenMPTargetTeamsGenericLoopDirective(
6635         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6636     break;
6637   case OMPD_parallel_loop:
6638     Res = ActOnOpenMPParallelGenericLoopDirective(
6639         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6640     break;
6641   case OMPD_target_parallel_loop:
6642     Res = ActOnOpenMPTargetParallelGenericLoopDirective(
6643         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6644     break;
6645   case OMPD_declare_target:
6646   case OMPD_end_declare_target:
6647   case OMPD_threadprivate:
6648   case OMPD_allocate:
6649   case OMPD_declare_reduction:
6650   case OMPD_declare_mapper:
6651   case OMPD_declare_simd:
6652   case OMPD_requires:
6653   case OMPD_declare_variant:
6654   case OMPD_begin_declare_variant:
6655   case OMPD_end_declare_variant:
6656     llvm_unreachable("OpenMP Directive is not allowed");
6657   case OMPD_unknown:
6658   default:
6659     llvm_unreachable("Unknown OpenMP directive");
6660   }
6661 
6662   ErrorFound = Res.isInvalid() || ErrorFound;
6663 
6664   // Check variables in the clauses if default(none) or
6665   // default(firstprivate) was specified.
6666   if (DSAStack->getDefaultDSA() == DSA_none ||
6667       DSAStack->getDefaultDSA() == DSA_private ||
6668       DSAStack->getDefaultDSA() == DSA_firstprivate) {
6669     DSAAttrChecker DSAChecker(DSAStack, *this, nullptr);
6670     for (OMPClause *C : Clauses) {
6671       switch (C->getClauseKind()) {
6672       case OMPC_num_threads:
6673       case OMPC_dist_schedule:
6674         // Do not analyse if no parent teams directive.
6675         if (isOpenMPTeamsDirective(Kind))
6676           break;
6677         continue;
6678       case OMPC_if:
6679         if (isOpenMPTeamsDirective(Kind) &&
6680             cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
6681           break;
6682         if (isOpenMPParallelDirective(Kind) &&
6683             isOpenMPTaskLoopDirective(Kind) &&
6684             cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel)
6685           break;
6686         continue;
6687       case OMPC_schedule:
6688       case OMPC_detach:
6689         break;
6690       case OMPC_grainsize:
6691       case OMPC_num_tasks:
6692       case OMPC_final:
6693       case OMPC_priority:
6694       case OMPC_novariants:
6695       case OMPC_nocontext:
6696         // Do not analyze if no parent parallel directive.
6697         if (isOpenMPParallelDirective(Kind))
6698           break;
6699         continue;
6700       case OMPC_ordered:
6701       case OMPC_device:
6702       case OMPC_num_teams:
6703       case OMPC_thread_limit:
6704       case OMPC_hint:
6705       case OMPC_collapse:
6706       case OMPC_safelen:
6707       case OMPC_simdlen:
6708       case OMPC_sizes:
6709       case OMPC_default:
6710       case OMPC_proc_bind:
6711       case OMPC_private:
6712       case OMPC_firstprivate:
6713       case OMPC_lastprivate:
6714       case OMPC_shared:
6715       case OMPC_reduction:
6716       case OMPC_task_reduction:
6717       case OMPC_in_reduction:
6718       case OMPC_linear:
6719       case OMPC_aligned:
6720       case OMPC_copyin:
6721       case OMPC_copyprivate:
6722       case OMPC_nowait:
6723       case OMPC_untied:
6724       case OMPC_mergeable:
6725       case OMPC_allocate:
6726       case OMPC_read:
6727       case OMPC_write:
6728       case OMPC_update:
6729       case OMPC_capture:
6730       case OMPC_compare:
6731       case OMPC_seq_cst:
6732       case OMPC_acq_rel:
6733       case OMPC_acquire:
6734       case OMPC_release:
6735       case OMPC_relaxed:
6736       case OMPC_depend:
6737       case OMPC_threads:
6738       case OMPC_simd:
6739       case OMPC_map:
6740       case OMPC_nogroup:
6741       case OMPC_defaultmap:
6742       case OMPC_to:
6743       case OMPC_from:
6744       case OMPC_use_device_ptr:
6745       case OMPC_use_device_addr:
6746       case OMPC_is_device_ptr:
6747       case OMPC_has_device_addr:
6748       case OMPC_nontemporal:
6749       case OMPC_order:
6750       case OMPC_destroy:
6751       case OMPC_inclusive:
6752       case OMPC_exclusive:
6753       case OMPC_uses_allocators:
6754       case OMPC_affinity:
6755       case OMPC_bind:
6756       case OMPC_filter:
6757         continue;
6758       case OMPC_allocator:
6759       case OMPC_flush:
6760       case OMPC_depobj:
6761       case OMPC_threadprivate:
6762       case OMPC_uniform:
6763       case OMPC_unknown:
6764       case OMPC_unified_address:
6765       case OMPC_unified_shared_memory:
6766       case OMPC_reverse_offload:
6767       case OMPC_dynamic_allocators:
6768       case OMPC_atomic_default_mem_order:
6769       case OMPC_device_type:
6770       case OMPC_match:
6771       case OMPC_when:
6772       case OMPC_at:
6773       case OMPC_severity:
6774       case OMPC_message:
6775       default:
6776         llvm_unreachable("Unexpected clause");
6777       }
6778       for (Stmt *CC : C->children()) {
6779         if (CC)
6780           DSAChecker.Visit(CC);
6781       }
6782     }
6783     for (const auto &P : DSAChecker.getVarsWithInheritedDSA())
6784       VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
6785   }
6786   for (const auto &P : VarsWithInheritedDSA) {
6787     if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
6788       continue;
6789     ErrorFound = true;
6790     if (DSAStack->getDefaultDSA() == DSA_none ||
6791         DSAStack->getDefaultDSA() == DSA_private ||
6792         DSAStack->getDefaultDSA() == DSA_firstprivate) {
6793       Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
6794           << P.first << P.second->getSourceRange();
6795       Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
6796     } else if (getLangOpts().OpenMP >= 50) {
6797       Diag(P.second->getExprLoc(),
6798            diag::err_omp_defaultmap_no_attr_for_variable)
6799           << P.first << P.second->getSourceRange();
6800       Diag(DSAStack->getDefaultDSALocation(),
6801            diag::note_omp_defaultmap_attr_none);
6802     }
6803   }
6804 
6805   if (!AllowedNameModifiers.empty())
6806     ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
6807                  ErrorFound;
6808 
6809   if (ErrorFound)
6810     return StmtError();
6811 
6812   if (!CurContext->isDependentContext() &&
6813       isOpenMPTargetExecutionDirective(Kind) &&
6814       !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
6815         DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
6816         DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
6817         DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
6818     // Register target to DSA Stack.
6819     DSAStack->addTargetDirLocation(StartLoc);
6820   }
6821 
6822   return Res;
6823 }
6824 
6825 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
6826     DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
6827     ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
6828     ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
6829     ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
6830   assert(Aligneds.size() == Alignments.size());
6831   assert(Linears.size() == LinModifiers.size());
6832   assert(Linears.size() == Steps.size());
6833   if (!DG || DG.get().isNull())
6834     return DeclGroupPtrTy();
6835 
6836   const int SimdId = 0;
6837   if (!DG.get().isSingleDecl()) {
6838     Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
6839         << SimdId;
6840     return DG;
6841   }
6842   Decl *ADecl = DG.get().getSingleDecl();
6843   if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
6844     ADecl = FTD->getTemplatedDecl();
6845 
6846   auto *FD = dyn_cast<FunctionDecl>(ADecl);
6847   if (!FD) {
6848     Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId;
6849     return DeclGroupPtrTy();
6850   }
6851 
6852   // OpenMP [2.8.2, declare simd construct, Description]
6853   // The parameter of the simdlen clause must be a constant positive integer
6854   // expression.
6855   ExprResult SL;
6856   if (Simdlen)
6857     SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
6858   // OpenMP [2.8.2, declare simd construct, Description]
6859   // The special this pointer can be used as if was one of the arguments to the
6860   // function in any of the linear, aligned, or uniform clauses.
6861   // The uniform clause declares one or more arguments to have an invariant
6862   // value for all concurrent invocations of the function in the execution of a
6863   // single SIMD loop.
6864   llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
6865   const Expr *UniformedLinearThis = nullptr;
6866   for (const Expr *E : Uniforms) {
6867     E = E->IgnoreParenImpCasts();
6868     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6869       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
6870         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6871             FD->getParamDecl(PVD->getFunctionScopeIndex())
6872                     ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
6873           UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
6874           continue;
6875         }
6876     if (isa<CXXThisExpr>(E)) {
6877       UniformedLinearThis = E;
6878       continue;
6879     }
6880     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6881         << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6882   }
6883   // OpenMP [2.8.2, declare simd construct, Description]
6884   // The aligned clause declares that the object to which each list item points
6885   // is aligned to the number of bytes expressed in the optional parameter of
6886   // the aligned clause.
6887   // The special this pointer can be used as if was one of the arguments to the
6888   // function in any of the linear, aligned, or uniform clauses.
6889   // The type of list items appearing in the aligned clause must be array,
6890   // pointer, reference to array, or reference to pointer.
6891   llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
6892   const Expr *AlignedThis = nullptr;
6893   for (const Expr *E : Aligneds) {
6894     E = E->IgnoreParenImpCasts();
6895     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6896       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6897         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6898         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6899             FD->getParamDecl(PVD->getFunctionScopeIndex())
6900                     ->getCanonicalDecl() == CanonPVD) {
6901           // OpenMP  [2.8.1, simd construct, Restrictions]
6902           // A list-item cannot appear in more than one aligned clause.
6903           if (AlignedArgs.count(CanonPVD) > 0) {
6904             Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
6905                 << 1 << getOpenMPClauseName(OMPC_aligned)
6906                 << E->getSourceRange();
6907             Diag(AlignedArgs[CanonPVD]->getExprLoc(),
6908                  diag::note_omp_explicit_dsa)
6909                 << getOpenMPClauseName(OMPC_aligned);
6910             continue;
6911           }
6912           AlignedArgs[CanonPVD] = E;
6913           QualType QTy = PVD->getType()
6914                              .getNonReferenceType()
6915                              .getUnqualifiedType()
6916                              .getCanonicalType();
6917           const Type *Ty = QTy.getTypePtrOrNull();
6918           if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
6919             Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
6920                 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
6921             Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
6922           }
6923           continue;
6924         }
6925       }
6926     if (isa<CXXThisExpr>(E)) {
6927       if (AlignedThis) {
6928         Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
6929             << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange();
6930         Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
6931             << getOpenMPClauseName(OMPC_aligned);
6932       }
6933       AlignedThis = E;
6934       continue;
6935     }
6936     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6937         << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6938   }
6939   // The optional parameter of the aligned clause, alignment, must be a constant
6940   // positive integer expression. If no optional parameter is specified,
6941   // implementation-defined default alignments for SIMD instructions on the
6942   // target platforms are assumed.
6943   SmallVector<const Expr *, 4> NewAligns;
6944   for (Expr *E : Alignments) {
6945     ExprResult Align;
6946     if (E)
6947       Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
6948     NewAligns.push_back(Align.get());
6949   }
6950   // OpenMP [2.8.2, declare simd construct, Description]
6951   // The linear clause declares one or more list items to be private to a SIMD
6952   // lane and to have a linear relationship with respect to the iteration space
6953   // of a loop.
6954   // The special this pointer can be used as if was one of the arguments to the
6955   // function in any of the linear, aligned, or uniform clauses.
6956   // When a linear-step expression is specified in a linear clause it must be
6957   // either a constant integer expression or an integer-typed parameter that is
6958   // specified in a uniform clause on the directive.
6959   llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
6960   const bool IsUniformedThis = UniformedLinearThis != nullptr;
6961   auto MI = LinModifiers.begin();
6962   for (const Expr *E : Linears) {
6963     auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
6964     ++MI;
6965     E = E->IgnoreParenImpCasts();
6966     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6967       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6968         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6969         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6970             FD->getParamDecl(PVD->getFunctionScopeIndex())
6971                     ->getCanonicalDecl() == CanonPVD) {
6972           // OpenMP  [2.15.3.7, linear Clause, Restrictions]
6973           // A list-item cannot appear in more than one linear clause.
6974           if (LinearArgs.count(CanonPVD) > 0) {
6975             Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6976                 << getOpenMPClauseName(OMPC_linear)
6977                 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
6978             Diag(LinearArgs[CanonPVD]->getExprLoc(),
6979                  diag::note_omp_explicit_dsa)
6980                 << getOpenMPClauseName(OMPC_linear);
6981             continue;
6982           }
6983           // Each argument can appear in at most one uniform or linear clause.
6984           if (UniformedArgs.count(CanonPVD) > 0) {
6985             Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6986                 << getOpenMPClauseName(OMPC_linear)
6987                 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
6988             Diag(UniformedArgs[CanonPVD]->getExprLoc(),
6989                  diag::note_omp_explicit_dsa)
6990                 << getOpenMPClauseName(OMPC_uniform);
6991             continue;
6992           }
6993           LinearArgs[CanonPVD] = E;
6994           if (E->isValueDependent() || E->isTypeDependent() ||
6995               E->isInstantiationDependent() ||
6996               E->containsUnexpandedParameterPack())
6997             continue;
6998           (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
6999                                       PVD->getOriginalType(),
7000                                       /*IsDeclareSimd=*/true);
7001           continue;
7002         }
7003       }
7004     if (isa<CXXThisExpr>(E)) {
7005       if (UniformedLinearThis) {
7006         Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
7007             << getOpenMPClauseName(OMPC_linear)
7008             << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
7009             << E->getSourceRange();
7010         Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
7011             << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
7012                                                    : OMPC_linear);
7013         continue;
7014       }
7015       UniformedLinearThis = E;
7016       if (E->isValueDependent() || E->isTypeDependent() ||
7017           E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
7018         continue;
7019       (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
7020                                   E->getType(), /*IsDeclareSimd=*/true);
7021       continue;
7022     }
7023     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
7024         << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
7025   }
7026   Expr *Step = nullptr;
7027   Expr *NewStep = nullptr;
7028   SmallVector<Expr *, 4> NewSteps;
7029   for (Expr *E : Steps) {
7030     // Skip the same step expression, it was checked already.
7031     if (Step == E || !E) {
7032       NewSteps.push_back(E ? NewStep : nullptr);
7033       continue;
7034     }
7035     Step = E;
7036     if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
7037       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7038         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
7039         if (UniformedArgs.count(CanonPVD) == 0) {
7040           Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
7041               << Step->getSourceRange();
7042         } else if (E->isValueDependent() || E->isTypeDependent() ||
7043                    E->isInstantiationDependent() ||
7044                    E->containsUnexpandedParameterPack() ||
7045                    CanonPVD->getType()->hasIntegerRepresentation()) {
7046           NewSteps.push_back(Step);
7047         } else {
7048           Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
7049               << Step->getSourceRange();
7050         }
7051         continue;
7052       }
7053     NewStep = Step;
7054     if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
7055         !Step->isInstantiationDependent() &&
7056         !Step->containsUnexpandedParameterPack()) {
7057       NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
7058                     .get();
7059       if (NewStep)
7060         NewStep =
7061             VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get();
7062     }
7063     NewSteps.push_back(NewStep);
7064   }
7065   auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
7066       Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
7067       Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
7068       const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
7069       const_cast<Expr **>(Linears.data()), Linears.size(),
7070       const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
7071       NewSteps.data(), NewSteps.size(), SR);
7072   ADecl->addAttr(NewAttr);
7073   return DG;
7074 }
7075 
7076 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
7077                          QualType NewType) {
7078   assert(NewType->isFunctionProtoType() &&
7079          "Expected function type with prototype.");
7080   assert(FD->getType()->isFunctionNoProtoType() &&
7081          "Expected function with type with no prototype.");
7082   assert(FDWithProto->getType()->isFunctionProtoType() &&
7083          "Expected function with prototype.");
7084   // Synthesize parameters with the same types.
7085   FD->setType(NewType);
7086   SmallVector<ParmVarDecl *, 16> Params;
7087   for (const ParmVarDecl *P : FDWithProto->parameters()) {
7088     auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(),
7089                                       SourceLocation(), nullptr, P->getType(),
7090                                       /*TInfo=*/nullptr, SC_None, nullptr);
7091     Param->setScopeInfo(0, Params.size());
7092     Param->setImplicit();
7093     Params.push_back(Param);
7094   }
7095 
7096   FD->setParams(Params);
7097 }
7098 
7099 void Sema::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D) {
7100   if (D->isInvalidDecl())
7101     return;
7102   FunctionDecl *FD = nullptr;
7103   if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
7104     FD = UTemplDecl->getTemplatedDecl();
7105   else
7106     FD = cast<FunctionDecl>(D);
7107   assert(FD && "Expected a function declaration!");
7108 
7109   // If we are instantiating templates we do *not* apply scoped assumptions but
7110   // only global ones. We apply scoped assumption to the template definition
7111   // though.
7112   if (!inTemplateInstantiation()) {
7113     for (AssumptionAttr *AA : OMPAssumeScoped)
7114       FD->addAttr(AA);
7115   }
7116   for (AssumptionAttr *AA : OMPAssumeGlobal)
7117     FD->addAttr(AA);
7118 }
7119 
7120 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI)
7121     : TI(&TI), NameSuffix(TI.getMangledName()) {}
7122 
7123 void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(
7124     Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists,
7125     SmallVectorImpl<FunctionDecl *> &Bases) {
7126   if (!D.getIdentifier())
7127     return;
7128 
7129   OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
7130 
7131   // Template specialization is an extension, check if we do it.
7132   bool IsTemplated = !TemplateParamLists.empty();
7133   if (IsTemplated &
7134       !DVScope.TI->isExtensionActive(
7135           llvm::omp::TraitProperty::implementation_extension_allow_templates))
7136     return;
7137 
7138   IdentifierInfo *BaseII = D.getIdentifier();
7139   LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(),
7140                       LookupOrdinaryName);
7141   LookupParsedName(Lookup, S, &D.getCXXScopeSpec());
7142 
7143   TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
7144   QualType FType = TInfo->getType();
7145 
7146   bool IsConstexpr =
7147       D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr;
7148   bool IsConsteval =
7149       D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Consteval;
7150 
7151   for (auto *Candidate : Lookup) {
7152     auto *CandidateDecl = Candidate->getUnderlyingDecl();
7153     FunctionDecl *UDecl = nullptr;
7154     if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl)) {
7155       auto *FTD = cast<FunctionTemplateDecl>(CandidateDecl);
7156       if (FTD->getTemplateParameters()->size() == TemplateParamLists.size())
7157         UDecl = FTD->getTemplatedDecl();
7158     } else if (!IsTemplated)
7159       UDecl = dyn_cast<FunctionDecl>(CandidateDecl);
7160     if (!UDecl)
7161       continue;
7162 
7163     // Don't specialize constexpr/consteval functions with
7164     // non-constexpr/consteval functions.
7165     if (UDecl->isConstexpr() && !IsConstexpr)
7166       continue;
7167     if (UDecl->isConsteval() && !IsConsteval)
7168       continue;
7169 
7170     QualType UDeclTy = UDecl->getType();
7171     if (!UDeclTy->isDependentType()) {
7172       QualType NewType = Context.mergeFunctionTypes(
7173           FType, UDeclTy, /* OfBlockPointer */ false,
7174           /* Unqualified */ false, /* AllowCXX */ true);
7175       if (NewType.isNull())
7176         continue;
7177     }
7178 
7179     // Found a base!
7180     Bases.push_back(UDecl);
7181   }
7182 
7183   bool UseImplicitBase = !DVScope.TI->isExtensionActive(
7184       llvm::omp::TraitProperty::implementation_extension_disable_implicit_base);
7185   // If no base was found we create a declaration that we use as base.
7186   if (Bases.empty() && UseImplicitBase) {
7187     D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration);
7188     Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists);
7189     BaseD->setImplicit(true);
7190     if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD))
7191       Bases.push_back(BaseTemplD->getTemplatedDecl());
7192     else
7193       Bases.push_back(cast<FunctionDecl>(BaseD));
7194   }
7195 
7196   std::string MangledName;
7197   MangledName += D.getIdentifier()->getName();
7198   MangledName += getOpenMPVariantManglingSeparatorStr();
7199   MangledName += DVScope.NameSuffix;
7200   IdentifierInfo &VariantII = Context.Idents.get(MangledName);
7201 
7202   VariantII.setMangledOpenMPVariantName(true);
7203   D.SetIdentifier(&VariantII, D.getBeginLoc());
7204 }
7205 
7206 void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(
7207     Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) {
7208   // Do not mark function as is used to prevent its emission if this is the
7209   // only place where it is used.
7210   EnterExpressionEvaluationContext Unevaluated(
7211       *this, Sema::ExpressionEvaluationContext::Unevaluated);
7212 
7213   FunctionDecl *FD = nullptr;
7214   if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
7215     FD = UTemplDecl->getTemplatedDecl();
7216   else
7217     FD = cast<FunctionDecl>(D);
7218   auto *VariantFuncRef = DeclRefExpr::Create(
7219       Context, NestedNameSpecifierLoc(), SourceLocation(), FD,
7220       /* RefersToEnclosingVariableOrCapture */ false,
7221       /* NameLoc */ FD->getLocation(), FD->getType(),
7222       ExprValueKind::VK_PRValue);
7223 
7224   OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
7225   auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit(
7226       Context, VariantFuncRef, DVScope.TI,
7227       /*NothingArgs=*/nullptr, /*NothingArgsSize=*/0,
7228       /*NeedDevicePtrArgs=*/nullptr, /*NeedDevicePtrArgsSize=*/0,
7229       /*AppendArgs=*/nullptr, /*AppendArgsSize=*/0);
7230   for (FunctionDecl *BaseFD : Bases)
7231     BaseFD->addAttr(OMPDeclareVariantA);
7232 }
7233 
7234 ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
7235                                  SourceLocation LParenLoc,
7236                                  MultiExprArg ArgExprs,
7237                                  SourceLocation RParenLoc, Expr *ExecConfig) {
7238   // The common case is a regular call we do not want to specialize at all. Try
7239   // to make that case fast by bailing early.
7240   CallExpr *CE = dyn_cast<CallExpr>(Call.get());
7241   if (!CE)
7242     return Call;
7243 
7244   FunctionDecl *CalleeFnDecl = CE->getDirectCallee();
7245   if (!CalleeFnDecl)
7246     return Call;
7247 
7248   if (LangOpts.OpenMP >= 51 && CalleeFnDecl->getIdentifier() &&
7249       CalleeFnDecl->getName().starts_with_insensitive("omp_")) {
7250     // checking for any calls inside an Order region
7251     if (Scope && Scope->isOpenMPOrderClauseScope())
7252       Diag(LParenLoc, diag::err_omp_unexpected_call_to_omp_runtime_api);
7253   }
7254 
7255   if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>())
7256     return Call;
7257 
7258   ASTContext &Context = getASTContext();
7259   std::function<void(StringRef)> DiagUnknownTrait = [this,
7260                                                      CE](StringRef ISATrait) {
7261     // TODO Track the selector locations in a way that is accessible here to
7262     // improve the diagnostic location.
7263     Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait)
7264         << ISATrait;
7265   };
7266   TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait),
7267                           getCurFunctionDecl(), DSAStack->getConstructTraits());
7268 
7269   QualType CalleeFnType = CalleeFnDecl->getType();
7270 
7271   SmallVector<Expr *, 4> Exprs;
7272   SmallVector<VariantMatchInfo, 4> VMIs;
7273   while (CalleeFnDecl) {
7274     for (OMPDeclareVariantAttr *A :
7275          CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) {
7276       Expr *VariantRef = A->getVariantFuncRef();
7277 
7278       VariantMatchInfo VMI;
7279       OMPTraitInfo &TI = A->getTraitInfo();
7280       TI.getAsVariantMatchInfo(Context, VMI);
7281       if (!isVariantApplicableInContext(VMI, OMPCtx,
7282                                         /* DeviceSetOnly */ false))
7283         continue;
7284 
7285       VMIs.push_back(VMI);
7286       Exprs.push_back(VariantRef);
7287     }
7288 
7289     CalleeFnDecl = CalleeFnDecl->getPreviousDecl();
7290   }
7291 
7292   ExprResult NewCall;
7293   do {
7294     int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
7295     if (BestIdx < 0)
7296       return Call;
7297     Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]);
7298     Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl();
7299 
7300     {
7301       // Try to build a (member) call expression for the current best applicable
7302       // variant expression. We allow this to fail in which case we continue
7303       // with the next best variant expression. The fail case is part of the
7304       // implementation defined behavior in the OpenMP standard when it talks
7305       // about what differences in the function prototypes: "Any differences
7306       // that the specific OpenMP context requires in the prototype of the
7307       // variant from the base function prototype are implementation defined."
7308       // This wording is there to allow the specialized variant to have a
7309       // different type than the base function. This is intended and OK but if
7310       // we cannot create a call the difference is not in the "implementation
7311       // defined range" we allow.
7312       Sema::TentativeAnalysisScope Trap(*this);
7313 
7314       if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) {
7315         auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE);
7316         BestExpr = MemberExpr::CreateImplicit(
7317             Context, MemberCall->getImplicitObjectArgument(),
7318             /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy,
7319             MemberCall->getValueKind(), MemberCall->getObjectKind());
7320       }
7321       NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc,
7322                               ExecConfig);
7323       if (NewCall.isUsable()) {
7324         if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) {
7325           FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee();
7326           QualType NewType = Context.mergeFunctionTypes(
7327               CalleeFnType, NewCalleeFnDecl->getType(),
7328               /* OfBlockPointer */ false,
7329               /* Unqualified */ false, /* AllowCXX */ true);
7330           if (!NewType.isNull())
7331             break;
7332           // Don't use the call if the function type was not compatible.
7333           NewCall = nullptr;
7334         }
7335       }
7336     }
7337 
7338     VMIs.erase(VMIs.begin() + BestIdx);
7339     Exprs.erase(Exprs.begin() + BestIdx);
7340   } while (!VMIs.empty());
7341 
7342   if (!NewCall.isUsable())
7343     return Call;
7344   return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0);
7345 }
7346 
7347 std::optional<std::pair<FunctionDecl *, Expr *>>
7348 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
7349                                         Expr *VariantRef, OMPTraitInfo &TI,
7350                                         unsigned NumAppendArgs,
7351                                         SourceRange SR) {
7352   if (!DG || DG.get().isNull())
7353     return std::nullopt;
7354 
7355   const int VariantId = 1;
7356   // Must be applied only to single decl.
7357   if (!DG.get().isSingleDecl()) {
7358     Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
7359         << VariantId << SR;
7360     return std::nullopt;
7361   }
7362   Decl *ADecl = DG.get().getSingleDecl();
7363   if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
7364     ADecl = FTD->getTemplatedDecl();
7365 
7366   // Decl must be a function.
7367   auto *FD = dyn_cast<FunctionDecl>(ADecl);
7368   if (!FD) {
7369     Diag(ADecl->getLocation(), diag::err_omp_function_expected)
7370         << VariantId << SR;
7371     return std::nullopt;
7372   }
7373 
7374   auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
7375     // The 'target' attribute needs to be separately checked because it does
7376     // not always signify a multiversion function declaration.
7377     return FD->isMultiVersion() || FD->hasAttr<TargetAttr>();
7378   };
7379   // OpenMP is not compatible with multiversion function attributes.
7380   if (HasMultiVersionAttributes(FD)) {
7381     Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
7382         << SR;
7383     return std::nullopt;
7384   }
7385 
7386   // Allow #pragma omp declare variant only if the function is not used.
7387   if (FD->isUsed(false))
7388     Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
7389         << FD->getLocation();
7390 
7391   // Check if the function was emitted already.
7392   const FunctionDecl *Definition;
7393   if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) &&
7394       (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition)))
7395     Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
7396         << FD->getLocation();
7397 
7398   // The VariantRef must point to function.
7399   if (!VariantRef) {
7400     Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
7401     return std::nullopt;
7402   }
7403 
7404   auto ShouldDelayChecks = [](Expr *&E, bool) {
7405     return E && (E->isTypeDependent() || E->isValueDependent() ||
7406                  E->containsUnexpandedParameterPack() ||
7407                  E->isInstantiationDependent());
7408   };
7409   // Do not check templates, wait until instantiation.
7410   if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) ||
7411       TI.anyScoreOrCondition(ShouldDelayChecks))
7412     return std::make_pair(FD, VariantRef);
7413 
7414   // Deal with non-constant score and user condition expressions.
7415   auto HandleNonConstantScoresAndConditions = [this](Expr *&E,
7416                                                      bool IsScore) -> bool {
7417     if (!E || E->isIntegerConstantExpr(Context))
7418       return false;
7419 
7420     if (IsScore) {
7421       // We warn on non-constant scores and pretend they were not present.
7422       Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant)
7423           << E;
7424       E = nullptr;
7425     } else {
7426       // We could replace a non-constant user condition with "false" but we
7427       // will soon need to handle these anyway for the dynamic version of
7428       // OpenMP context selectors.
7429       Diag(E->getExprLoc(),
7430            diag::err_omp_declare_variant_user_condition_not_constant)
7431           << E;
7432     }
7433     return true;
7434   };
7435   if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions))
7436     return std::nullopt;
7437 
7438   QualType AdjustedFnType = FD->getType();
7439   if (NumAppendArgs) {
7440     const auto *PTy = AdjustedFnType->getAsAdjusted<FunctionProtoType>();
7441     if (!PTy) {
7442       Diag(FD->getLocation(), diag::err_omp_declare_variant_prototype_required)
7443           << SR;
7444       return std::nullopt;
7445     }
7446     // Adjust the function type to account for an extra omp_interop_t for each
7447     // specified in the append_args clause.
7448     const TypeDecl *TD = nullptr;
7449     LookupResult Result(*this, &Context.Idents.get("omp_interop_t"),
7450                         SR.getBegin(), Sema::LookupOrdinaryName);
7451     if (LookupName(Result, getCurScope())) {
7452       NamedDecl *ND = Result.getFoundDecl();
7453       TD = dyn_cast_or_null<TypeDecl>(ND);
7454     }
7455     if (!TD) {
7456       Diag(SR.getBegin(), diag::err_omp_interop_type_not_found) << SR;
7457       return std::nullopt;
7458     }
7459     QualType InteropType = Context.getTypeDeclType(TD);
7460     if (PTy->isVariadic()) {
7461       Diag(FD->getLocation(), diag::err_omp_append_args_with_varargs) << SR;
7462       return std::nullopt;
7463     }
7464     llvm::SmallVector<QualType, 8> Params;
7465     Params.append(PTy->param_type_begin(), PTy->param_type_end());
7466     Params.insert(Params.end(), NumAppendArgs, InteropType);
7467     AdjustedFnType = Context.getFunctionType(PTy->getReturnType(), Params,
7468                                              PTy->getExtProtoInfo());
7469   }
7470 
7471   // Convert VariantRef expression to the type of the original function to
7472   // resolve possible conflicts.
7473   ExprResult VariantRefCast = VariantRef;
7474   if (LangOpts.CPlusPlus) {
7475     QualType FnPtrType;
7476     auto *Method = dyn_cast<CXXMethodDecl>(FD);
7477     if (Method && !Method->isStatic()) {
7478       const Type *ClassType =
7479           Context.getTypeDeclType(Method->getParent()).getTypePtr();
7480       FnPtrType = Context.getMemberPointerType(AdjustedFnType, ClassType);
7481       ExprResult ER;
7482       {
7483         // Build adrr_of unary op to correctly handle type checks for member
7484         // functions.
7485         Sema::TentativeAnalysisScope Trap(*this);
7486         ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf,
7487                                   VariantRef);
7488       }
7489       if (!ER.isUsable()) {
7490         Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7491             << VariantId << VariantRef->getSourceRange();
7492         return std::nullopt;
7493       }
7494       VariantRef = ER.get();
7495     } else {
7496       FnPtrType = Context.getPointerType(AdjustedFnType);
7497     }
7498     QualType VarianPtrType = Context.getPointerType(VariantRef->getType());
7499     if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) {
7500       ImplicitConversionSequence ICS = TryImplicitConversion(
7501           VariantRef, FnPtrType.getUnqualifiedType(),
7502           /*SuppressUserConversions=*/false, AllowedExplicit::None,
7503           /*InOverloadResolution=*/false,
7504           /*CStyle=*/false,
7505           /*AllowObjCWritebackConversion=*/false);
7506       if (ICS.isFailure()) {
7507         Diag(VariantRef->getExprLoc(),
7508              diag::err_omp_declare_variant_incompat_types)
7509             << VariantRef->getType()
7510             << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
7511             << (NumAppendArgs ? 1 : 0) << VariantRef->getSourceRange();
7512         return std::nullopt;
7513       }
7514       VariantRefCast = PerformImplicitConversion(
7515           VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
7516       if (!VariantRefCast.isUsable())
7517         return std::nullopt;
7518     }
7519     // Drop previously built artificial addr_of unary op for member functions.
7520     if (Method && !Method->isStatic()) {
7521       Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
7522       if (auto *UO = dyn_cast<UnaryOperator>(
7523               PossibleAddrOfVariantRef->IgnoreImplicit()))
7524         VariantRefCast = UO->getSubExpr();
7525     }
7526   }
7527 
7528   ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get());
7529   if (!ER.isUsable() ||
7530       !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
7531     Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7532         << VariantId << VariantRef->getSourceRange();
7533     return std::nullopt;
7534   }
7535 
7536   // The VariantRef must point to function.
7537   auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts());
7538   if (!DRE) {
7539     Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7540         << VariantId << VariantRef->getSourceRange();
7541     return std::nullopt;
7542   }
7543   auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
7544   if (!NewFD) {
7545     Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7546         << VariantId << VariantRef->getSourceRange();
7547     return std::nullopt;
7548   }
7549 
7550   if (FD->getCanonicalDecl() == NewFD->getCanonicalDecl()) {
7551     Diag(VariantRef->getExprLoc(),
7552          diag::err_omp_declare_variant_same_base_function)
7553         << VariantRef->getSourceRange();
7554     return std::nullopt;
7555   }
7556 
7557   // Check if function types are compatible in C.
7558   if (!LangOpts.CPlusPlus) {
7559     QualType NewType =
7560         Context.mergeFunctionTypes(AdjustedFnType, NewFD->getType());
7561     if (NewType.isNull()) {
7562       Diag(VariantRef->getExprLoc(),
7563            diag::err_omp_declare_variant_incompat_types)
7564           << NewFD->getType() << FD->getType() << (NumAppendArgs ? 1 : 0)
7565           << VariantRef->getSourceRange();
7566       return std::nullopt;
7567     }
7568     if (NewType->isFunctionProtoType()) {
7569       if (FD->getType()->isFunctionNoProtoType())
7570         setPrototype(*this, FD, NewFD, NewType);
7571       else if (NewFD->getType()->isFunctionNoProtoType())
7572         setPrototype(*this, NewFD, FD, NewType);
7573     }
7574   }
7575 
7576   // Check if variant function is not marked with declare variant directive.
7577   if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
7578     Diag(VariantRef->getExprLoc(),
7579          diag::warn_omp_declare_variant_marked_as_declare_variant)
7580         << VariantRef->getSourceRange();
7581     SourceRange SR =
7582         NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
7583     Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
7584     return std::nullopt;
7585   }
7586 
7587   enum DoesntSupport {
7588     VirtFuncs = 1,
7589     Constructors = 3,
7590     Destructors = 4,
7591     DeletedFuncs = 5,
7592     DefaultedFuncs = 6,
7593     ConstexprFuncs = 7,
7594     ConstevalFuncs = 8,
7595   };
7596   if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
7597     if (CXXFD->isVirtual()) {
7598       Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7599           << VirtFuncs;
7600       return std::nullopt;
7601     }
7602 
7603     if (isa<CXXConstructorDecl>(FD)) {
7604       Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7605           << Constructors;
7606       return std::nullopt;
7607     }
7608 
7609     if (isa<CXXDestructorDecl>(FD)) {
7610       Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7611           << Destructors;
7612       return std::nullopt;
7613     }
7614   }
7615 
7616   if (FD->isDeleted()) {
7617     Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7618         << DeletedFuncs;
7619     return std::nullopt;
7620   }
7621 
7622   if (FD->isDefaulted()) {
7623     Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7624         << DefaultedFuncs;
7625     return std::nullopt;
7626   }
7627 
7628   if (FD->isConstexpr()) {
7629     Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7630         << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
7631     return std::nullopt;
7632   }
7633 
7634   // Check general compatibility.
7635   if (areMultiversionVariantFunctionsCompatible(
7636           FD, NewFD, PartialDiagnostic::NullDiagnostic(),
7637           PartialDiagnosticAt(SourceLocation(),
7638                               PartialDiagnostic::NullDiagnostic()),
7639           PartialDiagnosticAt(
7640               VariantRef->getExprLoc(),
7641               PDiag(diag::err_omp_declare_variant_doesnt_support)),
7642           PartialDiagnosticAt(VariantRef->getExprLoc(),
7643                               PDiag(diag::err_omp_declare_variant_diff)
7644                                   << FD->getLocation()),
7645           /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
7646           /*CLinkageMayDiffer=*/true))
7647     return std::nullopt;
7648   return std::make_pair(FD, cast<Expr>(DRE));
7649 }
7650 
7651 void Sema::ActOnOpenMPDeclareVariantDirective(
7652     FunctionDecl *FD, Expr *VariantRef, OMPTraitInfo &TI,
7653     ArrayRef<Expr *> AdjustArgsNothing,
7654     ArrayRef<Expr *> AdjustArgsNeedDevicePtr,
7655     ArrayRef<OMPInteropInfo> AppendArgs, SourceLocation AdjustArgsLoc,
7656     SourceLocation AppendArgsLoc, SourceRange SR) {
7657 
7658   // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions]
7659   // An adjust_args clause or append_args clause can only be specified if the
7660   // dispatch selector of the construct selector set appears in the match
7661   // clause.
7662 
7663   SmallVector<Expr *, 8> AllAdjustArgs;
7664   llvm::append_range(AllAdjustArgs, AdjustArgsNothing);
7665   llvm::append_range(AllAdjustArgs, AdjustArgsNeedDevicePtr);
7666 
7667   if (!AllAdjustArgs.empty() || !AppendArgs.empty()) {
7668     VariantMatchInfo VMI;
7669     TI.getAsVariantMatchInfo(Context, VMI);
7670     if (!llvm::is_contained(
7671             VMI.ConstructTraits,
7672             llvm::omp::TraitProperty::construct_dispatch_dispatch)) {
7673       if (!AllAdjustArgs.empty())
7674         Diag(AdjustArgsLoc, diag::err_omp_clause_requires_dispatch_construct)
7675             << getOpenMPClauseName(OMPC_adjust_args);
7676       if (!AppendArgs.empty())
7677         Diag(AppendArgsLoc, diag::err_omp_clause_requires_dispatch_construct)
7678             << getOpenMPClauseName(OMPC_append_args);
7679       return;
7680     }
7681   }
7682 
7683   // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions]
7684   // Each argument can only appear in a single adjust_args clause for each
7685   // declare variant directive.
7686   llvm::SmallPtrSet<const VarDecl *, 4> AdjustVars;
7687 
7688   for (Expr *E : AllAdjustArgs) {
7689     E = E->IgnoreParenImpCasts();
7690     if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
7691       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7692         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
7693         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
7694             FD->getParamDecl(PVD->getFunctionScopeIndex())
7695                     ->getCanonicalDecl() == CanonPVD) {
7696           // It's a parameter of the function, check duplicates.
7697           if (!AdjustVars.insert(CanonPVD).second) {
7698             Diag(DRE->getLocation(), diag::err_omp_adjust_arg_multiple_clauses)
7699                 << PVD;
7700             return;
7701           }
7702           continue;
7703         }
7704       }
7705     }
7706     // Anything that is not a function parameter is an error.
7707     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) << FD << 0;
7708     return;
7709   }
7710 
7711   auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit(
7712       Context, VariantRef, &TI, const_cast<Expr **>(AdjustArgsNothing.data()),
7713       AdjustArgsNothing.size(),
7714       const_cast<Expr **>(AdjustArgsNeedDevicePtr.data()),
7715       AdjustArgsNeedDevicePtr.size(),
7716       const_cast<OMPInteropInfo *>(AppendArgs.data()), AppendArgs.size(), SR);
7717   FD->addAttr(NewAttr);
7718 }
7719 
7720 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
7721                                               Stmt *AStmt,
7722                                               SourceLocation StartLoc,
7723                                               SourceLocation EndLoc) {
7724   if (!AStmt)
7725     return StmtError();
7726 
7727   auto *CS = cast<CapturedStmt>(AStmt);
7728   // 1.2.2 OpenMP Language Terminology
7729   // Structured block - An executable statement with a single entry at the
7730   // top and a single exit at the bottom.
7731   // The point of exit cannot be a branch out of the structured block.
7732   // longjmp() and throw() must not violate the entry/exit criteria.
7733   CS->getCapturedDecl()->setNothrow();
7734 
7735   setFunctionHasBranchProtectedScope();
7736 
7737   return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
7738                                       DSAStack->getTaskgroupReductionRef(),
7739                                       DSAStack->isCancelRegion());
7740 }
7741 
7742 namespace {
7743 /// Iteration space of a single for loop.
7744 struct LoopIterationSpace final {
7745   /// True if the condition operator is the strict compare operator (<, > or
7746   /// !=).
7747   bool IsStrictCompare = false;
7748   /// Condition of the loop.
7749   Expr *PreCond = nullptr;
7750   /// This expression calculates the number of iterations in the loop.
7751   /// It is always possible to calculate it before starting the loop.
7752   Expr *NumIterations = nullptr;
7753   /// The loop counter variable.
7754   Expr *CounterVar = nullptr;
7755   /// Private loop counter variable.
7756   Expr *PrivateCounterVar = nullptr;
7757   /// This is initializer for the initial value of #CounterVar.
7758   Expr *CounterInit = nullptr;
7759   /// This is step for the #CounterVar used to generate its update:
7760   /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
7761   Expr *CounterStep = nullptr;
7762   /// Should step be subtracted?
7763   bool Subtract = false;
7764   /// Source range of the loop init.
7765   SourceRange InitSrcRange;
7766   /// Source range of the loop condition.
7767   SourceRange CondSrcRange;
7768   /// Source range of the loop increment.
7769   SourceRange IncSrcRange;
7770   /// Minimum value that can have the loop control variable. Used to support
7771   /// non-rectangular loops. Applied only for LCV with the non-iterator types,
7772   /// since only such variables can be used in non-loop invariant expressions.
7773   Expr *MinValue = nullptr;
7774   /// Maximum value that can have the loop control variable. Used to support
7775   /// non-rectangular loops. Applied only for LCV with the non-iterator type,
7776   /// since only such variables can be used in non-loop invariant expressions.
7777   Expr *MaxValue = nullptr;
7778   /// true, if the lower bound depends on the outer loop control var.
7779   bool IsNonRectangularLB = false;
7780   /// true, if the upper bound depends on the outer loop control var.
7781   bool IsNonRectangularUB = false;
7782   /// Index of the loop this loop depends on and forms non-rectangular loop
7783   /// nest.
7784   unsigned LoopDependentIdx = 0;
7785   /// Final condition for the non-rectangular loop nest support. It is used to
7786   /// check that the number of iterations for this particular counter must be
7787   /// finished.
7788   Expr *FinalCondition = nullptr;
7789 };
7790 
7791 /// Helper class for checking canonical form of the OpenMP loops and
7792 /// extracting iteration space of each loop in the loop nest, that will be used
7793 /// for IR generation.
7794 class OpenMPIterationSpaceChecker {
7795   /// Reference to Sema.
7796   Sema &SemaRef;
7797   /// Does the loop associated directive support non-rectangular loops?
7798   bool SupportsNonRectangular;
7799   /// Data-sharing stack.
7800   DSAStackTy &Stack;
7801   /// A location for diagnostics (when there is no some better location).
7802   SourceLocation DefaultLoc;
7803   /// A location for diagnostics (when increment is not compatible).
7804   SourceLocation ConditionLoc;
7805   /// A source location for referring to loop init later.
7806   SourceRange InitSrcRange;
7807   /// A source location for referring to condition later.
7808   SourceRange ConditionSrcRange;
7809   /// A source location for referring to increment later.
7810   SourceRange IncrementSrcRange;
7811   /// Loop variable.
7812   ValueDecl *LCDecl = nullptr;
7813   /// Reference to loop variable.
7814   Expr *LCRef = nullptr;
7815   /// Lower bound (initializer for the var).
7816   Expr *LB = nullptr;
7817   /// Upper bound.
7818   Expr *UB = nullptr;
7819   /// Loop step (increment).
7820   Expr *Step = nullptr;
7821   /// This flag is true when condition is one of:
7822   ///   Var <  UB
7823   ///   Var <= UB
7824   ///   UB  >  Var
7825   ///   UB  >= Var
7826   /// This will have no value when the condition is !=
7827   std::optional<bool> TestIsLessOp;
7828   /// This flag is true when condition is strict ( < or > ).
7829   bool TestIsStrictOp = false;
7830   /// This flag is true when step is subtracted on each iteration.
7831   bool SubtractStep = false;
7832   /// The outer loop counter this loop depends on (if any).
7833   const ValueDecl *DepDecl = nullptr;
7834   /// Contains number of loop (starts from 1) on which loop counter init
7835   /// expression of this loop depends on.
7836   std::optional<unsigned> InitDependOnLC;
7837   /// Contains number of loop (starts from 1) on which loop counter condition
7838   /// expression of this loop depends on.
7839   std::optional<unsigned> CondDependOnLC;
7840   /// Checks if the provide statement depends on the loop counter.
7841   std::optional<unsigned> doesDependOnLoopCounter(const Stmt *S,
7842                                                   bool IsInitializer);
7843   /// Original condition required for checking of the exit condition for
7844   /// non-rectangular loop.
7845   Expr *Condition = nullptr;
7846 
7847 public:
7848   OpenMPIterationSpaceChecker(Sema &SemaRef, bool SupportsNonRectangular,
7849                               DSAStackTy &Stack, SourceLocation DefaultLoc)
7850       : SemaRef(SemaRef), SupportsNonRectangular(SupportsNonRectangular),
7851         Stack(Stack), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
7852   /// Check init-expr for canonical loop form and save loop counter
7853   /// variable - #Var and its initialization value - #LB.
7854   bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
7855   /// Check test-expr for canonical form, save upper-bound (#UB), flags
7856   /// for less/greater and for strict/non-strict comparison.
7857   bool checkAndSetCond(Expr *S);
7858   /// Check incr-expr for canonical loop form and return true if it
7859   /// does not conform, otherwise save loop step (#Step).
7860   bool checkAndSetInc(Expr *S);
7861   /// Return the loop counter variable.
7862   ValueDecl *getLoopDecl() const { return LCDecl; }
7863   /// Return the reference expression to loop counter variable.
7864   Expr *getLoopDeclRefExpr() const { return LCRef; }
7865   /// Source range of the loop init.
7866   SourceRange getInitSrcRange() const { return InitSrcRange; }
7867   /// Source range of the loop condition.
7868   SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
7869   /// Source range of the loop increment.
7870   SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
7871   /// True if the step should be subtracted.
7872   bool shouldSubtractStep() const { return SubtractStep; }
7873   /// True, if the compare operator is strict (<, > or !=).
7874   bool isStrictTestOp() const { return TestIsStrictOp; }
7875   /// Build the expression to calculate the number of iterations.
7876   Expr *buildNumIterations(
7877       Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
7878       llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7879   /// Build the precondition expression for the loops.
7880   Expr *
7881   buildPreCond(Scope *S, Expr *Cond,
7882                llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7883   /// Build reference expression to the counter be used for codegen.
7884   DeclRefExpr *
7885   buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7886                   DSAStackTy &DSA) const;
7887   /// Build reference expression to the private counter be used for
7888   /// codegen.
7889   Expr *buildPrivateCounterVar() const;
7890   /// Build initialization of the counter be used for codegen.
7891   Expr *buildCounterInit() const;
7892   /// Build step of the counter be used for codegen.
7893   Expr *buildCounterStep() const;
7894   /// Build loop data with counter value for depend clauses in ordered
7895   /// directives.
7896   Expr *
7897   buildOrderedLoopData(Scope *S, Expr *Counter,
7898                        llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7899                        SourceLocation Loc, Expr *Inc = nullptr,
7900                        OverloadedOperatorKind OOK = OO_Amp);
7901   /// Builds the minimum value for the loop counter.
7902   std::pair<Expr *, Expr *> buildMinMaxValues(
7903       Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7904   /// Builds final condition for the non-rectangular loops.
7905   Expr *buildFinalCondition(Scope *S) const;
7906   /// Return true if any expression is dependent.
7907   bool dependent() const;
7908   /// Returns true if the initializer forms non-rectangular loop.
7909   bool doesInitDependOnLC() const { return InitDependOnLC.has_value(); }
7910   /// Returns true if the condition forms non-rectangular loop.
7911   bool doesCondDependOnLC() const { return CondDependOnLC.has_value(); }
7912   /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
7913   unsigned getLoopDependentIdx() const {
7914     return InitDependOnLC.value_or(CondDependOnLC.value_or(0));
7915   }
7916 
7917 private:
7918   /// Check the right-hand side of an assignment in the increment
7919   /// expression.
7920   bool checkAndSetIncRHS(Expr *RHS);
7921   /// Helper to set loop counter variable and its initializer.
7922   bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
7923                       bool EmitDiags);
7924   /// Helper to set upper bound.
7925   bool setUB(Expr *NewUB, std::optional<bool> LessOp, bool StrictOp,
7926              SourceRange SR, SourceLocation SL);
7927   /// Helper to set loop increment.
7928   bool setStep(Expr *NewStep, bool Subtract);
7929 };
7930 
7931 bool OpenMPIterationSpaceChecker::dependent() const {
7932   if (!LCDecl) {
7933     assert(!LB && !UB && !Step);
7934     return false;
7935   }
7936   return LCDecl->getType()->isDependentType() ||
7937          (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
7938          (Step && Step->isValueDependent());
7939 }
7940 
7941 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
7942                                                  Expr *NewLCRefExpr,
7943                                                  Expr *NewLB, bool EmitDiags) {
7944   // State consistency checking to ensure correct usage.
7945   assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
7946          UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
7947   if (!NewLCDecl || !NewLB || NewLB->containsErrors())
7948     return true;
7949   LCDecl = getCanonicalDecl(NewLCDecl);
7950   LCRef = NewLCRefExpr;
7951   if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
7952     if (const CXXConstructorDecl *Ctor = CE->getConstructor())
7953       if ((Ctor->isCopyOrMoveConstructor() ||
7954            Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
7955           CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
7956         NewLB = CE->getArg(0)->IgnoreParenImpCasts();
7957   LB = NewLB;
7958   if (EmitDiags)
7959     InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
7960   return false;
7961 }
7962 
7963 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, std::optional<bool> LessOp,
7964                                         bool StrictOp, SourceRange SR,
7965                                         SourceLocation SL) {
7966   // State consistency checking to ensure correct usage.
7967   assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&
7968          Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
7969   if (!NewUB || NewUB->containsErrors())
7970     return true;
7971   UB = NewUB;
7972   if (LessOp)
7973     TestIsLessOp = LessOp;
7974   TestIsStrictOp = StrictOp;
7975   ConditionSrcRange = SR;
7976   ConditionLoc = SL;
7977   CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
7978   return false;
7979 }
7980 
7981 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
7982   // State consistency checking to ensure correct usage.
7983   assert(LCDecl != nullptr && LB != nullptr && Step == nullptr);
7984   if (!NewStep || NewStep->containsErrors())
7985     return true;
7986   if (!NewStep->isValueDependent()) {
7987     // Check that the step is integer expression.
7988     SourceLocation StepLoc = NewStep->getBeginLoc();
7989     ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
7990         StepLoc, getExprAsWritten(NewStep));
7991     if (Val.isInvalid())
7992       return true;
7993     NewStep = Val.get();
7994 
7995     // OpenMP [2.6, Canonical Loop Form, Restrictions]
7996     //  If test-expr is of form var relational-op b and relational-op is < or
7997     //  <= then incr-expr must cause var to increase on each iteration of the
7998     //  loop. If test-expr is of form var relational-op b and relational-op is
7999     //  > or >= then incr-expr must cause var to decrease on each iteration of
8000     //  the loop.
8001     //  If test-expr is of form b relational-op var and relational-op is < or
8002     //  <= then incr-expr must cause var to decrease on each iteration of the
8003     //  loop. If test-expr is of form b relational-op var and relational-op is
8004     //  > or >= then incr-expr must cause var to increase on each iteration of
8005     //  the loop.
8006     std::optional<llvm::APSInt> Result =
8007         NewStep->getIntegerConstantExpr(SemaRef.Context);
8008     bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
8009     bool IsConstNeg =
8010         Result && Result->isSigned() && (Subtract != Result->isNegative());
8011     bool IsConstPos =
8012         Result && Result->isSigned() && (Subtract == Result->isNegative());
8013     bool IsConstZero = Result && !Result->getBoolValue();
8014 
8015     // != with increment is treated as <; != with decrement is treated as >
8016     if (!TestIsLessOp)
8017       TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
8018     if (UB && (IsConstZero ||
8019                (*TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract))
8020                               : (IsConstPos || (IsUnsigned && !Subtract))))) {
8021       SemaRef.Diag(NewStep->getExprLoc(),
8022                    diag::err_omp_loop_incr_not_compatible)
8023           << LCDecl << *TestIsLessOp << NewStep->getSourceRange();
8024       SemaRef.Diag(ConditionLoc,
8025                    diag::note_omp_loop_cond_requres_compatible_incr)
8026           << *TestIsLessOp << ConditionSrcRange;
8027       return true;
8028     }
8029     if (*TestIsLessOp == Subtract) {
8030       NewStep =
8031           SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
8032               .get();
8033       Subtract = !Subtract;
8034     }
8035   }
8036 
8037   Step = NewStep;
8038   SubtractStep = Subtract;
8039   return false;
8040 }
8041 
8042 namespace {
8043 /// Checker for the non-rectangular loops. Checks if the initializer or
8044 /// condition expression references loop counter variable.
8045 class LoopCounterRefChecker final
8046     : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
8047   Sema &SemaRef;
8048   DSAStackTy &Stack;
8049   const ValueDecl *CurLCDecl = nullptr;
8050   const ValueDecl *DepDecl = nullptr;
8051   const ValueDecl *PrevDepDecl = nullptr;
8052   bool IsInitializer = true;
8053   bool SupportsNonRectangular;
8054   unsigned BaseLoopId = 0;
8055   bool checkDecl(const Expr *E, const ValueDecl *VD) {
8056     if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
8057       SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
8058           << (IsInitializer ? 0 : 1);
8059       return false;
8060     }
8061     const auto &&Data = Stack.isLoopControlVariable(VD);
8062     // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
8063     // The type of the loop iterator on which we depend may not have a random
8064     // access iterator type.
8065     if (Data.first && VD->getType()->isRecordType()) {
8066       SmallString<128> Name;
8067       llvm::raw_svector_ostream OS(Name);
8068       VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
8069                                /*Qualified=*/true);
8070       SemaRef.Diag(E->getExprLoc(),
8071                    diag::err_omp_wrong_dependency_iterator_type)
8072           << OS.str();
8073       SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
8074       return false;
8075     }
8076     if (Data.first && !SupportsNonRectangular) {
8077       SemaRef.Diag(E->getExprLoc(), diag::err_omp_invariant_dependency);
8078       return false;
8079     }
8080     if (Data.first &&
8081         (DepDecl || (PrevDepDecl &&
8082                      getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
8083       if (!DepDecl && PrevDepDecl)
8084         DepDecl = PrevDepDecl;
8085       SmallString<128> Name;
8086       llvm::raw_svector_ostream OS(Name);
8087       DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
8088                                     /*Qualified=*/true);
8089       SemaRef.Diag(E->getExprLoc(),
8090                    diag::err_omp_invariant_or_linear_dependency)
8091           << OS.str();
8092       return false;
8093     }
8094     if (Data.first) {
8095       DepDecl = VD;
8096       BaseLoopId = Data.first;
8097     }
8098     return Data.first;
8099   }
8100 
8101 public:
8102   bool VisitDeclRefExpr(const DeclRefExpr *E) {
8103     const ValueDecl *VD = E->getDecl();
8104     if (isa<VarDecl>(VD))
8105       return checkDecl(E, VD);
8106     return false;
8107   }
8108   bool VisitMemberExpr(const MemberExpr *E) {
8109     if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
8110       const ValueDecl *VD = E->getMemberDecl();
8111       if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
8112         return checkDecl(E, VD);
8113     }
8114     return false;
8115   }
8116   bool VisitStmt(const Stmt *S) {
8117     bool Res = false;
8118     for (const Stmt *Child : S->children())
8119       Res = (Child && Visit(Child)) || Res;
8120     return Res;
8121   }
8122   explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
8123                                  const ValueDecl *CurLCDecl, bool IsInitializer,
8124                                  const ValueDecl *PrevDepDecl = nullptr,
8125                                  bool SupportsNonRectangular = true)
8126       : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
8127         PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer),
8128         SupportsNonRectangular(SupportsNonRectangular) {}
8129   unsigned getBaseLoopId() const {
8130     assert(CurLCDecl && "Expected loop dependency.");
8131     return BaseLoopId;
8132   }
8133   const ValueDecl *getDepDecl() const {
8134     assert(CurLCDecl && "Expected loop dependency.");
8135     return DepDecl;
8136   }
8137 };
8138 } // namespace
8139 
8140 std::optional<unsigned>
8141 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
8142                                                      bool IsInitializer) {
8143   // Check for the non-rectangular loops.
8144   LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
8145                                         DepDecl, SupportsNonRectangular);
8146   if (LoopStmtChecker.Visit(S)) {
8147     DepDecl = LoopStmtChecker.getDepDecl();
8148     return LoopStmtChecker.getBaseLoopId();
8149   }
8150   return std::nullopt;
8151 }
8152 
8153 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
8154   // Check init-expr for canonical loop form and save loop counter
8155   // variable - #Var and its initialization value - #LB.
8156   // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
8157   //   var = lb
8158   //   integer-type var = lb
8159   //   random-access-iterator-type var = lb
8160   //   pointer-type var = lb
8161   //
8162   if (!S) {
8163     if (EmitDiags) {
8164       SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
8165     }
8166     return true;
8167   }
8168   if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
8169     if (!ExprTemp->cleanupsHaveSideEffects())
8170       S = ExprTemp->getSubExpr();
8171 
8172   InitSrcRange = S->getSourceRange();
8173   if (Expr *E = dyn_cast<Expr>(S))
8174     S = E->IgnoreParens();
8175   if (auto *BO = dyn_cast<BinaryOperator>(S)) {
8176     if (BO->getOpcode() == BO_Assign) {
8177       Expr *LHS = BO->getLHS()->IgnoreParens();
8178       if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
8179         if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
8180           if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
8181             return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8182                                   EmitDiags);
8183         return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
8184       }
8185       if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
8186         if (ME->isArrow() &&
8187             isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8188           return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8189                                 EmitDiags);
8190       }
8191     }
8192   } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
8193     if (DS->isSingleDecl()) {
8194       if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
8195         if (Var->hasInit() && !Var->getType()->isReferenceType()) {
8196           // Accept non-canonical init form here but emit ext. warning.
8197           if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
8198             SemaRef.Diag(S->getBeginLoc(),
8199                          diag::ext_omp_loop_not_canonical_init)
8200                 << S->getSourceRange();
8201           return setLCDeclAndLB(
8202               Var,
8203               buildDeclRefExpr(SemaRef, Var,
8204                                Var->getType().getNonReferenceType(),
8205                                DS->getBeginLoc()),
8206               Var->getInit(), EmitDiags);
8207         }
8208       }
8209     }
8210   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8211     if (CE->getOperator() == OO_Equal) {
8212       Expr *LHS = CE->getArg(0);
8213       if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
8214         if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
8215           if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
8216             return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8217                                   EmitDiags);
8218         return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
8219       }
8220       if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
8221         if (ME->isArrow() &&
8222             isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8223           return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8224                                 EmitDiags);
8225       }
8226     }
8227   }
8228 
8229   if (dependent() || SemaRef.CurContext->isDependentContext())
8230     return false;
8231   if (EmitDiags) {
8232     SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
8233         << S->getSourceRange();
8234   }
8235   return true;
8236 }
8237 
8238 /// Ignore parenthesizes, implicit casts, copy constructor and return the
8239 /// variable (which may be the loop variable) if possible.
8240 static const ValueDecl *getInitLCDecl(const Expr *E) {
8241   if (!E)
8242     return nullptr;
8243   E = getExprAsWritten(E);
8244   if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
8245     if (const CXXConstructorDecl *Ctor = CE->getConstructor())
8246       if ((Ctor->isCopyOrMoveConstructor() ||
8247            Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
8248           CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
8249         E = CE->getArg(0)->IgnoreParenImpCasts();
8250   if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
8251     if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
8252       return getCanonicalDecl(VD);
8253   }
8254   if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
8255     if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8256       return getCanonicalDecl(ME->getMemberDecl());
8257   return nullptr;
8258 }
8259 
8260 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
8261   // Check test-expr for canonical form, save upper-bound UB, flags for
8262   // less/greater and for strict/non-strict comparison.
8263   // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following:
8264   //   var relational-op b
8265   //   b relational-op var
8266   //
8267   bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
8268   if (!S) {
8269     SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
8270         << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
8271     return true;
8272   }
8273   Condition = S;
8274   S = getExprAsWritten(S);
8275   SourceLocation CondLoc = S->getBeginLoc();
8276   auto &&CheckAndSetCond =
8277       [this, IneqCondIsCanonical](BinaryOperatorKind Opcode, const Expr *LHS,
8278                                   const Expr *RHS, SourceRange SR,
8279                                   SourceLocation OpLoc) -> std::optional<bool> {
8280     if (BinaryOperator::isRelationalOp(Opcode)) {
8281       if (getInitLCDecl(LHS) == LCDecl)
8282         return setUB(const_cast<Expr *>(RHS),
8283                      (Opcode == BO_LT || Opcode == BO_LE),
8284                      (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
8285       if (getInitLCDecl(RHS) == LCDecl)
8286         return setUB(const_cast<Expr *>(LHS),
8287                      (Opcode == BO_GT || Opcode == BO_GE),
8288                      (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
8289     } else if (IneqCondIsCanonical && Opcode == BO_NE) {
8290       return setUB(const_cast<Expr *>(getInitLCDecl(LHS) == LCDecl ? RHS : LHS),
8291                    /*LessOp=*/std::nullopt,
8292                    /*StrictOp=*/true, SR, OpLoc);
8293     }
8294     return std::nullopt;
8295   };
8296   std::optional<bool> Res;
8297   if (auto *RBO = dyn_cast<CXXRewrittenBinaryOperator>(S)) {
8298     CXXRewrittenBinaryOperator::DecomposedForm DF = RBO->getDecomposedForm();
8299     Res = CheckAndSetCond(DF.Opcode, DF.LHS, DF.RHS, RBO->getSourceRange(),
8300                           RBO->getOperatorLoc());
8301   } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
8302     Res = CheckAndSetCond(BO->getOpcode(), BO->getLHS(), BO->getRHS(),
8303                           BO->getSourceRange(), BO->getOperatorLoc());
8304   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8305     if (CE->getNumArgs() == 2) {
8306       Res = CheckAndSetCond(
8307           BinaryOperator::getOverloadedOpcode(CE->getOperator()), CE->getArg(0),
8308           CE->getArg(1), CE->getSourceRange(), CE->getOperatorLoc());
8309     }
8310   }
8311   if (Res)
8312     return *Res;
8313   if (dependent() || SemaRef.CurContext->isDependentContext())
8314     return false;
8315   SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
8316       << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
8317   return true;
8318 }
8319 
8320 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
8321   // RHS of canonical loop form increment can be:
8322   //   var + incr
8323   //   incr + var
8324   //   var - incr
8325   //
8326   RHS = RHS->IgnoreParenImpCasts();
8327   if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
8328     if (BO->isAdditiveOp()) {
8329       bool IsAdd = BO->getOpcode() == BO_Add;
8330       if (getInitLCDecl(BO->getLHS()) == LCDecl)
8331         return setStep(BO->getRHS(), !IsAdd);
8332       if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
8333         return setStep(BO->getLHS(), /*Subtract=*/false);
8334     }
8335   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
8336     bool IsAdd = CE->getOperator() == OO_Plus;
8337     if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
8338       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8339         return setStep(CE->getArg(1), !IsAdd);
8340       if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
8341         return setStep(CE->getArg(0), /*Subtract=*/false);
8342     }
8343   }
8344   if (dependent() || SemaRef.CurContext->isDependentContext())
8345     return false;
8346   SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
8347       << RHS->getSourceRange() << LCDecl;
8348   return true;
8349 }
8350 
8351 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
8352   // Check incr-expr for canonical loop form and return true if it
8353   // does not conform.
8354   // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
8355   //   ++var
8356   //   var++
8357   //   --var
8358   //   var--
8359   //   var += incr
8360   //   var -= incr
8361   //   var = var + incr
8362   //   var = incr + var
8363   //   var = var - incr
8364   //
8365   if (!S) {
8366     SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
8367     return true;
8368   }
8369   if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
8370     if (!ExprTemp->cleanupsHaveSideEffects())
8371       S = ExprTemp->getSubExpr();
8372 
8373   IncrementSrcRange = S->getSourceRange();
8374   S = S->IgnoreParens();
8375   if (auto *UO = dyn_cast<UnaryOperator>(S)) {
8376     if (UO->isIncrementDecrementOp() &&
8377         getInitLCDecl(UO->getSubExpr()) == LCDecl)
8378       return setStep(SemaRef
8379                          .ActOnIntegerConstant(UO->getBeginLoc(),
8380                                                (UO->isDecrementOp() ? -1 : 1))
8381                          .get(),
8382                      /*Subtract=*/false);
8383   } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
8384     switch (BO->getOpcode()) {
8385     case BO_AddAssign:
8386     case BO_SubAssign:
8387       if (getInitLCDecl(BO->getLHS()) == LCDecl)
8388         return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
8389       break;
8390     case BO_Assign:
8391       if (getInitLCDecl(BO->getLHS()) == LCDecl)
8392         return checkAndSetIncRHS(BO->getRHS());
8393       break;
8394     default:
8395       break;
8396     }
8397   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8398     switch (CE->getOperator()) {
8399     case OO_PlusPlus:
8400     case OO_MinusMinus:
8401       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8402         return setStep(SemaRef
8403                            .ActOnIntegerConstant(
8404                                CE->getBeginLoc(),
8405                                ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
8406                            .get(),
8407                        /*Subtract=*/false);
8408       break;
8409     case OO_PlusEqual:
8410     case OO_MinusEqual:
8411       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8412         return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
8413       break;
8414     case OO_Equal:
8415       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8416         return checkAndSetIncRHS(CE->getArg(1));
8417       break;
8418     default:
8419       break;
8420     }
8421   }
8422   if (dependent() || SemaRef.CurContext->isDependentContext())
8423     return false;
8424   SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
8425       << S->getSourceRange() << LCDecl;
8426   return true;
8427 }
8428 
8429 static ExprResult
8430 tryBuildCapture(Sema &SemaRef, Expr *Capture,
8431                 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8432                 StringRef Name = ".capture_expr.") {
8433   if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors())
8434     return Capture;
8435   if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
8436     return SemaRef.PerformImplicitConversion(
8437         Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
8438         /*AllowExplicit=*/true);
8439   auto I = Captures.find(Capture);
8440   if (I != Captures.end())
8441     return buildCapture(SemaRef, Capture, I->second, Name);
8442   DeclRefExpr *Ref = nullptr;
8443   ExprResult Res = buildCapture(SemaRef, Capture, Ref, Name);
8444   Captures[Capture] = Ref;
8445   return Res;
8446 }
8447 
8448 /// Calculate number of iterations, transforming to unsigned, if number of
8449 /// iterations may be larger than the original type.
8450 static Expr *
8451 calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc,
8452                   Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy,
8453                   bool TestIsStrictOp, bool RoundToStep,
8454                   llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8455   ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures, ".new_step");
8456   if (!NewStep.isUsable())
8457     return nullptr;
8458   llvm::APSInt LRes, SRes;
8459   bool IsLowerConst = false, IsStepConst = false;
8460   if (std::optional<llvm::APSInt> Res =
8461           Lower->getIntegerConstantExpr(SemaRef.Context)) {
8462     LRes = *Res;
8463     IsLowerConst = true;
8464   }
8465   if (std::optional<llvm::APSInt> Res =
8466           Step->getIntegerConstantExpr(SemaRef.Context)) {
8467     SRes = *Res;
8468     IsStepConst = true;
8469   }
8470   bool NoNeedToConvert = IsLowerConst && !RoundToStep &&
8471                          ((!TestIsStrictOp && LRes.isNonNegative()) ||
8472                           (TestIsStrictOp && LRes.isStrictlyPositive()));
8473   bool NeedToReorganize = false;
8474   // Check if any subexpressions in Lower -Step [+ 1] lead to overflow.
8475   if (!NoNeedToConvert && IsLowerConst &&
8476       (TestIsStrictOp || (RoundToStep && IsStepConst))) {
8477     NoNeedToConvert = true;
8478     if (RoundToStep) {
8479       unsigned BW = LRes.getBitWidth() > SRes.getBitWidth()
8480                         ? LRes.getBitWidth()
8481                         : SRes.getBitWidth();
8482       LRes = LRes.extend(BW + 1);
8483       LRes.setIsSigned(true);
8484       SRes = SRes.extend(BW + 1);
8485       SRes.setIsSigned(true);
8486       LRes -= SRes;
8487       NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes;
8488       LRes = LRes.trunc(BW);
8489     }
8490     if (TestIsStrictOp) {
8491       unsigned BW = LRes.getBitWidth();
8492       LRes = LRes.extend(BW + 1);
8493       LRes.setIsSigned(true);
8494       ++LRes;
8495       NoNeedToConvert =
8496           NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes;
8497       // truncate to the original bitwidth.
8498       LRes = LRes.trunc(BW);
8499     }
8500     NeedToReorganize = NoNeedToConvert;
8501   }
8502   llvm::APSInt URes;
8503   bool IsUpperConst = false;
8504   if (std::optional<llvm::APSInt> Res =
8505           Upper->getIntegerConstantExpr(SemaRef.Context)) {
8506     URes = *Res;
8507     IsUpperConst = true;
8508   }
8509   if (NoNeedToConvert && IsLowerConst && IsUpperConst &&
8510       (!RoundToStep || IsStepConst)) {
8511     unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth()
8512                                                           : URes.getBitWidth();
8513     LRes = LRes.extend(BW + 1);
8514     LRes.setIsSigned(true);
8515     URes = URes.extend(BW + 1);
8516     URes.setIsSigned(true);
8517     URes -= LRes;
8518     NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes;
8519     NeedToReorganize = NoNeedToConvert;
8520   }
8521   // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant
8522   // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to
8523   // unsigned.
8524   if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) &&
8525       !LCTy->isDependentType() && LCTy->isIntegerType()) {
8526     QualType LowerTy = Lower->getType();
8527     QualType UpperTy = Upper->getType();
8528     uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy);
8529     uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy);
8530     if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) ||
8531         (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) {
8532       QualType CastType = SemaRef.Context.getIntTypeForBitwidth(
8533           LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0);
8534       Upper =
8535           SemaRef
8536               .PerformImplicitConversion(
8537                   SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
8538                   CastType, Sema::AA_Converting)
8539               .get();
8540       Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get();
8541       NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get());
8542     }
8543   }
8544   if (!Lower || !Upper || NewStep.isInvalid())
8545     return nullptr;
8546 
8547   ExprResult Diff;
8548   // If need to reorganize, then calculate the form as Upper - (Lower - Step [+
8549   // 1]).
8550   if (NeedToReorganize) {
8551     Diff = Lower;
8552 
8553     if (RoundToStep) {
8554       // Lower - Step
8555       Diff =
8556           SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get());
8557       if (!Diff.isUsable())
8558         return nullptr;
8559     }
8560 
8561     // Lower - Step [+ 1]
8562     if (TestIsStrictOp)
8563       Diff = SemaRef.BuildBinOp(
8564           S, DefaultLoc, BO_Add, Diff.get(),
8565           SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8566     if (!Diff.isUsable())
8567       return nullptr;
8568 
8569     Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8570     if (!Diff.isUsable())
8571       return nullptr;
8572 
8573     // Upper - (Lower - Step [+ 1]).
8574     Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get());
8575     if (!Diff.isUsable())
8576       return nullptr;
8577   } else {
8578     Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
8579 
8580     if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) {
8581       // BuildBinOp already emitted error, this one is to point user to upper
8582       // and lower bound, and to tell what is passed to 'operator-'.
8583       SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
8584           << Upper->getSourceRange() << Lower->getSourceRange();
8585       return nullptr;
8586     }
8587 
8588     if (!Diff.isUsable())
8589       return nullptr;
8590 
8591     // Upper - Lower [- 1]
8592     if (TestIsStrictOp)
8593       Diff = SemaRef.BuildBinOp(
8594           S, DefaultLoc, BO_Sub, Diff.get(),
8595           SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8596     if (!Diff.isUsable())
8597       return nullptr;
8598 
8599     if (RoundToStep) {
8600       // Upper - Lower [- 1] + Step
8601       Diff =
8602           SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
8603       if (!Diff.isUsable())
8604         return nullptr;
8605     }
8606   }
8607 
8608   // Parentheses (for dumping/debugging purposes only).
8609   Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8610   if (!Diff.isUsable())
8611     return nullptr;
8612 
8613   // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step
8614   Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
8615   if (!Diff.isUsable())
8616     return nullptr;
8617 
8618   return Diff.get();
8619 }
8620 
8621 /// Build the expression to calculate the number of iterations.
8622 Expr *OpenMPIterationSpaceChecker::buildNumIterations(
8623     Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
8624     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8625   QualType VarType = LCDecl->getType().getNonReferenceType();
8626   if (!VarType->isIntegerType() && !VarType->isPointerType() &&
8627       !SemaRef.getLangOpts().CPlusPlus)
8628     return nullptr;
8629   Expr *LBVal = LB;
8630   Expr *UBVal = UB;
8631   // OuterVar = (LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
8632   // max(LB(MinVal), LB(MaxVal)))
8633   if (InitDependOnLC) {
8634     const LoopIterationSpace &IS = ResultIterSpaces[*InitDependOnLC - 1];
8635     if (!IS.MinValue || !IS.MaxValue)
8636       return nullptr;
8637     // OuterVar = Min
8638     ExprResult MinValue =
8639         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8640     if (!MinValue.isUsable())
8641       return nullptr;
8642 
8643     ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8644                                              IS.CounterVar, MinValue.get());
8645     if (!LBMinVal.isUsable())
8646       return nullptr;
8647     // OuterVar = Min, LBVal
8648     LBMinVal =
8649         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal);
8650     if (!LBMinVal.isUsable())
8651       return nullptr;
8652     // (OuterVar = Min, LBVal)
8653     LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get());
8654     if (!LBMinVal.isUsable())
8655       return nullptr;
8656 
8657     // OuterVar = Max
8658     ExprResult MaxValue =
8659         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8660     if (!MaxValue.isUsable())
8661       return nullptr;
8662 
8663     ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8664                                              IS.CounterVar, MaxValue.get());
8665     if (!LBMaxVal.isUsable())
8666       return nullptr;
8667     // OuterVar = Max, LBVal
8668     LBMaxVal =
8669         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal);
8670     if (!LBMaxVal.isUsable())
8671       return nullptr;
8672     // (OuterVar = Max, LBVal)
8673     LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get());
8674     if (!LBMaxVal.isUsable())
8675       return nullptr;
8676 
8677     Expr *LBMin =
8678         tryBuildCapture(SemaRef, LBMinVal.get(), Captures, ".lb_min").get();
8679     Expr *LBMax =
8680         tryBuildCapture(SemaRef, LBMaxVal.get(), Captures, ".lb_max").get();
8681     if (!LBMin || !LBMax)
8682       return nullptr;
8683     // LB(MinVal) < LB(MaxVal)
8684     ExprResult MinLessMaxRes =
8685         SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
8686     if (!MinLessMaxRes.isUsable())
8687       return nullptr;
8688     Expr *MinLessMax =
8689         tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures, ".min_less_max")
8690             .get();
8691     if (!MinLessMax)
8692       return nullptr;
8693     if (*TestIsLessOp) {
8694       // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
8695       // LB(MaxVal))
8696       ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8697                                                     MinLessMax, LBMin, LBMax);
8698       if (!MinLB.isUsable())
8699         return nullptr;
8700       LBVal = MinLB.get();
8701     } else {
8702       // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
8703       // LB(MaxVal))
8704       ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8705                                                     MinLessMax, LBMax, LBMin);
8706       if (!MaxLB.isUsable())
8707         return nullptr;
8708       LBVal = MaxLB.get();
8709     }
8710     // OuterVar = LB
8711     LBMinVal =
8712         SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, IS.CounterVar, LBVal);
8713     if (!LBMinVal.isUsable())
8714       return nullptr;
8715     LBVal = LBMinVal.get();
8716   }
8717   // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
8718   // min(UB(MinVal), UB(MaxVal))
8719   if (CondDependOnLC) {
8720     const LoopIterationSpace &IS = ResultIterSpaces[*CondDependOnLC - 1];
8721     if (!IS.MinValue || !IS.MaxValue)
8722       return nullptr;
8723     // OuterVar = Min
8724     ExprResult MinValue =
8725         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8726     if (!MinValue.isUsable())
8727       return nullptr;
8728 
8729     ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8730                                              IS.CounterVar, MinValue.get());
8731     if (!UBMinVal.isUsable())
8732       return nullptr;
8733     // OuterVar = Min, UBVal
8734     UBMinVal =
8735         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal);
8736     if (!UBMinVal.isUsable())
8737       return nullptr;
8738     // (OuterVar = Min, UBVal)
8739     UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get());
8740     if (!UBMinVal.isUsable())
8741       return nullptr;
8742 
8743     // OuterVar = Max
8744     ExprResult MaxValue =
8745         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8746     if (!MaxValue.isUsable())
8747       return nullptr;
8748 
8749     ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8750                                              IS.CounterVar, MaxValue.get());
8751     if (!UBMaxVal.isUsable())
8752       return nullptr;
8753     // OuterVar = Max, UBVal
8754     UBMaxVal =
8755         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal);
8756     if (!UBMaxVal.isUsable())
8757       return nullptr;
8758     // (OuterVar = Max, UBVal)
8759     UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get());
8760     if (!UBMaxVal.isUsable())
8761       return nullptr;
8762 
8763     Expr *UBMin =
8764         tryBuildCapture(SemaRef, UBMinVal.get(), Captures, ".ub_min").get();
8765     Expr *UBMax =
8766         tryBuildCapture(SemaRef, UBMaxVal.get(), Captures, ".ub_max").get();
8767     if (!UBMin || !UBMax)
8768       return nullptr;
8769     // UB(MinVal) > UB(MaxVal)
8770     ExprResult MinGreaterMaxRes =
8771         SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
8772     if (!MinGreaterMaxRes.isUsable())
8773       return nullptr;
8774     Expr *MinGreaterMax = tryBuildCapture(SemaRef, MinGreaterMaxRes.get(),
8775                                           Captures, ".min_greater_max")
8776                               .get();
8777     if (!MinGreaterMax)
8778       return nullptr;
8779     if (*TestIsLessOp) {
8780       // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
8781       // UB(MaxVal))
8782       ExprResult MaxUB = SemaRef.ActOnConditionalOp(
8783           DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
8784       if (!MaxUB.isUsable())
8785         return nullptr;
8786       UBVal = MaxUB.get();
8787     } else {
8788       // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
8789       // UB(MaxVal))
8790       ExprResult MinUB = SemaRef.ActOnConditionalOp(
8791           DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
8792       if (!MinUB.isUsable())
8793         return nullptr;
8794       UBVal = MinUB.get();
8795     }
8796   }
8797   Expr *UBExpr = *TestIsLessOp ? UBVal : LBVal;
8798   Expr *LBExpr = *TestIsLessOp ? LBVal : UBVal;
8799   Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures, ".upper").get();
8800   Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures, ".lower").get();
8801   if (!Upper || !Lower)
8802     return nullptr;
8803 
8804   ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8805                                       Step, VarType, TestIsStrictOp,
8806                                       /*RoundToStep=*/true, Captures);
8807   if (!Diff.isUsable())
8808     return nullptr;
8809 
8810   // OpenMP runtime requires 32-bit or 64-bit loop variables.
8811   QualType Type = Diff.get()->getType();
8812   ASTContext &C = SemaRef.Context;
8813   bool UseVarType = VarType->hasIntegerRepresentation() &&
8814                     C.getTypeSize(Type) > C.getTypeSize(VarType);
8815   if (!Type->isIntegerType() || UseVarType) {
8816     unsigned NewSize =
8817         UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
8818     bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
8819                                : Type->hasSignedIntegerRepresentation();
8820     Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
8821     if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
8822       Diff = SemaRef.PerformImplicitConversion(
8823           Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
8824       if (!Diff.isUsable())
8825         return nullptr;
8826     }
8827   }
8828   if (LimitedType) {
8829     unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
8830     if (NewSize != C.getTypeSize(Type)) {
8831       if (NewSize < C.getTypeSize(Type)) {
8832         assert(NewSize == 64 && "incorrect loop var size");
8833         SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
8834             << InitSrcRange << ConditionSrcRange;
8835       }
8836       QualType NewType = C.getIntTypeForBitwidth(
8837           NewSize, Type->hasSignedIntegerRepresentation() ||
8838                        C.getTypeSize(Type) < NewSize);
8839       if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
8840         Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
8841                                                  Sema::AA_Converting, true);
8842         if (!Diff.isUsable())
8843           return nullptr;
8844       }
8845     }
8846   }
8847 
8848   return Diff.get();
8849 }
8850 
8851 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
8852     Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8853   // Do not build for iterators, they cannot be used in non-rectangular loop
8854   // nests.
8855   if (LCDecl->getType()->isRecordType())
8856     return std::make_pair(nullptr, nullptr);
8857   // If we subtract, the min is in the condition, otherwise the min is in the
8858   // init value.
8859   Expr *MinExpr = nullptr;
8860   Expr *MaxExpr = nullptr;
8861   Expr *LBExpr = *TestIsLessOp ? LB : UB;
8862   Expr *UBExpr = *TestIsLessOp ? UB : LB;
8863   bool LBNonRect =
8864       *TestIsLessOp ? InitDependOnLC.has_value() : CondDependOnLC.has_value();
8865   bool UBNonRect =
8866       *TestIsLessOp ? CondDependOnLC.has_value() : InitDependOnLC.has_value();
8867   Expr *Lower =
8868       LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
8869   Expr *Upper =
8870       UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
8871   if (!Upper || !Lower)
8872     return std::make_pair(nullptr, nullptr);
8873 
8874   if (*TestIsLessOp)
8875     MinExpr = Lower;
8876   else
8877     MaxExpr = Upper;
8878 
8879   // Build minimum/maximum value based on number of iterations.
8880   QualType VarType = LCDecl->getType().getNonReferenceType();
8881 
8882   ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8883                                       Step, VarType, TestIsStrictOp,
8884                                       /*RoundToStep=*/false, Captures);
8885   if (!Diff.isUsable())
8886     return std::make_pair(nullptr, nullptr);
8887 
8888   // ((Upper - Lower [- 1]) / Step) * Step
8889   // Parentheses (for dumping/debugging purposes only).
8890   Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8891   if (!Diff.isUsable())
8892     return std::make_pair(nullptr, nullptr);
8893 
8894   ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures, ".new_step");
8895   if (!NewStep.isUsable())
8896     return std::make_pair(nullptr, nullptr);
8897   Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get());
8898   if (!Diff.isUsable())
8899     return std::make_pair(nullptr, nullptr);
8900 
8901   // Parentheses (for dumping/debugging purposes only).
8902   Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8903   if (!Diff.isUsable())
8904     return std::make_pair(nullptr, nullptr);
8905 
8906   // Convert to the ptrdiff_t, if original type is pointer.
8907   if (VarType->isAnyPointerType() &&
8908       !SemaRef.Context.hasSameType(
8909           Diff.get()->getType(),
8910           SemaRef.Context.getUnsignedPointerDiffType())) {
8911     Diff = SemaRef.PerformImplicitConversion(
8912         Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(),
8913         Sema::AA_Converting, /*AllowExplicit=*/true);
8914   }
8915   if (!Diff.isUsable())
8916     return std::make_pair(nullptr, nullptr);
8917 
8918   if (*TestIsLessOp) {
8919     // MinExpr = Lower;
8920     // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
8921     Diff = SemaRef.BuildBinOp(
8922         S, DefaultLoc, BO_Add,
8923         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(),
8924         Diff.get());
8925     if (!Diff.isUsable())
8926       return std::make_pair(nullptr, nullptr);
8927   } else {
8928     // MaxExpr = Upper;
8929     // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
8930     Diff = SemaRef.BuildBinOp(
8931         S, DefaultLoc, BO_Sub,
8932         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
8933         Diff.get());
8934     if (!Diff.isUsable())
8935       return std::make_pair(nullptr, nullptr);
8936   }
8937 
8938   // Convert to the original type.
8939   if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType))
8940     Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType,
8941                                              Sema::AA_Converting,
8942                                              /*AllowExplicit=*/true);
8943   if (!Diff.isUsable())
8944     return std::make_pair(nullptr, nullptr);
8945 
8946   Sema::TentativeAnalysisScope Trap(SemaRef);
8947   Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false);
8948   if (!Diff.isUsable())
8949     return std::make_pair(nullptr, nullptr);
8950 
8951   if (*TestIsLessOp)
8952     MaxExpr = Diff.get();
8953   else
8954     MinExpr = Diff.get();
8955 
8956   return std::make_pair(MinExpr, MaxExpr);
8957 }
8958 
8959 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const {
8960   if (InitDependOnLC || CondDependOnLC)
8961     return Condition;
8962   return nullptr;
8963 }
8964 
8965 Expr *OpenMPIterationSpaceChecker::buildPreCond(
8966     Scope *S, Expr *Cond,
8967     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8968   // Do not build a precondition when the condition/initialization is dependent
8969   // to prevent pessimistic early loop exit.
8970   // TODO: this can be improved by calculating min/max values but not sure that
8971   // it will be very effective.
8972   if (CondDependOnLC || InitDependOnLC)
8973     return SemaRef
8974         .PerformImplicitConversion(
8975             SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(),
8976             SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
8977             /*AllowExplicit=*/true)
8978         .get();
8979 
8980   // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
8981   Sema::TentativeAnalysisScope Trap(SemaRef);
8982 
8983   ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
8984   ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
8985   if (!NewLB.isUsable() || !NewUB.isUsable())
8986     return nullptr;
8987 
8988   ExprResult CondExpr =
8989       SemaRef.BuildBinOp(S, DefaultLoc,
8990                          *TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE)
8991                                        : (TestIsStrictOp ? BO_GT : BO_GE),
8992                          NewLB.get(), NewUB.get());
8993   if (CondExpr.isUsable()) {
8994     if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
8995                                                 SemaRef.Context.BoolTy))
8996       CondExpr = SemaRef.PerformImplicitConversion(
8997           CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
8998           /*AllowExplicit=*/true);
8999   }
9000 
9001   // Otherwise use original loop condition and evaluate it in runtime.
9002   return CondExpr.isUsable() ? CondExpr.get() : Cond;
9003 }
9004 
9005 /// Build reference expression to the counter be used for codegen.
9006 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
9007     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
9008     DSAStackTy &DSA) const {
9009   auto *VD = dyn_cast<VarDecl>(LCDecl);
9010   if (!VD) {
9011     VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
9012     DeclRefExpr *Ref = buildDeclRefExpr(
9013         SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
9014     const DSAStackTy::DSAVarData Data =
9015         DSA.getTopDSA(LCDecl, /*FromParent=*/false);
9016     // If the loop control decl is explicitly marked as private, do not mark it
9017     // as captured again.
9018     if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
9019       Captures.insert(std::make_pair(LCRef, Ref));
9020     return Ref;
9021   }
9022   return cast<DeclRefExpr>(LCRef);
9023 }
9024 
9025 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
9026   if (LCDecl && !LCDecl->isInvalidDecl()) {
9027     QualType Type = LCDecl->getType().getNonReferenceType();
9028     VarDecl *PrivateVar = buildVarDecl(
9029         SemaRef, DefaultLoc, Type, LCDecl->getName(),
9030         LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
9031         isa<VarDecl>(LCDecl)
9032             ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
9033             : nullptr);
9034     if (PrivateVar->isInvalidDecl())
9035       return nullptr;
9036     return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
9037   }
9038   return nullptr;
9039 }
9040 
9041 /// Build initialization of the counter to be used for codegen.
9042 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
9043 
9044 /// Build step of the counter be used for codegen.
9045 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
9046 
9047 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
9048     Scope *S, Expr *Counter,
9049     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
9050     Expr *Inc, OverloadedOperatorKind OOK) {
9051   Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
9052   if (!Cnt)
9053     return nullptr;
9054   if (Inc) {
9055     assert((OOK == OO_Plus || OOK == OO_Minus) &&
9056            "Expected only + or - operations for depend clauses.");
9057     BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
9058     Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
9059     if (!Cnt)
9060       return nullptr;
9061   }
9062   QualType VarType = LCDecl->getType().getNonReferenceType();
9063   if (!VarType->isIntegerType() && !VarType->isPointerType() &&
9064       !SemaRef.getLangOpts().CPlusPlus)
9065     return nullptr;
9066   // Upper - Lower
9067   Expr *Upper =
9068       *TestIsLessOp ? Cnt : tryBuildCapture(SemaRef, LB, Captures).get();
9069   Expr *Lower =
9070       *TestIsLessOp ? tryBuildCapture(SemaRef, LB, Captures).get() : Cnt;
9071   if (!Upper || !Lower)
9072     return nullptr;
9073 
9074   ExprResult Diff = calculateNumIters(
9075       SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
9076       /*TestIsStrictOp=*/false, /*RoundToStep=*/false, Captures);
9077   if (!Diff.isUsable())
9078     return nullptr;
9079 
9080   return Diff.get();
9081 }
9082 } // namespace
9083 
9084 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
9085   assert(getLangOpts().OpenMP && "OpenMP is not active.");
9086   assert(Init && "Expected loop in canonical form.");
9087   unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
9088   if (AssociatedLoops > 0 &&
9089       isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
9090     DSAStack->loopStart();
9091     OpenMPIterationSpaceChecker ISC(*this, /*SupportsNonRectangular=*/true,
9092                                     *DSAStack, ForLoc);
9093     if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
9094       if (ValueDecl *D = ISC.getLoopDecl()) {
9095         auto *VD = dyn_cast<VarDecl>(D);
9096         DeclRefExpr *PrivateRef = nullptr;
9097         if (!VD) {
9098           if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
9099             VD = Private;
9100           } else {
9101             PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
9102                                       /*WithInit=*/false);
9103             VD = cast<VarDecl>(PrivateRef->getDecl());
9104           }
9105         }
9106         DSAStack->addLoopControlVariable(D, VD);
9107         const Decl *LD = DSAStack->getPossiblyLoopCunter();
9108         if (LD != D->getCanonicalDecl()) {
9109           DSAStack->resetPossibleLoopCounter();
9110           if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
9111             MarkDeclarationsReferencedInExpr(
9112                 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
9113                                  Var->getType().getNonLValueExprType(Context),
9114                                  ForLoc, /*RefersToCapture=*/true));
9115         }
9116         OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
9117         // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
9118         // Referenced in a Construct, C/C++]. The loop iteration variable in the
9119         // associated for-loop of a simd construct with just one associated
9120         // for-loop may be listed in a linear clause with a constant-linear-step
9121         // that is the increment of the associated for-loop. The loop iteration
9122         // variable(s) in the associated for-loop(s) of a for or parallel for
9123         // construct may be listed in a private or lastprivate clause.
9124         DSAStackTy::DSAVarData DVar =
9125             DSAStack->getTopDSA(D, /*FromParent=*/false);
9126         // If LoopVarRefExpr is nullptr it means the corresponding loop variable
9127         // is declared in the loop and it is predetermined as a private.
9128         Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
9129         OpenMPClauseKind PredeterminedCKind =
9130             isOpenMPSimdDirective(DKind)
9131                 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
9132                 : OMPC_private;
9133         if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
9134               DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
9135               (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
9136                                          DVar.CKind != OMPC_private))) ||
9137              ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
9138                DKind == OMPD_master_taskloop || DKind == OMPD_masked_taskloop ||
9139                DKind == OMPD_parallel_master_taskloop ||
9140                DKind == OMPD_parallel_masked_taskloop ||
9141                isOpenMPDistributeDirective(DKind)) &&
9142               !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
9143               DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
9144             (DVar.CKind != OMPC_private || DVar.RefExpr)) {
9145           Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
9146               << getOpenMPClauseName(DVar.CKind)
9147               << getOpenMPDirectiveName(DKind)
9148               << getOpenMPClauseName(PredeterminedCKind);
9149           if (DVar.RefExpr == nullptr)
9150             DVar.CKind = PredeterminedCKind;
9151           reportOriginalDsa(*this, DSAStack, D, DVar,
9152                             /*IsLoopIterVar=*/true);
9153         } else if (LoopDeclRefExpr) {
9154           // Make the loop iteration variable private (for worksharing
9155           // constructs), linear (for simd directives with the only one
9156           // associated loop) or lastprivate (for simd directives with several
9157           // collapsed or ordered loops).
9158           if (DVar.CKind == OMPC_unknown)
9159             DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
9160                              PrivateRef);
9161         }
9162       }
9163     }
9164     DSAStack->setAssociatedLoops(AssociatedLoops - 1);
9165   }
9166 }
9167 
9168 namespace {
9169 // Utility for openmp doacross clause kind
9170 class OMPDoacrossKind {
9171 public:
9172   bool isSource(const OMPDoacrossClause *C) {
9173     return C->getDependenceType() == OMPC_DOACROSS_source ||
9174            C->getDependenceType() == OMPC_DOACROSS_source_omp_cur_iteration;
9175   }
9176   bool isSink(const OMPDoacrossClause *C) {
9177     return C->getDependenceType() == OMPC_DOACROSS_sink;
9178   }
9179   bool isSinkIter(const OMPDoacrossClause *C) {
9180     return C->getDependenceType() == OMPC_DOACROSS_sink_omp_cur_iteration;
9181   }
9182 };
9183 } // namespace
9184 /// Called on a for stmt to check and extract its iteration space
9185 /// for further processing (such as collapsing).
9186 static bool checkOpenMPIterationSpace(
9187     OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
9188     unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
9189     unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
9190     Expr *OrderedLoopCountExpr,
9191     Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
9192     llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,
9193     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9194   bool SupportsNonRectangular = !isOpenMPLoopTransformationDirective(DKind);
9195   // OpenMP [2.9.1, Canonical Loop Form]
9196   //   for (init-expr; test-expr; incr-expr) structured-block
9197   //   for (range-decl: range-expr) structured-block
9198   if (auto *CanonLoop = dyn_cast_or_null<OMPCanonicalLoop>(S))
9199     S = CanonLoop->getLoopStmt();
9200   auto *For = dyn_cast_or_null<ForStmt>(S);
9201   auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
9202   // Ranged for is supported only in OpenMP 5.0.
9203   if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) {
9204     SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
9205         << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
9206         << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
9207         << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
9208     if (TotalNestedLoopCount > 1) {
9209       if (CollapseLoopCountExpr && OrderedLoopCountExpr)
9210         SemaRef.Diag(DSA.getConstructLoc(),
9211                      diag::note_omp_collapse_ordered_expr)
9212             << 2 << CollapseLoopCountExpr->getSourceRange()
9213             << OrderedLoopCountExpr->getSourceRange();
9214       else if (CollapseLoopCountExpr)
9215         SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
9216                      diag::note_omp_collapse_ordered_expr)
9217             << 0 << CollapseLoopCountExpr->getSourceRange();
9218       else
9219         SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
9220                      diag::note_omp_collapse_ordered_expr)
9221             << 1 << OrderedLoopCountExpr->getSourceRange();
9222     }
9223     return true;
9224   }
9225   assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&
9226          "No loop body.");
9227   // Postpone analysis in dependent contexts for ranged for loops.
9228   if (CXXFor && SemaRef.CurContext->isDependentContext())
9229     return false;
9230 
9231   OpenMPIterationSpaceChecker ISC(SemaRef, SupportsNonRectangular, DSA,
9232                                   For ? For->getForLoc() : CXXFor->getForLoc());
9233 
9234   // Check init.
9235   Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt();
9236   if (ISC.checkAndSetInit(Init))
9237     return true;
9238 
9239   bool HasErrors = false;
9240 
9241   // Check loop variable's type.
9242   if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
9243     // OpenMP [2.6, Canonical Loop Form]
9244     // Var is one of the following:
9245     //   A variable of signed or unsigned integer type.
9246     //   For C++, a variable of a random access iterator type.
9247     //   For C, a variable of a pointer type.
9248     QualType VarType = LCDecl->getType().getNonReferenceType();
9249     if (!VarType->isDependentType() && !VarType->isIntegerType() &&
9250         !VarType->isPointerType() &&
9251         !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
9252       SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
9253           << SemaRef.getLangOpts().CPlusPlus;
9254       HasErrors = true;
9255     }
9256 
9257     // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
9258     // a Construct
9259     // The loop iteration variable(s) in the associated for-loop(s) of a for or
9260     // parallel for construct is (are) private.
9261     // The loop iteration variable in the associated for-loop of a simd
9262     // construct with just one associated for-loop is linear with a
9263     // constant-linear-step that is the increment of the associated for-loop.
9264     // Exclude loop var from the list of variables with implicitly defined data
9265     // sharing attributes.
9266     VarsWithImplicitDSA.erase(LCDecl);
9267 
9268     assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
9269 
9270     // Check test-expr.
9271     HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
9272 
9273     // Check incr-expr.
9274     HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
9275   }
9276 
9277   if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
9278     return HasErrors;
9279 
9280   // Build the loop's iteration space representation.
9281   ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
9282       DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
9283   ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
9284       ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
9285                              (isOpenMPWorksharingDirective(DKind) ||
9286                               isOpenMPGenericLoopDirective(DKind) ||
9287                               isOpenMPTaskLoopDirective(DKind) ||
9288                               isOpenMPDistributeDirective(DKind) ||
9289                               isOpenMPLoopTransformationDirective(DKind)),
9290                              Captures);
9291   ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
9292       ISC.buildCounterVar(Captures, DSA);
9293   ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
9294       ISC.buildPrivateCounterVar();
9295   ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
9296   ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
9297   ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
9298   ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
9299       ISC.getConditionSrcRange();
9300   ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
9301       ISC.getIncrementSrcRange();
9302   ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
9303   ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
9304       ISC.isStrictTestOp();
9305   std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
9306            ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
9307       ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
9308   ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
9309       ISC.buildFinalCondition(DSA.getCurScope());
9310   ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
9311       ISC.doesInitDependOnLC();
9312   ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
9313       ISC.doesCondDependOnLC();
9314   ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
9315       ISC.getLoopDependentIdx();
9316 
9317   HasErrors |=
9318       (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr ||
9319        ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr ||
9320        ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr ||
9321        ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr ||
9322        ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr ||
9323        ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr);
9324   if (!HasErrors && DSA.isOrderedRegion()) {
9325     if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
9326       if (CurrentNestedLoopCount <
9327           DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
9328         DSA.getOrderedRegionParam().second->setLoopNumIterations(
9329             CurrentNestedLoopCount,
9330             ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
9331         DSA.getOrderedRegionParam().second->setLoopCounter(
9332             CurrentNestedLoopCount,
9333             ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
9334       }
9335     }
9336     for (auto &Pair : DSA.getDoacrossDependClauses()) {
9337       auto *DependC = dyn_cast<OMPDependClause>(Pair.first);
9338       auto *DoacrossC = dyn_cast<OMPDoacrossClause>(Pair.first);
9339       unsigned NumLoops =
9340           DependC ? DependC->getNumLoops() : DoacrossC->getNumLoops();
9341       if (CurrentNestedLoopCount >= NumLoops) {
9342         // Erroneous case - clause has some problems.
9343         continue;
9344       }
9345       if (DependC && DependC->getDependencyKind() == OMPC_DEPEND_sink &&
9346           Pair.second.size() <= CurrentNestedLoopCount) {
9347         // Erroneous case - clause has some problems.
9348         DependC->setLoopData(CurrentNestedLoopCount, nullptr);
9349         continue;
9350       }
9351       OMPDoacrossKind ODK;
9352       if (DoacrossC && ODK.isSink(DoacrossC) &&
9353           Pair.second.size() <= CurrentNestedLoopCount) {
9354         // Erroneous case - clause has some problems.
9355         DoacrossC->setLoopData(CurrentNestedLoopCount, nullptr);
9356         continue;
9357       }
9358       Expr *CntValue;
9359       SourceLocation DepLoc =
9360           DependC ? DependC->getDependencyLoc() : DoacrossC->getDependenceLoc();
9361       if ((DependC && DependC->getDependencyKind() == OMPC_DEPEND_source) ||
9362           (DoacrossC && ODK.isSource(DoacrossC)))
9363         CntValue = ISC.buildOrderedLoopData(
9364             DSA.getCurScope(),
9365             ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9366             DepLoc);
9367       else if (DoacrossC && ODK.isSinkIter(DoacrossC)) {
9368         Expr *Cnt = SemaRef
9369                         .DefaultLvalueConversion(
9370                             ResultIterSpaces[CurrentNestedLoopCount].CounterVar)
9371                         .get();
9372         if (!Cnt)
9373           continue;
9374         // build CounterVar - 1
9375         Expr *Inc =
9376             SemaRef.ActOnIntegerConstant(DoacrossC->getColonLoc(), /*Val=*/1)
9377                 .get();
9378         CntValue = ISC.buildOrderedLoopData(
9379             DSA.getCurScope(),
9380             ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9381             DepLoc, Inc, clang::OO_Minus);
9382       } else
9383         CntValue = ISC.buildOrderedLoopData(
9384             DSA.getCurScope(),
9385             ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9386             DepLoc, Pair.second[CurrentNestedLoopCount].first,
9387             Pair.second[CurrentNestedLoopCount].second);
9388       if (DependC)
9389         DependC->setLoopData(CurrentNestedLoopCount, CntValue);
9390       else
9391         DoacrossC->setLoopData(CurrentNestedLoopCount, CntValue);
9392     }
9393   }
9394 
9395   return HasErrors;
9396 }
9397 
9398 /// Build 'VarRef = Start.
9399 static ExprResult
9400 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
9401                  ExprResult Start, bool IsNonRectangularLB,
9402                  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9403   // Build 'VarRef = Start.
9404   ExprResult NewStart = IsNonRectangularLB
9405                             ? Start.get()
9406                             : tryBuildCapture(SemaRef, Start.get(), Captures);
9407   if (!NewStart.isUsable())
9408     return ExprError();
9409   if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
9410                                    VarRef.get()->getType())) {
9411     NewStart = SemaRef.PerformImplicitConversion(
9412         NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
9413         /*AllowExplicit=*/true);
9414     if (!NewStart.isUsable())
9415       return ExprError();
9416   }
9417 
9418   ExprResult Init =
9419       SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
9420   return Init;
9421 }
9422 
9423 /// Build 'VarRef = Start + Iter * Step'.
9424 static ExprResult buildCounterUpdate(
9425     Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
9426     ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
9427     bool IsNonRectangularLB,
9428     llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
9429   // Add parentheses (for debugging purposes only).
9430   Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
9431   if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
9432       !Step.isUsable())
9433     return ExprError();
9434 
9435   ExprResult NewStep = Step;
9436   if (Captures)
9437     NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
9438   if (NewStep.isInvalid())
9439     return ExprError();
9440   ExprResult Update =
9441       SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
9442   if (!Update.isUsable())
9443     return ExprError();
9444 
9445   // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
9446   // 'VarRef = Start (+|-) Iter * Step'.
9447   if (!Start.isUsable())
9448     return ExprError();
9449   ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get());
9450   if (!NewStart.isUsable())
9451     return ExprError();
9452   if (Captures && !IsNonRectangularLB)
9453     NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
9454   if (NewStart.isInvalid())
9455     return ExprError();
9456 
9457   // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
9458   ExprResult SavedUpdate = Update;
9459   ExprResult UpdateVal;
9460   if (VarRef.get()->getType()->isOverloadableType() ||
9461       NewStart.get()->getType()->isOverloadableType() ||
9462       Update.get()->getType()->isOverloadableType()) {
9463     Sema::TentativeAnalysisScope Trap(SemaRef);
9464 
9465     Update =
9466         SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
9467     if (Update.isUsable()) {
9468       UpdateVal =
9469           SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
9470                              VarRef.get(), SavedUpdate.get());
9471       if (UpdateVal.isUsable()) {
9472         Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
9473                                             UpdateVal.get());
9474       }
9475     }
9476   }
9477 
9478   // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
9479   if (!Update.isUsable() || !UpdateVal.isUsable()) {
9480     Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
9481                                 NewStart.get(), SavedUpdate.get());
9482     if (!Update.isUsable())
9483       return ExprError();
9484 
9485     if (!SemaRef.Context.hasSameType(Update.get()->getType(),
9486                                      VarRef.get()->getType())) {
9487       Update = SemaRef.PerformImplicitConversion(
9488           Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
9489       if (!Update.isUsable())
9490         return ExprError();
9491     }
9492 
9493     Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
9494   }
9495   return Update;
9496 }
9497 
9498 /// Convert integer expression \a E to make it have at least \a Bits
9499 /// bits.
9500 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
9501   if (E == nullptr)
9502     return ExprError();
9503   ASTContext &C = SemaRef.Context;
9504   QualType OldType = E->getType();
9505   unsigned HasBits = C.getTypeSize(OldType);
9506   if (HasBits >= Bits)
9507     return ExprResult(E);
9508   // OK to convert to signed, because new type has more bits than old.
9509   QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
9510   return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
9511                                            true);
9512 }
9513 
9514 /// Check if the given expression \a E is a constant integer that fits
9515 /// into \a Bits bits.
9516 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
9517   if (E == nullptr)
9518     return false;
9519   if (std::optional<llvm::APSInt> Result =
9520           E->getIntegerConstantExpr(SemaRef.Context))
9521     return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits);
9522   return false;
9523 }
9524 
9525 /// Build preinits statement for the given declarations.
9526 static Stmt *buildPreInits(ASTContext &Context,
9527                            MutableArrayRef<Decl *> PreInits) {
9528   if (!PreInits.empty()) {
9529     return new (Context) DeclStmt(
9530         DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
9531         SourceLocation(), SourceLocation());
9532   }
9533   return nullptr;
9534 }
9535 
9536 /// Build preinits statement for the given declarations.
9537 static Stmt *
9538 buildPreInits(ASTContext &Context,
9539               const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9540   if (!Captures.empty()) {
9541     SmallVector<Decl *, 16> PreInits;
9542     for (const auto &Pair : Captures)
9543       PreInits.push_back(Pair.second->getDecl());
9544     return buildPreInits(Context, PreInits);
9545   }
9546   return nullptr;
9547 }
9548 
9549 /// Build postupdate expression for the given list of postupdates expressions.
9550 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
9551   Expr *PostUpdate = nullptr;
9552   if (!PostUpdates.empty()) {
9553     for (Expr *E : PostUpdates) {
9554       Expr *ConvE = S.BuildCStyleCastExpr(
9555                          E->getExprLoc(),
9556                          S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
9557                          E->getExprLoc(), E)
9558                         .get();
9559       PostUpdate = PostUpdate
9560                        ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
9561                                               PostUpdate, ConvE)
9562                              .get()
9563                        : ConvE;
9564     }
9565   }
9566   return PostUpdate;
9567 }
9568 
9569 /// Called on a for stmt to check itself and nested loops (if any).
9570 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
9571 /// number of collapsed loops otherwise.
9572 static unsigned
9573 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
9574                 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
9575                 DSAStackTy &DSA,
9576                 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
9577                 OMPLoopBasedDirective::HelperExprs &Built) {
9578   unsigned NestedLoopCount = 1;
9579   bool SupportsNonPerfectlyNested = (SemaRef.LangOpts.OpenMP >= 50) &&
9580                                     !isOpenMPLoopTransformationDirective(DKind);
9581 
9582   if (CollapseLoopCountExpr) {
9583     // Found 'collapse' clause - calculate collapse number.
9584     Expr::EvalResult Result;
9585     if (!CollapseLoopCountExpr->isValueDependent() &&
9586         CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
9587       NestedLoopCount = Result.Val.getInt().getLimitedValue();
9588     } else {
9589       Built.clear(/*Size=*/1);
9590       return 1;
9591     }
9592   }
9593   unsigned OrderedLoopCount = 1;
9594   if (OrderedLoopCountExpr) {
9595     // Found 'ordered' clause - calculate collapse number.
9596     Expr::EvalResult EVResult;
9597     if (!OrderedLoopCountExpr->isValueDependent() &&
9598         OrderedLoopCountExpr->EvaluateAsInt(EVResult,
9599                                             SemaRef.getASTContext())) {
9600       llvm::APSInt Result = EVResult.Val.getInt();
9601       if (Result.getLimitedValue() < NestedLoopCount) {
9602         SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
9603                      diag::err_omp_wrong_ordered_loop_count)
9604             << OrderedLoopCountExpr->getSourceRange();
9605         SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
9606                      diag::note_collapse_loop_count)
9607             << CollapseLoopCountExpr->getSourceRange();
9608       }
9609       OrderedLoopCount = Result.getLimitedValue();
9610     } else {
9611       Built.clear(/*Size=*/1);
9612       return 1;
9613     }
9614   }
9615   // This is helper routine for loop directives (e.g., 'for', 'simd',
9616   // 'for simd', etc.).
9617   llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
9618   unsigned NumLoops = std::max(OrderedLoopCount, NestedLoopCount);
9619   SmallVector<LoopIterationSpace, 4> IterSpaces(NumLoops);
9620   if (!OMPLoopBasedDirective::doForAllLoops(
9621           AStmt->IgnoreContainers(!isOpenMPLoopTransformationDirective(DKind)),
9622           SupportsNonPerfectlyNested, NumLoops,
9623           [DKind, &SemaRef, &DSA, NumLoops, NestedLoopCount,
9624            CollapseLoopCountExpr, OrderedLoopCountExpr, &VarsWithImplicitDSA,
9625            &IterSpaces, &Captures](unsigned Cnt, Stmt *CurStmt) {
9626             if (checkOpenMPIterationSpace(
9627                     DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
9628                     NumLoops, CollapseLoopCountExpr, OrderedLoopCountExpr,
9629                     VarsWithImplicitDSA, IterSpaces, Captures))
9630               return true;
9631             if (Cnt > 0 && Cnt >= NestedLoopCount &&
9632                 IterSpaces[Cnt].CounterVar) {
9633               // Handle initialization of captured loop iterator variables.
9634               auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
9635               if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
9636                 Captures[DRE] = DRE;
9637               }
9638             }
9639             return false;
9640           },
9641           [&SemaRef, &Captures](OMPLoopTransformationDirective *Transform) {
9642             Stmt *DependentPreInits = Transform->getPreInits();
9643             if (!DependentPreInits)
9644               return;
9645             for (Decl *C : cast<DeclStmt>(DependentPreInits)->getDeclGroup()) {
9646               auto *D = cast<VarDecl>(C);
9647               DeclRefExpr *Ref = buildDeclRefExpr(SemaRef, D, D->getType(),
9648                                                   Transform->getBeginLoc());
9649               Captures[Ref] = Ref;
9650             }
9651           }))
9652     return 0;
9653 
9654   Built.clear(/* size */ NestedLoopCount);
9655 
9656   if (SemaRef.CurContext->isDependentContext())
9657     return NestedLoopCount;
9658 
9659   // An example of what is generated for the following code:
9660   //
9661   //   #pragma omp simd collapse(2) ordered(2)
9662   //   for (i = 0; i < NI; ++i)
9663   //     for (k = 0; k < NK; ++k)
9664   //       for (j = J0; j < NJ; j+=2) {
9665   //         <loop body>
9666   //       }
9667   //
9668   // We generate the code below.
9669   // Note: the loop body may be outlined in CodeGen.
9670   // Note: some counters may be C++ classes, operator- is used to find number of
9671   // iterations and operator+= to calculate counter value.
9672   // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
9673   // or i64 is currently supported).
9674   //
9675   //   #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
9676   //   for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
9677   //     .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
9678   //     .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
9679   //     // similar updates for vars in clauses (e.g. 'linear')
9680   //     <loop body (using local i and j)>
9681   //   }
9682   //   i = NI; // assign final values of counters
9683   //   j = NJ;
9684   //
9685 
9686   // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
9687   // the iteration counts of the collapsed for loops.
9688   // Precondition tests if there is at least one iteration (all conditions are
9689   // true).
9690   auto PreCond = ExprResult(IterSpaces[0].PreCond);
9691   Expr *N0 = IterSpaces[0].NumIterations;
9692   ExprResult LastIteration32 =
9693       widenIterationCount(/*Bits=*/32,
9694                           SemaRef
9695                               .PerformImplicitConversion(
9696                                   N0->IgnoreImpCasts(), N0->getType(),
9697                                   Sema::AA_Converting, /*AllowExplicit=*/true)
9698                               .get(),
9699                           SemaRef);
9700   ExprResult LastIteration64 = widenIterationCount(
9701       /*Bits=*/64,
9702       SemaRef
9703           .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
9704                                      Sema::AA_Converting,
9705                                      /*AllowExplicit=*/true)
9706           .get(),
9707       SemaRef);
9708 
9709   if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
9710     return NestedLoopCount;
9711 
9712   ASTContext &C = SemaRef.Context;
9713   bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
9714 
9715   Scope *CurScope = DSA.getCurScope();
9716   for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
9717     if (PreCond.isUsable()) {
9718       PreCond =
9719           SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
9720                              PreCond.get(), IterSpaces[Cnt].PreCond);
9721     }
9722     Expr *N = IterSpaces[Cnt].NumIterations;
9723     SourceLocation Loc = N->getExprLoc();
9724     AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
9725     if (LastIteration32.isUsable())
9726       LastIteration32 = SemaRef.BuildBinOp(
9727           CurScope, Loc, BO_Mul, LastIteration32.get(),
9728           SemaRef
9729               .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
9730                                          Sema::AA_Converting,
9731                                          /*AllowExplicit=*/true)
9732               .get());
9733     if (LastIteration64.isUsable())
9734       LastIteration64 = SemaRef.BuildBinOp(
9735           CurScope, Loc, BO_Mul, LastIteration64.get(),
9736           SemaRef
9737               .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
9738                                          Sema::AA_Converting,
9739                                          /*AllowExplicit=*/true)
9740               .get());
9741   }
9742 
9743   // Choose either the 32-bit or 64-bit version.
9744   ExprResult LastIteration = LastIteration64;
9745   if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
9746       (LastIteration32.isUsable() &&
9747        C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
9748        (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
9749         fitsInto(
9750             /*Bits=*/32,
9751             LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
9752             LastIteration64.get(), SemaRef))))
9753     LastIteration = LastIteration32;
9754   QualType VType = LastIteration.get()->getType();
9755   QualType RealVType = VType;
9756   QualType StrideVType = VType;
9757   if (isOpenMPTaskLoopDirective(DKind)) {
9758     VType =
9759         SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
9760     StrideVType =
9761         SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
9762   }
9763 
9764   if (!LastIteration.isUsable())
9765     return 0;
9766 
9767   // Save the number of iterations.
9768   ExprResult NumIterations = LastIteration;
9769   {
9770     LastIteration = SemaRef.BuildBinOp(
9771         CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
9772         LastIteration.get(),
9773         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9774     if (!LastIteration.isUsable())
9775       return 0;
9776   }
9777 
9778   // Calculate the last iteration number beforehand instead of doing this on
9779   // each iteration. Do not do this if the number of iterations may be kfold-ed.
9780   bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context);
9781   ExprResult CalcLastIteration;
9782   if (!IsConstant) {
9783     ExprResult SaveRef =
9784         tryBuildCapture(SemaRef, LastIteration.get(), Captures);
9785     LastIteration = SaveRef;
9786 
9787     // Prepare SaveRef + 1.
9788     NumIterations = SemaRef.BuildBinOp(
9789         CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
9790         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9791     if (!NumIterations.isUsable())
9792       return 0;
9793   }
9794 
9795   SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
9796 
9797   // Build variables passed into runtime, necessary for worksharing directives.
9798   ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
9799   if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
9800       isOpenMPDistributeDirective(DKind) ||
9801       isOpenMPGenericLoopDirective(DKind) ||
9802       isOpenMPLoopTransformationDirective(DKind)) {
9803     // Lower bound variable, initialized with zero.
9804     VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
9805     LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
9806     SemaRef.AddInitializerToDecl(LBDecl,
9807                                  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9808                                  /*DirectInit*/ false);
9809 
9810     // Upper bound variable, initialized with last iteration number.
9811     VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
9812     UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
9813     SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
9814                                  /*DirectInit*/ false);
9815 
9816     // A 32-bit variable-flag where runtime returns 1 for the last iteration.
9817     // This will be used to implement clause 'lastprivate'.
9818     QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
9819     VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
9820     IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
9821     SemaRef.AddInitializerToDecl(ILDecl,
9822                                  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9823                                  /*DirectInit*/ false);
9824 
9825     // Stride variable returned by runtime (we initialize it to 1 by default).
9826     VarDecl *STDecl =
9827         buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
9828     ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
9829     SemaRef.AddInitializerToDecl(STDecl,
9830                                  SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
9831                                  /*DirectInit*/ false);
9832 
9833     // Build expression: UB = min(UB, LastIteration)
9834     // It is necessary for CodeGen of directives with static scheduling.
9835     ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
9836                                                 UB.get(), LastIteration.get());
9837     ExprResult CondOp = SemaRef.ActOnConditionalOp(
9838         LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
9839         LastIteration.get(), UB.get());
9840     EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
9841                              CondOp.get());
9842     EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
9843 
9844     // If we have a combined directive that combines 'distribute', 'for' or
9845     // 'simd' we need to be able to access the bounds of the schedule of the
9846     // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
9847     // by scheduling 'distribute' have to be passed to the schedule of 'for'.
9848     if (isOpenMPLoopBoundSharingDirective(DKind)) {
9849       // Lower bound variable, initialized with zero.
9850       VarDecl *CombLBDecl =
9851           buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
9852       CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
9853       SemaRef.AddInitializerToDecl(
9854           CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9855           /*DirectInit*/ false);
9856 
9857       // Upper bound variable, initialized with last iteration number.
9858       VarDecl *CombUBDecl =
9859           buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
9860       CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
9861       SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
9862                                    /*DirectInit*/ false);
9863 
9864       ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
9865           CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
9866       ExprResult CombCondOp =
9867           SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
9868                                      LastIteration.get(), CombUB.get());
9869       CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
9870                                    CombCondOp.get());
9871       CombEUB =
9872           SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
9873 
9874       const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
9875       // We expect to have at least 2 more parameters than the 'parallel'
9876       // directive does - the lower and upper bounds of the previous schedule.
9877       assert(CD->getNumParams() >= 4 &&
9878              "Unexpected number of parameters in loop combined directive");
9879 
9880       // Set the proper type for the bounds given what we learned from the
9881       // enclosed loops.
9882       ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
9883       ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
9884 
9885       // Previous lower and upper bounds are obtained from the region
9886       // parameters.
9887       PrevLB =
9888           buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
9889       PrevUB =
9890           buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
9891     }
9892   }
9893 
9894   // Build the iteration variable and its initialization before loop.
9895   ExprResult IV;
9896   ExprResult Init, CombInit;
9897   {
9898     VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
9899     IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
9900     Expr *RHS = (isOpenMPWorksharingDirective(DKind) ||
9901                  isOpenMPGenericLoopDirective(DKind) ||
9902                  isOpenMPTaskLoopDirective(DKind) ||
9903                  isOpenMPDistributeDirective(DKind) ||
9904                  isOpenMPLoopTransformationDirective(DKind))
9905                     ? LB.get()
9906                     : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
9907     Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
9908     Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
9909 
9910     if (isOpenMPLoopBoundSharingDirective(DKind)) {
9911       Expr *CombRHS =
9912           (isOpenMPWorksharingDirective(DKind) ||
9913            isOpenMPGenericLoopDirective(DKind) ||
9914            isOpenMPTaskLoopDirective(DKind) ||
9915            isOpenMPDistributeDirective(DKind))
9916               ? CombLB.get()
9917               : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
9918       CombInit =
9919           SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
9920       CombInit =
9921           SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
9922     }
9923   }
9924 
9925   bool UseStrictCompare =
9926       RealVType->hasUnsignedIntegerRepresentation() &&
9927       llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
9928         return LIS.IsStrictCompare;
9929       });
9930   // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
9931   // unsigned IV)) for worksharing loops.
9932   SourceLocation CondLoc = AStmt->getBeginLoc();
9933   Expr *BoundUB = UB.get();
9934   if (UseStrictCompare) {
9935     BoundUB =
9936         SemaRef
9937             .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
9938                         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9939             .get();
9940     BoundUB =
9941         SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
9942   }
9943   ExprResult Cond =
9944       (isOpenMPWorksharingDirective(DKind) ||
9945        isOpenMPGenericLoopDirective(DKind) ||
9946        isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind) ||
9947        isOpenMPLoopTransformationDirective(DKind))
9948           ? SemaRef.BuildBinOp(CurScope, CondLoc,
9949                                UseStrictCompare ? BO_LT : BO_LE, IV.get(),
9950                                BoundUB)
9951           : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
9952                                NumIterations.get());
9953   ExprResult CombDistCond;
9954   if (isOpenMPLoopBoundSharingDirective(DKind)) {
9955     CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
9956                                       NumIterations.get());
9957   }
9958 
9959   ExprResult CombCond;
9960   if (isOpenMPLoopBoundSharingDirective(DKind)) {
9961     Expr *BoundCombUB = CombUB.get();
9962     if (UseStrictCompare) {
9963       BoundCombUB =
9964           SemaRef
9965               .BuildBinOp(
9966                   CurScope, CondLoc, BO_Add, BoundCombUB,
9967                   SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9968               .get();
9969       BoundCombUB =
9970           SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
9971               .get();
9972     }
9973     CombCond =
9974         SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
9975                            IV.get(), BoundCombUB);
9976   }
9977   // Loop increment (IV = IV + 1)
9978   SourceLocation IncLoc = AStmt->getBeginLoc();
9979   ExprResult Inc =
9980       SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
9981                          SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
9982   if (!Inc.isUsable())
9983     return 0;
9984   Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
9985   Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
9986   if (!Inc.isUsable())
9987     return 0;
9988 
9989   // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
9990   // Used for directives with static scheduling.
9991   // In combined construct, add combined version that use CombLB and CombUB
9992   // base variables for the update
9993   ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
9994   if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
9995       isOpenMPGenericLoopDirective(DKind) ||
9996       isOpenMPDistributeDirective(DKind) ||
9997       isOpenMPLoopTransformationDirective(DKind)) {
9998     // LB + ST
9999     NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
10000     if (!NextLB.isUsable())
10001       return 0;
10002     // LB = LB + ST
10003     NextLB =
10004         SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
10005     NextLB =
10006         SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
10007     if (!NextLB.isUsable())
10008       return 0;
10009     // UB + ST
10010     NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
10011     if (!NextUB.isUsable())
10012       return 0;
10013     // UB = UB + ST
10014     NextUB =
10015         SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
10016     NextUB =
10017         SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
10018     if (!NextUB.isUsable())
10019       return 0;
10020     if (isOpenMPLoopBoundSharingDirective(DKind)) {
10021       CombNextLB =
10022           SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
10023       if (!NextLB.isUsable())
10024         return 0;
10025       // LB = LB + ST
10026       CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
10027                                       CombNextLB.get());
10028       CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
10029                                                /*DiscardedValue*/ false);
10030       if (!CombNextLB.isUsable())
10031         return 0;
10032       // UB + ST
10033       CombNextUB =
10034           SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
10035       if (!CombNextUB.isUsable())
10036         return 0;
10037       // UB = UB + ST
10038       CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
10039                                       CombNextUB.get());
10040       CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
10041                                                /*DiscardedValue*/ false);
10042       if (!CombNextUB.isUsable())
10043         return 0;
10044     }
10045   }
10046 
10047   // Create increment expression for distribute loop when combined in a same
10048   // directive with for as IV = IV + ST; ensure upper bound expression based
10049   // on PrevUB instead of NumIterations - used to implement 'for' when found
10050   // in combination with 'distribute', like in 'distribute parallel for'
10051   SourceLocation DistIncLoc = AStmt->getBeginLoc();
10052   ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
10053   if (isOpenMPLoopBoundSharingDirective(DKind)) {
10054     DistCond = SemaRef.BuildBinOp(
10055         CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
10056     assert(DistCond.isUsable() && "distribute cond expr was not built");
10057 
10058     DistInc =
10059         SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
10060     assert(DistInc.isUsable() && "distribute inc expr was not built");
10061     DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
10062                                  DistInc.get());
10063     DistInc =
10064         SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
10065     assert(DistInc.isUsable() && "distribute inc expr was not built");
10066 
10067     // Build expression: UB = min(UB, prevUB) for #for in composite or combined
10068     // construct
10069     ExprResult NewPrevUB = PrevUB;
10070     SourceLocation DistEUBLoc = AStmt->getBeginLoc();
10071     if (!SemaRef.Context.hasSameType(UB.get()->getType(),
10072                                      PrevUB.get()->getType())) {
10073       NewPrevUB = SemaRef.BuildCStyleCastExpr(
10074           DistEUBLoc,
10075           SemaRef.Context.getTrivialTypeSourceInfo(UB.get()->getType()),
10076           DistEUBLoc, NewPrevUB.get());
10077       if (!NewPrevUB.isUsable())
10078         return 0;
10079     }
10080     ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT,
10081                                                 UB.get(), NewPrevUB.get());
10082     ExprResult CondOp = SemaRef.ActOnConditionalOp(
10083         DistEUBLoc, DistEUBLoc, IsUBGreater.get(), NewPrevUB.get(), UB.get());
10084     PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
10085                                  CondOp.get());
10086     PrevEUB =
10087         SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
10088 
10089     // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
10090     // parallel for is in combination with a distribute directive with
10091     // schedule(static, 1)
10092     Expr *BoundPrevUB = PrevUB.get();
10093     if (UseStrictCompare) {
10094       BoundPrevUB =
10095           SemaRef
10096               .BuildBinOp(
10097                   CurScope, CondLoc, BO_Add, BoundPrevUB,
10098                   SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
10099               .get();
10100       BoundPrevUB =
10101           SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
10102               .get();
10103     }
10104     ParForInDistCond =
10105         SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
10106                            IV.get(), BoundPrevUB);
10107   }
10108 
10109   // Build updates and final values of the loop counters.
10110   bool HasErrors = false;
10111   Built.Counters.resize(NestedLoopCount);
10112   Built.Inits.resize(NestedLoopCount);
10113   Built.Updates.resize(NestedLoopCount);
10114   Built.Finals.resize(NestedLoopCount);
10115   Built.DependentCounters.resize(NestedLoopCount);
10116   Built.DependentInits.resize(NestedLoopCount);
10117   Built.FinalsConditions.resize(NestedLoopCount);
10118   {
10119     // We implement the following algorithm for obtaining the
10120     // original loop iteration variable values based on the
10121     // value of the collapsed loop iteration variable IV.
10122     //
10123     // Let n+1 be the number of collapsed loops in the nest.
10124     // Iteration variables (I0, I1, .... In)
10125     // Iteration counts (N0, N1, ... Nn)
10126     //
10127     // Acc = IV;
10128     //
10129     // To compute Ik for loop k, 0 <= k <= n, generate:
10130     //    Prod = N(k+1) * N(k+2) * ... * Nn;
10131     //    Ik = Acc / Prod;
10132     //    Acc -= Ik * Prod;
10133     //
10134     ExprResult Acc = IV;
10135     for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
10136       LoopIterationSpace &IS = IterSpaces[Cnt];
10137       SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
10138       ExprResult Iter;
10139 
10140       // Compute prod
10141       ExprResult Prod = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
10142       for (unsigned int K = Cnt + 1; K < NestedLoopCount; ++K)
10143         Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
10144                                   IterSpaces[K].NumIterations);
10145 
10146       // Iter = Acc / Prod
10147       // If there is at least one more inner loop to avoid
10148       // multiplication by 1.
10149       if (Cnt + 1 < NestedLoopCount)
10150         Iter =
10151             SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, Acc.get(), Prod.get());
10152       else
10153         Iter = Acc;
10154       if (!Iter.isUsable()) {
10155         HasErrors = true;
10156         break;
10157       }
10158 
10159       // Update Acc:
10160       // Acc -= Iter * Prod
10161       // Check if there is at least one more inner loop to avoid
10162       // multiplication by 1.
10163       if (Cnt + 1 < NestedLoopCount)
10164         Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Iter.get(),
10165                                   Prod.get());
10166       else
10167         Prod = Iter;
10168       Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, Acc.get(), Prod.get());
10169 
10170       // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
10171       auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
10172       DeclRefExpr *CounterVar = buildDeclRefExpr(
10173           SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
10174           /*RefersToCapture=*/true);
10175       ExprResult Init =
10176           buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
10177                            IS.CounterInit, IS.IsNonRectangularLB, Captures);
10178       if (!Init.isUsable()) {
10179         HasErrors = true;
10180         break;
10181       }
10182       ExprResult Update = buildCounterUpdate(
10183           SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
10184           IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
10185       if (!Update.isUsable()) {
10186         HasErrors = true;
10187         break;
10188       }
10189 
10190       // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
10191       ExprResult Final =
10192           buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
10193                              IS.CounterInit, IS.NumIterations, IS.CounterStep,
10194                              IS.Subtract, IS.IsNonRectangularLB, &Captures);
10195       if (!Final.isUsable()) {
10196         HasErrors = true;
10197         break;
10198       }
10199 
10200       if (!Update.isUsable() || !Final.isUsable()) {
10201         HasErrors = true;
10202         break;
10203       }
10204       // Save results
10205       Built.Counters[Cnt] = IS.CounterVar;
10206       Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
10207       Built.Inits[Cnt] = Init.get();
10208       Built.Updates[Cnt] = Update.get();
10209       Built.Finals[Cnt] = Final.get();
10210       Built.DependentCounters[Cnt] = nullptr;
10211       Built.DependentInits[Cnt] = nullptr;
10212       Built.FinalsConditions[Cnt] = nullptr;
10213       if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
10214         Built.DependentCounters[Cnt] = Built.Counters[IS.LoopDependentIdx - 1];
10215         Built.DependentInits[Cnt] = Built.Inits[IS.LoopDependentIdx - 1];
10216         Built.FinalsConditions[Cnt] = IS.FinalCondition;
10217       }
10218     }
10219   }
10220 
10221   if (HasErrors)
10222     return 0;
10223 
10224   // Save results
10225   Built.IterationVarRef = IV.get();
10226   Built.LastIteration = LastIteration.get();
10227   Built.NumIterations = NumIterations.get();
10228   Built.CalcLastIteration = SemaRef
10229                                 .ActOnFinishFullExpr(CalcLastIteration.get(),
10230                                                      /*DiscardedValue=*/false)
10231                                 .get();
10232   Built.PreCond = PreCond.get();
10233   Built.PreInits = buildPreInits(C, Captures);
10234   Built.Cond = Cond.get();
10235   Built.Init = Init.get();
10236   Built.Inc = Inc.get();
10237   Built.LB = LB.get();
10238   Built.UB = UB.get();
10239   Built.IL = IL.get();
10240   Built.ST = ST.get();
10241   Built.EUB = EUB.get();
10242   Built.NLB = NextLB.get();
10243   Built.NUB = NextUB.get();
10244   Built.PrevLB = PrevLB.get();
10245   Built.PrevUB = PrevUB.get();
10246   Built.DistInc = DistInc.get();
10247   Built.PrevEUB = PrevEUB.get();
10248   Built.DistCombinedFields.LB = CombLB.get();
10249   Built.DistCombinedFields.UB = CombUB.get();
10250   Built.DistCombinedFields.EUB = CombEUB.get();
10251   Built.DistCombinedFields.Init = CombInit.get();
10252   Built.DistCombinedFields.Cond = CombCond.get();
10253   Built.DistCombinedFields.NLB = CombNextLB.get();
10254   Built.DistCombinedFields.NUB = CombNextUB.get();
10255   Built.DistCombinedFields.DistCond = CombDistCond.get();
10256   Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
10257 
10258   return NestedLoopCount;
10259 }
10260 
10261 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
10262   auto CollapseClauses =
10263       OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
10264   if (CollapseClauses.begin() != CollapseClauses.end())
10265     return (*CollapseClauses.begin())->getNumForLoops();
10266   return nullptr;
10267 }
10268 
10269 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
10270   auto OrderedClauses =
10271       OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
10272   if (OrderedClauses.begin() != OrderedClauses.end())
10273     return (*OrderedClauses.begin())->getNumForLoops();
10274   return nullptr;
10275 }
10276 
10277 static bool checkSimdlenSafelenSpecified(Sema &S,
10278                                          const ArrayRef<OMPClause *> Clauses) {
10279   const OMPSafelenClause *Safelen = nullptr;
10280   const OMPSimdlenClause *Simdlen = nullptr;
10281 
10282   for (const OMPClause *Clause : Clauses) {
10283     if (Clause->getClauseKind() == OMPC_safelen)
10284       Safelen = cast<OMPSafelenClause>(Clause);
10285     else if (Clause->getClauseKind() == OMPC_simdlen)
10286       Simdlen = cast<OMPSimdlenClause>(Clause);
10287     if (Safelen && Simdlen)
10288       break;
10289   }
10290 
10291   if (Simdlen && Safelen) {
10292     const Expr *SimdlenLength = Simdlen->getSimdlen();
10293     const Expr *SafelenLength = Safelen->getSafelen();
10294     if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
10295         SimdlenLength->isInstantiationDependent() ||
10296         SimdlenLength->containsUnexpandedParameterPack())
10297       return false;
10298     if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
10299         SafelenLength->isInstantiationDependent() ||
10300         SafelenLength->containsUnexpandedParameterPack())
10301       return false;
10302     Expr::EvalResult SimdlenResult, SafelenResult;
10303     SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
10304     SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
10305     llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
10306     llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
10307     // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
10308     // If both simdlen and safelen clauses are specified, the value of the
10309     // simdlen parameter must be less than or equal to the value of the safelen
10310     // parameter.
10311     if (SimdlenRes > SafelenRes) {
10312       S.Diag(SimdlenLength->getExprLoc(),
10313              diag::err_omp_wrong_simdlen_safelen_values)
10314           << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
10315       return true;
10316     }
10317   }
10318   return false;
10319 }
10320 
10321 StmtResult
10322 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
10323                                SourceLocation StartLoc, SourceLocation EndLoc,
10324                                VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10325   if (!AStmt)
10326     return StmtError();
10327 
10328   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10329   OMPLoopBasedDirective::HelperExprs B;
10330   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10331   // define the nested loops number.
10332   unsigned NestedLoopCount = checkOpenMPLoop(
10333       OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
10334       AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
10335   if (NestedLoopCount == 0)
10336     return StmtError();
10337 
10338   assert((CurContext->isDependentContext() || B.builtAll()) &&
10339          "omp simd loop exprs were not built");
10340 
10341   if (!CurContext->isDependentContext()) {
10342     // Finalize the clauses that need pre-built expressions for CodeGen.
10343     for (OMPClause *C : Clauses) {
10344       if (auto *LC = dyn_cast<OMPLinearClause>(C))
10345         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10346                                      B.NumIterations, *this, CurScope,
10347                                      DSAStack))
10348           return StmtError();
10349     }
10350   }
10351 
10352   if (checkSimdlenSafelenSpecified(*this, Clauses))
10353     return StmtError();
10354 
10355   setFunctionHasBranchProtectedScope();
10356   return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
10357                                   Clauses, AStmt, B);
10358 }
10359 
10360 StmtResult
10361 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
10362                               SourceLocation StartLoc, SourceLocation EndLoc,
10363                               VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10364   if (!AStmt)
10365     return StmtError();
10366 
10367   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10368   OMPLoopBasedDirective::HelperExprs B;
10369   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10370   // define the nested loops number.
10371   unsigned NestedLoopCount = checkOpenMPLoop(
10372       OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
10373       AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
10374   if (NestedLoopCount == 0)
10375     return StmtError();
10376 
10377   assert((CurContext->isDependentContext() || B.builtAll()) &&
10378          "omp for loop exprs were not built");
10379 
10380   if (!CurContext->isDependentContext()) {
10381     // Finalize the clauses that need pre-built expressions for CodeGen.
10382     for (OMPClause *C : Clauses) {
10383       if (auto *LC = dyn_cast<OMPLinearClause>(C))
10384         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10385                                      B.NumIterations, *this, CurScope,
10386                                      DSAStack))
10387           return StmtError();
10388     }
10389   }
10390 
10391   setFunctionHasBranchProtectedScope();
10392   return OMPForDirective::Create(
10393       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10394       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10395 }
10396 
10397 StmtResult Sema::ActOnOpenMPForSimdDirective(
10398     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10399     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10400   if (!AStmt)
10401     return StmtError();
10402 
10403   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10404   OMPLoopBasedDirective::HelperExprs B;
10405   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10406   // define the nested loops number.
10407   unsigned NestedLoopCount =
10408       checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
10409                       getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
10410                       VarsWithImplicitDSA, B);
10411   if (NestedLoopCount == 0)
10412     return StmtError();
10413 
10414   assert((CurContext->isDependentContext() || B.builtAll()) &&
10415          "omp for simd loop exprs were not built");
10416 
10417   if (!CurContext->isDependentContext()) {
10418     // Finalize the clauses that need pre-built expressions for CodeGen.
10419     for (OMPClause *C : Clauses) {
10420       if (auto *LC = dyn_cast<OMPLinearClause>(C))
10421         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10422                                      B.NumIterations, *this, CurScope,
10423                                      DSAStack))
10424           return StmtError();
10425     }
10426   }
10427 
10428   if (checkSimdlenSafelenSpecified(*this, Clauses))
10429     return StmtError();
10430 
10431   setFunctionHasBranchProtectedScope();
10432   return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
10433                                      Clauses, AStmt, B);
10434 }
10435 
10436 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
10437                                               Stmt *AStmt,
10438                                               SourceLocation StartLoc,
10439                                               SourceLocation EndLoc) {
10440   if (!AStmt)
10441     return StmtError();
10442 
10443   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10444   auto BaseStmt = AStmt;
10445   while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
10446     BaseStmt = CS->getCapturedStmt();
10447   if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
10448     auto S = C->children();
10449     if (S.begin() == S.end())
10450       return StmtError();
10451     // All associated statements must be '#pragma omp section' except for
10452     // the first one.
10453     for (Stmt *SectionStmt : llvm::drop_begin(S)) {
10454       if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
10455         if (SectionStmt)
10456           Diag(SectionStmt->getBeginLoc(),
10457                diag::err_omp_sections_substmt_not_section);
10458         return StmtError();
10459       }
10460       cast<OMPSectionDirective>(SectionStmt)
10461           ->setHasCancel(DSAStack->isCancelRegion());
10462     }
10463   } else {
10464     Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
10465     return StmtError();
10466   }
10467 
10468   setFunctionHasBranchProtectedScope();
10469 
10470   return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10471                                       DSAStack->getTaskgroupReductionRef(),
10472                                       DSAStack->isCancelRegion());
10473 }
10474 
10475 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
10476                                              SourceLocation StartLoc,
10477                                              SourceLocation EndLoc) {
10478   if (!AStmt)
10479     return StmtError();
10480 
10481   setFunctionHasBranchProtectedScope();
10482   DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
10483 
10484   return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
10485                                      DSAStack->isCancelRegion());
10486 }
10487 
10488 static Expr *getDirectCallExpr(Expr *E) {
10489   E = E->IgnoreParenCasts()->IgnoreImplicit();
10490   if (auto *CE = dyn_cast<CallExpr>(E))
10491     if (CE->getDirectCallee())
10492       return E;
10493   return nullptr;
10494 }
10495 
10496 StmtResult Sema::ActOnOpenMPDispatchDirective(ArrayRef<OMPClause *> Clauses,
10497                                               Stmt *AStmt,
10498                                               SourceLocation StartLoc,
10499                                               SourceLocation EndLoc) {
10500   if (!AStmt)
10501     return StmtError();
10502 
10503   Stmt *S = cast<CapturedStmt>(AStmt)->getCapturedStmt();
10504 
10505   // 5.1 OpenMP
10506   // expression-stmt : an expression statement with one of the following forms:
10507   //   expression = target-call ( [expression-list] );
10508   //   target-call ( [expression-list] );
10509 
10510   SourceLocation TargetCallLoc;
10511 
10512   if (!CurContext->isDependentContext()) {
10513     Expr *TargetCall = nullptr;
10514 
10515     auto *E = dyn_cast<Expr>(S);
10516     if (!E) {
10517       Diag(S->getBeginLoc(), diag::err_omp_dispatch_statement_call);
10518       return StmtError();
10519     }
10520 
10521     E = E->IgnoreParenCasts()->IgnoreImplicit();
10522 
10523     if (auto *BO = dyn_cast<BinaryOperator>(E)) {
10524       if (BO->getOpcode() == BO_Assign)
10525         TargetCall = getDirectCallExpr(BO->getRHS());
10526     } else {
10527       if (auto *COCE = dyn_cast<CXXOperatorCallExpr>(E))
10528         if (COCE->getOperator() == OO_Equal)
10529           TargetCall = getDirectCallExpr(COCE->getArg(1));
10530       if (!TargetCall)
10531         TargetCall = getDirectCallExpr(E);
10532     }
10533     if (!TargetCall) {
10534       Diag(E->getBeginLoc(), diag::err_omp_dispatch_statement_call);
10535       return StmtError();
10536     }
10537     TargetCallLoc = TargetCall->getExprLoc();
10538   }
10539 
10540   setFunctionHasBranchProtectedScope();
10541 
10542   return OMPDispatchDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10543                                       TargetCallLoc);
10544 }
10545 
10546 static bool checkGenericLoopLastprivate(Sema &S, ArrayRef<OMPClause *> Clauses,
10547                                         OpenMPDirectiveKind K,
10548                                         DSAStackTy *Stack) {
10549   bool ErrorFound = false;
10550   for (OMPClause *C : Clauses) {
10551     if (auto *LPC = dyn_cast<OMPLastprivateClause>(C)) {
10552       for (Expr *RefExpr : LPC->varlists()) {
10553         SourceLocation ELoc;
10554         SourceRange ERange;
10555         Expr *SimpleRefExpr = RefExpr;
10556         auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
10557         if (ValueDecl *D = Res.first) {
10558           auto &&Info = Stack->isLoopControlVariable(D);
10559           if (!Info.first) {
10560             S.Diag(ELoc, diag::err_omp_lastprivate_loop_var_non_loop_iteration)
10561                 << getOpenMPDirectiveName(K);
10562             ErrorFound = true;
10563           }
10564         }
10565       }
10566     }
10567   }
10568   return ErrorFound;
10569 }
10570 
10571 StmtResult Sema::ActOnOpenMPGenericLoopDirective(
10572     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10573     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10574   if (!AStmt)
10575     return StmtError();
10576 
10577   // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10578   // A list item may not appear in a lastprivate clause unless it is the
10579   // loop iteration variable of a loop that is associated with the construct.
10580   if (checkGenericLoopLastprivate(*this, Clauses, OMPD_loop, DSAStack))
10581     return StmtError();
10582 
10583   auto *CS = cast<CapturedStmt>(AStmt);
10584   // 1.2.2 OpenMP Language Terminology
10585   // Structured block - An executable statement with a single entry at the
10586   // top and a single exit at the bottom.
10587   // The point of exit cannot be a branch out of the structured block.
10588   // longjmp() and throw() must not violate the entry/exit criteria.
10589   CS->getCapturedDecl()->setNothrow();
10590 
10591   OMPLoopDirective::HelperExprs B;
10592   // In presence of clause 'collapse', it will define the nested loops number.
10593   unsigned NestedLoopCount = checkOpenMPLoop(
10594       OMPD_loop, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
10595       AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
10596   if (NestedLoopCount == 0)
10597     return StmtError();
10598 
10599   assert((CurContext->isDependentContext() || B.builtAll()) &&
10600          "omp loop exprs were not built");
10601 
10602   setFunctionHasBranchProtectedScope();
10603   return OMPGenericLoopDirective::Create(Context, StartLoc, EndLoc,
10604                                          NestedLoopCount, Clauses, AStmt, B);
10605 }
10606 
10607 StmtResult Sema::ActOnOpenMPTeamsGenericLoopDirective(
10608     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10609     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10610   if (!AStmt)
10611     return StmtError();
10612 
10613   // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10614   // A list item may not appear in a lastprivate clause unless it is the
10615   // loop iteration variable of a loop that is associated with the construct.
10616   if (checkGenericLoopLastprivate(*this, Clauses, OMPD_teams_loop, DSAStack))
10617     return StmtError();
10618 
10619   auto *CS = cast<CapturedStmt>(AStmt);
10620   // 1.2.2 OpenMP Language Terminology
10621   // Structured block - An executable statement with a single entry at the
10622   // top and a single exit at the bottom.
10623   // The point of exit cannot be a branch out of the structured block.
10624   // longjmp() and throw() must not violate the entry/exit criteria.
10625   CS->getCapturedDecl()->setNothrow();
10626   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_loop);
10627        ThisCaptureLevel > 1; --ThisCaptureLevel) {
10628     CS = cast<CapturedStmt>(CS->getCapturedStmt());
10629     // 1.2.2 OpenMP Language Terminology
10630     // Structured block - An executable statement with a single entry at the
10631     // top and a single exit at the bottom.
10632     // The point of exit cannot be a branch out of the structured block.
10633     // longjmp() and throw() must not violate the entry/exit criteria.
10634     CS->getCapturedDecl()->setNothrow();
10635   }
10636 
10637   OMPLoopDirective::HelperExprs B;
10638   // In presence of clause 'collapse', it will define the nested loops number.
10639   unsigned NestedLoopCount =
10640       checkOpenMPLoop(OMPD_teams_loop, getCollapseNumberExpr(Clauses),
10641                       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10642                       VarsWithImplicitDSA, B);
10643   if (NestedLoopCount == 0)
10644     return StmtError();
10645 
10646   assert((CurContext->isDependentContext() || B.builtAll()) &&
10647          "omp loop exprs were not built");
10648 
10649   setFunctionHasBranchProtectedScope();
10650   DSAStack->setParentTeamsRegionLoc(StartLoc);
10651 
10652   return OMPTeamsGenericLoopDirective::Create(
10653       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10654 }
10655 
10656 StmtResult Sema::ActOnOpenMPTargetTeamsGenericLoopDirective(
10657     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10658     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10659   if (!AStmt)
10660     return StmtError();
10661 
10662   // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10663   // A list item may not appear in a lastprivate clause unless it is the
10664   // loop iteration variable of a loop that is associated with the construct.
10665   if (checkGenericLoopLastprivate(*this, Clauses, OMPD_target_teams_loop,
10666                                   DSAStack))
10667     return StmtError();
10668 
10669   auto *CS = cast<CapturedStmt>(AStmt);
10670   // 1.2.2 OpenMP Language Terminology
10671   // Structured block - An executable statement with a single entry at the
10672   // top and a single exit at the bottom.
10673   // The point of exit cannot be a branch out of the structured block.
10674   // longjmp() and throw() must not violate the entry/exit criteria.
10675   CS->getCapturedDecl()->setNothrow();
10676   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams_loop);
10677        ThisCaptureLevel > 1; --ThisCaptureLevel) {
10678     CS = cast<CapturedStmt>(CS->getCapturedStmt());
10679     // 1.2.2 OpenMP Language Terminology
10680     // Structured block - An executable statement with a single entry at the
10681     // top and a single exit at the bottom.
10682     // The point of exit cannot be a branch out of the structured block.
10683     // longjmp() and throw() must not violate the entry/exit criteria.
10684     CS->getCapturedDecl()->setNothrow();
10685   }
10686 
10687   OMPLoopDirective::HelperExprs B;
10688   // In presence of clause 'collapse', it will define the nested loops number.
10689   unsigned NestedLoopCount =
10690       checkOpenMPLoop(OMPD_target_teams_loop, getCollapseNumberExpr(Clauses),
10691                       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10692                       VarsWithImplicitDSA, B);
10693   if (NestedLoopCount == 0)
10694     return StmtError();
10695 
10696   assert((CurContext->isDependentContext() || B.builtAll()) &&
10697          "omp loop exprs were not built");
10698 
10699   setFunctionHasBranchProtectedScope();
10700 
10701   return OMPTargetTeamsGenericLoopDirective::Create(
10702       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10703 }
10704 
10705 StmtResult Sema::ActOnOpenMPParallelGenericLoopDirective(
10706     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10707     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10708   if (!AStmt)
10709     return StmtError();
10710 
10711   // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10712   // A list item may not appear in a lastprivate clause unless it is the
10713   // loop iteration variable of a loop that is associated with the construct.
10714   if (checkGenericLoopLastprivate(*this, Clauses, OMPD_parallel_loop, DSAStack))
10715     return StmtError();
10716 
10717   auto *CS = cast<CapturedStmt>(AStmt);
10718   // 1.2.2 OpenMP Language Terminology
10719   // Structured block - An executable statement with a single entry at the
10720   // top and a single exit at the bottom.
10721   // The point of exit cannot be a branch out of the structured block.
10722   // longjmp() and throw() must not violate the entry/exit criteria.
10723   CS->getCapturedDecl()->setNothrow();
10724   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_parallel_loop);
10725        ThisCaptureLevel > 1; --ThisCaptureLevel) {
10726     CS = cast<CapturedStmt>(CS->getCapturedStmt());
10727     // 1.2.2 OpenMP Language Terminology
10728     // Structured block - An executable statement with a single entry at the
10729     // top and a single exit at the bottom.
10730     // The point of exit cannot be a branch out of the structured block.
10731     // longjmp() and throw() must not violate the entry/exit criteria.
10732     CS->getCapturedDecl()->setNothrow();
10733   }
10734 
10735   OMPLoopDirective::HelperExprs B;
10736   // In presence of clause 'collapse', it will define the nested loops number.
10737   unsigned NestedLoopCount =
10738       checkOpenMPLoop(OMPD_parallel_loop, getCollapseNumberExpr(Clauses),
10739                       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10740                       VarsWithImplicitDSA, B);
10741   if (NestedLoopCount == 0)
10742     return StmtError();
10743 
10744   assert((CurContext->isDependentContext() || B.builtAll()) &&
10745          "omp loop exprs were not built");
10746 
10747   setFunctionHasBranchProtectedScope();
10748 
10749   return OMPParallelGenericLoopDirective::Create(
10750       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10751 }
10752 
10753 StmtResult Sema::ActOnOpenMPTargetParallelGenericLoopDirective(
10754     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10755     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10756   if (!AStmt)
10757     return StmtError();
10758 
10759   // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10760   // A list item may not appear in a lastprivate clause unless it is the
10761   // loop iteration variable of a loop that is associated with the construct.
10762   if (checkGenericLoopLastprivate(*this, Clauses, OMPD_target_parallel_loop,
10763                                   DSAStack))
10764     return StmtError();
10765 
10766   auto *CS = cast<CapturedStmt>(AStmt);
10767   // 1.2.2 OpenMP Language Terminology
10768   // Structured block - An executable statement with a single entry at the
10769   // top and a single exit at the bottom.
10770   // The point of exit cannot be a branch out of the structured block.
10771   // longjmp() and throw() must not violate the entry/exit criteria.
10772   CS->getCapturedDecl()->setNothrow();
10773   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_loop);
10774        ThisCaptureLevel > 1; --ThisCaptureLevel) {
10775     CS = cast<CapturedStmt>(CS->getCapturedStmt());
10776     // 1.2.2 OpenMP Language Terminology
10777     // Structured block - An executable statement with a single entry at the
10778     // top and a single exit at the bottom.
10779     // The point of exit cannot be a branch out of the structured block.
10780     // longjmp() and throw() must not violate the entry/exit criteria.
10781     CS->getCapturedDecl()->setNothrow();
10782   }
10783 
10784   OMPLoopDirective::HelperExprs B;
10785   // In presence of clause 'collapse', it will define the nested loops number.
10786   unsigned NestedLoopCount =
10787       checkOpenMPLoop(OMPD_target_parallel_loop, getCollapseNumberExpr(Clauses),
10788                       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10789                       VarsWithImplicitDSA, B);
10790   if (NestedLoopCount == 0)
10791     return StmtError();
10792 
10793   assert((CurContext->isDependentContext() || B.builtAll()) &&
10794          "omp loop exprs were not built");
10795 
10796   setFunctionHasBranchProtectedScope();
10797 
10798   return OMPTargetParallelGenericLoopDirective::Create(
10799       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10800 }
10801 
10802 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
10803                                             Stmt *AStmt,
10804                                             SourceLocation StartLoc,
10805                                             SourceLocation EndLoc) {
10806   if (!AStmt)
10807     return StmtError();
10808 
10809   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10810 
10811   setFunctionHasBranchProtectedScope();
10812 
10813   // OpenMP [2.7.3, single Construct, Restrictions]
10814   // The copyprivate clause must not be used with the nowait clause.
10815   const OMPClause *Nowait = nullptr;
10816   const OMPClause *Copyprivate = nullptr;
10817   for (const OMPClause *Clause : Clauses) {
10818     if (Clause->getClauseKind() == OMPC_nowait)
10819       Nowait = Clause;
10820     else if (Clause->getClauseKind() == OMPC_copyprivate)
10821       Copyprivate = Clause;
10822     if (Copyprivate && Nowait) {
10823       Diag(Copyprivate->getBeginLoc(),
10824            diag::err_omp_single_copyprivate_with_nowait);
10825       Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
10826       return StmtError();
10827     }
10828   }
10829 
10830   return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10831 }
10832 
10833 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
10834                                             SourceLocation StartLoc,
10835                                             SourceLocation EndLoc) {
10836   if (!AStmt)
10837     return StmtError();
10838 
10839   setFunctionHasBranchProtectedScope();
10840 
10841   return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
10842 }
10843 
10844 StmtResult Sema::ActOnOpenMPMaskedDirective(ArrayRef<OMPClause *> Clauses,
10845                                             Stmt *AStmt,
10846                                             SourceLocation StartLoc,
10847                                             SourceLocation EndLoc) {
10848   if (!AStmt)
10849     return StmtError();
10850 
10851   setFunctionHasBranchProtectedScope();
10852 
10853   return OMPMaskedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10854 }
10855 
10856 StmtResult Sema::ActOnOpenMPCriticalDirective(
10857     const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
10858     Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
10859   if (!AStmt)
10860     return StmtError();
10861 
10862   bool ErrorFound = false;
10863   llvm::APSInt Hint;
10864   SourceLocation HintLoc;
10865   bool DependentHint = false;
10866   for (const OMPClause *C : Clauses) {
10867     if (C->getClauseKind() == OMPC_hint) {
10868       if (!DirName.getName()) {
10869         Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
10870         ErrorFound = true;
10871       }
10872       Expr *E = cast<OMPHintClause>(C)->getHint();
10873       if (E->isTypeDependent() || E->isValueDependent() ||
10874           E->isInstantiationDependent()) {
10875         DependentHint = true;
10876       } else {
10877         Hint = E->EvaluateKnownConstInt(Context);
10878         HintLoc = C->getBeginLoc();
10879       }
10880     }
10881   }
10882   if (ErrorFound)
10883     return StmtError();
10884   const auto Pair = DSAStack->getCriticalWithHint(DirName);
10885   if (Pair.first && DirName.getName() && !DependentHint) {
10886     if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
10887       Diag(StartLoc, diag::err_omp_critical_with_hint);
10888       if (HintLoc.isValid())
10889         Diag(HintLoc, diag::note_omp_critical_hint_here)
10890             << 0 << toString(Hint, /*Radix=*/10, /*Signed=*/false);
10891       else
10892         Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
10893       if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
10894         Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
10895             << 1
10896             << toString(C->getHint()->EvaluateKnownConstInt(Context),
10897                         /*Radix=*/10, /*Signed=*/false);
10898       } else {
10899         Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
10900       }
10901     }
10902   }
10903 
10904   setFunctionHasBranchProtectedScope();
10905 
10906   auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
10907                                            Clauses, AStmt);
10908   if (!Pair.first && DirName.getName() && !DependentHint)
10909     DSAStack->addCriticalWithHint(Dir, Hint);
10910   return Dir;
10911 }
10912 
10913 StmtResult Sema::ActOnOpenMPParallelForDirective(
10914     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10915     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10916   if (!AStmt)
10917     return StmtError();
10918 
10919   auto *CS = cast<CapturedStmt>(AStmt);
10920   // 1.2.2 OpenMP Language Terminology
10921   // Structured block - An executable statement with a single entry at the
10922   // top and a single exit at the bottom.
10923   // The point of exit cannot be a branch out of the structured block.
10924   // longjmp() and throw() must not violate the entry/exit criteria.
10925   CS->getCapturedDecl()->setNothrow();
10926 
10927   OMPLoopBasedDirective::HelperExprs B;
10928   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10929   // define the nested loops number.
10930   unsigned NestedLoopCount =
10931       checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
10932                       getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
10933                       VarsWithImplicitDSA, B);
10934   if (NestedLoopCount == 0)
10935     return StmtError();
10936 
10937   assert((CurContext->isDependentContext() || B.builtAll()) &&
10938          "omp parallel for loop exprs were not built");
10939 
10940   if (!CurContext->isDependentContext()) {
10941     // Finalize the clauses that need pre-built expressions for CodeGen.
10942     for (OMPClause *C : Clauses) {
10943       if (auto *LC = dyn_cast<OMPLinearClause>(C))
10944         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10945                                      B.NumIterations, *this, CurScope,
10946                                      DSAStack))
10947           return StmtError();
10948     }
10949   }
10950 
10951   setFunctionHasBranchProtectedScope();
10952   return OMPParallelForDirective::Create(
10953       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10954       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10955 }
10956 
10957 StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
10958     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10959     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10960   if (!AStmt)
10961     return StmtError();
10962 
10963   auto *CS = cast<CapturedStmt>(AStmt);
10964   // 1.2.2 OpenMP Language Terminology
10965   // Structured block - An executable statement with a single entry at the
10966   // top and a single exit at the bottom.
10967   // The point of exit cannot be a branch out of the structured block.
10968   // longjmp() and throw() must not violate the entry/exit criteria.
10969   CS->getCapturedDecl()->setNothrow();
10970 
10971   OMPLoopBasedDirective::HelperExprs B;
10972   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10973   // define the nested loops number.
10974   unsigned NestedLoopCount =
10975       checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
10976                       getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
10977                       VarsWithImplicitDSA, B);
10978   if (NestedLoopCount == 0)
10979     return StmtError();
10980 
10981   if (!CurContext->isDependentContext()) {
10982     // Finalize the clauses that need pre-built expressions for CodeGen.
10983     for (OMPClause *C : Clauses) {
10984       if (auto *LC = dyn_cast<OMPLinearClause>(C))
10985         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10986                                      B.NumIterations, *this, CurScope,
10987                                      DSAStack))
10988           return StmtError();
10989     }
10990   }
10991 
10992   if (checkSimdlenSafelenSpecified(*this, Clauses))
10993     return StmtError();
10994 
10995   setFunctionHasBranchProtectedScope();
10996   return OMPParallelForSimdDirective::Create(
10997       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10998 }
10999 
11000 StmtResult
11001 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses,
11002                                          Stmt *AStmt, SourceLocation StartLoc,
11003                                          SourceLocation EndLoc) {
11004   if (!AStmt)
11005     return StmtError();
11006 
11007   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11008   auto *CS = cast<CapturedStmt>(AStmt);
11009   // 1.2.2 OpenMP Language Terminology
11010   // Structured block - An executable statement with a single entry at the
11011   // top and a single exit at the bottom.
11012   // The point of exit cannot be a branch out of the structured block.
11013   // longjmp() and throw() must not violate the entry/exit criteria.
11014   CS->getCapturedDecl()->setNothrow();
11015 
11016   setFunctionHasBranchProtectedScope();
11017 
11018   return OMPParallelMasterDirective::Create(
11019       Context, StartLoc, EndLoc, Clauses, AStmt,
11020       DSAStack->getTaskgroupReductionRef());
11021 }
11022 
11023 StmtResult
11024 Sema::ActOnOpenMPParallelMaskedDirective(ArrayRef<OMPClause *> Clauses,
11025                                          Stmt *AStmt, SourceLocation StartLoc,
11026                                          SourceLocation EndLoc) {
11027   if (!AStmt)
11028     return StmtError();
11029 
11030   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11031   auto *CS = cast<CapturedStmt>(AStmt);
11032   // 1.2.2 OpenMP Language Terminology
11033   // Structured block - An executable statement with a single entry at the
11034   // top and a single exit at the bottom.
11035   // The point of exit cannot be a branch out of the structured block.
11036   // longjmp() and throw() must not violate the entry/exit criteria.
11037   CS->getCapturedDecl()->setNothrow();
11038 
11039   setFunctionHasBranchProtectedScope();
11040 
11041   return OMPParallelMaskedDirective::Create(
11042       Context, StartLoc, EndLoc, Clauses, AStmt,
11043       DSAStack->getTaskgroupReductionRef());
11044 }
11045 
11046 StmtResult
11047 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
11048                                            Stmt *AStmt, SourceLocation StartLoc,
11049                                            SourceLocation EndLoc) {
11050   if (!AStmt)
11051     return StmtError();
11052 
11053   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11054   auto BaseStmt = AStmt;
11055   while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
11056     BaseStmt = CS->getCapturedStmt();
11057   if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
11058     auto S = C->children();
11059     if (S.begin() == S.end())
11060       return StmtError();
11061     // All associated statements must be '#pragma omp section' except for
11062     // the first one.
11063     for (Stmt *SectionStmt : llvm::drop_begin(S)) {
11064       if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
11065         if (SectionStmt)
11066           Diag(SectionStmt->getBeginLoc(),
11067                diag::err_omp_parallel_sections_substmt_not_section);
11068         return StmtError();
11069       }
11070       cast<OMPSectionDirective>(SectionStmt)
11071           ->setHasCancel(DSAStack->isCancelRegion());
11072     }
11073   } else {
11074     Diag(AStmt->getBeginLoc(),
11075          diag::err_omp_parallel_sections_not_compound_stmt);
11076     return StmtError();
11077   }
11078 
11079   setFunctionHasBranchProtectedScope();
11080 
11081   return OMPParallelSectionsDirective::Create(
11082       Context, StartLoc, EndLoc, Clauses, AStmt,
11083       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11084 }
11085 
11086 /// Find and diagnose mutually exclusive clause kinds.
11087 static bool checkMutuallyExclusiveClauses(
11088     Sema &S, ArrayRef<OMPClause *> Clauses,
11089     ArrayRef<OpenMPClauseKind> MutuallyExclusiveClauses) {
11090   const OMPClause *PrevClause = nullptr;
11091   bool ErrorFound = false;
11092   for (const OMPClause *C : Clauses) {
11093     if (llvm::is_contained(MutuallyExclusiveClauses, C->getClauseKind())) {
11094       if (!PrevClause) {
11095         PrevClause = C;
11096       } else if (PrevClause->getClauseKind() != C->getClauseKind()) {
11097         S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
11098             << getOpenMPClauseName(C->getClauseKind())
11099             << getOpenMPClauseName(PrevClause->getClauseKind());
11100         S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
11101             << getOpenMPClauseName(PrevClause->getClauseKind());
11102         ErrorFound = true;
11103       }
11104     }
11105   }
11106   return ErrorFound;
11107 }
11108 
11109 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
11110                                           Stmt *AStmt, SourceLocation StartLoc,
11111                                           SourceLocation EndLoc) {
11112   if (!AStmt)
11113     return StmtError();
11114 
11115   // OpenMP 5.0, 2.10.1 task Construct
11116   // If a detach clause appears on the directive, then a mergeable clause cannot
11117   // appear on the same directive.
11118   if (checkMutuallyExclusiveClauses(*this, Clauses,
11119                                     {OMPC_detach, OMPC_mergeable}))
11120     return StmtError();
11121 
11122   auto *CS = cast<CapturedStmt>(AStmt);
11123   // 1.2.2 OpenMP Language Terminology
11124   // Structured block - An executable statement with a single entry at the
11125   // top and a single exit at the bottom.
11126   // The point of exit cannot be a branch out of the structured block.
11127   // longjmp() and throw() must not violate the entry/exit criteria.
11128   CS->getCapturedDecl()->setNothrow();
11129 
11130   setFunctionHasBranchProtectedScope();
11131 
11132   return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
11133                                   DSAStack->isCancelRegion());
11134 }
11135 
11136 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
11137                                                SourceLocation EndLoc) {
11138   return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
11139 }
11140 
11141 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
11142                                              SourceLocation EndLoc) {
11143   return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
11144 }
11145 
11146 StmtResult Sema::ActOnOpenMPErrorDirective(ArrayRef<OMPClause *> Clauses,
11147                                            SourceLocation StartLoc,
11148                                            SourceLocation EndLoc,
11149                                            bool InExContext) {
11150   const OMPAtClause *AtC =
11151       OMPExecutableDirective::getSingleClause<OMPAtClause>(Clauses);
11152 
11153   if (AtC && !InExContext && AtC->getAtKind() == OMPC_AT_execution) {
11154     Diag(AtC->getAtKindKwLoc(), diag::err_omp_unexpected_execution_modifier);
11155     return StmtError();
11156   }
11157 
11158   const OMPSeverityClause *SeverityC =
11159       OMPExecutableDirective::getSingleClause<OMPSeverityClause>(Clauses);
11160   const OMPMessageClause *MessageC =
11161       OMPExecutableDirective::getSingleClause<OMPMessageClause>(Clauses);
11162   Expr *ME = MessageC ? MessageC->getMessageString() : nullptr;
11163 
11164   if (!AtC || AtC->getAtKind() == OMPC_AT_compilation) {
11165     if (SeverityC && SeverityC->getSeverityKind() == OMPC_SEVERITY_warning)
11166       Diag(SeverityC->getSeverityKindKwLoc(), diag::warn_diagnose_if_succeeded)
11167           << (ME ? cast<StringLiteral>(ME)->getString() : "WARNING");
11168     else
11169       Diag(StartLoc, diag::err_diagnose_if_succeeded)
11170           << (ME ? cast<StringLiteral>(ME)->getString() : "ERROR");
11171     if (!SeverityC || SeverityC->getSeverityKind() != OMPC_SEVERITY_warning)
11172       return StmtError();
11173   }
11174   return OMPErrorDirective::Create(Context, StartLoc, EndLoc, Clauses);
11175 }
11176 
11177 StmtResult Sema::ActOnOpenMPTaskwaitDirective(ArrayRef<OMPClause *> Clauses,
11178                                               SourceLocation StartLoc,
11179                                               SourceLocation EndLoc) {
11180   const OMPNowaitClause *NowaitC =
11181       OMPExecutableDirective::getSingleClause<OMPNowaitClause>(Clauses);
11182   bool HasDependC =
11183       !OMPExecutableDirective::getClausesOfKind<OMPDependClause>(Clauses)
11184            .empty();
11185   if (NowaitC && !HasDependC) {
11186     Diag(StartLoc, diag::err_omp_nowait_clause_without_depend);
11187     return StmtError();
11188   }
11189 
11190   return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc, Clauses);
11191 }
11192 
11193 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
11194                                                Stmt *AStmt,
11195                                                SourceLocation StartLoc,
11196                                                SourceLocation EndLoc) {
11197   if (!AStmt)
11198     return StmtError();
11199 
11200   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11201 
11202   setFunctionHasBranchProtectedScope();
11203 
11204   return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
11205                                        AStmt,
11206                                        DSAStack->getTaskgroupReductionRef());
11207 }
11208 
11209 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
11210                                            SourceLocation StartLoc,
11211                                            SourceLocation EndLoc) {
11212   OMPFlushClause *FC = nullptr;
11213   OMPClause *OrderClause = nullptr;
11214   for (OMPClause *C : Clauses) {
11215     if (C->getClauseKind() == OMPC_flush)
11216       FC = cast<OMPFlushClause>(C);
11217     else
11218       OrderClause = C;
11219   }
11220   OpenMPClauseKind MemOrderKind = OMPC_unknown;
11221   SourceLocation MemOrderLoc;
11222   for (const OMPClause *C : Clauses) {
11223     if (C->getClauseKind() == OMPC_acq_rel ||
11224         C->getClauseKind() == OMPC_acquire ||
11225         C->getClauseKind() == OMPC_release) {
11226       if (MemOrderKind != OMPC_unknown) {
11227         Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
11228             << getOpenMPDirectiveName(OMPD_flush) << 1
11229             << SourceRange(C->getBeginLoc(), C->getEndLoc());
11230         Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
11231             << getOpenMPClauseName(MemOrderKind);
11232       } else {
11233         MemOrderKind = C->getClauseKind();
11234         MemOrderLoc = C->getBeginLoc();
11235       }
11236     }
11237   }
11238   if (FC && OrderClause) {
11239     Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list)
11240         << getOpenMPClauseName(OrderClause->getClauseKind());
11241     Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here)
11242         << getOpenMPClauseName(OrderClause->getClauseKind());
11243     return StmtError();
11244   }
11245   return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
11246 }
11247 
11248 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses,
11249                                             SourceLocation StartLoc,
11250                                             SourceLocation EndLoc) {
11251   if (Clauses.empty()) {
11252     Diag(StartLoc, diag::err_omp_depobj_expected);
11253     return StmtError();
11254   } else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
11255     Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
11256     return StmtError();
11257   }
11258   // Only depobj expression and another single clause is allowed.
11259   if (Clauses.size() > 2) {
11260     Diag(Clauses[2]->getBeginLoc(),
11261          diag::err_omp_depobj_single_clause_expected);
11262     return StmtError();
11263   } else if (Clauses.size() < 1) {
11264     Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
11265     return StmtError();
11266   }
11267   return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses);
11268 }
11269 
11270 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses,
11271                                           SourceLocation StartLoc,
11272                                           SourceLocation EndLoc) {
11273   // Check that exactly one clause is specified.
11274   if (Clauses.size() != 1) {
11275     Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
11276          diag::err_omp_scan_single_clause_expected);
11277     return StmtError();
11278   }
11279   // Check that scan directive is used in the scopeof the OpenMP loop body.
11280   if (Scope *S = DSAStack->getCurScope()) {
11281     Scope *ParentS = S->getParent();
11282     if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() ||
11283         !ParentS->getBreakParent()->isOpenMPLoopScope())
11284       return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive)
11285                        << getOpenMPDirectiveName(OMPD_scan) << 5);
11286   }
11287   // Check that only one instance of scan directives is used in the same outer
11288   // region.
11289   if (DSAStack->doesParentHasScanDirective()) {
11290     Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan";
11291     Diag(DSAStack->getParentScanDirectiveLoc(),
11292          diag::note_omp_previous_directive)
11293         << "scan";
11294     return StmtError();
11295   }
11296   DSAStack->setParentHasScanDirective(StartLoc);
11297   return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses);
11298 }
11299 
11300 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
11301                                              Stmt *AStmt,
11302                                              SourceLocation StartLoc,
11303                                              SourceLocation EndLoc) {
11304   const OMPClause *DependFound = nullptr;
11305   const OMPClause *DependSourceClause = nullptr;
11306   const OMPClause *DependSinkClause = nullptr;
11307   const OMPClause *DoacrossFound = nullptr;
11308   const OMPClause *DoacrossSourceClause = nullptr;
11309   const OMPClause *DoacrossSinkClause = nullptr;
11310   bool ErrorFound = false;
11311   const OMPThreadsClause *TC = nullptr;
11312   const OMPSIMDClause *SC = nullptr;
11313   for (const OMPClause *C : Clauses) {
11314     auto DOC = dyn_cast<OMPDoacrossClause>(C);
11315     auto DC = dyn_cast<OMPDependClause>(C);
11316     if (DC || DOC) {
11317       DependFound = DC ? C : nullptr;
11318       DoacrossFound = DOC ? C : nullptr;
11319       OMPDoacrossKind ODK;
11320       if ((DC && DC->getDependencyKind() == OMPC_DEPEND_source) ||
11321           (DOC && (ODK.isSource(DOC)))) {
11322         if ((DC && DependSourceClause) || (DOC && DoacrossSourceClause)) {
11323           Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
11324               << getOpenMPDirectiveName(OMPD_ordered)
11325               << getOpenMPClauseName(DC ? OMPC_depend : OMPC_doacross) << 2;
11326           ErrorFound = true;
11327         } else {
11328           if (DC)
11329             DependSourceClause = C;
11330           else
11331             DoacrossSourceClause = C;
11332         }
11333         if ((DC && DependSinkClause) || (DOC && DoacrossSinkClause)) {
11334           Diag(C->getBeginLoc(), diag::err_omp_sink_and_source_not_allowed)
11335               << (DC ? "depend" : "doacross") << 0;
11336           ErrorFound = true;
11337         }
11338       } else if ((DC && DC->getDependencyKind() == OMPC_DEPEND_sink) ||
11339                  (DOC && (ODK.isSink(DOC) || ODK.isSinkIter(DOC)))) {
11340         if (DependSourceClause || DoacrossSourceClause) {
11341           Diag(C->getBeginLoc(), diag::err_omp_sink_and_source_not_allowed)
11342               << (DC ? "depend" : "doacross") << 1;
11343           ErrorFound = true;
11344         }
11345         if (DC)
11346           DependSinkClause = C;
11347         else
11348           DoacrossSinkClause = C;
11349       }
11350     } else if (C->getClauseKind() == OMPC_threads) {
11351       TC = cast<OMPThreadsClause>(C);
11352     } else if (C->getClauseKind() == OMPC_simd) {
11353       SC = cast<OMPSIMDClause>(C);
11354     }
11355   }
11356   if (!ErrorFound && !SC &&
11357       isOpenMPSimdDirective(DSAStack->getParentDirective())) {
11358     // OpenMP [2.8.1,simd Construct, Restrictions]
11359     // An ordered construct with the simd clause is the only OpenMP construct
11360     // that can appear in the simd region.
11361     Diag(StartLoc, diag::err_omp_prohibited_region_simd)
11362         << (LangOpts.OpenMP >= 50 ? 1 : 0);
11363     ErrorFound = true;
11364   } else if ((DependFound || DoacrossFound) && (TC || SC)) {
11365     SourceLocation Loc =
11366         DependFound ? DependFound->getBeginLoc() : DoacrossFound->getBeginLoc();
11367     Diag(Loc, diag::err_omp_depend_clause_thread_simd)
11368         << getOpenMPClauseName(DependFound ? OMPC_depend : OMPC_doacross)
11369         << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
11370     ErrorFound = true;
11371   } else if ((DependFound || DoacrossFound) &&
11372              !DSAStack->getParentOrderedRegionParam().first) {
11373     SourceLocation Loc =
11374         DependFound ? DependFound->getBeginLoc() : DoacrossFound->getBeginLoc();
11375     Diag(Loc, diag::err_omp_ordered_directive_without_param)
11376         << getOpenMPClauseName(DependFound ? OMPC_depend : OMPC_doacross);
11377     ErrorFound = true;
11378   } else if (TC || Clauses.empty()) {
11379     if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) {
11380       SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
11381       Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
11382           << (TC != nullptr);
11383       Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1;
11384       ErrorFound = true;
11385     }
11386   }
11387   if ((!AStmt && !DependFound && !DoacrossFound) || ErrorFound)
11388     return StmtError();
11389 
11390   // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions.
11391   // During execution of an iteration of a worksharing-loop or a loop nest
11392   // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread
11393   // must not execute more than one ordered region corresponding to an ordered
11394   // construct without a depend clause.
11395   if (!DependFound && !DoacrossFound) {
11396     if (DSAStack->doesParentHasOrderedDirective()) {
11397       Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered";
11398       Diag(DSAStack->getParentOrderedDirectiveLoc(),
11399            diag::note_omp_previous_directive)
11400           << "ordered";
11401       return StmtError();
11402     }
11403     DSAStack->setParentHasOrderedDirective(StartLoc);
11404   }
11405 
11406   if (AStmt) {
11407     assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11408 
11409     setFunctionHasBranchProtectedScope();
11410   }
11411 
11412   return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
11413 }
11414 
11415 namespace {
11416 /// Helper class for checking expression in 'omp atomic [update]'
11417 /// construct.
11418 class OpenMPAtomicUpdateChecker {
11419   /// Error results for atomic update expressions.
11420   enum ExprAnalysisErrorCode {
11421     /// A statement is not an expression statement.
11422     NotAnExpression,
11423     /// Expression is not builtin binary or unary operation.
11424     NotABinaryOrUnaryExpression,
11425     /// Unary operation is not post-/pre- increment/decrement operation.
11426     NotAnUnaryIncDecExpression,
11427     /// An expression is not of scalar type.
11428     NotAScalarType,
11429     /// A binary operation is not an assignment operation.
11430     NotAnAssignmentOp,
11431     /// RHS part of the binary operation is not a binary expression.
11432     NotABinaryExpression,
11433     /// RHS part is not additive/multiplicative/shift/biwise binary
11434     /// expression.
11435     NotABinaryOperator,
11436     /// RHS binary operation does not have reference to the updated LHS
11437     /// part.
11438     NotAnUpdateExpression,
11439     /// No errors is found.
11440     NoError
11441   };
11442   /// Reference to Sema.
11443   Sema &SemaRef;
11444   /// A location for note diagnostics (when error is found).
11445   SourceLocation NoteLoc;
11446   /// 'x' lvalue part of the source atomic expression.
11447   Expr *X;
11448   /// 'expr' rvalue part of the source atomic expression.
11449   Expr *E;
11450   /// Helper expression of the form
11451   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
11452   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
11453   Expr *UpdateExpr;
11454   /// Is 'x' a LHS in a RHS part of full update expression. It is
11455   /// important for non-associative operations.
11456   bool IsXLHSInRHSPart;
11457   BinaryOperatorKind Op;
11458   SourceLocation OpLoc;
11459   /// true if the source expression is a postfix unary operation, false
11460   /// if it is a prefix unary operation.
11461   bool IsPostfixUpdate;
11462 
11463 public:
11464   OpenMPAtomicUpdateChecker(Sema &SemaRef)
11465       : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
11466         IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
11467   /// Check specified statement that it is suitable for 'atomic update'
11468   /// constructs and extract 'x', 'expr' and Operation from the original
11469   /// expression. If DiagId and NoteId == 0, then only check is performed
11470   /// without error notification.
11471   /// \param DiagId Diagnostic which should be emitted if error is found.
11472   /// \param NoteId Diagnostic note for the main error message.
11473   /// \return true if statement is not an update expression, false otherwise.
11474   bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
11475   /// Return the 'x' lvalue part of the source atomic expression.
11476   Expr *getX() const { return X; }
11477   /// Return the 'expr' rvalue part of the source atomic expression.
11478   Expr *getExpr() const { return E; }
11479   /// Return the update expression used in calculation of the updated
11480   /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
11481   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
11482   Expr *getUpdateExpr() const { return UpdateExpr; }
11483   /// Return true if 'x' is LHS in RHS part of full update expression,
11484   /// false otherwise.
11485   bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
11486 
11487   /// true if the source expression is a postfix unary operation, false
11488   /// if it is a prefix unary operation.
11489   bool isPostfixUpdate() const { return IsPostfixUpdate; }
11490 
11491 private:
11492   bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
11493                             unsigned NoteId = 0);
11494 };
11495 
11496 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
11497     BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
11498   ExprAnalysisErrorCode ErrorFound = NoError;
11499   SourceLocation ErrorLoc, NoteLoc;
11500   SourceRange ErrorRange, NoteRange;
11501   // Allowed constructs are:
11502   //  x = x binop expr;
11503   //  x = expr binop x;
11504   if (AtomicBinOp->getOpcode() == BO_Assign) {
11505     X = AtomicBinOp->getLHS();
11506     if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
11507             AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
11508       if (AtomicInnerBinOp->isMultiplicativeOp() ||
11509           AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
11510           AtomicInnerBinOp->isBitwiseOp()) {
11511         Op = AtomicInnerBinOp->getOpcode();
11512         OpLoc = AtomicInnerBinOp->getOperatorLoc();
11513         Expr *LHS = AtomicInnerBinOp->getLHS();
11514         Expr *RHS = AtomicInnerBinOp->getRHS();
11515         llvm::FoldingSetNodeID XId, LHSId, RHSId;
11516         X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
11517                                           /*Canonical=*/true);
11518         LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
11519                                             /*Canonical=*/true);
11520         RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
11521                                             /*Canonical=*/true);
11522         if (XId == LHSId) {
11523           E = RHS;
11524           IsXLHSInRHSPart = true;
11525         } else if (XId == RHSId) {
11526           E = LHS;
11527           IsXLHSInRHSPart = false;
11528         } else {
11529           ErrorLoc = AtomicInnerBinOp->getExprLoc();
11530           ErrorRange = AtomicInnerBinOp->getSourceRange();
11531           NoteLoc = X->getExprLoc();
11532           NoteRange = X->getSourceRange();
11533           ErrorFound = NotAnUpdateExpression;
11534         }
11535       } else {
11536         ErrorLoc = AtomicInnerBinOp->getExprLoc();
11537         ErrorRange = AtomicInnerBinOp->getSourceRange();
11538         NoteLoc = AtomicInnerBinOp->getOperatorLoc();
11539         NoteRange = SourceRange(NoteLoc, NoteLoc);
11540         ErrorFound = NotABinaryOperator;
11541       }
11542     } else {
11543       NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
11544       NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
11545       ErrorFound = NotABinaryExpression;
11546     }
11547   } else {
11548     ErrorLoc = AtomicBinOp->getExprLoc();
11549     ErrorRange = AtomicBinOp->getSourceRange();
11550     NoteLoc = AtomicBinOp->getOperatorLoc();
11551     NoteRange = SourceRange(NoteLoc, NoteLoc);
11552     ErrorFound = NotAnAssignmentOp;
11553   }
11554   if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
11555     SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
11556     SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
11557     return true;
11558   }
11559   if (SemaRef.CurContext->isDependentContext())
11560     E = X = UpdateExpr = nullptr;
11561   return ErrorFound != NoError;
11562 }
11563 
11564 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
11565                                                unsigned NoteId) {
11566   ExprAnalysisErrorCode ErrorFound = NoError;
11567   SourceLocation ErrorLoc, NoteLoc;
11568   SourceRange ErrorRange, NoteRange;
11569   // Allowed constructs are:
11570   //  x++;
11571   //  x--;
11572   //  ++x;
11573   //  --x;
11574   //  x binop= expr;
11575   //  x = x binop expr;
11576   //  x = expr binop x;
11577   if (auto *AtomicBody = dyn_cast<Expr>(S)) {
11578     AtomicBody = AtomicBody->IgnoreParenImpCasts();
11579     if (AtomicBody->getType()->isScalarType() ||
11580         AtomicBody->isInstantiationDependent()) {
11581       if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
11582               AtomicBody->IgnoreParenImpCasts())) {
11583         // Check for Compound Assignment Operation
11584         Op = BinaryOperator::getOpForCompoundAssignment(
11585             AtomicCompAssignOp->getOpcode());
11586         OpLoc = AtomicCompAssignOp->getOperatorLoc();
11587         E = AtomicCompAssignOp->getRHS();
11588         X = AtomicCompAssignOp->getLHS()->IgnoreParens();
11589         IsXLHSInRHSPart = true;
11590       } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
11591                      AtomicBody->IgnoreParenImpCasts())) {
11592         // Check for Binary Operation
11593         if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
11594           return true;
11595       } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
11596                      AtomicBody->IgnoreParenImpCasts())) {
11597         // Check for Unary Operation
11598         if (AtomicUnaryOp->isIncrementDecrementOp()) {
11599           IsPostfixUpdate = AtomicUnaryOp->isPostfix();
11600           Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
11601           OpLoc = AtomicUnaryOp->getOperatorLoc();
11602           X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
11603           E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
11604           IsXLHSInRHSPart = true;
11605         } else {
11606           ErrorFound = NotAnUnaryIncDecExpression;
11607           ErrorLoc = AtomicUnaryOp->getExprLoc();
11608           ErrorRange = AtomicUnaryOp->getSourceRange();
11609           NoteLoc = AtomicUnaryOp->getOperatorLoc();
11610           NoteRange = SourceRange(NoteLoc, NoteLoc);
11611         }
11612       } else if (!AtomicBody->isInstantiationDependent()) {
11613         ErrorFound = NotABinaryOrUnaryExpression;
11614         NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
11615         NoteRange = ErrorRange = AtomicBody->getSourceRange();
11616       }
11617     } else {
11618       ErrorFound = NotAScalarType;
11619       NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
11620       NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
11621     }
11622   } else {
11623     ErrorFound = NotAnExpression;
11624     NoteLoc = ErrorLoc = S->getBeginLoc();
11625     NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
11626   }
11627   if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
11628     SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
11629     SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
11630     return true;
11631   }
11632   if (SemaRef.CurContext->isDependentContext())
11633     E = X = UpdateExpr = nullptr;
11634   if (ErrorFound == NoError && E && X) {
11635     // Build an update expression of form 'OpaqueValueExpr(x) binop
11636     // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
11637     // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
11638     auto *OVEX = new (SemaRef.getASTContext())
11639         OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_PRValue);
11640     auto *OVEExpr = new (SemaRef.getASTContext())
11641         OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_PRValue);
11642     ExprResult Update =
11643         SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
11644                                    IsXLHSInRHSPart ? OVEExpr : OVEX);
11645     if (Update.isInvalid())
11646       return true;
11647     Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
11648                                                Sema::AA_Casting);
11649     if (Update.isInvalid())
11650       return true;
11651     UpdateExpr = Update.get();
11652   }
11653   return ErrorFound != NoError;
11654 }
11655 
11656 /// Get the node id of the fixed point of an expression \a S.
11657 llvm::FoldingSetNodeID getNodeId(ASTContext &Context, const Expr *S) {
11658   llvm::FoldingSetNodeID Id;
11659   S->IgnoreParenImpCasts()->Profile(Id, Context, true);
11660   return Id;
11661 }
11662 
11663 /// Check if two expressions are same.
11664 bool checkIfTwoExprsAreSame(ASTContext &Context, const Expr *LHS,
11665                             const Expr *RHS) {
11666   return getNodeId(Context, LHS) == getNodeId(Context, RHS);
11667 }
11668 
11669 class OpenMPAtomicCompareChecker {
11670 public:
11671   /// All kinds of errors that can occur in `atomic compare`
11672   enum ErrorTy {
11673     /// Empty compound statement.
11674     NoStmt = 0,
11675     /// More than one statement in a compound statement.
11676     MoreThanOneStmt,
11677     /// Not an assignment binary operator.
11678     NotAnAssignment,
11679     /// Not a conditional operator.
11680     NotCondOp,
11681     /// Wrong false expr. According to the spec, 'x' should be at the false
11682     /// expression of a conditional expression.
11683     WrongFalseExpr,
11684     /// The condition of a conditional expression is not a binary operator.
11685     NotABinaryOp,
11686     /// Invalid binary operator (not <, >, or ==).
11687     InvalidBinaryOp,
11688     /// Invalid comparison (not x == e, e == x, x ordop expr, or expr ordop x).
11689     InvalidComparison,
11690     /// X is not a lvalue.
11691     XNotLValue,
11692     /// Not a scalar.
11693     NotScalar,
11694     /// Not an integer.
11695     NotInteger,
11696     /// 'else' statement is not expected.
11697     UnexpectedElse,
11698     /// Not an equality operator.
11699     NotEQ,
11700     /// Invalid assignment (not v == x).
11701     InvalidAssignment,
11702     /// Not if statement
11703     NotIfStmt,
11704     /// More than two statements in a compund statement.
11705     MoreThanTwoStmts,
11706     /// Not a compound statement.
11707     NotCompoundStmt,
11708     /// No else statement.
11709     NoElse,
11710     /// Not 'if (r)'.
11711     InvalidCondition,
11712     /// No error.
11713     NoError,
11714   };
11715 
11716   struct ErrorInfoTy {
11717     ErrorTy Error;
11718     SourceLocation ErrorLoc;
11719     SourceRange ErrorRange;
11720     SourceLocation NoteLoc;
11721     SourceRange NoteRange;
11722   };
11723 
11724   OpenMPAtomicCompareChecker(Sema &S) : ContextRef(S.getASTContext()) {}
11725 
11726   /// Check if statement \a S is valid for <tt>atomic compare</tt>.
11727   bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
11728 
11729   Expr *getX() const { return X; }
11730   Expr *getE() const { return E; }
11731   Expr *getD() const { return D; }
11732   Expr *getCond() const { return C; }
11733   bool isXBinopExpr() const { return IsXBinopExpr; }
11734 
11735 protected:
11736   /// Reference to ASTContext
11737   ASTContext &ContextRef;
11738   /// 'x' lvalue part of the source atomic expression.
11739   Expr *X = nullptr;
11740   /// 'expr' or 'e' rvalue part of the source atomic expression.
11741   Expr *E = nullptr;
11742   /// 'd' rvalue part of the source atomic expression.
11743   Expr *D = nullptr;
11744   /// 'cond' part of the source atomic expression. It is in one of the following
11745   /// forms:
11746   /// expr ordop x
11747   /// x ordop expr
11748   /// x == e
11749   /// e == x
11750   Expr *C = nullptr;
11751   /// True if the cond expr is in the form of 'x ordop expr'.
11752   bool IsXBinopExpr = true;
11753 
11754   /// Check if it is a valid conditional update statement (cond-update-stmt).
11755   bool checkCondUpdateStmt(IfStmt *S, ErrorInfoTy &ErrorInfo);
11756 
11757   /// Check if it is a valid conditional expression statement (cond-expr-stmt).
11758   bool checkCondExprStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
11759 
11760   /// Check if all captured values have right type.
11761   bool checkType(ErrorInfoTy &ErrorInfo) const;
11762 
11763   static bool CheckValue(const Expr *E, ErrorInfoTy &ErrorInfo,
11764                          bool ShouldBeLValue, bool ShouldBeInteger = false) {
11765     if (E->isInstantiationDependent())
11766       return true;
11767 
11768     if (ShouldBeLValue && !E->isLValue()) {
11769       ErrorInfo.Error = ErrorTy::XNotLValue;
11770       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11771       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11772       return false;
11773     }
11774 
11775     QualType QTy = E->getType();
11776     if (!QTy->isScalarType()) {
11777       ErrorInfo.Error = ErrorTy::NotScalar;
11778       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11779       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11780       return false;
11781     }
11782     if (ShouldBeInteger && !QTy->isIntegerType()) {
11783       ErrorInfo.Error = ErrorTy::NotInteger;
11784       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11785       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11786       return false;
11787     }
11788 
11789     return true;
11790   }
11791   };
11792 
11793 bool OpenMPAtomicCompareChecker::checkCondUpdateStmt(IfStmt *S,
11794                                                      ErrorInfoTy &ErrorInfo) {
11795   auto *Then = S->getThen();
11796   if (auto *CS = dyn_cast<CompoundStmt>(Then)) {
11797     if (CS->body_empty()) {
11798       ErrorInfo.Error = ErrorTy::NoStmt;
11799       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11800       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11801       return false;
11802     }
11803     if (CS->size() > 1) {
11804       ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11805       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11806       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
11807       return false;
11808     }
11809     Then = CS->body_front();
11810   }
11811 
11812   auto *BO = dyn_cast<BinaryOperator>(Then);
11813   if (!BO) {
11814     ErrorInfo.Error = ErrorTy::NotAnAssignment;
11815     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc();
11816     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange();
11817     return false;
11818   }
11819   if (BO->getOpcode() != BO_Assign) {
11820     ErrorInfo.Error = ErrorTy::NotAnAssignment;
11821     ErrorInfo.ErrorLoc = BO->getExprLoc();
11822     ErrorInfo.NoteLoc = BO->getOperatorLoc();
11823     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
11824     return false;
11825   }
11826 
11827   X = BO->getLHS();
11828 
11829   auto *Cond = dyn_cast<BinaryOperator>(S->getCond());
11830   if (!Cond) {
11831     ErrorInfo.Error = ErrorTy::NotABinaryOp;
11832     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc();
11833     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange();
11834     return false;
11835   }
11836 
11837   switch (Cond->getOpcode()) {
11838   case BO_EQ: {
11839     C = Cond;
11840     D = BO->getRHS();
11841     if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
11842       E = Cond->getRHS();
11843     } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11844       E = Cond->getLHS();
11845     } else {
11846       ErrorInfo.Error = ErrorTy::InvalidComparison;
11847       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11848       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11849       return false;
11850     }
11851     break;
11852   }
11853   case BO_LT:
11854   case BO_GT: {
11855     E = BO->getRHS();
11856     if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) &&
11857         checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) {
11858       C = Cond;
11859     } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) &&
11860                checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11861       C = Cond;
11862       IsXBinopExpr = false;
11863     } else {
11864       ErrorInfo.Error = ErrorTy::InvalidComparison;
11865       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11866       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11867       return false;
11868     }
11869     break;
11870   }
11871   default:
11872     ErrorInfo.Error = ErrorTy::InvalidBinaryOp;
11873     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11874     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11875     return false;
11876   }
11877 
11878   if (S->getElse()) {
11879     ErrorInfo.Error = ErrorTy::UnexpectedElse;
11880     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getElse()->getBeginLoc();
11881     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getElse()->getSourceRange();
11882     return false;
11883   }
11884 
11885   return true;
11886 }
11887 
11888 bool OpenMPAtomicCompareChecker::checkCondExprStmt(Stmt *S,
11889                                                    ErrorInfoTy &ErrorInfo) {
11890   auto *BO = dyn_cast<BinaryOperator>(S);
11891   if (!BO) {
11892     ErrorInfo.Error = ErrorTy::NotAnAssignment;
11893     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
11894     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
11895     return false;
11896   }
11897   if (BO->getOpcode() != BO_Assign) {
11898     ErrorInfo.Error = ErrorTy::NotAnAssignment;
11899     ErrorInfo.ErrorLoc = BO->getExprLoc();
11900     ErrorInfo.NoteLoc = BO->getOperatorLoc();
11901     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
11902     return false;
11903   }
11904 
11905   X = BO->getLHS();
11906 
11907   auto *CO = dyn_cast<ConditionalOperator>(BO->getRHS()->IgnoreParenImpCasts());
11908   if (!CO) {
11909     ErrorInfo.Error = ErrorTy::NotCondOp;
11910     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getRHS()->getExprLoc();
11911     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getRHS()->getSourceRange();
11912     return false;
11913   }
11914 
11915   if (!checkIfTwoExprsAreSame(ContextRef, X, CO->getFalseExpr())) {
11916     ErrorInfo.Error = ErrorTy::WrongFalseExpr;
11917     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getFalseExpr()->getExprLoc();
11918     ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
11919         CO->getFalseExpr()->getSourceRange();
11920     return false;
11921   }
11922 
11923   auto *Cond = dyn_cast<BinaryOperator>(CO->getCond());
11924   if (!Cond) {
11925     ErrorInfo.Error = ErrorTy::NotABinaryOp;
11926     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getCond()->getExprLoc();
11927     ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
11928         CO->getCond()->getSourceRange();
11929     return false;
11930   }
11931 
11932   switch (Cond->getOpcode()) {
11933   case BO_EQ: {
11934     C = Cond;
11935     D = CO->getTrueExpr();
11936     if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
11937       E = Cond->getRHS();
11938     } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11939       E = Cond->getLHS();
11940     } else {
11941       ErrorInfo.Error = ErrorTy::InvalidComparison;
11942       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11943       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11944       return false;
11945     }
11946     break;
11947   }
11948   case BO_LT:
11949   case BO_GT: {
11950     E = CO->getTrueExpr();
11951     if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) &&
11952         checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) {
11953       C = Cond;
11954     } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) &&
11955                checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11956       C = Cond;
11957       IsXBinopExpr = false;
11958     } else {
11959       ErrorInfo.Error = ErrorTy::InvalidComparison;
11960       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11961       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11962       return false;
11963     }
11964     break;
11965   }
11966   default:
11967     ErrorInfo.Error = ErrorTy::InvalidBinaryOp;
11968     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11969     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11970     return false;
11971   }
11972 
11973   return true;
11974 }
11975 
11976 bool OpenMPAtomicCompareChecker::checkType(ErrorInfoTy &ErrorInfo) const {
11977   // 'x' and 'e' cannot be nullptr
11978   assert(X && E && "X and E cannot be nullptr");
11979 
11980   if (!CheckValue(X, ErrorInfo, true))
11981     return false;
11982 
11983   if (!CheckValue(E, ErrorInfo, false))
11984     return false;
11985 
11986   if (D && !CheckValue(D, ErrorInfo, false))
11987     return false;
11988 
11989   return true;
11990 }
11991 
11992 bool OpenMPAtomicCompareChecker::checkStmt(
11993     Stmt *S, OpenMPAtomicCompareChecker::ErrorInfoTy &ErrorInfo) {
11994   auto *CS = dyn_cast<CompoundStmt>(S);
11995   if (CS) {
11996     if (CS->body_empty()) {
11997       ErrorInfo.Error = ErrorTy::NoStmt;
11998       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11999       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12000       return false;
12001     }
12002 
12003     if (CS->size() != 1) {
12004       ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12005       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12006       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12007       return false;
12008     }
12009     S = CS->body_front();
12010   }
12011 
12012   auto Res = false;
12013 
12014   if (auto *IS = dyn_cast<IfStmt>(S)) {
12015     // Check if the statement is in one of the following forms
12016     // (cond-update-stmt):
12017     // if (expr ordop x) { x = expr; }
12018     // if (x ordop expr) { x = expr; }
12019     // if (x == e) { x = d; }
12020     Res = checkCondUpdateStmt(IS, ErrorInfo);
12021   } else {
12022     // Check if the statement is in one of the following forms (cond-expr-stmt):
12023     // x = expr ordop x ? expr : x;
12024     // x = x ordop expr ? expr : x;
12025     // x = x == e ? d : x;
12026     Res = checkCondExprStmt(S, ErrorInfo);
12027   }
12028 
12029   if (!Res)
12030     return false;
12031 
12032   return checkType(ErrorInfo);
12033 }
12034 
12035 class OpenMPAtomicCompareCaptureChecker final
12036     : public OpenMPAtomicCompareChecker {
12037 public:
12038   OpenMPAtomicCompareCaptureChecker(Sema &S) : OpenMPAtomicCompareChecker(S) {}
12039 
12040   Expr *getV() const { return V; }
12041   Expr *getR() const { return R; }
12042   bool isFailOnly() const { return IsFailOnly; }
12043   bool isPostfixUpdate() const { return IsPostfixUpdate; }
12044 
12045   /// Check if statement \a S is valid for <tt>atomic compare capture</tt>.
12046   bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
12047 
12048 private:
12049   bool checkType(ErrorInfoTy &ErrorInfo);
12050 
12051   // NOTE: Form 3, 4, 5 in the following comments mean the 3rd, 4th, and 5th
12052   // form of 'conditional-update-capture-atomic' structured block on the v5.2
12053   // spec p.p. 82:
12054   // (1) { v = x; cond-update-stmt }
12055   // (2) { cond-update-stmt v = x; }
12056   // (3) if(x == e) { x = d; } else { v = x; }
12057   // (4) { r = x == e; if(r) { x = d; } }
12058   // (5) { r = x == e; if(r) { x = d; } else { v = x; } }
12059 
12060   /// Check if it is valid 'if(x == e) { x = d; } else { v = x; }' (form 3)
12061   bool checkForm3(IfStmt *S, ErrorInfoTy &ErrorInfo);
12062 
12063   /// Check if it is valid '{ r = x == e; if(r) { x = d; } }',
12064   /// or '{ r = x == e; if(r) { x = d; } else { v = x; } }' (form 4 and 5)
12065   bool checkForm45(Stmt *S, ErrorInfoTy &ErrorInfo);
12066 
12067   /// 'v' lvalue part of the source atomic expression.
12068   Expr *V = nullptr;
12069   /// 'r' lvalue part of the source atomic expression.
12070   Expr *R = nullptr;
12071   /// If 'v' is only updated when the comparison fails.
12072   bool IsFailOnly = false;
12073   /// If original value of 'x' must be stored in 'v', not an updated one.
12074   bool IsPostfixUpdate = false;
12075 };
12076 
12077 bool OpenMPAtomicCompareCaptureChecker::checkType(ErrorInfoTy &ErrorInfo) {
12078   if (!OpenMPAtomicCompareChecker::checkType(ErrorInfo))
12079     return false;
12080 
12081   if (V && !CheckValue(V, ErrorInfo, true))
12082     return false;
12083 
12084   if (R && !CheckValue(R, ErrorInfo, true, true))
12085     return false;
12086 
12087   return true;
12088 }
12089 
12090 bool OpenMPAtomicCompareCaptureChecker::checkForm3(IfStmt *S,
12091                                                    ErrorInfoTy &ErrorInfo) {
12092   IsFailOnly = true;
12093 
12094   auto *Then = S->getThen();
12095   if (auto *CS = dyn_cast<CompoundStmt>(Then)) {
12096     if (CS->body_empty()) {
12097       ErrorInfo.Error = ErrorTy::NoStmt;
12098       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12099       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12100       return false;
12101     }
12102     if (CS->size() > 1) {
12103       ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12104       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12105       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12106       return false;
12107     }
12108     Then = CS->body_front();
12109   }
12110 
12111   auto *BO = dyn_cast<BinaryOperator>(Then);
12112   if (!BO) {
12113     ErrorInfo.Error = ErrorTy::NotAnAssignment;
12114     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc();
12115     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange();
12116     return false;
12117   }
12118   if (BO->getOpcode() != BO_Assign) {
12119     ErrorInfo.Error = ErrorTy::NotAnAssignment;
12120     ErrorInfo.ErrorLoc = BO->getExprLoc();
12121     ErrorInfo.NoteLoc = BO->getOperatorLoc();
12122     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12123     return false;
12124   }
12125 
12126   X = BO->getLHS();
12127   D = BO->getRHS();
12128 
12129   auto *Cond = dyn_cast<BinaryOperator>(S->getCond());
12130   if (!Cond) {
12131     ErrorInfo.Error = ErrorTy::NotABinaryOp;
12132     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc();
12133     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange();
12134     return false;
12135   }
12136   if (Cond->getOpcode() != BO_EQ) {
12137     ErrorInfo.Error = ErrorTy::NotEQ;
12138     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12139     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12140     return false;
12141   }
12142 
12143   if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
12144     E = Cond->getRHS();
12145   } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
12146     E = Cond->getLHS();
12147   } else {
12148     ErrorInfo.Error = ErrorTy::InvalidComparison;
12149     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12150     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12151     return false;
12152   }
12153 
12154   C = Cond;
12155 
12156   if (!S->getElse()) {
12157     ErrorInfo.Error = ErrorTy::NoElse;
12158     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
12159     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12160     return false;
12161   }
12162 
12163   auto *Else = S->getElse();
12164   if (auto *CS = dyn_cast<CompoundStmt>(Else)) {
12165     if (CS->body_empty()) {
12166       ErrorInfo.Error = ErrorTy::NoStmt;
12167       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12168       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12169       return false;
12170     }
12171     if (CS->size() > 1) {
12172       ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12173       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12174       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12175       return false;
12176     }
12177     Else = CS->body_front();
12178   }
12179 
12180   auto *ElseBO = dyn_cast<BinaryOperator>(Else);
12181   if (!ElseBO) {
12182     ErrorInfo.Error = ErrorTy::NotAnAssignment;
12183     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc();
12184     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange();
12185     return false;
12186   }
12187   if (ElseBO->getOpcode() != BO_Assign) {
12188     ErrorInfo.Error = ErrorTy::NotAnAssignment;
12189     ErrorInfo.ErrorLoc = ElseBO->getExprLoc();
12190     ErrorInfo.NoteLoc = ElseBO->getOperatorLoc();
12191     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange();
12192     return false;
12193   }
12194 
12195   if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) {
12196     ErrorInfo.Error = ErrorTy::InvalidAssignment;
12197     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseBO->getRHS()->getExprLoc();
12198     ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12199         ElseBO->getRHS()->getSourceRange();
12200     return false;
12201   }
12202 
12203   V = ElseBO->getLHS();
12204 
12205   return checkType(ErrorInfo);
12206 }
12207 
12208 bool OpenMPAtomicCompareCaptureChecker::checkForm45(Stmt *S,
12209                                                     ErrorInfoTy &ErrorInfo) {
12210   // We don't check here as they should be already done before call this
12211   // function.
12212   auto *CS = cast<CompoundStmt>(S);
12213   assert(CS->size() == 2 && "CompoundStmt size is not expected");
12214   auto *S1 = cast<BinaryOperator>(CS->body_front());
12215   auto *S2 = cast<IfStmt>(CS->body_back());
12216   assert(S1->getOpcode() == BO_Assign && "unexpected binary operator");
12217 
12218   if (!checkIfTwoExprsAreSame(ContextRef, S1->getLHS(), S2->getCond())) {
12219     ErrorInfo.Error = ErrorTy::InvalidCondition;
12220     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getCond()->getExprLoc();
12221     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S1->getLHS()->getSourceRange();
12222     return false;
12223   }
12224 
12225   R = S1->getLHS();
12226 
12227   auto *Then = S2->getThen();
12228   if (auto *ThenCS = dyn_cast<CompoundStmt>(Then)) {
12229     if (ThenCS->body_empty()) {
12230       ErrorInfo.Error = ErrorTy::NoStmt;
12231       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc();
12232       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange();
12233       return false;
12234     }
12235     if (ThenCS->size() > 1) {
12236       ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12237       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc();
12238       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange();
12239       return false;
12240     }
12241     Then = ThenCS->body_front();
12242   }
12243 
12244   auto *ThenBO = dyn_cast<BinaryOperator>(Then);
12245   if (!ThenBO) {
12246     ErrorInfo.Error = ErrorTy::NotAnAssignment;
12247     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getBeginLoc();
12248     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S2->getSourceRange();
12249     return false;
12250   }
12251   if (ThenBO->getOpcode() != BO_Assign) {
12252     ErrorInfo.Error = ErrorTy::NotAnAssignment;
12253     ErrorInfo.ErrorLoc = ThenBO->getExprLoc();
12254     ErrorInfo.NoteLoc = ThenBO->getOperatorLoc();
12255     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenBO->getSourceRange();
12256     return false;
12257   }
12258 
12259   X = ThenBO->getLHS();
12260   D = ThenBO->getRHS();
12261 
12262   auto *BO = cast<BinaryOperator>(S1->getRHS()->IgnoreImpCasts());
12263   if (BO->getOpcode() != BO_EQ) {
12264     ErrorInfo.Error = ErrorTy::NotEQ;
12265     ErrorInfo.ErrorLoc = BO->getExprLoc();
12266     ErrorInfo.NoteLoc = BO->getOperatorLoc();
12267     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12268     return false;
12269   }
12270 
12271   C = BO;
12272 
12273   if (checkIfTwoExprsAreSame(ContextRef, X, BO->getLHS())) {
12274     E = BO->getRHS();
12275   } else if (checkIfTwoExprsAreSame(ContextRef, X, BO->getRHS())) {
12276     E = BO->getLHS();
12277   } else {
12278     ErrorInfo.Error = ErrorTy::InvalidComparison;
12279     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getExprLoc();
12280     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12281     return false;
12282   }
12283 
12284   if (S2->getElse()) {
12285     IsFailOnly = true;
12286 
12287     auto *Else = S2->getElse();
12288     if (auto *ElseCS = dyn_cast<CompoundStmt>(Else)) {
12289       if (ElseCS->body_empty()) {
12290         ErrorInfo.Error = ErrorTy::NoStmt;
12291         ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc();
12292         ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange();
12293         return false;
12294       }
12295       if (ElseCS->size() > 1) {
12296         ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12297         ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc();
12298         ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange();
12299         return false;
12300       }
12301       Else = ElseCS->body_front();
12302     }
12303 
12304     auto *ElseBO = dyn_cast<BinaryOperator>(Else);
12305     if (!ElseBO) {
12306       ErrorInfo.Error = ErrorTy::NotAnAssignment;
12307       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc();
12308       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange();
12309       return false;
12310     }
12311     if (ElseBO->getOpcode() != BO_Assign) {
12312       ErrorInfo.Error = ErrorTy::NotAnAssignment;
12313       ErrorInfo.ErrorLoc = ElseBO->getExprLoc();
12314       ErrorInfo.NoteLoc = ElseBO->getOperatorLoc();
12315       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange();
12316       return false;
12317     }
12318     if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) {
12319       ErrorInfo.Error = ErrorTy::InvalidAssignment;
12320       ErrorInfo.ErrorLoc = ElseBO->getRHS()->getExprLoc();
12321       ErrorInfo.NoteLoc = X->getExprLoc();
12322       ErrorInfo.ErrorRange = ElseBO->getRHS()->getSourceRange();
12323       ErrorInfo.NoteRange = X->getSourceRange();
12324       return false;
12325     }
12326 
12327     V = ElseBO->getLHS();
12328   }
12329 
12330   return checkType(ErrorInfo);
12331 }
12332 
12333 bool OpenMPAtomicCompareCaptureChecker::checkStmt(Stmt *S,
12334                                                   ErrorInfoTy &ErrorInfo) {
12335   // if(x == e) { x = d; } else { v = x; }
12336   if (auto *IS = dyn_cast<IfStmt>(S))
12337     return checkForm3(IS, ErrorInfo);
12338 
12339   auto *CS = dyn_cast<CompoundStmt>(S);
12340   if (!CS) {
12341     ErrorInfo.Error = ErrorTy::NotCompoundStmt;
12342     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
12343     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12344     return false;
12345   }
12346   if (CS->body_empty()) {
12347     ErrorInfo.Error = ErrorTy::NoStmt;
12348     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12349     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12350     return false;
12351   }
12352 
12353   // { if(x == e) { x = d; } else { v = x; } }
12354   if (CS->size() == 1) {
12355     auto *IS = dyn_cast<IfStmt>(CS->body_front());
12356     if (!IS) {
12357       ErrorInfo.Error = ErrorTy::NotIfStmt;
12358       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->body_front()->getBeginLoc();
12359       ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12360           CS->body_front()->getSourceRange();
12361       return false;
12362     }
12363 
12364     return checkForm3(IS, ErrorInfo);
12365   } else if (CS->size() == 2) {
12366     auto *S1 = CS->body_front();
12367     auto *S2 = CS->body_back();
12368 
12369     Stmt *UpdateStmt = nullptr;
12370     Stmt *CondUpdateStmt = nullptr;
12371     Stmt *CondExprStmt = nullptr;
12372 
12373     if (auto *BO = dyn_cast<BinaryOperator>(S1)) {
12374       // It could be one of the following cases:
12375       // { v = x; cond-update-stmt }
12376       // { v = x; cond-expr-stmt }
12377       // { cond-expr-stmt; v = x; }
12378       // form 45
12379       if (isa<BinaryOperator>(BO->getRHS()->IgnoreImpCasts()) ||
12380           isa<ConditionalOperator>(BO->getRHS()->IgnoreImpCasts())) {
12381         // check if form 45
12382         if (isa<IfStmt>(S2))
12383           return checkForm45(CS, ErrorInfo);
12384         // { cond-expr-stmt; v = x; }
12385         CondExprStmt = S1;
12386         UpdateStmt = S2;
12387       } else {
12388         IsPostfixUpdate = true;
12389         UpdateStmt = S1;
12390         if (isa<IfStmt>(S2)) {
12391           // { v = x; cond-update-stmt }
12392           CondUpdateStmt = S2;
12393         } else {
12394           // { v = x; cond-expr-stmt }
12395           CondExprStmt = S2;
12396         }
12397       }
12398     } else {
12399       // { cond-update-stmt v = x; }
12400       UpdateStmt = S2;
12401       CondUpdateStmt = S1;
12402     }
12403 
12404     auto CheckCondUpdateStmt = [this, &ErrorInfo](Stmt *CUS) {
12405       auto *IS = dyn_cast<IfStmt>(CUS);
12406       if (!IS) {
12407         ErrorInfo.Error = ErrorTy::NotIfStmt;
12408         ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CUS->getBeginLoc();
12409         ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CUS->getSourceRange();
12410         return false;
12411       }
12412 
12413       return checkCondUpdateStmt(IS, ErrorInfo);
12414     };
12415 
12416     // CheckUpdateStmt has to be called *after* CheckCondUpdateStmt.
12417     auto CheckUpdateStmt = [this, &ErrorInfo](Stmt *US) {
12418       auto *BO = dyn_cast<BinaryOperator>(US);
12419       if (!BO) {
12420         ErrorInfo.Error = ErrorTy::NotAnAssignment;
12421         ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = US->getBeginLoc();
12422         ErrorInfo.ErrorRange = ErrorInfo.NoteRange = US->getSourceRange();
12423         return false;
12424       }
12425       if (BO->getOpcode() != BO_Assign) {
12426         ErrorInfo.Error = ErrorTy::NotAnAssignment;
12427         ErrorInfo.ErrorLoc = BO->getExprLoc();
12428         ErrorInfo.NoteLoc = BO->getOperatorLoc();
12429         ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12430         return false;
12431       }
12432       if (!checkIfTwoExprsAreSame(ContextRef, this->X, BO->getRHS())) {
12433         ErrorInfo.Error = ErrorTy::InvalidAssignment;
12434         ErrorInfo.ErrorLoc = BO->getRHS()->getExprLoc();
12435         ErrorInfo.NoteLoc = this->X->getExprLoc();
12436         ErrorInfo.ErrorRange = BO->getRHS()->getSourceRange();
12437         ErrorInfo.NoteRange = this->X->getSourceRange();
12438         return false;
12439       }
12440 
12441       this->V = BO->getLHS();
12442 
12443       return true;
12444     };
12445 
12446     if (CondUpdateStmt && !CheckCondUpdateStmt(CondUpdateStmt))
12447       return false;
12448     if (CondExprStmt && !checkCondExprStmt(CondExprStmt, ErrorInfo))
12449       return false;
12450     if (!CheckUpdateStmt(UpdateStmt))
12451       return false;
12452   } else {
12453     ErrorInfo.Error = ErrorTy::MoreThanTwoStmts;
12454     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12455     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12456     return false;
12457   }
12458 
12459   return checkType(ErrorInfo);
12460 }
12461 } // namespace
12462 
12463 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
12464                                             Stmt *AStmt,
12465                                             SourceLocation StartLoc,
12466                                             SourceLocation EndLoc) {
12467   // Register location of the first atomic directive.
12468   DSAStack->addAtomicDirectiveLoc(StartLoc);
12469   if (!AStmt)
12470     return StmtError();
12471 
12472   // 1.2.2 OpenMP Language Terminology
12473   // Structured block - An executable statement with a single entry at the
12474   // top and a single exit at the bottom.
12475   // The point of exit cannot be a branch out of the structured block.
12476   // longjmp() and throw() must not violate the entry/exit criteria.
12477   OpenMPClauseKind AtomicKind = OMPC_unknown;
12478   SourceLocation AtomicKindLoc;
12479   OpenMPClauseKind MemOrderKind = OMPC_unknown;
12480   SourceLocation MemOrderLoc;
12481   bool MutexClauseEncountered = false;
12482   llvm::SmallSet<OpenMPClauseKind, 2> EncounteredAtomicKinds;
12483   for (const OMPClause *C : Clauses) {
12484     switch (C->getClauseKind()) {
12485     case OMPC_read:
12486     case OMPC_write:
12487     case OMPC_update:
12488       MutexClauseEncountered = true;
12489       [[fallthrough]];
12490     case OMPC_capture:
12491     case OMPC_compare: {
12492       if (AtomicKind != OMPC_unknown && MutexClauseEncountered) {
12493         Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
12494             << SourceRange(C->getBeginLoc(), C->getEndLoc());
12495         Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
12496             << getOpenMPClauseName(AtomicKind);
12497       } else {
12498         AtomicKind = C->getClauseKind();
12499         AtomicKindLoc = C->getBeginLoc();
12500         if (!EncounteredAtomicKinds.insert(C->getClauseKind()).second) {
12501           Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
12502               << SourceRange(C->getBeginLoc(), C->getEndLoc());
12503           Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
12504               << getOpenMPClauseName(AtomicKind);
12505         }
12506       }
12507       break;
12508     }
12509     case OMPC_seq_cst:
12510     case OMPC_acq_rel:
12511     case OMPC_acquire:
12512     case OMPC_release:
12513     case OMPC_relaxed: {
12514       if (MemOrderKind != OMPC_unknown) {
12515         Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
12516             << getOpenMPDirectiveName(OMPD_atomic) << 0
12517             << SourceRange(C->getBeginLoc(), C->getEndLoc());
12518         Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
12519             << getOpenMPClauseName(MemOrderKind);
12520       } else {
12521         MemOrderKind = C->getClauseKind();
12522         MemOrderLoc = C->getBeginLoc();
12523       }
12524       break;
12525     }
12526     // The following clauses are allowed, but we don't need to do anything here.
12527     case OMPC_hint:
12528       break;
12529     default:
12530       llvm_unreachable("unknown clause is encountered");
12531     }
12532   }
12533   bool IsCompareCapture = false;
12534   if (EncounteredAtomicKinds.contains(OMPC_compare) &&
12535       EncounteredAtomicKinds.contains(OMPC_capture)) {
12536     IsCompareCapture = true;
12537     AtomicKind = OMPC_compare;
12538   }
12539   // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions
12540   // If atomic-clause is read then memory-order-clause must not be acq_rel or
12541   // release.
12542   // If atomic-clause is write then memory-order-clause must not be acq_rel or
12543   // acquire.
12544   // If atomic-clause is update or not present then memory-order-clause must not
12545   // be acq_rel or acquire.
12546   if ((AtomicKind == OMPC_read &&
12547        (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) ||
12548       ((AtomicKind == OMPC_write || AtomicKind == OMPC_update ||
12549         AtomicKind == OMPC_unknown) &&
12550        (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) {
12551     SourceLocation Loc = AtomicKindLoc;
12552     if (AtomicKind == OMPC_unknown)
12553       Loc = StartLoc;
12554     Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
12555         << getOpenMPClauseName(AtomicKind)
12556         << (AtomicKind == OMPC_unknown ? 1 : 0)
12557         << getOpenMPClauseName(MemOrderKind);
12558     Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
12559         << getOpenMPClauseName(MemOrderKind);
12560   }
12561 
12562   Stmt *Body = AStmt;
12563   if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
12564     Body = EWC->getSubExpr();
12565 
12566   Expr *X = nullptr;
12567   Expr *V = nullptr;
12568   Expr *E = nullptr;
12569   Expr *UE = nullptr;
12570   Expr *D = nullptr;
12571   Expr *CE = nullptr;
12572   Expr *R = nullptr;
12573   bool IsXLHSInRHSPart = false;
12574   bool IsPostfixUpdate = false;
12575   bool IsFailOnly = false;
12576   // OpenMP [2.12.6, atomic Construct]
12577   // In the next expressions:
12578   // * x and v (as applicable) are both l-value expressions with scalar type.
12579   // * During the execution of an atomic region, multiple syntactic
12580   // occurrences of x must designate the same storage location.
12581   // * Neither of v and expr (as applicable) may access the storage location
12582   // designated by x.
12583   // * Neither of x and expr (as applicable) may access the storage location
12584   // designated by v.
12585   // * expr is an expression with scalar type.
12586   // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
12587   // * binop, binop=, ++, and -- are not overloaded operators.
12588   // * The expression x binop expr must be numerically equivalent to x binop
12589   // (expr). This requirement is satisfied if the operators in expr have
12590   // precedence greater than binop, or by using parentheses around expr or
12591   // subexpressions of expr.
12592   // * The expression expr binop x must be numerically equivalent to (expr)
12593   // binop x. This requirement is satisfied if the operators in expr have
12594   // precedence equal to or greater than binop, or by using parentheses around
12595   // expr or subexpressions of expr.
12596   // * For forms that allow multiple occurrences of x, the number of times
12597   // that x is evaluated is unspecified.
12598   if (AtomicKind == OMPC_read) {
12599     enum {
12600       NotAnExpression,
12601       NotAnAssignmentOp,
12602       NotAScalarType,
12603       NotAnLValue,
12604       NoError
12605     } ErrorFound = NoError;
12606     SourceLocation ErrorLoc, NoteLoc;
12607     SourceRange ErrorRange, NoteRange;
12608     // If clause is read:
12609     //  v = x;
12610     if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12611       const auto *AtomicBinOp =
12612           dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12613       if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
12614         X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
12615         V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
12616         if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
12617             (V->isInstantiationDependent() || V->getType()->isScalarType())) {
12618           if (!X->isLValue() || !V->isLValue()) {
12619             const Expr *NotLValueExpr = X->isLValue() ? V : X;
12620             ErrorFound = NotAnLValue;
12621             ErrorLoc = AtomicBinOp->getExprLoc();
12622             ErrorRange = AtomicBinOp->getSourceRange();
12623             NoteLoc = NotLValueExpr->getExprLoc();
12624             NoteRange = NotLValueExpr->getSourceRange();
12625           }
12626         } else if (!X->isInstantiationDependent() ||
12627                    !V->isInstantiationDependent()) {
12628           const Expr *NotScalarExpr =
12629               (X->isInstantiationDependent() || X->getType()->isScalarType())
12630                   ? V
12631                   : X;
12632           ErrorFound = NotAScalarType;
12633           ErrorLoc = AtomicBinOp->getExprLoc();
12634           ErrorRange = AtomicBinOp->getSourceRange();
12635           NoteLoc = NotScalarExpr->getExprLoc();
12636           NoteRange = NotScalarExpr->getSourceRange();
12637         }
12638       } else if (!AtomicBody->isInstantiationDependent()) {
12639         ErrorFound = NotAnAssignmentOp;
12640         ErrorLoc = AtomicBody->getExprLoc();
12641         ErrorRange = AtomicBody->getSourceRange();
12642         NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
12643                               : AtomicBody->getExprLoc();
12644         NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
12645                                 : AtomicBody->getSourceRange();
12646       }
12647     } else {
12648       ErrorFound = NotAnExpression;
12649       NoteLoc = ErrorLoc = Body->getBeginLoc();
12650       NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
12651     }
12652     if (ErrorFound != NoError) {
12653       Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
12654           << ErrorRange;
12655       Diag(NoteLoc, diag::note_omp_atomic_read_write)
12656           << ErrorFound << NoteRange;
12657       return StmtError();
12658     }
12659     if (CurContext->isDependentContext())
12660       V = X = nullptr;
12661   } else if (AtomicKind == OMPC_write) {
12662     enum {
12663       NotAnExpression,
12664       NotAnAssignmentOp,
12665       NotAScalarType,
12666       NotAnLValue,
12667       NoError
12668     } ErrorFound = NoError;
12669     SourceLocation ErrorLoc, NoteLoc;
12670     SourceRange ErrorRange, NoteRange;
12671     // If clause is write:
12672     //  x = expr;
12673     if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12674       const auto *AtomicBinOp =
12675           dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12676       if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
12677         X = AtomicBinOp->getLHS();
12678         E = AtomicBinOp->getRHS();
12679         if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
12680             (E->isInstantiationDependent() || E->getType()->isScalarType())) {
12681           if (!X->isLValue()) {
12682             ErrorFound = NotAnLValue;
12683             ErrorLoc = AtomicBinOp->getExprLoc();
12684             ErrorRange = AtomicBinOp->getSourceRange();
12685             NoteLoc = X->getExprLoc();
12686             NoteRange = X->getSourceRange();
12687           }
12688         } else if (!X->isInstantiationDependent() ||
12689                    !E->isInstantiationDependent()) {
12690           const Expr *NotScalarExpr =
12691               (X->isInstantiationDependent() || X->getType()->isScalarType())
12692                   ? E
12693                   : X;
12694           ErrorFound = NotAScalarType;
12695           ErrorLoc = AtomicBinOp->getExprLoc();
12696           ErrorRange = AtomicBinOp->getSourceRange();
12697           NoteLoc = NotScalarExpr->getExprLoc();
12698           NoteRange = NotScalarExpr->getSourceRange();
12699         }
12700       } else if (!AtomicBody->isInstantiationDependent()) {
12701         ErrorFound = NotAnAssignmentOp;
12702         ErrorLoc = AtomicBody->getExprLoc();
12703         ErrorRange = AtomicBody->getSourceRange();
12704         NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
12705                               : AtomicBody->getExprLoc();
12706         NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
12707                                 : AtomicBody->getSourceRange();
12708       }
12709     } else {
12710       ErrorFound = NotAnExpression;
12711       NoteLoc = ErrorLoc = Body->getBeginLoc();
12712       NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
12713     }
12714     if (ErrorFound != NoError) {
12715       Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
12716           << ErrorRange;
12717       Diag(NoteLoc, diag::note_omp_atomic_read_write)
12718           << ErrorFound << NoteRange;
12719       return StmtError();
12720     }
12721     if (CurContext->isDependentContext())
12722       E = X = nullptr;
12723   } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
12724     // If clause is update:
12725     //  x++;
12726     //  x--;
12727     //  ++x;
12728     //  --x;
12729     //  x binop= expr;
12730     //  x = x binop expr;
12731     //  x = expr binop x;
12732     OpenMPAtomicUpdateChecker Checker(*this);
12733     if (Checker.checkStatement(
12734             Body,
12735             (AtomicKind == OMPC_update)
12736                 ? diag::err_omp_atomic_update_not_expression_statement
12737                 : diag::err_omp_atomic_not_expression_statement,
12738             diag::note_omp_atomic_update))
12739       return StmtError();
12740     if (!CurContext->isDependentContext()) {
12741       E = Checker.getExpr();
12742       X = Checker.getX();
12743       UE = Checker.getUpdateExpr();
12744       IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12745     }
12746   } else if (AtomicKind == OMPC_capture) {
12747     enum {
12748       NotAnAssignmentOp,
12749       NotACompoundStatement,
12750       NotTwoSubstatements,
12751       NotASpecificExpression,
12752       NoError
12753     } ErrorFound = NoError;
12754     SourceLocation ErrorLoc, NoteLoc;
12755     SourceRange ErrorRange, NoteRange;
12756     if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12757       // If clause is a capture:
12758       //  v = x++;
12759       //  v = x--;
12760       //  v = ++x;
12761       //  v = --x;
12762       //  v = x binop= expr;
12763       //  v = x = x binop expr;
12764       //  v = x = expr binop x;
12765       const auto *AtomicBinOp =
12766           dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12767       if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
12768         V = AtomicBinOp->getLHS();
12769         Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
12770         OpenMPAtomicUpdateChecker Checker(*this);
12771         if (Checker.checkStatement(
12772                 Body, diag::err_omp_atomic_capture_not_expression_statement,
12773                 diag::note_omp_atomic_update))
12774           return StmtError();
12775         E = Checker.getExpr();
12776         X = Checker.getX();
12777         UE = Checker.getUpdateExpr();
12778         IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12779         IsPostfixUpdate = Checker.isPostfixUpdate();
12780       } else if (!AtomicBody->isInstantiationDependent()) {
12781         ErrorLoc = AtomicBody->getExprLoc();
12782         ErrorRange = AtomicBody->getSourceRange();
12783         NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
12784                               : AtomicBody->getExprLoc();
12785         NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
12786                                 : AtomicBody->getSourceRange();
12787         ErrorFound = NotAnAssignmentOp;
12788       }
12789       if (ErrorFound != NoError) {
12790         Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
12791             << ErrorRange;
12792         Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
12793         return StmtError();
12794       }
12795       if (CurContext->isDependentContext())
12796         UE = V = E = X = nullptr;
12797     } else {
12798       // If clause is a capture:
12799       //  { v = x; x = expr; }
12800       //  { v = x; x++; }
12801       //  { v = x; x--; }
12802       //  { v = x; ++x; }
12803       //  { v = x; --x; }
12804       //  { v = x; x binop= expr; }
12805       //  { v = x; x = x binop expr; }
12806       //  { v = x; x = expr binop x; }
12807       //  { x++; v = x; }
12808       //  { x--; v = x; }
12809       //  { ++x; v = x; }
12810       //  { --x; v = x; }
12811       //  { x binop= expr; v = x; }
12812       //  { x = x binop expr; v = x; }
12813       //  { x = expr binop x; v = x; }
12814       if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
12815         // Check that this is { expr1; expr2; }
12816         if (CS->size() == 2) {
12817           Stmt *First = CS->body_front();
12818           Stmt *Second = CS->body_back();
12819           if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
12820             First = EWC->getSubExpr()->IgnoreParenImpCasts();
12821           if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
12822             Second = EWC->getSubExpr()->IgnoreParenImpCasts();
12823           // Need to find what subexpression is 'v' and what is 'x'.
12824           OpenMPAtomicUpdateChecker Checker(*this);
12825           bool IsUpdateExprFound = !Checker.checkStatement(Second);
12826           BinaryOperator *BinOp = nullptr;
12827           if (IsUpdateExprFound) {
12828             BinOp = dyn_cast<BinaryOperator>(First);
12829             IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
12830           }
12831           if (IsUpdateExprFound && !CurContext->isDependentContext()) {
12832             //  { v = x; x++; }
12833             //  { v = x; x--; }
12834             //  { v = x; ++x; }
12835             //  { v = x; --x; }
12836             //  { v = x; x binop= expr; }
12837             //  { v = x; x = x binop expr; }
12838             //  { v = x; x = expr binop x; }
12839             // Check that the first expression has form v = x.
12840             Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
12841             llvm::FoldingSetNodeID XId, PossibleXId;
12842             Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
12843             PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
12844             IsUpdateExprFound = XId == PossibleXId;
12845             if (IsUpdateExprFound) {
12846               V = BinOp->getLHS();
12847               X = Checker.getX();
12848               E = Checker.getExpr();
12849               UE = Checker.getUpdateExpr();
12850               IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12851               IsPostfixUpdate = true;
12852             }
12853           }
12854           if (!IsUpdateExprFound) {
12855             IsUpdateExprFound = !Checker.checkStatement(First);
12856             BinOp = nullptr;
12857             if (IsUpdateExprFound) {
12858               BinOp = dyn_cast<BinaryOperator>(Second);
12859               IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
12860             }
12861             if (IsUpdateExprFound && !CurContext->isDependentContext()) {
12862               //  { x++; v = x; }
12863               //  { x--; v = x; }
12864               //  { ++x; v = x; }
12865               //  { --x; v = x; }
12866               //  { x binop= expr; v = x; }
12867               //  { x = x binop expr; v = x; }
12868               //  { x = expr binop x; v = x; }
12869               // Check that the second expression has form v = x.
12870               Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
12871               llvm::FoldingSetNodeID XId, PossibleXId;
12872               Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
12873               PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
12874               IsUpdateExprFound = XId == PossibleXId;
12875               if (IsUpdateExprFound) {
12876                 V = BinOp->getLHS();
12877                 X = Checker.getX();
12878                 E = Checker.getExpr();
12879                 UE = Checker.getUpdateExpr();
12880                 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12881                 IsPostfixUpdate = false;
12882               }
12883             }
12884           }
12885           if (!IsUpdateExprFound) {
12886             //  { v = x; x = expr; }
12887             auto *FirstExpr = dyn_cast<Expr>(First);
12888             auto *SecondExpr = dyn_cast<Expr>(Second);
12889             if (!FirstExpr || !SecondExpr ||
12890                 !(FirstExpr->isInstantiationDependent() ||
12891                   SecondExpr->isInstantiationDependent())) {
12892               auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
12893               if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
12894                 ErrorFound = NotAnAssignmentOp;
12895                 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
12896                                                 : First->getBeginLoc();
12897                 NoteRange = ErrorRange = FirstBinOp
12898                                              ? FirstBinOp->getSourceRange()
12899                                              : SourceRange(ErrorLoc, ErrorLoc);
12900               } else {
12901                 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
12902                 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
12903                   ErrorFound = NotAnAssignmentOp;
12904                   NoteLoc = ErrorLoc = SecondBinOp
12905                                            ? SecondBinOp->getOperatorLoc()
12906                                            : Second->getBeginLoc();
12907                   NoteRange = ErrorRange =
12908                       SecondBinOp ? SecondBinOp->getSourceRange()
12909                                   : SourceRange(ErrorLoc, ErrorLoc);
12910                 } else {
12911                   Expr *PossibleXRHSInFirst =
12912                       FirstBinOp->getRHS()->IgnoreParenImpCasts();
12913                   Expr *PossibleXLHSInSecond =
12914                       SecondBinOp->getLHS()->IgnoreParenImpCasts();
12915                   llvm::FoldingSetNodeID X1Id, X2Id;
12916                   PossibleXRHSInFirst->Profile(X1Id, Context,
12917                                                /*Canonical=*/true);
12918                   PossibleXLHSInSecond->Profile(X2Id, Context,
12919                                                 /*Canonical=*/true);
12920                   IsUpdateExprFound = X1Id == X2Id;
12921                   if (IsUpdateExprFound) {
12922                     V = FirstBinOp->getLHS();
12923                     X = SecondBinOp->getLHS();
12924                     E = SecondBinOp->getRHS();
12925                     UE = nullptr;
12926                     IsXLHSInRHSPart = false;
12927                     IsPostfixUpdate = true;
12928                   } else {
12929                     ErrorFound = NotASpecificExpression;
12930                     ErrorLoc = FirstBinOp->getExprLoc();
12931                     ErrorRange = FirstBinOp->getSourceRange();
12932                     NoteLoc = SecondBinOp->getLHS()->getExprLoc();
12933                     NoteRange = SecondBinOp->getRHS()->getSourceRange();
12934                   }
12935                 }
12936               }
12937             }
12938           }
12939         } else {
12940           NoteLoc = ErrorLoc = Body->getBeginLoc();
12941           NoteRange = ErrorRange =
12942               SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
12943           ErrorFound = NotTwoSubstatements;
12944         }
12945       } else {
12946         NoteLoc = ErrorLoc = Body->getBeginLoc();
12947         NoteRange = ErrorRange =
12948             SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
12949         ErrorFound = NotACompoundStatement;
12950       }
12951     }
12952     if (ErrorFound != NoError) {
12953       Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
12954           << ErrorRange;
12955       Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
12956       return StmtError();
12957     }
12958     if (CurContext->isDependentContext())
12959       UE = V = E = X = nullptr;
12960   } else if (AtomicKind == OMPC_compare) {
12961     if (IsCompareCapture) {
12962       OpenMPAtomicCompareCaptureChecker::ErrorInfoTy ErrorInfo;
12963       OpenMPAtomicCompareCaptureChecker Checker(*this);
12964       if (!Checker.checkStmt(Body, ErrorInfo)) {
12965         Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare_capture)
12966             << ErrorInfo.ErrorRange;
12967         Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare)
12968             << ErrorInfo.Error << ErrorInfo.NoteRange;
12969         return StmtError();
12970       }
12971       X = Checker.getX();
12972       E = Checker.getE();
12973       D = Checker.getD();
12974       CE = Checker.getCond();
12975       V = Checker.getV();
12976       R = Checker.getR();
12977       // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'.
12978       IsXLHSInRHSPart = Checker.isXBinopExpr();
12979       IsFailOnly = Checker.isFailOnly();
12980       IsPostfixUpdate = Checker.isPostfixUpdate();
12981     } else {
12982       OpenMPAtomicCompareChecker::ErrorInfoTy ErrorInfo;
12983       OpenMPAtomicCompareChecker Checker(*this);
12984       if (!Checker.checkStmt(Body, ErrorInfo)) {
12985         Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare)
12986             << ErrorInfo.ErrorRange;
12987         Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare)
12988           << ErrorInfo.Error << ErrorInfo.NoteRange;
12989         return StmtError();
12990       }
12991       X = Checker.getX();
12992       E = Checker.getE();
12993       D = Checker.getD();
12994       CE = Checker.getCond();
12995       // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'.
12996       IsXLHSInRHSPart = Checker.isXBinopExpr();
12997     }
12998   }
12999 
13000   setFunctionHasBranchProtectedScope();
13001 
13002   return OMPAtomicDirective::Create(
13003       Context, StartLoc, EndLoc, Clauses, AStmt,
13004       {X, V, R, E, UE, D, CE, IsXLHSInRHSPart, IsPostfixUpdate, IsFailOnly});
13005 }
13006 
13007 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
13008                                             Stmt *AStmt,
13009                                             SourceLocation StartLoc,
13010                                             SourceLocation EndLoc) {
13011   if (!AStmt)
13012     return StmtError();
13013 
13014   auto *CS = cast<CapturedStmt>(AStmt);
13015   // 1.2.2 OpenMP Language Terminology
13016   // Structured block - An executable statement with a single entry at the
13017   // top and a single exit at the bottom.
13018   // The point of exit cannot be a branch out of the structured block.
13019   // longjmp() and throw() must not violate the entry/exit criteria.
13020   CS->getCapturedDecl()->setNothrow();
13021   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
13022        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13023     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13024     // 1.2.2 OpenMP Language Terminology
13025     // Structured block - An executable statement with a single entry at the
13026     // top and a single exit at the bottom.
13027     // The point of exit cannot be a branch out of the structured block.
13028     // longjmp() and throw() must not violate the entry/exit criteria.
13029     CS->getCapturedDecl()->setNothrow();
13030   }
13031 
13032   // OpenMP [2.16, Nesting of Regions]
13033   // If specified, a teams construct must be contained within a target
13034   // construct. That target construct must contain no statements or directives
13035   // outside of the teams construct.
13036   if (DSAStack->hasInnerTeamsRegion()) {
13037     const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
13038     bool OMPTeamsFound = true;
13039     if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
13040       auto I = CS->body_begin();
13041       while (I != CS->body_end()) {
13042         const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
13043         if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) ||
13044             OMPTeamsFound) {
13045 
13046           OMPTeamsFound = false;
13047           break;
13048         }
13049         ++I;
13050       }
13051       assert(I != CS->body_end() && "Not found statement");
13052       S = *I;
13053     } else {
13054       const auto *OED = dyn_cast<OMPExecutableDirective>(S);
13055       OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
13056     }
13057     if (!OMPTeamsFound) {
13058       Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
13059       Diag(DSAStack->getInnerTeamsRegionLoc(),
13060            diag::note_omp_nested_teams_construct_here);
13061       Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
13062           << isa<OMPExecutableDirective>(S);
13063       return StmtError();
13064     }
13065   }
13066 
13067   setFunctionHasBranchProtectedScope();
13068 
13069   return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
13070 }
13071 
13072 StmtResult
13073 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
13074                                          Stmt *AStmt, SourceLocation StartLoc,
13075                                          SourceLocation EndLoc) {
13076   if (!AStmt)
13077     return StmtError();
13078 
13079   auto *CS = cast<CapturedStmt>(AStmt);
13080   // 1.2.2 OpenMP Language Terminology
13081   // Structured block - An executable statement with a single entry at the
13082   // top and a single exit at the bottom.
13083   // The point of exit cannot be a branch out of the structured block.
13084   // longjmp() and throw() must not violate the entry/exit criteria.
13085   CS->getCapturedDecl()->setNothrow();
13086   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
13087        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13088     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13089     // 1.2.2 OpenMP Language Terminology
13090     // Structured block - An executable statement with a single entry at the
13091     // top and a single exit at the bottom.
13092     // The point of exit cannot be a branch out of the structured block.
13093     // longjmp() and throw() must not violate the entry/exit criteria.
13094     CS->getCapturedDecl()->setNothrow();
13095   }
13096 
13097   setFunctionHasBranchProtectedScope();
13098 
13099   return OMPTargetParallelDirective::Create(
13100       Context, StartLoc, EndLoc, Clauses, AStmt,
13101       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
13102 }
13103 
13104 StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
13105     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13106     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13107   if (!AStmt)
13108     return StmtError();
13109 
13110   auto *CS = cast<CapturedStmt>(AStmt);
13111   // 1.2.2 OpenMP Language Terminology
13112   // Structured block - An executable statement with a single entry at the
13113   // top and a single exit at the bottom.
13114   // The point of exit cannot be a branch out of the structured block.
13115   // longjmp() and throw() must not violate the entry/exit criteria.
13116   CS->getCapturedDecl()->setNothrow();
13117   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
13118        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13119     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13120     // 1.2.2 OpenMP Language Terminology
13121     // Structured block - An executable statement with a single entry at the
13122     // top and a single exit at the bottom.
13123     // The point of exit cannot be a branch out of the structured block.
13124     // longjmp() and throw() must not violate the entry/exit criteria.
13125     CS->getCapturedDecl()->setNothrow();
13126   }
13127 
13128   OMPLoopBasedDirective::HelperExprs B;
13129   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13130   // define the nested loops number.
13131   unsigned NestedLoopCount =
13132       checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
13133                       getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
13134                       VarsWithImplicitDSA, B);
13135   if (NestedLoopCount == 0)
13136     return StmtError();
13137 
13138   assert((CurContext->isDependentContext() || B.builtAll()) &&
13139          "omp target parallel for loop exprs were not built");
13140 
13141   if (!CurContext->isDependentContext()) {
13142     // Finalize the clauses that need pre-built expressions for CodeGen.
13143     for (OMPClause *C : Clauses) {
13144       if (auto *LC = dyn_cast<OMPLinearClause>(C))
13145         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13146                                      B.NumIterations, *this, CurScope,
13147                                      DSAStack))
13148           return StmtError();
13149     }
13150   }
13151 
13152   setFunctionHasBranchProtectedScope();
13153   return OMPTargetParallelForDirective::Create(
13154       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13155       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
13156 }
13157 
13158 /// Check for existence of a map clause in the list of clauses.
13159 static bool hasClauses(ArrayRef<OMPClause *> Clauses,
13160                        const OpenMPClauseKind K) {
13161   return llvm::any_of(
13162       Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
13163 }
13164 
13165 template <typename... Params>
13166 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
13167                        const Params... ClauseTypes) {
13168   return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
13169 }
13170 
13171 /// Check if the variables in the mapping clause are externally visible.
13172 static bool isClauseMappable(ArrayRef<OMPClause *> Clauses) {
13173   for (const OMPClause *C : Clauses) {
13174     if (auto *TC = dyn_cast<OMPToClause>(C))
13175       return llvm::all_of(TC->all_decls(), [](ValueDecl *VD) {
13176         return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
13177                (VD->isExternallyVisible() &&
13178                 VD->getVisibility() != HiddenVisibility);
13179       });
13180     else if (auto *FC = dyn_cast<OMPFromClause>(C))
13181       return llvm::all_of(FC->all_decls(), [](ValueDecl *VD) {
13182         return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
13183                (VD->isExternallyVisible() &&
13184                 VD->getVisibility() != HiddenVisibility);
13185       });
13186   }
13187 
13188   return true;
13189 }
13190 
13191 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
13192                                                 Stmt *AStmt,
13193                                                 SourceLocation StartLoc,
13194                                                 SourceLocation EndLoc) {
13195   if (!AStmt)
13196     return StmtError();
13197 
13198   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13199 
13200   // OpenMP [2.12.2, target data Construct, Restrictions]
13201   // At least one map, use_device_addr or use_device_ptr clause must appear on
13202   // the directive.
13203   if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) &&
13204       (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) {
13205     StringRef Expected;
13206     if (LangOpts.OpenMP < 50)
13207       Expected = "'map' or 'use_device_ptr'";
13208     else
13209       Expected = "'map', 'use_device_ptr', or 'use_device_addr'";
13210     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13211         << Expected << getOpenMPDirectiveName(OMPD_target_data);
13212     return StmtError();
13213   }
13214 
13215   setFunctionHasBranchProtectedScope();
13216 
13217   return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
13218                                         AStmt);
13219 }
13220 
13221 StmtResult
13222 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
13223                                           SourceLocation StartLoc,
13224                                           SourceLocation EndLoc, Stmt *AStmt) {
13225   if (!AStmt)
13226     return StmtError();
13227 
13228   auto *CS = cast<CapturedStmt>(AStmt);
13229   // 1.2.2 OpenMP Language Terminology
13230   // Structured block - An executable statement with a single entry at the
13231   // top and a single exit at the bottom.
13232   // The point of exit cannot be a branch out of the structured block.
13233   // longjmp() and throw() must not violate the entry/exit criteria.
13234   CS->getCapturedDecl()->setNothrow();
13235   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
13236        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13237     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13238     // 1.2.2 OpenMP Language Terminology
13239     // Structured block - An executable statement with a single entry at the
13240     // top and a single exit at the bottom.
13241     // The point of exit cannot be a branch out of the structured block.
13242     // longjmp() and throw() must not violate the entry/exit criteria.
13243     CS->getCapturedDecl()->setNothrow();
13244   }
13245 
13246   // OpenMP [2.10.2, Restrictions, p. 99]
13247   // At least one map clause must appear on the directive.
13248   if (!hasClauses(Clauses, OMPC_map)) {
13249     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13250         << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
13251     return StmtError();
13252   }
13253 
13254   return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
13255                                              AStmt);
13256 }
13257 
13258 StmtResult
13259 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
13260                                          SourceLocation StartLoc,
13261                                          SourceLocation EndLoc, Stmt *AStmt) {
13262   if (!AStmt)
13263     return StmtError();
13264 
13265   auto *CS = cast<CapturedStmt>(AStmt);
13266   // 1.2.2 OpenMP Language Terminology
13267   // Structured block - An executable statement with a single entry at the
13268   // top and a single exit at the bottom.
13269   // The point of exit cannot be a branch out of the structured block.
13270   // longjmp() and throw() must not violate the entry/exit criteria.
13271   CS->getCapturedDecl()->setNothrow();
13272   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
13273        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13274     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13275     // 1.2.2 OpenMP Language Terminology
13276     // Structured block - An executable statement with a single entry at the
13277     // top and a single exit at the bottom.
13278     // The point of exit cannot be a branch out of the structured block.
13279     // longjmp() and throw() must not violate the entry/exit criteria.
13280     CS->getCapturedDecl()->setNothrow();
13281   }
13282 
13283   // OpenMP [2.10.3, Restrictions, p. 102]
13284   // At least one map clause must appear on the directive.
13285   if (!hasClauses(Clauses, OMPC_map)) {
13286     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13287         << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
13288     return StmtError();
13289   }
13290 
13291   return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
13292                                             AStmt);
13293 }
13294 
13295 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
13296                                                   SourceLocation StartLoc,
13297                                                   SourceLocation EndLoc,
13298                                                   Stmt *AStmt) {
13299   if (!AStmt)
13300     return StmtError();
13301 
13302   auto *CS = cast<CapturedStmt>(AStmt);
13303   // 1.2.2 OpenMP Language Terminology
13304   // Structured block - An executable statement with a single entry at the
13305   // top and a single exit at the bottom.
13306   // The point of exit cannot be a branch out of the structured block.
13307   // longjmp() and throw() must not violate the entry/exit criteria.
13308   CS->getCapturedDecl()->setNothrow();
13309   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
13310        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13311     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13312     // 1.2.2 OpenMP Language Terminology
13313     // Structured block - An executable statement with a single entry at the
13314     // top and a single exit at the bottom.
13315     // The point of exit cannot be a branch out of the structured block.
13316     // longjmp() and throw() must not violate the entry/exit criteria.
13317     CS->getCapturedDecl()->setNothrow();
13318   }
13319 
13320   if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
13321     Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
13322     return StmtError();
13323   }
13324 
13325   if (!isClauseMappable(Clauses)) {
13326     Diag(StartLoc, diag::err_omp_cannot_update_with_internal_linkage);
13327     return StmtError();
13328   }
13329 
13330   return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
13331                                           AStmt);
13332 }
13333 
13334 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
13335                                            Stmt *AStmt, SourceLocation StartLoc,
13336                                            SourceLocation EndLoc) {
13337   if (!AStmt)
13338     return StmtError();
13339 
13340   // Report affected OpenMP target offloading behavior when in HIP lang-mode.
13341   if (getLangOpts().HIP && (DSAStack->getParentDirective() == OMPD_target))
13342     Diag(StartLoc, diag::warn_hip_omp_target_directives);
13343 
13344   auto *CS = cast<CapturedStmt>(AStmt);
13345   // 1.2.2 OpenMP Language Terminology
13346   // Structured block - An executable statement with a single entry at the
13347   // top and a single exit at the bottom.
13348   // The point of exit cannot be a branch out of the structured block.
13349   // longjmp() and throw() must not violate the entry/exit criteria.
13350   CS->getCapturedDecl()->setNothrow();
13351 
13352   setFunctionHasBranchProtectedScope();
13353 
13354   DSAStack->setParentTeamsRegionLoc(StartLoc);
13355 
13356   return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
13357 }
13358 
13359 StmtResult
13360 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
13361                                             SourceLocation EndLoc,
13362                                             OpenMPDirectiveKind CancelRegion) {
13363   if (DSAStack->isParentNowaitRegion()) {
13364     Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
13365     return StmtError();
13366   }
13367   if (DSAStack->isParentOrderedRegion()) {
13368     Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
13369     return StmtError();
13370   }
13371   return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
13372                                                CancelRegion);
13373 }
13374 
13375 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
13376                                             SourceLocation StartLoc,
13377                                             SourceLocation EndLoc,
13378                                             OpenMPDirectiveKind CancelRegion) {
13379   if (DSAStack->isParentNowaitRegion()) {
13380     Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
13381     return StmtError();
13382   }
13383   if (DSAStack->isParentOrderedRegion()) {
13384     Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
13385     return StmtError();
13386   }
13387   DSAStack->setParentCancelRegion(/*Cancel=*/true);
13388   return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
13389                                     CancelRegion);
13390 }
13391 
13392 static bool checkReductionClauseWithNogroup(Sema &S,
13393                                             ArrayRef<OMPClause *> Clauses) {
13394   const OMPClause *ReductionClause = nullptr;
13395   const OMPClause *NogroupClause = nullptr;
13396   for (const OMPClause *C : Clauses) {
13397     if (C->getClauseKind() == OMPC_reduction) {
13398       ReductionClause = C;
13399       if (NogroupClause)
13400         break;
13401       continue;
13402     }
13403     if (C->getClauseKind() == OMPC_nogroup) {
13404       NogroupClause = C;
13405       if (ReductionClause)
13406         break;
13407       continue;
13408     }
13409   }
13410   if (ReductionClause && NogroupClause) {
13411     S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
13412         << SourceRange(NogroupClause->getBeginLoc(),
13413                        NogroupClause->getEndLoc());
13414     return true;
13415   }
13416   return false;
13417 }
13418 
13419 StmtResult Sema::ActOnOpenMPTaskLoopDirective(
13420     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13421     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13422   if (!AStmt)
13423     return StmtError();
13424 
13425   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13426   OMPLoopBasedDirective::HelperExprs B;
13427   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13428   // define the nested loops number.
13429   unsigned NestedLoopCount =
13430       checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
13431                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13432                       VarsWithImplicitDSA, B);
13433   if (NestedLoopCount == 0)
13434     return StmtError();
13435 
13436   assert((CurContext->isDependentContext() || B.builtAll()) &&
13437          "omp for loop exprs were not built");
13438 
13439   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13440   // The grainsize clause and num_tasks clause are mutually exclusive and may
13441   // not appear on the same taskloop directive.
13442   if (checkMutuallyExclusiveClauses(*this, Clauses,
13443                                     {OMPC_grainsize, OMPC_num_tasks}))
13444     return StmtError();
13445   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13446   // If a reduction clause is present on the taskloop directive, the nogroup
13447   // clause must not be specified.
13448   if (checkReductionClauseWithNogroup(*this, Clauses))
13449     return StmtError();
13450 
13451   setFunctionHasBranchProtectedScope();
13452   return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
13453                                       NestedLoopCount, Clauses, AStmt, B,
13454                                       DSAStack->isCancelRegion());
13455 }
13456 
13457 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
13458     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13459     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13460   if (!AStmt)
13461     return StmtError();
13462 
13463   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13464   OMPLoopBasedDirective::HelperExprs B;
13465   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13466   // define the nested loops number.
13467   unsigned NestedLoopCount =
13468       checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
13469                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13470                       VarsWithImplicitDSA, B);
13471   if (NestedLoopCount == 0)
13472     return StmtError();
13473 
13474   assert((CurContext->isDependentContext() || B.builtAll()) &&
13475          "omp for loop exprs were not built");
13476 
13477   if (!CurContext->isDependentContext()) {
13478     // Finalize the clauses that need pre-built expressions for CodeGen.
13479     for (OMPClause *C : Clauses) {
13480       if (auto *LC = dyn_cast<OMPLinearClause>(C))
13481         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13482                                      B.NumIterations, *this, CurScope,
13483                                      DSAStack))
13484           return StmtError();
13485     }
13486   }
13487 
13488   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13489   // The grainsize clause and num_tasks clause are mutually exclusive and may
13490   // not appear on the same taskloop directive.
13491   if (checkMutuallyExclusiveClauses(*this, Clauses,
13492                                     {OMPC_grainsize, OMPC_num_tasks}))
13493     return StmtError();
13494   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13495   // If a reduction clause is present on the taskloop directive, the nogroup
13496   // clause must not be specified.
13497   if (checkReductionClauseWithNogroup(*this, Clauses))
13498     return StmtError();
13499   if (checkSimdlenSafelenSpecified(*this, Clauses))
13500     return StmtError();
13501 
13502   setFunctionHasBranchProtectedScope();
13503   return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
13504                                           NestedLoopCount, Clauses, AStmt, B);
13505 }
13506 
13507 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective(
13508     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13509     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13510   if (!AStmt)
13511     return StmtError();
13512 
13513   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13514   OMPLoopBasedDirective::HelperExprs B;
13515   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13516   // define the nested loops number.
13517   unsigned NestedLoopCount =
13518       checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses),
13519                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13520                       VarsWithImplicitDSA, B);
13521   if (NestedLoopCount == 0)
13522     return StmtError();
13523 
13524   assert((CurContext->isDependentContext() || B.builtAll()) &&
13525          "omp for loop exprs were not built");
13526 
13527   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13528   // The grainsize clause and num_tasks clause are mutually exclusive and may
13529   // not appear on the same taskloop directive.
13530   if (checkMutuallyExclusiveClauses(*this, Clauses,
13531                                     {OMPC_grainsize, OMPC_num_tasks}))
13532     return StmtError();
13533   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13534   // If a reduction clause is present on the taskloop directive, the nogroup
13535   // clause must not be specified.
13536   if (checkReductionClauseWithNogroup(*this, Clauses))
13537     return StmtError();
13538 
13539   setFunctionHasBranchProtectedScope();
13540   return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc,
13541                                             NestedLoopCount, Clauses, AStmt, B,
13542                                             DSAStack->isCancelRegion());
13543 }
13544 
13545 StmtResult Sema::ActOnOpenMPMaskedTaskLoopDirective(
13546     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13547     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13548   if (!AStmt)
13549     return StmtError();
13550 
13551   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13552   OMPLoopBasedDirective::HelperExprs B;
13553   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13554   // define the nested loops number.
13555   unsigned NestedLoopCount =
13556       checkOpenMPLoop(OMPD_masked_taskloop, getCollapseNumberExpr(Clauses),
13557                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13558                       VarsWithImplicitDSA, B);
13559   if (NestedLoopCount == 0)
13560     return StmtError();
13561 
13562   assert((CurContext->isDependentContext() || B.builtAll()) &&
13563          "omp for loop exprs were not built");
13564 
13565   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13566   // The grainsize clause and num_tasks clause are mutually exclusive and may
13567   // not appear on the same taskloop directive.
13568   if (checkMutuallyExclusiveClauses(*this, Clauses,
13569                                     {OMPC_grainsize, OMPC_num_tasks}))
13570     return StmtError();
13571   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13572   // If a reduction clause is present on the taskloop directive, the nogroup
13573   // clause must not be specified.
13574   if (checkReductionClauseWithNogroup(*this, Clauses))
13575     return StmtError();
13576 
13577   setFunctionHasBranchProtectedScope();
13578   return OMPMaskedTaskLoopDirective::Create(Context, StartLoc, EndLoc,
13579                                             NestedLoopCount, Clauses, AStmt, B,
13580                                             DSAStack->isCancelRegion());
13581 }
13582 
13583 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective(
13584     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13585     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13586   if (!AStmt)
13587     return StmtError();
13588 
13589   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13590   OMPLoopBasedDirective::HelperExprs B;
13591   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13592   // define the nested loops number.
13593   unsigned NestedLoopCount =
13594       checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses),
13595                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13596                       VarsWithImplicitDSA, B);
13597   if (NestedLoopCount == 0)
13598     return StmtError();
13599 
13600   assert((CurContext->isDependentContext() || B.builtAll()) &&
13601          "omp for loop exprs were not built");
13602 
13603   if (!CurContext->isDependentContext()) {
13604     // Finalize the clauses that need pre-built expressions for CodeGen.
13605     for (OMPClause *C : Clauses) {
13606       if (auto *LC = dyn_cast<OMPLinearClause>(C))
13607         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13608                                      B.NumIterations, *this, CurScope,
13609                                      DSAStack))
13610           return StmtError();
13611     }
13612   }
13613 
13614   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13615   // The grainsize clause and num_tasks clause are mutually exclusive and may
13616   // not appear on the same taskloop directive.
13617   if (checkMutuallyExclusiveClauses(*this, Clauses,
13618                                     {OMPC_grainsize, OMPC_num_tasks}))
13619     return StmtError();
13620   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13621   // If a reduction clause is present on the taskloop directive, the nogroup
13622   // clause must not be specified.
13623   if (checkReductionClauseWithNogroup(*this, Clauses))
13624     return StmtError();
13625   if (checkSimdlenSafelenSpecified(*this, Clauses))
13626     return StmtError();
13627 
13628   setFunctionHasBranchProtectedScope();
13629   return OMPMasterTaskLoopSimdDirective::Create(
13630       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13631 }
13632 
13633 StmtResult Sema::ActOnOpenMPMaskedTaskLoopSimdDirective(
13634     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13635     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13636   if (!AStmt)
13637     return StmtError();
13638 
13639   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13640   OMPLoopBasedDirective::HelperExprs B;
13641   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13642   // define the nested loops number.
13643   unsigned NestedLoopCount =
13644       checkOpenMPLoop(OMPD_masked_taskloop_simd, getCollapseNumberExpr(Clauses),
13645                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13646                       VarsWithImplicitDSA, B);
13647   if (NestedLoopCount == 0)
13648     return StmtError();
13649 
13650   assert((CurContext->isDependentContext() || B.builtAll()) &&
13651          "omp for loop exprs were not built");
13652 
13653   if (!CurContext->isDependentContext()) {
13654     // Finalize the clauses that need pre-built expressions for CodeGen.
13655     for (OMPClause *C : Clauses) {
13656       if (auto *LC = dyn_cast<OMPLinearClause>(C))
13657         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13658                                      B.NumIterations, *this, CurScope,
13659                                      DSAStack))
13660           return StmtError();
13661     }
13662   }
13663 
13664   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13665   // The grainsize clause and num_tasks clause are mutually exclusive and may
13666   // not appear on the same taskloop directive.
13667   if (checkMutuallyExclusiveClauses(*this, Clauses,
13668                                     {OMPC_grainsize, OMPC_num_tasks}))
13669     return StmtError();
13670   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13671   // If a reduction clause is present on the taskloop directive, the nogroup
13672   // clause must not be specified.
13673   if (checkReductionClauseWithNogroup(*this, Clauses))
13674     return StmtError();
13675   if (checkSimdlenSafelenSpecified(*this, Clauses))
13676     return StmtError();
13677 
13678   setFunctionHasBranchProtectedScope();
13679   return OMPMaskedTaskLoopSimdDirective::Create(
13680       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13681 }
13682 
13683 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective(
13684     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13685     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13686   if (!AStmt)
13687     return StmtError();
13688 
13689   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13690   auto *CS = cast<CapturedStmt>(AStmt);
13691   // 1.2.2 OpenMP Language Terminology
13692   // Structured block - An executable statement with a single entry at the
13693   // top and a single exit at the bottom.
13694   // The point of exit cannot be a branch out of the structured block.
13695   // longjmp() and throw() must not violate the entry/exit criteria.
13696   CS->getCapturedDecl()->setNothrow();
13697   for (int ThisCaptureLevel =
13698            getOpenMPCaptureLevels(OMPD_parallel_master_taskloop);
13699        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13700     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13701     // 1.2.2 OpenMP Language Terminology
13702     // Structured block - An executable statement with a single entry at the
13703     // top and a single exit at the bottom.
13704     // The point of exit cannot be a branch out of the structured block.
13705     // longjmp() and throw() must not violate the entry/exit criteria.
13706     CS->getCapturedDecl()->setNothrow();
13707   }
13708 
13709   OMPLoopBasedDirective::HelperExprs B;
13710   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13711   // define the nested loops number.
13712   unsigned NestedLoopCount = checkOpenMPLoop(
13713       OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses),
13714       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
13715       VarsWithImplicitDSA, B);
13716   if (NestedLoopCount == 0)
13717     return StmtError();
13718 
13719   assert((CurContext->isDependentContext() || B.builtAll()) &&
13720          "omp for loop exprs were not built");
13721 
13722   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13723   // The grainsize clause and num_tasks clause are mutually exclusive and may
13724   // not appear on the same taskloop directive.
13725   if (checkMutuallyExclusiveClauses(*this, Clauses,
13726                                     {OMPC_grainsize, OMPC_num_tasks}))
13727     return StmtError();
13728   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13729   // If a reduction clause is present on the taskloop directive, the nogroup
13730   // clause must not be specified.
13731   if (checkReductionClauseWithNogroup(*this, Clauses))
13732     return StmtError();
13733 
13734   setFunctionHasBranchProtectedScope();
13735   return OMPParallelMasterTaskLoopDirective::Create(
13736       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13737       DSAStack->isCancelRegion());
13738 }
13739 
13740 StmtResult Sema::ActOnOpenMPParallelMaskedTaskLoopDirective(
13741     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13742     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13743   if (!AStmt)
13744     return StmtError();
13745 
13746   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13747   auto *CS = cast<CapturedStmt>(AStmt);
13748   // 1.2.2 OpenMP Language Terminology
13749   // Structured block - An executable statement with a single entry at the
13750   // top and a single exit at the bottom.
13751   // The point of exit cannot be a branch out of the structured block.
13752   // longjmp() and throw() must not violate the entry/exit criteria.
13753   CS->getCapturedDecl()->setNothrow();
13754   for (int ThisCaptureLevel =
13755            getOpenMPCaptureLevels(OMPD_parallel_masked_taskloop);
13756        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13757     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13758     // 1.2.2 OpenMP Language Terminology
13759     // Structured block - An executable statement with a single entry at the
13760     // top and a single exit at the bottom.
13761     // The point of exit cannot be a branch out of the structured block.
13762     // longjmp() and throw() must not violate the entry/exit criteria.
13763     CS->getCapturedDecl()->setNothrow();
13764   }
13765 
13766   OMPLoopBasedDirective::HelperExprs B;
13767   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13768   // define the nested loops number.
13769   unsigned NestedLoopCount = checkOpenMPLoop(
13770       OMPD_parallel_masked_taskloop, getCollapseNumberExpr(Clauses),
13771       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
13772       VarsWithImplicitDSA, B);
13773   if (NestedLoopCount == 0)
13774     return StmtError();
13775 
13776   assert((CurContext->isDependentContext() || B.builtAll()) &&
13777          "omp for loop exprs were not built");
13778 
13779   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13780   // The grainsize clause and num_tasks clause are mutually exclusive and may
13781   // not appear on the same taskloop directive.
13782   if (checkMutuallyExclusiveClauses(*this, Clauses,
13783                                     {OMPC_grainsize, OMPC_num_tasks}))
13784     return StmtError();
13785   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13786   // If a reduction clause is present on the taskloop directive, the nogroup
13787   // clause must not be specified.
13788   if (checkReductionClauseWithNogroup(*this, Clauses))
13789     return StmtError();
13790 
13791   setFunctionHasBranchProtectedScope();
13792   return OMPParallelMaskedTaskLoopDirective::Create(
13793       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13794       DSAStack->isCancelRegion());
13795 }
13796 
13797 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective(
13798     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13799     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13800   if (!AStmt)
13801     return StmtError();
13802 
13803   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13804   auto *CS = cast<CapturedStmt>(AStmt);
13805   // 1.2.2 OpenMP Language Terminology
13806   // Structured block - An executable statement with a single entry at the
13807   // top and a single exit at the bottom.
13808   // The point of exit cannot be a branch out of the structured block.
13809   // longjmp() and throw() must not violate the entry/exit criteria.
13810   CS->getCapturedDecl()->setNothrow();
13811   for (int ThisCaptureLevel =
13812            getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd);
13813        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13814     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13815     // 1.2.2 OpenMP Language Terminology
13816     // Structured block - An executable statement with a single entry at the
13817     // top and a single exit at the bottom.
13818     // The point of exit cannot be a branch out of the structured block.
13819     // longjmp() and throw() must not violate the entry/exit criteria.
13820     CS->getCapturedDecl()->setNothrow();
13821   }
13822 
13823   OMPLoopBasedDirective::HelperExprs B;
13824   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13825   // define the nested loops number.
13826   unsigned NestedLoopCount = checkOpenMPLoop(
13827       OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses),
13828       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
13829       VarsWithImplicitDSA, B);
13830   if (NestedLoopCount == 0)
13831     return StmtError();
13832 
13833   assert((CurContext->isDependentContext() || B.builtAll()) &&
13834          "omp for loop exprs were not built");
13835 
13836   if (!CurContext->isDependentContext()) {
13837     // Finalize the clauses that need pre-built expressions for CodeGen.
13838     for (OMPClause *C : Clauses) {
13839       if (auto *LC = dyn_cast<OMPLinearClause>(C))
13840         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13841                                      B.NumIterations, *this, CurScope,
13842                                      DSAStack))
13843           return StmtError();
13844     }
13845   }
13846 
13847   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13848   // The grainsize clause and num_tasks clause are mutually exclusive and may
13849   // not appear on the same taskloop directive.
13850   if (checkMutuallyExclusiveClauses(*this, Clauses,
13851                                     {OMPC_grainsize, OMPC_num_tasks}))
13852     return StmtError();
13853   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13854   // If a reduction clause is present on the taskloop directive, the nogroup
13855   // clause must not be specified.
13856   if (checkReductionClauseWithNogroup(*this, Clauses))
13857     return StmtError();
13858   if (checkSimdlenSafelenSpecified(*this, Clauses))
13859     return StmtError();
13860 
13861   setFunctionHasBranchProtectedScope();
13862   return OMPParallelMasterTaskLoopSimdDirective::Create(
13863       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13864 }
13865 
13866 StmtResult Sema::ActOnOpenMPParallelMaskedTaskLoopSimdDirective(
13867     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13868     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13869   if (!AStmt)
13870     return StmtError();
13871 
13872   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13873   auto *CS = cast<CapturedStmt>(AStmt);
13874   // 1.2.2 OpenMP Language Terminology
13875   // Structured block - An executable statement with a single entry at the
13876   // top and a single exit at the bottom.
13877   // The point of exit cannot be a branch out of the structured block.
13878   // longjmp() and throw() must not violate the entry/exit criteria.
13879   CS->getCapturedDecl()->setNothrow();
13880   for (int ThisCaptureLevel =
13881            getOpenMPCaptureLevels(OMPD_parallel_masked_taskloop_simd);
13882        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13883     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13884     // 1.2.2 OpenMP Language Terminology
13885     // Structured block - An executable statement with a single entry at the
13886     // top and a single exit at the bottom.
13887     // The point of exit cannot be a branch out of the structured block.
13888     // longjmp() and throw() must not violate the entry/exit criteria.
13889     CS->getCapturedDecl()->setNothrow();
13890   }
13891 
13892   OMPLoopBasedDirective::HelperExprs B;
13893   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13894   // define the nested loops number.
13895   unsigned NestedLoopCount = checkOpenMPLoop(
13896       OMPD_parallel_masked_taskloop_simd, getCollapseNumberExpr(Clauses),
13897       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
13898       VarsWithImplicitDSA, B);
13899   if (NestedLoopCount == 0)
13900     return StmtError();
13901 
13902   assert((CurContext->isDependentContext() || B.builtAll()) &&
13903          "omp for loop exprs were not built");
13904 
13905   if (!CurContext->isDependentContext()) {
13906     // Finalize the clauses that need pre-built expressions for CodeGen.
13907     for (OMPClause *C : Clauses) {
13908       if (auto *LC = dyn_cast<OMPLinearClause>(C))
13909         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13910                                      B.NumIterations, *this, CurScope,
13911                                      DSAStack))
13912           return StmtError();
13913     }
13914   }
13915 
13916   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13917   // The grainsize clause and num_tasks clause are mutually exclusive and may
13918   // not appear on the same taskloop directive.
13919   if (checkMutuallyExclusiveClauses(*this, Clauses,
13920                                     {OMPC_grainsize, OMPC_num_tasks}))
13921     return StmtError();
13922   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13923   // If a reduction clause is present on the taskloop directive, the nogroup
13924   // clause must not be specified.
13925   if (checkReductionClauseWithNogroup(*this, Clauses))
13926     return StmtError();
13927   if (checkSimdlenSafelenSpecified(*this, Clauses))
13928     return StmtError();
13929 
13930   setFunctionHasBranchProtectedScope();
13931   return OMPParallelMaskedTaskLoopSimdDirective::Create(
13932       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13933 }
13934 
13935 StmtResult Sema::ActOnOpenMPDistributeDirective(
13936     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13937     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13938   if (!AStmt)
13939     return StmtError();
13940 
13941   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13942   OMPLoopBasedDirective::HelperExprs B;
13943   // In presence of clause 'collapse' with number of loops, it will
13944   // define the nested loops number.
13945   unsigned NestedLoopCount =
13946       checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
13947                       nullptr /*ordered not a clause on distribute*/, AStmt,
13948                       *this, *DSAStack, VarsWithImplicitDSA, B);
13949   if (NestedLoopCount == 0)
13950     return StmtError();
13951 
13952   assert((CurContext->isDependentContext() || B.builtAll()) &&
13953          "omp for loop exprs were not built");
13954 
13955   setFunctionHasBranchProtectedScope();
13956   return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
13957                                         NestedLoopCount, Clauses, AStmt, B);
13958 }
13959 
13960 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
13961     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13962     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13963   if (!AStmt)
13964     return StmtError();
13965 
13966   auto *CS = cast<CapturedStmt>(AStmt);
13967   // 1.2.2 OpenMP Language Terminology
13968   // Structured block - An executable statement with a single entry at the
13969   // top and a single exit at the bottom.
13970   // The point of exit cannot be a branch out of the structured block.
13971   // longjmp() and throw() must not violate the entry/exit criteria.
13972   CS->getCapturedDecl()->setNothrow();
13973   for (int ThisCaptureLevel =
13974            getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
13975        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13976     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13977     // 1.2.2 OpenMP Language Terminology
13978     // Structured block - An executable statement with a single entry at the
13979     // top and a single exit at the bottom.
13980     // The point of exit cannot be a branch out of the structured block.
13981     // longjmp() and throw() must not violate the entry/exit criteria.
13982     CS->getCapturedDecl()->setNothrow();
13983   }
13984 
13985   OMPLoopBasedDirective::HelperExprs B;
13986   // In presence of clause 'collapse' with number of loops, it will
13987   // define the nested loops number.
13988   unsigned NestedLoopCount = checkOpenMPLoop(
13989       OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
13990       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
13991       VarsWithImplicitDSA, B);
13992   if (NestedLoopCount == 0)
13993     return StmtError();
13994 
13995   assert((CurContext->isDependentContext() || B.builtAll()) &&
13996          "omp for loop exprs were not built");
13997 
13998   setFunctionHasBranchProtectedScope();
13999   return OMPDistributeParallelForDirective::Create(
14000       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14001       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
14002 }
14003 
14004 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
14005     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14006     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14007   if (!AStmt)
14008     return StmtError();
14009 
14010   auto *CS = cast<CapturedStmt>(AStmt);
14011   // 1.2.2 OpenMP Language Terminology
14012   // Structured block - An executable statement with a single entry at the
14013   // top and a single exit at the bottom.
14014   // The point of exit cannot be a branch out of the structured block.
14015   // longjmp() and throw() must not violate the entry/exit criteria.
14016   CS->getCapturedDecl()->setNothrow();
14017   for (int ThisCaptureLevel =
14018            getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
14019        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14020     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14021     // 1.2.2 OpenMP Language Terminology
14022     // Structured block - An executable statement with a single entry at the
14023     // top and a single exit at the bottom.
14024     // The point of exit cannot be a branch out of the structured block.
14025     // longjmp() and throw() must not violate the entry/exit criteria.
14026     CS->getCapturedDecl()->setNothrow();
14027   }
14028 
14029   OMPLoopBasedDirective::HelperExprs B;
14030   // In presence of clause 'collapse' with number of loops, it will
14031   // define the nested loops number.
14032   unsigned NestedLoopCount = checkOpenMPLoop(
14033       OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
14034       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14035       VarsWithImplicitDSA, B);
14036   if (NestedLoopCount == 0)
14037     return StmtError();
14038 
14039   assert((CurContext->isDependentContext() || B.builtAll()) &&
14040          "omp for loop exprs were not built");
14041 
14042   if (!CurContext->isDependentContext()) {
14043     // Finalize the clauses that need pre-built expressions for CodeGen.
14044     for (OMPClause *C : Clauses) {
14045       if (auto *LC = dyn_cast<OMPLinearClause>(C))
14046         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14047                                      B.NumIterations, *this, CurScope,
14048                                      DSAStack))
14049           return StmtError();
14050     }
14051   }
14052 
14053   if (checkSimdlenSafelenSpecified(*this, Clauses))
14054     return StmtError();
14055 
14056   setFunctionHasBranchProtectedScope();
14057   return OMPDistributeParallelForSimdDirective::Create(
14058       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14059 }
14060 
14061 StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
14062     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14063     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14064   if (!AStmt)
14065     return StmtError();
14066 
14067   auto *CS = cast<CapturedStmt>(AStmt);
14068   // 1.2.2 OpenMP Language Terminology
14069   // Structured block - An executable statement with a single entry at the
14070   // top and a single exit at the bottom.
14071   // The point of exit cannot be a branch out of the structured block.
14072   // longjmp() and throw() must not violate the entry/exit criteria.
14073   CS->getCapturedDecl()->setNothrow();
14074   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
14075        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14076     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14077     // 1.2.2 OpenMP Language Terminology
14078     // Structured block - An executable statement with a single entry at the
14079     // top and a single exit at the bottom.
14080     // The point of exit cannot be a branch out of the structured block.
14081     // longjmp() and throw() must not violate the entry/exit criteria.
14082     CS->getCapturedDecl()->setNothrow();
14083   }
14084 
14085   OMPLoopBasedDirective::HelperExprs B;
14086   // In presence of clause 'collapse' with number of loops, it will
14087   // define the nested loops number.
14088   unsigned NestedLoopCount =
14089       checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
14090                       nullptr /*ordered not a clause on distribute*/, CS, *this,
14091                       *DSAStack, VarsWithImplicitDSA, B);
14092   if (NestedLoopCount == 0)
14093     return StmtError();
14094 
14095   assert((CurContext->isDependentContext() || B.builtAll()) &&
14096          "omp for loop exprs were not built");
14097 
14098   if (!CurContext->isDependentContext()) {
14099     // Finalize the clauses that need pre-built expressions for CodeGen.
14100     for (OMPClause *C : Clauses) {
14101       if (auto *LC = dyn_cast<OMPLinearClause>(C))
14102         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14103                                      B.NumIterations, *this, CurScope,
14104                                      DSAStack))
14105           return StmtError();
14106     }
14107   }
14108 
14109   if (checkSimdlenSafelenSpecified(*this, Clauses))
14110     return StmtError();
14111 
14112   setFunctionHasBranchProtectedScope();
14113   return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
14114                                             NestedLoopCount, Clauses, AStmt, B);
14115 }
14116 
14117 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
14118     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14119     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14120   if (!AStmt)
14121     return StmtError();
14122 
14123   auto *CS = cast<CapturedStmt>(AStmt);
14124   // 1.2.2 OpenMP Language Terminology
14125   // Structured block - An executable statement with a single entry at the
14126   // top and a single exit at the bottom.
14127   // The point of exit cannot be a branch out of the structured block.
14128   // longjmp() and throw() must not violate the entry/exit criteria.
14129   CS->getCapturedDecl()->setNothrow();
14130   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
14131        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14132     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14133     // 1.2.2 OpenMP Language Terminology
14134     // Structured block - An executable statement with a single entry at the
14135     // top and a single exit at the bottom.
14136     // The point of exit cannot be a branch out of the structured block.
14137     // longjmp() and throw() must not violate the entry/exit criteria.
14138     CS->getCapturedDecl()->setNothrow();
14139   }
14140 
14141   OMPLoopBasedDirective::HelperExprs B;
14142   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
14143   // define the nested loops number.
14144   unsigned NestedLoopCount = checkOpenMPLoop(
14145       OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
14146       getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, VarsWithImplicitDSA,
14147       B);
14148   if (NestedLoopCount == 0)
14149     return StmtError();
14150 
14151   assert((CurContext->isDependentContext() || B.builtAll()) &&
14152          "omp target parallel for simd loop exprs were not built");
14153 
14154   if (!CurContext->isDependentContext()) {
14155     // Finalize the clauses that need pre-built expressions for CodeGen.
14156     for (OMPClause *C : Clauses) {
14157       if (auto *LC = dyn_cast<OMPLinearClause>(C))
14158         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14159                                      B.NumIterations, *this, CurScope,
14160                                      DSAStack))
14161           return StmtError();
14162     }
14163   }
14164   if (checkSimdlenSafelenSpecified(*this, Clauses))
14165     return StmtError();
14166 
14167   setFunctionHasBranchProtectedScope();
14168   return OMPTargetParallelForSimdDirective::Create(
14169       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14170 }
14171 
14172 StmtResult Sema::ActOnOpenMPTargetSimdDirective(
14173     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14174     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14175   if (!AStmt)
14176     return StmtError();
14177 
14178   auto *CS = cast<CapturedStmt>(AStmt);
14179   // 1.2.2 OpenMP Language Terminology
14180   // Structured block - An executable statement with a single entry at the
14181   // top and a single exit at the bottom.
14182   // The point of exit cannot be a branch out of the structured block.
14183   // longjmp() and throw() must not violate the entry/exit criteria.
14184   CS->getCapturedDecl()->setNothrow();
14185   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
14186        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14187     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14188     // 1.2.2 OpenMP Language Terminology
14189     // Structured block - An executable statement with a single entry at the
14190     // top and a single exit at the bottom.
14191     // The point of exit cannot be a branch out of the structured block.
14192     // longjmp() and throw() must not violate the entry/exit criteria.
14193     CS->getCapturedDecl()->setNothrow();
14194   }
14195 
14196   OMPLoopBasedDirective::HelperExprs B;
14197   // In presence of clause 'collapse' with number of loops, it will define the
14198   // nested loops number.
14199   unsigned NestedLoopCount =
14200       checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
14201                       getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
14202                       VarsWithImplicitDSA, B);
14203   if (NestedLoopCount == 0)
14204     return StmtError();
14205 
14206   assert((CurContext->isDependentContext() || B.builtAll()) &&
14207          "omp target simd loop exprs were not built");
14208 
14209   if (!CurContext->isDependentContext()) {
14210     // Finalize the clauses that need pre-built expressions for CodeGen.
14211     for (OMPClause *C : Clauses) {
14212       if (auto *LC = dyn_cast<OMPLinearClause>(C))
14213         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14214                                      B.NumIterations, *this, CurScope,
14215                                      DSAStack))
14216           return StmtError();
14217     }
14218   }
14219 
14220   if (checkSimdlenSafelenSpecified(*this, Clauses))
14221     return StmtError();
14222 
14223   setFunctionHasBranchProtectedScope();
14224   return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
14225                                         NestedLoopCount, Clauses, AStmt, B);
14226 }
14227 
14228 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
14229     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14230     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14231   if (!AStmt)
14232     return StmtError();
14233 
14234   auto *CS = cast<CapturedStmt>(AStmt);
14235   // 1.2.2 OpenMP Language Terminology
14236   // Structured block - An executable statement with a single entry at the
14237   // top and a single exit at the bottom.
14238   // The point of exit cannot be a branch out of the structured block.
14239   // longjmp() and throw() must not violate the entry/exit criteria.
14240   CS->getCapturedDecl()->setNothrow();
14241   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
14242        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14243     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14244     // 1.2.2 OpenMP Language Terminology
14245     // Structured block - An executable statement with a single entry at the
14246     // top and a single exit at the bottom.
14247     // The point of exit cannot be a branch out of the structured block.
14248     // longjmp() and throw() must not violate the entry/exit criteria.
14249     CS->getCapturedDecl()->setNothrow();
14250   }
14251 
14252   OMPLoopBasedDirective::HelperExprs B;
14253   // In presence of clause 'collapse' with number of loops, it will
14254   // define the nested loops number.
14255   unsigned NestedLoopCount =
14256       checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
14257                       nullptr /*ordered not a clause on distribute*/, CS, *this,
14258                       *DSAStack, VarsWithImplicitDSA, B);
14259   if (NestedLoopCount == 0)
14260     return StmtError();
14261 
14262   assert((CurContext->isDependentContext() || B.builtAll()) &&
14263          "omp teams distribute loop exprs were not built");
14264 
14265   setFunctionHasBranchProtectedScope();
14266 
14267   DSAStack->setParentTeamsRegionLoc(StartLoc);
14268 
14269   return OMPTeamsDistributeDirective::Create(
14270       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14271 }
14272 
14273 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
14274     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14275     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14276   if (!AStmt)
14277     return StmtError();
14278 
14279   auto *CS = cast<CapturedStmt>(AStmt);
14280   // 1.2.2 OpenMP Language Terminology
14281   // Structured block - An executable statement with a single entry at the
14282   // top and a single exit at the bottom.
14283   // The point of exit cannot be a branch out of the structured block.
14284   // longjmp() and throw() must not violate the entry/exit criteria.
14285   CS->getCapturedDecl()->setNothrow();
14286   for (int ThisCaptureLevel =
14287            getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
14288        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14289     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14290     // 1.2.2 OpenMP Language Terminology
14291     // Structured block - An executable statement with a single entry at the
14292     // top and a single exit at the bottom.
14293     // The point of exit cannot be a branch out of the structured block.
14294     // longjmp() and throw() must not violate the entry/exit criteria.
14295     CS->getCapturedDecl()->setNothrow();
14296   }
14297 
14298   OMPLoopBasedDirective::HelperExprs B;
14299   // In presence of clause 'collapse' with number of loops, it will
14300   // define the nested loops number.
14301   unsigned NestedLoopCount = checkOpenMPLoop(
14302       OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
14303       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14304       VarsWithImplicitDSA, B);
14305 
14306   if (NestedLoopCount == 0)
14307     return StmtError();
14308 
14309   assert((CurContext->isDependentContext() || B.builtAll()) &&
14310          "omp teams distribute simd loop exprs were not built");
14311 
14312   if (!CurContext->isDependentContext()) {
14313     // Finalize the clauses that need pre-built expressions for CodeGen.
14314     for (OMPClause *C : Clauses) {
14315       if (auto *LC = dyn_cast<OMPLinearClause>(C))
14316         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14317                                      B.NumIterations, *this, CurScope,
14318                                      DSAStack))
14319           return StmtError();
14320     }
14321   }
14322 
14323   if (checkSimdlenSafelenSpecified(*this, Clauses))
14324     return StmtError();
14325 
14326   setFunctionHasBranchProtectedScope();
14327 
14328   DSAStack->setParentTeamsRegionLoc(StartLoc);
14329 
14330   return OMPTeamsDistributeSimdDirective::Create(
14331       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14332 }
14333 
14334 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
14335     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14336     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14337   if (!AStmt)
14338     return StmtError();
14339 
14340   auto *CS = cast<CapturedStmt>(AStmt);
14341   // 1.2.2 OpenMP Language Terminology
14342   // Structured block - An executable statement with a single entry at the
14343   // top and a single exit at the bottom.
14344   // The point of exit cannot be a branch out of the structured block.
14345   // longjmp() and throw() must not violate the entry/exit criteria.
14346   CS->getCapturedDecl()->setNothrow();
14347 
14348   for (int ThisCaptureLevel =
14349            getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
14350        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14351     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14352     // 1.2.2 OpenMP Language Terminology
14353     // Structured block - An executable statement with a single entry at the
14354     // top and a single exit at the bottom.
14355     // The point of exit cannot be a branch out of the structured block.
14356     // longjmp() and throw() must not violate the entry/exit criteria.
14357     CS->getCapturedDecl()->setNothrow();
14358   }
14359 
14360   OMPLoopBasedDirective::HelperExprs B;
14361   // In presence of clause 'collapse' with number of loops, it will
14362   // define the nested loops number.
14363   unsigned NestedLoopCount = checkOpenMPLoop(
14364       OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
14365       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14366       VarsWithImplicitDSA, B);
14367 
14368   if (NestedLoopCount == 0)
14369     return StmtError();
14370 
14371   assert((CurContext->isDependentContext() || B.builtAll()) &&
14372          "omp for loop exprs were not built");
14373 
14374   if (!CurContext->isDependentContext()) {
14375     // Finalize the clauses that need pre-built expressions for CodeGen.
14376     for (OMPClause *C : Clauses) {
14377       if (auto *LC = dyn_cast<OMPLinearClause>(C))
14378         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14379                                      B.NumIterations, *this, CurScope,
14380                                      DSAStack))
14381           return StmtError();
14382     }
14383   }
14384 
14385   if (checkSimdlenSafelenSpecified(*this, Clauses))
14386     return StmtError();
14387 
14388   setFunctionHasBranchProtectedScope();
14389 
14390   DSAStack->setParentTeamsRegionLoc(StartLoc);
14391 
14392   return OMPTeamsDistributeParallelForSimdDirective::Create(
14393       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14394 }
14395 
14396 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
14397     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14398     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14399   if (!AStmt)
14400     return StmtError();
14401 
14402   auto *CS = cast<CapturedStmt>(AStmt);
14403   // 1.2.2 OpenMP Language Terminology
14404   // Structured block - An executable statement with a single entry at the
14405   // top and a single exit at the bottom.
14406   // The point of exit cannot be a branch out of the structured block.
14407   // longjmp() and throw() must not violate the entry/exit criteria.
14408   CS->getCapturedDecl()->setNothrow();
14409 
14410   for (int ThisCaptureLevel =
14411            getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
14412        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14413     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14414     // 1.2.2 OpenMP Language Terminology
14415     // Structured block - An executable statement with a single entry at the
14416     // top and a single exit at the bottom.
14417     // The point of exit cannot be a branch out of the structured block.
14418     // longjmp() and throw() must not violate the entry/exit criteria.
14419     CS->getCapturedDecl()->setNothrow();
14420   }
14421 
14422   OMPLoopBasedDirective::HelperExprs B;
14423   // In presence of clause 'collapse' with number of loops, it will
14424   // define the nested loops number.
14425   unsigned NestedLoopCount = checkOpenMPLoop(
14426       OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
14427       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14428       VarsWithImplicitDSA, B);
14429 
14430   if (NestedLoopCount == 0)
14431     return StmtError();
14432 
14433   assert((CurContext->isDependentContext() || B.builtAll()) &&
14434          "omp for loop exprs were not built");
14435 
14436   setFunctionHasBranchProtectedScope();
14437 
14438   DSAStack->setParentTeamsRegionLoc(StartLoc);
14439 
14440   return OMPTeamsDistributeParallelForDirective::Create(
14441       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14442       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
14443 }
14444 
14445 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
14446                                                  Stmt *AStmt,
14447                                                  SourceLocation StartLoc,
14448                                                  SourceLocation EndLoc) {
14449   if (!AStmt)
14450     return StmtError();
14451 
14452   auto *CS = cast<CapturedStmt>(AStmt);
14453   // 1.2.2 OpenMP Language Terminology
14454   // Structured block - An executable statement with a single entry at the
14455   // top and a single exit at the bottom.
14456   // The point of exit cannot be a branch out of the structured block.
14457   // longjmp() and throw() must not violate the entry/exit criteria.
14458   CS->getCapturedDecl()->setNothrow();
14459 
14460   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
14461        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14462     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14463     // 1.2.2 OpenMP Language Terminology
14464     // Structured block - An executable statement with a single entry at the
14465     // top and a single exit at the bottom.
14466     // The point of exit cannot be a branch out of the structured block.
14467     // longjmp() and throw() must not violate the entry/exit criteria.
14468     CS->getCapturedDecl()->setNothrow();
14469   }
14470   setFunctionHasBranchProtectedScope();
14471 
14472   return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
14473                                          AStmt);
14474 }
14475 
14476 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
14477     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14478     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14479   if (!AStmt)
14480     return StmtError();
14481 
14482   auto *CS = cast<CapturedStmt>(AStmt);
14483   // 1.2.2 OpenMP Language Terminology
14484   // Structured block - An executable statement with a single entry at the
14485   // top and a single exit at the bottom.
14486   // The point of exit cannot be a branch out of the structured block.
14487   // longjmp() and throw() must not violate the entry/exit criteria.
14488   CS->getCapturedDecl()->setNothrow();
14489   for (int ThisCaptureLevel =
14490            getOpenMPCaptureLevels(OMPD_target_teams_distribute);
14491        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14492     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14493     // 1.2.2 OpenMP Language Terminology
14494     // Structured block - An executable statement with a single entry at the
14495     // top and a single exit at the bottom.
14496     // The point of exit cannot be a branch out of the structured block.
14497     // longjmp() and throw() must not violate the entry/exit criteria.
14498     CS->getCapturedDecl()->setNothrow();
14499   }
14500 
14501   OMPLoopBasedDirective::HelperExprs B;
14502   // In presence of clause 'collapse' with number of loops, it will
14503   // define the nested loops number.
14504   unsigned NestedLoopCount = checkOpenMPLoop(
14505       OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
14506       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14507       VarsWithImplicitDSA, B);
14508   if (NestedLoopCount == 0)
14509     return StmtError();
14510 
14511   assert((CurContext->isDependentContext() || B.builtAll()) &&
14512          "omp target teams distribute loop exprs were not built");
14513 
14514   setFunctionHasBranchProtectedScope();
14515   return OMPTargetTeamsDistributeDirective::Create(
14516       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14517 }
14518 
14519 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
14520     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14521     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14522   if (!AStmt)
14523     return StmtError();
14524 
14525   auto *CS = cast<CapturedStmt>(AStmt);
14526   // 1.2.2 OpenMP Language Terminology
14527   // Structured block - An executable statement with a single entry at the
14528   // top and a single exit at the bottom.
14529   // The point of exit cannot be a branch out of the structured block.
14530   // longjmp() and throw() must not violate the entry/exit criteria.
14531   CS->getCapturedDecl()->setNothrow();
14532   for (int ThisCaptureLevel =
14533            getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
14534        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14535     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14536     // 1.2.2 OpenMP Language Terminology
14537     // Structured block - An executable statement with a single entry at the
14538     // top and a single exit at the bottom.
14539     // The point of exit cannot be a branch out of the structured block.
14540     // longjmp() and throw() must not violate the entry/exit criteria.
14541     CS->getCapturedDecl()->setNothrow();
14542   }
14543 
14544   OMPLoopBasedDirective::HelperExprs B;
14545   // In presence of clause 'collapse' with number of loops, it will
14546   // define the nested loops number.
14547   unsigned NestedLoopCount = checkOpenMPLoop(
14548       OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
14549       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14550       VarsWithImplicitDSA, B);
14551   if (NestedLoopCount == 0)
14552     return StmtError();
14553 
14554   assert((CurContext->isDependentContext() || B.builtAll()) &&
14555          "omp target teams distribute parallel for loop exprs were not built");
14556 
14557   if (!CurContext->isDependentContext()) {
14558     // Finalize the clauses that need pre-built expressions for CodeGen.
14559     for (OMPClause *C : Clauses) {
14560       if (auto *LC = dyn_cast<OMPLinearClause>(C))
14561         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14562                                      B.NumIterations, *this, CurScope,
14563                                      DSAStack))
14564           return StmtError();
14565     }
14566   }
14567 
14568   setFunctionHasBranchProtectedScope();
14569   return OMPTargetTeamsDistributeParallelForDirective::Create(
14570       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14571       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
14572 }
14573 
14574 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
14575     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14576     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14577   if (!AStmt)
14578     return StmtError();
14579 
14580   auto *CS = cast<CapturedStmt>(AStmt);
14581   // 1.2.2 OpenMP Language Terminology
14582   // Structured block - An executable statement with a single entry at the
14583   // top and a single exit at the bottom.
14584   // The point of exit cannot be a branch out of the structured block.
14585   // longjmp() and throw() must not violate the entry/exit criteria.
14586   CS->getCapturedDecl()->setNothrow();
14587   for (int ThisCaptureLevel = getOpenMPCaptureLevels(
14588            OMPD_target_teams_distribute_parallel_for_simd);
14589        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14590     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14591     // 1.2.2 OpenMP Language Terminology
14592     // Structured block - An executable statement with a single entry at the
14593     // top and a single exit at the bottom.
14594     // The point of exit cannot be a branch out of the structured block.
14595     // longjmp() and throw() must not violate the entry/exit criteria.
14596     CS->getCapturedDecl()->setNothrow();
14597   }
14598 
14599   OMPLoopBasedDirective::HelperExprs B;
14600   // In presence of clause 'collapse' with number of loops, it will
14601   // define the nested loops number.
14602   unsigned NestedLoopCount =
14603       checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
14604                       getCollapseNumberExpr(Clauses),
14605                       nullptr /*ordered not a clause on distribute*/, CS, *this,
14606                       *DSAStack, VarsWithImplicitDSA, B);
14607   if (NestedLoopCount == 0)
14608     return StmtError();
14609 
14610   assert((CurContext->isDependentContext() || B.builtAll()) &&
14611          "omp target teams distribute parallel for simd loop exprs were not "
14612          "built");
14613 
14614   if (!CurContext->isDependentContext()) {
14615     // Finalize the clauses that need pre-built expressions for CodeGen.
14616     for (OMPClause *C : Clauses) {
14617       if (auto *LC = dyn_cast<OMPLinearClause>(C))
14618         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14619                                      B.NumIterations, *this, CurScope,
14620                                      DSAStack))
14621           return StmtError();
14622     }
14623   }
14624 
14625   if (checkSimdlenSafelenSpecified(*this, Clauses))
14626     return StmtError();
14627 
14628   setFunctionHasBranchProtectedScope();
14629   return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
14630       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14631 }
14632 
14633 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
14634     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14635     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14636   if (!AStmt)
14637     return StmtError();
14638 
14639   auto *CS = cast<CapturedStmt>(AStmt);
14640   // 1.2.2 OpenMP Language Terminology
14641   // Structured block - An executable statement with a single entry at the
14642   // top and a single exit at the bottom.
14643   // The point of exit cannot be a branch out of the structured block.
14644   // longjmp() and throw() must not violate the entry/exit criteria.
14645   CS->getCapturedDecl()->setNothrow();
14646   for (int ThisCaptureLevel =
14647            getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
14648        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14649     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14650     // 1.2.2 OpenMP Language Terminology
14651     // Structured block - An executable statement with a single entry at the
14652     // top and a single exit at the bottom.
14653     // The point of exit cannot be a branch out of the structured block.
14654     // longjmp() and throw() must not violate the entry/exit criteria.
14655     CS->getCapturedDecl()->setNothrow();
14656   }
14657 
14658   OMPLoopBasedDirective::HelperExprs B;
14659   // In presence of clause 'collapse' with number of loops, it will
14660   // define the nested loops number.
14661   unsigned NestedLoopCount = checkOpenMPLoop(
14662       OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
14663       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14664       VarsWithImplicitDSA, B);
14665   if (NestedLoopCount == 0)
14666     return StmtError();
14667 
14668   assert((CurContext->isDependentContext() || B.builtAll()) &&
14669          "omp target teams distribute simd loop exprs were not built");
14670 
14671   if (!CurContext->isDependentContext()) {
14672     // Finalize the clauses that need pre-built expressions for CodeGen.
14673     for (OMPClause *C : Clauses) {
14674       if (auto *LC = dyn_cast<OMPLinearClause>(C))
14675         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14676                                      B.NumIterations, *this, CurScope,
14677                                      DSAStack))
14678           return StmtError();
14679     }
14680   }
14681 
14682   if (checkSimdlenSafelenSpecified(*this, Clauses))
14683     return StmtError();
14684 
14685   setFunctionHasBranchProtectedScope();
14686   return OMPTargetTeamsDistributeSimdDirective::Create(
14687       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14688 }
14689 
14690 bool Sema::checkTransformableLoopNest(
14691     OpenMPDirectiveKind Kind, Stmt *AStmt, int NumLoops,
14692     SmallVectorImpl<OMPLoopBasedDirective::HelperExprs> &LoopHelpers,
14693     Stmt *&Body,
14694     SmallVectorImpl<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>>
14695         &OriginalInits) {
14696   OriginalInits.emplace_back();
14697   bool Result = OMPLoopBasedDirective::doForAllLoops(
14698       AStmt->IgnoreContainers(), /*TryImperfectlyNestedLoops=*/false, NumLoops,
14699       [this, &LoopHelpers, &Body, &OriginalInits, Kind](unsigned Cnt,
14700                                                         Stmt *CurStmt) {
14701         VarsWithInheritedDSAType TmpDSA;
14702         unsigned SingleNumLoops =
14703             checkOpenMPLoop(Kind, nullptr, nullptr, CurStmt, *this, *DSAStack,
14704                             TmpDSA, LoopHelpers[Cnt]);
14705         if (SingleNumLoops == 0)
14706           return true;
14707         assert(SingleNumLoops == 1 && "Expect single loop iteration space");
14708         if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
14709           OriginalInits.back().push_back(For->getInit());
14710           Body = For->getBody();
14711         } else {
14712           assert(isa<CXXForRangeStmt>(CurStmt) &&
14713                  "Expected canonical for or range-based for loops.");
14714           auto *CXXFor = cast<CXXForRangeStmt>(CurStmt);
14715           OriginalInits.back().push_back(CXXFor->getBeginStmt());
14716           Body = CXXFor->getBody();
14717         }
14718         OriginalInits.emplace_back();
14719         return false;
14720       },
14721       [&OriginalInits](OMPLoopBasedDirective *Transform) {
14722         Stmt *DependentPreInits;
14723         if (auto *Dir = dyn_cast<OMPTileDirective>(Transform))
14724           DependentPreInits = Dir->getPreInits();
14725         else if (auto *Dir = dyn_cast<OMPUnrollDirective>(Transform))
14726           DependentPreInits = Dir->getPreInits();
14727         else
14728           llvm_unreachable("Unhandled loop transformation");
14729         if (!DependentPreInits)
14730           return;
14731         llvm::append_range(OriginalInits.back(),
14732                            cast<DeclStmt>(DependentPreInits)->getDeclGroup());
14733       });
14734   assert(OriginalInits.back().empty() && "No preinit after innermost loop");
14735   OriginalInits.pop_back();
14736   return Result;
14737 }
14738 
14739 StmtResult Sema::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses,
14740                                           Stmt *AStmt, SourceLocation StartLoc,
14741                                           SourceLocation EndLoc) {
14742   auto SizesClauses =
14743       OMPExecutableDirective::getClausesOfKind<OMPSizesClause>(Clauses);
14744   if (SizesClauses.empty()) {
14745     // A missing 'sizes' clause is already reported by the parser.
14746     return StmtError();
14747   }
14748   const OMPSizesClause *SizesClause = *SizesClauses.begin();
14749   unsigned NumLoops = SizesClause->getNumSizes();
14750 
14751   // Empty statement should only be possible if there already was an error.
14752   if (!AStmt)
14753     return StmtError();
14754 
14755   // Verify and diagnose loop nest.
14756   SmallVector<OMPLoopBasedDirective::HelperExprs, 4> LoopHelpers(NumLoops);
14757   Stmt *Body = nullptr;
14758   SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, 4>
14759       OriginalInits;
14760   if (!checkTransformableLoopNest(OMPD_tile, AStmt, NumLoops, LoopHelpers, Body,
14761                                   OriginalInits))
14762     return StmtError();
14763 
14764   // Delay tiling to when template is completely instantiated.
14765   if (CurContext->isDependentContext())
14766     return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses,
14767                                     NumLoops, AStmt, nullptr, nullptr);
14768 
14769   SmallVector<Decl *, 4> PreInits;
14770 
14771   // Create iteration variables for the generated loops.
14772   SmallVector<VarDecl *, 4> FloorIndVars;
14773   SmallVector<VarDecl *, 4> TileIndVars;
14774   FloorIndVars.resize(NumLoops);
14775   TileIndVars.resize(NumLoops);
14776   for (unsigned I = 0; I < NumLoops; ++I) {
14777     OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
14778 
14779     assert(LoopHelper.Counters.size() == 1 &&
14780            "Expect single-dimensional loop iteration space");
14781     auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
14782     std::string OrigVarName = OrigCntVar->getNameInfo().getAsString();
14783     DeclRefExpr *IterVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
14784     QualType CntTy = IterVarRef->getType();
14785 
14786     // Iteration variable for the floor (i.e. outer) loop.
14787     {
14788       std::string FloorCntName =
14789           (Twine(".floor_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
14790       VarDecl *FloorCntDecl =
14791           buildVarDecl(*this, {}, CntTy, FloorCntName, nullptr, OrigCntVar);
14792       FloorIndVars[I] = FloorCntDecl;
14793     }
14794 
14795     // Iteration variable for the tile (i.e. inner) loop.
14796     {
14797       std::string TileCntName =
14798           (Twine(".tile_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
14799 
14800       // Reuse the iteration variable created by checkOpenMPLoop. It is also
14801       // used by the expressions to derive the original iteration variable's
14802       // value from the logical iteration number.
14803       auto *TileCntDecl = cast<VarDecl>(IterVarRef->getDecl());
14804       TileCntDecl->setDeclName(&PP.getIdentifierTable().get(TileCntName));
14805       TileIndVars[I] = TileCntDecl;
14806     }
14807     for (auto &P : OriginalInits[I]) {
14808       if (auto *D = P.dyn_cast<Decl *>())
14809         PreInits.push_back(D);
14810       else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>()))
14811         PreInits.append(PI->decl_begin(), PI->decl_end());
14812     }
14813     if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
14814       PreInits.append(PI->decl_begin(), PI->decl_end());
14815     // Gather declarations for the data members used as counters.
14816     for (Expr *CounterRef : LoopHelper.Counters) {
14817       auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
14818       if (isa<OMPCapturedExprDecl>(CounterDecl))
14819         PreInits.push_back(CounterDecl);
14820     }
14821   }
14822 
14823   // Once the original iteration values are set, append the innermost body.
14824   Stmt *Inner = Body;
14825 
14826   // Create tile loops from the inside to the outside.
14827   for (int I = NumLoops - 1; I >= 0; --I) {
14828     OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
14829     Expr *NumIterations = LoopHelper.NumIterations;
14830     auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
14831     QualType CntTy = OrigCntVar->getType();
14832     Expr *DimTileSize = SizesClause->getSizesRefs()[I];
14833     Scope *CurScope = getCurScope();
14834 
14835     // Commonly used variables.
14836     DeclRefExpr *TileIV = buildDeclRefExpr(*this, TileIndVars[I], CntTy,
14837                                            OrigCntVar->getExprLoc());
14838     DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
14839                                             OrigCntVar->getExprLoc());
14840 
14841     // For init-statement: auto .tile.iv = .floor.iv
14842     AddInitializerToDecl(TileIndVars[I], DefaultLvalueConversion(FloorIV).get(),
14843                          /*DirectInit=*/false);
14844     Decl *CounterDecl = TileIndVars[I];
14845     StmtResult InitStmt = new (Context)
14846         DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
14847                  OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
14848     if (!InitStmt.isUsable())
14849       return StmtError();
14850 
14851     // For cond-expression: .tile.iv < min(.floor.iv + DimTileSize,
14852     // NumIterations)
14853     ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
14854                                       BO_Add, FloorIV, DimTileSize);
14855     if (!EndOfTile.isUsable())
14856       return StmtError();
14857     ExprResult IsPartialTile =
14858         BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT,
14859                    NumIterations, EndOfTile.get());
14860     if (!IsPartialTile.isUsable())
14861       return StmtError();
14862     ExprResult MinTileAndIterSpace = ActOnConditionalOp(
14863         LoopHelper.Cond->getBeginLoc(), LoopHelper.Cond->getEndLoc(),
14864         IsPartialTile.get(), NumIterations, EndOfTile.get());
14865     if (!MinTileAndIterSpace.isUsable())
14866       return StmtError();
14867     ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
14868                                      BO_LT, TileIV, MinTileAndIterSpace.get());
14869     if (!CondExpr.isUsable())
14870       return StmtError();
14871 
14872     // For incr-statement: ++.tile.iv
14873     ExprResult IncrStmt =
14874         BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), UO_PreInc, TileIV);
14875     if (!IncrStmt.isUsable())
14876       return StmtError();
14877 
14878     // Statements to set the original iteration variable's value from the
14879     // logical iteration number.
14880     // Generated for loop is:
14881     // Original_for_init;
14882     // for (auto .tile.iv = .floor.iv; .tile.iv < min(.floor.iv + DimTileSize,
14883     // NumIterations); ++.tile.iv) {
14884     //   Original_Body;
14885     //   Original_counter_update;
14886     // }
14887     // FIXME: If the innermost body is an loop itself, inserting these
14888     // statements stops it being recognized  as a perfectly nested loop (e.g.
14889     // for applying tiling again). If this is the case, sink the expressions
14890     // further into the inner loop.
14891     SmallVector<Stmt *, 4> BodyParts;
14892     BodyParts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
14893     BodyParts.push_back(Inner);
14894     Inner = CompoundStmt::Create(Context, BodyParts, FPOptionsOverride(),
14895                                  Inner->getBeginLoc(), Inner->getEndLoc());
14896     Inner = new (Context)
14897         ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
14898                 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
14899                 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
14900   }
14901 
14902   // Create floor loops from the inside to the outside.
14903   for (int I = NumLoops - 1; I >= 0; --I) {
14904     auto &LoopHelper = LoopHelpers[I];
14905     Expr *NumIterations = LoopHelper.NumIterations;
14906     DeclRefExpr *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
14907     QualType CntTy = OrigCntVar->getType();
14908     Expr *DimTileSize = SizesClause->getSizesRefs()[I];
14909     Scope *CurScope = getCurScope();
14910 
14911     // Commonly used variables.
14912     DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
14913                                             OrigCntVar->getExprLoc());
14914 
14915     // For init-statement: auto .floor.iv = 0
14916     AddInitializerToDecl(
14917         FloorIndVars[I],
14918         ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
14919         /*DirectInit=*/false);
14920     Decl *CounterDecl = FloorIndVars[I];
14921     StmtResult InitStmt = new (Context)
14922         DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
14923                  OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
14924     if (!InitStmt.isUsable())
14925       return StmtError();
14926 
14927     // For cond-expression: .floor.iv < NumIterations
14928     ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
14929                                      BO_LT, FloorIV, NumIterations);
14930     if (!CondExpr.isUsable())
14931       return StmtError();
14932 
14933     // For incr-statement: .floor.iv += DimTileSize
14934     ExprResult IncrStmt = BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(),
14935                                      BO_AddAssign, FloorIV, DimTileSize);
14936     if (!IncrStmt.isUsable())
14937       return StmtError();
14938 
14939     Inner = new (Context)
14940         ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
14941                 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
14942                 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
14943   }
14944 
14945   return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, NumLoops,
14946                                   AStmt, Inner,
14947                                   buildPreInits(Context, PreInits));
14948 }
14949 
14950 StmtResult Sema::ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses,
14951                                             Stmt *AStmt,
14952                                             SourceLocation StartLoc,
14953                                             SourceLocation EndLoc) {
14954   // Empty statement should only be possible if there already was an error.
14955   if (!AStmt)
14956     return StmtError();
14957 
14958   if (checkMutuallyExclusiveClauses(*this, Clauses, {OMPC_partial, OMPC_full}))
14959     return StmtError();
14960 
14961   const OMPFullClause *FullClause =
14962       OMPExecutableDirective::getSingleClause<OMPFullClause>(Clauses);
14963   const OMPPartialClause *PartialClause =
14964       OMPExecutableDirective::getSingleClause<OMPPartialClause>(Clauses);
14965   assert(!(FullClause && PartialClause) &&
14966          "mutual exclusivity must have been checked before");
14967 
14968   constexpr unsigned NumLoops = 1;
14969   Stmt *Body = nullptr;
14970   SmallVector<OMPLoopBasedDirective::HelperExprs, NumLoops> LoopHelpers(
14971       NumLoops);
14972   SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, NumLoops + 1>
14973       OriginalInits;
14974   if (!checkTransformableLoopNest(OMPD_unroll, AStmt, NumLoops, LoopHelpers,
14975                                   Body, OriginalInits))
14976     return StmtError();
14977 
14978   unsigned NumGeneratedLoops = PartialClause ? 1 : 0;
14979 
14980   // Delay unrolling to when template is completely instantiated.
14981   if (CurContext->isDependentContext())
14982     return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
14983                                       NumGeneratedLoops, nullptr, nullptr);
14984 
14985   OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front();
14986 
14987   if (FullClause) {
14988     if (!VerifyPositiveIntegerConstantInClause(
14989              LoopHelper.NumIterations, OMPC_full, /*StrictlyPositive=*/false,
14990              /*SuppressExprDiags=*/true)
14991              .isUsable()) {
14992       Diag(AStmt->getBeginLoc(), diag::err_omp_unroll_full_variable_trip_count);
14993       Diag(FullClause->getBeginLoc(), diag::note_omp_directive_here)
14994           << "#pragma omp unroll full";
14995       return StmtError();
14996     }
14997   }
14998 
14999   // The generated loop may only be passed to other loop-associated directive
15000   // when a partial clause is specified. Without the requirement it is
15001   // sufficient to generate loop unroll metadata at code-generation.
15002   if (NumGeneratedLoops == 0)
15003     return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
15004                                       NumGeneratedLoops, nullptr, nullptr);
15005 
15006   // Otherwise, we need to provide a de-sugared/transformed AST that can be
15007   // associated with another loop directive.
15008   //
15009   // The canonical loop analysis return by checkTransformableLoopNest assumes
15010   // the following structure to be the same loop without transformations or
15011   // directives applied: \code OriginalInits; LoopHelper.PreInits;
15012   // LoopHelper.Counters;
15013   // for (; IV < LoopHelper.NumIterations; ++IV) {
15014   //   LoopHelper.Updates;
15015   //   Body;
15016   // }
15017   // \endcode
15018   // where IV is a variable declared and initialized to 0 in LoopHelper.PreInits
15019   // and referenced by LoopHelper.IterationVarRef.
15020   //
15021   // The unrolling directive transforms this into the following loop:
15022   // \code
15023   // OriginalInits;         \
15024   // LoopHelper.PreInits;    > NewPreInits
15025   // LoopHelper.Counters;   /
15026   // for (auto UIV = 0; UIV < LoopHelper.NumIterations; UIV+=Factor) {
15027   //   #pragma clang loop unroll_count(Factor)
15028   //   for (IV = UIV; IV < UIV + Factor && UIV < LoopHelper.NumIterations; ++IV)
15029   //   {
15030   //     LoopHelper.Updates;
15031   //     Body;
15032   //   }
15033   // }
15034   // \endcode
15035   // where UIV is a new logical iteration counter. IV must be the same VarDecl
15036   // as the original LoopHelper.IterationVarRef because LoopHelper.Updates
15037   // references it. If the partially unrolled loop is associated with another
15038   // loop directive (like an OMPForDirective), it will use checkOpenMPLoop to
15039   // analyze this loop, i.e. the outer loop must fulfill the constraints of an
15040   // OpenMP canonical loop. The inner loop is not an associable canonical loop
15041   // and only exists to defer its unrolling to LLVM's LoopUnroll instead of
15042   // doing it in the frontend (by adding loop metadata). NewPreInits becomes a
15043   // property of the OMPLoopBasedDirective instead of statements in
15044   // CompoundStatement. This is to allow the loop to become a non-outermost loop
15045   // of a canonical loop nest where these PreInits are emitted before the
15046   // outermost directive.
15047 
15048   // Determine the PreInit declarations.
15049   SmallVector<Decl *, 4> PreInits;
15050   assert(OriginalInits.size() == 1 &&
15051          "Expecting a single-dimensional loop iteration space");
15052   for (auto &P : OriginalInits[0]) {
15053     if (auto *D = P.dyn_cast<Decl *>())
15054       PreInits.push_back(D);
15055     else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>()))
15056       PreInits.append(PI->decl_begin(), PI->decl_end());
15057   }
15058   if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
15059     PreInits.append(PI->decl_begin(), PI->decl_end());
15060   // Gather declarations for the data members used as counters.
15061   for (Expr *CounterRef : LoopHelper.Counters) {
15062     auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
15063     if (isa<OMPCapturedExprDecl>(CounterDecl))
15064       PreInits.push_back(CounterDecl);
15065   }
15066 
15067   auto *IterationVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
15068   QualType IVTy = IterationVarRef->getType();
15069   assert(LoopHelper.Counters.size() == 1 &&
15070          "Expecting a single-dimensional loop iteration space");
15071   auto *OrigVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
15072 
15073   // Determine the unroll factor.
15074   uint64_t Factor;
15075   SourceLocation FactorLoc;
15076   if (Expr *FactorVal = PartialClause->getFactor()) {
15077     Factor = FactorVal->getIntegerConstantExpr(Context)->getZExtValue();
15078     FactorLoc = FactorVal->getExprLoc();
15079   } else {
15080     // TODO: Use a better profitability model.
15081     Factor = 2;
15082   }
15083   assert(Factor > 0 && "Expected positive unroll factor");
15084   auto MakeFactorExpr = [this, Factor, IVTy, FactorLoc]() {
15085     return IntegerLiteral::Create(
15086         Context, llvm::APInt(Context.getIntWidth(IVTy), Factor), IVTy,
15087         FactorLoc);
15088   };
15089 
15090   // Iteration variable SourceLocations.
15091   SourceLocation OrigVarLoc = OrigVar->getExprLoc();
15092   SourceLocation OrigVarLocBegin = OrigVar->getBeginLoc();
15093   SourceLocation OrigVarLocEnd = OrigVar->getEndLoc();
15094 
15095   // Internal variable names.
15096   std::string OrigVarName = OrigVar->getNameInfo().getAsString();
15097   std::string OuterIVName = (Twine(".unrolled.iv.") + OrigVarName).str();
15098   std::string InnerIVName = (Twine(".unroll_inner.iv.") + OrigVarName).str();
15099   std::string InnerTripCountName =
15100       (Twine(".unroll_inner.tripcount.") + OrigVarName).str();
15101 
15102   // Create the iteration variable for the unrolled loop.
15103   VarDecl *OuterIVDecl =
15104       buildVarDecl(*this, {}, IVTy, OuterIVName, nullptr, OrigVar);
15105   auto MakeOuterRef = [this, OuterIVDecl, IVTy, OrigVarLoc]() {
15106     return buildDeclRefExpr(*this, OuterIVDecl, IVTy, OrigVarLoc);
15107   };
15108 
15109   // Iteration variable for the inner loop: Reuse the iteration variable created
15110   // by checkOpenMPLoop.
15111   auto *InnerIVDecl = cast<VarDecl>(IterationVarRef->getDecl());
15112   InnerIVDecl->setDeclName(&PP.getIdentifierTable().get(InnerIVName));
15113   auto MakeInnerRef = [this, InnerIVDecl, IVTy, OrigVarLoc]() {
15114     return buildDeclRefExpr(*this, InnerIVDecl, IVTy, OrigVarLoc);
15115   };
15116 
15117   // Make a copy of the NumIterations expression for each use: By the AST
15118   // constraints, every expression object in a DeclContext must be unique.
15119   CaptureVars CopyTransformer(*this);
15120   auto MakeNumIterations = [&CopyTransformer, &LoopHelper]() -> Expr * {
15121     return AssertSuccess(
15122         CopyTransformer.TransformExpr(LoopHelper.NumIterations));
15123   };
15124 
15125   // Inner For init-statement: auto .unroll_inner.iv = .unrolled.iv
15126   ExprResult LValueConv = DefaultLvalueConversion(MakeOuterRef());
15127   AddInitializerToDecl(InnerIVDecl, LValueConv.get(), /*DirectInit=*/false);
15128   StmtResult InnerInit = new (Context)
15129       DeclStmt(DeclGroupRef(InnerIVDecl), OrigVarLocBegin, OrigVarLocEnd);
15130   if (!InnerInit.isUsable())
15131     return StmtError();
15132 
15133   // Inner For cond-expression:
15134   // \code
15135   //   .unroll_inner.iv < .unrolled.iv + Factor &&
15136   //   .unroll_inner.iv < NumIterations
15137   // \endcode
15138   // This conjunction of two conditions allows ScalarEvolution to derive the
15139   // maximum trip count of the inner loop.
15140   ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
15141                                     BO_Add, MakeOuterRef(), MakeFactorExpr());
15142   if (!EndOfTile.isUsable())
15143     return StmtError();
15144   ExprResult InnerCond1 = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
15145                                      BO_LT, MakeInnerRef(), EndOfTile.get());
15146   if (!InnerCond1.isUsable())
15147     return StmtError();
15148   ExprResult InnerCond2 =
15149       BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeInnerRef(),
15150                  MakeNumIterations());
15151   if (!InnerCond2.isUsable())
15152     return StmtError();
15153   ExprResult InnerCond =
15154       BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LAnd,
15155                  InnerCond1.get(), InnerCond2.get());
15156   if (!InnerCond.isUsable())
15157     return StmtError();
15158 
15159   // Inner For incr-statement: ++.unroll_inner.iv
15160   ExprResult InnerIncr = BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(),
15161                                       UO_PreInc, MakeInnerRef());
15162   if (!InnerIncr.isUsable())
15163     return StmtError();
15164 
15165   // Inner For statement.
15166   SmallVector<Stmt *> InnerBodyStmts;
15167   InnerBodyStmts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
15168   InnerBodyStmts.push_back(Body);
15169   CompoundStmt *InnerBody =
15170       CompoundStmt::Create(Context, InnerBodyStmts, FPOptionsOverride(),
15171                            Body->getBeginLoc(), Body->getEndLoc());
15172   ForStmt *InnerFor = new (Context)
15173       ForStmt(Context, InnerInit.get(), InnerCond.get(), nullptr,
15174               InnerIncr.get(), InnerBody, LoopHelper.Init->getBeginLoc(),
15175               LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
15176 
15177   // Unroll metadata for the inner loop.
15178   // This needs to take into account the remainder portion of the unrolled loop,
15179   // hence `unroll(full)` does not apply here, even though the LoopUnroll pass
15180   // supports multiple loop exits. Instead, unroll using a factor equivalent to
15181   // the maximum trip count, which will also generate a remainder loop. Just
15182   // `unroll(enable)` (which could have been useful if the user has not
15183   // specified a concrete factor; even though the outer loop cannot be
15184   // influenced anymore, would avoid more code bloat than necessary) will refuse
15185   // the loop because "Won't unroll; remainder loop could not be generated when
15186   // assuming runtime trip count". Even if it did work, it must not choose a
15187   // larger unroll factor than the maximum loop length, or it would always just
15188   // execute the remainder loop.
15189   LoopHintAttr *UnrollHintAttr =
15190       LoopHintAttr::CreateImplicit(Context, LoopHintAttr::UnrollCount,
15191                                    LoopHintAttr::Numeric, MakeFactorExpr());
15192   AttributedStmt *InnerUnrolled =
15193       AttributedStmt::Create(Context, StartLoc, {UnrollHintAttr}, InnerFor);
15194 
15195   // Outer For init-statement: auto .unrolled.iv = 0
15196   AddInitializerToDecl(
15197       OuterIVDecl, ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
15198       /*DirectInit=*/false);
15199   StmtResult OuterInit = new (Context)
15200       DeclStmt(DeclGroupRef(OuterIVDecl), OrigVarLocBegin, OrigVarLocEnd);
15201   if (!OuterInit.isUsable())
15202     return StmtError();
15203 
15204   // Outer For cond-expression: .unrolled.iv < NumIterations
15205   ExprResult OuterConde =
15206       BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeOuterRef(),
15207                  MakeNumIterations());
15208   if (!OuterConde.isUsable())
15209     return StmtError();
15210 
15211   // Outer For incr-statement: .unrolled.iv += Factor
15212   ExprResult OuterIncr =
15213       BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(), BO_AddAssign,
15214                  MakeOuterRef(), MakeFactorExpr());
15215   if (!OuterIncr.isUsable())
15216     return StmtError();
15217 
15218   // Outer For statement.
15219   ForStmt *OuterFor = new (Context)
15220       ForStmt(Context, OuterInit.get(), OuterConde.get(), nullptr,
15221               OuterIncr.get(), InnerUnrolled, LoopHelper.Init->getBeginLoc(),
15222               LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
15223 
15224   return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
15225                                     NumGeneratedLoops, OuterFor,
15226                                     buildPreInits(Context, PreInits));
15227 }
15228 
15229 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
15230                                              SourceLocation StartLoc,
15231                                              SourceLocation LParenLoc,
15232                                              SourceLocation EndLoc) {
15233   OMPClause *Res = nullptr;
15234   switch (Kind) {
15235   case OMPC_final:
15236     Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
15237     break;
15238   case OMPC_num_threads:
15239     Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
15240     break;
15241   case OMPC_safelen:
15242     Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
15243     break;
15244   case OMPC_simdlen:
15245     Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
15246     break;
15247   case OMPC_allocator:
15248     Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
15249     break;
15250   case OMPC_collapse:
15251     Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
15252     break;
15253   case OMPC_ordered:
15254     Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
15255     break;
15256   case OMPC_num_teams:
15257     Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
15258     break;
15259   case OMPC_thread_limit:
15260     Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
15261     break;
15262   case OMPC_priority:
15263     Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
15264     break;
15265   case OMPC_hint:
15266     Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
15267     break;
15268   case OMPC_depobj:
15269     Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc);
15270     break;
15271   case OMPC_detach:
15272     Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc);
15273     break;
15274   case OMPC_novariants:
15275     Res = ActOnOpenMPNovariantsClause(Expr, StartLoc, LParenLoc, EndLoc);
15276     break;
15277   case OMPC_nocontext:
15278     Res = ActOnOpenMPNocontextClause(Expr, StartLoc, LParenLoc, EndLoc);
15279     break;
15280   case OMPC_filter:
15281     Res = ActOnOpenMPFilterClause(Expr, StartLoc, LParenLoc, EndLoc);
15282     break;
15283   case OMPC_partial:
15284     Res = ActOnOpenMPPartialClause(Expr, StartLoc, LParenLoc, EndLoc);
15285     break;
15286   case OMPC_message:
15287     Res = ActOnOpenMPMessageClause(Expr, StartLoc, LParenLoc, EndLoc);
15288     break;
15289   case OMPC_align:
15290     Res = ActOnOpenMPAlignClause(Expr, StartLoc, LParenLoc, EndLoc);
15291     break;
15292   case OMPC_ompx_dyn_cgroup_mem:
15293     Res = ActOnOpenMPXDynCGroupMemClause(Expr, StartLoc, LParenLoc, EndLoc);
15294     break;
15295   case OMPC_grainsize:
15296   case OMPC_num_tasks:
15297   case OMPC_device:
15298   case OMPC_if:
15299   case OMPC_default:
15300   case OMPC_proc_bind:
15301   case OMPC_schedule:
15302   case OMPC_private:
15303   case OMPC_firstprivate:
15304   case OMPC_lastprivate:
15305   case OMPC_shared:
15306   case OMPC_reduction:
15307   case OMPC_task_reduction:
15308   case OMPC_in_reduction:
15309   case OMPC_linear:
15310   case OMPC_aligned:
15311   case OMPC_copyin:
15312   case OMPC_copyprivate:
15313   case OMPC_nowait:
15314   case OMPC_untied:
15315   case OMPC_mergeable:
15316   case OMPC_threadprivate:
15317   case OMPC_sizes:
15318   case OMPC_allocate:
15319   case OMPC_flush:
15320   case OMPC_read:
15321   case OMPC_write:
15322   case OMPC_update:
15323   case OMPC_capture:
15324   case OMPC_compare:
15325   case OMPC_seq_cst:
15326   case OMPC_acq_rel:
15327   case OMPC_acquire:
15328   case OMPC_release:
15329   case OMPC_relaxed:
15330   case OMPC_depend:
15331   case OMPC_threads:
15332   case OMPC_simd:
15333   case OMPC_map:
15334   case OMPC_nogroup:
15335   case OMPC_dist_schedule:
15336   case OMPC_defaultmap:
15337   case OMPC_unknown:
15338   case OMPC_uniform:
15339   case OMPC_to:
15340   case OMPC_from:
15341   case OMPC_use_device_ptr:
15342   case OMPC_use_device_addr:
15343   case OMPC_is_device_ptr:
15344   case OMPC_unified_address:
15345   case OMPC_unified_shared_memory:
15346   case OMPC_reverse_offload:
15347   case OMPC_dynamic_allocators:
15348   case OMPC_atomic_default_mem_order:
15349   case OMPC_device_type:
15350   case OMPC_match:
15351   case OMPC_nontemporal:
15352   case OMPC_order:
15353   case OMPC_at:
15354   case OMPC_severity:
15355   case OMPC_destroy:
15356   case OMPC_inclusive:
15357   case OMPC_exclusive:
15358   case OMPC_uses_allocators:
15359   case OMPC_affinity:
15360   case OMPC_when:
15361   case OMPC_bind:
15362   default:
15363     llvm_unreachable("Clause is not allowed.");
15364   }
15365   return Res;
15366 }
15367 
15368 // An OpenMP directive such as 'target parallel' has two captured regions:
15369 // for the 'target' and 'parallel' respectively.  This function returns
15370 // the region in which to capture expressions associated with a clause.
15371 // A return value of OMPD_unknown signifies that the expression should not
15372 // be captured.
15373 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
15374     OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion,
15375     OpenMPDirectiveKind NameModifier = OMPD_unknown) {
15376   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
15377   switch (CKind) {
15378   case OMPC_if:
15379     switch (DKind) {
15380     case OMPD_target_parallel_for_simd:
15381       if (OpenMPVersion >= 50 &&
15382           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
15383         CaptureRegion = OMPD_parallel;
15384         break;
15385       }
15386       [[fallthrough]];
15387     case OMPD_target_parallel:
15388     case OMPD_target_parallel_for:
15389     case OMPD_target_parallel_loop:
15390       // If this clause applies to the nested 'parallel' region, capture within
15391       // the 'target' region, otherwise do not capture.
15392       if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
15393         CaptureRegion = OMPD_target;
15394       break;
15395     case OMPD_target_teams_distribute_parallel_for_simd:
15396       if (OpenMPVersion >= 50 &&
15397           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
15398         CaptureRegion = OMPD_parallel;
15399         break;
15400       }
15401       [[fallthrough]];
15402     case OMPD_target_teams_loop:
15403     case OMPD_target_teams_distribute_parallel_for:
15404       // If this clause applies to the nested 'parallel' region, capture within
15405       // the 'teams' region, otherwise do not capture.
15406       if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
15407         CaptureRegion = OMPD_teams;
15408       break;
15409     case OMPD_teams_distribute_parallel_for_simd:
15410       if (OpenMPVersion >= 50 &&
15411           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
15412         CaptureRegion = OMPD_parallel;
15413         break;
15414       }
15415       [[fallthrough]];
15416     case OMPD_teams_distribute_parallel_for:
15417       CaptureRegion = OMPD_teams;
15418       break;
15419     case OMPD_target_update:
15420     case OMPD_target_enter_data:
15421     case OMPD_target_exit_data:
15422       CaptureRegion = OMPD_task;
15423       break;
15424     case OMPD_parallel_masked_taskloop:
15425       if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
15426         CaptureRegion = OMPD_parallel;
15427       break;
15428     case OMPD_parallel_master_taskloop:
15429       if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
15430         CaptureRegion = OMPD_parallel;
15431       break;
15432     case OMPD_parallel_masked_taskloop_simd:
15433       if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
15434           NameModifier == OMPD_taskloop) {
15435         CaptureRegion = OMPD_parallel;
15436         break;
15437       }
15438       if (OpenMPVersion <= 45)
15439         break;
15440       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15441         CaptureRegion = OMPD_taskloop;
15442       break;
15443     case OMPD_parallel_master_taskloop_simd:
15444       if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
15445           NameModifier == OMPD_taskloop) {
15446         CaptureRegion = OMPD_parallel;
15447         break;
15448       }
15449       if (OpenMPVersion <= 45)
15450         break;
15451       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15452         CaptureRegion = OMPD_taskloop;
15453       break;
15454     case OMPD_parallel_for_simd:
15455       if (OpenMPVersion <= 45)
15456         break;
15457       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15458         CaptureRegion = OMPD_parallel;
15459       break;
15460     case OMPD_taskloop_simd:
15461     case OMPD_master_taskloop_simd:
15462     case OMPD_masked_taskloop_simd:
15463       if (OpenMPVersion <= 45)
15464         break;
15465       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15466         CaptureRegion = OMPD_taskloop;
15467       break;
15468     case OMPD_distribute_parallel_for_simd:
15469       if (OpenMPVersion <= 45)
15470         break;
15471       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15472         CaptureRegion = OMPD_parallel;
15473       break;
15474     case OMPD_target_simd:
15475       if (OpenMPVersion >= 50 &&
15476           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
15477         CaptureRegion = OMPD_target;
15478       break;
15479     case OMPD_teams_distribute_simd:
15480     case OMPD_target_teams_distribute_simd:
15481       if (OpenMPVersion >= 50 &&
15482           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
15483         CaptureRegion = OMPD_teams;
15484       break;
15485     case OMPD_cancel:
15486     case OMPD_parallel:
15487     case OMPD_parallel_master:
15488     case OMPD_parallel_masked:
15489     case OMPD_parallel_sections:
15490     case OMPD_parallel_for:
15491     case OMPD_parallel_loop:
15492     case OMPD_target:
15493     case OMPD_target_teams:
15494     case OMPD_target_teams_distribute:
15495     case OMPD_distribute_parallel_for:
15496     case OMPD_task:
15497     case OMPD_taskloop:
15498     case OMPD_master_taskloop:
15499     case OMPD_masked_taskloop:
15500     case OMPD_target_data:
15501     case OMPD_simd:
15502     case OMPD_for_simd:
15503     case OMPD_distribute_simd:
15504       // Do not capture if-clause expressions.
15505       break;
15506     case OMPD_threadprivate:
15507     case OMPD_allocate:
15508     case OMPD_taskyield:
15509     case OMPD_error:
15510     case OMPD_barrier:
15511     case OMPD_taskwait:
15512     case OMPD_cancellation_point:
15513     case OMPD_flush:
15514     case OMPD_depobj:
15515     case OMPD_scan:
15516     case OMPD_declare_reduction:
15517     case OMPD_declare_mapper:
15518     case OMPD_declare_simd:
15519     case OMPD_declare_variant:
15520     case OMPD_begin_declare_variant:
15521     case OMPD_end_declare_variant:
15522     case OMPD_declare_target:
15523     case OMPD_end_declare_target:
15524     case OMPD_loop:
15525     case OMPD_teams_loop:
15526     case OMPD_teams:
15527     case OMPD_tile:
15528     case OMPD_unroll:
15529     case OMPD_for:
15530     case OMPD_sections:
15531     case OMPD_section:
15532     case OMPD_single:
15533     case OMPD_master:
15534     case OMPD_masked:
15535     case OMPD_critical:
15536     case OMPD_taskgroup:
15537     case OMPD_distribute:
15538     case OMPD_ordered:
15539     case OMPD_atomic:
15540     case OMPD_teams_distribute:
15541     case OMPD_requires:
15542     case OMPD_metadirective:
15543       llvm_unreachable("Unexpected OpenMP directive with if-clause");
15544     case OMPD_unknown:
15545     default:
15546       llvm_unreachable("Unknown OpenMP directive");
15547     }
15548     break;
15549   case OMPC_num_threads:
15550     switch (DKind) {
15551     case OMPD_target_parallel:
15552     case OMPD_target_parallel_for:
15553     case OMPD_target_parallel_for_simd:
15554     case OMPD_target_parallel_loop:
15555       CaptureRegion = OMPD_target;
15556       break;
15557     case OMPD_teams_distribute_parallel_for:
15558     case OMPD_teams_distribute_parallel_for_simd:
15559     case OMPD_target_teams_distribute_parallel_for:
15560     case OMPD_target_teams_distribute_parallel_for_simd:
15561       CaptureRegion = OMPD_teams;
15562       break;
15563     case OMPD_parallel:
15564     case OMPD_parallel_master:
15565     case OMPD_parallel_masked:
15566     case OMPD_parallel_sections:
15567     case OMPD_parallel_for:
15568     case OMPD_parallel_for_simd:
15569     case OMPD_parallel_loop:
15570     case OMPD_distribute_parallel_for:
15571     case OMPD_distribute_parallel_for_simd:
15572     case OMPD_parallel_master_taskloop:
15573     case OMPD_parallel_masked_taskloop:
15574     case OMPD_parallel_master_taskloop_simd:
15575     case OMPD_parallel_masked_taskloop_simd:
15576       // Do not capture num_threads-clause expressions.
15577       break;
15578     case OMPD_target_data:
15579     case OMPD_target_enter_data:
15580     case OMPD_target_exit_data:
15581     case OMPD_target_update:
15582     case OMPD_target:
15583     case OMPD_target_simd:
15584     case OMPD_target_teams:
15585     case OMPD_target_teams_distribute:
15586     case OMPD_target_teams_distribute_simd:
15587     case OMPD_cancel:
15588     case OMPD_task:
15589     case OMPD_taskloop:
15590     case OMPD_taskloop_simd:
15591     case OMPD_master_taskloop:
15592     case OMPD_masked_taskloop:
15593     case OMPD_master_taskloop_simd:
15594     case OMPD_masked_taskloop_simd:
15595     case OMPD_threadprivate:
15596     case OMPD_allocate:
15597     case OMPD_taskyield:
15598     case OMPD_error:
15599     case OMPD_barrier:
15600     case OMPD_taskwait:
15601     case OMPD_cancellation_point:
15602     case OMPD_flush:
15603     case OMPD_depobj:
15604     case OMPD_scan:
15605     case OMPD_declare_reduction:
15606     case OMPD_declare_mapper:
15607     case OMPD_declare_simd:
15608     case OMPD_declare_variant:
15609     case OMPD_begin_declare_variant:
15610     case OMPD_end_declare_variant:
15611     case OMPD_declare_target:
15612     case OMPD_end_declare_target:
15613     case OMPD_loop:
15614     case OMPD_teams_loop:
15615     case OMPD_target_teams_loop:
15616     case OMPD_teams:
15617     case OMPD_simd:
15618     case OMPD_tile:
15619     case OMPD_unroll:
15620     case OMPD_for:
15621     case OMPD_for_simd:
15622     case OMPD_sections:
15623     case OMPD_section:
15624     case OMPD_single:
15625     case OMPD_master:
15626     case OMPD_masked:
15627     case OMPD_critical:
15628     case OMPD_taskgroup:
15629     case OMPD_distribute:
15630     case OMPD_ordered:
15631     case OMPD_atomic:
15632     case OMPD_distribute_simd:
15633     case OMPD_teams_distribute:
15634     case OMPD_teams_distribute_simd:
15635     case OMPD_requires:
15636     case OMPD_metadirective:
15637       llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
15638     case OMPD_unknown:
15639     default:
15640       llvm_unreachable("Unknown OpenMP directive");
15641     }
15642     break;
15643   case OMPC_num_teams:
15644     switch (DKind) {
15645     case OMPD_target_teams:
15646     case OMPD_target_teams_distribute:
15647     case OMPD_target_teams_distribute_simd:
15648     case OMPD_target_teams_distribute_parallel_for:
15649     case OMPD_target_teams_distribute_parallel_for_simd:
15650     case OMPD_target_teams_loop:
15651       CaptureRegion = OMPD_target;
15652       break;
15653     case OMPD_teams_distribute_parallel_for:
15654     case OMPD_teams_distribute_parallel_for_simd:
15655     case OMPD_teams:
15656     case OMPD_teams_distribute:
15657     case OMPD_teams_distribute_simd:
15658     case OMPD_teams_loop:
15659       // Do not capture num_teams-clause expressions.
15660       break;
15661     case OMPD_distribute_parallel_for:
15662     case OMPD_distribute_parallel_for_simd:
15663     case OMPD_task:
15664     case OMPD_taskloop:
15665     case OMPD_taskloop_simd:
15666     case OMPD_master_taskloop:
15667     case OMPD_masked_taskloop:
15668     case OMPD_master_taskloop_simd:
15669     case OMPD_masked_taskloop_simd:
15670     case OMPD_parallel_master_taskloop:
15671     case OMPD_parallel_masked_taskloop:
15672     case OMPD_parallel_master_taskloop_simd:
15673     case OMPD_parallel_masked_taskloop_simd:
15674     case OMPD_target_data:
15675     case OMPD_target_enter_data:
15676     case OMPD_target_exit_data:
15677     case OMPD_target_update:
15678     case OMPD_cancel:
15679     case OMPD_parallel:
15680     case OMPD_parallel_master:
15681     case OMPD_parallel_masked:
15682     case OMPD_parallel_sections:
15683     case OMPD_parallel_for:
15684     case OMPD_parallel_for_simd:
15685     case OMPD_parallel_loop:
15686     case OMPD_target:
15687     case OMPD_target_simd:
15688     case OMPD_target_parallel:
15689     case OMPD_target_parallel_for:
15690     case OMPD_target_parallel_for_simd:
15691     case OMPD_target_parallel_loop:
15692     case OMPD_threadprivate:
15693     case OMPD_allocate:
15694     case OMPD_taskyield:
15695     case OMPD_error:
15696     case OMPD_barrier:
15697     case OMPD_taskwait:
15698     case OMPD_cancellation_point:
15699     case OMPD_flush:
15700     case OMPD_depobj:
15701     case OMPD_scan:
15702     case OMPD_declare_reduction:
15703     case OMPD_declare_mapper:
15704     case OMPD_declare_simd:
15705     case OMPD_declare_variant:
15706     case OMPD_begin_declare_variant:
15707     case OMPD_end_declare_variant:
15708     case OMPD_declare_target:
15709     case OMPD_end_declare_target:
15710     case OMPD_loop:
15711     case OMPD_simd:
15712     case OMPD_tile:
15713     case OMPD_unroll:
15714     case OMPD_for:
15715     case OMPD_for_simd:
15716     case OMPD_sections:
15717     case OMPD_section:
15718     case OMPD_single:
15719     case OMPD_master:
15720     case OMPD_masked:
15721     case OMPD_critical:
15722     case OMPD_taskgroup:
15723     case OMPD_distribute:
15724     case OMPD_ordered:
15725     case OMPD_atomic:
15726     case OMPD_distribute_simd:
15727     case OMPD_requires:
15728     case OMPD_metadirective:
15729       llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
15730     case OMPD_unknown:
15731     default:
15732       llvm_unreachable("Unknown OpenMP directive");
15733     }
15734     break;
15735   case OMPC_thread_limit:
15736     switch (DKind) {
15737     case OMPD_target:
15738     case OMPD_target_teams:
15739     case OMPD_target_teams_distribute:
15740     case OMPD_target_teams_distribute_simd:
15741     case OMPD_target_teams_distribute_parallel_for:
15742     case OMPD_target_teams_distribute_parallel_for_simd:
15743     case OMPD_target_teams_loop:
15744       CaptureRegion = OMPD_target;
15745       break;
15746     case OMPD_teams_distribute_parallel_for:
15747     case OMPD_teams_distribute_parallel_for_simd:
15748     case OMPD_teams:
15749     case OMPD_teams_distribute:
15750     case OMPD_teams_distribute_simd:
15751     case OMPD_teams_loop:
15752       // Do not capture thread_limit-clause expressions.
15753       break;
15754     case OMPD_distribute_parallel_for:
15755     case OMPD_distribute_parallel_for_simd:
15756     case OMPD_task:
15757     case OMPD_taskloop:
15758     case OMPD_taskloop_simd:
15759     case OMPD_master_taskloop:
15760     case OMPD_masked_taskloop:
15761     case OMPD_master_taskloop_simd:
15762     case OMPD_masked_taskloop_simd:
15763     case OMPD_parallel_master_taskloop:
15764     case OMPD_parallel_masked_taskloop:
15765     case OMPD_parallel_master_taskloop_simd:
15766     case OMPD_parallel_masked_taskloop_simd:
15767     case OMPD_target_data:
15768     case OMPD_target_enter_data:
15769     case OMPD_target_exit_data:
15770     case OMPD_target_update:
15771     case OMPD_cancel:
15772     case OMPD_parallel:
15773     case OMPD_parallel_master:
15774     case OMPD_parallel_masked:
15775     case OMPD_parallel_sections:
15776     case OMPD_parallel_for:
15777     case OMPD_parallel_for_simd:
15778     case OMPD_parallel_loop:
15779     case OMPD_target_simd:
15780     case OMPD_target_parallel:
15781     case OMPD_target_parallel_for:
15782     case OMPD_target_parallel_for_simd:
15783     case OMPD_target_parallel_loop:
15784     case OMPD_threadprivate:
15785     case OMPD_allocate:
15786     case OMPD_taskyield:
15787     case OMPD_error:
15788     case OMPD_barrier:
15789     case OMPD_taskwait:
15790     case OMPD_cancellation_point:
15791     case OMPD_flush:
15792     case OMPD_depobj:
15793     case OMPD_scan:
15794     case OMPD_declare_reduction:
15795     case OMPD_declare_mapper:
15796     case OMPD_declare_simd:
15797     case OMPD_declare_variant:
15798     case OMPD_begin_declare_variant:
15799     case OMPD_end_declare_variant:
15800     case OMPD_declare_target:
15801     case OMPD_end_declare_target:
15802     case OMPD_loop:
15803     case OMPD_simd:
15804     case OMPD_tile:
15805     case OMPD_unroll:
15806     case OMPD_for:
15807     case OMPD_for_simd:
15808     case OMPD_sections:
15809     case OMPD_section:
15810     case OMPD_single:
15811     case OMPD_master:
15812     case OMPD_masked:
15813     case OMPD_critical:
15814     case OMPD_taskgroup:
15815     case OMPD_distribute:
15816     case OMPD_ordered:
15817     case OMPD_atomic:
15818     case OMPD_distribute_simd:
15819     case OMPD_requires:
15820     case OMPD_metadirective:
15821       llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
15822     case OMPD_unknown:
15823     default:
15824       llvm_unreachable("Unknown OpenMP directive");
15825     }
15826     break;
15827   case OMPC_schedule:
15828     switch (DKind) {
15829     case OMPD_parallel_for:
15830     case OMPD_parallel_for_simd:
15831     case OMPD_distribute_parallel_for:
15832     case OMPD_distribute_parallel_for_simd:
15833     case OMPD_teams_distribute_parallel_for:
15834     case OMPD_teams_distribute_parallel_for_simd:
15835     case OMPD_target_parallel_for:
15836     case OMPD_target_parallel_for_simd:
15837     case OMPD_target_teams_distribute_parallel_for:
15838     case OMPD_target_teams_distribute_parallel_for_simd:
15839       CaptureRegion = OMPD_parallel;
15840       break;
15841     case OMPD_for:
15842     case OMPD_for_simd:
15843       // Do not capture schedule-clause expressions.
15844       break;
15845     case OMPD_task:
15846     case OMPD_taskloop:
15847     case OMPD_taskloop_simd:
15848     case OMPD_master_taskloop:
15849     case OMPD_masked_taskloop:
15850     case OMPD_master_taskloop_simd:
15851     case OMPD_masked_taskloop_simd:
15852     case OMPD_parallel_master_taskloop:
15853     case OMPD_parallel_masked_taskloop:
15854     case OMPD_parallel_master_taskloop_simd:
15855     case OMPD_parallel_masked_taskloop_simd:
15856     case OMPD_target_data:
15857     case OMPD_target_enter_data:
15858     case OMPD_target_exit_data:
15859     case OMPD_target_update:
15860     case OMPD_teams:
15861     case OMPD_teams_distribute:
15862     case OMPD_teams_distribute_simd:
15863     case OMPD_target_teams_distribute:
15864     case OMPD_target_teams_distribute_simd:
15865     case OMPD_target:
15866     case OMPD_target_simd:
15867     case OMPD_target_parallel:
15868     case OMPD_cancel:
15869     case OMPD_parallel:
15870     case OMPD_parallel_master:
15871     case OMPD_parallel_masked:
15872     case OMPD_parallel_sections:
15873     case OMPD_threadprivate:
15874     case OMPD_allocate:
15875     case OMPD_taskyield:
15876     case OMPD_error:
15877     case OMPD_barrier:
15878     case OMPD_taskwait:
15879     case OMPD_cancellation_point:
15880     case OMPD_flush:
15881     case OMPD_depobj:
15882     case OMPD_scan:
15883     case OMPD_declare_reduction:
15884     case OMPD_declare_mapper:
15885     case OMPD_declare_simd:
15886     case OMPD_declare_variant:
15887     case OMPD_begin_declare_variant:
15888     case OMPD_end_declare_variant:
15889     case OMPD_declare_target:
15890     case OMPD_end_declare_target:
15891     case OMPD_loop:
15892     case OMPD_teams_loop:
15893     case OMPD_target_teams_loop:
15894     case OMPD_parallel_loop:
15895     case OMPD_target_parallel_loop:
15896     case OMPD_simd:
15897     case OMPD_tile:
15898     case OMPD_unroll:
15899     case OMPD_sections:
15900     case OMPD_section:
15901     case OMPD_single:
15902     case OMPD_master:
15903     case OMPD_masked:
15904     case OMPD_critical:
15905     case OMPD_taskgroup:
15906     case OMPD_distribute:
15907     case OMPD_ordered:
15908     case OMPD_atomic:
15909     case OMPD_distribute_simd:
15910     case OMPD_target_teams:
15911     case OMPD_requires:
15912     case OMPD_metadirective:
15913       llvm_unreachable("Unexpected OpenMP directive with schedule clause");
15914     case OMPD_unknown:
15915     default:
15916       llvm_unreachable("Unknown OpenMP directive");
15917     }
15918     break;
15919   case OMPC_dist_schedule:
15920     switch (DKind) {
15921     case OMPD_teams_distribute_parallel_for:
15922     case OMPD_teams_distribute_parallel_for_simd:
15923     case OMPD_teams_distribute:
15924     case OMPD_teams_distribute_simd:
15925     case OMPD_target_teams_distribute_parallel_for:
15926     case OMPD_target_teams_distribute_parallel_for_simd:
15927     case OMPD_target_teams_distribute:
15928     case OMPD_target_teams_distribute_simd:
15929       CaptureRegion = OMPD_teams;
15930       break;
15931     case OMPD_distribute_parallel_for:
15932     case OMPD_distribute_parallel_for_simd:
15933     case OMPD_distribute:
15934     case OMPD_distribute_simd:
15935       // Do not capture dist_schedule-clause expressions.
15936       break;
15937     case OMPD_parallel_for:
15938     case OMPD_parallel_for_simd:
15939     case OMPD_target_parallel_for_simd:
15940     case OMPD_target_parallel_for:
15941     case OMPD_task:
15942     case OMPD_taskloop:
15943     case OMPD_taskloop_simd:
15944     case OMPD_master_taskloop:
15945     case OMPD_masked_taskloop:
15946     case OMPD_master_taskloop_simd:
15947     case OMPD_masked_taskloop_simd:
15948     case OMPD_parallel_master_taskloop:
15949     case OMPD_parallel_masked_taskloop:
15950     case OMPD_parallel_master_taskloop_simd:
15951     case OMPD_parallel_masked_taskloop_simd:
15952     case OMPD_target_data:
15953     case OMPD_target_enter_data:
15954     case OMPD_target_exit_data:
15955     case OMPD_target_update:
15956     case OMPD_teams:
15957     case OMPD_target:
15958     case OMPD_target_simd:
15959     case OMPD_target_parallel:
15960     case OMPD_cancel:
15961     case OMPD_parallel:
15962     case OMPD_parallel_master:
15963     case OMPD_parallel_masked:
15964     case OMPD_parallel_sections:
15965     case OMPD_threadprivate:
15966     case OMPD_allocate:
15967     case OMPD_taskyield:
15968     case OMPD_error:
15969     case OMPD_barrier:
15970     case OMPD_taskwait:
15971     case OMPD_cancellation_point:
15972     case OMPD_flush:
15973     case OMPD_depobj:
15974     case OMPD_scan:
15975     case OMPD_declare_reduction:
15976     case OMPD_declare_mapper:
15977     case OMPD_declare_simd:
15978     case OMPD_declare_variant:
15979     case OMPD_begin_declare_variant:
15980     case OMPD_end_declare_variant:
15981     case OMPD_declare_target:
15982     case OMPD_end_declare_target:
15983     case OMPD_loop:
15984     case OMPD_teams_loop:
15985     case OMPD_target_teams_loop:
15986     case OMPD_parallel_loop:
15987     case OMPD_target_parallel_loop:
15988     case OMPD_simd:
15989     case OMPD_tile:
15990     case OMPD_unroll:
15991     case OMPD_for:
15992     case OMPD_for_simd:
15993     case OMPD_sections:
15994     case OMPD_section:
15995     case OMPD_single:
15996     case OMPD_master:
15997     case OMPD_masked:
15998     case OMPD_critical:
15999     case OMPD_taskgroup:
16000     case OMPD_ordered:
16001     case OMPD_atomic:
16002     case OMPD_target_teams:
16003     case OMPD_requires:
16004     case OMPD_metadirective:
16005       llvm_unreachable("Unexpected OpenMP directive with dist_schedule clause");
16006     case OMPD_unknown:
16007     default:
16008       llvm_unreachable("Unknown OpenMP directive");
16009     }
16010     break;
16011   case OMPC_ompx_dyn_cgroup_mem:
16012     switch (DKind) {
16013     case OMPD_target:
16014     case OMPD_target_simd:
16015     case OMPD_target_teams:
16016     case OMPD_target_parallel:
16017     case OMPD_target_teams_distribute:
16018     case OMPD_target_teams_distribute_simd:
16019     case OMPD_target_parallel_for:
16020     case OMPD_target_parallel_for_simd:
16021     case OMPD_target_parallel_loop:
16022     case OMPD_target_teams_distribute_parallel_for:
16023     case OMPD_target_teams_distribute_parallel_for_simd:
16024     case OMPD_target_teams_loop:
16025       CaptureRegion = OMPD_target;
16026       break;
16027     default:
16028       llvm_unreachable("Unknown OpenMP directive");
16029     }
16030     break;
16031   case OMPC_device:
16032     switch (DKind) {
16033     case OMPD_target_update:
16034     case OMPD_target_enter_data:
16035     case OMPD_target_exit_data:
16036     case OMPD_target:
16037     case OMPD_target_simd:
16038     case OMPD_target_teams:
16039     case OMPD_target_parallel:
16040     case OMPD_target_teams_distribute:
16041     case OMPD_target_teams_distribute_simd:
16042     case OMPD_target_parallel_for:
16043     case OMPD_target_parallel_for_simd:
16044     case OMPD_target_parallel_loop:
16045     case OMPD_target_teams_distribute_parallel_for:
16046     case OMPD_target_teams_distribute_parallel_for_simd:
16047     case OMPD_target_teams_loop:
16048     case OMPD_dispatch:
16049       CaptureRegion = OMPD_task;
16050       break;
16051     case OMPD_target_data:
16052     case OMPD_interop:
16053       // Do not capture device-clause expressions.
16054       break;
16055     case OMPD_teams_distribute_parallel_for:
16056     case OMPD_teams_distribute_parallel_for_simd:
16057     case OMPD_teams:
16058     case OMPD_teams_distribute:
16059     case OMPD_teams_distribute_simd:
16060     case OMPD_distribute_parallel_for:
16061     case OMPD_distribute_parallel_for_simd:
16062     case OMPD_task:
16063     case OMPD_taskloop:
16064     case OMPD_taskloop_simd:
16065     case OMPD_master_taskloop:
16066     case OMPD_masked_taskloop:
16067     case OMPD_master_taskloop_simd:
16068     case OMPD_masked_taskloop_simd:
16069     case OMPD_parallel_master_taskloop:
16070     case OMPD_parallel_masked_taskloop:
16071     case OMPD_parallel_master_taskloop_simd:
16072     case OMPD_parallel_masked_taskloop_simd:
16073     case OMPD_cancel:
16074     case OMPD_parallel:
16075     case OMPD_parallel_master:
16076     case OMPD_parallel_masked:
16077     case OMPD_parallel_sections:
16078     case OMPD_parallel_for:
16079     case OMPD_parallel_for_simd:
16080     case OMPD_threadprivate:
16081     case OMPD_allocate:
16082     case OMPD_taskyield:
16083     case OMPD_error:
16084     case OMPD_barrier:
16085     case OMPD_taskwait:
16086     case OMPD_cancellation_point:
16087     case OMPD_flush:
16088     case OMPD_depobj:
16089     case OMPD_scan:
16090     case OMPD_declare_reduction:
16091     case OMPD_declare_mapper:
16092     case OMPD_declare_simd:
16093     case OMPD_declare_variant:
16094     case OMPD_begin_declare_variant:
16095     case OMPD_end_declare_variant:
16096     case OMPD_declare_target:
16097     case OMPD_end_declare_target:
16098     case OMPD_loop:
16099     case OMPD_teams_loop:
16100     case OMPD_parallel_loop:
16101     case OMPD_simd:
16102     case OMPD_tile:
16103     case OMPD_unroll:
16104     case OMPD_for:
16105     case OMPD_for_simd:
16106     case OMPD_sections:
16107     case OMPD_section:
16108     case OMPD_single:
16109     case OMPD_master:
16110     case OMPD_masked:
16111     case OMPD_critical:
16112     case OMPD_taskgroup:
16113     case OMPD_distribute:
16114     case OMPD_ordered:
16115     case OMPD_atomic:
16116     case OMPD_distribute_simd:
16117     case OMPD_requires:
16118     case OMPD_metadirective:
16119       llvm_unreachable("Unexpected OpenMP directive with device-clause");
16120     case OMPD_unknown:
16121     default:
16122       llvm_unreachable("Unknown OpenMP directive");
16123     }
16124     break;
16125   case OMPC_grainsize:
16126   case OMPC_num_tasks:
16127   case OMPC_final:
16128   case OMPC_priority:
16129     switch (DKind) {
16130     case OMPD_task:
16131     case OMPD_taskloop:
16132     case OMPD_taskloop_simd:
16133     case OMPD_master_taskloop:
16134     case OMPD_masked_taskloop:
16135     case OMPD_master_taskloop_simd:
16136     case OMPD_masked_taskloop_simd:
16137       break;
16138     case OMPD_parallel_masked_taskloop:
16139     case OMPD_parallel_masked_taskloop_simd:
16140     case OMPD_parallel_master_taskloop:
16141     case OMPD_parallel_master_taskloop_simd:
16142       CaptureRegion = OMPD_parallel;
16143       break;
16144     case OMPD_target_update:
16145     case OMPD_target_enter_data:
16146     case OMPD_target_exit_data:
16147     case OMPD_target:
16148     case OMPD_target_simd:
16149     case OMPD_target_teams:
16150     case OMPD_target_parallel:
16151     case OMPD_target_teams_distribute:
16152     case OMPD_target_teams_distribute_simd:
16153     case OMPD_target_parallel_for:
16154     case OMPD_target_parallel_for_simd:
16155     case OMPD_target_teams_distribute_parallel_for:
16156     case OMPD_target_teams_distribute_parallel_for_simd:
16157     case OMPD_target_data:
16158     case OMPD_teams_distribute_parallel_for:
16159     case OMPD_teams_distribute_parallel_for_simd:
16160     case OMPD_teams:
16161     case OMPD_teams_distribute:
16162     case OMPD_teams_distribute_simd:
16163     case OMPD_distribute_parallel_for:
16164     case OMPD_distribute_parallel_for_simd:
16165     case OMPD_cancel:
16166     case OMPD_parallel:
16167     case OMPD_parallel_master:
16168     case OMPD_parallel_masked:
16169     case OMPD_parallel_sections:
16170     case OMPD_parallel_for:
16171     case OMPD_parallel_for_simd:
16172     case OMPD_threadprivate:
16173     case OMPD_allocate:
16174     case OMPD_taskyield:
16175     case OMPD_error:
16176     case OMPD_barrier:
16177     case OMPD_taskwait:
16178     case OMPD_cancellation_point:
16179     case OMPD_flush:
16180     case OMPD_depobj:
16181     case OMPD_scan:
16182     case OMPD_declare_reduction:
16183     case OMPD_declare_mapper:
16184     case OMPD_declare_simd:
16185     case OMPD_declare_variant:
16186     case OMPD_begin_declare_variant:
16187     case OMPD_end_declare_variant:
16188     case OMPD_declare_target:
16189     case OMPD_end_declare_target:
16190     case OMPD_loop:
16191     case OMPD_teams_loop:
16192     case OMPD_target_teams_loop:
16193     case OMPD_parallel_loop:
16194     case OMPD_target_parallel_loop:
16195     case OMPD_simd:
16196     case OMPD_tile:
16197     case OMPD_unroll:
16198     case OMPD_for:
16199     case OMPD_for_simd:
16200     case OMPD_sections:
16201     case OMPD_section:
16202     case OMPD_single:
16203     case OMPD_master:
16204     case OMPD_masked:
16205     case OMPD_critical:
16206     case OMPD_taskgroup:
16207     case OMPD_distribute:
16208     case OMPD_ordered:
16209     case OMPD_atomic:
16210     case OMPD_distribute_simd:
16211     case OMPD_requires:
16212     case OMPD_metadirective:
16213       llvm_unreachable("Unexpected OpenMP directive with grainsize-clause");
16214     case OMPD_unknown:
16215     default:
16216       llvm_unreachable("Unknown OpenMP directive");
16217     }
16218     break;
16219   case OMPC_novariants:
16220   case OMPC_nocontext:
16221     switch (DKind) {
16222     case OMPD_dispatch:
16223       CaptureRegion = OMPD_task;
16224       break;
16225     default:
16226       llvm_unreachable("Unexpected OpenMP directive");
16227     }
16228     break;
16229   case OMPC_filter:
16230     // Do not capture filter-clause expressions.
16231     break;
16232   case OMPC_when:
16233     if (DKind == OMPD_metadirective) {
16234       CaptureRegion = OMPD_metadirective;
16235     } else if (DKind == OMPD_unknown) {
16236       llvm_unreachable("Unknown OpenMP directive");
16237     } else {
16238       llvm_unreachable("Unexpected OpenMP directive with when clause");
16239     }
16240     break;
16241   case OMPC_firstprivate:
16242   case OMPC_lastprivate:
16243   case OMPC_reduction:
16244   case OMPC_task_reduction:
16245   case OMPC_in_reduction:
16246   case OMPC_linear:
16247   case OMPC_default:
16248   case OMPC_proc_bind:
16249   case OMPC_safelen:
16250   case OMPC_simdlen:
16251   case OMPC_sizes:
16252   case OMPC_allocator:
16253   case OMPC_collapse:
16254   case OMPC_private:
16255   case OMPC_shared:
16256   case OMPC_aligned:
16257   case OMPC_copyin:
16258   case OMPC_copyprivate:
16259   case OMPC_ordered:
16260   case OMPC_nowait:
16261   case OMPC_untied:
16262   case OMPC_mergeable:
16263   case OMPC_threadprivate:
16264   case OMPC_allocate:
16265   case OMPC_flush:
16266   case OMPC_depobj:
16267   case OMPC_read:
16268   case OMPC_write:
16269   case OMPC_update:
16270   case OMPC_capture:
16271   case OMPC_compare:
16272   case OMPC_seq_cst:
16273   case OMPC_acq_rel:
16274   case OMPC_acquire:
16275   case OMPC_release:
16276   case OMPC_relaxed:
16277   case OMPC_depend:
16278   case OMPC_threads:
16279   case OMPC_simd:
16280   case OMPC_map:
16281   case OMPC_nogroup:
16282   case OMPC_hint:
16283   case OMPC_defaultmap:
16284   case OMPC_unknown:
16285   case OMPC_uniform:
16286   case OMPC_to:
16287   case OMPC_from:
16288   case OMPC_use_device_ptr:
16289   case OMPC_use_device_addr:
16290   case OMPC_is_device_ptr:
16291   case OMPC_unified_address:
16292   case OMPC_unified_shared_memory:
16293   case OMPC_reverse_offload:
16294   case OMPC_dynamic_allocators:
16295   case OMPC_atomic_default_mem_order:
16296   case OMPC_device_type:
16297   case OMPC_match:
16298   case OMPC_nontemporal:
16299   case OMPC_order:
16300   case OMPC_at:
16301   case OMPC_severity:
16302   case OMPC_message:
16303   case OMPC_destroy:
16304   case OMPC_detach:
16305   case OMPC_inclusive:
16306   case OMPC_exclusive:
16307   case OMPC_uses_allocators:
16308   case OMPC_affinity:
16309   case OMPC_bind:
16310   default:
16311     llvm_unreachable("Unexpected OpenMP clause.");
16312   }
16313   return CaptureRegion;
16314 }
16315 
16316 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
16317                                      Expr *Condition, SourceLocation StartLoc,
16318                                      SourceLocation LParenLoc,
16319                                      SourceLocation NameModifierLoc,
16320                                      SourceLocation ColonLoc,
16321                                      SourceLocation EndLoc) {
16322   Expr *ValExpr = Condition;
16323   Stmt *HelperValStmt = nullptr;
16324   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
16325   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
16326       !Condition->isInstantiationDependent() &&
16327       !Condition->containsUnexpandedParameterPack()) {
16328     ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
16329     if (Val.isInvalid())
16330       return nullptr;
16331 
16332     ValExpr = Val.get();
16333 
16334     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16335     CaptureRegion = getOpenMPCaptureRegionForClause(
16336         DKind, OMPC_if, LangOpts.OpenMP, NameModifier);
16337     if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16338       ValExpr = MakeFullExpr(ValExpr).get();
16339       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16340       ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16341       HelperValStmt = buildPreInits(Context, Captures);
16342     }
16343   }
16344 
16345   return new (Context)
16346       OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
16347                   LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
16348 }
16349 
16350 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
16351                                         SourceLocation StartLoc,
16352                                         SourceLocation LParenLoc,
16353                                         SourceLocation EndLoc) {
16354   Expr *ValExpr = Condition;
16355   Stmt *HelperValStmt = nullptr;
16356   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
16357   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
16358       !Condition->isInstantiationDependent() &&
16359       !Condition->containsUnexpandedParameterPack()) {
16360     ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
16361     if (Val.isInvalid())
16362       return nullptr;
16363 
16364     ValExpr = MakeFullExpr(Val.get()).get();
16365 
16366     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16367     CaptureRegion =
16368         getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP);
16369     if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16370       ValExpr = MakeFullExpr(ValExpr).get();
16371       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16372       ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16373       HelperValStmt = buildPreInits(Context, Captures);
16374     }
16375   }
16376 
16377   return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion,
16378                                       StartLoc, LParenLoc, EndLoc);
16379 }
16380 
16381 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
16382                                                         Expr *Op) {
16383   if (!Op)
16384     return ExprError();
16385 
16386   class IntConvertDiagnoser : public ICEConvertDiagnoser {
16387   public:
16388     IntConvertDiagnoser()
16389         : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
16390     SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
16391                                          QualType T) override {
16392       return S.Diag(Loc, diag::err_omp_not_integral) << T;
16393     }
16394     SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
16395                                              QualType T) override {
16396       return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
16397     }
16398     SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
16399                                                QualType T,
16400                                                QualType ConvTy) override {
16401       return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
16402     }
16403     SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
16404                                            QualType ConvTy) override {
16405       return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
16406              << ConvTy->isEnumeralType() << ConvTy;
16407     }
16408     SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
16409                                             QualType T) override {
16410       return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
16411     }
16412     SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
16413                                         QualType ConvTy) override {
16414       return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
16415              << ConvTy->isEnumeralType() << ConvTy;
16416     }
16417     SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
16418                                              QualType) override {
16419       llvm_unreachable("conversion functions are permitted");
16420     }
16421   } ConvertDiagnoser;
16422   return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
16423 }
16424 
16425 static bool
16426 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind,
16427                           bool StrictlyPositive, bool BuildCapture = false,
16428                           OpenMPDirectiveKind DKind = OMPD_unknown,
16429                           OpenMPDirectiveKind *CaptureRegion = nullptr,
16430                           Stmt **HelperValStmt = nullptr) {
16431   if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
16432       !ValExpr->isInstantiationDependent()) {
16433     SourceLocation Loc = ValExpr->getExprLoc();
16434     ExprResult Value =
16435         SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
16436     if (Value.isInvalid())
16437       return false;
16438 
16439     ValExpr = Value.get();
16440     // The expression must evaluate to a non-negative integer value.
16441     if (std::optional<llvm::APSInt> Result =
16442             ValExpr->getIntegerConstantExpr(SemaRef.Context)) {
16443       if (Result->isSigned() &&
16444           !((!StrictlyPositive && Result->isNonNegative()) ||
16445             (StrictlyPositive && Result->isStrictlyPositive()))) {
16446         SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
16447             << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
16448             << ValExpr->getSourceRange();
16449         return false;
16450       }
16451     }
16452     if (!BuildCapture)
16453       return true;
16454     *CaptureRegion =
16455         getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP);
16456     if (*CaptureRegion != OMPD_unknown &&
16457         !SemaRef.CurContext->isDependentContext()) {
16458       ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
16459       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16460       ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
16461       *HelperValStmt = buildPreInits(SemaRef.Context, Captures);
16462     }
16463   }
16464   return true;
16465 }
16466 
16467 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
16468                                              SourceLocation StartLoc,
16469                                              SourceLocation LParenLoc,
16470                                              SourceLocation EndLoc) {
16471   Expr *ValExpr = NumThreads;
16472   Stmt *HelperValStmt = nullptr;
16473 
16474   // OpenMP [2.5, Restrictions]
16475   //  The num_threads expression must evaluate to a positive integer value.
16476   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
16477                                  /*StrictlyPositive=*/true))
16478     return nullptr;
16479 
16480   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16481   OpenMPDirectiveKind CaptureRegion =
16482       getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP);
16483   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16484     ValExpr = MakeFullExpr(ValExpr).get();
16485     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16486     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16487     HelperValStmt = buildPreInits(Context, Captures);
16488   }
16489 
16490   return new (Context) OMPNumThreadsClause(
16491       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
16492 }
16493 
16494 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
16495                                                        OpenMPClauseKind CKind,
16496                                                        bool StrictlyPositive,
16497                                                        bool SuppressExprDiags) {
16498   if (!E)
16499     return ExprError();
16500   if (E->isValueDependent() || E->isTypeDependent() ||
16501       E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
16502     return E;
16503 
16504   llvm::APSInt Result;
16505   ExprResult ICE;
16506   if (SuppressExprDiags) {
16507     // Use a custom diagnoser that suppresses 'note' diagnostics about the
16508     // expression.
16509     struct SuppressedDiagnoser : public Sema::VerifyICEDiagnoser {
16510       SuppressedDiagnoser() : VerifyICEDiagnoser(/*Suppress=*/true) {}
16511       Sema::SemaDiagnosticBuilder diagnoseNotICE(Sema &S,
16512                                                  SourceLocation Loc) override {
16513         llvm_unreachable("Diagnostic suppressed");
16514       }
16515     } Diagnoser;
16516     ICE = VerifyIntegerConstantExpression(E, &Result, Diagnoser, AllowFold);
16517   } else {
16518     ICE = VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold);
16519   }
16520   if (ICE.isInvalid())
16521     return ExprError();
16522 
16523   if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
16524       (!StrictlyPositive && !Result.isNonNegative())) {
16525     Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
16526         << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
16527         << E->getSourceRange();
16528     return ExprError();
16529   }
16530   if ((CKind == OMPC_aligned || CKind == OMPC_align) && !Result.isPowerOf2()) {
16531     Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
16532         << E->getSourceRange();
16533     return ExprError();
16534   }
16535   if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
16536     DSAStack->setAssociatedLoops(Result.getExtValue());
16537   else if (CKind == OMPC_ordered)
16538     DSAStack->setAssociatedLoops(Result.getExtValue());
16539   return ICE;
16540 }
16541 
16542 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
16543                                           SourceLocation LParenLoc,
16544                                           SourceLocation EndLoc) {
16545   // OpenMP [2.8.1, simd construct, Description]
16546   // The parameter of the safelen clause must be a constant
16547   // positive integer expression.
16548   ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
16549   if (Safelen.isInvalid())
16550     return nullptr;
16551   return new (Context)
16552       OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
16553 }
16554 
16555 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
16556                                           SourceLocation LParenLoc,
16557                                           SourceLocation EndLoc) {
16558   // OpenMP [2.8.1, simd construct, Description]
16559   // The parameter of the simdlen clause must be a constant
16560   // positive integer expression.
16561   ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
16562   if (Simdlen.isInvalid())
16563     return nullptr;
16564   return new (Context)
16565       OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
16566 }
16567 
16568 /// Tries to find omp_allocator_handle_t type.
16569 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
16570                                     DSAStackTy *Stack) {
16571   if (!Stack->getOMPAllocatorHandleT().isNull())
16572     return true;
16573 
16574   // Set the allocator handle type.
16575   IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_allocator_handle_t");
16576   ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
16577   if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
16578     S.Diag(Loc, diag::err_omp_implied_type_not_found)
16579         << "omp_allocator_handle_t";
16580     return false;
16581   }
16582   QualType AllocatorHandleEnumTy = PT.get();
16583   AllocatorHandleEnumTy.addConst();
16584   Stack->setOMPAllocatorHandleT(AllocatorHandleEnumTy);
16585 
16586   // Fill the predefined allocator map.
16587   bool ErrorFound = false;
16588   for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
16589     auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
16590     StringRef Allocator =
16591         OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
16592     DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
16593     auto *VD = dyn_cast_or_null<ValueDecl>(
16594         S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
16595     if (!VD) {
16596       ErrorFound = true;
16597       break;
16598     }
16599     QualType AllocatorType =
16600         VD->getType().getNonLValueExprType(S.getASTContext());
16601     ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
16602     if (!Res.isUsable()) {
16603       ErrorFound = true;
16604       break;
16605     }
16606     Res = S.PerformImplicitConversion(Res.get(), AllocatorHandleEnumTy,
16607                                       Sema::AA_Initializing,
16608                                       /* AllowExplicit */ true);
16609     if (!Res.isUsable()) {
16610       ErrorFound = true;
16611       break;
16612     }
16613     Stack->setAllocator(AllocatorKind, Res.get());
16614   }
16615   if (ErrorFound) {
16616     S.Diag(Loc, diag::err_omp_implied_type_not_found)
16617         << "omp_allocator_handle_t";
16618     return false;
16619   }
16620 
16621   return true;
16622 }
16623 
16624 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc,
16625                                             SourceLocation LParenLoc,
16626                                             SourceLocation EndLoc) {
16627   // OpenMP [2.11.3, allocate Directive, Description]
16628   // allocator is an expression of omp_allocator_handle_t type.
16629   if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack))
16630     return nullptr;
16631 
16632   ExprResult Allocator = DefaultLvalueConversion(A);
16633   if (Allocator.isInvalid())
16634     return nullptr;
16635   Allocator = PerformImplicitConversion(Allocator.get(),
16636                                         DSAStack->getOMPAllocatorHandleT(),
16637                                         Sema::AA_Initializing,
16638                                         /*AllowExplicit=*/true);
16639   if (Allocator.isInvalid())
16640     return nullptr;
16641   return new (Context)
16642       OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
16643 }
16644 
16645 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
16646                                            SourceLocation StartLoc,
16647                                            SourceLocation LParenLoc,
16648                                            SourceLocation EndLoc) {
16649   // OpenMP [2.7.1, loop construct, Description]
16650   // OpenMP [2.8.1, simd construct, Description]
16651   // OpenMP [2.9.6, distribute construct, Description]
16652   // The parameter of the collapse clause must be a constant
16653   // positive integer expression.
16654   ExprResult NumForLoopsResult =
16655       VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
16656   if (NumForLoopsResult.isInvalid())
16657     return nullptr;
16658   return new (Context)
16659       OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
16660 }
16661 
16662 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
16663                                           SourceLocation EndLoc,
16664                                           SourceLocation LParenLoc,
16665                                           Expr *NumForLoops) {
16666   // OpenMP [2.7.1, loop construct, Description]
16667   // OpenMP [2.8.1, simd construct, Description]
16668   // OpenMP [2.9.6, distribute construct, Description]
16669   // The parameter of the ordered clause must be a constant
16670   // positive integer expression if any.
16671   if (NumForLoops && LParenLoc.isValid()) {
16672     ExprResult NumForLoopsResult =
16673         VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
16674     if (NumForLoopsResult.isInvalid())
16675       return nullptr;
16676     NumForLoops = NumForLoopsResult.get();
16677   } else {
16678     NumForLoops = nullptr;
16679   }
16680   auto *Clause = OMPOrderedClause::Create(
16681       Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0,
16682       StartLoc, LParenLoc, EndLoc);
16683   DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
16684   return Clause;
16685 }
16686 
16687 OMPClause *Sema::ActOnOpenMPSimpleClause(
16688     OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
16689     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
16690   OMPClause *Res = nullptr;
16691   switch (Kind) {
16692   case OMPC_default:
16693     Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument),
16694                                    ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16695     break;
16696   case OMPC_proc_bind:
16697     Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument),
16698                                     ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16699     break;
16700   case OMPC_atomic_default_mem_order:
16701     Res = ActOnOpenMPAtomicDefaultMemOrderClause(
16702         static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
16703         ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16704     break;
16705   case OMPC_update:
16706     Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
16707                                   ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16708     break;
16709   case OMPC_bind:
16710     Res = ActOnOpenMPBindClause(static_cast<OpenMPBindClauseKind>(Argument),
16711                                 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16712     break;
16713   case OMPC_at:
16714     Res = ActOnOpenMPAtClause(static_cast<OpenMPAtClauseKind>(Argument),
16715                               ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16716     break;
16717   case OMPC_severity:
16718     Res = ActOnOpenMPSeverityClause(
16719         static_cast<OpenMPSeverityClauseKind>(Argument), ArgumentLoc, StartLoc,
16720         LParenLoc, EndLoc);
16721     break;
16722   case OMPC_if:
16723   case OMPC_final:
16724   case OMPC_num_threads:
16725   case OMPC_safelen:
16726   case OMPC_simdlen:
16727   case OMPC_sizes:
16728   case OMPC_allocator:
16729   case OMPC_collapse:
16730   case OMPC_schedule:
16731   case OMPC_private:
16732   case OMPC_firstprivate:
16733   case OMPC_lastprivate:
16734   case OMPC_shared:
16735   case OMPC_reduction:
16736   case OMPC_task_reduction:
16737   case OMPC_in_reduction:
16738   case OMPC_linear:
16739   case OMPC_aligned:
16740   case OMPC_copyin:
16741   case OMPC_copyprivate:
16742   case OMPC_ordered:
16743   case OMPC_nowait:
16744   case OMPC_untied:
16745   case OMPC_mergeable:
16746   case OMPC_threadprivate:
16747   case OMPC_allocate:
16748   case OMPC_flush:
16749   case OMPC_depobj:
16750   case OMPC_read:
16751   case OMPC_write:
16752   case OMPC_capture:
16753   case OMPC_compare:
16754   case OMPC_seq_cst:
16755   case OMPC_acq_rel:
16756   case OMPC_acquire:
16757   case OMPC_release:
16758   case OMPC_relaxed:
16759   case OMPC_depend:
16760   case OMPC_device:
16761   case OMPC_threads:
16762   case OMPC_simd:
16763   case OMPC_map:
16764   case OMPC_num_teams:
16765   case OMPC_thread_limit:
16766   case OMPC_priority:
16767   case OMPC_grainsize:
16768   case OMPC_nogroup:
16769   case OMPC_num_tasks:
16770   case OMPC_hint:
16771   case OMPC_dist_schedule:
16772   case OMPC_defaultmap:
16773   case OMPC_unknown:
16774   case OMPC_uniform:
16775   case OMPC_to:
16776   case OMPC_from:
16777   case OMPC_use_device_ptr:
16778   case OMPC_use_device_addr:
16779   case OMPC_is_device_ptr:
16780   case OMPC_has_device_addr:
16781   case OMPC_unified_address:
16782   case OMPC_unified_shared_memory:
16783   case OMPC_reverse_offload:
16784   case OMPC_dynamic_allocators:
16785   case OMPC_device_type:
16786   case OMPC_match:
16787   case OMPC_nontemporal:
16788   case OMPC_destroy:
16789   case OMPC_novariants:
16790   case OMPC_nocontext:
16791   case OMPC_detach:
16792   case OMPC_inclusive:
16793   case OMPC_exclusive:
16794   case OMPC_uses_allocators:
16795   case OMPC_affinity:
16796   case OMPC_when:
16797   case OMPC_message:
16798   default:
16799     llvm_unreachable("Clause is not allowed.");
16800   }
16801   return Res;
16802 }
16803 
16804 static std::string
16805 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
16806                         ArrayRef<unsigned> Exclude = std::nullopt) {
16807   SmallString<256> Buffer;
16808   llvm::raw_svector_ostream Out(Buffer);
16809   unsigned Skipped = Exclude.size();
16810   for (unsigned I = First; I < Last; ++I) {
16811     if (llvm::is_contained(Exclude, I)) {
16812       --Skipped;
16813       continue;
16814     }
16815     Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
16816     if (I + Skipped + 2 == Last)
16817       Out << " or ";
16818     else if (I + Skipped + 1 != Last)
16819       Out << ", ";
16820   }
16821   return std::string(Out.str());
16822 }
16823 
16824 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind,
16825                                           SourceLocation KindKwLoc,
16826                                           SourceLocation StartLoc,
16827                                           SourceLocation LParenLoc,
16828                                           SourceLocation EndLoc) {
16829   if (Kind == OMP_DEFAULT_unknown) {
16830     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16831         << getListOfPossibleValues(OMPC_default, /*First=*/0,
16832                                    /*Last=*/unsigned(OMP_DEFAULT_unknown))
16833         << getOpenMPClauseName(OMPC_default);
16834     return nullptr;
16835   }
16836 
16837   switch (Kind) {
16838   case OMP_DEFAULT_none:
16839     DSAStack->setDefaultDSANone(KindKwLoc);
16840     break;
16841   case OMP_DEFAULT_shared:
16842     DSAStack->setDefaultDSAShared(KindKwLoc);
16843     break;
16844   case OMP_DEFAULT_firstprivate:
16845     DSAStack->setDefaultDSAFirstPrivate(KindKwLoc);
16846     break;
16847   case OMP_DEFAULT_private:
16848     DSAStack->setDefaultDSAPrivate(KindKwLoc);
16849     break;
16850   default:
16851     llvm_unreachable("DSA unexpected in OpenMP default clause");
16852   }
16853 
16854   return new (Context)
16855       OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
16856 }
16857 
16858 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind,
16859                                            SourceLocation KindKwLoc,
16860                                            SourceLocation StartLoc,
16861                                            SourceLocation LParenLoc,
16862                                            SourceLocation EndLoc) {
16863   if (Kind == OMP_PROC_BIND_unknown) {
16864     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16865         << getListOfPossibleValues(OMPC_proc_bind,
16866                                    /*First=*/unsigned(OMP_PROC_BIND_master),
16867                                    /*Last=*/
16868                                    unsigned(LangOpts.OpenMP > 50
16869                                                 ? OMP_PROC_BIND_primary
16870                                                 : OMP_PROC_BIND_spread) +
16871                                        1)
16872         << getOpenMPClauseName(OMPC_proc_bind);
16873     return nullptr;
16874   }
16875   if (Kind == OMP_PROC_BIND_primary && LangOpts.OpenMP < 51)
16876     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16877         << getListOfPossibleValues(OMPC_proc_bind,
16878                                    /*First=*/unsigned(OMP_PROC_BIND_master),
16879                                    /*Last=*/
16880                                    unsigned(OMP_PROC_BIND_spread) + 1)
16881         << getOpenMPClauseName(OMPC_proc_bind);
16882   return new (Context)
16883       OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
16884 }
16885 
16886 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause(
16887     OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc,
16888     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
16889   if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) {
16890     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16891         << getListOfPossibleValues(
16892                OMPC_atomic_default_mem_order, /*First=*/0,
16893                /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown)
16894         << getOpenMPClauseName(OMPC_atomic_default_mem_order);
16895     return nullptr;
16896   }
16897   return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
16898                                                       LParenLoc, EndLoc);
16899 }
16900 
16901 OMPClause *Sema::ActOnOpenMPAtClause(OpenMPAtClauseKind Kind,
16902                                      SourceLocation KindKwLoc,
16903                                      SourceLocation StartLoc,
16904                                      SourceLocation LParenLoc,
16905                                      SourceLocation EndLoc) {
16906   if (Kind == OMPC_AT_unknown) {
16907     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16908         << getListOfPossibleValues(OMPC_at, /*First=*/0,
16909                                    /*Last=*/OMPC_AT_unknown)
16910         << getOpenMPClauseName(OMPC_at);
16911     return nullptr;
16912   }
16913   return new (Context)
16914       OMPAtClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
16915 }
16916 
16917 OMPClause *Sema::ActOnOpenMPSeverityClause(OpenMPSeverityClauseKind Kind,
16918                                            SourceLocation KindKwLoc,
16919                                            SourceLocation StartLoc,
16920                                            SourceLocation LParenLoc,
16921                                            SourceLocation EndLoc) {
16922   if (Kind == OMPC_SEVERITY_unknown) {
16923     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16924         << getListOfPossibleValues(OMPC_severity, /*First=*/0,
16925                                    /*Last=*/OMPC_SEVERITY_unknown)
16926         << getOpenMPClauseName(OMPC_severity);
16927     return nullptr;
16928   }
16929   return new (Context)
16930       OMPSeverityClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
16931 }
16932 
16933 OMPClause *Sema::ActOnOpenMPMessageClause(Expr *ME, SourceLocation StartLoc,
16934                                           SourceLocation LParenLoc,
16935                                           SourceLocation EndLoc) {
16936   assert(ME && "NULL expr in Message clause");
16937   if (!isa<StringLiteral>(ME)) {
16938     Diag(ME->getBeginLoc(), diag::warn_clause_expected_string)
16939         << getOpenMPClauseName(OMPC_message);
16940     return nullptr;
16941   }
16942   return new (Context) OMPMessageClause(ME, StartLoc, LParenLoc, EndLoc);
16943 }
16944 
16945 OMPClause *Sema::ActOnOpenMPOrderClause(
16946     OpenMPOrderClauseModifier Modifier, OpenMPOrderClauseKind Kind,
16947     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
16948     SourceLocation KindLoc, SourceLocation EndLoc) {
16949   if (Kind != OMPC_ORDER_concurrent ||
16950       (LangOpts.OpenMP < 51 && MLoc.isValid())) {
16951     // Kind should be concurrent,
16952     // Modifiers introduced in OpenMP 5.1
16953     static_assert(OMPC_ORDER_unknown > 0,
16954                   "OMPC_ORDER_unknown not greater than 0");
16955 
16956     Diag(KindLoc, diag::err_omp_unexpected_clause_value)
16957         << getListOfPossibleValues(OMPC_order,
16958                                    /*First=*/0,
16959                                    /*Last=*/OMPC_ORDER_unknown)
16960         << getOpenMPClauseName(OMPC_order);
16961     return nullptr;
16962   }
16963   if (LangOpts.OpenMP >= 51) {
16964     if (Modifier == OMPC_ORDER_MODIFIER_unknown && MLoc.isValid()) {
16965       Diag(MLoc, diag::err_omp_unexpected_clause_value)
16966           << getListOfPossibleValues(OMPC_order,
16967                                      /*First=*/OMPC_ORDER_MODIFIER_unknown + 1,
16968                                      /*Last=*/OMPC_ORDER_MODIFIER_last)
16969           << getOpenMPClauseName(OMPC_order);
16970     } else {
16971       DSAStack->setRegionHasOrderConcurrent(/*HasOrderConcurrent=*/true);
16972       if (DSAStack->getCurScope()) {
16973         // mark the current scope with 'order' flag
16974         unsigned existingFlags = DSAStack->getCurScope()->getFlags();
16975         DSAStack->getCurScope()->setFlags(existingFlags |
16976                                           Scope::OpenMPOrderClauseScope);
16977       }
16978     }
16979   }
16980   return new (Context) OMPOrderClause(Kind, KindLoc, StartLoc, LParenLoc,
16981                                       EndLoc, Modifier, MLoc);
16982 }
16983 
16984 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,
16985                                          SourceLocation KindKwLoc,
16986                                          SourceLocation StartLoc,
16987                                          SourceLocation LParenLoc,
16988                                          SourceLocation EndLoc) {
16989   if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source ||
16990       Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) {
16991     SmallVector<unsigned> Except = {
16992         OMPC_DEPEND_source, OMPC_DEPEND_sink, OMPC_DEPEND_depobj,
16993         OMPC_DEPEND_outallmemory, OMPC_DEPEND_inoutallmemory};
16994     if (LangOpts.OpenMP < 51)
16995       Except.push_back(OMPC_DEPEND_inoutset);
16996     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16997         << getListOfPossibleValues(OMPC_depend, /*First=*/0,
16998                                    /*Last=*/OMPC_DEPEND_unknown, Except)
16999         << getOpenMPClauseName(OMPC_update);
17000     return nullptr;
17001   }
17002   return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind,
17003                                  EndLoc);
17004 }
17005 
17006 OMPClause *Sema::ActOnOpenMPSizesClause(ArrayRef<Expr *> SizeExprs,
17007                                         SourceLocation StartLoc,
17008                                         SourceLocation LParenLoc,
17009                                         SourceLocation EndLoc) {
17010   for (Expr *SizeExpr : SizeExprs) {
17011     ExprResult NumForLoopsResult = VerifyPositiveIntegerConstantInClause(
17012         SizeExpr, OMPC_sizes, /*StrictlyPositive=*/true);
17013     if (!NumForLoopsResult.isUsable())
17014       return nullptr;
17015   }
17016 
17017   DSAStack->setAssociatedLoops(SizeExprs.size());
17018   return OMPSizesClause::Create(Context, StartLoc, LParenLoc, EndLoc,
17019                                 SizeExprs);
17020 }
17021 
17022 OMPClause *Sema::ActOnOpenMPFullClause(SourceLocation StartLoc,
17023                                        SourceLocation EndLoc) {
17024   return OMPFullClause::Create(Context, StartLoc, EndLoc);
17025 }
17026 
17027 OMPClause *Sema::ActOnOpenMPPartialClause(Expr *FactorExpr,
17028                                           SourceLocation StartLoc,
17029                                           SourceLocation LParenLoc,
17030                                           SourceLocation EndLoc) {
17031   if (FactorExpr) {
17032     // If an argument is specified, it must be a constant (or an unevaluated
17033     // template expression).
17034     ExprResult FactorResult = VerifyPositiveIntegerConstantInClause(
17035         FactorExpr, OMPC_partial, /*StrictlyPositive=*/true);
17036     if (FactorResult.isInvalid())
17037       return nullptr;
17038     FactorExpr = FactorResult.get();
17039   }
17040 
17041   return OMPPartialClause::Create(Context, StartLoc, LParenLoc, EndLoc,
17042                                   FactorExpr);
17043 }
17044 
17045 OMPClause *Sema::ActOnOpenMPAlignClause(Expr *A, SourceLocation StartLoc,
17046                                         SourceLocation LParenLoc,
17047                                         SourceLocation EndLoc) {
17048   ExprResult AlignVal;
17049   AlignVal = VerifyPositiveIntegerConstantInClause(A, OMPC_align);
17050   if (AlignVal.isInvalid())
17051     return nullptr;
17052   return OMPAlignClause::Create(Context, AlignVal.get(), StartLoc, LParenLoc,
17053                                 EndLoc);
17054 }
17055 
17056 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
17057     OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
17058     SourceLocation StartLoc, SourceLocation LParenLoc,
17059     ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
17060     SourceLocation EndLoc) {
17061   OMPClause *Res = nullptr;
17062   switch (Kind) {
17063   case OMPC_schedule:
17064     enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
17065     assert(Argument.size() == NumberOfElements &&
17066            ArgumentLoc.size() == NumberOfElements);
17067     Res = ActOnOpenMPScheduleClause(
17068         static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
17069         static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
17070         static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
17071         StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
17072         ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
17073     break;
17074   case OMPC_if:
17075     assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
17076     Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
17077                               Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
17078                               DelimLoc, EndLoc);
17079     break;
17080   case OMPC_dist_schedule:
17081     Res = ActOnOpenMPDistScheduleClause(
17082         static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
17083         StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
17084     break;
17085   case OMPC_defaultmap:
17086     enum { Modifier, DefaultmapKind };
17087     Res = ActOnOpenMPDefaultmapClause(
17088         static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
17089         static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
17090         StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
17091         EndLoc);
17092     break;
17093   case OMPC_order:
17094     enum { OrderModifier, OrderKind };
17095     Res = ActOnOpenMPOrderClause(
17096         static_cast<OpenMPOrderClauseModifier>(Argument[OrderModifier]),
17097         static_cast<OpenMPOrderClauseKind>(Argument[OrderKind]), StartLoc,
17098         LParenLoc, ArgumentLoc[OrderModifier], ArgumentLoc[OrderKind], EndLoc);
17099     break;
17100   case OMPC_device:
17101     assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
17102     Res = ActOnOpenMPDeviceClause(
17103         static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr,
17104         StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
17105     break;
17106   case OMPC_grainsize:
17107     assert(Argument.size() == 1 && ArgumentLoc.size() == 1 &&
17108            "Modifier for grainsize clause and its location are expected.");
17109     Res = ActOnOpenMPGrainsizeClause(
17110         static_cast<OpenMPGrainsizeClauseModifier>(Argument.back()), Expr,
17111         StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
17112     break;
17113   case OMPC_num_tasks:
17114     assert(Argument.size() == 1 && ArgumentLoc.size() == 1 &&
17115            "Modifier for num_tasks clause and its location are expected.");
17116     Res = ActOnOpenMPNumTasksClause(
17117         static_cast<OpenMPNumTasksClauseModifier>(Argument.back()), Expr,
17118         StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
17119     break;
17120   case OMPC_final:
17121   case OMPC_num_threads:
17122   case OMPC_safelen:
17123   case OMPC_simdlen:
17124   case OMPC_sizes:
17125   case OMPC_allocator:
17126   case OMPC_collapse:
17127   case OMPC_default:
17128   case OMPC_proc_bind:
17129   case OMPC_private:
17130   case OMPC_firstprivate:
17131   case OMPC_lastprivate:
17132   case OMPC_shared:
17133   case OMPC_reduction:
17134   case OMPC_task_reduction:
17135   case OMPC_in_reduction:
17136   case OMPC_linear:
17137   case OMPC_aligned:
17138   case OMPC_copyin:
17139   case OMPC_copyprivate:
17140   case OMPC_ordered:
17141   case OMPC_nowait:
17142   case OMPC_untied:
17143   case OMPC_mergeable:
17144   case OMPC_threadprivate:
17145   case OMPC_allocate:
17146   case OMPC_flush:
17147   case OMPC_depobj:
17148   case OMPC_read:
17149   case OMPC_write:
17150   case OMPC_update:
17151   case OMPC_capture:
17152   case OMPC_compare:
17153   case OMPC_seq_cst:
17154   case OMPC_acq_rel:
17155   case OMPC_acquire:
17156   case OMPC_release:
17157   case OMPC_relaxed:
17158   case OMPC_depend:
17159   case OMPC_threads:
17160   case OMPC_simd:
17161   case OMPC_map:
17162   case OMPC_num_teams:
17163   case OMPC_thread_limit:
17164   case OMPC_priority:
17165   case OMPC_nogroup:
17166   case OMPC_hint:
17167   case OMPC_unknown:
17168   case OMPC_uniform:
17169   case OMPC_to:
17170   case OMPC_from:
17171   case OMPC_use_device_ptr:
17172   case OMPC_use_device_addr:
17173   case OMPC_is_device_ptr:
17174   case OMPC_has_device_addr:
17175   case OMPC_unified_address:
17176   case OMPC_unified_shared_memory:
17177   case OMPC_reverse_offload:
17178   case OMPC_dynamic_allocators:
17179   case OMPC_atomic_default_mem_order:
17180   case OMPC_device_type:
17181   case OMPC_match:
17182   case OMPC_nontemporal:
17183   case OMPC_at:
17184   case OMPC_severity:
17185   case OMPC_message:
17186   case OMPC_destroy:
17187   case OMPC_novariants:
17188   case OMPC_nocontext:
17189   case OMPC_detach:
17190   case OMPC_inclusive:
17191   case OMPC_exclusive:
17192   case OMPC_uses_allocators:
17193   case OMPC_affinity:
17194   case OMPC_when:
17195   case OMPC_bind:
17196   default:
17197     llvm_unreachable("Clause is not allowed.");
17198   }
17199   return Res;
17200 }
17201 
17202 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
17203                                    OpenMPScheduleClauseModifier M2,
17204                                    SourceLocation M1Loc, SourceLocation M2Loc) {
17205   if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
17206     SmallVector<unsigned, 2> Excluded;
17207     if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
17208       Excluded.push_back(M2);
17209     if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
17210       Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
17211     if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
17212       Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
17213     S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
17214         << getListOfPossibleValues(OMPC_schedule,
17215                                    /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
17216                                    /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
17217                                    Excluded)
17218         << getOpenMPClauseName(OMPC_schedule);
17219     return true;
17220   }
17221   return false;
17222 }
17223 
17224 OMPClause *Sema::ActOnOpenMPScheduleClause(
17225     OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
17226     OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
17227     SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
17228     SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
17229   if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
17230       checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
17231     return nullptr;
17232   // OpenMP, 2.7.1, Loop Construct, Restrictions
17233   // Either the monotonic modifier or the nonmonotonic modifier can be specified
17234   // but not both.
17235   if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
17236       (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
17237        M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
17238       (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
17239        M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
17240     Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
17241         << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
17242         << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
17243     return nullptr;
17244   }
17245   if (Kind == OMPC_SCHEDULE_unknown) {
17246     std::string Values;
17247     if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
17248       unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
17249       Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
17250                                        /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
17251                                        Exclude);
17252     } else {
17253       Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
17254                                        /*Last=*/OMPC_SCHEDULE_unknown);
17255     }
17256     Diag(KindLoc, diag::err_omp_unexpected_clause_value)
17257         << Values << getOpenMPClauseName(OMPC_schedule);
17258     return nullptr;
17259   }
17260   // OpenMP, 2.7.1, Loop Construct, Restrictions
17261   // The nonmonotonic modifier can only be specified with schedule(dynamic) or
17262   // schedule(guided).
17263   // OpenMP 5.0 does not have this restriction.
17264   if (LangOpts.OpenMP < 50 &&
17265       (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
17266        M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
17267       Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
17268     Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
17269          diag::err_omp_schedule_nonmonotonic_static);
17270     return nullptr;
17271   }
17272   Expr *ValExpr = ChunkSize;
17273   Stmt *HelperValStmt = nullptr;
17274   if (ChunkSize) {
17275     if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
17276         !ChunkSize->isInstantiationDependent() &&
17277         !ChunkSize->containsUnexpandedParameterPack()) {
17278       SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
17279       ExprResult Val =
17280           PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
17281       if (Val.isInvalid())
17282         return nullptr;
17283 
17284       ValExpr = Val.get();
17285 
17286       // OpenMP [2.7.1, Restrictions]
17287       //  chunk_size must be a loop invariant integer expression with a positive
17288       //  value.
17289       if (std::optional<llvm::APSInt> Result =
17290               ValExpr->getIntegerConstantExpr(Context)) {
17291         if (Result->isSigned() && !Result->isStrictlyPositive()) {
17292           Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
17293               << "schedule" << 1 << ChunkSize->getSourceRange();
17294           return nullptr;
17295         }
17296       } else if (getOpenMPCaptureRegionForClause(
17297                      DSAStack->getCurrentDirective(), OMPC_schedule,
17298                      LangOpts.OpenMP) != OMPD_unknown &&
17299                  !CurContext->isDependentContext()) {
17300         ValExpr = MakeFullExpr(ValExpr).get();
17301         llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
17302         ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
17303         HelperValStmt = buildPreInits(Context, Captures);
17304       }
17305     }
17306   }
17307 
17308   return new (Context)
17309       OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
17310                         ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
17311 }
17312 
17313 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
17314                                    SourceLocation StartLoc,
17315                                    SourceLocation EndLoc) {
17316   OMPClause *Res = nullptr;
17317   switch (Kind) {
17318   case OMPC_ordered:
17319     Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
17320     break;
17321   case OMPC_nowait:
17322     Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
17323     break;
17324   case OMPC_untied:
17325     Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
17326     break;
17327   case OMPC_mergeable:
17328     Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
17329     break;
17330   case OMPC_read:
17331     Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
17332     break;
17333   case OMPC_write:
17334     Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
17335     break;
17336   case OMPC_update:
17337     Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
17338     break;
17339   case OMPC_capture:
17340     Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
17341     break;
17342   case OMPC_compare:
17343     Res = ActOnOpenMPCompareClause(StartLoc, EndLoc);
17344     break;
17345   case OMPC_seq_cst:
17346     Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
17347     break;
17348   case OMPC_acq_rel:
17349     Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc);
17350     break;
17351   case OMPC_acquire:
17352     Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc);
17353     break;
17354   case OMPC_release:
17355     Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc);
17356     break;
17357   case OMPC_relaxed:
17358     Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc);
17359     break;
17360   case OMPC_threads:
17361     Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
17362     break;
17363   case OMPC_simd:
17364     Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
17365     break;
17366   case OMPC_nogroup:
17367     Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
17368     break;
17369   case OMPC_unified_address:
17370     Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
17371     break;
17372   case OMPC_unified_shared_memory:
17373     Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
17374     break;
17375   case OMPC_reverse_offload:
17376     Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
17377     break;
17378   case OMPC_dynamic_allocators:
17379     Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
17380     break;
17381   case OMPC_destroy:
17382     Res = ActOnOpenMPDestroyClause(/*InteropVar=*/nullptr, StartLoc,
17383                                    /*LParenLoc=*/SourceLocation(),
17384                                    /*VarLoc=*/SourceLocation(), EndLoc);
17385     break;
17386   case OMPC_full:
17387     Res = ActOnOpenMPFullClause(StartLoc, EndLoc);
17388     break;
17389   case OMPC_partial:
17390     Res = ActOnOpenMPPartialClause(nullptr, StartLoc, /*LParenLoc=*/{}, EndLoc);
17391     break;
17392   case OMPC_if:
17393   case OMPC_final:
17394   case OMPC_num_threads:
17395   case OMPC_safelen:
17396   case OMPC_simdlen:
17397   case OMPC_sizes:
17398   case OMPC_allocator:
17399   case OMPC_collapse:
17400   case OMPC_schedule:
17401   case OMPC_private:
17402   case OMPC_firstprivate:
17403   case OMPC_lastprivate:
17404   case OMPC_shared:
17405   case OMPC_reduction:
17406   case OMPC_task_reduction:
17407   case OMPC_in_reduction:
17408   case OMPC_linear:
17409   case OMPC_aligned:
17410   case OMPC_copyin:
17411   case OMPC_copyprivate:
17412   case OMPC_default:
17413   case OMPC_proc_bind:
17414   case OMPC_threadprivate:
17415   case OMPC_allocate:
17416   case OMPC_flush:
17417   case OMPC_depobj:
17418   case OMPC_depend:
17419   case OMPC_device:
17420   case OMPC_map:
17421   case OMPC_num_teams:
17422   case OMPC_thread_limit:
17423   case OMPC_priority:
17424   case OMPC_grainsize:
17425   case OMPC_num_tasks:
17426   case OMPC_hint:
17427   case OMPC_dist_schedule:
17428   case OMPC_defaultmap:
17429   case OMPC_unknown:
17430   case OMPC_uniform:
17431   case OMPC_to:
17432   case OMPC_from:
17433   case OMPC_use_device_ptr:
17434   case OMPC_use_device_addr:
17435   case OMPC_is_device_ptr:
17436   case OMPC_has_device_addr:
17437   case OMPC_atomic_default_mem_order:
17438   case OMPC_device_type:
17439   case OMPC_match:
17440   case OMPC_nontemporal:
17441   case OMPC_order:
17442   case OMPC_at:
17443   case OMPC_severity:
17444   case OMPC_message:
17445   case OMPC_novariants:
17446   case OMPC_nocontext:
17447   case OMPC_detach:
17448   case OMPC_inclusive:
17449   case OMPC_exclusive:
17450   case OMPC_uses_allocators:
17451   case OMPC_affinity:
17452   case OMPC_when:
17453   case OMPC_ompx_dyn_cgroup_mem:
17454   default:
17455     llvm_unreachable("Clause is not allowed.");
17456   }
17457   return Res;
17458 }
17459 
17460 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
17461                                          SourceLocation EndLoc) {
17462   DSAStack->setNowaitRegion();
17463   return new (Context) OMPNowaitClause(StartLoc, EndLoc);
17464 }
17465 
17466 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
17467                                          SourceLocation EndLoc) {
17468   DSAStack->setUntiedRegion();
17469   return new (Context) OMPUntiedClause(StartLoc, EndLoc);
17470 }
17471 
17472 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
17473                                             SourceLocation EndLoc) {
17474   return new (Context) OMPMergeableClause(StartLoc, EndLoc);
17475 }
17476 
17477 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
17478                                        SourceLocation EndLoc) {
17479   return new (Context) OMPReadClause(StartLoc, EndLoc);
17480 }
17481 
17482 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
17483                                         SourceLocation EndLoc) {
17484   return new (Context) OMPWriteClause(StartLoc, EndLoc);
17485 }
17486 
17487 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
17488                                          SourceLocation EndLoc) {
17489   return OMPUpdateClause::Create(Context, StartLoc, EndLoc);
17490 }
17491 
17492 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
17493                                           SourceLocation EndLoc) {
17494   return new (Context) OMPCaptureClause(StartLoc, EndLoc);
17495 }
17496 
17497 OMPClause *Sema::ActOnOpenMPCompareClause(SourceLocation StartLoc,
17498                                           SourceLocation EndLoc) {
17499   return new (Context) OMPCompareClause(StartLoc, EndLoc);
17500 }
17501 
17502 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
17503                                          SourceLocation EndLoc) {
17504   return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
17505 }
17506 
17507 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc,
17508                                          SourceLocation EndLoc) {
17509   return new (Context) OMPAcqRelClause(StartLoc, EndLoc);
17510 }
17511 
17512 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc,
17513                                           SourceLocation EndLoc) {
17514   return new (Context) OMPAcquireClause(StartLoc, EndLoc);
17515 }
17516 
17517 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc,
17518                                           SourceLocation EndLoc) {
17519   return new (Context) OMPReleaseClause(StartLoc, EndLoc);
17520 }
17521 
17522 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc,
17523                                           SourceLocation EndLoc) {
17524   return new (Context) OMPRelaxedClause(StartLoc, EndLoc);
17525 }
17526 
17527 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
17528                                           SourceLocation EndLoc) {
17529   return new (Context) OMPThreadsClause(StartLoc, EndLoc);
17530 }
17531 
17532 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
17533                                        SourceLocation EndLoc) {
17534   return new (Context) OMPSIMDClause(StartLoc, EndLoc);
17535 }
17536 
17537 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
17538                                           SourceLocation EndLoc) {
17539   return new (Context) OMPNogroupClause(StartLoc, EndLoc);
17540 }
17541 
17542 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
17543                                                  SourceLocation EndLoc) {
17544   return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
17545 }
17546 
17547 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
17548                                                       SourceLocation EndLoc) {
17549   return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
17550 }
17551 
17552 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
17553                                                  SourceLocation EndLoc) {
17554   return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
17555 }
17556 
17557 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
17558                                                     SourceLocation EndLoc) {
17559   return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
17560 }
17561 
17562 StmtResult Sema::ActOnOpenMPInteropDirective(ArrayRef<OMPClause *> Clauses,
17563                                              SourceLocation StartLoc,
17564                                              SourceLocation EndLoc) {
17565 
17566   // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17567   // At least one action-clause must appear on a directive.
17568   if (!hasClauses(Clauses, OMPC_init, OMPC_use, OMPC_destroy, OMPC_nowait)) {
17569     StringRef Expected = "'init', 'use', 'destroy', or 'nowait'";
17570     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
17571         << Expected << getOpenMPDirectiveName(OMPD_interop);
17572     return StmtError();
17573   }
17574 
17575   // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17576   // A depend clause can only appear on the directive if a targetsync
17577   // interop-type is present or the interop-var was initialized with
17578   // the targetsync interop-type.
17579 
17580   // If there is any 'init' clause diagnose if there is no 'init' clause with
17581   // interop-type of 'targetsync'. Cases involving other directives cannot be
17582   // diagnosed.
17583   const OMPDependClause *DependClause = nullptr;
17584   bool HasInitClause = false;
17585   bool IsTargetSync = false;
17586   for (const OMPClause *C : Clauses) {
17587     if (IsTargetSync)
17588       break;
17589     if (const auto *InitClause = dyn_cast<OMPInitClause>(C)) {
17590       HasInitClause = true;
17591       if (InitClause->getIsTargetSync())
17592         IsTargetSync = true;
17593     } else if (const auto *DC = dyn_cast<OMPDependClause>(C)) {
17594       DependClause = DC;
17595     }
17596   }
17597   if (DependClause && HasInitClause && !IsTargetSync) {
17598     Diag(DependClause->getBeginLoc(), diag::err_omp_interop_bad_depend_clause);
17599     return StmtError();
17600   }
17601 
17602   // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17603   // Each interop-var may be specified for at most one action-clause of each
17604   // interop construct.
17605   llvm::SmallPtrSet<const ValueDecl *, 4> InteropVars;
17606   for (OMPClause *C : Clauses) {
17607     OpenMPClauseKind ClauseKind = C->getClauseKind();
17608     std::pair<ValueDecl *, bool> DeclResult;
17609     SourceLocation ELoc;
17610     SourceRange ERange;
17611 
17612     if (ClauseKind == OMPC_init) {
17613       auto *E = cast<OMPInitClause>(C)->getInteropVar();
17614       DeclResult = getPrivateItem(*this, E, ELoc, ERange);
17615     } else if (ClauseKind == OMPC_use) {
17616       auto *E = cast<OMPUseClause>(C)->getInteropVar();
17617       DeclResult = getPrivateItem(*this, E, ELoc, ERange);
17618     } else if (ClauseKind == OMPC_destroy) {
17619       auto *E = cast<OMPDestroyClause>(C)->getInteropVar();
17620       DeclResult = getPrivateItem(*this, E, ELoc, ERange);
17621     }
17622 
17623     if (DeclResult.first) {
17624       if (!InteropVars.insert(DeclResult.first).second) {
17625         Diag(ELoc, diag::err_omp_interop_var_multiple_actions)
17626             << DeclResult.first;
17627         return StmtError();
17628       }
17629     }
17630   }
17631 
17632   return OMPInteropDirective::Create(Context, StartLoc, EndLoc, Clauses);
17633 }
17634 
17635 static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr,
17636                                    SourceLocation VarLoc,
17637                                    OpenMPClauseKind Kind) {
17638   SourceLocation ELoc;
17639   SourceRange ERange;
17640   Expr *RefExpr = InteropVarExpr;
17641   auto Res =
17642       getPrivateItem(SemaRef, RefExpr, ELoc, ERange,
17643                      /*AllowArraySection=*/false, /*DiagType=*/"omp_interop_t");
17644 
17645   if (Res.second) {
17646     // It will be analyzed later.
17647     return true;
17648   }
17649 
17650   if (!Res.first)
17651     return false;
17652 
17653   // Interop variable should be of type omp_interop_t.
17654   bool HasError = false;
17655   QualType InteropType;
17656   LookupResult Result(SemaRef, &SemaRef.Context.Idents.get("omp_interop_t"),
17657                       VarLoc, Sema::LookupOrdinaryName);
17658   if (SemaRef.LookupName(Result, SemaRef.getCurScope())) {
17659     NamedDecl *ND = Result.getFoundDecl();
17660     if (const auto *TD = dyn_cast<TypeDecl>(ND)) {
17661       InteropType = QualType(TD->getTypeForDecl(), 0);
17662     } else {
17663       HasError = true;
17664     }
17665   } else {
17666     HasError = true;
17667   }
17668 
17669   if (HasError) {
17670     SemaRef.Diag(VarLoc, diag::err_omp_implied_type_not_found)
17671         << "omp_interop_t";
17672     return false;
17673   }
17674 
17675   QualType VarType = InteropVarExpr->getType().getUnqualifiedType();
17676   if (!SemaRef.Context.hasSameType(InteropType, VarType)) {
17677     SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_wrong_type);
17678     return false;
17679   }
17680 
17681   // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17682   // The interop-var passed to init or destroy must be non-const.
17683   if ((Kind == OMPC_init || Kind == OMPC_destroy) &&
17684       isConstNotMutableType(SemaRef, InteropVarExpr->getType())) {
17685     SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected)
17686         << /*non-const*/ 1;
17687     return false;
17688   }
17689   return true;
17690 }
17691 
17692 OMPClause *
17693 Sema::ActOnOpenMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo,
17694                             SourceLocation StartLoc, SourceLocation LParenLoc,
17695                             SourceLocation VarLoc, SourceLocation EndLoc) {
17696 
17697   if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_init))
17698     return nullptr;
17699 
17700   // Check prefer_type values.  These foreign-runtime-id values are either
17701   // string literals or constant integral expressions.
17702   for (const Expr *E : InteropInfo.PreferTypes) {
17703     if (E->isValueDependent() || E->isTypeDependent() ||
17704         E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
17705       continue;
17706     if (E->isIntegerConstantExpr(Context))
17707       continue;
17708     if (isa<StringLiteral>(E))
17709       continue;
17710     Diag(E->getExprLoc(), diag::err_omp_interop_prefer_type);
17711     return nullptr;
17712   }
17713 
17714   return OMPInitClause::Create(Context, InteropVar, InteropInfo, StartLoc,
17715                                LParenLoc, VarLoc, EndLoc);
17716 }
17717 
17718 OMPClause *Sema::ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
17719                                       SourceLocation LParenLoc,
17720                                       SourceLocation VarLoc,
17721                                       SourceLocation EndLoc) {
17722 
17723   if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_use))
17724     return nullptr;
17725 
17726   return new (Context)
17727       OMPUseClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
17728 }
17729 
17730 OMPClause *Sema::ActOnOpenMPDestroyClause(Expr *InteropVar,
17731                                           SourceLocation StartLoc,
17732                                           SourceLocation LParenLoc,
17733                                           SourceLocation VarLoc,
17734                                           SourceLocation EndLoc) {
17735   if (!InteropVar && LangOpts.OpenMP >= 52 &&
17736       DSAStack->getCurrentDirective() == OMPD_depobj) {
17737     Diag(StartLoc, diag::err_omp_expected_clause_argument)
17738         << getOpenMPClauseName(OMPC_destroy)
17739         << getOpenMPDirectiveName(OMPD_depobj);
17740     return nullptr;
17741   }
17742   if (InteropVar &&
17743       !isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_destroy))
17744     return nullptr;
17745 
17746   return new (Context)
17747       OMPDestroyClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
17748 }
17749 
17750 OMPClause *Sema::ActOnOpenMPNovariantsClause(Expr *Condition,
17751                                              SourceLocation StartLoc,
17752                                              SourceLocation LParenLoc,
17753                                              SourceLocation EndLoc) {
17754   Expr *ValExpr = Condition;
17755   Stmt *HelperValStmt = nullptr;
17756   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
17757   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
17758       !Condition->isInstantiationDependent() &&
17759       !Condition->containsUnexpandedParameterPack()) {
17760     ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
17761     if (Val.isInvalid())
17762       return nullptr;
17763 
17764     ValExpr = MakeFullExpr(Val.get()).get();
17765 
17766     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
17767     CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_novariants,
17768                                                     LangOpts.OpenMP);
17769     if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
17770       ValExpr = MakeFullExpr(ValExpr).get();
17771       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
17772       ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
17773       HelperValStmt = buildPreInits(Context, Captures);
17774     }
17775   }
17776 
17777   return new (Context) OMPNovariantsClause(
17778       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
17779 }
17780 
17781 OMPClause *Sema::ActOnOpenMPNocontextClause(Expr *Condition,
17782                                             SourceLocation StartLoc,
17783                                             SourceLocation LParenLoc,
17784                                             SourceLocation EndLoc) {
17785   Expr *ValExpr = Condition;
17786   Stmt *HelperValStmt = nullptr;
17787   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
17788   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
17789       !Condition->isInstantiationDependent() &&
17790       !Condition->containsUnexpandedParameterPack()) {
17791     ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
17792     if (Val.isInvalid())
17793       return nullptr;
17794 
17795     ValExpr = MakeFullExpr(Val.get()).get();
17796 
17797     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
17798     CaptureRegion =
17799         getOpenMPCaptureRegionForClause(DKind, OMPC_nocontext, LangOpts.OpenMP);
17800     if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
17801       ValExpr = MakeFullExpr(ValExpr).get();
17802       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
17803       ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
17804       HelperValStmt = buildPreInits(Context, Captures);
17805     }
17806   }
17807 
17808   return new (Context) OMPNocontextClause(ValExpr, HelperValStmt, CaptureRegion,
17809                                           StartLoc, LParenLoc, EndLoc);
17810 }
17811 
17812 OMPClause *Sema::ActOnOpenMPFilterClause(Expr *ThreadID,
17813                                          SourceLocation StartLoc,
17814                                          SourceLocation LParenLoc,
17815                                          SourceLocation EndLoc) {
17816   Expr *ValExpr = ThreadID;
17817   Stmt *HelperValStmt = nullptr;
17818 
17819   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
17820   OpenMPDirectiveKind CaptureRegion =
17821       getOpenMPCaptureRegionForClause(DKind, OMPC_filter, LangOpts.OpenMP);
17822   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
17823     ValExpr = MakeFullExpr(ValExpr).get();
17824     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
17825     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
17826     HelperValStmt = buildPreInits(Context, Captures);
17827   }
17828 
17829   return new (Context) OMPFilterClause(ValExpr, HelperValStmt, CaptureRegion,
17830                                        StartLoc, LParenLoc, EndLoc);
17831 }
17832 
17833 OMPClause *Sema::ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
17834                                           ArrayRef<Expr *> VarList,
17835                                           const OMPVarListLocTy &Locs,
17836                                           OpenMPVarListDataTy &Data) {
17837   SourceLocation StartLoc = Locs.StartLoc;
17838   SourceLocation LParenLoc = Locs.LParenLoc;
17839   SourceLocation EndLoc = Locs.EndLoc;
17840   OMPClause *Res = nullptr;
17841   int ExtraModifier = Data.ExtraModifier;
17842   SourceLocation ExtraModifierLoc = Data.ExtraModifierLoc;
17843   SourceLocation ColonLoc = Data.ColonLoc;
17844   switch (Kind) {
17845   case OMPC_private:
17846     Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
17847     break;
17848   case OMPC_firstprivate:
17849     Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
17850     break;
17851   case OMPC_lastprivate:
17852     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown &&
17853            "Unexpected lastprivate modifier.");
17854     Res = ActOnOpenMPLastprivateClause(
17855         VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier),
17856         ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
17857     break;
17858   case OMPC_shared:
17859     Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
17860     break;
17861   case OMPC_reduction:
17862     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown &&
17863            "Unexpected lastprivate modifier.");
17864     Res = ActOnOpenMPReductionClause(
17865         VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier),
17866         StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
17867         Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId);
17868     break;
17869   case OMPC_task_reduction:
17870     Res = ActOnOpenMPTaskReductionClause(
17871         VarList, StartLoc, LParenLoc, ColonLoc, EndLoc,
17872         Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId);
17873     break;
17874   case OMPC_in_reduction:
17875     Res = ActOnOpenMPInReductionClause(
17876         VarList, StartLoc, LParenLoc, ColonLoc, EndLoc,
17877         Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId);
17878     break;
17879   case OMPC_linear:
17880     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown &&
17881            "Unexpected linear modifier.");
17882     Res = ActOnOpenMPLinearClause(
17883         VarList, Data.DepModOrTailExpr, StartLoc, LParenLoc,
17884         static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc,
17885         ColonLoc, EndLoc);
17886     break;
17887   case OMPC_aligned:
17888     Res = ActOnOpenMPAlignedClause(VarList, Data.DepModOrTailExpr, StartLoc,
17889                                    LParenLoc, ColonLoc, EndLoc);
17890     break;
17891   case OMPC_copyin:
17892     Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
17893     break;
17894   case OMPC_copyprivate:
17895     Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
17896     break;
17897   case OMPC_flush:
17898     Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
17899     break;
17900   case OMPC_depend:
17901     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown &&
17902            "Unexpected depend modifier.");
17903     Res = ActOnOpenMPDependClause(
17904         {static_cast<OpenMPDependClauseKind>(ExtraModifier), ExtraModifierLoc,
17905          ColonLoc, Data.OmpAllMemoryLoc},
17906         Data.DepModOrTailExpr, VarList, StartLoc, LParenLoc, EndLoc);
17907     break;
17908   case OMPC_map:
17909     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown &&
17910            "Unexpected map modifier.");
17911     Res = ActOnOpenMPMapClause(
17912         Data.IteratorExpr, Data.MapTypeModifiers, Data.MapTypeModifiersLoc,
17913         Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId,
17914         static_cast<OpenMPMapClauseKind>(ExtraModifier), Data.IsMapTypeImplicit,
17915         ExtraModifierLoc, ColonLoc, VarList, Locs);
17916     break;
17917   case OMPC_to:
17918     Res =
17919         ActOnOpenMPToClause(Data.MotionModifiers, Data.MotionModifiersLoc,
17920                             Data.ReductionOrMapperIdScopeSpec,
17921                             Data.ReductionOrMapperId, ColonLoc, VarList, Locs);
17922     break;
17923   case OMPC_from:
17924     Res = ActOnOpenMPFromClause(Data.MotionModifiers, Data.MotionModifiersLoc,
17925                                 Data.ReductionOrMapperIdScopeSpec,
17926                                 Data.ReductionOrMapperId, ColonLoc, VarList,
17927                                 Locs);
17928     break;
17929   case OMPC_use_device_ptr:
17930     Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
17931     break;
17932   case OMPC_use_device_addr:
17933     Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
17934     break;
17935   case OMPC_is_device_ptr:
17936     Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
17937     break;
17938   case OMPC_has_device_addr:
17939     Res = ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
17940     break;
17941   case OMPC_allocate:
17942     Res = ActOnOpenMPAllocateClause(Data.DepModOrTailExpr, VarList, StartLoc,
17943                                     LParenLoc, ColonLoc, EndLoc);
17944     break;
17945   case OMPC_nontemporal:
17946     Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc);
17947     break;
17948   case OMPC_inclusive:
17949     Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
17950     break;
17951   case OMPC_exclusive:
17952     Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
17953     break;
17954   case OMPC_affinity:
17955     Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc,
17956                                     Data.DepModOrTailExpr, VarList);
17957     break;
17958   case OMPC_doacross:
17959     Res = ActOnOpenMPDoacrossClause(
17960         static_cast<OpenMPDoacrossClauseModifier>(ExtraModifier),
17961         ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
17962     break;
17963   case OMPC_if:
17964   case OMPC_depobj:
17965   case OMPC_final:
17966   case OMPC_num_threads:
17967   case OMPC_safelen:
17968   case OMPC_simdlen:
17969   case OMPC_sizes:
17970   case OMPC_allocator:
17971   case OMPC_collapse:
17972   case OMPC_default:
17973   case OMPC_proc_bind:
17974   case OMPC_schedule:
17975   case OMPC_ordered:
17976   case OMPC_nowait:
17977   case OMPC_untied:
17978   case OMPC_mergeable:
17979   case OMPC_threadprivate:
17980   case OMPC_read:
17981   case OMPC_write:
17982   case OMPC_update:
17983   case OMPC_capture:
17984   case OMPC_compare:
17985   case OMPC_seq_cst:
17986   case OMPC_acq_rel:
17987   case OMPC_acquire:
17988   case OMPC_release:
17989   case OMPC_relaxed:
17990   case OMPC_device:
17991   case OMPC_threads:
17992   case OMPC_simd:
17993   case OMPC_num_teams:
17994   case OMPC_thread_limit:
17995   case OMPC_priority:
17996   case OMPC_grainsize:
17997   case OMPC_nogroup:
17998   case OMPC_num_tasks:
17999   case OMPC_hint:
18000   case OMPC_dist_schedule:
18001   case OMPC_defaultmap:
18002   case OMPC_unknown:
18003   case OMPC_uniform:
18004   case OMPC_unified_address:
18005   case OMPC_unified_shared_memory:
18006   case OMPC_reverse_offload:
18007   case OMPC_dynamic_allocators:
18008   case OMPC_atomic_default_mem_order:
18009   case OMPC_device_type:
18010   case OMPC_match:
18011   case OMPC_order:
18012   case OMPC_at:
18013   case OMPC_severity:
18014   case OMPC_message:
18015   case OMPC_destroy:
18016   case OMPC_novariants:
18017   case OMPC_nocontext:
18018   case OMPC_detach:
18019   case OMPC_uses_allocators:
18020   case OMPC_when:
18021   case OMPC_bind:
18022   default:
18023     llvm_unreachable("Clause is not allowed.");
18024   }
18025   return Res;
18026 }
18027 
18028 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
18029                                        ExprObjectKind OK, SourceLocation Loc) {
18030   ExprResult Res = BuildDeclRefExpr(
18031       Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
18032   if (!Res.isUsable())
18033     return ExprError();
18034   if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
18035     Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
18036     if (!Res.isUsable())
18037       return ExprError();
18038   }
18039   if (VK != VK_LValue && Res.get()->isGLValue()) {
18040     Res = DefaultLvalueConversion(Res.get());
18041     if (!Res.isUsable())
18042       return ExprError();
18043   }
18044   return Res;
18045 }
18046 
18047 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
18048                                           SourceLocation StartLoc,
18049                                           SourceLocation LParenLoc,
18050                                           SourceLocation EndLoc) {
18051   SmallVector<Expr *, 8> Vars;
18052   SmallVector<Expr *, 8> PrivateCopies;
18053   bool IsImplicitClause =
18054       StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
18055   for (Expr *RefExpr : VarList) {
18056     assert(RefExpr && "NULL expr in OpenMP private clause.");
18057     SourceLocation ELoc;
18058     SourceRange ERange;
18059     Expr *SimpleRefExpr = RefExpr;
18060     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18061     if (Res.second) {
18062       // It will be analyzed later.
18063       Vars.push_back(RefExpr);
18064       PrivateCopies.push_back(nullptr);
18065     }
18066     ValueDecl *D = Res.first;
18067     if (!D)
18068       continue;
18069 
18070     QualType Type = D->getType();
18071     auto *VD = dyn_cast<VarDecl>(D);
18072 
18073     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
18074     //  A variable that appears in a private clause must not have an incomplete
18075     //  type or a reference type.
18076     if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
18077       continue;
18078     Type = Type.getNonReferenceType();
18079 
18080     // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
18081     // A variable that is privatized must not have a const-qualified type
18082     // unless it is of class type with a mutable member. This restriction does
18083     // not apply to the firstprivate clause.
18084     //
18085     // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
18086     // A variable that appears in a private clause must not have a
18087     // const-qualified type unless it is of class type with a mutable member.
18088     if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
18089       continue;
18090 
18091     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
18092     // in a Construct]
18093     //  Variables with the predetermined data-sharing attributes may not be
18094     //  listed in data-sharing attributes clauses, except for the cases
18095     //  listed below. For these exceptions only, listing a predetermined
18096     //  variable in a data-sharing attribute clause is allowed and overrides
18097     //  the variable's predetermined data-sharing attributes.
18098     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
18099     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
18100       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
18101                                           << getOpenMPClauseName(OMPC_private);
18102       reportOriginalDsa(*this, DSAStack, D, DVar);
18103       continue;
18104     }
18105 
18106     OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
18107     // Variably modified types are not supported for tasks.
18108     if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
18109         isOpenMPTaskingDirective(CurrDir)) {
18110       Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
18111           << getOpenMPClauseName(OMPC_private) << Type
18112           << getOpenMPDirectiveName(CurrDir);
18113       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18114                                VarDecl::DeclarationOnly;
18115       Diag(D->getLocation(),
18116            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18117           << D;
18118       continue;
18119     }
18120 
18121     // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
18122     // A list item cannot appear in both a map clause and a data-sharing
18123     // attribute clause on the same construct
18124     //
18125     // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
18126     // A list item cannot appear in both a map clause and a data-sharing
18127     // attribute clause on the same construct unless the construct is a
18128     // combined construct.
18129     if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) ||
18130         CurrDir == OMPD_target) {
18131       OpenMPClauseKind ConflictKind;
18132       if (DSAStack->checkMappableExprComponentListsForDecl(
18133               VD, /*CurrentRegionOnly=*/true,
18134               [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
18135                   OpenMPClauseKind WhereFoundClauseKind) -> bool {
18136                 ConflictKind = WhereFoundClauseKind;
18137                 return true;
18138               })) {
18139         Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
18140             << getOpenMPClauseName(OMPC_private)
18141             << getOpenMPClauseName(ConflictKind)
18142             << getOpenMPDirectiveName(CurrDir);
18143         reportOriginalDsa(*this, DSAStack, D, DVar);
18144         continue;
18145       }
18146     }
18147 
18148     // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
18149     //  A variable of class type (or array thereof) that appears in a private
18150     //  clause requires an accessible, unambiguous default constructor for the
18151     //  class type.
18152     // Generate helper private variable and initialize it with the default
18153     // value. The address of the original variable is replaced by the address of
18154     // the new private variable in CodeGen. This new variable is not added to
18155     // IdResolver, so the code in the OpenMP region uses original variable for
18156     // proper diagnostics.
18157     Type = Type.getUnqualifiedType();
18158     VarDecl *VDPrivate =
18159         buildVarDecl(*this, ELoc, Type, D->getName(),
18160                      D->hasAttrs() ? &D->getAttrs() : nullptr,
18161                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
18162     ActOnUninitializedDecl(VDPrivate);
18163     if (VDPrivate->isInvalidDecl())
18164       continue;
18165     DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
18166         *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
18167 
18168     DeclRefExpr *Ref = nullptr;
18169     if (!VD && !CurContext->isDependentContext()) {
18170       auto *FD = dyn_cast<FieldDecl>(D);
18171       VarDecl *VD = FD ? DSAStack->getImplicitFDCapExprDecl(FD) : nullptr;
18172       if (VD)
18173         Ref = buildDeclRefExpr(*this, VD, VD->getType().getNonReferenceType(),
18174                                RefExpr->getExprLoc());
18175       else
18176         Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
18177     }
18178     if (!IsImplicitClause)
18179       DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
18180     Vars.push_back((VD || CurContext->isDependentContext())
18181                        ? RefExpr->IgnoreParens()
18182                        : Ref);
18183     PrivateCopies.push_back(VDPrivateRefExpr);
18184   }
18185 
18186   if (Vars.empty())
18187     return nullptr;
18188 
18189   return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
18190                                   PrivateCopies);
18191 }
18192 
18193 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
18194                                                SourceLocation StartLoc,
18195                                                SourceLocation LParenLoc,
18196                                                SourceLocation EndLoc) {
18197   SmallVector<Expr *, 8> Vars;
18198   SmallVector<Expr *, 8> PrivateCopies;
18199   SmallVector<Expr *, 8> Inits;
18200   SmallVector<Decl *, 4> ExprCaptures;
18201   bool IsImplicitClause =
18202       StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
18203   SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc();
18204 
18205   for (Expr *RefExpr : VarList) {
18206     assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
18207     SourceLocation ELoc;
18208     SourceRange ERange;
18209     Expr *SimpleRefExpr = RefExpr;
18210     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18211     if (Res.second) {
18212       // It will be analyzed later.
18213       Vars.push_back(RefExpr);
18214       PrivateCopies.push_back(nullptr);
18215       Inits.push_back(nullptr);
18216     }
18217     ValueDecl *D = Res.first;
18218     if (!D)
18219       continue;
18220 
18221     ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
18222     QualType Type = D->getType();
18223     auto *VD = dyn_cast<VarDecl>(D);
18224 
18225     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
18226     //  A variable that appears in a private clause must not have an incomplete
18227     //  type or a reference type.
18228     if (RequireCompleteType(ELoc, Type,
18229                             diag::err_omp_firstprivate_incomplete_type))
18230       continue;
18231     Type = Type.getNonReferenceType();
18232 
18233     // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
18234     //  A variable of class type (or array thereof) that appears in a private
18235     //  clause requires an accessible, unambiguous copy constructor for the
18236     //  class type.
18237     QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
18238 
18239     // If an implicit firstprivate variable found it was checked already.
18240     DSAStackTy::DSAVarData TopDVar;
18241     if (!IsImplicitClause) {
18242       DSAStackTy::DSAVarData DVar =
18243           DSAStack->getTopDSA(D, /*FromParent=*/false);
18244       TopDVar = DVar;
18245       OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
18246       bool IsConstant = ElemType.isConstant(Context);
18247       // OpenMP [2.4.13, Data-sharing Attribute Clauses]
18248       //  A list item that specifies a given variable may not appear in more
18249       // than one clause on the same directive, except that a variable may be
18250       //  specified in both firstprivate and lastprivate clauses.
18251       // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
18252       // A list item may appear in a firstprivate or lastprivate clause but not
18253       // both.
18254       if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
18255           (isOpenMPDistributeDirective(CurrDir) ||
18256            DVar.CKind != OMPC_lastprivate) &&
18257           DVar.RefExpr) {
18258         Diag(ELoc, diag::err_omp_wrong_dsa)
18259             << getOpenMPClauseName(DVar.CKind)
18260             << getOpenMPClauseName(OMPC_firstprivate);
18261         reportOriginalDsa(*this, DSAStack, D, DVar);
18262         continue;
18263       }
18264 
18265       // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
18266       // in a Construct]
18267       //  Variables with the predetermined data-sharing attributes may not be
18268       //  listed in data-sharing attributes clauses, except for the cases
18269       //  listed below. For these exceptions only, listing a predetermined
18270       //  variable in a data-sharing attribute clause is allowed and overrides
18271       //  the variable's predetermined data-sharing attributes.
18272       // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
18273       // in a Construct, C/C++, p.2]
18274       //  Variables with const-qualified type having no mutable member may be
18275       //  listed in a firstprivate clause, even if they are static data members.
18276       if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
18277           DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
18278         Diag(ELoc, diag::err_omp_wrong_dsa)
18279             << getOpenMPClauseName(DVar.CKind)
18280             << getOpenMPClauseName(OMPC_firstprivate);
18281         reportOriginalDsa(*this, DSAStack, D, DVar);
18282         continue;
18283       }
18284 
18285       // OpenMP [2.9.3.4, Restrictions, p.2]
18286       //  A list item that is private within a parallel region must not appear
18287       //  in a firstprivate clause on a worksharing construct if any of the
18288       //  worksharing regions arising from the worksharing construct ever bind
18289       //  to any of the parallel regions arising from the parallel construct.
18290       // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
18291       // A list item that is private within a teams region must not appear in a
18292       // firstprivate clause on a distribute construct if any of the distribute
18293       // regions arising from the distribute construct ever bind to any of the
18294       // teams regions arising from the teams construct.
18295       // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
18296       // A list item that appears in a reduction clause of a teams construct
18297       // must not appear in a firstprivate clause on a distribute construct if
18298       // any of the distribute regions arising from the distribute construct
18299       // ever bind to any of the teams regions arising from the teams construct.
18300       if ((isOpenMPWorksharingDirective(CurrDir) ||
18301            isOpenMPDistributeDirective(CurrDir)) &&
18302           !isOpenMPParallelDirective(CurrDir) &&
18303           !isOpenMPTeamsDirective(CurrDir)) {
18304         DVar = DSAStack->getImplicitDSA(D, true);
18305         if (DVar.CKind != OMPC_shared &&
18306             (isOpenMPParallelDirective(DVar.DKind) ||
18307              isOpenMPTeamsDirective(DVar.DKind) ||
18308              DVar.DKind == OMPD_unknown)) {
18309           Diag(ELoc, diag::err_omp_required_access)
18310               << getOpenMPClauseName(OMPC_firstprivate)
18311               << getOpenMPClauseName(OMPC_shared);
18312           reportOriginalDsa(*this, DSAStack, D, DVar);
18313           continue;
18314         }
18315       }
18316       // OpenMP [2.9.3.4, Restrictions, p.3]
18317       //  A list item that appears in a reduction clause of a parallel construct
18318       //  must not appear in a firstprivate clause on a worksharing or task
18319       //  construct if any of the worksharing or task regions arising from the
18320       //  worksharing or task construct ever bind to any of the parallel regions
18321       //  arising from the parallel construct.
18322       // OpenMP [2.9.3.4, Restrictions, p.4]
18323       //  A list item that appears in a reduction clause in worksharing
18324       //  construct must not appear in a firstprivate clause in a task construct
18325       //  encountered during execution of any of the worksharing regions arising
18326       //  from the worksharing construct.
18327       if (isOpenMPTaskingDirective(CurrDir)) {
18328         DVar = DSAStack->hasInnermostDSA(
18329             D,
18330             [](OpenMPClauseKind C, bool AppliedToPointee) {
18331               return C == OMPC_reduction && !AppliedToPointee;
18332             },
18333             [](OpenMPDirectiveKind K) {
18334               return isOpenMPParallelDirective(K) ||
18335                      isOpenMPWorksharingDirective(K) ||
18336                      isOpenMPTeamsDirective(K);
18337             },
18338             /*FromParent=*/true);
18339         if (DVar.CKind == OMPC_reduction &&
18340             (isOpenMPParallelDirective(DVar.DKind) ||
18341              isOpenMPWorksharingDirective(DVar.DKind) ||
18342              isOpenMPTeamsDirective(DVar.DKind))) {
18343           Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
18344               << getOpenMPDirectiveName(DVar.DKind);
18345           reportOriginalDsa(*this, DSAStack, D, DVar);
18346           continue;
18347         }
18348       }
18349 
18350       // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
18351       // A list item cannot appear in both a map clause and a data-sharing
18352       // attribute clause on the same construct
18353       //
18354       // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
18355       // A list item cannot appear in both a map clause and a data-sharing
18356       // attribute clause on the same construct unless the construct is a
18357       // combined construct.
18358       if ((LangOpts.OpenMP <= 45 &&
18359            isOpenMPTargetExecutionDirective(CurrDir)) ||
18360           CurrDir == OMPD_target) {
18361         OpenMPClauseKind ConflictKind;
18362         if (DSAStack->checkMappableExprComponentListsForDecl(
18363                 VD, /*CurrentRegionOnly=*/true,
18364                 [&ConflictKind](
18365                     OMPClauseMappableExprCommon::MappableExprComponentListRef,
18366                     OpenMPClauseKind WhereFoundClauseKind) {
18367                   ConflictKind = WhereFoundClauseKind;
18368                   return true;
18369                 })) {
18370           Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
18371               << getOpenMPClauseName(OMPC_firstprivate)
18372               << getOpenMPClauseName(ConflictKind)
18373               << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
18374           reportOriginalDsa(*this, DSAStack, D, DVar);
18375           continue;
18376         }
18377       }
18378     }
18379 
18380     // Variably modified types are not supported for tasks.
18381     if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
18382         isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
18383       Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
18384           << getOpenMPClauseName(OMPC_firstprivate) << Type
18385           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
18386       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18387                                VarDecl::DeclarationOnly;
18388       Diag(D->getLocation(),
18389            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18390           << D;
18391       continue;
18392     }
18393 
18394     Type = Type.getUnqualifiedType();
18395     VarDecl *VDPrivate =
18396         buildVarDecl(*this, ELoc, Type, D->getName(),
18397                      D->hasAttrs() ? &D->getAttrs() : nullptr,
18398                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
18399     // Generate helper private variable and initialize it with the value of the
18400     // original variable. The address of the original variable is replaced by
18401     // the address of the new private variable in the CodeGen. This new variable
18402     // is not added to IdResolver, so the code in the OpenMP region uses
18403     // original variable for proper diagnostics and variable capturing.
18404     Expr *VDInitRefExpr = nullptr;
18405     // For arrays generate initializer for single element and replace it by the
18406     // original array element in CodeGen.
18407     if (Type->isArrayType()) {
18408       VarDecl *VDInit =
18409           buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
18410       VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
18411       Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
18412       ElemType = ElemType.getUnqualifiedType();
18413       VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
18414                                          ".firstprivate.temp");
18415       InitializedEntity Entity =
18416           InitializedEntity::InitializeVariable(VDInitTemp);
18417       InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
18418 
18419       InitializationSequence InitSeq(*this, Entity, Kind, Init);
18420       ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
18421       if (Result.isInvalid())
18422         VDPrivate->setInvalidDecl();
18423       else
18424         VDPrivate->setInit(Result.getAs<Expr>());
18425       // Remove temp variable declaration.
18426       Context.Deallocate(VDInitTemp);
18427     } else {
18428       VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
18429                                      ".firstprivate.temp");
18430       VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
18431                                        RefExpr->getExprLoc());
18432       AddInitializerToDecl(VDPrivate,
18433                            DefaultLvalueConversion(VDInitRefExpr).get(),
18434                            /*DirectInit=*/false);
18435     }
18436     if (VDPrivate->isInvalidDecl()) {
18437       if (IsImplicitClause) {
18438         Diag(RefExpr->getExprLoc(),
18439              diag::note_omp_task_predetermined_firstprivate_here);
18440       }
18441       continue;
18442     }
18443     CurContext->addDecl(VDPrivate);
18444     DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
18445         *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
18446         RefExpr->getExprLoc());
18447     DeclRefExpr *Ref = nullptr;
18448     if (!VD && !CurContext->isDependentContext()) {
18449       if (TopDVar.CKind == OMPC_lastprivate) {
18450         Ref = TopDVar.PrivateCopy;
18451       } else {
18452         auto *FD = dyn_cast<FieldDecl>(D);
18453         VarDecl *VD = FD ? DSAStack->getImplicitFDCapExprDecl(FD) : nullptr;
18454         if (VD)
18455           Ref = buildDeclRefExpr(*this, VD, VD->getType().getNonReferenceType(),
18456                                  RefExpr->getExprLoc());
18457         else
18458           Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
18459         if (VD || !isOpenMPCapturedDecl(D))
18460           ExprCaptures.push_back(Ref->getDecl());
18461       }
18462     }
18463     if (!IsImplicitClause)
18464       DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
18465     Vars.push_back((VD || CurContext->isDependentContext())
18466                        ? RefExpr->IgnoreParens()
18467                        : Ref);
18468     PrivateCopies.push_back(VDPrivateRefExpr);
18469     Inits.push_back(VDInitRefExpr);
18470   }
18471 
18472   if (Vars.empty())
18473     return nullptr;
18474 
18475   return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
18476                                        Vars, PrivateCopies, Inits,
18477                                        buildPreInits(Context, ExprCaptures));
18478 }
18479 
18480 OMPClause *Sema::ActOnOpenMPLastprivateClause(
18481     ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind,
18482     SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc,
18483     SourceLocation LParenLoc, SourceLocation EndLoc) {
18484   if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) {
18485     assert(ColonLoc.isValid() && "Colon location must be valid.");
18486     Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
18487         << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0,
18488                                    /*Last=*/OMPC_LASTPRIVATE_unknown)
18489         << getOpenMPClauseName(OMPC_lastprivate);
18490     return nullptr;
18491   }
18492 
18493   SmallVector<Expr *, 8> Vars;
18494   SmallVector<Expr *, 8> SrcExprs;
18495   SmallVector<Expr *, 8> DstExprs;
18496   SmallVector<Expr *, 8> AssignmentOps;
18497   SmallVector<Decl *, 4> ExprCaptures;
18498   SmallVector<Expr *, 4> ExprPostUpdates;
18499   for (Expr *RefExpr : VarList) {
18500     assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
18501     SourceLocation ELoc;
18502     SourceRange ERange;
18503     Expr *SimpleRefExpr = RefExpr;
18504     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18505     if (Res.second) {
18506       // It will be analyzed later.
18507       Vars.push_back(RefExpr);
18508       SrcExprs.push_back(nullptr);
18509       DstExprs.push_back(nullptr);
18510       AssignmentOps.push_back(nullptr);
18511     }
18512     ValueDecl *D = Res.first;
18513     if (!D)
18514       continue;
18515 
18516     QualType Type = D->getType();
18517     auto *VD = dyn_cast<VarDecl>(D);
18518 
18519     // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
18520     //  A variable that appears in a lastprivate clause must not have an
18521     //  incomplete type or a reference type.
18522     if (RequireCompleteType(ELoc, Type,
18523                             diag::err_omp_lastprivate_incomplete_type))
18524       continue;
18525     Type = Type.getNonReferenceType();
18526 
18527     // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
18528     // A variable that is privatized must not have a const-qualified type
18529     // unless it is of class type with a mutable member. This restriction does
18530     // not apply to the firstprivate clause.
18531     //
18532     // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
18533     // A variable that appears in a lastprivate clause must not have a
18534     // const-qualified type unless it is of class type with a mutable member.
18535     if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
18536       continue;
18537 
18538     // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions]
18539     // A list item that appears in a lastprivate clause with the conditional
18540     // modifier must be a scalar variable.
18541     if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) {
18542       Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
18543       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18544                                VarDecl::DeclarationOnly;
18545       Diag(D->getLocation(),
18546            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18547           << D;
18548       continue;
18549     }
18550 
18551     OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
18552     // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
18553     // in a Construct]
18554     //  Variables with the predetermined data-sharing attributes may not be
18555     //  listed in data-sharing attributes clauses, except for the cases
18556     //  listed below.
18557     // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
18558     // A list item may appear in a firstprivate or lastprivate clause but not
18559     // both.
18560     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
18561     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
18562         (isOpenMPDistributeDirective(CurrDir) ||
18563          DVar.CKind != OMPC_firstprivate) &&
18564         (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
18565       Diag(ELoc, diag::err_omp_wrong_dsa)
18566           << getOpenMPClauseName(DVar.CKind)
18567           << getOpenMPClauseName(OMPC_lastprivate);
18568       reportOriginalDsa(*this, DSAStack, D, DVar);
18569       continue;
18570     }
18571 
18572     // OpenMP [2.14.3.5, Restrictions, p.2]
18573     // A list item that is private within a parallel region, or that appears in
18574     // the reduction clause of a parallel construct, must not appear in a
18575     // lastprivate clause on a worksharing construct if any of the corresponding
18576     // worksharing regions ever binds to any of the corresponding parallel
18577     // regions.
18578     DSAStackTy::DSAVarData TopDVar = DVar;
18579     if (isOpenMPWorksharingDirective(CurrDir) &&
18580         !isOpenMPParallelDirective(CurrDir) &&
18581         !isOpenMPTeamsDirective(CurrDir)) {
18582       DVar = DSAStack->getImplicitDSA(D, true);
18583       if (DVar.CKind != OMPC_shared) {
18584         Diag(ELoc, diag::err_omp_required_access)
18585             << getOpenMPClauseName(OMPC_lastprivate)
18586             << getOpenMPClauseName(OMPC_shared);
18587         reportOriginalDsa(*this, DSAStack, D, DVar);
18588         continue;
18589       }
18590     }
18591 
18592     // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
18593     //  A variable of class type (or array thereof) that appears in a
18594     //  lastprivate clause requires an accessible, unambiguous default
18595     //  constructor for the class type, unless the list item is also specified
18596     //  in a firstprivate clause.
18597     //  A variable of class type (or array thereof) that appears in a
18598     //  lastprivate clause requires an accessible, unambiguous copy assignment
18599     //  operator for the class type.
18600     Type = Context.getBaseElementType(Type).getNonReferenceType();
18601     VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
18602                                   Type.getUnqualifiedType(), ".lastprivate.src",
18603                                   D->hasAttrs() ? &D->getAttrs() : nullptr);
18604     DeclRefExpr *PseudoSrcExpr =
18605         buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
18606     VarDecl *DstVD =
18607         buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
18608                      D->hasAttrs() ? &D->getAttrs() : nullptr);
18609     DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
18610     // For arrays generate assignment operation for single element and replace
18611     // it by the original array element in CodeGen.
18612     ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
18613                                          PseudoDstExpr, PseudoSrcExpr);
18614     if (AssignmentOp.isInvalid())
18615       continue;
18616     AssignmentOp =
18617         ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
18618     if (AssignmentOp.isInvalid())
18619       continue;
18620 
18621     DeclRefExpr *Ref = nullptr;
18622     if (!VD && !CurContext->isDependentContext()) {
18623       if (TopDVar.CKind == OMPC_firstprivate) {
18624         Ref = TopDVar.PrivateCopy;
18625       } else {
18626         Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
18627         if (!isOpenMPCapturedDecl(D))
18628           ExprCaptures.push_back(Ref->getDecl());
18629       }
18630       if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) ||
18631           (!isOpenMPCapturedDecl(D) &&
18632            Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
18633         ExprResult RefRes = DefaultLvalueConversion(Ref);
18634         if (!RefRes.isUsable())
18635           continue;
18636         ExprResult PostUpdateRes =
18637             BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
18638                        RefRes.get());
18639         if (!PostUpdateRes.isUsable())
18640           continue;
18641         ExprPostUpdates.push_back(
18642             IgnoredValueConversions(PostUpdateRes.get()).get());
18643       }
18644     }
18645     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
18646     Vars.push_back((VD || CurContext->isDependentContext())
18647                        ? RefExpr->IgnoreParens()
18648                        : Ref);
18649     SrcExprs.push_back(PseudoSrcExpr);
18650     DstExprs.push_back(PseudoDstExpr);
18651     AssignmentOps.push_back(AssignmentOp.get());
18652   }
18653 
18654   if (Vars.empty())
18655     return nullptr;
18656 
18657   return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
18658                                       Vars, SrcExprs, DstExprs, AssignmentOps,
18659                                       LPKind, LPKindLoc, ColonLoc,
18660                                       buildPreInits(Context, ExprCaptures),
18661                                       buildPostUpdate(*this, ExprPostUpdates));
18662 }
18663 
18664 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
18665                                          SourceLocation StartLoc,
18666                                          SourceLocation LParenLoc,
18667                                          SourceLocation EndLoc) {
18668   SmallVector<Expr *, 8> Vars;
18669   for (Expr *RefExpr : VarList) {
18670     assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
18671     SourceLocation ELoc;
18672     SourceRange ERange;
18673     Expr *SimpleRefExpr = RefExpr;
18674     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18675     if (Res.second) {
18676       // It will be analyzed later.
18677       Vars.push_back(RefExpr);
18678     }
18679     ValueDecl *D = Res.first;
18680     if (!D)
18681       continue;
18682 
18683     auto *VD = dyn_cast<VarDecl>(D);
18684     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
18685     // in a Construct]
18686     //  Variables with the predetermined data-sharing attributes may not be
18687     //  listed in data-sharing attributes clauses, except for the cases
18688     //  listed below. For these exceptions only, listing a predetermined
18689     //  variable in a data-sharing attribute clause is allowed and overrides
18690     //  the variable's predetermined data-sharing attributes.
18691     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
18692     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
18693         DVar.RefExpr) {
18694       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
18695                                           << getOpenMPClauseName(OMPC_shared);
18696       reportOriginalDsa(*this, DSAStack, D, DVar);
18697       continue;
18698     }
18699 
18700     DeclRefExpr *Ref = nullptr;
18701     if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
18702       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
18703     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
18704     Vars.push_back((VD || !Ref || CurContext->isDependentContext())
18705                        ? RefExpr->IgnoreParens()
18706                        : Ref);
18707   }
18708 
18709   if (Vars.empty())
18710     return nullptr;
18711 
18712   return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
18713 }
18714 
18715 namespace {
18716 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
18717   DSAStackTy *Stack;
18718 
18719 public:
18720   bool VisitDeclRefExpr(DeclRefExpr *E) {
18721     if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
18722       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
18723       if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
18724         return false;
18725       if (DVar.CKind != OMPC_unknown)
18726         return true;
18727       DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
18728           VD,
18729           [](OpenMPClauseKind C, bool AppliedToPointee, bool) {
18730             return isOpenMPPrivate(C) && !AppliedToPointee;
18731           },
18732           [](OpenMPDirectiveKind) { return true; },
18733           /*FromParent=*/true);
18734       return DVarPrivate.CKind != OMPC_unknown;
18735     }
18736     return false;
18737   }
18738   bool VisitStmt(Stmt *S) {
18739     for (Stmt *Child : S->children()) {
18740       if (Child && Visit(Child))
18741         return true;
18742     }
18743     return false;
18744   }
18745   explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
18746 };
18747 } // namespace
18748 
18749 namespace {
18750 // Transform MemberExpression for specified FieldDecl of current class to
18751 // DeclRefExpr to specified OMPCapturedExprDecl.
18752 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
18753   typedef TreeTransform<TransformExprToCaptures> BaseTransform;
18754   ValueDecl *Field = nullptr;
18755   DeclRefExpr *CapturedExpr = nullptr;
18756 
18757 public:
18758   TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
18759       : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
18760 
18761   ExprResult TransformMemberExpr(MemberExpr *E) {
18762     if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
18763         E->getMemberDecl() == Field) {
18764       CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
18765       return CapturedExpr;
18766     }
18767     return BaseTransform::TransformMemberExpr(E);
18768   }
18769   DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
18770 };
18771 } // namespace
18772 
18773 template <typename T, typename U>
18774 static T filterLookupForUDReductionAndMapper(
18775     SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
18776   for (U &Set : Lookups) {
18777     for (auto *D : Set) {
18778       if (T Res = Gen(cast<ValueDecl>(D)))
18779         return Res;
18780     }
18781   }
18782   return T();
18783 }
18784 
18785 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
18786   assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case");
18787 
18788   for (auto *RD : D->redecls()) {
18789     // Don't bother with extra checks if we already know this one isn't visible.
18790     if (RD == D)
18791       continue;
18792 
18793     auto ND = cast<NamedDecl>(RD);
18794     if (LookupResult::isVisible(SemaRef, ND))
18795       return ND;
18796   }
18797 
18798   return nullptr;
18799 }
18800 
18801 static void
18802 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id,
18803                         SourceLocation Loc, QualType Ty,
18804                         SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
18805   // Find all of the associated namespaces and classes based on the
18806   // arguments we have.
18807   Sema::AssociatedNamespaceSet AssociatedNamespaces;
18808   Sema::AssociatedClassSet AssociatedClasses;
18809   OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
18810   SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
18811                                              AssociatedClasses);
18812 
18813   // C++ [basic.lookup.argdep]p3:
18814   //   Let X be the lookup set produced by unqualified lookup (3.4.1)
18815   //   and let Y be the lookup set produced by argument dependent
18816   //   lookup (defined as follows). If X contains [...] then Y is
18817   //   empty. Otherwise Y is the set of declarations found in the
18818   //   namespaces associated with the argument types as described
18819   //   below. The set of declarations found by the lookup of the name
18820   //   is the union of X and Y.
18821   //
18822   // Here, we compute Y and add its members to the overloaded
18823   // candidate set.
18824   for (auto *NS : AssociatedNamespaces) {
18825     //   When considering an associated namespace, the lookup is the
18826     //   same as the lookup performed when the associated namespace is
18827     //   used as a qualifier (3.4.3.2) except that:
18828     //
18829     //     -- Any using-directives in the associated namespace are
18830     //        ignored.
18831     //
18832     //     -- Any namespace-scope friend functions declared in
18833     //        associated classes are visible within their respective
18834     //        namespaces even if they are not visible during an ordinary
18835     //        lookup (11.4).
18836     DeclContext::lookup_result R = NS->lookup(Id.getName());
18837     for (auto *D : R) {
18838       auto *Underlying = D;
18839       if (auto *USD = dyn_cast<UsingShadowDecl>(D))
18840         Underlying = USD->getTargetDecl();
18841 
18842       if (!isa<OMPDeclareReductionDecl>(Underlying) &&
18843           !isa<OMPDeclareMapperDecl>(Underlying))
18844         continue;
18845 
18846       if (!SemaRef.isVisible(D)) {
18847         D = findAcceptableDecl(SemaRef, D);
18848         if (!D)
18849           continue;
18850         if (auto *USD = dyn_cast<UsingShadowDecl>(D))
18851           Underlying = USD->getTargetDecl();
18852       }
18853       Lookups.emplace_back();
18854       Lookups.back().addDecl(Underlying);
18855     }
18856   }
18857 }
18858 
18859 static ExprResult
18860 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
18861                          Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
18862                          const DeclarationNameInfo &ReductionId, QualType Ty,
18863                          CXXCastPath &BasePath, Expr *UnresolvedReduction) {
18864   if (ReductionIdScopeSpec.isInvalid())
18865     return ExprError();
18866   SmallVector<UnresolvedSet<8>, 4> Lookups;
18867   if (S) {
18868     LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
18869     Lookup.suppressDiagnostics();
18870     while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
18871       NamedDecl *D = Lookup.getRepresentativeDecl();
18872       do {
18873         S = S->getParent();
18874       } while (S && !S->isDeclScope(D));
18875       if (S)
18876         S = S->getParent();
18877       Lookups.emplace_back();
18878       Lookups.back().append(Lookup.begin(), Lookup.end());
18879       Lookup.clear();
18880     }
18881   } else if (auto *ULE =
18882                  cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
18883     Lookups.push_back(UnresolvedSet<8>());
18884     Decl *PrevD = nullptr;
18885     for (NamedDecl *D : ULE->decls()) {
18886       if (D == PrevD)
18887         Lookups.push_back(UnresolvedSet<8>());
18888       else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
18889         Lookups.back().addDecl(DRD);
18890       PrevD = D;
18891     }
18892   }
18893   if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
18894       Ty->isInstantiationDependentType() ||
18895       Ty->containsUnexpandedParameterPack() ||
18896       filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
18897         return !D->isInvalidDecl() &&
18898                (D->getType()->isDependentType() ||
18899                 D->getType()->isInstantiationDependentType() ||
18900                 D->getType()->containsUnexpandedParameterPack());
18901       })) {
18902     UnresolvedSet<8> ResSet;
18903     for (const UnresolvedSet<8> &Set : Lookups) {
18904       if (Set.empty())
18905         continue;
18906       ResSet.append(Set.begin(), Set.end());
18907       // The last item marks the end of all declarations at the specified scope.
18908       ResSet.addDecl(Set[Set.size() - 1]);
18909     }
18910     return UnresolvedLookupExpr::Create(
18911         SemaRef.Context, /*NamingClass=*/nullptr,
18912         ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
18913         /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
18914   }
18915   // Lookup inside the classes.
18916   // C++ [over.match.oper]p3:
18917   //   For a unary operator @ with an operand of a type whose
18918   //   cv-unqualified version is T1, and for a binary operator @ with
18919   //   a left operand of a type whose cv-unqualified version is T1 and
18920   //   a right operand of a type whose cv-unqualified version is T2,
18921   //   three sets of candidate functions, designated member
18922   //   candidates, non-member candidates and built-in candidates, are
18923   //   constructed as follows:
18924   //     -- If T1 is a complete class type or a class currently being
18925   //        defined, the set of member candidates is the result of the
18926   //        qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
18927   //        the set of member candidates is empty.
18928   LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
18929   Lookup.suppressDiagnostics();
18930   if (const auto *TyRec = Ty->getAs<RecordType>()) {
18931     // Complete the type if it can be completed.
18932     // If the type is neither complete nor being defined, bail out now.
18933     if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
18934         TyRec->getDecl()->getDefinition()) {
18935       Lookup.clear();
18936       SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
18937       if (Lookup.empty()) {
18938         Lookups.emplace_back();
18939         Lookups.back().append(Lookup.begin(), Lookup.end());
18940       }
18941     }
18942   }
18943   // Perform ADL.
18944   if (SemaRef.getLangOpts().CPlusPlus)
18945     argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
18946   if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
18947           Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
18948             if (!D->isInvalidDecl() &&
18949                 SemaRef.Context.hasSameType(D->getType(), Ty))
18950               return D;
18951             return nullptr;
18952           }))
18953     return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
18954                                     VK_LValue, Loc);
18955   if (SemaRef.getLangOpts().CPlusPlus) {
18956     if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
18957             Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
18958               if (!D->isInvalidDecl() &&
18959                   SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
18960                   !Ty.isMoreQualifiedThan(D->getType()))
18961                 return D;
18962               return nullptr;
18963             })) {
18964       CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
18965                          /*DetectVirtual=*/false);
18966       if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
18967         if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
18968                 VD->getType().getUnqualifiedType()))) {
18969           if (SemaRef.CheckBaseClassAccess(
18970                   Loc, VD->getType(), Ty, Paths.front(),
18971                   /*DiagID=*/0) != Sema::AR_inaccessible) {
18972             SemaRef.BuildBasePathArray(Paths, BasePath);
18973             return SemaRef.BuildDeclRefExpr(
18974                 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
18975           }
18976         }
18977       }
18978     }
18979   }
18980   if (ReductionIdScopeSpec.isSet()) {
18981     SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
18982         << Ty << Range;
18983     return ExprError();
18984   }
18985   return ExprEmpty();
18986 }
18987 
18988 namespace {
18989 /// Data for the reduction-based clauses.
18990 struct ReductionData {
18991   /// List of original reduction items.
18992   SmallVector<Expr *, 8> Vars;
18993   /// List of private copies of the reduction items.
18994   SmallVector<Expr *, 8> Privates;
18995   /// LHS expressions for the reduction_op expressions.
18996   SmallVector<Expr *, 8> LHSs;
18997   /// RHS expressions for the reduction_op expressions.
18998   SmallVector<Expr *, 8> RHSs;
18999   /// Reduction operation expression.
19000   SmallVector<Expr *, 8> ReductionOps;
19001   /// inscan copy operation expressions.
19002   SmallVector<Expr *, 8> InscanCopyOps;
19003   /// inscan copy temp array expressions for prefix sums.
19004   SmallVector<Expr *, 8> InscanCopyArrayTemps;
19005   /// inscan copy temp array element expressions for prefix sums.
19006   SmallVector<Expr *, 8> InscanCopyArrayElems;
19007   /// Taskgroup descriptors for the corresponding reduction items in
19008   /// in_reduction clauses.
19009   SmallVector<Expr *, 8> TaskgroupDescriptors;
19010   /// List of captures for clause.
19011   SmallVector<Decl *, 4> ExprCaptures;
19012   /// List of postupdate expressions.
19013   SmallVector<Expr *, 4> ExprPostUpdates;
19014   /// Reduction modifier.
19015   unsigned RedModifier = 0;
19016   ReductionData() = delete;
19017   /// Reserves required memory for the reduction data.
19018   ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) {
19019     Vars.reserve(Size);
19020     Privates.reserve(Size);
19021     LHSs.reserve(Size);
19022     RHSs.reserve(Size);
19023     ReductionOps.reserve(Size);
19024     if (RedModifier == OMPC_REDUCTION_inscan) {
19025       InscanCopyOps.reserve(Size);
19026       InscanCopyArrayTemps.reserve(Size);
19027       InscanCopyArrayElems.reserve(Size);
19028     }
19029     TaskgroupDescriptors.reserve(Size);
19030     ExprCaptures.reserve(Size);
19031     ExprPostUpdates.reserve(Size);
19032   }
19033   /// Stores reduction item and reduction operation only (required for dependent
19034   /// reduction item).
19035   void push(Expr *Item, Expr *ReductionOp) {
19036     Vars.emplace_back(Item);
19037     Privates.emplace_back(nullptr);
19038     LHSs.emplace_back(nullptr);
19039     RHSs.emplace_back(nullptr);
19040     ReductionOps.emplace_back(ReductionOp);
19041     TaskgroupDescriptors.emplace_back(nullptr);
19042     if (RedModifier == OMPC_REDUCTION_inscan) {
19043       InscanCopyOps.push_back(nullptr);
19044       InscanCopyArrayTemps.push_back(nullptr);
19045       InscanCopyArrayElems.push_back(nullptr);
19046     }
19047   }
19048   /// Stores reduction data.
19049   void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
19050             Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp,
19051             Expr *CopyArrayElem) {
19052     Vars.emplace_back(Item);
19053     Privates.emplace_back(Private);
19054     LHSs.emplace_back(LHS);
19055     RHSs.emplace_back(RHS);
19056     ReductionOps.emplace_back(ReductionOp);
19057     TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
19058     if (RedModifier == OMPC_REDUCTION_inscan) {
19059       InscanCopyOps.push_back(CopyOp);
19060       InscanCopyArrayTemps.push_back(CopyArrayTemp);
19061       InscanCopyArrayElems.push_back(CopyArrayElem);
19062     } else {
19063       assert(CopyOp == nullptr && CopyArrayTemp == nullptr &&
19064              CopyArrayElem == nullptr &&
19065              "Copy operation must be used for inscan reductions only.");
19066     }
19067   }
19068 };
19069 } // namespace
19070 
19071 static bool checkOMPArraySectionConstantForReduction(
19072     ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
19073     SmallVectorImpl<llvm::APSInt> &ArraySizes) {
19074   const Expr *Length = OASE->getLength();
19075   if (Length == nullptr) {
19076     // For array sections of the form [1:] or [:], we would need to analyze
19077     // the lower bound...
19078     if (OASE->getColonLocFirst().isValid())
19079       return false;
19080 
19081     // This is an array subscript which has implicit length 1!
19082     SingleElement = true;
19083     ArraySizes.push_back(llvm::APSInt::get(1));
19084   } else {
19085     Expr::EvalResult Result;
19086     if (!Length->EvaluateAsInt(Result, Context))
19087       return false;
19088 
19089     llvm::APSInt ConstantLengthValue = Result.Val.getInt();
19090     SingleElement = (ConstantLengthValue.getSExtValue() == 1);
19091     ArraySizes.push_back(ConstantLengthValue);
19092   }
19093 
19094   // Get the base of this array section and walk up from there.
19095   const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
19096 
19097   // We require length = 1 for all array sections except the right-most to
19098   // guarantee that the memory region is contiguous and has no holes in it.
19099   while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
19100     Length = TempOASE->getLength();
19101     if (Length == nullptr) {
19102       // For array sections of the form [1:] or [:], we would need to analyze
19103       // the lower bound...
19104       if (OASE->getColonLocFirst().isValid())
19105         return false;
19106 
19107       // This is an array subscript which has implicit length 1!
19108       ArraySizes.push_back(llvm::APSInt::get(1));
19109     } else {
19110       Expr::EvalResult Result;
19111       if (!Length->EvaluateAsInt(Result, Context))
19112         return false;
19113 
19114       llvm::APSInt ConstantLengthValue = Result.Val.getInt();
19115       if (ConstantLengthValue.getSExtValue() != 1)
19116         return false;
19117 
19118       ArraySizes.push_back(ConstantLengthValue);
19119     }
19120     Base = TempOASE->getBase()->IgnoreParenImpCasts();
19121   }
19122 
19123   // If we have a single element, we don't need to add the implicit lengths.
19124   if (!SingleElement) {
19125     while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
19126       // Has implicit length 1!
19127       ArraySizes.push_back(llvm::APSInt::get(1));
19128       Base = TempASE->getBase()->IgnoreParenImpCasts();
19129     }
19130   }
19131 
19132   // This array section can be privatized as a single value or as a constant
19133   // sized array.
19134   return true;
19135 }
19136 
19137 static BinaryOperatorKind
19138 getRelatedCompoundReductionOp(BinaryOperatorKind BOK) {
19139   if (BOK == BO_Add)
19140     return BO_AddAssign;
19141   if (BOK == BO_Mul)
19142     return BO_MulAssign;
19143   if (BOK == BO_And)
19144     return BO_AndAssign;
19145   if (BOK == BO_Or)
19146     return BO_OrAssign;
19147   if (BOK == BO_Xor)
19148     return BO_XorAssign;
19149   return BOK;
19150 }
19151 
19152 static bool actOnOMPReductionKindClause(
19153     Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
19154     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
19155     SourceLocation ColonLoc, SourceLocation EndLoc,
19156     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
19157     ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
19158   DeclarationName DN = ReductionId.getName();
19159   OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator();
19160   BinaryOperatorKind BOK = BO_Comma;
19161 
19162   ASTContext &Context = S.Context;
19163   // OpenMP [2.14.3.6, reduction clause]
19164   // C
19165   // reduction-identifier is either an identifier or one of the following
19166   // operators: +, -, *,  &, |, ^, && and ||
19167   // C++
19168   // reduction-identifier is either an id-expression or one of the following
19169   // operators: +, -, *, &, |, ^, && and ||
19170   switch (OOK) {
19171   case OO_Plus:
19172     BOK = BO_Add;
19173     break;
19174   case OO_Minus:
19175     // Minus(-) operator is not supported in TR11 (OpenMP 6.0). Setting BOK to
19176     // BO_Comma will automatically diagnose it for OpenMP > 52 as not allowed
19177     // reduction identifier.
19178     if (S.LangOpts.OpenMP > 52)
19179       BOK = BO_Comma;
19180     else
19181       BOK = BO_Add;
19182     break;
19183   case OO_Star:
19184     BOK = BO_Mul;
19185     break;
19186   case OO_Amp:
19187     BOK = BO_And;
19188     break;
19189   case OO_Pipe:
19190     BOK = BO_Or;
19191     break;
19192   case OO_Caret:
19193     BOK = BO_Xor;
19194     break;
19195   case OO_AmpAmp:
19196     BOK = BO_LAnd;
19197     break;
19198   case OO_PipePipe:
19199     BOK = BO_LOr;
19200     break;
19201   case OO_New:
19202   case OO_Delete:
19203   case OO_Array_New:
19204   case OO_Array_Delete:
19205   case OO_Slash:
19206   case OO_Percent:
19207   case OO_Tilde:
19208   case OO_Exclaim:
19209   case OO_Equal:
19210   case OO_Less:
19211   case OO_Greater:
19212   case OO_LessEqual:
19213   case OO_GreaterEqual:
19214   case OO_PlusEqual:
19215   case OO_MinusEqual:
19216   case OO_StarEqual:
19217   case OO_SlashEqual:
19218   case OO_PercentEqual:
19219   case OO_CaretEqual:
19220   case OO_AmpEqual:
19221   case OO_PipeEqual:
19222   case OO_LessLess:
19223   case OO_GreaterGreater:
19224   case OO_LessLessEqual:
19225   case OO_GreaterGreaterEqual:
19226   case OO_EqualEqual:
19227   case OO_ExclaimEqual:
19228   case OO_Spaceship:
19229   case OO_PlusPlus:
19230   case OO_MinusMinus:
19231   case OO_Comma:
19232   case OO_ArrowStar:
19233   case OO_Arrow:
19234   case OO_Call:
19235   case OO_Subscript:
19236   case OO_Conditional:
19237   case OO_Coawait:
19238   case NUM_OVERLOADED_OPERATORS:
19239     llvm_unreachable("Unexpected reduction identifier");
19240   case OO_None:
19241     if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
19242       if (II->isStr("max"))
19243         BOK = BO_GT;
19244       else if (II->isStr("min"))
19245         BOK = BO_LT;
19246     }
19247     break;
19248   }
19249 
19250   // OpenMP 5.2, 5.5.5 (see page 627, line 18) reduction Clause, Restrictions
19251   // A reduction clause with the minus (-) operator was deprecated
19252   if (OOK == OO_Minus && S.LangOpts.OpenMP == 52)
19253     S.Diag(ReductionId.getLoc(), diag::warn_omp_minus_in_reduction_deprecated);
19254 
19255   SourceRange ReductionIdRange;
19256   if (ReductionIdScopeSpec.isValid())
19257     ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
19258   else
19259     ReductionIdRange.setBegin(ReductionId.getBeginLoc());
19260   ReductionIdRange.setEnd(ReductionId.getEndLoc());
19261 
19262   auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
19263   bool FirstIter = true;
19264   for (Expr *RefExpr : VarList) {
19265     assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
19266     // OpenMP [2.1, C/C++]
19267     //  A list item is a variable or array section, subject to the restrictions
19268     //  specified in Section 2.4 on page 42 and in each of the sections
19269     // describing clauses and directives for which a list appears.
19270     // OpenMP  [2.14.3.3, Restrictions, p.1]
19271     //  A variable that is part of another variable (as an array or
19272     //  structure element) cannot appear in a private clause.
19273     if (!FirstIter && IR != ER)
19274       ++IR;
19275     FirstIter = false;
19276     SourceLocation ELoc;
19277     SourceRange ERange;
19278     Expr *SimpleRefExpr = RefExpr;
19279     auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
19280                               /*AllowArraySection=*/true);
19281     if (Res.second) {
19282       // Try to find 'declare reduction' corresponding construct before using
19283       // builtin/overloaded operators.
19284       QualType Type = Context.DependentTy;
19285       CXXCastPath BasePath;
19286       ExprResult DeclareReductionRef = buildDeclareReductionRef(
19287           S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
19288           ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
19289       Expr *ReductionOp = nullptr;
19290       if (S.CurContext->isDependentContext() &&
19291           (DeclareReductionRef.isUnset() ||
19292            isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
19293         ReductionOp = DeclareReductionRef.get();
19294       // It will be analyzed later.
19295       RD.push(RefExpr, ReductionOp);
19296     }
19297     ValueDecl *D = Res.first;
19298     if (!D)
19299       continue;
19300 
19301     Expr *TaskgroupDescriptor = nullptr;
19302     QualType Type;
19303     auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
19304     auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
19305     if (ASE) {
19306       Type = ASE->getType().getNonReferenceType();
19307     } else if (OASE) {
19308       QualType BaseType =
19309           OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
19310       if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
19311         Type = ATy->getElementType();
19312       else
19313         Type = BaseType->getPointeeType();
19314       Type = Type.getNonReferenceType();
19315     } else {
19316       Type = Context.getBaseElementType(D->getType().getNonReferenceType());
19317     }
19318     auto *VD = dyn_cast<VarDecl>(D);
19319 
19320     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
19321     //  A variable that appears in a private clause must not have an incomplete
19322     //  type or a reference type.
19323     if (S.RequireCompleteType(ELoc, D->getType(),
19324                               diag::err_omp_reduction_incomplete_type))
19325       continue;
19326     // OpenMP [2.14.3.6, reduction clause, Restrictions]
19327     // A list item that appears in a reduction clause must not be
19328     // const-qualified.
19329     if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
19330                                   /*AcceptIfMutable*/ false, ASE || OASE))
19331       continue;
19332 
19333     OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
19334     // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
19335     //  If a list-item is a reference type then it must bind to the same object
19336     //  for all threads of the team.
19337     if (!ASE && !OASE) {
19338       if (VD) {
19339         VarDecl *VDDef = VD->getDefinition();
19340         if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
19341           DSARefChecker Check(Stack);
19342           if (Check.Visit(VDDef->getInit())) {
19343             S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
19344                 << getOpenMPClauseName(ClauseKind) << ERange;
19345             S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
19346             continue;
19347           }
19348         }
19349       }
19350 
19351       // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
19352       // in a Construct]
19353       //  Variables with the predetermined data-sharing attributes may not be
19354       //  listed in data-sharing attributes clauses, except for the cases
19355       //  listed below. For these exceptions only, listing a predetermined
19356       //  variable in a data-sharing attribute clause is allowed and overrides
19357       //  the variable's predetermined data-sharing attributes.
19358       // OpenMP [2.14.3.6, Restrictions, p.3]
19359       //  Any number of reduction clauses can be specified on the directive,
19360       //  but a list item can appear only once in the reduction clauses for that
19361       //  directive.
19362       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
19363       if (DVar.CKind == OMPC_reduction) {
19364         S.Diag(ELoc, diag::err_omp_once_referenced)
19365             << getOpenMPClauseName(ClauseKind);
19366         if (DVar.RefExpr)
19367           S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
19368         continue;
19369       }
19370       if (DVar.CKind != OMPC_unknown) {
19371         S.Diag(ELoc, diag::err_omp_wrong_dsa)
19372             << getOpenMPClauseName(DVar.CKind)
19373             << getOpenMPClauseName(OMPC_reduction);
19374         reportOriginalDsa(S, Stack, D, DVar);
19375         continue;
19376       }
19377 
19378       // OpenMP [2.14.3.6, Restrictions, p.1]
19379       //  A list item that appears in a reduction clause of a worksharing
19380       //  construct must be shared in the parallel regions to which any of the
19381       //  worksharing regions arising from the worksharing construct bind.
19382       if (isOpenMPWorksharingDirective(CurrDir) &&
19383           !isOpenMPParallelDirective(CurrDir) &&
19384           !isOpenMPTeamsDirective(CurrDir)) {
19385         DVar = Stack->getImplicitDSA(D, true);
19386         if (DVar.CKind != OMPC_shared) {
19387           S.Diag(ELoc, diag::err_omp_required_access)
19388               << getOpenMPClauseName(OMPC_reduction)
19389               << getOpenMPClauseName(OMPC_shared);
19390           reportOriginalDsa(S, Stack, D, DVar);
19391           continue;
19392         }
19393       }
19394     } else {
19395       // Threadprivates cannot be shared between threads, so dignose if the base
19396       // is a threadprivate variable.
19397       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
19398       if (DVar.CKind == OMPC_threadprivate) {
19399         S.Diag(ELoc, diag::err_omp_wrong_dsa)
19400             << getOpenMPClauseName(DVar.CKind)
19401             << getOpenMPClauseName(OMPC_reduction);
19402         reportOriginalDsa(S, Stack, D, DVar);
19403         continue;
19404       }
19405     }
19406 
19407     // Try to find 'declare reduction' corresponding construct before using
19408     // builtin/overloaded operators.
19409     CXXCastPath BasePath;
19410     ExprResult DeclareReductionRef = buildDeclareReductionRef(
19411         S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
19412         ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
19413     if (DeclareReductionRef.isInvalid())
19414       continue;
19415     if (S.CurContext->isDependentContext() &&
19416         (DeclareReductionRef.isUnset() ||
19417          isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
19418       RD.push(RefExpr, DeclareReductionRef.get());
19419       continue;
19420     }
19421     if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
19422       // Not allowed reduction identifier is found.
19423       if (S.LangOpts.OpenMP > 52)
19424         S.Diag(ReductionId.getBeginLoc(),
19425                diag::err_omp_unknown_reduction_identifier_since_omp_6_0)
19426             << Type << ReductionIdRange;
19427       else
19428         S.Diag(ReductionId.getBeginLoc(),
19429                diag::err_omp_unknown_reduction_identifier_prior_omp_6_0)
19430             << Type << ReductionIdRange;
19431       continue;
19432     }
19433 
19434     // OpenMP [2.14.3.6, reduction clause, Restrictions]
19435     // The type of a list item that appears in a reduction clause must be valid
19436     // for the reduction-identifier. For a max or min reduction in C, the type
19437     // of the list item must be an allowed arithmetic data type: char, int,
19438     // float, double, or _Bool, possibly modified with long, short, signed, or
19439     // unsigned. For a max or min reduction in C++, the type of the list item
19440     // must be an allowed arithmetic data type: char, wchar_t, int, float,
19441     // double, or bool, possibly modified with long, short, signed, or unsigned.
19442     if (DeclareReductionRef.isUnset()) {
19443       if ((BOK == BO_GT || BOK == BO_LT) &&
19444           !(Type->isScalarType() ||
19445             (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
19446         S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
19447             << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
19448         if (!ASE && !OASE) {
19449           bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19450                                    VarDecl::DeclarationOnly;
19451           S.Diag(D->getLocation(),
19452                  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19453               << D;
19454         }
19455         continue;
19456       }
19457       if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
19458           !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
19459         S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
19460             << getOpenMPClauseName(ClauseKind);
19461         if (!ASE && !OASE) {
19462           bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19463                                    VarDecl::DeclarationOnly;
19464           S.Diag(D->getLocation(),
19465                  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19466               << D;
19467         }
19468         continue;
19469       }
19470     }
19471 
19472     Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
19473     VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
19474                                   D->hasAttrs() ? &D->getAttrs() : nullptr);
19475     VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
19476                                   D->hasAttrs() ? &D->getAttrs() : nullptr);
19477     QualType PrivateTy = Type;
19478 
19479     // Try if we can determine constant lengths for all array sections and avoid
19480     // the VLA.
19481     bool ConstantLengthOASE = false;
19482     if (OASE) {
19483       bool SingleElement;
19484       llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
19485       ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
19486           Context, OASE, SingleElement, ArraySizes);
19487 
19488       // If we don't have a single element, we must emit a constant array type.
19489       if (ConstantLengthOASE && !SingleElement) {
19490         for (llvm::APSInt &Size : ArraySizes)
19491           PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr,
19492                                                    ArrayType::Normal,
19493                                                    /*IndexTypeQuals=*/0);
19494       }
19495     }
19496 
19497     if ((OASE && !ConstantLengthOASE) ||
19498         (!OASE && !ASE &&
19499          D->getType().getNonReferenceType()->isVariablyModifiedType())) {
19500       if (!Context.getTargetInfo().isVLASupported()) {
19501         if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) {
19502           S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
19503           S.Diag(ELoc, diag::note_vla_unsupported);
19504           continue;
19505         } else {
19506           S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
19507           S.targetDiag(ELoc, diag::note_vla_unsupported);
19508         }
19509       }
19510       // For arrays/array sections only:
19511       // Create pseudo array type for private copy. The size for this array will
19512       // be generated during codegen.
19513       // For array subscripts or single variables Private Ty is the same as Type
19514       // (type of the variable or single array element).
19515       PrivateTy = Context.getVariableArrayType(
19516           Type,
19517           new (Context)
19518               OpaqueValueExpr(ELoc, Context.getSizeType(), VK_PRValue),
19519           ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
19520     } else if (!ASE && !OASE &&
19521                Context.getAsArrayType(D->getType().getNonReferenceType())) {
19522       PrivateTy = D->getType().getNonReferenceType();
19523     }
19524     // Private copy.
19525     VarDecl *PrivateVD =
19526         buildVarDecl(S, ELoc, PrivateTy, D->getName(),
19527                      D->hasAttrs() ? &D->getAttrs() : nullptr,
19528                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
19529     // Add initializer for private variable.
19530     Expr *Init = nullptr;
19531     DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
19532     DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
19533     if (DeclareReductionRef.isUsable()) {
19534       auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
19535       auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
19536       if (DRD->getInitializer()) {
19537         Init = DRDRef;
19538         RHSVD->setInit(DRDRef);
19539         RHSVD->setInitStyle(VarDecl::CallInit);
19540       }
19541     } else {
19542       switch (BOK) {
19543       case BO_Add:
19544       case BO_Xor:
19545       case BO_Or:
19546       case BO_LOr:
19547         // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
19548         if (Type->isScalarType() || Type->isAnyComplexType())
19549           Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
19550         break;
19551       case BO_Mul:
19552       case BO_LAnd:
19553         if (Type->isScalarType() || Type->isAnyComplexType()) {
19554           // '*' and '&&' reduction ops - initializer is '1'.
19555           Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
19556         }
19557         break;
19558       case BO_And: {
19559         // '&' reduction op - initializer is '~0'.
19560         QualType OrigType = Type;
19561         if (auto *ComplexTy = OrigType->getAs<ComplexType>())
19562           Type = ComplexTy->getElementType();
19563         if (Type->isRealFloatingType()) {
19564           llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue(
19565               Context.getFloatTypeSemantics(Type));
19566           Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
19567                                          Type, ELoc);
19568         } else if (Type->isScalarType()) {
19569           uint64_t Size = Context.getTypeSize(Type);
19570           QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
19571           llvm::APInt InitValue = llvm::APInt::getAllOnes(Size);
19572           Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
19573         }
19574         if (Init && OrigType->isAnyComplexType()) {
19575           // Init = 0xFFFF + 0xFFFFi;
19576           auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
19577           Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
19578         }
19579         Type = OrigType;
19580         break;
19581       }
19582       case BO_LT:
19583       case BO_GT: {
19584         // 'min' reduction op - initializer is 'Largest representable number in
19585         // the reduction list item type'.
19586         // 'max' reduction op - initializer is 'Least representable number in
19587         // the reduction list item type'.
19588         if (Type->isIntegerType() || Type->isPointerType()) {
19589           bool IsSigned = Type->hasSignedIntegerRepresentation();
19590           uint64_t Size = Context.getTypeSize(Type);
19591           QualType IntTy =
19592               Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
19593           llvm::APInt InitValue =
19594               (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
19595                                         : llvm::APInt::getMinValue(Size)
19596               : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
19597                              : llvm::APInt::getMaxValue(Size);
19598           Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
19599           if (Type->isPointerType()) {
19600             // Cast to pointer type.
19601             ExprResult CastExpr = S.BuildCStyleCastExpr(
19602                 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
19603             if (CastExpr.isInvalid())
19604               continue;
19605             Init = CastExpr.get();
19606           }
19607         } else if (Type->isRealFloatingType()) {
19608           llvm::APFloat InitValue = llvm::APFloat::getLargest(
19609               Context.getFloatTypeSemantics(Type), BOK != BO_LT);
19610           Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
19611                                          Type, ELoc);
19612         }
19613         break;
19614       }
19615       case BO_PtrMemD:
19616       case BO_PtrMemI:
19617       case BO_MulAssign:
19618       case BO_Div:
19619       case BO_Rem:
19620       case BO_Sub:
19621       case BO_Shl:
19622       case BO_Shr:
19623       case BO_LE:
19624       case BO_GE:
19625       case BO_EQ:
19626       case BO_NE:
19627       case BO_Cmp:
19628       case BO_AndAssign:
19629       case BO_XorAssign:
19630       case BO_OrAssign:
19631       case BO_Assign:
19632       case BO_AddAssign:
19633       case BO_SubAssign:
19634       case BO_DivAssign:
19635       case BO_RemAssign:
19636       case BO_ShlAssign:
19637       case BO_ShrAssign:
19638       case BO_Comma:
19639         llvm_unreachable("Unexpected reduction operation");
19640       }
19641     }
19642     if (Init && DeclareReductionRef.isUnset()) {
19643       S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
19644       // Store initializer for single element in private copy. Will be used
19645       // during codegen.
19646       PrivateVD->setInit(RHSVD->getInit());
19647       PrivateVD->setInitStyle(RHSVD->getInitStyle());
19648     } else if (!Init) {
19649       S.ActOnUninitializedDecl(RHSVD);
19650       // Store initializer for single element in private copy. Will be used
19651       // during codegen.
19652       PrivateVD->setInit(RHSVD->getInit());
19653       PrivateVD->setInitStyle(RHSVD->getInitStyle());
19654     }
19655     if (RHSVD->isInvalidDecl())
19656       continue;
19657     if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) {
19658       S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
19659           << Type << ReductionIdRange;
19660       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19661                                VarDecl::DeclarationOnly;
19662       S.Diag(D->getLocation(),
19663              IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19664           << D;
19665       continue;
19666     }
19667     DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
19668     ExprResult ReductionOp;
19669     if (DeclareReductionRef.isUsable()) {
19670       QualType RedTy = DeclareReductionRef.get()->getType();
19671       QualType PtrRedTy = Context.getPointerType(RedTy);
19672       ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
19673       ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
19674       if (!BasePath.empty()) {
19675         LHS = S.DefaultLvalueConversion(LHS.get());
19676         RHS = S.DefaultLvalueConversion(RHS.get());
19677         LHS = ImplicitCastExpr::Create(
19678             Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath,
19679             LHS.get()->getValueKind(), FPOptionsOverride());
19680         RHS = ImplicitCastExpr::Create(
19681             Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath,
19682             RHS.get()->getValueKind(), FPOptionsOverride());
19683       }
19684       FunctionProtoType::ExtProtoInfo EPI;
19685       QualType Params[] = {PtrRedTy, PtrRedTy};
19686       QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
19687       auto *OVE = new (Context) OpaqueValueExpr(
19688           ELoc, Context.getPointerType(FnTy), VK_PRValue, OK_Ordinary,
19689           S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
19690       Expr *Args[] = {LHS.get(), RHS.get()};
19691       ReductionOp =
19692           CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_PRValue, ELoc,
19693                            S.CurFPFeatureOverrides());
19694     } else {
19695       BinaryOperatorKind CombBOK = getRelatedCompoundReductionOp(BOK);
19696       if (Type->isRecordType() && CombBOK != BOK) {
19697         Sema::TentativeAnalysisScope Trap(S);
19698         ReductionOp =
19699             S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
19700                          CombBOK, LHSDRE, RHSDRE);
19701       }
19702       if (!ReductionOp.isUsable()) {
19703         ReductionOp =
19704             S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), BOK,
19705                          LHSDRE, RHSDRE);
19706         if (ReductionOp.isUsable()) {
19707           if (BOK != BO_LT && BOK != BO_GT) {
19708             ReductionOp =
19709                 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
19710                              BO_Assign, LHSDRE, ReductionOp.get());
19711           } else {
19712             auto *ConditionalOp = new (Context)
19713                 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc,
19714                                     RHSDRE, Type, VK_LValue, OK_Ordinary);
19715             ReductionOp =
19716                 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
19717                              BO_Assign, LHSDRE, ConditionalOp);
19718           }
19719         }
19720       }
19721       if (ReductionOp.isUsable())
19722         ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
19723                                             /*DiscardedValue*/ false);
19724       if (!ReductionOp.isUsable())
19725         continue;
19726     }
19727 
19728     // Add copy operations for inscan reductions.
19729     // LHS = RHS;
19730     ExprResult CopyOpRes, TempArrayRes, TempArrayElem;
19731     if (ClauseKind == OMPC_reduction &&
19732         RD.RedModifier == OMPC_REDUCTION_inscan) {
19733       ExprResult RHS = S.DefaultLvalueConversion(RHSDRE);
19734       CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE,
19735                                RHS.get());
19736       if (!CopyOpRes.isUsable())
19737         continue;
19738       CopyOpRes =
19739           S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true);
19740       if (!CopyOpRes.isUsable())
19741         continue;
19742       // For simd directive and simd-based directives in simd mode no need to
19743       // construct temp array, need just a single temp element.
19744       if (Stack->getCurrentDirective() == OMPD_simd ||
19745           (S.getLangOpts().OpenMPSimd &&
19746            isOpenMPSimdDirective(Stack->getCurrentDirective()))) {
19747         VarDecl *TempArrayVD =
19748             buildVarDecl(S, ELoc, PrivateTy, D->getName(),
19749                          D->hasAttrs() ? &D->getAttrs() : nullptr);
19750         // Add a constructor to the temp decl.
19751         S.ActOnUninitializedDecl(TempArrayVD);
19752         TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc);
19753       } else {
19754         // Build temp array for prefix sum.
19755         auto *Dim = new (S.Context)
19756             OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue);
19757         QualType ArrayTy =
19758             S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal,
19759                                            /*IndexTypeQuals=*/0, {ELoc, ELoc});
19760         VarDecl *TempArrayVD =
19761             buildVarDecl(S, ELoc, ArrayTy, D->getName(),
19762                          D->hasAttrs() ? &D->getAttrs() : nullptr);
19763         // Add a constructor to the temp decl.
19764         S.ActOnUninitializedDecl(TempArrayVD);
19765         TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc);
19766         TempArrayElem =
19767             S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get());
19768         auto *Idx = new (S.Context)
19769             OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue);
19770         TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(),
19771                                                           ELoc, Idx, ELoc);
19772       }
19773     }
19774 
19775     // OpenMP [2.15.4.6, Restrictions, p.2]
19776     // A list item that appears in an in_reduction clause of a task construct
19777     // must appear in a task_reduction clause of a construct associated with a
19778     // taskgroup region that includes the participating task in its taskgroup
19779     // set. The construct associated with the innermost region that meets this
19780     // condition must specify the same reduction-identifier as the in_reduction
19781     // clause.
19782     if (ClauseKind == OMPC_in_reduction) {
19783       SourceRange ParentSR;
19784       BinaryOperatorKind ParentBOK;
19785       const Expr *ParentReductionOp = nullptr;
19786       Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr;
19787       DSAStackTy::DSAVarData ParentBOKDSA =
19788           Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
19789                                                   ParentBOKTD);
19790       DSAStackTy::DSAVarData ParentReductionOpDSA =
19791           Stack->getTopMostTaskgroupReductionData(
19792               D, ParentSR, ParentReductionOp, ParentReductionOpTD);
19793       bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
19794       bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
19795       if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
19796           (DeclareReductionRef.isUsable() && IsParentBOK) ||
19797           (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) {
19798         bool EmitError = true;
19799         if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
19800           llvm::FoldingSetNodeID RedId, ParentRedId;
19801           ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
19802           DeclareReductionRef.get()->Profile(RedId, Context,
19803                                              /*Canonical=*/true);
19804           EmitError = RedId != ParentRedId;
19805         }
19806         if (EmitError) {
19807           S.Diag(ReductionId.getBeginLoc(),
19808                  diag::err_omp_reduction_identifier_mismatch)
19809               << ReductionIdRange << RefExpr->getSourceRange();
19810           S.Diag(ParentSR.getBegin(),
19811                  diag::note_omp_previous_reduction_identifier)
19812               << ParentSR
19813               << (IsParentBOK ? ParentBOKDSA.RefExpr
19814                               : ParentReductionOpDSA.RefExpr)
19815                      ->getSourceRange();
19816           continue;
19817         }
19818       }
19819       TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
19820     }
19821 
19822     DeclRefExpr *Ref = nullptr;
19823     Expr *VarsExpr = RefExpr->IgnoreParens();
19824     if (!VD && !S.CurContext->isDependentContext()) {
19825       if (ASE || OASE) {
19826         TransformExprToCaptures RebuildToCapture(S, D);
19827         VarsExpr =
19828             RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
19829         Ref = RebuildToCapture.getCapturedExpr();
19830       } else {
19831         VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
19832       }
19833       if (!S.isOpenMPCapturedDecl(D)) {
19834         RD.ExprCaptures.emplace_back(Ref->getDecl());
19835         if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
19836           ExprResult RefRes = S.DefaultLvalueConversion(Ref);
19837           if (!RefRes.isUsable())
19838             continue;
19839           ExprResult PostUpdateRes =
19840               S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
19841                            RefRes.get());
19842           if (!PostUpdateRes.isUsable())
19843             continue;
19844           if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
19845               Stack->getCurrentDirective() == OMPD_taskgroup) {
19846             S.Diag(RefExpr->getExprLoc(),
19847                    diag::err_omp_reduction_non_addressable_expression)
19848                 << RefExpr->getSourceRange();
19849             continue;
19850           }
19851           RD.ExprPostUpdates.emplace_back(
19852               S.IgnoredValueConversions(PostUpdateRes.get()).get());
19853         }
19854       }
19855     }
19856     // All reduction items are still marked as reduction (to do not increase
19857     // code base size).
19858     unsigned Modifier = RD.RedModifier;
19859     // Consider task_reductions as reductions with task modifier. Required for
19860     // correct analysis of in_reduction clauses.
19861     if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction)
19862       Modifier = OMPC_REDUCTION_task;
19863     Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier,
19864                   ASE || OASE);
19865     if (Modifier == OMPC_REDUCTION_task &&
19866         (CurrDir == OMPD_taskgroup ||
19867          ((isOpenMPParallelDirective(CurrDir) ||
19868            isOpenMPWorksharingDirective(CurrDir)) &&
19869           !isOpenMPSimdDirective(CurrDir)))) {
19870       if (DeclareReductionRef.isUsable())
19871         Stack->addTaskgroupReductionData(D, ReductionIdRange,
19872                                          DeclareReductionRef.get());
19873       else
19874         Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
19875     }
19876     RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
19877             TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(),
19878             TempArrayElem.get());
19879   }
19880   return RD.Vars.empty();
19881 }
19882 
19883 OMPClause *Sema::ActOnOpenMPReductionClause(
19884     ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
19885     SourceLocation StartLoc, SourceLocation LParenLoc,
19886     SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
19887     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
19888     ArrayRef<Expr *> UnresolvedReductions) {
19889   if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) {
19890     Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
19891         << getListOfPossibleValues(OMPC_reduction, /*First=*/0,
19892                                    /*Last=*/OMPC_REDUCTION_unknown)
19893         << getOpenMPClauseName(OMPC_reduction);
19894     return nullptr;
19895   }
19896   // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions
19897   // A reduction clause with the inscan reduction-modifier may only appear on a
19898   // worksharing-loop construct, a worksharing-loop SIMD construct, a simd
19899   // construct, a parallel worksharing-loop construct or a parallel
19900   // worksharing-loop SIMD construct.
19901   if (Modifier == OMPC_REDUCTION_inscan &&
19902       (DSAStack->getCurrentDirective() != OMPD_for &&
19903        DSAStack->getCurrentDirective() != OMPD_for_simd &&
19904        DSAStack->getCurrentDirective() != OMPD_simd &&
19905        DSAStack->getCurrentDirective() != OMPD_parallel_for &&
19906        DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) {
19907     Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
19908     return nullptr;
19909   }
19910 
19911   ReductionData RD(VarList.size(), Modifier);
19912   if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList,
19913                                   StartLoc, LParenLoc, ColonLoc, EndLoc,
19914                                   ReductionIdScopeSpec, ReductionId,
19915                                   UnresolvedReductions, RD))
19916     return nullptr;
19917 
19918   return OMPReductionClause::Create(
19919       Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier,
19920       RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
19921       RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps,
19922       RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems,
19923       buildPreInits(Context, RD.ExprCaptures),
19924       buildPostUpdate(*this, RD.ExprPostUpdates));
19925 }
19926 
19927 OMPClause *Sema::ActOnOpenMPTaskReductionClause(
19928     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
19929     SourceLocation ColonLoc, SourceLocation EndLoc,
19930     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
19931     ArrayRef<Expr *> UnresolvedReductions) {
19932   ReductionData RD(VarList.size());
19933   if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList,
19934                                   StartLoc, LParenLoc, ColonLoc, EndLoc,
19935                                   ReductionIdScopeSpec, ReductionId,
19936                                   UnresolvedReductions, RD))
19937     return nullptr;
19938 
19939   return OMPTaskReductionClause::Create(
19940       Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
19941       ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
19942       RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
19943       buildPreInits(Context, RD.ExprCaptures),
19944       buildPostUpdate(*this, RD.ExprPostUpdates));
19945 }
19946 
19947 OMPClause *Sema::ActOnOpenMPInReductionClause(
19948     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
19949     SourceLocation ColonLoc, SourceLocation EndLoc,
19950     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
19951     ArrayRef<Expr *> UnresolvedReductions) {
19952   ReductionData RD(VarList.size());
19953   if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList,
19954                                   StartLoc, LParenLoc, ColonLoc, EndLoc,
19955                                   ReductionIdScopeSpec, ReductionId,
19956                                   UnresolvedReductions, RD))
19957     return nullptr;
19958 
19959   return OMPInReductionClause::Create(
19960       Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
19961       ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
19962       RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
19963       buildPreInits(Context, RD.ExprCaptures),
19964       buildPostUpdate(*this, RD.ExprPostUpdates));
19965 }
19966 
19967 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
19968                                      SourceLocation LinLoc) {
19969   if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
19970       LinKind == OMPC_LINEAR_unknown) {
19971     Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
19972     return true;
19973   }
19974   return false;
19975 }
19976 
19977 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
19978                                  OpenMPLinearClauseKind LinKind, QualType Type,
19979                                  bool IsDeclareSimd) {
19980   const auto *VD = dyn_cast_or_null<VarDecl>(D);
19981   // A variable must not have an incomplete type or a reference type.
19982   if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
19983     return true;
19984   if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
19985       !Type->isReferenceType()) {
19986     Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
19987         << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
19988     return true;
19989   }
19990   Type = Type.getNonReferenceType();
19991 
19992   // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
19993   // A variable that is privatized must not have a const-qualified type
19994   // unless it is of class type with a mutable member. This restriction does
19995   // not apply to the firstprivate clause, nor to the linear clause on
19996   // declarative directives (like declare simd).
19997   if (!IsDeclareSimd &&
19998       rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
19999     return true;
20000 
20001   // A list item must be of integral or pointer type.
20002   Type = Type.getUnqualifiedType().getCanonicalType();
20003   const auto *Ty = Type.getTypePtrOrNull();
20004   if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
20005               !Ty->isIntegralType(Context) && !Ty->isPointerType())) {
20006     Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
20007     if (D) {
20008       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
20009                                VarDecl::DeclarationOnly;
20010       Diag(D->getLocation(),
20011            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
20012           << D;
20013     }
20014     return true;
20015   }
20016   return false;
20017 }
20018 
20019 OMPClause *Sema::ActOnOpenMPLinearClause(
20020     ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
20021     SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
20022     SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
20023   SmallVector<Expr *, 8> Vars;
20024   SmallVector<Expr *, 8> Privates;
20025   SmallVector<Expr *, 8> Inits;
20026   SmallVector<Decl *, 4> ExprCaptures;
20027   SmallVector<Expr *, 4> ExprPostUpdates;
20028   if (CheckOpenMPLinearModifier(LinKind, LinLoc))
20029     LinKind = OMPC_LINEAR_val;
20030   for (Expr *RefExpr : VarList) {
20031     assert(RefExpr && "NULL expr in OpenMP linear clause.");
20032     SourceLocation ELoc;
20033     SourceRange ERange;
20034     Expr *SimpleRefExpr = RefExpr;
20035     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20036     if (Res.second) {
20037       // It will be analyzed later.
20038       Vars.push_back(RefExpr);
20039       Privates.push_back(nullptr);
20040       Inits.push_back(nullptr);
20041     }
20042     ValueDecl *D = Res.first;
20043     if (!D)
20044       continue;
20045 
20046     QualType Type = D->getType();
20047     auto *VD = dyn_cast<VarDecl>(D);
20048 
20049     // OpenMP [2.14.3.7, linear clause]
20050     //  A list-item cannot appear in more than one linear clause.
20051     //  A list-item that appears in a linear clause cannot appear in any
20052     //  other data-sharing attribute clause.
20053     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
20054     if (DVar.RefExpr) {
20055       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
20056                                           << getOpenMPClauseName(OMPC_linear);
20057       reportOriginalDsa(*this, DSAStack, D, DVar);
20058       continue;
20059     }
20060 
20061     if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
20062       continue;
20063     Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
20064 
20065     // Build private copy of original var.
20066     VarDecl *Private =
20067         buildVarDecl(*this, ELoc, Type, D->getName(),
20068                      D->hasAttrs() ? &D->getAttrs() : nullptr,
20069                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
20070     DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
20071     // Build var to save initial value.
20072     VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
20073     Expr *InitExpr;
20074     DeclRefExpr *Ref = nullptr;
20075     if (!VD && !CurContext->isDependentContext()) {
20076       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
20077       if (!isOpenMPCapturedDecl(D)) {
20078         ExprCaptures.push_back(Ref->getDecl());
20079         if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
20080           ExprResult RefRes = DefaultLvalueConversion(Ref);
20081           if (!RefRes.isUsable())
20082             continue;
20083           ExprResult PostUpdateRes =
20084               BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
20085                          SimpleRefExpr, RefRes.get());
20086           if (!PostUpdateRes.isUsable())
20087             continue;
20088           ExprPostUpdates.push_back(
20089               IgnoredValueConversions(PostUpdateRes.get()).get());
20090         }
20091       }
20092     }
20093     if (LinKind == OMPC_LINEAR_uval)
20094       InitExpr = VD ? VD->getInit() : SimpleRefExpr;
20095     else
20096       InitExpr = VD ? SimpleRefExpr : Ref;
20097     AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
20098                          /*DirectInit=*/false);
20099     DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
20100 
20101     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
20102     Vars.push_back((VD || CurContext->isDependentContext())
20103                        ? RefExpr->IgnoreParens()
20104                        : Ref);
20105     Privates.push_back(PrivateRef);
20106     Inits.push_back(InitRef);
20107   }
20108 
20109   if (Vars.empty())
20110     return nullptr;
20111 
20112   Expr *StepExpr = Step;
20113   Expr *CalcStepExpr = nullptr;
20114   if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
20115       !Step->isInstantiationDependent() &&
20116       !Step->containsUnexpandedParameterPack()) {
20117     SourceLocation StepLoc = Step->getBeginLoc();
20118     ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
20119     if (Val.isInvalid())
20120       return nullptr;
20121     StepExpr = Val.get();
20122 
20123     // Build var to save the step value.
20124     VarDecl *SaveVar =
20125         buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
20126     ExprResult SaveRef =
20127         buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
20128     ExprResult CalcStep =
20129         BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
20130     CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
20131 
20132     // Warn about zero linear step (it would be probably better specified as
20133     // making corresponding variables 'const').
20134     if (std::optional<llvm::APSInt> Result =
20135             StepExpr->getIntegerConstantExpr(Context)) {
20136       if (!Result->isNegative() && !Result->isStrictlyPositive())
20137         Diag(StepLoc, diag::warn_omp_linear_step_zero)
20138             << Vars[0] << (Vars.size() > 1);
20139     } else if (CalcStep.isUsable()) {
20140       // Calculate the step beforehand instead of doing this on each iteration.
20141       // (This is not used if the number of iterations may be kfold-ed).
20142       CalcStepExpr = CalcStep.get();
20143     }
20144   }
20145 
20146   return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
20147                                  ColonLoc, EndLoc, Vars, Privates, Inits,
20148                                  StepExpr, CalcStepExpr,
20149                                  buildPreInits(Context, ExprCaptures),
20150                                  buildPostUpdate(*this, ExprPostUpdates));
20151 }
20152 
20153 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
20154                                      Expr *NumIterations, Sema &SemaRef,
20155                                      Scope *S, DSAStackTy *Stack) {
20156   // Walk the vars and build update/final expressions for the CodeGen.
20157   SmallVector<Expr *, 8> Updates;
20158   SmallVector<Expr *, 8> Finals;
20159   SmallVector<Expr *, 8> UsedExprs;
20160   Expr *Step = Clause.getStep();
20161   Expr *CalcStep = Clause.getCalcStep();
20162   // OpenMP [2.14.3.7, linear clause]
20163   // If linear-step is not specified it is assumed to be 1.
20164   if (!Step)
20165     Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
20166   else if (CalcStep)
20167     Step = cast<BinaryOperator>(CalcStep)->getLHS();
20168   bool HasErrors = false;
20169   auto CurInit = Clause.inits().begin();
20170   auto CurPrivate = Clause.privates().begin();
20171   OpenMPLinearClauseKind LinKind = Clause.getModifier();
20172   for (Expr *RefExpr : Clause.varlists()) {
20173     SourceLocation ELoc;
20174     SourceRange ERange;
20175     Expr *SimpleRefExpr = RefExpr;
20176     auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
20177     ValueDecl *D = Res.first;
20178     if (Res.second || !D) {
20179       Updates.push_back(nullptr);
20180       Finals.push_back(nullptr);
20181       HasErrors = true;
20182       continue;
20183     }
20184     auto &&Info = Stack->isLoopControlVariable(D);
20185     // OpenMP [2.15.11, distribute simd Construct]
20186     // A list item may not appear in a linear clause, unless it is the loop
20187     // iteration variable.
20188     if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
20189         isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
20190       SemaRef.Diag(ELoc,
20191                    diag::err_omp_linear_distribute_var_non_loop_iteration);
20192       Updates.push_back(nullptr);
20193       Finals.push_back(nullptr);
20194       HasErrors = true;
20195       continue;
20196     }
20197     Expr *InitExpr = *CurInit;
20198 
20199     // Build privatized reference to the current linear var.
20200     auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
20201     Expr *CapturedRef;
20202     if (LinKind == OMPC_LINEAR_uval)
20203       CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
20204     else
20205       CapturedRef =
20206           buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
20207                            DE->getType().getUnqualifiedType(), DE->getExprLoc(),
20208                            /*RefersToCapture=*/true);
20209 
20210     // Build update: Var = InitExpr + IV * Step
20211     ExprResult Update;
20212     if (!Info.first)
20213       Update = buildCounterUpdate(
20214           SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
20215           /*Subtract=*/false, /*IsNonRectangularLB=*/false);
20216     else
20217       Update = *CurPrivate;
20218     Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
20219                                          /*DiscardedValue*/ false);
20220 
20221     // Build final: Var = PrivCopy;
20222     ExprResult Final;
20223     if (!Info.first)
20224       Final = SemaRef.BuildBinOp(
20225           S, RefExpr->getExprLoc(), BO_Assign, CapturedRef,
20226           SemaRef.DefaultLvalueConversion(*CurPrivate).get());
20227     else
20228       Final = *CurPrivate;
20229     Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
20230                                         /*DiscardedValue*/ false);
20231 
20232     if (!Update.isUsable() || !Final.isUsable()) {
20233       Updates.push_back(nullptr);
20234       Finals.push_back(nullptr);
20235       UsedExprs.push_back(nullptr);
20236       HasErrors = true;
20237     } else {
20238       Updates.push_back(Update.get());
20239       Finals.push_back(Final.get());
20240       if (!Info.first)
20241         UsedExprs.push_back(SimpleRefExpr);
20242     }
20243     ++CurInit;
20244     ++CurPrivate;
20245   }
20246   if (Expr *S = Clause.getStep())
20247     UsedExprs.push_back(S);
20248   // Fill the remaining part with the nullptr.
20249   UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr);
20250   Clause.setUpdates(Updates);
20251   Clause.setFinals(Finals);
20252   Clause.setUsedExprs(UsedExprs);
20253   return HasErrors;
20254 }
20255 
20256 OMPClause *Sema::ActOnOpenMPAlignedClause(
20257     ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
20258     SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
20259   SmallVector<Expr *, 8> Vars;
20260   for (Expr *RefExpr : VarList) {
20261     assert(RefExpr && "NULL expr in OpenMP linear clause.");
20262     SourceLocation ELoc;
20263     SourceRange ERange;
20264     Expr *SimpleRefExpr = RefExpr;
20265     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20266     if (Res.second) {
20267       // It will be analyzed later.
20268       Vars.push_back(RefExpr);
20269     }
20270     ValueDecl *D = Res.first;
20271     if (!D)
20272       continue;
20273 
20274     QualType QType = D->getType();
20275     auto *VD = dyn_cast<VarDecl>(D);
20276 
20277     // OpenMP  [2.8.1, simd construct, Restrictions]
20278     // The type of list items appearing in the aligned clause must be
20279     // array, pointer, reference to array, or reference to pointer.
20280     QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
20281     const Type *Ty = QType.getTypePtrOrNull();
20282     if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
20283       Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
20284           << QType << getLangOpts().CPlusPlus << ERange;
20285       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
20286                                VarDecl::DeclarationOnly;
20287       Diag(D->getLocation(),
20288            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
20289           << D;
20290       continue;
20291     }
20292 
20293     // OpenMP  [2.8.1, simd construct, Restrictions]
20294     // A list-item cannot appear in more than one aligned clause.
20295     if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
20296       Diag(ELoc, diag::err_omp_used_in_clause_twice)
20297           << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
20298       Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
20299           << getOpenMPClauseName(OMPC_aligned);
20300       continue;
20301     }
20302 
20303     DeclRefExpr *Ref = nullptr;
20304     if (!VD && isOpenMPCapturedDecl(D))
20305       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
20306     Vars.push_back(DefaultFunctionArrayConversion(
20307                        (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
20308                        .get());
20309   }
20310 
20311   // OpenMP [2.8.1, simd construct, Description]
20312   // The parameter of the aligned clause, alignment, must be a constant
20313   // positive integer expression.
20314   // If no optional parameter is specified, implementation-defined default
20315   // alignments for SIMD instructions on the target platforms are assumed.
20316   if (Alignment != nullptr) {
20317     ExprResult AlignResult =
20318         VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
20319     if (AlignResult.isInvalid())
20320       return nullptr;
20321     Alignment = AlignResult.get();
20322   }
20323   if (Vars.empty())
20324     return nullptr;
20325 
20326   return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
20327                                   EndLoc, Vars, Alignment);
20328 }
20329 
20330 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
20331                                          SourceLocation StartLoc,
20332                                          SourceLocation LParenLoc,
20333                                          SourceLocation EndLoc) {
20334   SmallVector<Expr *, 8> Vars;
20335   SmallVector<Expr *, 8> SrcExprs;
20336   SmallVector<Expr *, 8> DstExprs;
20337   SmallVector<Expr *, 8> AssignmentOps;
20338   for (Expr *RefExpr : VarList) {
20339     assert(RefExpr && "NULL expr in OpenMP copyin clause.");
20340     if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
20341       // It will be analyzed later.
20342       Vars.push_back(RefExpr);
20343       SrcExprs.push_back(nullptr);
20344       DstExprs.push_back(nullptr);
20345       AssignmentOps.push_back(nullptr);
20346       continue;
20347     }
20348 
20349     SourceLocation ELoc = RefExpr->getExprLoc();
20350     // OpenMP [2.1, C/C++]
20351     //  A list item is a variable name.
20352     // OpenMP  [2.14.4.1, Restrictions, p.1]
20353     //  A list item that appears in a copyin clause must be threadprivate.
20354     auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
20355     if (!DE || !isa<VarDecl>(DE->getDecl())) {
20356       Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
20357           << 0 << RefExpr->getSourceRange();
20358       continue;
20359     }
20360 
20361     Decl *D = DE->getDecl();
20362     auto *VD = cast<VarDecl>(D);
20363 
20364     QualType Type = VD->getType();
20365     if (Type->isDependentType() || Type->isInstantiationDependentType()) {
20366       // It will be analyzed later.
20367       Vars.push_back(DE);
20368       SrcExprs.push_back(nullptr);
20369       DstExprs.push_back(nullptr);
20370       AssignmentOps.push_back(nullptr);
20371       continue;
20372     }
20373 
20374     // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
20375     //  A list item that appears in a copyin clause must be threadprivate.
20376     if (!DSAStack->isThreadPrivate(VD)) {
20377       Diag(ELoc, diag::err_omp_required_access)
20378           << getOpenMPClauseName(OMPC_copyin)
20379           << getOpenMPDirectiveName(OMPD_threadprivate);
20380       continue;
20381     }
20382 
20383     // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
20384     //  A variable of class type (or array thereof) that appears in a
20385     //  copyin clause requires an accessible, unambiguous copy assignment
20386     //  operator for the class type.
20387     QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
20388     VarDecl *SrcVD =
20389         buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
20390                      ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
20391     DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
20392         *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
20393     VarDecl *DstVD =
20394         buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
20395                      VD->hasAttrs() ? &VD->getAttrs() : nullptr);
20396     DeclRefExpr *PseudoDstExpr =
20397         buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
20398     // For arrays generate assignment operation for single element and replace
20399     // it by the original array element in CodeGen.
20400     ExprResult AssignmentOp =
20401         BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
20402                    PseudoSrcExpr);
20403     if (AssignmentOp.isInvalid())
20404       continue;
20405     AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
20406                                        /*DiscardedValue*/ false);
20407     if (AssignmentOp.isInvalid())
20408       continue;
20409 
20410     DSAStack->addDSA(VD, DE, OMPC_copyin);
20411     Vars.push_back(DE);
20412     SrcExprs.push_back(PseudoSrcExpr);
20413     DstExprs.push_back(PseudoDstExpr);
20414     AssignmentOps.push_back(AssignmentOp.get());
20415   }
20416 
20417   if (Vars.empty())
20418     return nullptr;
20419 
20420   return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
20421                                  SrcExprs, DstExprs, AssignmentOps);
20422 }
20423 
20424 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
20425                                               SourceLocation StartLoc,
20426                                               SourceLocation LParenLoc,
20427                                               SourceLocation EndLoc) {
20428   SmallVector<Expr *, 8> Vars;
20429   SmallVector<Expr *, 8> SrcExprs;
20430   SmallVector<Expr *, 8> DstExprs;
20431   SmallVector<Expr *, 8> AssignmentOps;
20432   for (Expr *RefExpr : VarList) {
20433     assert(RefExpr && "NULL expr in OpenMP linear clause.");
20434     SourceLocation ELoc;
20435     SourceRange ERange;
20436     Expr *SimpleRefExpr = RefExpr;
20437     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20438     if (Res.second) {
20439       // It will be analyzed later.
20440       Vars.push_back(RefExpr);
20441       SrcExprs.push_back(nullptr);
20442       DstExprs.push_back(nullptr);
20443       AssignmentOps.push_back(nullptr);
20444     }
20445     ValueDecl *D = Res.first;
20446     if (!D)
20447       continue;
20448 
20449     QualType Type = D->getType();
20450     auto *VD = dyn_cast<VarDecl>(D);
20451 
20452     // OpenMP [2.14.4.2, Restrictions, p.2]
20453     //  A list item that appears in a copyprivate clause may not appear in a
20454     //  private or firstprivate clause on the single construct.
20455     if (!VD || !DSAStack->isThreadPrivate(VD)) {
20456       DSAStackTy::DSAVarData DVar =
20457           DSAStack->getTopDSA(D, /*FromParent=*/false);
20458       if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
20459           DVar.RefExpr) {
20460         Diag(ELoc, diag::err_omp_wrong_dsa)
20461             << getOpenMPClauseName(DVar.CKind)
20462             << getOpenMPClauseName(OMPC_copyprivate);
20463         reportOriginalDsa(*this, DSAStack, D, DVar);
20464         continue;
20465       }
20466 
20467       // OpenMP [2.11.4.2, Restrictions, p.1]
20468       //  All list items that appear in a copyprivate clause must be either
20469       //  threadprivate or private in the enclosing context.
20470       if (DVar.CKind == OMPC_unknown) {
20471         DVar = DSAStack->getImplicitDSA(D, false);
20472         if (DVar.CKind == OMPC_shared) {
20473           Diag(ELoc, diag::err_omp_required_access)
20474               << getOpenMPClauseName(OMPC_copyprivate)
20475               << "threadprivate or private in the enclosing context";
20476           reportOriginalDsa(*this, DSAStack, D, DVar);
20477           continue;
20478         }
20479       }
20480     }
20481 
20482     // Variably modified types are not supported.
20483     if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
20484       Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
20485           << getOpenMPClauseName(OMPC_copyprivate) << Type
20486           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
20487       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
20488                                VarDecl::DeclarationOnly;
20489       Diag(D->getLocation(),
20490            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
20491           << D;
20492       continue;
20493     }
20494 
20495     // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
20496     //  A variable of class type (or array thereof) that appears in a
20497     //  copyin clause requires an accessible, unambiguous copy assignment
20498     //  operator for the class type.
20499     Type = Context.getBaseElementType(Type.getNonReferenceType())
20500                .getUnqualifiedType();
20501     VarDecl *SrcVD =
20502         buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
20503                      D->hasAttrs() ? &D->getAttrs() : nullptr);
20504     DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
20505     VarDecl *DstVD =
20506         buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
20507                      D->hasAttrs() ? &D->getAttrs() : nullptr);
20508     DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
20509     ExprResult AssignmentOp = BuildBinOp(
20510         DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
20511     if (AssignmentOp.isInvalid())
20512       continue;
20513     AssignmentOp =
20514         ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
20515     if (AssignmentOp.isInvalid())
20516       continue;
20517 
20518     // No need to mark vars as copyprivate, they are already threadprivate or
20519     // implicitly private.
20520     assert(VD || isOpenMPCapturedDecl(D));
20521     Vars.push_back(
20522         VD ? RefExpr->IgnoreParens()
20523            : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
20524     SrcExprs.push_back(PseudoSrcExpr);
20525     DstExprs.push_back(PseudoDstExpr);
20526     AssignmentOps.push_back(AssignmentOp.get());
20527   }
20528 
20529   if (Vars.empty())
20530     return nullptr;
20531 
20532   return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
20533                                       Vars, SrcExprs, DstExprs, AssignmentOps);
20534 }
20535 
20536 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
20537                                         SourceLocation StartLoc,
20538                                         SourceLocation LParenLoc,
20539                                         SourceLocation EndLoc) {
20540   if (VarList.empty())
20541     return nullptr;
20542 
20543   return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
20544 }
20545 
20546 /// Tries to find omp_depend_t. type.
20547 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack,
20548                            bool Diagnose = true) {
20549   QualType OMPDependT = Stack->getOMPDependT();
20550   if (!OMPDependT.isNull())
20551     return true;
20552   IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t");
20553   ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
20554   if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
20555     if (Diagnose)
20556       S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t";
20557     return false;
20558   }
20559   Stack->setOMPDependT(PT.get());
20560   return true;
20561 }
20562 
20563 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
20564                                          SourceLocation LParenLoc,
20565                                          SourceLocation EndLoc) {
20566   if (!Depobj)
20567     return nullptr;
20568 
20569   bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack);
20570 
20571   // OpenMP 5.0, 2.17.10.1 depobj Construct
20572   // depobj is an lvalue expression of type omp_depend_t.
20573   if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() &&
20574       !Depobj->isInstantiationDependent() &&
20575       !Depobj->containsUnexpandedParameterPack() &&
20576       (OMPDependTFound &&
20577        !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(),
20578                                    /*CompareUnqualified=*/true))) {
20579     Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
20580         << 0 << Depobj->getType() << Depobj->getSourceRange();
20581   }
20582 
20583   if (!Depobj->isLValue()) {
20584     Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
20585         << 1 << Depobj->getSourceRange();
20586   }
20587 
20588   return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj);
20589 }
20590 
20591 namespace {
20592 // Utility struct that gathers the related info for doacross clause.
20593 struct DoacrossDataInfoTy {
20594   // The list of expressions.
20595   SmallVector<Expr *, 8> Vars;
20596   // The OperatorOffset for doacross loop.
20597   DSAStackTy::OperatorOffsetTy OpsOffs;
20598   // The depended loop count.
20599   llvm::APSInt TotalDepCount;
20600 };
20601 } // namespace
20602 static DoacrossDataInfoTy
20603 ProcessOpenMPDoacrossClauseCommon(Sema &SemaRef, bool IsSource,
20604                                   ArrayRef<Expr *> VarList, DSAStackTy *Stack,
20605                                   SourceLocation EndLoc) {
20606 
20607   SmallVector<Expr *, 8> Vars;
20608   DSAStackTy::OperatorOffsetTy OpsOffs;
20609   llvm::APSInt DepCounter(/*BitWidth=*/32);
20610   llvm::APSInt TotalDepCount(/*BitWidth=*/32);
20611 
20612   if (const Expr *OrderedCountExpr =
20613           Stack->getParentOrderedRegionParam().first) {
20614     TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(SemaRef.Context);
20615     TotalDepCount.setIsUnsigned(/*Val=*/true);
20616   }
20617 
20618   for (Expr *RefExpr : VarList) {
20619     assert(RefExpr && "NULL expr in OpenMP doacross clause.");
20620     if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
20621       // It will be analyzed later.
20622       Vars.push_back(RefExpr);
20623       continue;
20624     }
20625 
20626     SourceLocation ELoc = RefExpr->getExprLoc();
20627     Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
20628     if (!IsSource) {
20629       if (Stack->getParentOrderedRegionParam().first &&
20630           DepCounter >= TotalDepCount) {
20631         SemaRef.Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
20632         continue;
20633       }
20634       ++DepCounter;
20635       // OpenMP  [2.13.9, Summary]
20636       // depend(dependence-type : vec), where dependence-type is:
20637       // 'sink' and where vec is the iteration vector, which has the form:
20638       //  x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
20639       // where n is the value specified by the ordered clause in the loop
20640       // directive, xi denotes the loop iteration variable of the i-th nested
20641       // loop associated with the loop directive, and di is a constant
20642       // non-negative integer.
20643       if (SemaRef.CurContext->isDependentContext()) {
20644         // It will be analyzed later.
20645         Vars.push_back(RefExpr);
20646         continue;
20647       }
20648       SimpleExpr = SimpleExpr->IgnoreImplicit();
20649       OverloadedOperatorKind OOK = OO_None;
20650       SourceLocation OOLoc;
20651       Expr *LHS = SimpleExpr;
20652       Expr *RHS = nullptr;
20653       if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
20654         OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
20655         OOLoc = BO->getOperatorLoc();
20656         LHS = BO->getLHS()->IgnoreParenImpCasts();
20657         RHS = BO->getRHS()->IgnoreParenImpCasts();
20658       } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
20659         OOK = OCE->getOperator();
20660         OOLoc = OCE->getOperatorLoc();
20661         LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
20662         RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
20663       } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
20664         OOK = MCE->getMethodDecl()
20665                   ->getNameInfo()
20666                   .getName()
20667                   .getCXXOverloadedOperator();
20668         OOLoc = MCE->getCallee()->getExprLoc();
20669         LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
20670         RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
20671       }
20672       SourceLocation ELoc;
20673       SourceRange ERange;
20674       auto Res = getPrivateItem(SemaRef, LHS, ELoc, ERange);
20675       if (Res.second) {
20676         // It will be analyzed later.
20677         Vars.push_back(RefExpr);
20678       }
20679       ValueDecl *D = Res.first;
20680       if (!D)
20681         continue;
20682 
20683       if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
20684         SemaRef.Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
20685         continue;
20686       }
20687       if (RHS) {
20688         ExprResult RHSRes = SemaRef.VerifyPositiveIntegerConstantInClause(
20689             RHS, OMPC_depend, /*StrictlyPositive=*/false);
20690         if (RHSRes.isInvalid())
20691           continue;
20692       }
20693       if (!SemaRef.CurContext->isDependentContext() &&
20694           Stack->getParentOrderedRegionParam().first &&
20695           DepCounter != Stack->isParentLoopControlVariable(D).first) {
20696         const ValueDecl *VD =
20697             Stack->getParentLoopControlVariable(DepCounter.getZExtValue());
20698         if (VD)
20699           SemaRef.Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
20700               << 1 << VD;
20701         else
20702           SemaRef.Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
20703               << 0;
20704         continue;
20705       }
20706       OpsOffs.emplace_back(RHS, OOK);
20707     }
20708     Vars.push_back(RefExpr->IgnoreParenImpCasts());
20709   }
20710   if (!SemaRef.CurContext->isDependentContext() && !IsSource &&
20711       TotalDepCount > VarList.size() &&
20712       Stack->getParentOrderedRegionParam().first &&
20713       Stack->getParentLoopControlVariable(VarList.size() + 1)) {
20714     SemaRef.Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
20715         << 1 << Stack->getParentLoopControlVariable(VarList.size() + 1);
20716   }
20717   return {Vars, OpsOffs, TotalDepCount};
20718 }
20719 
20720 OMPClause *
20721 Sema::ActOnOpenMPDependClause(const OMPDependClause::DependDataTy &Data,
20722                               Expr *DepModifier, ArrayRef<Expr *> VarList,
20723                               SourceLocation StartLoc, SourceLocation LParenLoc,
20724                               SourceLocation EndLoc) {
20725   OpenMPDependClauseKind DepKind = Data.DepKind;
20726   SourceLocation DepLoc = Data.DepLoc;
20727   if (DSAStack->getCurrentDirective() == OMPD_ordered &&
20728       DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
20729     Diag(DepLoc, diag::err_omp_unexpected_clause_value)
20730         << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
20731     return nullptr;
20732   }
20733   if (DSAStack->getCurrentDirective() == OMPD_taskwait &&
20734       DepKind == OMPC_DEPEND_mutexinoutset) {
20735     Diag(DepLoc, diag::err_omp_taskwait_depend_mutexinoutset_not_allowed);
20736     return nullptr;
20737   }
20738   if ((DSAStack->getCurrentDirective() != OMPD_ordered ||
20739        DSAStack->getCurrentDirective() == OMPD_depobj) &&
20740       (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
20741        DepKind == OMPC_DEPEND_sink ||
20742        ((LangOpts.OpenMP < 50 ||
20743          DSAStack->getCurrentDirective() == OMPD_depobj) &&
20744         DepKind == OMPC_DEPEND_depobj))) {
20745     SmallVector<unsigned, 6> Except = {OMPC_DEPEND_source, OMPC_DEPEND_sink,
20746                                        OMPC_DEPEND_outallmemory,
20747                                        OMPC_DEPEND_inoutallmemory};
20748     if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj)
20749       Except.push_back(OMPC_DEPEND_depobj);
20750     if (LangOpts.OpenMP < 51)
20751       Except.push_back(OMPC_DEPEND_inoutset);
20752     std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier)
20753                                ? "depend modifier(iterator) or "
20754                                : "";
20755     Diag(DepLoc, diag::err_omp_unexpected_clause_value)
20756         << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0,
20757                                               /*Last=*/OMPC_DEPEND_unknown,
20758                                               Except)
20759         << getOpenMPClauseName(OMPC_depend);
20760     return nullptr;
20761   }
20762   if (DepModifier &&
20763       (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) {
20764     Diag(DepModifier->getExprLoc(),
20765          diag::err_omp_depend_sink_source_with_modifier);
20766     return nullptr;
20767   }
20768   if (DepModifier &&
20769       !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator))
20770     Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator);
20771 
20772   SmallVector<Expr *, 8> Vars;
20773   DSAStackTy::OperatorOffsetTy OpsOffs;
20774   llvm::APSInt TotalDepCount(/*BitWidth=*/32);
20775 
20776   if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
20777     DoacrossDataInfoTy VarOffset = ProcessOpenMPDoacrossClauseCommon(
20778         *this, DepKind == OMPC_DEPEND_source, VarList, DSAStack, EndLoc);
20779     Vars = VarOffset.Vars;
20780     OpsOffs = VarOffset.OpsOffs;
20781     TotalDepCount = VarOffset.TotalDepCount;
20782   } else {
20783     for (Expr *RefExpr : VarList) {
20784       assert(RefExpr && "NULL expr in OpenMP shared clause.");
20785       if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
20786         // It will be analyzed later.
20787         Vars.push_back(RefExpr);
20788         continue;
20789       }
20790 
20791       SourceLocation ELoc = RefExpr->getExprLoc();
20792       Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
20793       if (DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) {
20794         bool OMPDependTFound = LangOpts.OpenMP >= 50;
20795         if (OMPDependTFound)
20796           OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack,
20797                                            DepKind == OMPC_DEPEND_depobj);
20798         if (DepKind == OMPC_DEPEND_depobj) {
20799           // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
20800           // List items used in depend clauses with the depobj dependence type
20801           // must be expressions of the omp_depend_t type.
20802           if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
20803               !RefExpr->isInstantiationDependent() &&
20804               !RefExpr->containsUnexpandedParameterPack() &&
20805               (OMPDependTFound &&
20806                !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(),
20807                                                RefExpr->getType()))) {
20808             Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
20809                 << 0 << RefExpr->getType() << RefExpr->getSourceRange();
20810             continue;
20811           }
20812           if (!RefExpr->isLValue()) {
20813             Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
20814                 << 1 << RefExpr->getType() << RefExpr->getSourceRange();
20815             continue;
20816           }
20817         } else {
20818           // OpenMP 5.0 [2.17.11, Restrictions]
20819           // List items used in depend clauses cannot be zero-length array
20820           // sections.
20821           QualType ExprTy = RefExpr->getType().getNonReferenceType();
20822           const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
20823           if (OASE) {
20824             QualType BaseType =
20825                 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
20826             if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
20827               ExprTy = ATy->getElementType();
20828             else
20829               ExprTy = BaseType->getPointeeType();
20830             ExprTy = ExprTy.getNonReferenceType();
20831             const Expr *Length = OASE->getLength();
20832             Expr::EvalResult Result;
20833             if (Length && !Length->isValueDependent() &&
20834                 Length->EvaluateAsInt(Result, Context) &&
20835                 Result.Val.getInt().isZero()) {
20836               Diag(ELoc,
20837                    diag::err_omp_depend_zero_length_array_section_not_allowed)
20838                   << SimpleExpr->getSourceRange();
20839               continue;
20840             }
20841           }
20842 
20843           // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
20844           // List items used in depend clauses with the in, out, inout,
20845           // inoutset, or mutexinoutset dependence types cannot be
20846           // expressions of the omp_depend_t type.
20847           if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
20848               !RefExpr->isInstantiationDependent() &&
20849               !RefExpr->containsUnexpandedParameterPack() &&
20850               (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
20851                (OMPDependTFound && DSAStack->getOMPDependT().getTypePtr() ==
20852                                        ExprTy.getTypePtr()))) {
20853             Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
20854                 << (LangOpts.OpenMP >= 50 ? 1 : 0)
20855                 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
20856             continue;
20857           }
20858 
20859           auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
20860           if (ASE && !ASE->getBase()->isTypeDependent() &&
20861               !ASE->getBase()
20862                    ->getType()
20863                    .getNonReferenceType()
20864                    ->isPointerType() &&
20865               !ASE->getBase()->getType().getNonReferenceType()->isArrayType()) {
20866             Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
20867                 << (LangOpts.OpenMP >= 50 ? 1 : 0)
20868                 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
20869             continue;
20870           }
20871 
20872           ExprResult Res;
20873           {
20874             Sema::TentativeAnalysisScope Trap(*this);
20875             Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
20876                                        RefExpr->IgnoreParenImpCasts());
20877           }
20878           if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
20879               !isa<OMPArrayShapingExpr>(SimpleExpr)) {
20880             Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
20881                 << (LangOpts.OpenMP >= 50 ? 1 : 0)
20882                 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
20883             continue;
20884           }
20885         }
20886       }
20887       Vars.push_back(RefExpr->IgnoreParenImpCasts());
20888     }
20889   }
20890 
20891   if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
20892       DepKind != OMPC_DEPEND_outallmemory &&
20893       DepKind != OMPC_DEPEND_inoutallmemory && Vars.empty())
20894     return nullptr;
20895 
20896   auto *C = OMPDependClause::Create(
20897       Context, StartLoc, LParenLoc, EndLoc,
20898       {DepKind, DepLoc, Data.ColonLoc, Data.OmpAllMemoryLoc}, DepModifier, Vars,
20899       TotalDepCount.getZExtValue());
20900   if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
20901       DSAStack->isParentOrderedRegion())
20902     DSAStack->addDoacrossDependClause(C, OpsOffs);
20903   return C;
20904 }
20905 
20906 OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
20907                                          Expr *Device, SourceLocation StartLoc,
20908                                          SourceLocation LParenLoc,
20909                                          SourceLocation ModifierLoc,
20910                                          SourceLocation EndLoc) {
20911   assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) &&
20912          "Unexpected device modifier in OpenMP < 50.");
20913 
20914   bool ErrorFound = false;
20915   if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) {
20916     std::string Values =
20917         getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown);
20918     Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
20919         << Values << getOpenMPClauseName(OMPC_device);
20920     ErrorFound = true;
20921   }
20922 
20923   Expr *ValExpr = Device;
20924   Stmt *HelperValStmt = nullptr;
20925 
20926   // OpenMP [2.9.1, Restrictions]
20927   // The device expression must evaluate to a non-negative integer value.
20928   ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
20929                                           /*StrictlyPositive=*/false) ||
20930                ErrorFound;
20931   if (ErrorFound)
20932     return nullptr;
20933 
20934   // OpenMP 5.0 [2.12.5, Restrictions]
20935   // In case of ancestor device-modifier, a requires directive with
20936   // the reverse_offload clause must be specified.
20937   if (Modifier == OMPC_DEVICE_ancestor) {
20938     if (!DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>()) {
20939       targetDiag(
20940           StartLoc,
20941           diag::err_omp_device_ancestor_without_requires_reverse_offload);
20942       ErrorFound = true;
20943     }
20944   }
20945 
20946   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
20947   OpenMPDirectiveKind CaptureRegion =
20948       getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP);
20949   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
20950     ValExpr = MakeFullExpr(ValExpr).get();
20951     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
20952     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
20953     HelperValStmt = buildPreInits(Context, Captures);
20954   }
20955 
20956   return new (Context)
20957       OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
20958                       LParenLoc, ModifierLoc, EndLoc);
20959 }
20960 
20961 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
20962                               DSAStackTy *Stack, QualType QTy,
20963                               bool FullCheck = true) {
20964   if (SemaRef.RequireCompleteType(SL, QTy, diag::err_incomplete_type))
20965     return false;
20966   if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
20967       !QTy.isTriviallyCopyableType(SemaRef.Context))
20968     SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
20969   return true;
20970 }
20971 
20972 /// Return true if it can be proven that the provided array expression
20973 /// (array section or array subscript) does NOT specify the whole size of the
20974 /// array whose base type is \a BaseQTy.
20975 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
20976                                                         const Expr *E,
20977                                                         QualType BaseQTy) {
20978   const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
20979 
20980   // If this is an array subscript, it refers to the whole size if the size of
20981   // the dimension is constant and equals 1. Also, an array section assumes the
20982   // format of an array subscript if no colon is used.
20983   if (isa<ArraySubscriptExpr>(E) ||
20984       (OASE && OASE->getColonLocFirst().isInvalid())) {
20985     if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
20986       return ATy->getSize().getSExtValue() != 1;
20987     // Size can't be evaluated statically.
20988     return false;
20989   }
20990 
20991   assert(OASE && "Expecting array section if not an array subscript.");
20992   const Expr *LowerBound = OASE->getLowerBound();
20993   const Expr *Length = OASE->getLength();
20994 
20995   // If there is a lower bound that does not evaluates to zero, we are not
20996   // covering the whole dimension.
20997   if (LowerBound) {
20998     Expr::EvalResult Result;
20999     if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
21000       return false; // Can't get the integer value as a constant.
21001 
21002     llvm::APSInt ConstLowerBound = Result.Val.getInt();
21003     if (ConstLowerBound.getSExtValue())
21004       return true;
21005   }
21006 
21007   // If we don't have a length we covering the whole dimension.
21008   if (!Length)
21009     return false;
21010 
21011   // If the base is a pointer, we don't have a way to get the size of the
21012   // pointee.
21013   if (BaseQTy->isPointerType())
21014     return false;
21015 
21016   // We can only check if the length is the same as the size of the dimension
21017   // if we have a constant array.
21018   const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
21019   if (!CATy)
21020     return false;
21021 
21022   Expr::EvalResult Result;
21023   if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
21024     return false; // Can't get the integer value as a constant.
21025 
21026   llvm::APSInt ConstLength = Result.Val.getInt();
21027   return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
21028 }
21029 
21030 // Return true if it can be proven that the provided array expression (array
21031 // section or array subscript) does NOT specify a single element of the array
21032 // whose base type is \a BaseQTy.
21033 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
21034                                                         const Expr *E,
21035                                                         QualType BaseQTy) {
21036   const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
21037 
21038   // An array subscript always refer to a single element. Also, an array section
21039   // assumes the format of an array subscript if no colon is used.
21040   if (isa<ArraySubscriptExpr>(E) ||
21041       (OASE && OASE->getColonLocFirst().isInvalid()))
21042     return false;
21043 
21044   assert(OASE && "Expecting array section if not an array subscript.");
21045   const Expr *Length = OASE->getLength();
21046 
21047   // If we don't have a length we have to check if the array has unitary size
21048   // for this dimension. Also, we should always expect a length if the base type
21049   // is pointer.
21050   if (!Length) {
21051     if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
21052       return ATy->getSize().getSExtValue() != 1;
21053     // We cannot assume anything.
21054     return false;
21055   }
21056 
21057   // Check if the length evaluates to 1.
21058   Expr::EvalResult Result;
21059   if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
21060     return false; // Can't get the integer value as a constant.
21061 
21062   llvm::APSInt ConstLength = Result.Val.getInt();
21063   return ConstLength.getSExtValue() != 1;
21064 }
21065 
21066 // The base of elements of list in a map clause have to be either:
21067 //  - a reference to variable or field.
21068 //  - a member expression.
21069 //  - an array expression.
21070 //
21071 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
21072 // reference to 'r'.
21073 //
21074 // If we have:
21075 //
21076 // struct SS {
21077 //   Bla S;
21078 //   foo() {
21079 //     #pragma omp target map (S.Arr[:12]);
21080 //   }
21081 // }
21082 //
21083 // We want to retrieve the member expression 'this->S';
21084 
21085 // OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2]
21086 //  If a list item is an array section, it must specify contiguous storage.
21087 //
21088 // For this restriction it is sufficient that we make sure only references
21089 // to variables or fields and array expressions, and that no array sections
21090 // exist except in the rightmost expression (unless they cover the whole
21091 // dimension of the array). E.g. these would be invalid:
21092 //
21093 //   r.ArrS[3:5].Arr[6:7]
21094 //
21095 //   r.ArrS[3:5].x
21096 //
21097 // but these would be valid:
21098 //   r.ArrS[3].Arr[6:7]
21099 //
21100 //   r.ArrS[3].x
21101 namespace {
21102 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> {
21103   Sema &SemaRef;
21104   OpenMPClauseKind CKind = OMPC_unknown;
21105   OpenMPDirectiveKind DKind = OMPD_unknown;
21106   OMPClauseMappableExprCommon::MappableExprComponentList &Components;
21107   bool IsNonContiguous = false;
21108   bool NoDiagnose = false;
21109   const Expr *RelevantExpr = nullptr;
21110   bool AllowUnitySizeArraySection = true;
21111   bool AllowWholeSizeArraySection = true;
21112   bool AllowAnotherPtr = true;
21113   SourceLocation ELoc;
21114   SourceRange ERange;
21115 
21116   void emitErrorMsg() {
21117     // If nothing else worked, this is not a valid map clause expression.
21118     if (SemaRef.getLangOpts().OpenMP < 50) {
21119       SemaRef.Diag(ELoc,
21120                    diag::err_omp_expected_named_var_member_or_array_expression)
21121           << ERange;
21122     } else {
21123       SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
21124           << getOpenMPClauseName(CKind) << ERange;
21125     }
21126   }
21127 
21128 public:
21129   bool VisitDeclRefExpr(DeclRefExpr *DRE) {
21130     if (!isa<VarDecl>(DRE->getDecl())) {
21131       emitErrorMsg();
21132       return false;
21133     }
21134     assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21135     RelevantExpr = DRE;
21136     // Record the component.
21137     Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous);
21138     return true;
21139   }
21140 
21141   bool VisitMemberExpr(MemberExpr *ME) {
21142     Expr *E = ME;
21143     Expr *BaseE = ME->getBase()->IgnoreParenCasts();
21144 
21145     if (isa<CXXThisExpr>(BaseE)) {
21146       assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21147       // We found a base expression: this->Val.
21148       RelevantExpr = ME;
21149     } else {
21150       E = BaseE;
21151     }
21152 
21153     if (!isa<FieldDecl>(ME->getMemberDecl())) {
21154       if (!NoDiagnose) {
21155         SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
21156             << ME->getSourceRange();
21157         return false;
21158       }
21159       if (RelevantExpr)
21160         return false;
21161       return Visit(E);
21162     }
21163 
21164     auto *FD = cast<FieldDecl>(ME->getMemberDecl());
21165 
21166     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
21167     //  A bit-field cannot appear in a map clause.
21168     //
21169     if (FD->isBitField()) {
21170       if (!NoDiagnose) {
21171         SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
21172             << ME->getSourceRange() << getOpenMPClauseName(CKind);
21173         return false;
21174       }
21175       if (RelevantExpr)
21176         return false;
21177       return Visit(E);
21178     }
21179 
21180     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
21181     //  If the type of a list item is a reference to a type T then the type
21182     //  will be considered to be T for all purposes of this clause.
21183     QualType CurType = BaseE->getType().getNonReferenceType();
21184 
21185     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
21186     //  A list item cannot be a variable that is a member of a structure with
21187     //  a union type.
21188     //
21189     if (CurType->isUnionType()) {
21190       if (!NoDiagnose) {
21191         SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
21192             << ME->getSourceRange();
21193         return false;
21194       }
21195       return RelevantExpr || Visit(E);
21196     }
21197 
21198     // If we got a member expression, we should not expect any array section
21199     // before that:
21200     //
21201     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
21202     //  If a list item is an element of a structure, only the rightmost symbol
21203     //  of the variable reference can be an array section.
21204     //
21205     AllowUnitySizeArraySection = false;
21206     AllowWholeSizeArraySection = false;
21207 
21208     // Record the component.
21209     Components.emplace_back(ME, FD, IsNonContiguous);
21210     return RelevantExpr || Visit(E);
21211   }
21212 
21213   bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) {
21214     Expr *E = AE->getBase()->IgnoreParenImpCasts();
21215 
21216     if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
21217       if (!NoDiagnose) {
21218         SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
21219             << 0 << AE->getSourceRange();
21220         return false;
21221       }
21222       return RelevantExpr || Visit(E);
21223     }
21224 
21225     // If we got an array subscript that express the whole dimension we
21226     // can have any array expressions before. If it only expressing part of
21227     // the dimension, we can only have unitary-size array expressions.
21228     if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, E->getType()))
21229       AllowWholeSizeArraySection = false;
21230 
21231     if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) {
21232       Expr::EvalResult Result;
21233       if (!AE->getIdx()->isValueDependent() &&
21234           AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) &&
21235           !Result.Val.getInt().isZero()) {
21236         SemaRef.Diag(AE->getIdx()->getExprLoc(),
21237                      diag::err_omp_invalid_map_this_expr);
21238         SemaRef.Diag(AE->getIdx()->getExprLoc(),
21239                      diag::note_omp_invalid_subscript_on_this_ptr_map);
21240       }
21241       assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21242       RelevantExpr = TE;
21243     }
21244 
21245     // Record the component - we don't have any declaration associated.
21246     Components.emplace_back(AE, nullptr, IsNonContiguous);
21247 
21248     return RelevantExpr || Visit(E);
21249   }
21250 
21251   bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) {
21252     // After OMP 5.0  Array section in reduction clause will be implicitly
21253     // mapped
21254     assert(!(SemaRef.getLangOpts().OpenMP < 50 && NoDiagnose) &&
21255            "Array sections cannot be implicitly mapped.");
21256     Expr *E = OASE->getBase()->IgnoreParenImpCasts();
21257     QualType CurType =
21258         OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
21259 
21260     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
21261     //  If the type of a list item is a reference to a type T then the type
21262     //  will be considered to be T for all purposes of this clause.
21263     if (CurType->isReferenceType())
21264       CurType = CurType->getPointeeType();
21265 
21266     bool IsPointer = CurType->isAnyPointerType();
21267 
21268     if (!IsPointer && !CurType->isArrayType()) {
21269       SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
21270           << 0 << OASE->getSourceRange();
21271       return false;
21272     }
21273 
21274     bool NotWhole =
21275         checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType);
21276     bool NotUnity =
21277         checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType);
21278 
21279     if (AllowWholeSizeArraySection) {
21280       // Any array section is currently allowed. Allowing a whole size array
21281       // section implies allowing a unity array section as well.
21282       //
21283       // If this array section refers to the whole dimension we can still
21284       // accept other array sections before this one, except if the base is a
21285       // pointer. Otherwise, only unitary sections are accepted.
21286       if (NotWhole || IsPointer)
21287         AllowWholeSizeArraySection = false;
21288     } else if (DKind == OMPD_target_update &&
21289                SemaRef.getLangOpts().OpenMP >= 50) {
21290       if (IsPointer && !AllowAnotherPtr)
21291         SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined)
21292             << /*array of unknown bound */ 1;
21293       else
21294         IsNonContiguous = true;
21295     } else if (AllowUnitySizeArraySection && NotUnity) {
21296       // A unity or whole array section is not allowed and that is not
21297       // compatible with the properties of the current array section.
21298       if (NoDiagnose)
21299         return false;
21300       SemaRef.Diag(ELoc,
21301                    diag::err_array_section_does_not_specify_contiguous_storage)
21302           << OASE->getSourceRange();
21303       return false;
21304     }
21305 
21306     if (IsPointer)
21307       AllowAnotherPtr = false;
21308 
21309     if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
21310       Expr::EvalResult ResultR;
21311       Expr::EvalResult ResultL;
21312       if (!OASE->getLength()->isValueDependent() &&
21313           OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) &&
21314           !ResultR.Val.getInt().isOne()) {
21315         SemaRef.Diag(OASE->getLength()->getExprLoc(),
21316                      diag::err_omp_invalid_map_this_expr);
21317         SemaRef.Diag(OASE->getLength()->getExprLoc(),
21318                      diag::note_omp_invalid_length_on_this_ptr_mapping);
21319       }
21320       if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() &&
21321           OASE->getLowerBound()->EvaluateAsInt(ResultL,
21322                                                SemaRef.getASTContext()) &&
21323           !ResultL.Val.getInt().isZero()) {
21324         SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
21325                      diag::err_omp_invalid_map_this_expr);
21326         SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
21327                      diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
21328       }
21329       assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21330       RelevantExpr = TE;
21331     }
21332 
21333     // Record the component - we don't have any declaration associated.
21334     Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false);
21335     return RelevantExpr || Visit(E);
21336   }
21337   bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
21338     Expr *Base = E->getBase();
21339 
21340     // Record the component - we don't have any declaration associated.
21341     Components.emplace_back(E, nullptr, IsNonContiguous);
21342 
21343     return Visit(Base->IgnoreParenImpCasts());
21344   }
21345 
21346   bool VisitUnaryOperator(UnaryOperator *UO) {
21347     if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() ||
21348         UO->getOpcode() != UO_Deref) {
21349       emitErrorMsg();
21350       return false;
21351     }
21352     if (!RelevantExpr) {
21353       // Record the component if haven't found base decl.
21354       Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false);
21355     }
21356     return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts());
21357   }
21358   bool VisitBinaryOperator(BinaryOperator *BO) {
21359     if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) {
21360       emitErrorMsg();
21361       return false;
21362     }
21363 
21364     // Pointer arithmetic is the only thing we expect to happen here so after we
21365     // make sure the binary operator is a pointer type, the only thing we need
21366     // to do is to visit the subtree that has the same type as root (so that we
21367     // know the other subtree is just an offset)
21368     Expr *LE = BO->getLHS()->IgnoreParenImpCasts();
21369     Expr *RE = BO->getRHS()->IgnoreParenImpCasts();
21370     Components.emplace_back(BO, nullptr, false);
21371     assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() ||
21372             RE->getType().getTypePtr() == BO->getType().getTypePtr()) &&
21373            "Either LHS or RHS have base decl inside");
21374     if (BO->getType().getTypePtr() == LE->getType().getTypePtr())
21375       return RelevantExpr || Visit(LE);
21376     return RelevantExpr || Visit(RE);
21377   }
21378   bool VisitCXXThisExpr(CXXThisExpr *CTE) {
21379     assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21380     RelevantExpr = CTE;
21381     Components.emplace_back(CTE, nullptr, IsNonContiguous);
21382     return true;
21383   }
21384   bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) {
21385     assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21386     Components.emplace_back(COCE, nullptr, IsNonContiguous);
21387     return true;
21388   }
21389   bool VisitOpaqueValueExpr(OpaqueValueExpr *E) {
21390     Expr *Source = E->getSourceExpr();
21391     if (!Source) {
21392       emitErrorMsg();
21393       return false;
21394     }
21395     return Visit(Source);
21396   }
21397   bool VisitStmt(Stmt *) {
21398     emitErrorMsg();
21399     return false;
21400   }
21401   const Expr *getFoundBase() const { return RelevantExpr; }
21402   explicit MapBaseChecker(
21403       Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind,
21404       OMPClauseMappableExprCommon::MappableExprComponentList &Components,
21405       bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange)
21406       : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components),
21407         NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
21408 };
21409 } // namespace
21410 
21411 /// Return the expression of the base of the mappable expression or null if it
21412 /// cannot be determined and do all the necessary checks to see if the
21413 /// expression is valid as a standalone mappable expression. In the process,
21414 /// record all the components of the expression.
21415 static const Expr *checkMapClauseExpressionBase(
21416     Sema &SemaRef, Expr *E,
21417     OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
21418     OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) {
21419   SourceLocation ELoc = E->getExprLoc();
21420   SourceRange ERange = E->getSourceRange();
21421   MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc,
21422                          ERange);
21423   if (Checker.Visit(E->IgnoreParens())) {
21424     // Check if the highest dimension array section has length specified
21425     if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() &&
21426         (CKind == OMPC_to || CKind == OMPC_from)) {
21427       auto CI = CurComponents.rbegin();
21428       auto CE = CurComponents.rend();
21429       for (; CI != CE; ++CI) {
21430         const auto *OASE =
21431             dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression());
21432         if (!OASE)
21433           continue;
21434         if (OASE && OASE->getLength())
21435           break;
21436         SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length)
21437             << ERange;
21438       }
21439     }
21440     return Checker.getFoundBase();
21441   }
21442   return nullptr;
21443 }
21444 
21445 // Return true if expression E associated with value VD has conflicts with other
21446 // map information.
21447 static bool checkMapConflicts(
21448     Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
21449     bool CurrentRegionOnly,
21450     OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
21451     OpenMPClauseKind CKind) {
21452   assert(VD && E);
21453   SourceLocation ELoc = E->getExprLoc();
21454   SourceRange ERange = E->getSourceRange();
21455 
21456   // In order to easily check the conflicts we need to match each component of
21457   // the expression under test with the components of the expressions that are
21458   // already in the stack.
21459 
21460   assert(!CurComponents.empty() && "Map clause expression with no components!");
21461   assert(CurComponents.back().getAssociatedDeclaration() == VD &&
21462          "Map clause expression with unexpected base!");
21463 
21464   // Variables to help detecting enclosing problems in data environment nests.
21465   bool IsEnclosedByDataEnvironmentExpr = false;
21466   const Expr *EnclosingExpr = nullptr;
21467 
21468   bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
21469       VD, CurrentRegionOnly,
21470       [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
21471        ERange, CKind, &EnclosingExpr,
21472        CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef
21473                           StackComponents,
21474                       OpenMPClauseKind Kind) {
21475         if (CKind == Kind && SemaRef.LangOpts.OpenMP >= 50)
21476           return false;
21477         assert(!StackComponents.empty() &&
21478                "Map clause expression with no components!");
21479         assert(StackComponents.back().getAssociatedDeclaration() == VD &&
21480                "Map clause expression with unexpected base!");
21481         (void)VD;
21482 
21483         // The whole expression in the stack.
21484         const Expr *RE = StackComponents.front().getAssociatedExpression();
21485 
21486         // Expressions must start from the same base. Here we detect at which
21487         // point both expressions diverge from each other and see if we can
21488         // detect if the memory referred to both expressions is contiguous and
21489         // do not overlap.
21490         auto CI = CurComponents.rbegin();
21491         auto CE = CurComponents.rend();
21492         auto SI = StackComponents.rbegin();
21493         auto SE = StackComponents.rend();
21494         for (; CI != CE && SI != SE; ++CI, ++SI) {
21495 
21496           // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
21497           //  At most one list item can be an array item derived from a given
21498           //  variable in map clauses of the same construct.
21499           if (CurrentRegionOnly &&
21500               (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
21501                isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) ||
21502                isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) &&
21503               (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
21504                isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) ||
21505                isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) {
21506             SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
21507                          diag::err_omp_multiple_array_items_in_map_clause)
21508                 << CI->getAssociatedExpression()->getSourceRange();
21509             SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
21510                          diag::note_used_here)
21511                 << SI->getAssociatedExpression()->getSourceRange();
21512             return true;
21513           }
21514 
21515           // Do both expressions have the same kind?
21516           if (CI->getAssociatedExpression()->getStmtClass() !=
21517               SI->getAssociatedExpression()->getStmtClass())
21518             break;
21519 
21520           // Are we dealing with different variables/fields?
21521           if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
21522             break;
21523         }
21524         // Check if the extra components of the expressions in the enclosing
21525         // data environment are redundant for the current base declaration.
21526         // If they are, the maps completely overlap, which is legal.
21527         for (; SI != SE; ++SI) {
21528           QualType Type;
21529           if (const auto *ASE =
21530                   dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
21531             Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
21532           } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
21533                          SI->getAssociatedExpression())) {
21534             const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
21535             Type =
21536                 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
21537           } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>(
21538                          SI->getAssociatedExpression())) {
21539             Type = OASE->getBase()->getType()->getPointeeType();
21540           }
21541           if (Type.isNull() || Type->isAnyPointerType() ||
21542               checkArrayExpressionDoesNotReferToWholeSize(
21543                   SemaRef, SI->getAssociatedExpression(), Type))
21544             break;
21545         }
21546 
21547         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
21548         //  List items of map clauses in the same construct must not share
21549         //  original storage.
21550         //
21551         // If the expressions are exactly the same or one is a subset of the
21552         // other, it means they are sharing storage.
21553         if (CI == CE && SI == SE) {
21554           if (CurrentRegionOnly) {
21555             if (CKind == OMPC_map) {
21556               SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
21557             } else {
21558               assert(CKind == OMPC_to || CKind == OMPC_from);
21559               SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
21560                   << ERange;
21561             }
21562             SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
21563                 << RE->getSourceRange();
21564             return true;
21565           }
21566           // If we find the same expression in the enclosing data environment,
21567           // that is legal.
21568           IsEnclosedByDataEnvironmentExpr = true;
21569           return false;
21570         }
21571 
21572         QualType DerivedType =
21573             std::prev(CI)->getAssociatedDeclaration()->getType();
21574         SourceLocation DerivedLoc =
21575             std::prev(CI)->getAssociatedExpression()->getExprLoc();
21576 
21577         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
21578         //  If the type of a list item is a reference to a type T then the type
21579         //  will be considered to be T for all purposes of this clause.
21580         DerivedType = DerivedType.getNonReferenceType();
21581 
21582         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
21583         //  A variable for which the type is pointer and an array section
21584         //  derived from that variable must not appear as list items of map
21585         //  clauses of the same construct.
21586         //
21587         // Also, cover one of the cases in:
21588         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
21589         //  If any part of the original storage of a list item has corresponding
21590         //  storage in the device data environment, all of the original storage
21591         //  must have corresponding storage in the device data environment.
21592         //
21593         if (DerivedType->isAnyPointerType()) {
21594           if (CI == CE || SI == SE) {
21595             SemaRef.Diag(
21596                 DerivedLoc,
21597                 diag::err_omp_pointer_mapped_along_with_derived_section)
21598                 << DerivedLoc;
21599             SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
21600                 << RE->getSourceRange();
21601             return true;
21602           }
21603           if (CI->getAssociatedExpression()->getStmtClass() !=
21604                   SI->getAssociatedExpression()->getStmtClass() ||
21605               CI->getAssociatedDeclaration()->getCanonicalDecl() ==
21606                   SI->getAssociatedDeclaration()->getCanonicalDecl()) {
21607             assert(CI != CE && SI != SE);
21608             SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
21609                 << DerivedLoc;
21610             SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
21611                 << RE->getSourceRange();
21612             return true;
21613           }
21614         }
21615 
21616         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
21617         //  List items of map clauses in the same construct must not share
21618         //  original storage.
21619         //
21620         // An expression is a subset of the other.
21621         if (CurrentRegionOnly && (CI == CE || SI == SE)) {
21622           if (CKind == OMPC_map) {
21623             if (CI != CE || SI != SE) {
21624               // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
21625               // a pointer.
21626               auto Begin =
21627                   CI != CE ? CurComponents.begin() : StackComponents.begin();
21628               auto End = CI != CE ? CurComponents.end() : StackComponents.end();
21629               auto It = Begin;
21630               while (It != End && !It->getAssociatedDeclaration())
21631                 std::advance(It, 1);
21632               assert(It != End &&
21633                      "Expected at least one component with the declaration.");
21634               if (It != Begin && It->getAssociatedDeclaration()
21635                                      ->getType()
21636                                      .getCanonicalType()
21637                                      ->isAnyPointerType()) {
21638                 IsEnclosedByDataEnvironmentExpr = false;
21639                 EnclosingExpr = nullptr;
21640                 return false;
21641               }
21642             }
21643             SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
21644           } else {
21645             assert(CKind == OMPC_to || CKind == OMPC_from);
21646             SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
21647                 << ERange;
21648           }
21649           SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
21650               << RE->getSourceRange();
21651           return true;
21652         }
21653 
21654         // The current expression uses the same base as other expression in the
21655         // data environment but does not contain it completely.
21656         if (!CurrentRegionOnly && SI != SE)
21657           EnclosingExpr = RE;
21658 
21659         // The current expression is a subset of the expression in the data
21660         // environment.
21661         IsEnclosedByDataEnvironmentExpr |=
21662             (!CurrentRegionOnly && CI != CE && SI == SE);
21663 
21664         return false;
21665       });
21666 
21667   if (CurrentRegionOnly)
21668     return FoundError;
21669 
21670   // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
21671   //  If any part of the original storage of a list item has corresponding
21672   //  storage in the device data environment, all of the original storage must
21673   //  have corresponding storage in the device data environment.
21674   // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
21675   //  If a list item is an element of a structure, and a different element of
21676   //  the structure has a corresponding list item in the device data environment
21677   //  prior to a task encountering the construct associated with the map clause,
21678   //  then the list item must also have a corresponding list item in the device
21679   //  data environment prior to the task encountering the construct.
21680   //
21681   if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
21682     SemaRef.Diag(ELoc,
21683                  diag::err_omp_original_storage_is_shared_and_does_not_contain)
21684         << ERange;
21685     SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
21686         << EnclosingExpr->getSourceRange();
21687     return true;
21688   }
21689 
21690   return FoundError;
21691 }
21692 
21693 // Look up the user-defined mapper given the mapper name and mapped type, and
21694 // build a reference to it.
21695 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
21696                                             CXXScopeSpec &MapperIdScopeSpec,
21697                                             const DeclarationNameInfo &MapperId,
21698                                             QualType Type,
21699                                             Expr *UnresolvedMapper) {
21700   if (MapperIdScopeSpec.isInvalid())
21701     return ExprError();
21702   // Get the actual type for the array type.
21703   if (Type->isArrayType()) {
21704     assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type");
21705     Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType();
21706   }
21707   // Find all user-defined mappers with the given MapperId.
21708   SmallVector<UnresolvedSet<8>, 4> Lookups;
21709   LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
21710   Lookup.suppressDiagnostics();
21711   if (S) {
21712     while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) {
21713       NamedDecl *D = Lookup.getRepresentativeDecl();
21714       while (S && !S->isDeclScope(D))
21715         S = S->getParent();
21716       if (S)
21717         S = S->getParent();
21718       Lookups.emplace_back();
21719       Lookups.back().append(Lookup.begin(), Lookup.end());
21720       Lookup.clear();
21721     }
21722   } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
21723     // Extract the user-defined mappers with the given MapperId.
21724     Lookups.push_back(UnresolvedSet<8>());
21725     for (NamedDecl *D : ULE->decls()) {
21726       auto *DMD = cast<OMPDeclareMapperDecl>(D);
21727       assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation.");
21728       Lookups.back().addDecl(DMD);
21729     }
21730   }
21731   // Defer the lookup for dependent types. The results will be passed through
21732   // UnresolvedMapper on instantiation.
21733   if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
21734       Type->isInstantiationDependentType() ||
21735       Type->containsUnexpandedParameterPack() ||
21736       filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
21737         return !D->isInvalidDecl() &&
21738                (D->getType()->isDependentType() ||
21739                 D->getType()->isInstantiationDependentType() ||
21740                 D->getType()->containsUnexpandedParameterPack());
21741       })) {
21742     UnresolvedSet<8> URS;
21743     for (const UnresolvedSet<8> &Set : Lookups) {
21744       if (Set.empty())
21745         continue;
21746       URS.append(Set.begin(), Set.end());
21747     }
21748     return UnresolvedLookupExpr::Create(
21749         SemaRef.Context, /*NamingClass=*/nullptr,
21750         MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
21751         /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end());
21752   }
21753   SourceLocation Loc = MapperId.getLoc();
21754   // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
21755   //  The type must be of struct, union or class type in C and C++
21756   if (!Type->isStructureOrClassType() && !Type->isUnionType() &&
21757       (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) {
21758     SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type);
21759     return ExprError();
21760   }
21761   // Perform argument dependent lookup.
21762   if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
21763     argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
21764   // Return the first user-defined mapper with the desired type.
21765   if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
21766           Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
21767             if (!D->isInvalidDecl() &&
21768                 SemaRef.Context.hasSameType(D->getType(), Type))
21769               return D;
21770             return nullptr;
21771           }))
21772     return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
21773   // Find the first user-defined mapper with a type derived from the desired
21774   // type.
21775   if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
21776           Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
21777             if (!D->isInvalidDecl() &&
21778                 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
21779                 !Type.isMoreQualifiedThan(D->getType()))
21780               return D;
21781             return nullptr;
21782           })) {
21783     CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
21784                        /*DetectVirtual=*/false);
21785     if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
21786       if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
21787               VD->getType().getUnqualifiedType()))) {
21788         if (SemaRef.CheckBaseClassAccess(
21789                 Loc, VD->getType(), Type, Paths.front(),
21790                 /*DiagID=*/0) != Sema::AR_inaccessible) {
21791           return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
21792         }
21793       }
21794     }
21795   }
21796   // Report error if a mapper is specified, but cannot be found.
21797   if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
21798     SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
21799         << Type << MapperId.getName();
21800     return ExprError();
21801   }
21802   return ExprEmpty();
21803 }
21804 
21805 namespace {
21806 // Utility struct that gathers all the related lists associated with a mappable
21807 // expression.
21808 struct MappableVarListInfo {
21809   // The list of expressions.
21810   ArrayRef<Expr *> VarList;
21811   // The list of processed expressions.
21812   SmallVector<Expr *, 16> ProcessedVarList;
21813   // The mappble components for each expression.
21814   OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
21815   // The base declaration of the variable.
21816   SmallVector<ValueDecl *, 16> VarBaseDeclarations;
21817   // The reference to the user-defined mapper associated with every expression.
21818   SmallVector<Expr *, 16> UDMapperList;
21819 
21820   MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
21821     // We have a list of components and base declarations for each entry in the
21822     // variable list.
21823     VarComponents.reserve(VarList.size());
21824     VarBaseDeclarations.reserve(VarList.size());
21825   }
21826 };
21827 } // namespace
21828 
21829 // Check the validity of the provided variable list for the provided clause kind
21830 // \a CKind. In the check process the valid expressions, mappable expression
21831 // components, variables, and user-defined mappers are extracted and used to
21832 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
21833 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
21834 // and \a MapperId are expected to be valid if the clause kind is 'map'.
21835 static void checkMappableExpressionList(
21836     Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
21837     MappableVarListInfo &MVLI, SourceLocation StartLoc,
21838     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
21839     ArrayRef<Expr *> UnresolvedMappers,
21840     OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
21841     ArrayRef<OpenMPMapModifierKind> Modifiers = std::nullopt,
21842     bool IsMapTypeImplicit = false, bool NoDiagnose = false) {
21843   // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
21844   assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
21845          "Unexpected clause kind with mappable expressions!");
21846 
21847   // If the identifier of user-defined mapper is not specified, it is "default".
21848   // We do not change the actual name in this clause to distinguish whether a
21849   // mapper is specified explicitly, i.e., it is not explicitly specified when
21850   // MapperId.getName() is empty.
21851   if (!MapperId.getName() || MapperId.getName().isEmpty()) {
21852     auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
21853     MapperId.setName(DeclNames.getIdentifier(
21854         &SemaRef.getASTContext().Idents.get("default")));
21855     MapperId.setLoc(StartLoc);
21856   }
21857 
21858   // Iterators to find the current unresolved mapper expression.
21859   auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
21860   bool UpdateUMIt = false;
21861   Expr *UnresolvedMapper = nullptr;
21862 
21863   bool HasHoldModifier =
21864       llvm::is_contained(Modifiers, OMPC_MAP_MODIFIER_ompx_hold);
21865 
21866   // Keep track of the mappable components and base declarations in this clause.
21867   // Each entry in the list is going to have a list of components associated. We
21868   // record each set of the components so that we can build the clause later on.
21869   // In the end we should have the same amount of declarations and component
21870   // lists.
21871 
21872   for (Expr *RE : MVLI.VarList) {
21873     assert(RE && "Null expr in omp to/from/map clause");
21874     SourceLocation ELoc = RE->getExprLoc();
21875 
21876     // Find the current unresolved mapper expression.
21877     if (UpdateUMIt && UMIt != UMEnd) {
21878       UMIt++;
21879       assert(
21880           UMIt != UMEnd &&
21881           "Expect the size of UnresolvedMappers to match with that of VarList");
21882     }
21883     UpdateUMIt = true;
21884     if (UMIt != UMEnd)
21885       UnresolvedMapper = *UMIt;
21886 
21887     const Expr *VE = RE->IgnoreParenLValueCasts();
21888 
21889     if (VE->isValueDependent() || VE->isTypeDependent() ||
21890         VE->isInstantiationDependent() ||
21891         VE->containsUnexpandedParameterPack()) {
21892       // Try to find the associated user-defined mapper.
21893       ExprResult ER = buildUserDefinedMapperRef(
21894           SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
21895           VE->getType().getCanonicalType(), UnresolvedMapper);
21896       if (ER.isInvalid())
21897         continue;
21898       MVLI.UDMapperList.push_back(ER.get());
21899       // We can only analyze this information once the missing information is
21900       // resolved.
21901       MVLI.ProcessedVarList.push_back(RE);
21902       continue;
21903     }
21904 
21905     Expr *SimpleExpr = RE->IgnoreParenCasts();
21906 
21907     if (!RE->isLValue()) {
21908       if (SemaRef.getLangOpts().OpenMP < 50) {
21909         SemaRef.Diag(
21910             ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
21911             << RE->getSourceRange();
21912       } else {
21913         SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
21914             << getOpenMPClauseName(CKind) << RE->getSourceRange();
21915       }
21916       continue;
21917     }
21918 
21919     OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
21920     ValueDecl *CurDeclaration = nullptr;
21921 
21922     // Obtain the array or member expression bases if required. Also, fill the
21923     // components array with all the components identified in the process.
21924     const Expr *BE =
21925         checkMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents, CKind,
21926                                      DSAS->getCurrentDirective(), NoDiagnose);
21927     if (!BE)
21928       continue;
21929 
21930     assert(!CurComponents.empty() &&
21931            "Invalid mappable expression information.");
21932 
21933     if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
21934       // Add store "this" pointer to class in DSAStackTy for future checking
21935       DSAS->addMappedClassesQualTypes(TE->getType());
21936       // Try to find the associated user-defined mapper.
21937       ExprResult ER = buildUserDefinedMapperRef(
21938           SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
21939           VE->getType().getCanonicalType(), UnresolvedMapper);
21940       if (ER.isInvalid())
21941         continue;
21942       MVLI.UDMapperList.push_back(ER.get());
21943       // Skip restriction checking for variable or field declarations
21944       MVLI.ProcessedVarList.push_back(RE);
21945       MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
21946       MVLI.VarComponents.back().append(CurComponents.begin(),
21947                                        CurComponents.end());
21948       MVLI.VarBaseDeclarations.push_back(nullptr);
21949       continue;
21950     }
21951 
21952     // For the following checks, we rely on the base declaration which is
21953     // expected to be associated with the last component. The declaration is
21954     // expected to be a variable or a field (if 'this' is being mapped).
21955     CurDeclaration = CurComponents.back().getAssociatedDeclaration();
21956     assert(CurDeclaration && "Null decl on map clause.");
21957     assert(
21958         CurDeclaration->isCanonicalDecl() &&
21959         "Expecting components to have associated only canonical declarations.");
21960 
21961     auto *VD = dyn_cast<VarDecl>(CurDeclaration);
21962     const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
21963 
21964     assert((VD || FD) && "Only variables or fields are expected here!");
21965     (void)FD;
21966 
21967     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
21968     // threadprivate variables cannot appear in a map clause.
21969     // OpenMP 4.5 [2.10.5, target update Construct]
21970     // threadprivate variables cannot appear in a from clause.
21971     if (VD && DSAS->isThreadPrivate(VD)) {
21972       if (NoDiagnose)
21973         continue;
21974       DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
21975       SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
21976           << getOpenMPClauseName(CKind);
21977       reportOriginalDsa(SemaRef, DSAS, VD, DVar);
21978       continue;
21979     }
21980 
21981     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
21982     //  A list item cannot appear in both a map clause and a data-sharing
21983     //  attribute clause on the same construct.
21984 
21985     // Check conflicts with other map clause expressions. We check the conflicts
21986     // with the current construct separately from the enclosing data
21987     // environment, because the restrictions are different. We only have to
21988     // check conflicts across regions for the map clauses.
21989     if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
21990                           /*CurrentRegionOnly=*/true, CurComponents, CKind))
21991       break;
21992     if (CKind == OMPC_map &&
21993         (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) &&
21994         checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
21995                           /*CurrentRegionOnly=*/false, CurComponents, CKind))
21996       break;
21997 
21998     // OpenMP 4.5 [2.10.5, target update Construct]
21999     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
22000     //  If the type of a list item is a reference to a type T then the type will
22001     //  be considered to be T for all purposes of this clause.
22002     auto I = llvm::find_if(
22003         CurComponents,
22004         [](const OMPClauseMappableExprCommon::MappableComponent &MC) {
22005           return MC.getAssociatedDeclaration();
22006         });
22007     assert(I != CurComponents.end() && "Null decl on map clause.");
22008     (void)I;
22009     QualType Type;
22010     auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens());
22011     auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens());
22012     auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens());
22013     if (ASE) {
22014       Type = ASE->getType().getNonReferenceType();
22015     } else if (OASE) {
22016       QualType BaseType =
22017           OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
22018       if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
22019         Type = ATy->getElementType();
22020       else
22021         Type = BaseType->getPointeeType();
22022       Type = Type.getNonReferenceType();
22023     } else if (OAShE) {
22024       Type = OAShE->getBase()->getType()->getPointeeType();
22025     } else {
22026       Type = VE->getType();
22027     }
22028 
22029     // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
22030     // A list item in a to or from clause must have a mappable type.
22031     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
22032     //  A list item must have a mappable type.
22033     if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
22034                            DSAS, Type, /*FullCheck=*/true))
22035       continue;
22036 
22037     if (CKind == OMPC_map) {
22038       // target enter data
22039       // OpenMP [2.10.2, Restrictions, p. 99]
22040       // A map-type must be specified in all map clauses and must be either
22041       // to or alloc. Starting with OpenMP 5.2 the default map type is `to` if
22042       // no map type is present.
22043       OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
22044       if (DKind == OMPD_target_enter_data &&
22045           !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc ||
22046             SemaRef.getLangOpts().OpenMP >= 52)) {
22047         SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
22048             << (IsMapTypeImplicit ? 1 : 0)
22049             << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
22050             << getOpenMPDirectiveName(DKind);
22051         continue;
22052       }
22053 
22054       // target exit_data
22055       // OpenMP [2.10.3, Restrictions, p. 102]
22056       // A map-type must be specified in all map clauses and must be either
22057       // from, release, or delete. Starting with OpenMP 5.2 the default map
22058       // type is `from` if no map type is present.
22059       if (DKind == OMPD_target_exit_data &&
22060           !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
22061             MapType == OMPC_MAP_delete || SemaRef.getLangOpts().OpenMP >= 52)) {
22062         SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
22063             << (IsMapTypeImplicit ? 1 : 0)
22064             << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
22065             << getOpenMPDirectiveName(DKind);
22066         continue;
22067       }
22068 
22069       // The 'ompx_hold' modifier is specifically intended to be used on a
22070       // 'target' or 'target data' directive to prevent data from being unmapped
22071       // during the associated statement.  It is not permitted on a 'target
22072       // enter data' or 'target exit data' directive, which have no associated
22073       // statement.
22074       if ((DKind == OMPD_target_enter_data || DKind == OMPD_target_exit_data) &&
22075           HasHoldModifier) {
22076         SemaRef.Diag(StartLoc,
22077                      diag::err_omp_invalid_map_type_modifier_for_directive)
22078             << getOpenMPSimpleClauseTypeName(OMPC_map,
22079                                              OMPC_MAP_MODIFIER_ompx_hold)
22080             << getOpenMPDirectiveName(DKind);
22081         continue;
22082       }
22083 
22084       // target, target data
22085       // OpenMP 5.0 [2.12.2, Restrictions, p. 163]
22086       // OpenMP 5.0 [2.12.5, Restrictions, p. 174]
22087       // A map-type in a map clause must be to, from, tofrom or alloc
22088       if ((DKind == OMPD_target_data ||
22089            isOpenMPTargetExecutionDirective(DKind)) &&
22090           !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
22091             MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) {
22092         SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
22093             << (IsMapTypeImplicit ? 1 : 0)
22094             << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
22095             << getOpenMPDirectiveName(DKind);
22096         continue;
22097       }
22098 
22099       // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
22100       // A list item cannot appear in both a map clause and a data-sharing
22101       // attribute clause on the same construct
22102       //
22103       // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
22104       // A list item cannot appear in both a map clause and a data-sharing
22105       // attribute clause on the same construct unless the construct is a
22106       // combined construct.
22107       if (VD && ((SemaRef.LangOpts.OpenMP <= 45 &&
22108                   isOpenMPTargetExecutionDirective(DKind)) ||
22109                  DKind == OMPD_target)) {
22110         DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
22111         if (isOpenMPPrivate(DVar.CKind)) {
22112           SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
22113               << getOpenMPClauseName(DVar.CKind)
22114               << getOpenMPClauseName(OMPC_map)
22115               << getOpenMPDirectiveName(DSAS->getCurrentDirective());
22116           reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
22117           continue;
22118         }
22119       }
22120     }
22121 
22122     // Try to find the associated user-defined mapper.
22123     ExprResult ER = buildUserDefinedMapperRef(
22124         SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
22125         Type.getCanonicalType(), UnresolvedMapper);
22126     if (ER.isInvalid())
22127       continue;
22128     MVLI.UDMapperList.push_back(ER.get());
22129 
22130     // Save the current expression.
22131     MVLI.ProcessedVarList.push_back(RE);
22132 
22133     // Store the components in the stack so that they can be used to check
22134     // against other clauses later on.
22135     DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
22136                                           /*WhereFoundClauseKind=*/OMPC_map);
22137 
22138     // Save the components and declaration to create the clause. For purposes of
22139     // the clause creation, any component list that has base 'this' uses
22140     // null as base declaration.
22141     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
22142     MVLI.VarComponents.back().append(CurComponents.begin(),
22143                                      CurComponents.end());
22144     MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
22145                                                            : CurDeclaration);
22146   }
22147 }
22148 
22149 OMPClause *Sema::ActOnOpenMPMapClause(
22150     Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
22151     ArrayRef<SourceLocation> MapTypeModifiersLoc,
22152     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
22153     OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
22154     SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
22155     const OMPVarListLocTy &Locs, bool NoDiagnose,
22156     ArrayRef<Expr *> UnresolvedMappers) {
22157   OpenMPMapModifierKind Modifiers[] = {
22158       OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
22159       OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
22160       OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown};
22161   SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers];
22162 
22163   if (IteratorModifier && !IteratorModifier->getType()->isSpecificBuiltinType(
22164                               BuiltinType::OMPIterator))
22165     Diag(IteratorModifier->getExprLoc(),
22166          diag::err_omp_map_modifier_not_iterator);
22167 
22168   // Process map-type-modifiers, flag errors for duplicate modifiers.
22169   unsigned Count = 0;
22170   for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
22171     if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
22172         llvm::is_contained(Modifiers, MapTypeModifiers[I])) {
22173       Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
22174       continue;
22175     }
22176     assert(Count < NumberOfOMPMapClauseModifiers &&
22177            "Modifiers exceed the allowed number of map type modifiers");
22178     Modifiers[Count] = MapTypeModifiers[I];
22179     ModifiersLoc[Count] = MapTypeModifiersLoc[I];
22180     ++Count;
22181   }
22182 
22183   MappableVarListInfo MVLI(VarList);
22184   checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc,
22185                               MapperIdScopeSpec, MapperId, UnresolvedMappers,
22186                               MapType, Modifiers, IsMapTypeImplicit,
22187                               NoDiagnose);
22188 
22189   // We need to produce a map clause even if we don't have variables so that
22190   // other diagnostics related with non-existing map clauses are accurate.
22191   return OMPMapClause::Create(
22192       Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
22193       MVLI.VarComponents, MVLI.UDMapperList, IteratorModifier, Modifiers,
22194       ModifiersLoc, MapperIdScopeSpec.getWithLocInContext(Context), MapperId,
22195       MapType, IsMapTypeImplicit, MapLoc);
22196 }
22197 
22198 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
22199                                                TypeResult ParsedType) {
22200   assert(ParsedType.isUsable());
22201 
22202   QualType ReductionType = GetTypeFromParser(ParsedType.get());
22203   if (ReductionType.isNull())
22204     return QualType();
22205 
22206   // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
22207   // A type name in a declare reduction directive cannot be a function type, an
22208   // array type, a reference type, or a type qualified with const, volatile or
22209   // restrict.
22210   if (ReductionType.hasQualifiers()) {
22211     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
22212     return QualType();
22213   }
22214 
22215   if (ReductionType->isFunctionType()) {
22216     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
22217     return QualType();
22218   }
22219   if (ReductionType->isReferenceType()) {
22220     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
22221     return QualType();
22222   }
22223   if (ReductionType->isArrayType()) {
22224     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
22225     return QualType();
22226   }
22227   return ReductionType;
22228 }
22229 
22230 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
22231     Scope *S, DeclContext *DC, DeclarationName Name,
22232     ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
22233     AccessSpecifier AS, Decl *PrevDeclInScope) {
22234   SmallVector<Decl *, 8> Decls;
22235   Decls.reserve(ReductionTypes.size());
22236 
22237   LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
22238                       forRedeclarationInCurContext());
22239   // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
22240   // A reduction-identifier may not be re-declared in the current scope for the
22241   // same type or for a type that is compatible according to the base language
22242   // rules.
22243   llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
22244   OMPDeclareReductionDecl *PrevDRD = nullptr;
22245   bool InCompoundScope = true;
22246   if (S != nullptr) {
22247     // Find previous declaration with the same name not referenced in other
22248     // declarations.
22249     FunctionScopeInfo *ParentFn = getEnclosingFunction();
22250     InCompoundScope =
22251         (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
22252     LookupName(Lookup, S);
22253     FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
22254                          /*AllowInlineNamespace=*/false);
22255     llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
22256     LookupResult::Filter Filter = Lookup.makeFilter();
22257     while (Filter.hasNext()) {
22258       auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
22259       if (InCompoundScope) {
22260         auto I = UsedAsPrevious.find(PrevDecl);
22261         if (I == UsedAsPrevious.end())
22262           UsedAsPrevious[PrevDecl] = false;
22263         if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
22264           UsedAsPrevious[D] = true;
22265       }
22266       PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
22267           PrevDecl->getLocation();
22268     }
22269     Filter.done();
22270     if (InCompoundScope) {
22271       for (const auto &PrevData : UsedAsPrevious) {
22272         if (!PrevData.second) {
22273           PrevDRD = PrevData.first;
22274           break;
22275         }
22276       }
22277     }
22278   } else if (PrevDeclInScope != nullptr) {
22279     auto *PrevDRDInScope = PrevDRD =
22280         cast<OMPDeclareReductionDecl>(PrevDeclInScope);
22281     do {
22282       PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
22283           PrevDRDInScope->getLocation();
22284       PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
22285     } while (PrevDRDInScope != nullptr);
22286   }
22287   for (const auto &TyData : ReductionTypes) {
22288     const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
22289     bool Invalid = false;
22290     if (I != PreviousRedeclTypes.end()) {
22291       Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
22292           << TyData.first;
22293       Diag(I->second, diag::note_previous_definition);
22294       Invalid = true;
22295     }
22296     PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
22297     auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
22298                                                 Name, TyData.first, PrevDRD);
22299     DC->addDecl(DRD);
22300     DRD->setAccess(AS);
22301     Decls.push_back(DRD);
22302     if (Invalid)
22303       DRD->setInvalidDecl();
22304     else
22305       PrevDRD = DRD;
22306   }
22307 
22308   return DeclGroupPtrTy::make(
22309       DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
22310 }
22311 
22312 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
22313   auto *DRD = cast<OMPDeclareReductionDecl>(D);
22314 
22315   // Enter new function scope.
22316   PushFunctionScope();
22317   setFunctionHasBranchProtectedScope();
22318   getCurFunction()->setHasOMPDeclareReductionCombiner();
22319 
22320   if (S != nullptr)
22321     PushDeclContext(S, DRD);
22322   else
22323     CurContext = DRD;
22324 
22325   PushExpressionEvaluationContext(
22326       ExpressionEvaluationContext::PotentiallyEvaluated);
22327 
22328   QualType ReductionType = DRD->getType();
22329   // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
22330   // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
22331   // uses semantics of argument handles by value, but it should be passed by
22332   // reference. C lang does not support references, so pass all parameters as
22333   // pointers.
22334   // Create 'T omp_in;' variable.
22335   VarDecl *OmpInParm =
22336       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
22337   // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
22338   // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
22339   // uses semantics of argument handles by value, but it should be passed by
22340   // reference. C lang does not support references, so pass all parameters as
22341   // pointers.
22342   // Create 'T omp_out;' variable.
22343   VarDecl *OmpOutParm =
22344       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
22345   if (S != nullptr) {
22346     PushOnScopeChains(OmpInParm, S);
22347     PushOnScopeChains(OmpOutParm, S);
22348   } else {
22349     DRD->addDecl(OmpInParm);
22350     DRD->addDecl(OmpOutParm);
22351   }
22352   Expr *InE =
22353       ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
22354   Expr *OutE =
22355       ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
22356   DRD->setCombinerData(InE, OutE);
22357 }
22358 
22359 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
22360   auto *DRD = cast<OMPDeclareReductionDecl>(D);
22361   DiscardCleanupsInEvaluationContext();
22362   PopExpressionEvaluationContext();
22363 
22364   PopDeclContext();
22365   PopFunctionScopeInfo();
22366 
22367   if (Combiner != nullptr)
22368     DRD->setCombiner(Combiner);
22369   else
22370     DRD->setInvalidDecl();
22371 }
22372 
22373 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
22374   auto *DRD = cast<OMPDeclareReductionDecl>(D);
22375 
22376   // Enter new function scope.
22377   PushFunctionScope();
22378   setFunctionHasBranchProtectedScope();
22379 
22380   if (S != nullptr)
22381     PushDeclContext(S, DRD);
22382   else
22383     CurContext = DRD;
22384 
22385   PushExpressionEvaluationContext(
22386       ExpressionEvaluationContext::PotentiallyEvaluated);
22387 
22388   QualType ReductionType = DRD->getType();
22389   // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
22390   // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
22391   // uses semantics of argument handles by value, but it should be passed by
22392   // reference. C lang does not support references, so pass all parameters as
22393   // pointers.
22394   // Create 'T omp_priv;' variable.
22395   VarDecl *OmpPrivParm =
22396       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
22397   // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
22398   // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
22399   // uses semantics of argument handles by value, but it should be passed by
22400   // reference. C lang does not support references, so pass all parameters as
22401   // pointers.
22402   // Create 'T omp_orig;' variable.
22403   VarDecl *OmpOrigParm =
22404       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
22405   if (S != nullptr) {
22406     PushOnScopeChains(OmpPrivParm, S);
22407     PushOnScopeChains(OmpOrigParm, S);
22408   } else {
22409     DRD->addDecl(OmpPrivParm);
22410     DRD->addDecl(OmpOrigParm);
22411   }
22412   Expr *OrigE =
22413       ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
22414   Expr *PrivE =
22415       ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
22416   DRD->setInitializerData(OrigE, PrivE);
22417   return OmpPrivParm;
22418 }
22419 
22420 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
22421                                                      VarDecl *OmpPrivParm) {
22422   auto *DRD = cast<OMPDeclareReductionDecl>(D);
22423   DiscardCleanupsInEvaluationContext();
22424   PopExpressionEvaluationContext();
22425 
22426   PopDeclContext();
22427   PopFunctionScopeInfo();
22428 
22429   if (Initializer != nullptr) {
22430     DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
22431   } else if (OmpPrivParm->hasInit()) {
22432     DRD->setInitializer(OmpPrivParm->getInit(),
22433                         OmpPrivParm->isDirectInit()
22434                             ? OMPDeclareReductionDecl::DirectInit
22435                             : OMPDeclareReductionDecl::CopyInit);
22436   } else {
22437     DRD->setInvalidDecl();
22438   }
22439 }
22440 
22441 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
22442     Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
22443   for (Decl *D : DeclReductions.get()) {
22444     if (IsValid) {
22445       if (S)
22446         PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
22447                           /*AddToContext=*/false);
22448     } else {
22449       D->setInvalidDecl();
22450     }
22451   }
22452   return DeclReductions;
22453 }
22454 
22455 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) {
22456   TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
22457   QualType T = TInfo->getType();
22458   if (D.isInvalidType())
22459     return true;
22460 
22461   if (getLangOpts().CPlusPlus) {
22462     // Check that there are no default arguments (C++ only).
22463     CheckExtraCXXDefaultArguments(D);
22464   }
22465 
22466   return CreateParsedType(T, TInfo);
22467 }
22468 
22469 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
22470                                             TypeResult ParsedType) {
22471   assert(ParsedType.isUsable() && "Expect usable parsed mapper type");
22472 
22473   QualType MapperType = GetTypeFromParser(ParsedType.get());
22474   assert(!MapperType.isNull() && "Expect valid mapper type");
22475 
22476   // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
22477   //  The type must be of struct, union or class type in C and C++
22478   if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
22479     Diag(TyLoc, diag::err_omp_mapper_wrong_type);
22480     return QualType();
22481   }
22482   return MapperType;
22483 }
22484 
22485 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective(
22486     Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
22487     SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
22488     Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) {
22489   LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
22490                       forRedeclarationInCurContext());
22491   // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
22492   //  A mapper-identifier may not be redeclared in the current scope for the
22493   //  same type or for a type that is compatible according to the base language
22494   //  rules.
22495   llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
22496   OMPDeclareMapperDecl *PrevDMD = nullptr;
22497   bool InCompoundScope = true;
22498   if (S != nullptr) {
22499     // Find previous declaration with the same name not referenced in other
22500     // declarations.
22501     FunctionScopeInfo *ParentFn = getEnclosingFunction();
22502     InCompoundScope =
22503         (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
22504     LookupName(Lookup, S);
22505     FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
22506                          /*AllowInlineNamespace=*/false);
22507     llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
22508     LookupResult::Filter Filter = Lookup.makeFilter();
22509     while (Filter.hasNext()) {
22510       auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
22511       if (InCompoundScope) {
22512         auto I = UsedAsPrevious.find(PrevDecl);
22513         if (I == UsedAsPrevious.end())
22514           UsedAsPrevious[PrevDecl] = false;
22515         if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
22516           UsedAsPrevious[D] = true;
22517       }
22518       PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
22519           PrevDecl->getLocation();
22520     }
22521     Filter.done();
22522     if (InCompoundScope) {
22523       for (const auto &PrevData : UsedAsPrevious) {
22524         if (!PrevData.second) {
22525           PrevDMD = PrevData.first;
22526           break;
22527         }
22528       }
22529     }
22530   } else if (PrevDeclInScope) {
22531     auto *PrevDMDInScope = PrevDMD =
22532         cast<OMPDeclareMapperDecl>(PrevDeclInScope);
22533     do {
22534       PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
22535           PrevDMDInScope->getLocation();
22536       PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
22537     } while (PrevDMDInScope != nullptr);
22538   }
22539   const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
22540   bool Invalid = false;
22541   if (I != PreviousRedeclTypes.end()) {
22542     Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
22543         << MapperType << Name;
22544     Diag(I->second, diag::note_previous_definition);
22545     Invalid = true;
22546   }
22547   // Build expressions for implicit maps of data members with 'default'
22548   // mappers.
22549   SmallVector<OMPClause *, 4> ClausesWithImplicit(Clauses.begin(),
22550                                                   Clauses.end());
22551   if (LangOpts.OpenMP >= 50)
22552     processImplicitMapsWithDefaultMappers(*this, DSAStack, ClausesWithImplicit);
22553   auto *DMD =
22554       OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, MapperType, VN,
22555                                    ClausesWithImplicit, PrevDMD);
22556   if (S)
22557     PushOnScopeChains(DMD, S);
22558   else
22559     DC->addDecl(DMD);
22560   DMD->setAccess(AS);
22561   if (Invalid)
22562     DMD->setInvalidDecl();
22563 
22564   auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl();
22565   VD->setDeclContext(DMD);
22566   VD->setLexicalDeclContext(DMD);
22567   DMD->addDecl(VD);
22568   DMD->setMapperVarRef(MapperVarRef);
22569 
22570   return DeclGroupPtrTy::make(DeclGroupRef(DMD));
22571 }
22572 
22573 ExprResult
22574 Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType,
22575                                                SourceLocation StartLoc,
22576                                                DeclarationName VN) {
22577   TypeSourceInfo *TInfo =
22578       Context.getTrivialTypeSourceInfo(MapperType, StartLoc);
22579   auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(),
22580                              StartLoc, StartLoc, VN.getAsIdentifierInfo(),
22581                              MapperType, TInfo, SC_None);
22582   if (S)
22583     PushOnScopeChains(VD, S, /*AddToContext=*/false);
22584   Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
22585   DSAStack->addDeclareMapperVarRef(E);
22586   return E;
22587 }
22588 
22589 void Sema::ActOnOpenMPIteratorVarDecl(VarDecl *VD) {
22590   if (DSAStack->getDeclareMapperVarRef())
22591     DSAStack->addIteratorVarDecl(VD);
22592 }
22593 
22594 bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const {
22595   assert(LangOpts.OpenMP && "Expected OpenMP mode.");
22596   const Expr *Ref = DSAStack->getDeclareMapperVarRef();
22597   if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref)) {
22598     if (VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl())
22599       return true;
22600     if (VD->isUsableInConstantExpressions(Context))
22601       return true;
22602     if (LangOpts.OpenMP >= 52 && DSAStack->isIteratorVarDecl(VD))
22603       return true;
22604     return false;
22605   }
22606   return true;
22607 }
22608 
22609 const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const {
22610   assert(LangOpts.OpenMP && "Expected OpenMP mode.");
22611   return cast<DeclRefExpr>(DSAStack->getDeclareMapperVarRef())->getDecl();
22612 }
22613 
22614 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
22615                                            SourceLocation StartLoc,
22616                                            SourceLocation LParenLoc,
22617                                            SourceLocation EndLoc) {
22618   Expr *ValExpr = NumTeams;
22619   Stmt *HelperValStmt = nullptr;
22620 
22621   // OpenMP [teams Constrcut, Restrictions]
22622   // The num_teams expression must evaluate to a positive integer value.
22623   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
22624                                  /*StrictlyPositive=*/true))
22625     return nullptr;
22626 
22627   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
22628   OpenMPDirectiveKind CaptureRegion =
22629       getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP);
22630   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
22631     ValExpr = MakeFullExpr(ValExpr).get();
22632     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
22633     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
22634     HelperValStmt = buildPreInits(Context, Captures);
22635   }
22636 
22637   return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
22638                                          StartLoc, LParenLoc, EndLoc);
22639 }
22640 
22641 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
22642                                               SourceLocation StartLoc,
22643                                               SourceLocation LParenLoc,
22644                                               SourceLocation EndLoc) {
22645   Expr *ValExpr = ThreadLimit;
22646   Stmt *HelperValStmt = nullptr;
22647 
22648   // OpenMP [teams Constrcut, Restrictions]
22649   // The thread_limit expression must evaluate to a positive integer value.
22650   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
22651                                  /*StrictlyPositive=*/true))
22652     return nullptr;
22653 
22654   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
22655   OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
22656       DKind, OMPC_thread_limit, LangOpts.OpenMP);
22657   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
22658     ValExpr = MakeFullExpr(ValExpr).get();
22659     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
22660     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
22661     HelperValStmt = buildPreInits(Context, Captures);
22662   }
22663 
22664   return new (Context) OMPThreadLimitClause(
22665       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
22666 }
22667 
22668 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
22669                                            SourceLocation StartLoc,
22670                                            SourceLocation LParenLoc,
22671                                            SourceLocation EndLoc) {
22672   Expr *ValExpr = Priority;
22673   Stmt *HelperValStmt = nullptr;
22674   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
22675 
22676   // OpenMP [2.9.1, task Constrcut]
22677   // The priority-value is a non-negative numerical scalar expression.
22678   if (!isNonNegativeIntegerValue(
22679           ValExpr, *this, OMPC_priority,
22680           /*StrictlyPositive=*/false, /*BuildCapture=*/true,
22681           DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
22682     return nullptr;
22683 
22684   return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion,
22685                                          StartLoc, LParenLoc, EndLoc);
22686 }
22687 
22688 OMPClause *Sema::ActOnOpenMPGrainsizeClause(
22689     OpenMPGrainsizeClauseModifier Modifier, Expr *Grainsize,
22690     SourceLocation StartLoc, SourceLocation LParenLoc,
22691     SourceLocation ModifierLoc, SourceLocation EndLoc) {
22692   assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 51) &&
22693          "Unexpected grainsize modifier in OpenMP < 51.");
22694 
22695   if (ModifierLoc.isValid() && Modifier == OMPC_GRAINSIZE_unknown) {
22696     std::string Values = getListOfPossibleValues(OMPC_grainsize, /*First=*/0,
22697                                                  OMPC_GRAINSIZE_unknown);
22698     Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
22699         << Values << getOpenMPClauseName(OMPC_grainsize);
22700     return nullptr;
22701   }
22702 
22703   Expr *ValExpr = Grainsize;
22704   Stmt *HelperValStmt = nullptr;
22705   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
22706 
22707   // OpenMP [2.9.2, taskloop Constrcut]
22708   // The parameter of the grainsize clause must be a positive integer
22709   // expression.
22710   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize,
22711                                  /*StrictlyPositive=*/true,
22712                                  /*BuildCapture=*/true,
22713                                  DSAStack->getCurrentDirective(),
22714                                  &CaptureRegion, &HelperValStmt))
22715     return nullptr;
22716 
22717   return new (Context)
22718       OMPGrainsizeClause(Modifier, ValExpr, HelperValStmt, CaptureRegion,
22719                          StartLoc, LParenLoc, ModifierLoc, EndLoc);
22720 }
22721 
22722 OMPClause *Sema::ActOnOpenMPNumTasksClause(
22723     OpenMPNumTasksClauseModifier Modifier, Expr *NumTasks,
22724     SourceLocation StartLoc, SourceLocation LParenLoc,
22725     SourceLocation ModifierLoc, SourceLocation EndLoc) {
22726   assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 51) &&
22727          "Unexpected num_tasks modifier in OpenMP < 51.");
22728 
22729   if (ModifierLoc.isValid() && Modifier == OMPC_NUMTASKS_unknown) {
22730     std::string Values = getListOfPossibleValues(OMPC_num_tasks, /*First=*/0,
22731                                                  OMPC_NUMTASKS_unknown);
22732     Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
22733         << Values << getOpenMPClauseName(OMPC_num_tasks);
22734     return nullptr;
22735   }
22736 
22737   Expr *ValExpr = NumTasks;
22738   Stmt *HelperValStmt = nullptr;
22739   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
22740 
22741   // OpenMP [2.9.2, taskloop Constrcut]
22742   // The parameter of the num_tasks clause must be a positive integer
22743   // expression.
22744   if (!isNonNegativeIntegerValue(
22745           ValExpr, *this, OMPC_num_tasks,
22746           /*StrictlyPositive=*/true, /*BuildCapture=*/true,
22747           DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
22748     return nullptr;
22749 
22750   return new (Context)
22751       OMPNumTasksClause(Modifier, ValExpr, HelperValStmt, CaptureRegion,
22752                         StartLoc, LParenLoc, ModifierLoc, EndLoc);
22753 }
22754 
22755 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
22756                                        SourceLocation LParenLoc,
22757                                        SourceLocation EndLoc) {
22758   // OpenMP [2.13.2, critical construct, Description]
22759   // ... where hint-expression is an integer constant expression that evaluates
22760   // to a valid lock hint.
22761   ExprResult HintExpr =
22762       VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint, false);
22763   if (HintExpr.isInvalid())
22764     return nullptr;
22765   return new (Context)
22766       OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
22767 }
22768 
22769 /// Tries to find omp_event_handle_t type.
22770 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc,
22771                                 DSAStackTy *Stack) {
22772   QualType OMPEventHandleT = Stack->getOMPEventHandleT();
22773   if (!OMPEventHandleT.isNull())
22774     return true;
22775   IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t");
22776   ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
22777   if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
22778     S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t";
22779     return false;
22780   }
22781   Stack->setOMPEventHandleT(PT.get());
22782   return true;
22783 }
22784 
22785 OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc,
22786                                          SourceLocation LParenLoc,
22787                                          SourceLocation EndLoc) {
22788   if (!Evt->isValueDependent() && !Evt->isTypeDependent() &&
22789       !Evt->isInstantiationDependent() &&
22790       !Evt->containsUnexpandedParameterPack()) {
22791     if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack))
22792       return nullptr;
22793     // OpenMP 5.0, 2.10.1 task Construct.
22794     // event-handle is a variable of the omp_event_handle_t type.
22795     auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts());
22796     if (!Ref) {
22797       Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
22798           << "omp_event_handle_t" << 0 << Evt->getSourceRange();
22799       return nullptr;
22800     }
22801     auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl());
22802     if (!VD) {
22803       Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
22804           << "omp_event_handle_t" << 0 << Evt->getSourceRange();
22805       return nullptr;
22806     }
22807     if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(),
22808                                         VD->getType()) ||
22809         VD->getType().isConstant(Context)) {
22810       Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
22811           << "omp_event_handle_t" << 1 << VD->getType()
22812           << Evt->getSourceRange();
22813       return nullptr;
22814     }
22815     // OpenMP 5.0, 2.10.1 task Construct
22816     // [detach clause]... The event-handle will be considered as if it was
22817     // specified on a firstprivate clause.
22818     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false);
22819     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
22820         DVar.RefExpr) {
22821       Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa)
22822           << getOpenMPClauseName(DVar.CKind)
22823           << getOpenMPClauseName(OMPC_firstprivate);
22824       reportOriginalDsa(*this, DSAStack, VD, DVar);
22825       return nullptr;
22826     }
22827   }
22828 
22829   return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc);
22830 }
22831 
22832 OMPClause *Sema::ActOnOpenMPDistScheduleClause(
22833     OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
22834     SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
22835     SourceLocation EndLoc) {
22836   if (Kind == OMPC_DIST_SCHEDULE_unknown) {
22837     std::string Values;
22838     Values += "'";
22839     Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
22840     Values += "'";
22841     Diag(KindLoc, diag::err_omp_unexpected_clause_value)
22842         << Values << getOpenMPClauseName(OMPC_dist_schedule);
22843     return nullptr;
22844   }
22845   Expr *ValExpr = ChunkSize;
22846   Stmt *HelperValStmt = nullptr;
22847   if (ChunkSize) {
22848     if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
22849         !ChunkSize->isInstantiationDependent() &&
22850         !ChunkSize->containsUnexpandedParameterPack()) {
22851       SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
22852       ExprResult Val =
22853           PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
22854       if (Val.isInvalid())
22855         return nullptr;
22856 
22857       ValExpr = Val.get();
22858 
22859       // OpenMP [2.7.1, Restrictions]
22860       //  chunk_size must be a loop invariant integer expression with a positive
22861       //  value.
22862       if (std::optional<llvm::APSInt> Result =
22863               ValExpr->getIntegerConstantExpr(Context)) {
22864         if (Result->isSigned() && !Result->isStrictlyPositive()) {
22865           Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
22866               << "dist_schedule" << ChunkSize->getSourceRange();
22867           return nullptr;
22868         }
22869       } else if (getOpenMPCaptureRegionForClause(
22870                      DSAStack->getCurrentDirective(), OMPC_dist_schedule,
22871                      LangOpts.OpenMP) != OMPD_unknown &&
22872                  !CurContext->isDependentContext()) {
22873         ValExpr = MakeFullExpr(ValExpr).get();
22874         llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
22875         ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
22876         HelperValStmt = buildPreInits(Context, Captures);
22877       }
22878     }
22879   }
22880 
22881   return new (Context)
22882       OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
22883                             Kind, ValExpr, HelperValStmt);
22884 }
22885 
22886 OMPClause *Sema::ActOnOpenMPDefaultmapClause(
22887     OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
22888     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
22889     SourceLocation KindLoc, SourceLocation EndLoc) {
22890   if (getLangOpts().OpenMP < 50) {
22891     if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
22892         Kind != OMPC_DEFAULTMAP_scalar) {
22893       std::string Value;
22894       SourceLocation Loc;
22895       Value += "'";
22896       if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
22897         Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
22898                                                OMPC_DEFAULTMAP_MODIFIER_tofrom);
22899         Loc = MLoc;
22900       } else {
22901         Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
22902                                                OMPC_DEFAULTMAP_scalar);
22903         Loc = KindLoc;
22904       }
22905       Value += "'";
22906       Diag(Loc, diag::err_omp_unexpected_clause_value)
22907           << Value << getOpenMPClauseName(OMPC_defaultmap);
22908       return nullptr;
22909     }
22910   } else {
22911     bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown);
22912     bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) ||
22913                             (LangOpts.OpenMP >= 50 && KindLoc.isInvalid());
22914     if (!isDefaultmapKind || !isDefaultmapModifier) {
22915       StringRef KindValue = "'scalar', 'aggregate', 'pointer'";
22916       if (LangOpts.OpenMP == 50) {
22917         StringRef ModifierValue = "'alloc', 'from', 'to', 'tofrom', "
22918                                   "'firstprivate', 'none', 'default'";
22919         if (!isDefaultmapKind && isDefaultmapModifier) {
22920           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
22921               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
22922         } else if (isDefaultmapKind && !isDefaultmapModifier) {
22923           Diag(MLoc, diag::err_omp_unexpected_clause_value)
22924               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
22925         } else {
22926           Diag(MLoc, diag::err_omp_unexpected_clause_value)
22927               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
22928           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
22929               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
22930         }
22931       } else {
22932         StringRef ModifierValue =
22933             "'alloc', 'from', 'to', 'tofrom', "
22934             "'firstprivate', 'none', 'default', 'present'";
22935         if (!isDefaultmapKind && isDefaultmapModifier) {
22936           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
22937               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
22938         } else if (isDefaultmapKind && !isDefaultmapModifier) {
22939           Diag(MLoc, diag::err_omp_unexpected_clause_value)
22940               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
22941         } else {
22942           Diag(MLoc, diag::err_omp_unexpected_clause_value)
22943               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
22944           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
22945               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
22946         }
22947       }
22948       return nullptr;
22949     }
22950 
22951     // OpenMP [5.0, 2.12.5, Restrictions, p. 174]
22952     //  At most one defaultmap clause for each category can appear on the
22953     //  directive.
22954     if (DSAStack->checkDefaultmapCategory(Kind)) {
22955       Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
22956       return nullptr;
22957     }
22958   }
22959   if (Kind == OMPC_DEFAULTMAP_unknown) {
22960     // Variable category is not specified - mark all categories.
22961     DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc);
22962     DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc);
22963     DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc);
22964   } else {
22965     DSAStack->setDefaultDMAAttr(M, Kind, StartLoc);
22966   }
22967 
22968   return new (Context)
22969       OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
22970 }
22971 
22972 bool Sema::ActOnStartOpenMPDeclareTargetContext(
22973     DeclareTargetContextInfo &DTCI) {
22974   DeclContext *CurLexicalContext = getCurLexicalContext();
22975   if (!CurLexicalContext->isFileContext() &&
22976       !CurLexicalContext->isExternCContext() &&
22977       !CurLexicalContext->isExternCXXContext() &&
22978       !isa<CXXRecordDecl>(CurLexicalContext) &&
22979       !isa<ClassTemplateDecl>(CurLexicalContext) &&
22980       !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
22981       !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
22982     Diag(DTCI.Loc, diag::err_omp_region_not_file_context);
22983     return false;
22984   }
22985 
22986   // Report affected OpenMP target offloading behavior when in HIP lang-mode.
22987   if (getLangOpts().HIP)
22988     Diag(DTCI.Loc, diag::warn_hip_omp_target_directives);
22989 
22990   DeclareTargetNesting.push_back(DTCI);
22991   return true;
22992 }
22993 
22994 const Sema::DeclareTargetContextInfo
22995 Sema::ActOnOpenMPEndDeclareTargetDirective() {
22996   assert(!DeclareTargetNesting.empty() &&
22997          "check isInOpenMPDeclareTargetContext() first!");
22998   return DeclareTargetNesting.pop_back_val();
22999 }
23000 
23001 void Sema::ActOnFinishedOpenMPDeclareTargetContext(
23002     DeclareTargetContextInfo &DTCI) {
23003   for (auto &It : DTCI.ExplicitlyMapped)
23004     ActOnOpenMPDeclareTargetName(It.first, It.second.Loc, It.second.MT, DTCI);
23005 }
23006 
23007 void Sema::DiagnoseUnterminatedOpenMPDeclareTarget() {
23008   if (DeclareTargetNesting.empty())
23009     return;
23010   DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back();
23011   Diag(DTCI.Loc, diag::warn_omp_unterminated_declare_target)
23012       << getOpenMPDirectiveName(DTCI.Kind);
23013 }
23014 
23015 NamedDecl *Sema::lookupOpenMPDeclareTargetName(Scope *CurScope,
23016                                                CXXScopeSpec &ScopeSpec,
23017                                                const DeclarationNameInfo &Id) {
23018   LookupResult Lookup(*this, Id, LookupOrdinaryName);
23019   LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
23020 
23021   if (Lookup.isAmbiguous())
23022     return nullptr;
23023   Lookup.suppressDiagnostics();
23024 
23025   if (!Lookup.isSingleResult()) {
23026     VarOrFuncDeclFilterCCC CCC(*this);
23027     if (TypoCorrection Corrected =
23028             CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
23029                         CTK_ErrorRecovery)) {
23030       diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
23031                                   << Id.getName());
23032       checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
23033       return nullptr;
23034     }
23035 
23036     Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
23037     return nullptr;
23038   }
23039 
23040   NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
23041   if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
23042       !isa<FunctionTemplateDecl>(ND)) {
23043     Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
23044     return nullptr;
23045   }
23046   return ND;
23047 }
23048 
23049 void Sema::ActOnOpenMPDeclareTargetName(NamedDecl *ND, SourceLocation Loc,
23050                                         OMPDeclareTargetDeclAttr::MapTypeTy MT,
23051                                         DeclareTargetContextInfo &DTCI) {
23052   assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
23053           isa<FunctionTemplateDecl>(ND)) &&
23054          "Expected variable, function or function template.");
23055 
23056   // Diagnose marking after use as it may lead to incorrect diagnosis and
23057   // codegen.
23058   if (LangOpts.OpenMP >= 50 &&
23059       (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced()))
23060     Diag(Loc, diag::warn_omp_declare_target_after_first_use);
23061 
23062   // Report affected OpenMP target offloading behavior when in HIP lang-mode.
23063   if (getLangOpts().HIP)
23064     Diag(Loc, diag::warn_hip_omp_target_directives);
23065 
23066   // Explicit declare target lists have precedence.
23067   const unsigned Level = -1;
23068 
23069   auto *VD = cast<ValueDecl>(ND);
23070   std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
23071       OMPDeclareTargetDeclAttr::getActiveAttr(VD);
23072   if (ActiveAttr && (*ActiveAttr)->getDevType() != DTCI.DT &&
23073       (*ActiveAttr)->getLevel() == Level) {
23074     Diag(Loc, diag::err_omp_device_type_mismatch)
23075         << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DTCI.DT)
23076         << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(
23077                (*ActiveAttr)->getDevType());
23078     return;
23079   }
23080   if (ActiveAttr && (*ActiveAttr)->getMapType() != MT &&
23081       (*ActiveAttr)->getLevel() == Level) {
23082     Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
23083     return;
23084   }
23085 
23086   if (ActiveAttr && (*ActiveAttr)->getLevel() == Level)
23087     return;
23088 
23089   Expr *IndirectE = nullptr;
23090   bool IsIndirect = false;
23091   if (DTCI.Indirect) {
23092     IndirectE = *DTCI.Indirect;
23093     if (!IndirectE)
23094       IsIndirect = true;
23095   }
23096   auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
23097       Context, MT, DTCI.DT, IndirectE, IsIndirect, Level,
23098       SourceRange(Loc, Loc));
23099   ND->addAttr(A);
23100   if (ASTMutationListener *ML = Context.getASTMutationListener())
23101     ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
23102   checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc);
23103 }
23104 
23105 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
23106                                      Sema &SemaRef, Decl *D) {
23107   if (!D || !isa<VarDecl>(D))
23108     return;
23109   auto *VD = cast<VarDecl>(D);
23110   std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
23111       OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
23112   if (SemaRef.LangOpts.OpenMP >= 50 &&
23113       (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) ||
23114        SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) &&
23115       VD->hasGlobalStorage()) {
23116     if (!MapTy || (*MapTy != OMPDeclareTargetDeclAttr::MT_To &&
23117                    *MapTy != OMPDeclareTargetDeclAttr::MT_Enter)) {
23118       // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
23119       // If a lambda declaration and definition appears between a
23120       // declare target directive and the matching end declare target
23121       // directive, all variables that are captured by the lambda
23122       // expression must also appear in a to clause.
23123       SemaRef.Diag(VD->getLocation(),
23124                    diag::err_omp_lambda_capture_in_declare_target_not_to);
23125       SemaRef.Diag(SL, diag::note_var_explicitly_captured_here)
23126           << VD << 0 << SR;
23127       return;
23128     }
23129   }
23130   if (MapTy)
23131     return;
23132   SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
23133   SemaRef.Diag(SL, diag::note_used_here) << SR;
23134 }
23135 
23136 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
23137                                    Sema &SemaRef, DSAStackTy *Stack,
23138                                    ValueDecl *VD) {
23139   return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
23140          checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
23141                            /*FullCheck=*/false);
23142 }
23143 
23144 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
23145                                             SourceLocation IdLoc) {
23146   if (!D || D->isInvalidDecl())
23147     return;
23148   SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
23149   SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
23150   if (auto *VD = dyn_cast<VarDecl>(D)) {
23151     // Only global variables can be marked as declare target.
23152     if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
23153         !VD->isStaticDataMember())
23154       return;
23155     // 2.10.6: threadprivate variable cannot appear in a declare target
23156     // directive.
23157     if (DSAStack->isThreadPrivate(VD)) {
23158       Diag(SL, diag::err_omp_threadprivate_in_target);
23159       reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false));
23160       return;
23161     }
23162   }
23163   if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
23164     D = FTD->getTemplatedDecl();
23165   if (auto *FD = dyn_cast<FunctionDecl>(D)) {
23166     std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
23167         OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
23168     if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
23169       Diag(IdLoc, diag::err_omp_function_in_link_clause);
23170       Diag(FD->getLocation(), diag::note_defined_here) << FD;
23171       return;
23172     }
23173   }
23174   if (auto *VD = dyn_cast<ValueDecl>(D)) {
23175     // Problem if any with var declared with incomplete type will be reported
23176     // as normal, so no need to check it here.
23177     if ((E || !VD->getType()->isIncompleteType()) &&
23178         !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD))
23179       return;
23180     if (!E && isInOpenMPDeclareTargetContext()) {
23181       // Checking declaration inside declare target region.
23182       if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
23183           isa<FunctionTemplateDecl>(D)) {
23184         std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
23185             OMPDeclareTargetDeclAttr::getActiveAttr(VD);
23186         unsigned Level = DeclareTargetNesting.size();
23187         if (ActiveAttr && (*ActiveAttr)->getLevel() >= Level)
23188           return;
23189         DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back();
23190         Expr *IndirectE = nullptr;
23191         bool IsIndirect = false;
23192         if (DTCI.Indirect) {
23193           IndirectE = *DTCI.Indirect;
23194           if (!IndirectE)
23195             IsIndirect = true;
23196         }
23197         auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
23198             Context,
23199             getLangOpts().OpenMP >= 52 ? OMPDeclareTargetDeclAttr::MT_Enter
23200                                        : OMPDeclareTargetDeclAttr::MT_To,
23201             DTCI.DT, IndirectE, IsIndirect, Level,
23202             SourceRange(DTCI.Loc, DTCI.Loc));
23203         D->addAttr(A);
23204         if (ASTMutationListener *ML = Context.getASTMutationListener())
23205           ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
23206       }
23207       return;
23208     }
23209   }
23210   if (!E)
23211     return;
23212   checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
23213 }
23214 
23215 /// This class visits every VarDecl that the initializer references and adds
23216 /// OMPDeclareTargetDeclAttr to each of them.
23217 class GlobalDeclRefChecker final
23218     : public StmtVisitor<GlobalDeclRefChecker> {
23219   SmallVector<VarDecl *> DeclVector;
23220   Attr *A;
23221 
23222 public:
23223   /// A StmtVisitor class function that visits all DeclRefExpr and adds
23224   /// OMPDeclareTargetDeclAttr to them.
23225   void VisitDeclRefExpr(DeclRefExpr *Node) {
23226     if (auto *VD = dyn_cast<VarDecl>(Node->getDecl())) {
23227       VD->addAttr(A);
23228       DeclVector.push_back(VD);
23229     }
23230   }
23231   /// A function that iterates across each of the Expr's children.
23232   void VisitExpr(Expr *Ex) {
23233     for (auto *Child : Ex->children()) {
23234       Visit(Child);
23235     }
23236   }
23237   /// A function that keeps a record of all the Decls that are variables, has
23238   /// OMPDeclareTargetDeclAttr, and has global storage in the DeclVector. Pop
23239   /// each Decl one at a time and use the inherited 'visit' functions to look
23240   /// for DeclRefExpr.
23241   void declareTargetInitializer(Decl *TD) {
23242     A = TD->getAttr<OMPDeclareTargetDeclAttr>();
23243     DeclVector.push_back(cast<VarDecl>(TD));
23244     while (!DeclVector.empty()) {
23245       VarDecl *TargetVarDecl = DeclVector.pop_back_val();
23246       if (TargetVarDecl->hasAttr<OMPDeclareTargetDeclAttr>() &&
23247           TargetVarDecl->hasInit() && TargetVarDecl->hasGlobalStorage()) {
23248         if (Expr *Ex = TargetVarDecl->getInit())
23249           Visit(Ex);
23250       }
23251     }
23252   }
23253 };
23254 
23255 /// Adding OMPDeclareTargetDeclAttr to variables with static storage
23256 /// duration that are referenced in the initializer expression list of
23257 /// variables with static storage duration in declare target directive.
23258 void Sema::ActOnOpenMPDeclareTargetInitializer(Decl *TargetDecl) {
23259   GlobalDeclRefChecker Checker;
23260   if (isa<VarDecl>(TargetDecl))
23261     Checker.declareTargetInitializer(TargetDecl);
23262 }
23263 
23264 OMPClause *Sema::ActOnOpenMPToClause(
23265     ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
23266     ArrayRef<SourceLocation> MotionModifiersLoc,
23267     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
23268     SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
23269     const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
23270   OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
23271                                           OMPC_MOTION_MODIFIER_unknown};
23272   SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
23273 
23274   // Process motion-modifiers, flag errors for duplicate modifiers.
23275   unsigned Count = 0;
23276   for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
23277     if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
23278         llvm::is_contained(Modifiers, MotionModifiers[I])) {
23279       Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
23280       continue;
23281     }
23282     assert(Count < NumberOfOMPMotionModifiers &&
23283            "Modifiers exceed the allowed number of motion modifiers");
23284     Modifiers[Count] = MotionModifiers[I];
23285     ModifiersLoc[Count] = MotionModifiersLoc[I];
23286     ++Count;
23287   }
23288 
23289   MappableVarListInfo MVLI(VarList);
23290   checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc,
23291                               MapperIdScopeSpec, MapperId, UnresolvedMappers);
23292   if (MVLI.ProcessedVarList.empty())
23293     return nullptr;
23294 
23295   return OMPToClause::Create(
23296       Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
23297       MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
23298       MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
23299 }
23300 
23301 OMPClause *Sema::ActOnOpenMPFromClause(
23302     ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
23303     ArrayRef<SourceLocation> MotionModifiersLoc,
23304     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
23305     SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
23306     const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
23307   OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
23308                                           OMPC_MOTION_MODIFIER_unknown};
23309   SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
23310 
23311   // Process motion-modifiers, flag errors for duplicate modifiers.
23312   unsigned Count = 0;
23313   for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
23314     if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
23315         llvm::is_contained(Modifiers, MotionModifiers[I])) {
23316       Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
23317       continue;
23318     }
23319     assert(Count < NumberOfOMPMotionModifiers &&
23320            "Modifiers exceed the allowed number of motion modifiers");
23321     Modifiers[Count] = MotionModifiers[I];
23322     ModifiersLoc[Count] = MotionModifiersLoc[I];
23323     ++Count;
23324   }
23325 
23326   MappableVarListInfo MVLI(VarList);
23327   checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc,
23328                               MapperIdScopeSpec, MapperId, UnresolvedMappers);
23329   if (MVLI.ProcessedVarList.empty())
23330     return nullptr;
23331 
23332   return OMPFromClause::Create(
23333       Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
23334       MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
23335       MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
23336 }
23337 
23338 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
23339                                                const OMPVarListLocTy &Locs) {
23340   MappableVarListInfo MVLI(VarList);
23341   SmallVector<Expr *, 8> PrivateCopies;
23342   SmallVector<Expr *, 8> Inits;
23343 
23344   for (Expr *RefExpr : VarList) {
23345     assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
23346     SourceLocation ELoc;
23347     SourceRange ERange;
23348     Expr *SimpleRefExpr = RefExpr;
23349     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
23350     if (Res.second) {
23351       // It will be analyzed later.
23352       MVLI.ProcessedVarList.push_back(RefExpr);
23353       PrivateCopies.push_back(nullptr);
23354       Inits.push_back(nullptr);
23355     }
23356     ValueDecl *D = Res.first;
23357     if (!D)
23358       continue;
23359 
23360     QualType Type = D->getType();
23361     Type = Type.getNonReferenceType().getUnqualifiedType();
23362 
23363     auto *VD = dyn_cast<VarDecl>(D);
23364 
23365     // Item should be a pointer or reference to pointer.
23366     if (!Type->isPointerType()) {
23367       Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
23368           << 0 << RefExpr->getSourceRange();
23369       continue;
23370     }
23371 
23372     // Build the private variable and the expression that refers to it.
23373     auto VDPrivate =
23374         buildVarDecl(*this, ELoc, Type, D->getName(),
23375                      D->hasAttrs() ? &D->getAttrs() : nullptr,
23376                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
23377     if (VDPrivate->isInvalidDecl())
23378       continue;
23379 
23380     CurContext->addDecl(VDPrivate);
23381     DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
23382         *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
23383 
23384     // Add temporary variable to initialize the private copy of the pointer.
23385     VarDecl *VDInit =
23386         buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
23387     DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
23388         *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
23389     AddInitializerToDecl(VDPrivate,
23390                          DefaultLvalueConversion(VDInitRefExpr).get(),
23391                          /*DirectInit=*/false);
23392 
23393     // If required, build a capture to implement the privatization initialized
23394     // with the current list item value.
23395     DeclRefExpr *Ref = nullptr;
23396     if (!VD)
23397       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
23398     MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
23399     PrivateCopies.push_back(VDPrivateRefExpr);
23400     Inits.push_back(VDInitRefExpr);
23401 
23402     // We need to add a data sharing attribute for this variable to make sure it
23403     // is correctly captured. A variable that shows up in a use_device_ptr has
23404     // similar properties of a first private variable.
23405     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
23406 
23407     // Create a mappable component for the list item. List items in this clause
23408     // only need a component.
23409     MVLI.VarBaseDeclarations.push_back(D);
23410     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
23411     MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D,
23412                                            /*IsNonContiguous=*/false);
23413   }
23414 
23415   if (MVLI.ProcessedVarList.empty())
23416     return nullptr;
23417 
23418   return OMPUseDevicePtrClause::Create(
23419       Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
23420       MVLI.VarBaseDeclarations, MVLI.VarComponents);
23421 }
23422 
23423 OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
23424                                                 const OMPVarListLocTy &Locs) {
23425   MappableVarListInfo MVLI(VarList);
23426 
23427   for (Expr *RefExpr : VarList) {
23428     assert(RefExpr && "NULL expr in OpenMP use_device_addr clause.");
23429     SourceLocation ELoc;
23430     SourceRange ERange;
23431     Expr *SimpleRefExpr = RefExpr;
23432     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
23433                               /*AllowArraySection=*/true);
23434     if (Res.second) {
23435       // It will be analyzed later.
23436       MVLI.ProcessedVarList.push_back(RefExpr);
23437     }
23438     ValueDecl *D = Res.first;
23439     if (!D)
23440       continue;
23441     auto *VD = dyn_cast<VarDecl>(D);
23442 
23443     // If required, build a capture to implement the privatization initialized
23444     // with the current list item value.
23445     DeclRefExpr *Ref = nullptr;
23446     if (!VD)
23447       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
23448     MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
23449 
23450     // We need to add a data sharing attribute for this variable to make sure it
23451     // is correctly captured. A variable that shows up in a use_device_addr has
23452     // similar properties of a first private variable.
23453     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
23454 
23455     // Create a mappable component for the list item. List items in this clause
23456     // only need a component.
23457     MVLI.VarBaseDeclarations.push_back(D);
23458     MVLI.VarComponents.emplace_back();
23459     Expr *Component = SimpleRefExpr;
23460     if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
23461                isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
23462       Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
23463     MVLI.VarComponents.back().emplace_back(Component, D,
23464                                            /*IsNonContiguous=*/false);
23465   }
23466 
23467   if (MVLI.ProcessedVarList.empty())
23468     return nullptr;
23469 
23470   return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
23471                                         MVLI.VarBaseDeclarations,
23472                                         MVLI.VarComponents);
23473 }
23474 
23475 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
23476                                               const OMPVarListLocTy &Locs) {
23477   MappableVarListInfo MVLI(VarList);
23478   for (Expr *RefExpr : VarList) {
23479     assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
23480     SourceLocation ELoc;
23481     SourceRange ERange;
23482     Expr *SimpleRefExpr = RefExpr;
23483     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
23484     if (Res.second) {
23485       // It will be analyzed later.
23486       MVLI.ProcessedVarList.push_back(RefExpr);
23487     }
23488     ValueDecl *D = Res.first;
23489     if (!D)
23490       continue;
23491 
23492     QualType Type = D->getType();
23493     // item should be a pointer or array or reference to pointer or array
23494     if (!Type.getNonReferenceType()->isPointerType() &&
23495         !Type.getNonReferenceType()->isArrayType()) {
23496       Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
23497           << 0 << RefExpr->getSourceRange();
23498       continue;
23499     }
23500 
23501     // Check if the declaration in the clause does not show up in any data
23502     // sharing attribute.
23503     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
23504     if (isOpenMPPrivate(DVar.CKind)) {
23505       Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
23506           << getOpenMPClauseName(DVar.CKind)
23507           << getOpenMPClauseName(OMPC_is_device_ptr)
23508           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
23509       reportOriginalDsa(*this, DSAStack, D, DVar);
23510       continue;
23511     }
23512 
23513     const Expr *ConflictExpr;
23514     if (DSAStack->checkMappableExprComponentListsForDecl(
23515             D, /*CurrentRegionOnly=*/true,
23516             [&ConflictExpr](
23517                 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
23518                 OpenMPClauseKind) -> bool {
23519               ConflictExpr = R.front().getAssociatedExpression();
23520               return true;
23521             })) {
23522       Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
23523       Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
23524           << ConflictExpr->getSourceRange();
23525       continue;
23526     }
23527 
23528     // Store the components in the stack so that they can be used to check
23529     // against other clauses later on.
23530     OMPClauseMappableExprCommon::MappableComponent MC(
23531         SimpleRefExpr, D, /*IsNonContiguous=*/false);
23532     DSAStack->addMappableExpressionComponents(
23533         D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
23534 
23535     // Record the expression we've just processed.
23536     MVLI.ProcessedVarList.push_back(SimpleRefExpr);
23537 
23538     // Create a mappable component for the list item. List items in this clause
23539     // only need a component. We use a null declaration to signal fields in
23540     // 'this'.
23541     assert((isa<DeclRefExpr>(SimpleRefExpr) ||
23542             isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
23543            "Unexpected device pointer expression!");
23544     MVLI.VarBaseDeclarations.push_back(
23545         isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
23546     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
23547     MVLI.VarComponents.back().push_back(MC);
23548   }
23549 
23550   if (MVLI.ProcessedVarList.empty())
23551     return nullptr;
23552 
23553   return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
23554                                       MVLI.VarBaseDeclarations,
23555                                       MVLI.VarComponents);
23556 }
23557 
23558 OMPClause *Sema::ActOnOpenMPHasDeviceAddrClause(ArrayRef<Expr *> VarList,
23559                                                 const OMPVarListLocTy &Locs) {
23560   MappableVarListInfo MVLI(VarList);
23561   for (Expr *RefExpr : VarList) {
23562     assert(RefExpr && "NULL expr in OpenMP has_device_addr clause.");
23563     SourceLocation ELoc;
23564     SourceRange ERange;
23565     Expr *SimpleRefExpr = RefExpr;
23566     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
23567                               /*AllowArraySection=*/true);
23568     if (Res.second) {
23569       // It will be analyzed later.
23570       MVLI.ProcessedVarList.push_back(RefExpr);
23571     }
23572     ValueDecl *D = Res.first;
23573     if (!D)
23574       continue;
23575 
23576     // Check if the declaration in the clause does not show up in any data
23577     // sharing attribute.
23578     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
23579     if (isOpenMPPrivate(DVar.CKind)) {
23580       Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
23581           << getOpenMPClauseName(DVar.CKind)
23582           << getOpenMPClauseName(OMPC_has_device_addr)
23583           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
23584       reportOriginalDsa(*this, DSAStack, D, DVar);
23585       continue;
23586     }
23587 
23588     const Expr *ConflictExpr;
23589     if (DSAStack->checkMappableExprComponentListsForDecl(
23590             D, /*CurrentRegionOnly=*/true,
23591             [&ConflictExpr](
23592                 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
23593                 OpenMPClauseKind) -> bool {
23594               ConflictExpr = R.front().getAssociatedExpression();
23595               return true;
23596             })) {
23597       Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
23598       Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
23599           << ConflictExpr->getSourceRange();
23600       continue;
23601     }
23602 
23603     // Store the components in the stack so that they can be used to check
23604     // against other clauses later on.
23605     Expr *Component = SimpleRefExpr;
23606     auto *VD = dyn_cast<VarDecl>(D);
23607     if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
23608                isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
23609       Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
23610     OMPClauseMappableExprCommon::MappableComponent MC(
23611         Component, D, /*IsNonContiguous=*/false);
23612     DSAStack->addMappableExpressionComponents(
23613         D, MC, /*WhereFoundClauseKind=*/OMPC_has_device_addr);
23614 
23615     // Record the expression we've just processed.
23616     if (!VD && !CurContext->isDependentContext()) {
23617       DeclRefExpr *Ref =
23618           buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
23619       assert(Ref && "has_device_addr capture failed");
23620       MVLI.ProcessedVarList.push_back(Ref);
23621     } else
23622       MVLI.ProcessedVarList.push_back(RefExpr->IgnoreParens());
23623 
23624     // Create a mappable component for the list item. List items in this clause
23625     // only need a component. We use a null declaration to signal fields in
23626     // 'this'.
23627     assert((isa<DeclRefExpr>(SimpleRefExpr) ||
23628             isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
23629            "Unexpected device pointer expression!");
23630     MVLI.VarBaseDeclarations.push_back(
23631         isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
23632     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
23633     MVLI.VarComponents.back().push_back(MC);
23634   }
23635 
23636   if (MVLI.ProcessedVarList.empty())
23637     return nullptr;
23638 
23639   return OMPHasDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
23640                                         MVLI.VarBaseDeclarations,
23641                                         MVLI.VarComponents);
23642 }
23643 
23644 OMPClause *Sema::ActOnOpenMPAllocateClause(
23645     Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
23646     SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
23647   if (Allocator) {
23648     // OpenMP [2.11.4 allocate Clause, Description]
23649     // allocator is an expression of omp_allocator_handle_t type.
23650     if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack))
23651       return nullptr;
23652 
23653     ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
23654     if (AllocatorRes.isInvalid())
23655       return nullptr;
23656     AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
23657                                              DSAStack->getOMPAllocatorHandleT(),
23658                                              Sema::AA_Initializing,
23659                                              /*AllowExplicit=*/true);
23660     if (AllocatorRes.isInvalid())
23661       return nullptr;
23662     Allocator = AllocatorRes.get();
23663   } else {
23664     // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
23665     // allocate clauses that appear on a target construct or on constructs in a
23666     // target region must specify an allocator expression unless a requires
23667     // directive with the dynamic_allocators clause is present in the same
23668     // compilation unit.
23669     if (LangOpts.OpenMPIsTargetDevice &&
23670         !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
23671       targetDiag(StartLoc, diag::err_expected_allocator_expression);
23672   }
23673   // Analyze and build list of variables.
23674   SmallVector<Expr *, 8> Vars;
23675   for (Expr *RefExpr : VarList) {
23676     assert(RefExpr && "NULL expr in OpenMP private clause.");
23677     SourceLocation ELoc;
23678     SourceRange ERange;
23679     Expr *SimpleRefExpr = RefExpr;
23680     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
23681     if (Res.second) {
23682       // It will be analyzed later.
23683       Vars.push_back(RefExpr);
23684     }
23685     ValueDecl *D = Res.first;
23686     if (!D)
23687       continue;
23688 
23689     auto *VD = dyn_cast<VarDecl>(D);
23690     DeclRefExpr *Ref = nullptr;
23691     if (!VD && !CurContext->isDependentContext())
23692       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
23693     Vars.push_back((VD || CurContext->isDependentContext())
23694                        ? RefExpr->IgnoreParens()
23695                        : Ref);
23696   }
23697 
23698   if (Vars.empty())
23699     return nullptr;
23700 
23701   if (Allocator)
23702     DSAStack->addInnerAllocatorExpr(Allocator);
23703   return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
23704                                    ColonLoc, EndLoc, Vars);
23705 }
23706 
23707 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
23708                                               SourceLocation StartLoc,
23709                                               SourceLocation LParenLoc,
23710                                               SourceLocation EndLoc) {
23711   SmallVector<Expr *, 8> Vars;
23712   for (Expr *RefExpr : VarList) {
23713     assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
23714     SourceLocation ELoc;
23715     SourceRange ERange;
23716     Expr *SimpleRefExpr = RefExpr;
23717     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
23718     if (Res.second)
23719       // It will be analyzed later.
23720       Vars.push_back(RefExpr);
23721     ValueDecl *D = Res.first;
23722     if (!D)
23723       continue;
23724 
23725     // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions.
23726     // A list-item cannot appear in more than one nontemporal clause.
23727     if (const Expr *PrevRef =
23728             DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) {
23729       Diag(ELoc, diag::err_omp_used_in_clause_twice)
23730           << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
23731       Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
23732           << getOpenMPClauseName(OMPC_nontemporal);
23733       continue;
23734     }
23735 
23736     Vars.push_back(RefExpr);
23737   }
23738 
23739   if (Vars.empty())
23740     return nullptr;
23741 
23742   return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc,
23743                                       Vars);
23744 }
23745 
23746 OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList,
23747                                             SourceLocation StartLoc,
23748                                             SourceLocation LParenLoc,
23749                                             SourceLocation EndLoc) {
23750   SmallVector<Expr *, 8> Vars;
23751   for (Expr *RefExpr : VarList) {
23752     assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
23753     SourceLocation ELoc;
23754     SourceRange ERange;
23755     Expr *SimpleRefExpr = RefExpr;
23756     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
23757                               /*AllowArraySection=*/true);
23758     if (Res.second)
23759       // It will be analyzed later.
23760       Vars.push_back(RefExpr);
23761     ValueDecl *D = Res.first;
23762     if (!D)
23763       continue;
23764 
23765     const DSAStackTy::DSAVarData DVar =
23766         DSAStack->getTopDSA(D, /*FromParent=*/true);
23767     // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
23768     // A list item that appears in the inclusive or exclusive clause must appear
23769     // in a reduction clause with the inscan modifier on the enclosing
23770     // worksharing-loop, worksharing-loop SIMD, or simd construct.
23771     if (DVar.CKind != OMPC_reduction || DVar.Modifier != OMPC_REDUCTION_inscan)
23772       Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
23773           << RefExpr->getSourceRange();
23774 
23775     if (DSAStack->getParentDirective() != OMPD_unknown)
23776       DSAStack->markDeclAsUsedInScanDirective(D);
23777     Vars.push_back(RefExpr);
23778   }
23779 
23780   if (Vars.empty())
23781     return nullptr;
23782 
23783   return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
23784 }
23785 
23786 OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList,
23787                                             SourceLocation StartLoc,
23788                                             SourceLocation LParenLoc,
23789                                             SourceLocation EndLoc) {
23790   SmallVector<Expr *, 8> Vars;
23791   for (Expr *RefExpr : VarList) {
23792     assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
23793     SourceLocation ELoc;
23794     SourceRange ERange;
23795     Expr *SimpleRefExpr = RefExpr;
23796     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
23797                               /*AllowArraySection=*/true);
23798     if (Res.second)
23799       // It will be analyzed later.
23800       Vars.push_back(RefExpr);
23801     ValueDecl *D = Res.first;
23802     if (!D)
23803       continue;
23804 
23805     OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective();
23806     DSAStackTy::DSAVarData DVar;
23807     if (ParentDirective != OMPD_unknown)
23808       DVar = DSAStack->getTopDSA(D, /*FromParent=*/true);
23809     // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
23810     // A list item that appears in the inclusive or exclusive clause must appear
23811     // in a reduction clause with the inscan modifier on the enclosing
23812     // worksharing-loop, worksharing-loop SIMD, or simd construct.
23813     if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction ||
23814         DVar.Modifier != OMPC_REDUCTION_inscan) {
23815       Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
23816           << RefExpr->getSourceRange();
23817     } else {
23818       DSAStack->markDeclAsUsedInScanDirective(D);
23819     }
23820     Vars.push_back(RefExpr);
23821   }
23822 
23823   if (Vars.empty())
23824     return nullptr;
23825 
23826   return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
23827 }
23828 
23829 /// Tries to find omp_alloctrait_t type.
23830 static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) {
23831   QualType OMPAlloctraitT = Stack->getOMPAlloctraitT();
23832   if (!OMPAlloctraitT.isNull())
23833     return true;
23834   IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t");
23835   ParsedType PT = S.getTypeName(II, Loc, S.getCurScope());
23836   if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
23837     S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t";
23838     return false;
23839   }
23840   Stack->setOMPAlloctraitT(PT.get());
23841   return true;
23842 }
23843 
23844 OMPClause *Sema::ActOnOpenMPUsesAllocatorClause(
23845     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
23846     ArrayRef<UsesAllocatorsData> Data) {
23847   // OpenMP [2.12.5, target Construct]
23848   // allocator is an identifier of omp_allocator_handle_t type.
23849   if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack))
23850     return nullptr;
23851   // OpenMP [2.12.5, target Construct]
23852   // allocator-traits-array is an identifier of const omp_alloctrait_t * type.
23853   if (llvm::any_of(
23854           Data,
23855           [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) &&
23856       !findOMPAlloctraitT(*this, StartLoc, DSAStack))
23857     return nullptr;
23858   llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators;
23859   for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
23860     auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
23861     StringRef Allocator =
23862         OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
23863     DeclarationName AllocatorName = &Context.Idents.get(Allocator);
23864     PredefinedAllocators.insert(LookupSingleName(
23865         TUScope, AllocatorName, StartLoc, Sema::LookupAnyName));
23866   }
23867 
23868   SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData;
23869   for (const UsesAllocatorsData &D : Data) {
23870     Expr *AllocatorExpr = nullptr;
23871     // Check allocator expression.
23872     if (D.Allocator->isTypeDependent()) {
23873       AllocatorExpr = D.Allocator;
23874     } else {
23875       // Traits were specified - need to assign new allocator to the specified
23876       // allocator, so it must be an lvalue.
23877       AllocatorExpr = D.Allocator->IgnoreParenImpCasts();
23878       auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr);
23879       bool IsPredefinedAllocator = false;
23880       if (DRE) {
23881         OMPAllocateDeclAttr::AllocatorTypeTy AllocatorTy =
23882             getAllocatorKind(*this, DSAStack, AllocatorExpr);
23883         IsPredefinedAllocator =
23884             AllocatorTy !=
23885             OMPAllocateDeclAttr::AllocatorTypeTy::OMPUserDefinedMemAlloc;
23886       }
23887       QualType OMPAllocatorHandleT = DSAStack->getOMPAllocatorHandleT();
23888       QualType AllocatorExprType = AllocatorExpr->getType();
23889       bool IsTypeCompatible = IsPredefinedAllocator;
23890       IsTypeCompatible = IsTypeCompatible ||
23891                          Context.hasSameUnqualifiedType(AllocatorExprType,
23892                                                         OMPAllocatorHandleT);
23893       IsTypeCompatible =
23894           IsTypeCompatible ||
23895           Context.typesAreCompatible(AllocatorExprType, OMPAllocatorHandleT);
23896       bool IsNonConstantLValue =
23897           !AllocatorExprType.isConstant(Context) && AllocatorExpr->isLValue();
23898       if (!DRE || !IsTypeCompatible ||
23899           (!IsPredefinedAllocator && !IsNonConstantLValue)) {
23900         Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected)
23901             << "omp_allocator_handle_t" << (DRE ? 1 : 0)
23902             << AllocatorExpr->getType() << D.Allocator->getSourceRange();
23903         continue;
23904       }
23905       // OpenMP [2.12.5, target Construct]
23906       // Predefined allocators appearing in a uses_allocators clause cannot have
23907       // traits specified.
23908       if (IsPredefinedAllocator && D.AllocatorTraits) {
23909         Diag(D.AllocatorTraits->getExprLoc(),
23910              diag::err_omp_predefined_allocator_with_traits)
23911             << D.AllocatorTraits->getSourceRange();
23912         Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator)
23913             << cast<NamedDecl>(DRE->getDecl())->getName()
23914             << D.Allocator->getSourceRange();
23915         continue;
23916       }
23917       // OpenMP [2.12.5, target Construct]
23918       // Non-predefined allocators appearing in a uses_allocators clause must
23919       // have traits specified.
23920       if (!IsPredefinedAllocator && !D.AllocatorTraits) {
23921         Diag(D.Allocator->getExprLoc(),
23922              diag::err_omp_nonpredefined_allocator_without_traits);
23923         continue;
23924       }
23925       // No allocator traits - just convert it to rvalue.
23926       if (!D.AllocatorTraits)
23927         AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get();
23928       DSAStack->addUsesAllocatorsDecl(
23929           DRE->getDecl(),
23930           IsPredefinedAllocator
23931               ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator
23932               : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator);
23933     }
23934     Expr *AllocatorTraitsExpr = nullptr;
23935     if (D.AllocatorTraits) {
23936       if (D.AllocatorTraits->isTypeDependent()) {
23937         AllocatorTraitsExpr = D.AllocatorTraits;
23938       } else {
23939         // OpenMP [2.12.5, target Construct]
23940         // Arrays that contain allocator traits that appear in a uses_allocators
23941         // clause must be constant arrays, have constant values and be defined
23942         // in the same scope as the construct in which the clause appears.
23943         AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts();
23944         // Check that traits expr is a constant array.
23945         QualType TraitTy;
23946         if (const ArrayType *Ty =
23947                 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe())
23948           if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty))
23949             TraitTy = ConstArrayTy->getElementType();
23950         if (TraitTy.isNull() ||
23951             !(Context.hasSameUnqualifiedType(TraitTy,
23952                                              DSAStack->getOMPAlloctraitT()) ||
23953               Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(),
23954                                          /*CompareUnqualified=*/true))) {
23955           Diag(D.AllocatorTraits->getExprLoc(),
23956                diag::err_omp_expected_array_alloctraits)
23957               << AllocatorTraitsExpr->getType();
23958           continue;
23959         }
23960         // Do not map by default allocator traits if it is a standalone
23961         // variable.
23962         if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr))
23963           DSAStack->addUsesAllocatorsDecl(
23964               DRE->getDecl(),
23965               DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait);
23966       }
23967     }
23968     OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back();
23969     NewD.Allocator = AllocatorExpr;
23970     NewD.AllocatorTraits = AllocatorTraitsExpr;
23971     NewD.LParenLoc = D.LParenLoc;
23972     NewD.RParenLoc = D.RParenLoc;
23973   }
23974   return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc,
23975                                          NewData);
23976 }
23977 
23978 OMPClause *Sema::ActOnOpenMPAffinityClause(
23979     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
23980     SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) {
23981   SmallVector<Expr *, 8> Vars;
23982   for (Expr *RefExpr : Locators) {
23983     assert(RefExpr && "NULL expr in OpenMP shared clause.");
23984     if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) {
23985       // It will be analyzed later.
23986       Vars.push_back(RefExpr);
23987       continue;
23988     }
23989 
23990     SourceLocation ELoc = RefExpr->getExprLoc();
23991     Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts();
23992 
23993     if (!SimpleExpr->isLValue()) {
23994       Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
23995           << 1 << 0 << RefExpr->getSourceRange();
23996       continue;
23997     }
23998 
23999     ExprResult Res;
24000     {
24001       Sema::TentativeAnalysisScope Trap(*this);
24002       Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr);
24003     }
24004     if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
24005         !isa<OMPArrayShapingExpr>(SimpleExpr)) {
24006       Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
24007           << 1 << 0 << RefExpr->getSourceRange();
24008       continue;
24009     }
24010     Vars.push_back(SimpleExpr);
24011   }
24012 
24013   return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
24014                                    EndLoc, Modifier, Vars);
24015 }
24016 
24017 OMPClause *Sema::ActOnOpenMPBindClause(OpenMPBindClauseKind Kind,
24018                                        SourceLocation KindLoc,
24019                                        SourceLocation StartLoc,
24020                                        SourceLocation LParenLoc,
24021                                        SourceLocation EndLoc) {
24022   if (Kind == OMPC_BIND_unknown) {
24023     Diag(KindLoc, diag::err_omp_unexpected_clause_value)
24024         << getListOfPossibleValues(OMPC_bind, /*First=*/0,
24025                                    /*Last=*/unsigned(OMPC_BIND_unknown))
24026         << getOpenMPClauseName(OMPC_bind);
24027     return nullptr;
24028   }
24029 
24030   return OMPBindClause::Create(Context, Kind, KindLoc, StartLoc, LParenLoc,
24031                                EndLoc);
24032 }
24033 
24034 OMPClause *Sema::ActOnOpenMPXDynCGroupMemClause(Expr *Size,
24035                                                 SourceLocation StartLoc,
24036                                                 SourceLocation LParenLoc,
24037                                                 SourceLocation EndLoc) {
24038   Expr *ValExpr = Size;
24039   Stmt *HelperValStmt = nullptr;
24040 
24041   // OpenMP [2.5, Restrictions]
24042   //  The ompx_dyn_cgroup_mem expression must evaluate to a positive integer
24043   //  value.
24044   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_ompx_dyn_cgroup_mem,
24045                                  /*StrictlyPositive=*/false))
24046     return nullptr;
24047 
24048   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
24049   OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
24050       DKind, OMPC_ompx_dyn_cgroup_mem, LangOpts.OpenMP);
24051   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
24052     ValExpr = MakeFullExpr(ValExpr).get();
24053     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
24054     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
24055     HelperValStmt = buildPreInits(Context, Captures);
24056   }
24057 
24058   return new (Context) OMPXDynCGroupMemClause(
24059       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
24060 }
24061 
24062 OMPClause *Sema::ActOnOpenMPDoacrossClause(
24063     OpenMPDoacrossClauseModifier DepType, SourceLocation DepLoc,
24064     SourceLocation ColonLoc, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
24065     SourceLocation LParenLoc, SourceLocation EndLoc) {
24066 
24067   if (DSAStack->getCurrentDirective() == OMPD_ordered &&
24068       DepType != OMPC_DOACROSS_source && DepType != OMPC_DOACROSS_sink &&
24069       DepType != OMPC_DOACROSS_sink_omp_cur_iteration &&
24070       DepType != OMPC_DOACROSS_source_omp_cur_iteration &&
24071       DepType != OMPC_DOACROSS_source) {
24072     Diag(DepLoc, diag::err_omp_unexpected_clause_value)
24073         << "'source' or 'sink'" << getOpenMPClauseName(OMPC_doacross);
24074     return nullptr;
24075   }
24076 
24077   SmallVector<Expr *, 8> Vars;
24078   DSAStackTy::OperatorOffsetTy OpsOffs;
24079   llvm::APSInt TotalDepCount(/*BitWidth=*/32);
24080   DoacrossDataInfoTy VarOffset = ProcessOpenMPDoacrossClauseCommon(
24081       *this,
24082       DepType == OMPC_DOACROSS_source ||
24083           DepType == OMPC_DOACROSS_source_omp_cur_iteration ||
24084           DepType == OMPC_DOACROSS_sink_omp_cur_iteration,
24085       VarList, DSAStack, EndLoc);
24086   Vars = VarOffset.Vars;
24087   OpsOffs = VarOffset.OpsOffs;
24088   TotalDepCount = VarOffset.TotalDepCount;
24089   auto *C = OMPDoacrossClause::Create(Context, StartLoc, LParenLoc, EndLoc,
24090                                       DepType, DepLoc, ColonLoc, Vars,
24091                                       TotalDepCount.getZExtValue());
24092   if (DSAStack->isParentOrderedRegion())
24093     DSAStack->addDoacrossDependClause(C, OpsOffs);
24094   return C;
24095 }
24096