xref: /llvm-project/clang/lib/Sema/SemaOpenMP.cpp (revision ad38e24eb74e97148faec97c4f843b87768b6e9b)
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 "clang/Sema/SemaOpenMP.h"
15 
16 #include "TreeTransform.h"
17 #include "clang/AST/ASTContext.h"
18 #include "clang/AST/ASTMutationListener.h"
19 #include "clang/AST/CXXInheritance.h"
20 #include "clang/AST/Decl.h"
21 #include "clang/AST/DeclCXX.h"
22 #include "clang/AST/DeclOpenMP.h"
23 #include "clang/AST/DynamicRecursiveASTVisitor.h"
24 #include "clang/AST/OpenMPClause.h"
25 #include "clang/AST/StmtCXX.h"
26 #include "clang/AST/StmtOpenMP.h"
27 #include "clang/AST/StmtVisitor.h"
28 #include "clang/Basic/DiagnosticSema.h"
29 #include "clang/Basic/OpenMPKinds.h"
30 #include "clang/Basic/PartialDiagnostic.h"
31 #include "clang/Basic/TargetInfo.h"
32 #include "clang/Sema/EnterExpressionEvaluationContext.h"
33 #include "clang/Sema/Initialization.h"
34 #include "clang/Sema/Lookup.h"
35 #include "clang/Sema/ParsedAttr.h"
36 #include "clang/Sema/Scope.h"
37 #include "clang/Sema/ScopeInfo.h"
38 #include "clang/Sema/Sema.h"
39 #include "llvm/ADT/IndexedMap.h"
40 #include "llvm/ADT/PointerEmbeddedInt.h"
41 #include "llvm/ADT/STLExtras.h"
42 #include "llvm/ADT/Sequence.h"
43 #include "llvm/ADT/SetVector.h"
44 #include "llvm/ADT/SmallSet.h"
45 #include "llvm/ADT/StringExtras.h"
46 #include "llvm/Frontend/OpenMP/OMPAssume.h"
47 #include "llvm/Frontend/OpenMP/OMPConstants.h"
48 #include "llvm/IR/Assumptions.h"
49 #include <optional>
50 
51 using namespace clang;
52 using namespace llvm::omp;
53 
54 //===----------------------------------------------------------------------===//
55 // Stack of data-sharing attributes for variables
56 //===----------------------------------------------------------------------===//
57 
58 static const Expr *checkMapClauseExpressionBase(
59     Sema &SemaRef, Expr *E,
60     OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
61     OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose);
62 
63 namespace {
64 /// Default data sharing attributes, which can be applied to directive.
65 enum DefaultDataSharingAttributes {
66   DSA_unspecified = 0,       /// Data sharing attribute not specified.
67   DSA_none = 1 << 0,         /// Default data sharing attribute 'none'.
68   DSA_shared = 1 << 1,       /// Default data sharing attribute 'shared'.
69   DSA_private = 1 << 2,      /// Default data sharing attribute 'private'.
70   DSA_firstprivate = 1 << 3, /// Default data sharing attribute 'firstprivate'.
71 };
72 
73 /// Stack for tracking declarations used in OpenMP directives and
74 /// clauses and their data-sharing attributes.
75 class DSAStackTy {
76 public:
77   struct DSAVarData {
78     OpenMPDirectiveKind DKind = OMPD_unknown;
79     OpenMPClauseKind CKind = OMPC_unknown;
80     unsigned Modifier = 0;
81     const Expr *RefExpr = nullptr;
82     DeclRefExpr *PrivateCopy = nullptr;
83     SourceLocation ImplicitDSALoc;
84     bool AppliedToPointee = false;
85     DSAVarData() = default;
86     DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
87                const Expr *RefExpr, DeclRefExpr *PrivateCopy,
88                SourceLocation ImplicitDSALoc, unsigned Modifier,
89                bool AppliedToPointee)
90         : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr),
91           PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc),
92           AppliedToPointee(AppliedToPointee) {}
93   };
94   using OperatorOffsetTy =
95       llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>;
96   using DoacrossClauseMapTy = llvm::DenseMap<OMPClause *, OperatorOffsetTy>;
97   /// Kind of the declaration used in the uses_allocators clauses.
98   enum class UsesAllocatorsDeclKind {
99     /// Predefined allocator
100     PredefinedAllocator,
101     /// User-defined allocator
102     UserDefinedAllocator,
103     /// The declaration that represent allocator trait
104     AllocatorTrait,
105   };
106 
107 private:
108   struct DSAInfo {
109     OpenMPClauseKind Attributes = OMPC_unknown;
110     unsigned Modifier = 0;
111     /// Pointer to a reference expression and a flag which shows that the
112     /// variable is marked as lastprivate(true) or not (false).
113     llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
114     DeclRefExpr *PrivateCopy = nullptr;
115     /// true if the attribute is applied to the pointee, not the variable
116     /// itself.
117     bool AppliedToPointee = false;
118   };
119   using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
120   using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
121   using LCDeclInfo = std::pair<unsigned, VarDecl *>;
122   using LoopControlVariablesMapTy =
123       llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
124   /// Struct that associates a component with the clause kind where they are
125   /// found.
126   struct MappedExprComponentTy {
127     OMPClauseMappableExprCommon::MappableExprComponentLists Components;
128     OpenMPClauseKind Kind = OMPC_unknown;
129   };
130   using MappedExprComponentsTy =
131       llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
132   using CriticalsWithHintsTy =
133       llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
134   struct ReductionData {
135     using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
136     SourceRange ReductionRange;
137     llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
138     ReductionData() = default;
139     void set(BinaryOperatorKind BO, SourceRange RR) {
140       ReductionRange = RR;
141       ReductionOp = BO;
142     }
143     void set(const Expr *RefExpr, SourceRange RR) {
144       ReductionRange = RR;
145       ReductionOp = RefExpr;
146     }
147   };
148   using DeclReductionMapTy =
149       llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
150   struct DefaultmapInfo {
151     OpenMPDefaultmapClauseModifier ImplicitBehavior =
152         OMPC_DEFAULTMAP_MODIFIER_unknown;
153     SourceLocation SLoc;
154     DefaultmapInfo() = default;
155     DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc)
156         : ImplicitBehavior(M), SLoc(Loc) {}
157   };
158 
159   struct SharingMapTy {
160     DeclSAMapTy SharingMap;
161     DeclReductionMapTy ReductionMap;
162     UsedRefMapTy AlignedMap;
163     UsedRefMapTy NontemporalMap;
164     MappedExprComponentsTy MappedExprComponents;
165     LoopControlVariablesMapTy LCVMap;
166     DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
167     SourceLocation DefaultAttrLoc;
168     DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown + 1];
169     OpenMPDirectiveKind Directive = OMPD_unknown;
170     DeclarationNameInfo DirectiveName;
171     Scope *CurScope = nullptr;
172     DeclContext *Context = nullptr;
173     SourceLocation ConstructLoc;
174     /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
175     /// get the data (loop counters etc.) about enclosing loop-based construct.
176     /// This data is required during codegen.
177     DoacrossClauseMapTy DoacrossDepends;
178     /// First argument (Expr *) contains optional argument of the
179     /// 'ordered' clause, the second one is true if the regions has 'ordered'
180     /// clause, false otherwise.
181     std::optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
182     bool RegionHasOrderConcurrent = false;
183     unsigned AssociatedLoops = 1;
184     bool HasMutipleLoops = false;
185     const Decl *PossiblyLoopCounter = nullptr;
186     bool NowaitRegion = false;
187     bool UntiedRegion = false;
188     bool CancelRegion = false;
189     bool LoopStart = false;
190     bool BodyComplete = false;
191     SourceLocation PrevScanLocation;
192     SourceLocation PrevOrderedLocation;
193     SourceLocation InnerTeamsRegionLoc;
194     /// Reference to the taskgroup task_reduction reference expression.
195     Expr *TaskgroupReductionRef = nullptr;
196     llvm::DenseSet<QualType> MappedClassesQualTypes;
197     SmallVector<Expr *, 4> InnerUsedAllocators;
198     llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates;
199     /// List of globals marked as declare target link in this target region
200     /// (isOpenMPTargetExecutionDirective(Directive) == true).
201     llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls;
202     /// List of decls used in inclusive/exclusive clauses of the scan directive.
203     llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective;
204     llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind>
205         UsesAllocatorsDecls;
206     /// Data is required on creating capture fields for implicit
207     /// default first|private clause.
208     struct ImplicitDefaultFDInfoTy {
209       /// Field decl.
210       const FieldDecl *FD = nullptr;
211       /// Nesting stack level
212       size_t StackLevel = 0;
213       /// Capture variable decl.
214       VarDecl *VD = nullptr;
215       ImplicitDefaultFDInfoTy(const FieldDecl *FD, size_t StackLevel,
216                               VarDecl *VD)
217           : FD(FD), StackLevel(StackLevel), VD(VD) {}
218     };
219     /// List of captured fields
220     llvm::SmallVector<ImplicitDefaultFDInfoTy, 8>
221         ImplicitDefaultFirstprivateFDs;
222     Expr *DeclareMapperVar = nullptr;
223     SmallVector<VarDecl *, 16> IteratorVarDecls;
224     SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
225                  Scope *CurScope, SourceLocation Loc)
226         : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
227           ConstructLoc(Loc) {}
228     SharingMapTy() = default;
229   };
230 
231   using StackTy = SmallVector<SharingMapTy, 4>;
232 
233   /// Stack of used declaration and their data-sharing attributes.
234   DeclSAMapTy Threadprivates;
235   const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
236   SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack;
237   /// true, if check for DSA must be from parent directive, false, if
238   /// from current directive.
239   OpenMPClauseKind ClauseKindMode = OMPC_unknown;
240   Sema &SemaRef;
241   bool ForceCapturing = false;
242   /// true if all the variables in the target executable directives must be
243   /// captured by reference.
244   bool ForceCaptureByReferenceInTargetExecutable = false;
245   CriticalsWithHintsTy Criticals;
246   unsigned IgnoredStackElements = 0;
247 
248   /// Iterators over the stack iterate in order from innermost to outermost
249   /// directive.
250   using const_iterator = StackTy::const_reverse_iterator;
251   const_iterator begin() const {
252     return Stack.empty() ? const_iterator()
253                          : Stack.back().first.rbegin() + IgnoredStackElements;
254   }
255   const_iterator end() const {
256     return Stack.empty() ? const_iterator() : Stack.back().first.rend();
257   }
258   using iterator = StackTy::reverse_iterator;
259   iterator begin() {
260     return Stack.empty() ? iterator()
261                          : Stack.back().first.rbegin() + IgnoredStackElements;
262   }
263   iterator end() {
264     return Stack.empty() ? iterator() : Stack.back().first.rend();
265   }
266 
267   // Convenience operations to get at the elements of the stack.
268 
269   bool isStackEmpty() const {
270     return Stack.empty() ||
271            Stack.back().second != CurrentNonCapturingFunctionScope ||
272            Stack.back().first.size() <= IgnoredStackElements;
273   }
274   size_t getStackSize() const {
275     return isStackEmpty() ? 0
276                           : Stack.back().first.size() - IgnoredStackElements;
277   }
278 
279   SharingMapTy *getTopOfStackOrNull() {
280     size_t Size = getStackSize();
281     if (Size == 0)
282       return nullptr;
283     return &Stack.back().first[Size - 1];
284   }
285   const SharingMapTy *getTopOfStackOrNull() const {
286     return const_cast<DSAStackTy &>(*this).getTopOfStackOrNull();
287   }
288   SharingMapTy &getTopOfStack() {
289     assert(!isStackEmpty() && "no current directive");
290     return *getTopOfStackOrNull();
291   }
292   const SharingMapTy &getTopOfStack() const {
293     return const_cast<DSAStackTy &>(*this).getTopOfStack();
294   }
295 
296   SharingMapTy *getSecondOnStackOrNull() {
297     size_t Size = getStackSize();
298     if (Size <= 1)
299       return nullptr;
300     return &Stack.back().first[Size - 2];
301   }
302   const SharingMapTy *getSecondOnStackOrNull() const {
303     return const_cast<DSAStackTy &>(*this).getSecondOnStackOrNull();
304   }
305 
306   /// Get the stack element at a certain level (previously returned by
307   /// \c getNestingLevel).
308   ///
309   /// Note that nesting levels count from outermost to innermost, and this is
310   /// the reverse of our iteration order where new inner levels are pushed at
311   /// the front of the stack.
312   SharingMapTy &getStackElemAtLevel(unsigned Level) {
313     assert(Level < getStackSize() && "no such stack element");
314     return Stack.back().first[Level];
315   }
316   const SharingMapTy &getStackElemAtLevel(unsigned Level) const {
317     return const_cast<DSAStackTy &>(*this).getStackElemAtLevel(Level);
318   }
319 
320   DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const;
321 
322   /// Checks if the variable is a local for OpenMP region.
323   bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const;
324 
325   /// Vector of previously declared requires directives
326   SmallVector<const OMPRequiresDecl *, 2> RequiresDecls;
327   /// omp_allocator_handle_t type.
328   QualType OMPAllocatorHandleT;
329   /// omp_depend_t type.
330   QualType OMPDependT;
331   /// omp_event_handle_t type.
332   QualType OMPEventHandleT;
333   /// omp_alloctrait_t type.
334   QualType OMPAlloctraitT;
335   /// Expression for the predefined allocators.
336   Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
337       nullptr};
338   /// Vector of previously encountered target directives
339   SmallVector<SourceLocation, 2> TargetLocations;
340   SourceLocation AtomicLocation;
341   /// Vector of declare variant construct traits.
342   SmallVector<llvm::omp::TraitProperty, 8> ConstructTraits;
343 
344 public:
345   explicit DSAStackTy(Sema &S) : SemaRef(S) {}
346 
347   /// Sets omp_allocator_handle_t type.
348   void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; }
349   /// Gets omp_allocator_handle_t type.
350   QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; }
351   /// Sets omp_alloctrait_t type.
352   void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; }
353   /// Gets omp_alloctrait_t type.
354   QualType getOMPAlloctraitT() const { return OMPAlloctraitT; }
355   /// Sets the given default allocator.
356   void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
357                     Expr *Allocator) {
358     OMPPredefinedAllocators[AllocatorKind] = Allocator;
359   }
360   /// Returns the specified default allocator.
361   Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const {
362     return OMPPredefinedAllocators[AllocatorKind];
363   }
364   /// Sets omp_depend_t type.
365   void setOMPDependT(QualType Ty) { OMPDependT = Ty; }
366   /// Gets omp_depend_t type.
367   QualType getOMPDependT() const { return OMPDependT; }
368 
369   /// Sets omp_event_handle_t type.
370   void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; }
371   /// Gets omp_event_handle_t type.
372   QualType getOMPEventHandleT() const { return OMPEventHandleT; }
373 
374   bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
375   OpenMPClauseKind getClauseParsingMode() const {
376     assert(isClauseParsingMode() && "Must be in clause parsing mode.");
377     return ClauseKindMode;
378   }
379   void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
380 
381   bool isBodyComplete() const {
382     const SharingMapTy *Top = getTopOfStackOrNull();
383     return Top && Top->BodyComplete;
384   }
385   void setBodyComplete() { getTopOfStack().BodyComplete = true; }
386 
387   bool isForceVarCapturing() const { return ForceCapturing; }
388   void setForceVarCapturing(bool V) { ForceCapturing = V; }
389 
390   void setForceCaptureByReferenceInTargetExecutable(bool V) {
391     ForceCaptureByReferenceInTargetExecutable = V;
392   }
393   bool isForceCaptureByReferenceInTargetExecutable() const {
394     return ForceCaptureByReferenceInTargetExecutable;
395   }
396 
397   void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
398             Scope *CurScope, SourceLocation Loc) {
399     assert(!IgnoredStackElements &&
400            "cannot change stack while ignoring elements");
401     if (Stack.empty() ||
402         Stack.back().second != CurrentNonCapturingFunctionScope)
403       Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
404     Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
405     Stack.back().first.back().DefaultAttrLoc = Loc;
406   }
407 
408   void pop() {
409     assert(!IgnoredStackElements &&
410            "cannot change stack while ignoring elements");
411     assert(!Stack.back().first.empty() &&
412            "Data-sharing attributes stack is empty!");
413     Stack.back().first.pop_back();
414   }
415 
416   /// RAII object to temporarily leave the scope of a directive when we want to
417   /// logically operate in its parent.
418   class ParentDirectiveScope {
419     DSAStackTy &Self;
420     bool Active;
421 
422   public:
423     ParentDirectiveScope(DSAStackTy &Self, bool Activate)
424         : Self(Self), Active(false) {
425       if (Activate)
426         enable();
427     }
428     ~ParentDirectiveScope() { disable(); }
429     void disable() {
430       if (Active) {
431         --Self.IgnoredStackElements;
432         Active = false;
433       }
434     }
435     void enable() {
436       if (!Active) {
437         ++Self.IgnoredStackElements;
438         Active = true;
439       }
440     }
441   };
442 
443   /// Marks that we're started loop parsing.
444   void loopInit() {
445     assert(isOpenMPLoopDirective(getCurrentDirective()) &&
446            "Expected loop-based directive.");
447     getTopOfStack().LoopStart = true;
448   }
449   /// Start capturing of the variables in the loop context.
450   void loopStart() {
451     assert(isOpenMPLoopDirective(getCurrentDirective()) &&
452            "Expected loop-based directive.");
453     getTopOfStack().LoopStart = false;
454   }
455   /// true, if variables are captured, false otherwise.
456   bool isLoopStarted() const {
457     assert(isOpenMPLoopDirective(getCurrentDirective()) &&
458            "Expected loop-based directive.");
459     return !getTopOfStack().LoopStart;
460   }
461   /// Marks (or clears) declaration as possibly loop counter.
462   void resetPossibleLoopCounter(const Decl *D = nullptr) {
463     getTopOfStack().PossiblyLoopCounter = D ? D->getCanonicalDecl() : D;
464   }
465   /// Gets the possible loop counter decl.
466   const Decl *getPossiblyLoopCounter() const {
467     return getTopOfStack().PossiblyLoopCounter;
468   }
469   /// Start new OpenMP region stack in new non-capturing function.
470   void pushFunction() {
471     assert(!IgnoredStackElements &&
472            "cannot change stack while ignoring elements");
473     const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
474     assert(!isa<CapturingScopeInfo>(CurFnScope));
475     CurrentNonCapturingFunctionScope = CurFnScope;
476   }
477   /// Pop region stack for non-capturing function.
478   void popFunction(const FunctionScopeInfo *OldFSI) {
479     assert(!IgnoredStackElements &&
480            "cannot change stack while ignoring elements");
481     if (!Stack.empty() && Stack.back().second == OldFSI) {
482       assert(Stack.back().first.empty());
483       Stack.pop_back();
484     }
485     CurrentNonCapturingFunctionScope = nullptr;
486     for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
487       if (!isa<CapturingScopeInfo>(FSI)) {
488         CurrentNonCapturingFunctionScope = FSI;
489         break;
490       }
491     }
492   }
493 
494   void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) {
495     Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
496   }
497   const std::pair<const OMPCriticalDirective *, llvm::APSInt>
498   getCriticalWithHint(const DeclarationNameInfo &Name) const {
499     auto I = Criticals.find(Name.getAsString());
500     if (I != Criticals.end())
501       return I->second;
502     return std::make_pair(nullptr, llvm::APSInt());
503   }
504   /// If 'aligned' declaration for given variable \a D was not seen yet,
505   /// add it and return NULL; otherwise return previous occurrence's expression
506   /// for diagnostics.
507   const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE);
508   /// If 'nontemporal' declaration for given variable \a D was not seen yet,
509   /// add it and return NULL; otherwise return previous occurrence's expression
510   /// for diagnostics.
511   const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE);
512 
513   /// Register specified variable as loop control variable.
514   void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture);
515   /// Check if the specified variable is a loop control variable for
516   /// current 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 isLoopControlVariable(const ValueDecl *D) const;
520   /// Check if the specified variable is a loop control variable for
521   /// parent 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 isParentLoopControlVariable(const ValueDecl *D) const;
525   /// Check if the specified variable is a loop control variable for
526   /// current region.
527   /// \return The index of the loop control variable in the list of associated
528   /// for-loops (from outer to inner).
529   const LCDeclInfo isLoopControlVariable(const ValueDecl *D,
530                                          unsigned Level) const;
531   /// Get the loop control variable for the I-th loop (or nullptr) in
532   /// parent directive.
533   const ValueDecl *getParentLoopControlVariable(unsigned I) const;
534 
535   /// Marks the specified decl \p D as used in scan directive.
536   void markDeclAsUsedInScanDirective(ValueDecl *D) {
537     if (SharingMapTy *Stack = getSecondOnStackOrNull())
538       Stack->UsedInScanDirective.insert(D);
539   }
540 
541   /// Checks if the specified declaration was used in the inner scan directive.
542   bool isUsedInScanDirective(ValueDecl *D) const {
543     if (const SharingMapTy *Stack = getTopOfStackOrNull())
544       return Stack->UsedInScanDirective.contains(D);
545     return false;
546   }
547 
548   /// Adds explicit data sharing attribute to the specified declaration.
549   void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
550               DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0,
551               bool AppliedToPointee = false);
552 
553   /// Adds additional information for the reduction items with the reduction id
554   /// represented as an operator.
555   void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
556                                  BinaryOperatorKind BOK);
557   /// Adds additional information for the reduction items with the reduction id
558   /// represented as reduction identifier.
559   void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
560                                  const Expr *ReductionRef);
561   /// Returns the location and reduction operation from the innermost parent
562   /// region for the given \p D.
563   const DSAVarData
564   getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
565                                    BinaryOperatorKind &BOK,
566                                    Expr *&TaskgroupDescriptor) const;
567   /// Returns the location and reduction operation from the innermost parent
568   /// region for the given \p D.
569   const DSAVarData
570   getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
571                                    const Expr *&ReductionRef,
572                                    Expr *&TaskgroupDescriptor) const;
573   /// Return reduction reference expression for the current taskgroup or
574   /// parallel/worksharing directives with task reductions.
575   Expr *getTaskgroupReductionRef() const {
576     assert((getTopOfStack().Directive == OMPD_taskgroup ||
577             ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
578               isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
579              !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
580            "taskgroup reference expression requested for non taskgroup or "
581            "parallel/worksharing directive.");
582     return getTopOfStack().TaskgroupReductionRef;
583   }
584   /// Checks if the given \p VD declaration is actually a taskgroup reduction
585   /// descriptor variable at the \p Level of OpenMP regions.
586   bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
587     return getStackElemAtLevel(Level).TaskgroupReductionRef &&
588            cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
589                    ->getDecl() == VD;
590   }
591 
592   /// Returns data sharing attributes from top of the stack for the
593   /// specified declaration.
594   const DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
595   /// Returns data-sharing attributes for the specified declaration.
596   const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const;
597   /// Returns data-sharing attributes for the specified declaration.
598   const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const;
599   /// Checks if the specified variables has data-sharing attributes which
600   /// match specified \a CPred predicate in any directive which matches \a DPred
601   /// predicate.
602   const DSAVarData
603   hasDSA(ValueDecl *D,
604          const llvm::function_ref<bool(OpenMPClauseKind, bool,
605                                        DefaultDataSharingAttributes)>
606              CPred,
607          const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
608          bool FromParent) const;
609   /// Checks if the specified variables has data-sharing attributes which
610   /// match specified \a CPred predicate in any innermost directive which
611   /// matches \a DPred predicate.
612   const DSAVarData
613   hasInnermostDSA(ValueDecl *D,
614                   const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
615                   const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
616                   bool FromParent) const;
617   /// Checks if the specified variables has explicit data-sharing
618   /// attributes which match specified \a CPred predicate at the specified
619   /// OpenMP region.
620   bool
621   hasExplicitDSA(const ValueDecl *D,
622                  const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
623                  unsigned Level, bool NotLastprivate = false) const;
624 
625   /// Returns true if the directive at level \Level matches in the
626   /// specified \a DPred predicate.
627   bool hasExplicitDirective(
628       const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
629       unsigned Level) const;
630 
631   /// Finds a directive which matches specified \a DPred predicate.
632   bool hasDirective(
633       const llvm::function_ref<bool(
634           OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)>
635           DPred,
636       bool FromParent) const;
637 
638   /// Returns currently analyzed directive.
639   OpenMPDirectiveKind getCurrentDirective() const {
640     const SharingMapTy *Top = getTopOfStackOrNull();
641     return Top ? Top->Directive : OMPD_unknown;
642   }
643   /// Returns directive kind at specified level.
644   OpenMPDirectiveKind getDirective(unsigned Level) const {
645     assert(!isStackEmpty() && "No directive at specified level.");
646     return getStackElemAtLevel(Level).Directive;
647   }
648   /// Returns the capture region at the specified level.
649   OpenMPDirectiveKind getCaptureRegion(unsigned Level,
650                                        unsigned OpenMPCaptureLevel) const {
651     SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
652     getOpenMPCaptureRegions(CaptureRegions, getDirective(Level));
653     return CaptureRegions[OpenMPCaptureLevel];
654   }
655   /// Returns parent directive.
656   OpenMPDirectiveKind getParentDirective() const {
657     const SharingMapTy *Parent = getSecondOnStackOrNull();
658     return Parent ? Parent->Directive : OMPD_unknown;
659   }
660 
661   /// Add requires decl to internal vector
662   void addRequiresDecl(OMPRequiresDecl *RD) { RequiresDecls.push_back(RD); }
663 
664   /// Checks if the defined 'requires' directive has specified type of clause.
665   template <typename ClauseType> bool hasRequiresDeclWithClause() const {
666     return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
667       return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
668         return isa<ClauseType>(C);
669       });
670     });
671   }
672 
673   /// Checks for a duplicate clause amongst previously declared requires
674   /// directives
675   bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const {
676     bool IsDuplicate = false;
677     for (OMPClause *CNew : ClauseList) {
678       for (const OMPRequiresDecl *D : RequiresDecls) {
679         for (const OMPClause *CPrev : D->clauselists()) {
680           if (CNew->getClauseKind() == CPrev->getClauseKind()) {
681             SemaRef.Diag(CNew->getBeginLoc(),
682                          diag::err_omp_requires_clause_redeclaration)
683                 << getOpenMPClauseName(CNew->getClauseKind());
684             SemaRef.Diag(CPrev->getBeginLoc(),
685                          diag::note_omp_requires_previous_clause)
686                 << getOpenMPClauseName(CPrev->getClauseKind());
687             IsDuplicate = true;
688           }
689         }
690       }
691     }
692     return IsDuplicate;
693   }
694 
695   /// Add location of previously encountered target to internal vector
696   void addTargetDirLocation(SourceLocation LocStart) {
697     TargetLocations.push_back(LocStart);
698   }
699 
700   /// Add location for the first encountered atomic directive.
701   void addAtomicDirectiveLoc(SourceLocation Loc) {
702     if (AtomicLocation.isInvalid())
703       AtomicLocation = Loc;
704   }
705 
706   /// Returns the location of the first encountered atomic directive in the
707   /// module.
708   SourceLocation getAtomicDirectiveLoc() const { return AtomicLocation; }
709 
710   // Return previously encountered target region locations.
711   ArrayRef<SourceLocation> getEncounteredTargetLocs() const {
712     return TargetLocations;
713   }
714 
715   /// Set default data sharing attribute to none.
716   void setDefaultDSANone(SourceLocation Loc) {
717     getTopOfStack().DefaultAttr = DSA_none;
718     getTopOfStack().DefaultAttrLoc = Loc;
719   }
720   /// Set default data sharing attribute to shared.
721   void setDefaultDSAShared(SourceLocation Loc) {
722     getTopOfStack().DefaultAttr = DSA_shared;
723     getTopOfStack().DefaultAttrLoc = Loc;
724   }
725   /// Set default data sharing attribute to private.
726   void setDefaultDSAPrivate(SourceLocation Loc) {
727     getTopOfStack().DefaultAttr = DSA_private;
728     getTopOfStack().DefaultAttrLoc = Loc;
729   }
730   /// Set default data sharing attribute to firstprivate.
731   void setDefaultDSAFirstPrivate(SourceLocation Loc) {
732     getTopOfStack().DefaultAttr = DSA_firstprivate;
733     getTopOfStack().DefaultAttrLoc = Loc;
734   }
735   /// Set default data mapping attribute to Modifier:Kind
736   void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,
737                          OpenMPDefaultmapClauseKind Kind, SourceLocation Loc) {
738     DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind];
739     DMI.ImplicitBehavior = M;
740     DMI.SLoc = Loc;
741   }
742   /// Check whether the implicit-behavior has been set in defaultmap
743   bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) {
744     if (VariableCategory == OMPC_DEFAULTMAP_unknown)
745       return getTopOfStack()
746                      .DefaultmapMap[OMPC_DEFAULTMAP_aggregate]
747                      .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
748              getTopOfStack()
749                      .DefaultmapMap[OMPC_DEFAULTMAP_scalar]
750                      .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
751              getTopOfStack()
752                      .DefaultmapMap[OMPC_DEFAULTMAP_pointer]
753                      .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown;
754     return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
755            OMPC_DEFAULTMAP_MODIFIER_unknown;
756   }
757 
758   ArrayRef<llvm::omp::TraitProperty> getConstructTraits() {
759     return ConstructTraits;
760   }
761   void handleConstructTrait(ArrayRef<llvm::omp::TraitProperty> Traits,
762                             bool ScopeEntry) {
763     if (ScopeEntry)
764       ConstructTraits.append(Traits.begin(), Traits.end());
765     else
766       for (llvm::omp::TraitProperty Trait : llvm::reverse(Traits)) {
767         llvm::omp::TraitProperty Top = ConstructTraits.pop_back_val();
768         assert(Top == Trait && "Something left a trait on the stack!");
769         (void)Trait;
770         (void)Top;
771       }
772   }
773 
774   DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const {
775     return getStackSize() <= Level ? DSA_unspecified
776                                    : getStackElemAtLevel(Level).DefaultAttr;
777   }
778   DefaultDataSharingAttributes getDefaultDSA() const {
779     return isStackEmpty() ? DSA_unspecified : getTopOfStack().DefaultAttr;
780   }
781   SourceLocation getDefaultDSALocation() const {
782     return isStackEmpty() ? SourceLocation() : getTopOfStack().DefaultAttrLoc;
783   }
784   OpenMPDefaultmapClauseModifier
785   getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const {
786     return isStackEmpty()
787                ? OMPC_DEFAULTMAP_MODIFIER_unknown
788                : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior;
789   }
790   OpenMPDefaultmapClauseModifier
791   getDefaultmapModifierAtLevel(unsigned Level,
792                                OpenMPDefaultmapClauseKind Kind) const {
793     return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior;
794   }
795   bool isDefaultmapCapturedByRef(unsigned Level,
796                                  OpenMPDefaultmapClauseKind Kind) const {
797     OpenMPDefaultmapClauseModifier M =
798         getDefaultmapModifierAtLevel(Level, Kind);
799     if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) {
800       return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
801              (M == OMPC_DEFAULTMAP_MODIFIER_to) ||
802              (M == OMPC_DEFAULTMAP_MODIFIER_from) ||
803              (M == OMPC_DEFAULTMAP_MODIFIER_tofrom) ||
804              (M == OMPC_DEFAULTMAP_MODIFIER_present);
805     }
806     return true;
807   }
808   static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M,
809                                      OpenMPDefaultmapClauseKind Kind) {
810     switch (Kind) {
811     case OMPC_DEFAULTMAP_scalar:
812     case OMPC_DEFAULTMAP_pointer:
813       return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) ||
814              (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) ||
815              (M == OMPC_DEFAULTMAP_MODIFIER_default);
816     case OMPC_DEFAULTMAP_aggregate:
817       return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
818     default:
819       break;
820     }
821     llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum");
822   }
823   bool mustBeFirstprivateAtLevel(unsigned Level,
824                                  OpenMPDefaultmapClauseKind Kind) const {
825     OpenMPDefaultmapClauseModifier M =
826         getDefaultmapModifierAtLevel(Level, Kind);
827     return mustBeFirstprivateBase(M, Kind);
828   }
829   bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const {
830     OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind);
831     return mustBeFirstprivateBase(M, Kind);
832   }
833 
834   /// Checks if the specified variable is a threadprivate.
835   bool isThreadPrivate(VarDecl *D) {
836     const DSAVarData DVar = getTopDSA(D, false);
837     return isOpenMPThreadPrivate(DVar.CKind);
838   }
839 
840   /// Marks current region as ordered (it has an 'ordered' clause).
841   void setOrderedRegion(bool IsOrdered, const Expr *Param,
842                         OMPOrderedClause *Clause) {
843     if (IsOrdered)
844       getTopOfStack().OrderedRegion.emplace(Param, Clause);
845     else
846       getTopOfStack().OrderedRegion.reset();
847   }
848   /// Returns true, if region is ordered (has associated 'ordered' clause),
849   /// false - otherwise.
850   bool isOrderedRegion() const {
851     if (const SharingMapTy *Top = getTopOfStackOrNull())
852       return Top->OrderedRegion.has_value();
853     return false;
854   }
855   /// Returns optional parameter for the ordered region.
856   std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
857     if (const SharingMapTy *Top = getTopOfStackOrNull())
858       if (Top->OrderedRegion)
859         return *Top->OrderedRegion;
860     return std::make_pair(nullptr, nullptr);
861   }
862   /// Returns true, if parent region is ordered (has associated
863   /// 'ordered' clause), false - otherwise.
864   bool isParentOrderedRegion() const {
865     if (const SharingMapTy *Parent = getSecondOnStackOrNull())
866       return Parent->OrderedRegion.has_value();
867     return false;
868   }
869   /// Returns optional parameter for the ordered region.
870   std::pair<const Expr *, OMPOrderedClause *>
871   getParentOrderedRegionParam() const {
872     if (const SharingMapTy *Parent = getSecondOnStackOrNull())
873       if (Parent->OrderedRegion)
874         return *Parent->OrderedRegion;
875     return std::make_pair(nullptr, nullptr);
876   }
877   /// Marks current region as having an 'order' clause.
878   void setRegionHasOrderConcurrent(bool HasOrderConcurrent) {
879     getTopOfStack().RegionHasOrderConcurrent = HasOrderConcurrent;
880   }
881   /// Returns true, if parent region is order (has associated
882   /// 'order' clause), false - otherwise.
883   bool isParentOrderConcurrent() const {
884     if (const SharingMapTy *Parent = getSecondOnStackOrNull())
885       return Parent->RegionHasOrderConcurrent;
886     return false;
887   }
888   /// Marks current region as nowait (it has a 'nowait' clause).
889   void setNowaitRegion(bool IsNowait = true) {
890     getTopOfStack().NowaitRegion = IsNowait;
891   }
892   /// Returns true, if parent region is nowait (has associated
893   /// 'nowait' clause), false - otherwise.
894   bool isParentNowaitRegion() const {
895     if (const SharingMapTy *Parent = getSecondOnStackOrNull())
896       return Parent->NowaitRegion;
897     return false;
898   }
899   /// Marks current region as untied (it has a 'untied' clause).
900   void setUntiedRegion(bool IsUntied = true) {
901     getTopOfStack().UntiedRegion = IsUntied;
902   }
903   /// Return true if current region is untied.
904   bool isUntiedRegion() const {
905     const SharingMapTy *Top = getTopOfStackOrNull();
906     return Top ? Top->UntiedRegion : false;
907   }
908   /// Marks parent region as cancel region.
909   void setParentCancelRegion(bool Cancel = true) {
910     if (SharingMapTy *Parent = getSecondOnStackOrNull())
911       Parent->CancelRegion |= Cancel;
912   }
913   /// Return true if current region has inner cancel construct.
914   bool isCancelRegion() const {
915     const SharingMapTy *Top = getTopOfStackOrNull();
916     return Top ? Top->CancelRegion : false;
917   }
918 
919   /// Mark that parent region already has scan directive.
920   void setParentHasScanDirective(SourceLocation Loc) {
921     if (SharingMapTy *Parent = getSecondOnStackOrNull())
922       Parent->PrevScanLocation = Loc;
923   }
924   /// Return true if current region has inner cancel construct.
925   bool doesParentHasScanDirective() const {
926     const SharingMapTy *Top = getSecondOnStackOrNull();
927     return Top ? Top->PrevScanLocation.isValid() : false;
928   }
929   /// Return true if current region has inner cancel construct.
930   SourceLocation getParentScanDirectiveLoc() const {
931     const SharingMapTy *Top = getSecondOnStackOrNull();
932     return Top ? Top->PrevScanLocation : SourceLocation();
933   }
934   /// Mark that parent region already has ordered directive.
935   void setParentHasOrderedDirective(SourceLocation Loc) {
936     if (SharingMapTy *Parent = getSecondOnStackOrNull())
937       Parent->PrevOrderedLocation = Loc;
938   }
939   /// Return true if current region has inner ordered construct.
940   bool doesParentHasOrderedDirective() const {
941     const SharingMapTy *Top = getSecondOnStackOrNull();
942     return Top ? Top->PrevOrderedLocation.isValid() : false;
943   }
944   /// Returns the location of the previously specified ordered directive.
945   SourceLocation getParentOrderedDirectiveLoc() const {
946     const SharingMapTy *Top = getSecondOnStackOrNull();
947     return Top ? Top->PrevOrderedLocation : SourceLocation();
948   }
949 
950   /// Set collapse value for the region.
951   void setAssociatedLoops(unsigned Val) {
952     getTopOfStack().AssociatedLoops = Val;
953     if (Val > 1)
954       getTopOfStack().HasMutipleLoops = true;
955   }
956   /// Return collapse value for region.
957   unsigned getAssociatedLoops() const {
958     const SharingMapTy *Top = getTopOfStackOrNull();
959     return Top ? Top->AssociatedLoops : 0;
960   }
961   /// Returns true if the construct is associated with multiple loops.
962   bool hasMutipleLoops() const {
963     const SharingMapTy *Top = getTopOfStackOrNull();
964     return Top ? Top->HasMutipleLoops : false;
965   }
966 
967   /// Marks current target region as one with closely nested teams
968   /// region.
969   void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
970     if (SharingMapTy *Parent = getSecondOnStackOrNull())
971       Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
972   }
973   /// Returns true, if current region has closely nested teams region.
974   bool hasInnerTeamsRegion() const {
975     return getInnerTeamsRegionLoc().isValid();
976   }
977   /// Returns location of the nested teams region (if any).
978   SourceLocation getInnerTeamsRegionLoc() const {
979     const SharingMapTy *Top = getTopOfStackOrNull();
980     return Top ? Top->InnerTeamsRegionLoc : SourceLocation();
981   }
982 
983   Scope *getCurScope() const {
984     const SharingMapTy *Top = getTopOfStackOrNull();
985     return Top ? Top->CurScope : nullptr;
986   }
987   void setContext(DeclContext *DC) { getTopOfStack().Context = DC; }
988   SourceLocation getConstructLoc() const {
989     const SharingMapTy *Top = getTopOfStackOrNull();
990     return Top ? Top->ConstructLoc : SourceLocation();
991   }
992 
993   /// Do the check specified in \a Check to all component lists and return true
994   /// if any issue is found.
995   bool checkMappableExprComponentListsForDecl(
996       const ValueDecl *VD, bool CurrentRegionOnly,
997       const llvm::function_ref<
998           bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
999                OpenMPClauseKind)>
1000           Check) const {
1001     if (isStackEmpty())
1002       return false;
1003     auto SI = begin();
1004     auto SE = end();
1005 
1006     if (SI == SE)
1007       return false;
1008 
1009     if (CurrentRegionOnly)
1010       SE = std::next(SI);
1011     else
1012       std::advance(SI, 1);
1013 
1014     for (; SI != SE; ++SI) {
1015       auto MI = SI->MappedExprComponents.find(VD);
1016       if (MI != SI->MappedExprComponents.end())
1017         for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
1018              MI->second.Components)
1019           if (Check(L, MI->second.Kind))
1020             return true;
1021     }
1022     return false;
1023   }
1024 
1025   /// Do the check specified in \a Check to all component lists at a given level
1026   /// and return true if any issue is found.
1027   bool checkMappableExprComponentListsForDeclAtLevel(
1028       const ValueDecl *VD, unsigned Level,
1029       const llvm::function_ref<
1030           bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
1031                OpenMPClauseKind)>
1032           Check) const {
1033     if (getStackSize() <= Level)
1034       return false;
1035 
1036     const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1037     auto MI = StackElem.MappedExprComponents.find(VD);
1038     if (MI != StackElem.MappedExprComponents.end())
1039       for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
1040            MI->second.Components)
1041         if (Check(L, MI->second.Kind))
1042           return true;
1043     return false;
1044   }
1045 
1046   /// Create a new mappable expression component list associated with a given
1047   /// declaration and initialize it with the provided list of components.
1048   void addMappableExpressionComponents(
1049       const ValueDecl *VD,
1050       OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
1051       OpenMPClauseKind WhereFoundClauseKind) {
1052     MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
1053     // Create new entry and append the new components there.
1054     MEC.Components.resize(MEC.Components.size() + 1);
1055     MEC.Components.back().append(Components.begin(), Components.end());
1056     MEC.Kind = WhereFoundClauseKind;
1057   }
1058 
1059   unsigned getNestingLevel() const {
1060     assert(!isStackEmpty());
1061     return getStackSize() - 1;
1062   }
1063   void addDoacrossDependClause(OMPClause *C, const OperatorOffsetTy &OpsOffs) {
1064     SharingMapTy *Parent = getSecondOnStackOrNull();
1065     assert(Parent && isOpenMPWorksharingDirective(Parent->Directive));
1066     Parent->DoacrossDepends.try_emplace(C, OpsOffs);
1067   }
1068   llvm::iterator_range<DoacrossClauseMapTy::const_iterator>
1069   getDoacrossDependClauses() const {
1070     const SharingMapTy &StackElem = getTopOfStack();
1071     if (isOpenMPWorksharingDirective(StackElem.Directive)) {
1072       const DoacrossClauseMapTy &Ref = StackElem.DoacrossDepends;
1073       return llvm::make_range(Ref.begin(), Ref.end());
1074     }
1075     return llvm::make_range(StackElem.DoacrossDepends.end(),
1076                             StackElem.DoacrossDepends.end());
1077   }
1078 
1079   // Store types of classes which have been explicitly mapped
1080   void addMappedClassesQualTypes(QualType QT) {
1081     SharingMapTy &StackElem = getTopOfStack();
1082     StackElem.MappedClassesQualTypes.insert(QT);
1083   }
1084 
1085   // Return set of mapped classes types
1086   bool isClassPreviouslyMapped(QualType QT) const {
1087     const SharingMapTy &StackElem = getTopOfStack();
1088     return StackElem.MappedClassesQualTypes.contains(QT);
1089   }
1090 
1091   /// Adds global declare target to the parent target region.
1092   void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) {
1093     assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
1094                E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
1095            "Expected declare target link global.");
1096     for (auto &Elem : *this) {
1097       if (isOpenMPTargetExecutionDirective(Elem.Directive)) {
1098         Elem.DeclareTargetLinkVarDecls.push_back(E);
1099         return;
1100       }
1101     }
1102   }
1103 
1104   /// Returns the list of globals with declare target link if current directive
1105   /// is target.
1106   ArrayRef<DeclRefExpr *> getLinkGlobals() const {
1107     assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) &&
1108            "Expected target executable directive.");
1109     return getTopOfStack().DeclareTargetLinkVarDecls;
1110   }
1111 
1112   /// Adds list of allocators expressions.
1113   void addInnerAllocatorExpr(Expr *E) {
1114     getTopOfStack().InnerUsedAllocators.push_back(E);
1115   }
1116   /// Return list of used allocators.
1117   ArrayRef<Expr *> getInnerAllocators() const {
1118     return getTopOfStack().InnerUsedAllocators;
1119   }
1120   /// Marks the declaration as implicitly firstprivate nin the task-based
1121   /// regions.
1122   void addImplicitTaskFirstprivate(unsigned Level, Decl *D) {
1123     getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D);
1124   }
1125   /// Checks if the decl is implicitly firstprivate in the task-based region.
1126   bool isImplicitTaskFirstprivate(Decl *D) const {
1127     return getTopOfStack().ImplicitTaskFirstprivates.contains(D);
1128   }
1129 
1130   /// Marks decl as used in uses_allocators clause as the allocator.
1131   void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) {
1132     getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind);
1133   }
1134   /// Checks if specified decl is used in uses allocator clause as the
1135   /// allocator.
1136   std::optional<UsesAllocatorsDeclKind>
1137   isUsesAllocatorsDecl(unsigned Level, const Decl *D) const {
1138     const SharingMapTy &StackElem = getTopOfStack();
1139     auto I = StackElem.UsesAllocatorsDecls.find(D);
1140     if (I == StackElem.UsesAllocatorsDecls.end())
1141       return std::nullopt;
1142     return I->getSecond();
1143   }
1144   std::optional<UsesAllocatorsDeclKind>
1145   isUsesAllocatorsDecl(const Decl *D) const {
1146     const SharingMapTy &StackElem = getTopOfStack();
1147     auto I = StackElem.UsesAllocatorsDecls.find(D);
1148     if (I == StackElem.UsesAllocatorsDecls.end())
1149       return std::nullopt;
1150     return I->getSecond();
1151   }
1152 
1153   void addDeclareMapperVarRef(Expr *Ref) {
1154     SharingMapTy &StackElem = getTopOfStack();
1155     StackElem.DeclareMapperVar = Ref;
1156   }
1157   const Expr *getDeclareMapperVarRef() const {
1158     const SharingMapTy *Top = getTopOfStackOrNull();
1159     return Top ? Top->DeclareMapperVar : nullptr;
1160   }
1161 
1162   /// Add a new iterator variable.
1163   void addIteratorVarDecl(VarDecl *VD) {
1164     SharingMapTy &StackElem = getTopOfStack();
1165     StackElem.IteratorVarDecls.push_back(VD->getCanonicalDecl());
1166   }
1167   /// Check if variable declaration is an iterator VarDecl.
1168   bool isIteratorVarDecl(const VarDecl *VD) const {
1169     const SharingMapTy *Top = getTopOfStackOrNull();
1170     if (!Top)
1171       return false;
1172 
1173     return llvm::is_contained(Top->IteratorVarDecls, VD->getCanonicalDecl());
1174   }
1175   /// get captured field from ImplicitDefaultFirstprivateFDs
1176   VarDecl *getImplicitFDCapExprDecl(const FieldDecl *FD) const {
1177     const_iterator I = begin();
1178     const_iterator EndI = end();
1179     size_t StackLevel = getStackSize();
1180     for (; I != EndI; ++I) {
1181       if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private)
1182         break;
1183       StackLevel--;
1184     }
1185     assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI));
1186     if (I == EndI)
1187       return nullptr;
1188     for (const auto &IFD : I->ImplicitDefaultFirstprivateFDs)
1189       if (IFD.FD == FD && IFD.StackLevel == StackLevel)
1190         return IFD.VD;
1191     return nullptr;
1192   }
1193   /// Check if capture decl is field captured in ImplicitDefaultFirstprivateFDs
1194   bool isImplicitDefaultFirstprivateFD(VarDecl *VD) const {
1195     const_iterator I = begin();
1196     const_iterator EndI = end();
1197     for (; I != EndI; ++I)
1198       if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private)
1199         break;
1200     if (I == EndI)
1201       return false;
1202     for (const auto &IFD : I->ImplicitDefaultFirstprivateFDs)
1203       if (IFD.VD == VD)
1204         return true;
1205     return false;
1206   }
1207   /// Store capture FD info in ImplicitDefaultFirstprivateFDs
1208   void addImplicitDefaultFirstprivateFD(const FieldDecl *FD, VarDecl *VD) {
1209     iterator I = begin();
1210     const_iterator EndI = end();
1211     size_t StackLevel = getStackSize();
1212     for (; I != EndI; ++I) {
1213       if (I->DefaultAttr == DSA_private || I->DefaultAttr == DSA_firstprivate) {
1214         I->ImplicitDefaultFirstprivateFDs.emplace_back(FD, StackLevel, VD);
1215         break;
1216       }
1217       StackLevel--;
1218     }
1219     assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI));
1220   }
1221 };
1222 
1223 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1224   return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
1225 }
1226 
1227 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1228   return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) ||
1229          DKind == OMPD_unknown;
1230 }
1231 
1232 } // namespace
1233 
1234 static const Expr *getExprAsWritten(const Expr *E) {
1235   if (const auto *FE = dyn_cast<FullExpr>(E))
1236     E = FE->getSubExpr();
1237 
1238   if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
1239     E = MTE->getSubExpr();
1240 
1241   while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
1242     E = Binder->getSubExpr();
1243 
1244   if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
1245     E = ICE->getSubExprAsWritten();
1246   return E->IgnoreParens();
1247 }
1248 
1249 static Expr *getExprAsWritten(Expr *E) {
1250   return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
1251 }
1252 
1253 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
1254   if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
1255     if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
1256       D = ME->getMemberDecl();
1257 
1258   D = cast<ValueDecl>(D->getCanonicalDecl());
1259   return D;
1260 }
1261 
1262 static ValueDecl *getCanonicalDecl(ValueDecl *D) {
1263   return const_cast<ValueDecl *>(
1264       getCanonicalDecl(const_cast<const ValueDecl *>(D)));
1265 }
1266 
1267 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
1268                                           ValueDecl *D) const {
1269   D = getCanonicalDecl(D);
1270   auto *VD = dyn_cast<VarDecl>(D);
1271   const auto *FD = dyn_cast<FieldDecl>(D);
1272   DSAVarData DVar;
1273   if (Iter == end()) {
1274     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1275     // in a region but not in construct]
1276     //  File-scope or namespace-scope variables referenced in called routines
1277     //  in the region are shared unless they appear in a threadprivate
1278     //  directive.
1279     if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
1280       DVar.CKind = OMPC_shared;
1281 
1282     // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
1283     // in a region but not in construct]
1284     //  Variables with static storage duration that are declared in called
1285     //  routines in the region are shared.
1286     if (VD && VD->hasGlobalStorage())
1287       DVar.CKind = OMPC_shared;
1288 
1289     // Non-static data members are shared by default.
1290     if (FD)
1291       DVar.CKind = OMPC_shared;
1292 
1293     return DVar;
1294   }
1295 
1296   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1297   // in a Construct, C/C++, predetermined, p.1]
1298   // Variables with automatic storage duration that are declared in a scope
1299   // inside the construct are private.
1300   if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
1301       (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
1302     DVar.CKind = OMPC_private;
1303     return DVar;
1304   }
1305 
1306   DVar.DKind = Iter->Directive;
1307   // Explicitly specified attributes and local variables with predetermined
1308   // attributes.
1309   if (Iter->SharingMap.count(D)) {
1310     const DSAInfo &Data = Iter->SharingMap.lookup(D);
1311     DVar.RefExpr = Data.RefExpr.getPointer();
1312     DVar.PrivateCopy = Data.PrivateCopy;
1313     DVar.CKind = Data.Attributes;
1314     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1315     DVar.Modifier = Data.Modifier;
1316     DVar.AppliedToPointee = Data.AppliedToPointee;
1317     return DVar;
1318   }
1319 
1320   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1321   // in a Construct, C/C++, implicitly determined, p.1]
1322   //  In a parallel or task construct, the data-sharing attributes of these
1323   //  variables are determined by the default clause, if present.
1324   switch (Iter->DefaultAttr) {
1325   case DSA_shared:
1326     DVar.CKind = OMPC_shared;
1327     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1328     return DVar;
1329   case DSA_none:
1330     return DVar;
1331   case DSA_firstprivate:
1332     if (VD && VD->getStorageDuration() == SD_Static &&
1333         VD->getDeclContext()->isFileContext()) {
1334       DVar.CKind = OMPC_unknown;
1335     } else {
1336       DVar.CKind = OMPC_firstprivate;
1337     }
1338     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1339     return DVar;
1340   case DSA_private:
1341     // each variable with static storage duration that is declared
1342     // in a namespace or global scope and referenced in the construct,
1343     // and that does not have a predetermined data-sharing attribute
1344     if (VD && VD->getStorageDuration() == SD_Static &&
1345         VD->getDeclContext()->isFileContext()) {
1346       DVar.CKind = OMPC_unknown;
1347     } else {
1348       DVar.CKind = OMPC_private;
1349     }
1350     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1351     return DVar;
1352   case DSA_unspecified:
1353     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1354     // in a Construct, implicitly determined, p.2]
1355     //  In a parallel construct, if no default clause is present, these
1356     //  variables are shared.
1357     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1358     if ((isOpenMPParallelDirective(DVar.DKind) &&
1359          !isOpenMPTaskLoopDirective(DVar.DKind)) ||
1360         isOpenMPTeamsDirective(DVar.DKind)) {
1361       DVar.CKind = OMPC_shared;
1362       return DVar;
1363     }
1364 
1365     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1366     // in a Construct, implicitly determined, p.4]
1367     //  In a task construct, if no default clause is present, a variable that in
1368     //  the enclosing context is determined to be shared by all implicit tasks
1369     //  bound to the current team is shared.
1370     if (isOpenMPTaskingDirective(DVar.DKind)) {
1371       DSAVarData DVarTemp;
1372       const_iterator I = Iter, E = end();
1373       do {
1374         ++I;
1375         // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
1376         // Referenced in a Construct, implicitly determined, p.6]
1377         //  In a task construct, if no default clause is present, a variable
1378         //  whose data-sharing attribute is not determined by the rules above is
1379         //  firstprivate.
1380         DVarTemp = getDSA(I, D);
1381         if (DVarTemp.CKind != OMPC_shared) {
1382           DVar.RefExpr = nullptr;
1383           DVar.CKind = OMPC_firstprivate;
1384           return DVar;
1385         }
1386       } while (I != E && !isImplicitTaskingRegion(I->Directive));
1387       DVar.CKind =
1388           (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1389       return DVar;
1390     }
1391   }
1392   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1393   // in a Construct, implicitly determined, p.3]
1394   //  For constructs other than task, if no default clause is present, these
1395   //  variables inherit their data-sharing attributes from the enclosing
1396   //  context.
1397   return getDSA(++Iter, D);
1398 }
1399 
1400 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
1401                                          const Expr *NewDE) {
1402   assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1403   D = getCanonicalDecl(D);
1404   SharingMapTy &StackElem = getTopOfStack();
1405   auto [It, Inserted] = StackElem.AlignedMap.try_emplace(D, NewDE);
1406   if (Inserted) {
1407     assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1408     return nullptr;
1409   }
1410   assert(It->second && "Unexpected nullptr expr in the aligned map");
1411   return It->second;
1412 }
1413 
1414 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D,
1415                                              const Expr *NewDE) {
1416   assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1417   D = getCanonicalDecl(D);
1418   SharingMapTy &StackElem = getTopOfStack();
1419   auto [It, Inserted] = StackElem.NontemporalMap.try_emplace(D, NewDE);
1420   if (Inserted) {
1421     assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1422     return nullptr;
1423   }
1424   assert(It->second && "Unexpected nullptr expr in the aligned map");
1425   return It->second;
1426 }
1427 
1428 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
1429   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1430   D = getCanonicalDecl(D);
1431   SharingMapTy &StackElem = getTopOfStack();
1432   StackElem.LCVMap.try_emplace(
1433       D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
1434 }
1435 
1436 const DSAStackTy::LCDeclInfo
1437 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
1438   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1439   D = getCanonicalDecl(D);
1440   const SharingMapTy &StackElem = getTopOfStack();
1441   auto It = StackElem.LCVMap.find(D);
1442   if (It != StackElem.LCVMap.end())
1443     return It->second;
1444   return {0, nullptr};
1445 }
1446 
1447 const DSAStackTy::LCDeclInfo
1448 DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const {
1449   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1450   D = getCanonicalDecl(D);
1451   for (unsigned I = Level + 1; I > 0; --I) {
1452     const SharingMapTy &StackElem = getStackElemAtLevel(I - 1);
1453     auto It = StackElem.LCVMap.find(D);
1454     if (It != StackElem.LCVMap.end())
1455       return It->second;
1456   }
1457   return {0, nullptr};
1458 }
1459 
1460 const DSAStackTy::LCDeclInfo
1461 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
1462   const SharingMapTy *Parent = getSecondOnStackOrNull();
1463   assert(Parent && "Data-sharing attributes stack is empty");
1464   D = getCanonicalDecl(D);
1465   auto It = Parent->LCVMap.find(D);
1466   if (It != Parent->LCVMap.end())
1467     return It->second;
1468   return {0, nullptr};
1469 }
1470 
1471 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
1472   const SharingMapTy *Parent = getSecondOnStackOrNull();
1473   assert(Parent && "Data-sharing attributes stack is empty");
1474   if (Parent->LCVMap.size() < I)
1475     return nullptr;
1476   for (const auto &Pair : Parent->LCVMap)
1477     if (Pair.second.first == I)
1478       return Pair.first;
1479   return nullptr;
1480 }
1481 
1482 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
1483                         DeclRefExpr *PrivateCopy, unsigned Modifier,
1484                         bool AppliedToPointee) {
1485   D = getCanonicalDecl(D);
1486   if (A == OMPC_threadprivate) {
1487     DSAInfo &Data = Threadprivates[D];
1488     Data.Attributes = A;
1489     Data.RefExpr.setPointer(E);
1490     Data.PrivateCopy = nullptr;
1491     Data.Modifier = Modifier;
1492   } else {
1493     DSAInfo &Data = getTopOfStack().SharingMap[D];
1494     assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
1495            (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
1496            (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
1497            (isLoopControlVariable(D).first && A == OMPC_private));
1498     Data.Modifier = Modifier;
1499     if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
1500       Data.RefExpr.setInt(/*IntVal=*/true);
1501       return;
1502     }
1503     const bool IsLastprivate =
1504         A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
1505     Data.Attributes = A;
1506     Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1507     Data.PrivateCopy = PrivateCopy;
1508     Data.AppliedToPointee = AppliedToPointee;
1509     if (PrivateCopy) {
1510       DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()];
1511       Data.Modifier = Modifier;
1512       Data.Attributes = A;
1513       Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1514       Data.PrivateCopy = nullptr;
1515       Data.AppliedToPointee = AppliedToPointee;
1516     }
1517   }
1518 }
1519 
1520 /// Build a variable declaration for OpenMP loop iteration variable.
1521 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
1522                              StringRef Name, const AttrVec *Attrs = nullptr,
1523                              DeclRefExpr *OrigRef = nullptr) {
1524   DeclContext *DC = SemaRef.CurContext;
1525   IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
1526   TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
1527   auto *Decl =
1528       VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
1529   if (Attrs) {
1530     for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
1531          I != E; ++I)
1532       Decl->addAttr(*I);
1533   }
1534   Decl->setImplicit();
1535   if (OrigRef) {
1536     Decl->addAttr(
1537         OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
1538   }
1539   return Decl;
1540 }
1541 
1542 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
1543                                      SourceLocation Loc,
1544                                      bool RefersToCapture = false) {
1545   D->setReferenced();
1546   D->markUsed(S.Context);
1547   return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
1548                              SourceLocation(), D, RefersToCapture, Loc, Ty,
1549                              VK_LValue);
1550 }
1551 
1552 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1553                                            BinaryOperatorKind BOK) {
1554   D = getCanonicalDecl(D);
1555   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1556   assert(
1557       getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1558       "Additional reduction info may be specified only for reduction items.");
1559   ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1560   assert(ReductionData.ReductionRange.isInvalid() &&
1561          (getTopOfStack().Directive == OMPD_taskgroup ||
1562           ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1563             isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1564            !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1565          "Additional reduction info may be specified only once for reduction "
1566          "items.");
1567   ReductionData.set(BOK, SR);
1568   Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1569   if (!TaskgroupReductionRef) {
1570     VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1571                                SemaRef.Context.VoidPtrTy, ".task_red.");
1572     TaskgroupReductionRef =
1573         buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1574   }
1575 }
1576 
1577 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1578                                            const Expr *ReductionRef) {
1579   D = getCanonicalDecl(D);
1580   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1581   assert(
1582       getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1583       "Additional reduction info may be specified only for reduction items.");
1584   ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1585   assert(ReductionData.ReductionRange.isInvalid() &&
1586          (getTopOfStack().Directive == OMPD_taskgroup ||
1587           ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1588             isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1589            !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1590          "Additional reduction info may be specified only once for reduction "
1591          "items.");
1592   ReductionData.set(ReductionRef, SR);
1593   Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1594   if (!TaskgroupReductionRef) {
1595     VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1596                                SemaRef.Context.VoidPtrTy, ".task_red.");
1597     TaskgroupReductionRef =
1598         buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1599   }
1600 }
1601 
1602 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1603     const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
1604     Expr *&TaskgroupDescriptor) const {
1605   D = getCanonicalDecl(D);
1606   assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1607   for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1608     const DSAInfo &Data = I->SharingMap.lookup(D);
1609     if (Data.Attributes != OMPC_reduction ||
1610         Data.Modifier != OMPC_REDUCTION_task)
1611       continue;
1612     const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1613     if (!ReductionData.ReductionOp ||
1614         isa<const Expr *>(ReductionData.ReductionOp))
1615       return DSAVarData();
1616     SR = ReductionData.ReductionRange;
1617     BOK = cast<ReductionData::BOKPtrType>(ReductionData.ReductionOp);
1618     assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1619                                        "expression for the descriptor is not "
1620                                        "set.");
1621     TaskgroupDescriptor = I->TaskgroupReductionRef;
1622     return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1623                       Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1624                       /*AppliedToPointee=*/false);
1625   }
1626   return DSAVarData();
1627 }
1628 
1629 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1630     const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
1631     Expr *&TaskgroupDescriptor) const {
1632   D = getCanonicalDecl(D);
1633   assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1634   for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1635     const DSAInfo &Data = I->SharingMap.lookup(D);
1636     if (Data.Attributes != OMPC_reduction ||
1637         Data.Modifier != OMPC_REDUCTION_task)
1638       continue;
1639     const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1640     if (!ReductionData.ReductionOp ||
1641         !isa<const Expr *>(ReductionData.ReductionOp))
1642       return DSAVarData();
1643     SR = ReductionData.ReductionRange;
1644     ReductionRef = cast<const Expr *>(ReductionData.ReductionOp);
1645     assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1646                                        "expression for the descriptor is not "
1647                                        "set.");
1648     TaskgroupDescriptor = I->TaskgroupReductionRef;
1649     return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1650                       Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1651                       /*AppliedToPointee=*/false);
1652   }
1653   return DSAVarData();
1654 }
1655 
1656 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const {
1657   D = D->getCanonicalDecl();
1658   for (const_iterator E = end(); I != E; ++I) {
1659     if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1660         isOpenMPTargetExecutionDirective(I->Directive)) {
1661       if (I->CurScope) {
1662         Scope *TopScope = I->CurScope->getParent();
1663         Scope *CurScope = getCurScope();
1664         while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D))
1665           CurScope = CurScope->getParent();
1666         return CurScope != TopScope;
1667       }
1668       for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent())
1669         if (I->Context == DC)
1670           return true;
1671       return false;
1672     }
1673   }
1674   return false;
1675 }
1676 
1677 static bool isConstNotMutableType(Sema &SemaRef, QualType Type,
1678                                   bool AcceptIfMutable = true,
1679                                   bool *IsClassType = nullptr) {
1680   ASTContext &Context = SemaRef.getASTContext();
1681   Type = Type.getNonReferenceType().getCanonicalType();
1682   bool IsConstant = Type.isConstant(Context);
1683   Type = Context.getBaseElementType(Type);
1684   const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus
1685                                 ? Type->getAsCXXRecordDecl()
1686                                 : nullptr;
1687   if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1688     if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1689       RD = CTD->getTemplatedDecl();
1690   if (IsClassType)
1691     *IsClassType = RD;
1692   return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD &&
1693                          RD->hasDefinition() && RD->hasMutableFields());
1694 }
1695 
1696 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D,
1697                                       QualType Type, OpenMPClauseKind CKind,
1698                                       SourceLocation ELoc,
1699                                       bool AcceptIfMutable = true,
1700                                       bool ListItemNotVar = false) {
1701   ASTContext &Context = SemaRef.getASTContext();
1702   bool IsClassType;
1703   if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) {
1704     unsigned Diag = ListItemNotVar ? diag::err_omp_const_list_item
1705                     : IsClassType  ? diag::err_omp_const_not_mutable_variable
1706                                    : diag::err_omp_const_variable;
1707     SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind);
1708     if (!ListItemNotVar && D) {
1709       const VarDecl *VD = dyn_cast<VarDecl>(D);
1710       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
1711                                VarDecl::DeclarationOnly;
1712       SemaRef.Diag(D->getLocation(),
1713                    IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1714           << D;
1715     }
1716     return true;
1717   }
1718   return false;
1719 }
1720 
1721 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1722                                                    bool FromParent) {
1723   D = getCanonicalDecl(D);
1724   DSAVarData DVar;
1725 
1726   auto *VD = dyn_cast<VarDecl>(D);
1727   auto TI = Threadprivates.find(D);
1728   if (TI != Threadprivates.end()) {
1729     DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1730     DVar.CKind = OMPC_threadprivate;
1731     DVar.Modifier = TI->getSecond().Modifier;
1732     return DVar;
1733   }
1734   if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1735     DVar.RefExpr = buildDeclRefExpr(
1736         SemaRef, VD, D->getType().getNonReferenceType(),
1737         VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1738     DVar.CKind = OMPC_threadprivate;
1739     addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1740     return DVar;
1741   }
1742   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1743   // in a Construct, C/C++, predetermined, p.1]
1744   //  Variables appearing in threadprivate directives are threadprivate.
1745   if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1746        !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1747          SemaRef.getLangOpts().OpenMPUseTLS &&
1748          SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1749       (VD && VD->getStorageClass() == SC_Register &&
1750        VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1751     DVar.RefExpr = buildDeclRefExpr(
1752         SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1753     DVar.CKind = OMPC_threadprivate;
1754     addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1755     return DVar;
1756   }
1757   if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1758       VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1759       !isLoopControlVariable(D).first) {
1760     const_iterator IterTarget =
1761         std::find_if(begin(), end(), [](const SharingMapTy &Data) {
1762           return isOpenMPTargetExecutionDirective(Data.Directive);
1763         });
1764     if (IterTarget != end()) {
1765       const_iterator ParentIterTarget = IterTarget + 1;
1766       for (const_iterator Iter = begin(); Iter != ParentIterTarget; ++Iter) {
1767         if (isOpenMPLocal(VD, Iter)) {
1768           DVar.RefExpr =
1769               buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1770                                D->getLocation());
1771           DVar.CKind = OMPC_threadprivate;
1772           return DVar;
1773         }
1774       }
1775       if (!isClauseParsingMode() || IterTarget != begin()) {
1776         auto DSAIter = IterTarget->SharingMap.find(D);
1777         if (DSAIter != IterTarget->SharingMap.end() &&
1778             isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1779           DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1780           DVar.CKind = OMPC_threadprivate;
1781           return DVar;
1782         }
1783         const_iterator End = end();
1784         if (!SemaRef.OpenMP().isOpenMPCapturedByRef(
1785                 D, std::distance(ParentIterTarget, End),
1786                 /*OpenMPCaptureLevel=*/0)) {
1787           DVar.RefExpr =
1788               buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1789                                IterTarget->ConstructLoc);
1790           DVar.CKind = OMPC_threadprivate;
1791           return DVar;
1792         }
1793       }
1794     }
1795   }
1796 
1797   if (isStackEmpty())
1798     // Not in OpenMP execution region and top scope was already checked.
1799     return DVar;
1800 
1801   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1802   // in a Construct, C/C++, predetermined, p.4]
1803   //  Static data members are shared.
1804   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1805   // in a Construct, C/C++, predetermined, p.7]
1806   //  Variables with static storage duration that are declared in a scope
1807   //  inside the construct are shared.
1808   if (VD && VD->isStaticDataMember()) {
1809     // Check for explicitly specified attributes.
1810     const_iterator I = begin();
1811     const_iterator EndI = end();
1812     if (FromParent && I != EndI)
1813       ++I;
1814     if (I != EndI) {
1815       auto It = I->SharingMap.find(D);
1816       if (It != I->SharingMap.end()) {
1817         const DSAInfo &Data = It->getSecond();
1818         DVar.RefExpr = Data.RefExpr.getPointer();
1819         DVar.PrivateCopy = Data.PrivateCopy;
1820         DVar.CKind = Data.Attributes;
1821         DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1822         DVar.DKind = I->Directive;
1823         DVar.Modifier = Data.Modifier;
1824         DVar.AppliedToPointee = Data.AppliedToPointee;
1825         return DVar;
1826       }
1827     }
1828 
1829     DVar.CKind = OMPC_shared;
1830     return DVar;
1831   }
1832 
1833   auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
1834   // The predetermined shared attribute for const-qualified types having no
1835   // mutable members was removed after OpenMP 3.1.
1836   if (SemaRef.LangOpts.OpenMP <= 31) {
1837     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1838     // in a Construct, C/C++, predetermined, p.6]
1839     //  Variables with const qualified type having no mutable member are
1840     //  shared.
1841     if (isConstNotMutableType(SemaRef, D->getType())) {
1842       // Variables with const-qualified type having no mutable member may be
1843       // listed in a firstprivate clause, even if they are static data members.
1844       DSAVarData DVarTemp = hasInnermostDSA(
1845           D,
1846           [](OpenMPClauseKind C, bool) {
1847             return C == OMPC_firstprivate || C == OMPC_shared;
1848           },
1849           MatchesAlways, FromParent);
1850       if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1851         return DVarTemp;
1852 
1853       DVar.CKind = OMPC_shared;
1854       return DVar;
1855     }
1856   }
1857 
1858   // Explicitly specified attributes and local variables with predetermined
1859   // attributes.
1860   const_iterator I = begin();
1861   const_iterator EndI = end();
1862   if (FromParent && I != EndI)
1863     ++I;
1864   if (I == EndI)
1865     return DVar;
1866   auto It = I->SharingMap.find(D);
1867   if (It != I->SharingMap.end()) {
1868     const DSAInfo &Data = It->getSecond();
1869     DVar.RefExpr = Data.RefExpr.getPointer();
1870     DVar.PrivateCopy = Data.PrivateCopy;
1871     DVar.CKind = Data.Attributes;
1872     DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1873     DVar.DKind = I->Directive;
1874     DVar.Modifier = Data.Modifier;
1875     DVar.AppliedToPointee = Data.AppliedToPointee;
1876   }
1877 
1878   return DVar;
1879 }
1880 
1881 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1882                                                         bool FromParent) const {
1883   if (isStackEmpty()) {
1884     const_iterator I;
1885     return getDSA(I, D);
1886   }
1887   D = getCanonicalDecl(D);
1888   const_iterator StartI = begin();
1889   const_iterator EndI = end();
1890   if (FromParent && StartI != EndI)
1891     ++StartI;
1892   return getDSA(StartI, D);
1893 }
1894 
1895 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1896                                                         unsigned Level) const {
1897   if (getStackSize() <= Level)
1898     return DSAVarData();
1899   D = getCanonicalDecl(D);
1900   const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level);
1901   return getDSA(StartI, D);
1902 }
1903 
1904 const DSAStackTy::DSAVarData
1905 DSAStackTy::hasDSA(ValueDecl *D,
1906                    const llvm::function_ref<bool(OpenMPClauseKind, bool,
1907                                                  DefaultDataSharingAttributes)>
1908                        CPred,
1909                    const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1910                    bool FromParent) const {
1911   if (isStackEmpty())
1912     return {};
1913   D = getCanonicalDecl(D);
1914   const_iterator I = begin();
1915   const_iterator EndI = end();
1916   if (FromParent && I != EndI)
1917     ++I;
1918   for (; I != EndI; ++I) {
1919     if (!DPred(I->Directive) &&
1920         !isImplicitOrExplicitTaskingRegion(I->Directive))
1921       continue;
1922     const_iterator NewI = I;
1923     DSAVarData DVar = getDSA(NewI, D);
1924     if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee, I->DefaultAttr))
1925       return DVar;
1926   }
1927   return {};
1928 }
1929 
1930 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1931     ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1932     const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1933     bool FromParent) const {
1934   if (isStackEmpty())
1935     return {};
1936   D = getCanonicalDecl(D);
1937   const_iterator StartI = begin();
1938   const_iterator EndI = end();
1939   if (FromParent && StartI != EndI)
1940     ++StartI;
1941   if (StartI == EndI || !DPred(StartI->Directive))
1942     return {};
1943   const_iterator NewI = StartI;
1944   DSAVarData DVar = getDSA(NewI, D);
1945   return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee))
1946              ? DVar
1947              : DSAVarData();
1948 }
1949 
1950 bool DSAStackTy::hasExplicitDSA(
1951     const ValueDecl *D,
1952     const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1953     unsigned Level, bool NotLastprivate) const {
1954   if (getStackSize() <= Level)
1955     return false;
1956   D = getCanonicalDecl(D);
1957   const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1958   auto I = StackElem.SharingMap.find(D);
1959   if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() &&
1960       CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) &&
1961       (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1962     return true;
1963   // Check predetermined rules for the loop control variables.
1964   auto LI = StackElem.LCVMap.find(D);
1965   if (LI != StackElem.LCVMap.end())
1966     return CPred(OMPC_private, /*AppliedToPointee=*/false);
1967   return false;
1968 }
1969 
1970 bool DSAStackTy::hasExplicitDirective(
1971     const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1972     unsigned Level) const {
1973   if (getStackSize() <= Level)
1974     return false;
1975   const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1976   return DPred(StackElem.Directive);
1977 }
1978 
1979 bool DSAStackTy::hasDirective(
1980     const llvm::function_ref<bool(OpenMPDirectiveKind,
1981                                   const DeclarationNameInfo &, SourceLocation)>
1982         DPred,
1983     bool FromParent) const {
1984   // We look only in the enclosing region.
1985   size_t Skip = FromParent ? 2 : 1;
1986   for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
1987        I != E; ++I) {
1988     if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1989       return true;
1990   }
1991   return false;
1992 }
1993 
1994 void SemaOpenMP::InitDataSharingAttributesStack() {
1995   VarDataSharingAttributesStack = new DSAStackTy(SemaRef);
1996 }
1997 
1998 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1999 
2000 void SemaOpenMP::pushOpenMPFunctionRegion() { DSAStack->pushFunction(); }
2001 
2002 void SemaOpenMP::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
2003   DSAStack->popFunction(OldFSI);
2004 }
2005 
2006 static bool isOpenMPDeviceDelayedContext(Sema &S) {
2007   assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsTargetDevice &&
2008          "Expected OpenMP device compilation.");
2009   return !S.OpenMP().isInOpenMPTargetExecutionDirective();
2010 }
2011 
2012 namespace {
2013 /// Status of the function emission on the host/device.
2014 enum class FunctionEmissionStatus {
2015   Emitted,
2016   Discarded,
2017   Unknown,
2018 };
2019 } // anonymous namespace
2020 
2021 SemaBase::SemaDiagnosticBuilder
2022 SemaOpenMP::diagIfOpenMPDeviceCode(SourceLocation Loc, unsigned DiagID,
2023                                    const FunctionDecl *FD) {
2024   assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsTargetDevice &&
2025          "Expected OpenMP device compilation.");
2026 
2027   SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
2028   if (FD) {
2029     Sema::FunctionEmissionStatus FES = SemaRef.getEmissionStatus(FD);
2030     switch (FES) {
2031     case Sema::FunctionEmissionStatus::Emitted:
2032       Kind = SemaDiagnosticBuilder::K_Immediate;
2033       break;
2034     case Sema::FunctionEmissionStatus::Unknown:
2035       // TODO: We should always delay diagnostics here in case a target
2036       //       region is in a function we do not emit. However, as the
2037       //       current diagnostics are associated with the function containing
2038       //       the target region and we do not emit that one, we would miss out
2039       //       on diagnostics for the target region itself. We need to anchor
2040       //       the diagnostics with the new generated function *or* ensure we
2041       //       emit diagnostics associated with the surrounding function.
2042       Kind = isOpenMPDeviceDelayedContext(SemaRef)
2043                  ? SemaDiagnosticBuilder::K_Deferred
2044                  : SemaDiagnosticBuilder::K_Immediate;
2045       break;
2046     case Sema::FunctionEmissionStatus::TemplateDiscarded:
2047     case Sema::FunctionEmissionStatus::OMPDiscarded:
2048       Kind = SemaDiagnosticBuilder::K_Nop;
2049       break;
2050     case Sema::FunctionEmissionStatus::CUDADiscarded:
2051       llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation");
2052       break;
2053     }
2054   }
2055 
2056   return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, SemaRef);
2057 }
2058 
2059 SemaBase::SemaDiagnosticBuilder
2060 SemaOpenMP::diagIfOpenMPHostCode(SourceLocation Loc, unsigned DiagID,
2061                                  const FunctionDecl *FD) {
2062   assert(getLangOpts().OpenMP && !getLangOpts().OpenMPIsTargetDevice &&
2063          "Expected OpenMP host compilation.");
2064 
2065   SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
2066   if (FD) {
2067     Sema::FunctionEmissionStatus FES = SemaRef.getEmissionStatus(FD);
2068     switch (FES) {
2069     case Sema::FunctionEmissionStatus::Emitted:
2070       Kind = SemaDiagnosticBuilder::K_Immediate;
2071       break;
2072     case Sema::FunctionEmissionStatus::Unknown:
2073       Kind = SemaDiagnosticBuilder::K_Deferred;
2074       break;
2075     case Sema::FunctionEmissionStatus::TemplateDiscarded:
2076     case Sema::FunctionEmissionStatus::OMPDiscarded:
2077     case Sema::FunctionEmissionStatus::CUDADiscarded:
2078       Kind = SemaDiagnosticBuilder::K_Nop;
2079       break;
2080     }
2081   }
2082 
2083   return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, SemaRef);
2084 }
2085 
2086 static OpenMPDefaultmapClauseKind
2087 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) {
2088   if (LO.OpenMP <= 45) {
2089     if (VD->getType().getNonReferenceType()->isScalarType())
2090       return OMPC_DEFAULTMAP_scalar;
2091     return OMPC_DEFAULTMAP_aggregate;
2092   }
2093   if (VD->getType().getNonReferenceType()->isAnyPointerType())
2094     return OMPC_DEFAULTMAP_pointer;
2095   if (VD->getType().getNonReferenceType()->isScalarType())
2096     return OMPC_DEFAULTMAP_scalar;
2097   return OMPC_DEFAULTMAP_aggregate;
2098 }
2099 
2100 bool SemaOpenMP::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
2101                                        unsigned OpenMPCaptureLevel) const {
2102   assert(getLangOpts().OpenMP && "OpenMP is not allowed");
2103 
2104   ASTContext &Ctx = getASTContext();
2105   bool IsByRef = true;
2106 
2107   // Find the directive that is associated with the provided scope.
2108   D = cast<ValueDecl>(D->getCanonicalDecl());
2109   QualType Ty = D->getType();
2110 
2111   bool IsVariableUsedInMapClause = false;
2112   if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
2113     // This table summarizes how a given variable should be passed to the device
2114     // given its type and the clauses where it appears. This table is based on
2115     // the description in OpenMP 4.5 [2.10.4, target Construct] and
2116     // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
2117     //
2118     // =========================================================================
2119     // | type |  defaultmap   | pvt | first | is_device_ptr |    map   | res.  |
2120     // |      |(tofrom:scalar)|     |  pvt  |               |has_dv_adr|       |
2121     // =========================================================================
2122     // | scl  |               |     |       |       -       |          | bycopy|
2123     // | scl  |               |  -  |   x   |       -       |     -    | bycopy|
2124     // | scl  |               |  x  |   -   |       -       |     -    | null  |
2125     // | scl  |       x       |     |       |       -       |          | byref |
2126     // | scl  |       x       |  -  |   x   |       -       |     -    | bycopy|
2127     // | scl  |       x       |  x  |   -   |       -       |     -    | null  |
2128     // | scl  |               |  -  |   -   |       -       |     x    | byref |
2129     // | scl  |       x       |  -  |   -   |       -       |     x    | byref |
2130     //
2131     // | agg  |      n.a.     |     |       |       -       |          | byref |
2132     // | agg  |      n.a.     |  -  |   x   |       -       |     -    | byref |
2133     // | agg  |      n.a.     |  x  |   -   |       -       |     -    | null  |
2134     // | agg  |      n.a.     |  -  |   -   |       -       |     x    | byref |
2135     // | agg  |      n.a.     |  -  |   -   |       -       |    x[]   | byref |
2136     //
2137     // | ptr  |      n.a.     |     |       |       -       |          | bycopy|
2138     // | ptr  |      n.a.     |  -  |   x   |       -       |     -    | bycopy|
2139     // | ptr  |      n.a.     |  x  |   -   |       -       |     -    | null  |
2140     // | ptr  |      n.a.     |  -  |   -   |       -       |     x    | byref |
2141     // | ptr  |      n.a.     |  -  |   -   |       -       |    x[]   | bycopy|
2142     // | ptr  |      n.a.     |  -  |   -   |       x       |          | bycopy|
2143     // | ptr  |      n.a.     |  -  |   -   |       x       |     x    | bycopy|
2144     // | ptr  |      n.a.     |  -  |   -   |       x       |    x[]   | bycopy|
2145     // =========================================================================
2146     // Legend:
2147     //  scl - scalar
2148     //  ptr - pointer
2149     //  agg - aggregate
2150     //  x - applies
2151     //  - - invalid in this combination
2152     //  [] - mapped with an array section
2153     //  byref - should be mapped by reference
2154     //  byval - should be mapped by value
2155     //  null - initialize a local variable to null on the device
2156     //
2157     // Observations:
2158     //  - All scalar declarations that show up in a map clause have to be passed
2159     //    by reference, because they may have been mapped in the enclosing data
2160     //    environment.
2161     //  - If the scalar value does not fit the size of uintptr, it has to be
2162     //    passed by reference, regardless the result in the table above.
2163     //  - For pointers mapped by value that have either an implicit map or an
2164     //    array section, the runtime library may pass the NULL value to the
2165     //    device instead of the value passed to it by the compiler.
2166 
2167     if (Ty->isReferenceType())
2168       Ty = Ty->castAs<ReferenceType>()->getPointeeType();
2169 
2170     // Locate map clauses and see if the variable being captured is referred to
2171     // in any of those clauses. Here we only care about variables, not fields,
2172     // because fields are part of aggregates.
2173     bool IsVariableAssociatedWithSection = false;
2174 
2175     DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2176         D, Level,
2177         [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection,
2178          D](OMPClauseMappableExprCommon::MappableExprComponentListRef
2179                 MapExprComponents,
2180             OpenMPClauseKind WhereFoundClauseKind) {
2181           // Both map and has_device_addr clauses information influences how a
2182           // variable is captured. E.g. is_device_ptr does not require changing
2183           // the default behavior.
2184           if (WhereFoundClauseKind != OMPC_map &&
2185               WhereFoundClauseKind != OMPC_has_device_addr)
2186             return false;
2187 
2188           auto EI = MapExprComponents.rbegin();
2189           auto EE = MapExprComponents.rend();
2190 
2191           assert(EI != EE && "Invalid map expression!");
2192 
2193           if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2194             IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
2195 
2196           ++EI;
2197           if (EI == EE)
2198             return false;
2199           auto Last = std::prev(EE);
2200           const auto *UO =
2201               dyn_cast<UnaryOperator>(Last->getAssociatedExpression());
2202           if ((UO && UO->getOpcode() == UO_Deref) ||
2203               isa<ArraySubscriptExpr>(Last->getAssociatedExpression()) ||
2204               isa<ArraySectionExpr>(Last->getAssociatedExpression()) ||
2205               isa<MemberExpr>(EI->getAssociatedExpression()) ||
2206               isa<OMPArrayShapingExpr>(Last->getAssociatedExpression())) {
2207             IsVariableAssociatedWithSection = true;
2208             // There is nothing more we need to know about this variable.
2209             return true;
2210           }
2211 
2212           // Keep looking for more map info.
2213           return false;
2214         });
2215 
2216     if (IsVariableUsedInMapClause) {
2217       // If variable is identified in a map clause it is always captured by
2218       // reference except if it is a pointer that is dereferenced somehow.
2219       IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
2220     } else {
2221       // By default, all the data that has a scalar type is mapped by copy
2222       // (except for reduction variables).
2223       // Defaultmap scalar is mutual exclusive to defaultmap pointer
2224       IsByRef = (DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
2225                  !Ty->isAnyPointerType()) ||
2226                 !Ty->isScalarType() ||
2227                 DSAStack->isDefaultmapCapturedByRef(
2228                     Level, getVariableCategoryFromDecl(getLangOpts(), D)) ||
2229                 DSAStack->hasExplicitDSA(
2230                     D,
2231                     [](OpenMPClauseKind K, bool AppliedToPointee) {
2232                       return K == OMPC_reduction && !AppliedToPointee;
2233                     },
2234                     Level);
2235     }
2236   }
2237 
2238   if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
2239     IsByRef =
2240         ((IsVariableUsedInMapClause &&
2241           DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) ==
2242               OMPD_target) ||
2243          !(DSAStack->hasExplicitDSA(
2244                D,
2245                [](OpenMPClauseKind K, bool AppliedToPointee) -> bool {
2246                  return K == OMPC_firstprivate ||
2247                         (K == OMPC_reduction && AppliedToPointee);
2248                },
2249                Level, /*NotLastprivate=*/true) ||
2250            DSAStack->isUsesAllocatorsDecl(Level, D))) &&
2251         // If the variable is artificial and must be captured by value - try to
2252         // capture by value.
2253         !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
2254           !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) &&
2255         // If the variable is implicitly firstprivate and scalar - capture by
2256         // copy
2257         !((DSAStack->getDefaultDSA() == DSA_firstprivate ||
2258            DSAStack->getDefaultDSA() == DSA_private) &&
2259           !DSAStack->hasExplicitDSA(
2260               D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; },
2261               Level) &&
2262           !DSAStack->isLoopControlVariable(D, Level).first);
2263   }
2264 
2265   // When passing data by copy, we need to make sure it fits the uintptr size
2266   // and alignment, because the runtime library only deals with uintptr types.
2267   // If it does not fit the uintptr size, we need to pass the data by reference
2268   // instead.
2269   if (!IsByRef && (Ctx.getTypeSizeInChars(Ty) >
2270                        Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
2271                    Ctx.getAlignOfGlobalVarInChars(Ty, dyn_cast<VarDecl>(D)) >
2272                        Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
2273     IsByRef = true;
2274   }
2275 
2276   return IsByRef;
2277 }
2278 
2279 unsigned SemaOpenMP::getOpenMPNestingLevel() const {
2280   assert(getLangOpts().OpenMP);
2281   return DSAStack->getNestingLevel();
2282 }
2283 
2284 bool SemaOpenMP::isInOpenMPTaskUntiedContext() const {
2285   return isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
2286          DSAStack->isUntiedRegion();
2287 }
2288 
2289 bool SemaOpenMP::isInOpenMPTargetExecutionDirective() const {
2290   return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) &&
2291           !DSAStack->isClauseParsingMode()) ||
2292          DSAStack->hasDirective(
2293              [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2294                 SourceLocation) -> bool {
2295                return isOpenMPTargetExecutionDirective(K);
2296              },
2297              false);
2298 }
2299 
2300 bool SemaOpenMP::isOpenMPRebuildMemberExpr(ValueDecl *D) {
2301   // Only rebuild for Field.
2302   if (!dyn_cast<FieldDecl>(D))
2303     return false;
2304   DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2305       D,
2306       [](OpenMPClauseKind C, bool AppliedToPointee,
2307          DefaultDataSharingAttributes DefaultAttr) {
2308         return isOpenMPPrivate(C) && !AppliedToPointee &&
2309                (DefaultAttr == DSA_firstprivate || DefaultAttr == DSA_private);
2310       },
2311       [](OpenMPDirectiveKind) { return true; },
2312       DSAStack->isClauseParsingMode());
2313   if (DVarPrivate.CKind != OMPC_unknown)
2314     return true;
2315   return false;
2316 }
2317 
2318 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
2319                                              Expr *CaptureExpr, bool WithInit,
2320                                              DeclContext *CurContext,
2321                                              bool AsExpression);
2322 
2323 VarDecl *SemaOpenMP::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
2324                                           unsigned StopAt) {
2325   assert(getLangOpts().OpenMP && "OpenMP is not allowed");
2326   D = getCanonicalDecl(D);
2327 
2328   auto *VD = dyn_cast<VarDecl>(D);
2329   // Do not capture constexpr variables.
2330   if (VD && VD->isConstexpr())
2331     return nullptr;
2332 
2333   // If we want to determine whether the variable should be captured from the
2334   // perspective of the current capturing scope, and we've already left all the
2335   // capturing scopes of the top directive on the stack, check from the
2336   // perspective of its parent directive (if any) instead.
2337   DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2338       *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete());
2339 
2340   // If we are attempting to capture a global variable in a directive with
2341   // 'target' we return true so that this global is also mapped to the device.
2342   //
2343   if (VD && !VD->hasLocalStorage() &&
2344       (SemaRef.getCurCapturedRegion() || SemaRef.getCurBlock() ||
2345        SemaRef.getCurLambda())) {
2346     if (isInOpenMPTargetExecutionDirective()) {
2347       DSAStackTy::DSAVarData DVarTop =
2348           DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
2349       if (DVarTop.CKind != OMPC_unknown && DVarTop.RefExpr)
2350         return VD;
2351       // If the declaration is enclosed in a 'declare target' directive,
2352       // then it should not be captured.
2353       //
2354       if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2355         return nullptr;
2356       CapturedRegionScopeInfo *CSI = nullptr;
2357       for (FunctionScopeInfo *FSI : llvm::drop_begin(
2358                llvm::reverse(SemaRef.FunctionScopes),
2359                CheckScopeInfo ? (SemaRef.FunctionScopes.size() - (StopAt + 1))
2360                               : 0)) {
2361         if (!isa<CapturingScopeInfo>(FSI))
2362           return nullptr;
2363         if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2364           if (RSI->CapRegionKind == CR_OpenMP) {
2365             CSI = RSI;
2366             break;
2367           }
2368       }
2369       assert(CSI && "Failed to find CapturedRegionScopeInfo");
2370       SmallVector<OpenMPDirectiveKind, 4> Regions;
2371       getOpenMPCaptureRegions(Regions,
2372                               DSAStack->getDirective(CSI->OpenMPLevel));
2373       if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task)
2374         return VD;
2375     }
2376     if (isInOpenMPDeclareTargetContext()) {
2377       // Try to mark variable as declare target if it is used in capturing
2378       // regions.
2379       if (getLangOpts().OpenMP <= 45 &&
2380           !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2381         checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
2382       return nullptr;
2383     }
2384   }
2385 
2386   if (CheckScopeInfo) {
2387     bool OpenMPFound = false;
2388     for (unsigned I = StopAt + 1; I > 0; --I) {
2389       FunctionScopeInfo *FSI = SemaRef.FunctionScopes[I - 1];
2390       if (!isa<CapturingScopeInfo>(FSI))
2391         return nullptr;
2392       if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2393         if (RSI->CapRegionKind == CR_OpenMP) {
2394           OpenMPFound = true;
2395           break;
2396         }
2397     }
2398     if (!OpenMPFound)
2399       return nullptr;
2400   }
2401 
2402   if (DSAStack->getCurrentDirective() != OMPD_unknown &&
2403       (!DSAStack->isClauseParsingMode() ||
2404        DSAStack->getParentDirective() != OMPD_unknown)) {
2405     auto &&Info = DSAStack->isLoopControlVariable(D);
2406     if (Info.first ||
2407         (VD && VD->hasLocalStorage() &&
2408          isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) ||
2409         (VD && DSAStack->isForceVarCapturing()))
2410       return VD ? VD : Info.second;
2411     DSAStackTy::DSAVarData DVarTop =
2412         DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
2413     if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) &&
2414         (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee))
2415       return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
2416     // Threadprivate variables must not be captured.
2417     if (isOpenMPThreadPrivate(DVarTop.CKind))
2418       return nullptr;
2419     // The variable is not private or it is the variable in the directive with
2420     // default(none) clause and not used in any clause.
2421     DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2422         D,
2423         [](OpenMPClauseKind C, bool AppliedToPointee, bool) {
2424           return isOpenMPPrivate(C) && !AppliedToPointee;
2425         },
2426         [](OpenMPDirectiveKind) { return true; },
2427         DSAStack->isClauseParsingMode());
2428     // Global shared must not be captured.
2429     if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2430         ((DSAStack->getDefaultDSA() != DSA_none &&
2431           DSAStack->getDefaultDSA() != DSA_private &&
2432           DSAStack->getDefaultDSA() != DSA_firstprivate) ||
2433          DVarTop.CKind == OMPC_shared))
2434       return nullptr;
2435     auto *FD = dyn_cast<FieldDecl>(D);
2436     if (DVarPrivate.CKind != OMPC_unknown && !VD && FD &&
2437         !DVarPrivate.PrivateCopy) {
2438       DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2439           D,
2440           [](OpenMPClauseKind C, bool AppliedToPointee,
2441              DefaultDataSharingAttributes DefaultAttr) {
2442             return isOpenMPPrivate(C) && !AppliedToPointee &&
2443                    (DefaultAttr == DSA_firstprivate ||
2444                     DefaultAttr == DSA_private);
2445           },
2446           [](OpenMPDirectiveKind) { return true; },
2447           DSAStack->isClauseParsingMode());
2448       if (DVarPrivate.CKind == OMPC_unknown)
2449         return nullptr;
2450 
2451       VarDecl *VD = DSAStack->getImplicitFDCapExprDecl(FD);
2452       if (VD)
2453         return VD;
2454       if (SemaRef.getCurrentThisType().isNull())
2455         return nullptr;
2456       Expr *ThisExpr = SemaRef.BuildCXXThisExpr(SourceLocation(),
2457                                                 SemaRef.getCurrentThisType(),
2458                                                 /*IsImplicit=*/true);
2459       const CXXScopeSpec CS = CXXScopeSpec();
2460       Expr *ME = SemaRef.BuildMemberExpr(
2461           ThisExpr, /*IsArrow=*/true, SourceLocation(),
2462           NestedNameSpecifierLoc(), SourceLocation(), FD,
2463           DeclAccessPair::make(FD, FD->getAccess()),
2464           /*HadMultipleCandidates=*/false, DeclarationNameInfo(), FD->getType(),
2465           VK_LValue, OK_Ordinary);
2466       OMPCapturedExprDecl *CD = buildCaptureDecl(
2467           SemaRef, FD->getIdentifier(), ME, DVarPrivate.CKind != OMPC_private,
2468           SemaRef.CurContext->getParent(), /*AsExpression=*/false);
2469       DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
2470           SemaRef, CD, CD->getType().getNonReferenceType(), SourceLocation());
2471       VD = cast<VarDecl>(VDPrivateRefExpr->getDecl());
2472       DSAStack->addImplicitDefaultFirstprivateFD(FD, VD);
2473       return VD;
2474     }
2475     if (DVarPrivate.CKind != OMPC_unknown ||
2476         (VD && (DSAStack->getDefaultDSA() == DSA_none ||
2477                 DSAStack->getDefaultDSA() == DSA_private ||
2478                 DSAStack->getDefaultDSA() == DSA_firstprivate)))
2479       return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2480   }
2481   return nullptr;
2482 }
2483 
2484 void SemaOpenMP::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
2485                                               unsigned Level) const {
2486   FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2487 }
2488 
2489 void SemaOpenMP::startOpenMPLoop() {
2490   assert(getLangOpts().OpenMP && "OpenMP must be enabled.");
2491   if (isOpenMPLoopDirective(DSAStack->getCurrentDirective()))
2492     DSAStack->loopInit();
2493 }
2494 
2495 void SemaOpenMP::startOpenMPCXXRangeFor() {
2496   assert(getLangOpts().OpenMP && "OpenMP must be enabled.");
2497   if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2498     DSAStack->resetPossibleLoopCounter();
2499     DSAStack->loopStart();
2500   }
2501 }
2502 
2503 OpenMPClauseKind SemaOpenMP::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level,
2504                                                  unsigned CapLevel) const {
2505   assert(getLangOpts().OpenMP && "OpenMP is not allowed");
2506   if (DSAStack->getCurrentDirective() != OMPD_unknown &&
2507       (!DSAStack->isClauseParsingMode() ||
2508        DSAStack->getParentDirective() != OMPD_unknown)) {
2509     DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2510         D,
2511         [](OpenMPClauseKind C, bool AppliedToPointee,
2512            DefaultDataSharingAttributes DefaultAttr) {
2513           return isOpenMPPrivate(C) && !AppliedToPointee &&
2514                  DefaultAttr == DSA_private;
2515         },
2516         [](OpenMPDirectiveKind) { return true; },
2517         DSAStack->isClauseParsingMode());
2518     if (DVarPrivate.CKind == OMPC_private && isa<OMPCapturedExprDecl>(D) &&
2519         DSAStack->isImplicitDefaultFirstprivateFD(cast<VarDecl>(D)) &&
2520         !DSAStack->isLoopControlVariable(D).first)
2521       return OMPC_private;
2522   }
2523   if (DSAStack->hasExplicitDirective(isOpenMPTaskingDirective, Level)) {
2524     bool IsTriviallyCopyable =
2525         D->getType().getNonReferenceType().isTriviallyCopyableType(
2526             getASTContext()) &&
2527         !D->getType()
2528              .getNonReferenceType()
2529              .getCanonicalType()
2530              ->getAsCXXRecordDecl();
2531     OpenMPDirectiveKind DKind = DSAStack->getDirective(Level);
2532     SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2533     getOpenMPCaptureRegions(CaptureRegions, DKind);
2534     if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) &&
2535         (IsTriviallyCopyable ||
2536          !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) {
2537       if (DSAStack->hasExplicitDSA(
2538               D,
2539               [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; },
2540               Level, /*NotLastprivate=*/true))
2541         return OMPC_firstprivate;
2542       DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2543       if (DVar.CKind != OMPC_shared &&
2544           !DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) {
2545         DSAStack->addImplicitTaskFirstprivate(Level, D);
2546         return OMPC_firstprivate;
2547       }
2548     }
2549   }
2550   if (isOpenMPLoopDirective(DSAStack->getCurrentDirective()) &&
2551       !isOpenMPLoopTransformationDirective(DSAStack->getCurrentDirective())) {
2552     if (DSAStack->getAssociatedLoops() > 0 && !DSAStack->isLoopStarted()) {
2553       DSAStack->resetPossibleLoopCounter(D);
2554       DSAStack->loopStart();
2555       return OMPC_private;
2556     }
2557     if ((DSAStack->getPossiblyLoopCounter() == D->getCanonicalDecl() ||
2558          DSAStack->isLoopControlVariable(D).first) &&
2559         !DSAStack->hasExplicitDSA(
2560             D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; },
2561             Level) &&
2562         !isOpenMPSimdDirective(DSAStack->getCurrentDirective()))
2563       return OMPC_private;
2564   }
2565   if (const auto *VD = dyn_cast<VarDecl>(D)) {
2566     if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2567         DSAStack->isForceVarCapturing() &&
2568         !DSAStack->hasExplicitDSA(
2569             D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; },
2570             Level))
2571       return OMPC_private;
2572   }
2573   // User-defined allocators are private since they must be defined in the
2574   // context of target region.
2575   if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) &&
2576       DSAStack->isUsesAllocatorsDecl(Level, D).value_or(
2577           DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2578           DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2579     return OMPC_private;
2580   return (DSAStack->hasExplicitDSA(
2581               D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; },
2582               Level) ||
2583           (DSAStack->isClauseParsingMode() &&
2584            DSAStack->getClauseParsingMode() == OMPC_private) ||
2585           // Consider taskgroup reduction descriptor variable a private
2586           // to avoid possible capture in the region.
2587           (DSAStack->hasExplicitDirective(
2588                [](OpenMPDirectiveKind K) {
2589                  return K == OMPD_taskgroup ||
2590                         ((isOpenMPParallelDirective(K) ||
2591                           isOpenMPWorksharingDirective(K)) &&
2592                          !isOpenMPSimdDirective(K));
2593                },
2594                Level) &&
2595            DSAStack->isTaskgroupReductionRef(D, Level)))
2596              ? OMPC_private
2597              : OMPC_unknown;
2598 }
2599 
2600 void SemaOpenMP::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
2601                                       unsigned Level) {
2602   assert(getLangOpts().OpenMP && "OpenMP is not allowed");
2603   D = getCanonicalDecl(D);
2604   OpenMPClauseKind OMPC = OMPC_unknown;
2605   for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) {
2606     const unsigned NewLevel = I - 1;
2607     if (DSAStack->hasExplicitDSA(
2608             D,
2609             [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) {
2610               if (isOpenMPPrivate(K) && !AppliedToPointee) {
2611                 OMPC = K;
2612                 return true;
2613               }
2614               return false;
2615             },
2616             NewLevel))
2617       break;
2618     if (DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2619             D, NewLevel,
2620             [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
2621                OpenMPClauseKind) { return true; })) {
2622       OMPC = OMPC_map;
2623       break;
2624     }
2625     if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2626                                        NewLevel)) {
2627       OMPC = OMPC_map;
2628       if (DSAStack->mustBeFirstprivateAtLevel(
2629               NewLevel, getVariableCategoryFromDecl(getLangOpts(), D)))
2630         OMPC = OMPC_firstprivate;
2631       break;
2632     }
2633   }
2634   if (OMPC != OMPC_unknown)
2635     FD->addAttr(
2636         OMPCaptureKindAttr::CreateImplicit(getASTContext(), unsigned(OMPC)));
2637 }
2638 
2639 bool SemaOpenMP::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level,
2640                                             unsigned CaptureLevel) const {
2641   assert(getLangOpts().OpenMP && "OpenMP is not allowed");
2642   // Return true if the current level is no longer enclosed in a target region.
2643 
2644   SmallVector<OpenMPDirectiveKind, 4> Regions;
2645   getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level));
2646   const auto *VD = dyn_cast<VarDecl>(D);
2647   return VD && !VD->hasLocalStorage() &&
2648          DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2649                                         Level) &&
2650          Regions[CaptureLevel] != OMPD_task;
2651 }
2652 
2653 bool SemaOpenMP::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level,
2654                                             unsigned CaptureLevel) const {
2655   assert(getLangOpts().OpenMP && "OpenMP is not allowed");
2656   // Return true if the current level is no longer enclosed in a target region.
2657 
2658   if (const auto *VD = dyn_cast<VarDecl>(D)) {
2659     if (!VD->hasLocalStorage()) {
2660       if (isInOpenMPTargetExecutionDirective())
2661         return true;
2662       DSAStackTy::DSAVarData TopDVar =
2663           DSAStack->getTopDSA(D, /*FromParent=*/false);
2664       unsigned NumLevels =
2665           getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2666       if (Level == 0)
2667         // non-file scope static variable with default(firstprivate)
2668         // should be global captured.
2669         return (NumLevels == CaptureLevel + 1 &&
2670                 (TopDVar.CKind != OMPC_shared ||
2671                  DSAStack->getDefaultDSA() == DSA_firstprivate));
2672       do {
2673         --Level;
2674         DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2675         if (DVar.CKind != OMPC_shared)
2676           return true;
2677       } while (Level > 0);
2678     }
2679   }
2680   return true;
2681 }
2682 
2683 void SemaOpenMP::DestroyDataSharingAttributesStack() { delete DSAStack; }
2684 
2685 void SemaOpenMP::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,
2686                                                 OMPTraitInfo &TI) {
2687   OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2688 }
2689 
2690 void SemaOpenMP::ActOnOpenMPEndDeclareVariant() {
2691   assert(isInOpenMPDeclareVariantScope() &&
2692          "Not in OpenMP declare variant scope!");
2693 
2694   OMPDeclareVariantScopes.pop_back();
2695 }
2696 
2697 void SemaOpenMP::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller,
2698                                                const FunctionDecl *Callee,
2699                                                SourceLocation Loc) {
2700   assert(getLangOpts().OpenMP && "Expected OpenMP compilation mode.");
2701   std::optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2702       OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl());
2703   // Ignore host functions during device analysis.
2704   if (getLangOpts().OpenMPIsTargetDevice &&
2705       (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host))
2706     return;
2707   // Ignore nohost functions during host analysis.
2708   if (!getLangOpts().OpenMPIsTargetDevice && DevTy &&
2709       *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2710     return;
2711   const FunctionDecl *FD = Callee->getMostRecentDecl();
2712   DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2713   if (getLangOpts().OpenMPIsTargetDevice && DevTy &&
2714       *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2715     // Diagnose host function called during device codegen.
2716     StringRef HostDevTy =
2717         getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host);
2718     Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2719     Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2720          diag::note_omp_marked_device_type_here)
2721         << HostDevTy;
2722     return;
2723   }
2724   if (!getLangOpts().OpenMPIsTargetDevice &&
2725       !getLangOpts().OpenMPOffloadMandatory && DevTy &&
2726       *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 SemaOpenMP::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
2756                                      const DeclarationNameInfo &DirName,
2757                                      Scope *CurScope, SourceLocation Loc) {
2758   DSAStack->push(DKind, DirName, CurScope, Loc);
2759   SemaRef.PushExpressionEvaluationContext(
2760       Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
2761 }
2762 
2763 void SemaOpenMP::StartOpenMPClause(OpenMPClauseKind K) {
2764   DSAStack->setClauseParsingMode(K);
2765 }
2766 
2767 void SemaOpenMP::EndOpenMPClause() {
2768   DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
2769   SemaRef.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->varlist()) {
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 SemaOpenMP::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 
2860   auto FinalizeLastprivate = [&](OMPLastprivateClause *Clause) {
2861     SmallVector<Expr *, 8> PrivateCopies;
2862     for (Expr *DE : Clause->varlist()) {
2863       if (DE->isValueDependent() || DE->isTypeDependent()) {
2864         PrivateCopies.push_back(nullptr);
2865         continue;
2866       }
2867       auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2868       auto *VD = cast<VarDecl>(DRE->getDecl());
2869       QualType Type = VD->getType().getNonReferenceType();
2870       const DSAStackTy::DSAVarData DVar =
2871           DSAStack->getTopDSA(VD, /*FromParent=*/false);
2872       if (DVar.CKind != OMPC_lastprivate) {
2873         // The variable is also a firstprivate, so initialization sequence
2874         // for private copy is generated already.
2875         PrivateCopies.push_back(nullptr);
2876         continue;
2877       }
2878       // Generate helper private variable and initialize it with the
2879       // default value. The address of the original variable is replaced
2880       // by the address of the new private variable in CodeGen. This new
2881       // variable is not added to IdResolver, so the code in the OpenMP
2882       // region uses original variable for proper diagnostics.
2883       VarDecl *VDPrivate = buildVarDecl(
2884           SemaRef, DE->getExprLoc(), Type.getUnqualifiedType(), VD->getName(),
2885           VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
2886       SemaRef.ActOnUninitializedDecl(VDPrivate);
2887       if (VDPrivate->isInvalidDecl()) {
2888         PrivateCopies.push_back(nullptr);
2889         continue;
2890       }
2891       PrivateCopies.push_back(buildDeclRefExpr(
2892           SemaRef, VDPrivate, DE->getType(), DE->getExprLoc()));
2893     }
2894     Clause->setPrivateCopies(PrivateCopies);
2895   };
2896 
2897   auto FinalizeNontemporal = [&](OMPNontemporalClause *Clause) {
2898     // Finalize nontemporal clause by handling private copies, if any.
2899     SmallVector<Expr *, 8> PrivateRefs;
2900     for (Expr *RefExpr : Clause->varlist()) {
2901       assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
2902       SourceLocation ELoc;
2903       SourceRange ERange;
2904       Expr *SimpleRefExpr = RefExpr;
2905       auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
2906       if (Res.second)
2907         // It will be analyzed later.
2908         PrivateRefs.push_back(RefExpr);
2909       ValueDecl *D = Res.first;
2910       if (!D)
2911         continue;
2912 
2913       const DSAStackTy::DSAVarData DVar =
2914           DSAStack->getTopDSA(D, /*FromParent=*/false);
2915       PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2916                                              : SimpleRefExpr);
2917     }
2918     Clause->setPrivateRefs(PrivateRefs);
2919   };
2920 
2921   auto FinalizeAllocators = [&](OMPUsesAllocatorsClause *Clause) {
2922     for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) {
2923       OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I);
2924       auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts());
2925       if (!DRE)
2926         continue;
2927       ValueDecl *VD = DRE->getDecl();
2928       if (!VD || !isa<VarDecl>(VD))
2929         continue;
2930       DSAStackTy::DSAVarData DVar =
2931           DSAStack->getTopDSA(VD, /*FromParent=*/false);
2932       // OpenMP [2.12.5, target Construct]
2933       // Memory allocators that appear in a uses_allocators clause cannot
2934       // appear in other data-sharing attribute clauses or data-mapping
2935       // attribute clauses in the same construct.
2936       Expr *MapExpr = nullptr;
2937       if (DVar.RefExpr ||
2938           DSAStack->checkMappableExprComponentListsForDecl(
2939               VD, /*CurrentRegionOnly=*/true,
2940               [VD, &MapExpr](
2941                   OMPClauseMappableExprCommon::MappableExprComponentListRef
2942                       MapExprComponents,
2943                   OpenMPClauseKind C) {
2944                 auto MI = MapExprComponents.rbegin();
2945                 auto ME = MapExprComponents.rend();
2946                 if (MI != ME &&
2947                     MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2948                         VD->getCanonicalDecl()) {
2949                   MapExpr = MI->getAssociatedExpression();
2950                   return true;
2951                 }
2952                 return false;
2953               })) {
2954         Diag(D.Allocator->getExprLoc(), diag::err_omp_allocator_used_in_clauses)
2955             << D.Allocator->getSourceRange();
2956         if (DVar.RefExpr)
2957           reportOriginalDsa(SemaRef, DSAStack, VD, DVar);
2958         else
2959           Diag(MapExpr->getExprLoc(), diag::note_used_here)
2960               << MapExpr->getSourceRange();
2961       }
2962     }
2963   };
2964 
2965   if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2966     for (OMPClause *C : D->clauses()) {
2967       if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2968         FinalizeLastprivate(Clause);
2969       } else if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) {
2970         FinalizeNontemporal(Clause);
2971       } else if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) {
2972         FinalizeAllocators(Clause);
2973       }
2974     }
2975     // Check allocate clauses.
2976     if (!SemaRef.CurContext->isDependentContext())
2977       checkAllocateClauses(SemaRef, DSAStack, D->clauses());
2978     checkReductionClauses(SemaRef, DSAStack, D->clauses());
2979   }
2980 
2981   DSAStack->pop();
2982   SemaRef.DiscardCleanupsInEvaluationContext();
2983   SemaRef.PopExpressionEvaluationContext();
2984 }
2985 
2986 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
2987                                      Expr *NumIterations, Sema &SemaRef,
2988                                      Scope *S, DSAStackTy *Stack);
2989 
2990 static bool finishLinearClauses(Sema &SemaRef, ArrayRef<OMPClause *> Clauses,
2991                                 OMPLoopBasedDirective::HelperExprs &B,
2992                                 DSAStackTy *Stack) {
2993   assert((SemaRef.CurContext->isDependentContext() || B.builtAll()) &&
2994          "loop exprs were not built");
2995 
2996   if (SemaRef.CurContext->isDependentContext())
2997     return false;
2998 
2999   // Finalize the clauses that need pre-built expressions for CodeGen.
3000   for (OMPClause *C : Clauses) {
3001     auto *LC = dyn_cast<OMPLinearClause>(C);
3002     if (!LC)
3003       continue;
3004     if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
3005                                  B.NumIterations, SemaRef,
3006                                  SemaRef.getCurScope(), Stack))
3007       return true;
3008   }
3009 
3010   return false;
3011 }
3012 
3013 namespace {
3014 
3015 class VarDeclFilterCCC final : public CorrectionCandidateCallback {
3016 private:
3017   Sema &SemaRef;
3018 
3019 public:
3020   explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
3021   bool ValidateCandidate(const TypoCorrection &Candidate) override {
3022     NamedDecl *ND = Candidate.getCorrectionDecl();
3023     if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
3024       return VD->hasGlobalStorage() &&
3025              SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
3026                                    SemaRef.getCurScope());
3027     }
3028     return false;
3029   }
3030 
3031   std::unique_ptr<CorrectionCandidateCallback> clone() override {
3032     return std::make_unique<VarDeclFilterCCC>(*this);
3033   }
3034 };
3035 
3036 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
3037 private:
3038   Sema &SemaRef;
3039 
3040 public:
3041   explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
3042   bool ValidateCandidate(const TypoCorrection &Candidate) override {
3043     NamedDecl *ND = Candidate.getCorrectionDecl();
3044     if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
3045                isa<FunctionDecl>(ND))) {
3046       return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
3047                                    SemaRef.getCurScope());
3048     }
3049     return false;
3050   }
3051 
3052   std::unique_ptr<CorrectionCandidateCallback> clone() override {
3053     return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
3054   }
3055 };
3056 
3057 } // namespace
3058 
3059 ExprResult SemaOpenMP::ActOnOpenMPIdExpression(Scope *CurScope,
3060                                                CXXScopeSpec &ScopeSpec,
3061                                                const DeclarationNameInfo &Id,
3062                                                OpenMPDirectiveKind Kind) {
3063   ASTContext &Context = getASTContext();
3064   LookupResult Lookup(SemaRef, Id, Sema::LookupOrdinaryName);
3065   SemaRef.LookupParsedName(Lookup, CurScope, &ScopeSpec,
3066                            /*ObjectType=*/QualType(),
3067                            /*AllowBuiltinCreation=*/true);
3068 
3069   if (Lookup.isAmbiguous())
3070     return ExprError();
3071 
3072   VarDecl *VD;
3073   if (!Lookup.isSingleResult()) {
3074     VarDeclFilterCCC CCC(SemaRef);
3075     if (TypoCorrection Corrected =
3076             SemaRef.CorrectTypo(Id, Sema::LookupOrdinaryName, CurScope, nullptr,
3077                                 CCC, Sema::CTK_ErrorRecovery)) {
3078       SemaRef.diagnoseTypo(
3079           Corrected,
3080           SemaRef.PDiag(Lookup.empty() ? diag::err_undeclared_var_use_suggest
3081                                        : diag::err_omp_expected_var_arg_suggest)
3082               << Id.getName());
3083       VD = Corrected.getCorrectionDeclAs<VarDecl>();
3084     } else {
3085       Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
3086                                        : diag::err_omp_expected_var_arg)
3087           << Id.getName();
3088       return ExprError();
3089     }
3090   } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
3091     Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
3092     Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
3093     return ExprError();
3094   }
3095   Lookup.suppressDiagnostics();
3096 
3097   // OpenMP [2.9.2, Syntax, C/C++]
3098   //   Variables must be file-scope, namespace-scope, or static block-scope.
3099   if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
3100     Diag(Id.getLoc(), diag::err_omp_global_var_arg)
3101         << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
3102     bool IsDecl =
3103         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3104     Diag(VD->getLocation(),
3105          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3106         << VD;
3107     return ExprError();
3108   }
3109 
3110   VarDecl *CanonicalVD = VD->getCanonicalDecl();
3111   NamedDecl *ND = CanonicalVD;
3112   // OpenMP [2.9.2, Restrictions, C/C++, p.2]
3113   //   A threadprivate directive for file-scope variables must appear outside
3114   //   any definition or declaration.
3115   if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
3116       !SemaRef.getCurLexicalContext()->isTranslationUnit()) {
3117     Diag(Id.getLoc(), diag::err_omp_var_scope)
3118         << getOpenMPDirectiveName(Kind) << VD;
3119     bool IsDecl =
3120         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3121     Diag(VD->getLocation(),
3122          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3123         << VD;
3124     return ExprError();
3125   }
3126   // OpenMP [2.9.2, Restrictions, C/C++, p.3]
3127   //   A threadprivate directive for static class member variables must appear
3128   //   in the class definition, in the same scope in which the member
3129   //   variables are declared.
3130   if (CanonicalVD->isStaticDataMember() &&
3131       !CanonicalVD->getDeclContext()->Equals(SemaRef.getCurLexicalContext())) {
3132     Diag(Id.getLoc(), diag::err_omp_var_scope)
3133         << getOpenMPDirectiveName(Kind) << VD;
3134     bool IsDecl =
3135         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3136     Diag(VD->getLocation(),
3137          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3138         << VD;
3139     return ExprError();
3140   }
3141   // OpenMP [2.9.2, Restrictions, C/C++, p.4]
3142   //   A threadprivate directive for namespace-scope variables must appear
3143   //   outside any definition or declaration other than the namespace
3144   //   definition itself.
3145   if (CanonicalVD->getDeclContext()->isNamespace() &&
3146       (!SemaRef.getCurLexicalContext()->isFileContext() ||
3147        !SemaRef.getCurLexicalContext()->Encloses(
3148            CanonicalVD->getDeclContext()))) {
3149     Diag(Id.getLoc(), diag::err_omp_var_scope)
3150         << getOpenMPDirectiveName(Kind) << VD;
3151     bool IsDecl =
3152         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3153     Diag(VD->getLocation(),
3154          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3155         << VD;
3156     return ExprError();
3157   }
3158   // OpenMP [2.9.2, Restrictions, C/C++, p.6]
3159   //   A threadprivate directive for static block-scope variables must appear
3160   //   in the scope of the variable and not in a nested scope.
3161   if (CanonicalVD->isLocalVarDecl() && CurScope &&
3162       !SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), CurScope)) {
3163     Diag(Id.getLoc(), diag::err_omp_var_scope)
3164         << getOpenMPDirectiveName(Kind) << VD;
3165     bool IsDecl =
3166         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3167     Diag(VD->getLocation(),
3168          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3169         << VD;
3170     return ExprError();
3171   }
3172 
3173   // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
3174   //   A threadprivate directive must lexically precede all references to any
3175   //   of the variables in its list.
3176   if (Kind == OMPD_threadprivate && VD->isUsed() &&
3177       !DSAStack->isThreadPrivate(VD)) {
3178     Diag(Id.getLoc(), diag::err_omp_var_used)
3179         << getOpenMPDirectiveName(Kind) << VD;
3180     return ExprError();
3181   }
3182 
3183   QualType ExprType = VD->getType().getNonReferenceType();
3184   return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
3185                              SourceLocation(), VD,
3186                              /*RefersToEnclosingVariableOrCapture=*/false,
3187                              Id.getLoc(), ExprType, VK_LValue);
3188 }
3189 
3190 SemaOpenMP::DeclGroupPtrTy
3191 SemaOpenMP::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
3192                                               ArrayRef<Expr *> VarList) {
3193   if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
3194     SemaRef.CurContext->addDecl(D);
3195     return DeclGroupPtrTy::make(DeclGroupRef(D));
3196   }
3197   return nullptr;
3198 }
3199 
3200 namespace {
3201 class LocalVarRefChecker final
3202     : public ConstStmtVisitor<LocalVarRefChecker, bool> {
3203   Sema &SemaRef;
3204 
3205 public:
3206   bool VisitDeclRefExpr(const DeclRefExpr *E) {
3207     if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3208       if (VD->hasLocalStorage()) {
3209         SemaRef.Diag(E->getBeginLoc(),
3210                      diag::err_omp_local_var_in_threadprivate_init)
3211             << E->getSourceRange();
3212         SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
3213             << VD << VD->getSourceRange();
3214         return true;
3215       }
3216     }
3217     return false;
3218   }
3219   bool VisitStmt(const Stmt *S) {
3220     for (const Stmt *Child : S->children()) {
3221       if (Child && Visit(Child))
3222         return true;
3223     }
3224     return false;
3225   }
3226   explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
3227 };
3228 } // namespace
3229 
3230 OMPThreadPrivateDecl *
3231 SemaOpenMP::CheckOMPThreadPrivateDecl(SourceLocation Loc,
3232                                       ArrayRef<Expr *> VarList) {
3233   ASTContext &Context = getASTContext();
3234   SmallVector<Expr *, 8> Vars;
3235   for (Expr *RefExpr : VarList) {
3236     auto *DE = cast<DeclRefExpr>(RefExpr);
3237     auto *VD = cast<VarDecl>(DE->getDecl());
3238     SourceLocation ILoc = DE->getExprLoc();
3239 
3240     // Mark variable as used.
3241     VD->setReferenced();
3242     VD->markUsed(Context);
3243 
3244     QualType QType = VD->getType();
3245     if (QType->isDependentType() || QType->isInstantiationDependentType()) {
3246       // It will be analyzed later.
3247       Vars.push_back(DE);
3248       continue;
3249     }
3250 
3251     // OpenMP [2.9.2, Restrictions, C/C++, p.10]
3252     //   A threadprivate variable must not have an incomplete type.
3253     if (SemaRef.RequireCompleteType(
3254             ILoc, VD->getType(), diag::err_omp_threadprivate_incomplete_type)) {
3255       continue;
3256     }
3257 
3258     // OpenMP [2.9.2, Restrictions, C/C++, p.10]
3259     //   A threadprivate variable must not have a reference type.
3260     if (VD->getType()->isReferenceType()) {
3261       Diag(ILoc, diag::err_omp_ref_type_arg)
3262           << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
3263       bool IsDecl =
3264           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3265       Diag(VD->getLocation(),
3266            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3267           << VD;
3268       continue;
3269     }
3270 
3271     // Check if this is a TLS variable. If TLS is not being supported, produce
3272     // the corresponding diagnostic.
3273     if ((VD->getTLSKind() != VarDecl::TLS_None &&
3274          !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
3275            getLangOpts().OpenMPUseTLS &&
3276            getASTContext().getTargetInfo().isTLSSupported())) ||
3277         (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3278          !VD->isLocalVarDecl())) {
3279       Diag(ILoc, diag::err_omp_var_thread_local)
3280           << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
3281       bool IsDecl =
3282           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3283       Diag(VD->getLocation(),
3284            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3285           << VD;
3286       continue;
3287     }
3288 
3289     // Check if initial value of threadprivate variable reference variable with
3290     // local storage (it is not supported by runtime).
3291     if (const Expr *Init = VD->getAnyInitializer()) {
3292       LocalVarRefChecker Checker(SemaRef);
3293       if (Checker.Visit(Init))
3294         continue;
3295     }
3296 
3297     Vars.push_back(RefExpr);
3298     DSAStack->addDSA(VD, DE, OMPC_threadprivate);
3299     VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3300         Context, SourceRange(Loc, Loc)));
3301     if (ASTMutationListener *ML = Context.getASTMutationListener())
3302       ML->DeclarationMarkedOpenMPThreadPrivate(VD);
3303   }
3304   OMPThreadPrivateDecl *D = nullptr;
3305   if (!Vars.empty()) {
3306     D = OMPThreadPrivateDecl::Create(Context, SemaRef.getCurLexicalContext(),
3307                                      Loc, Vars);
3308     D->setAccess(AS_public);
3309   }
3310   return D;
3311 }
3312 
3313 static OMPAllocateDeclAttr::AllocatorTypeTy
3314 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
3315   if (!Allocator)
3316     return OMPAllocateDeclAttr::OMPNullMemAlloc;
3317   if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3318       Allocator->isInstantiationDependent() ||
3319       Allocator->containsUnexpandedParameterPack())
3320     return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3321   auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3322   llvm::FoldingSetNodeID AEId;
3323   const Expr *AE = Allocator->IgnoreParenImpCasts();
3324   AE->IgnoreImpCasts()->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
3325   for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
3326     auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
3327     const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
3328     llvm::FoldingSetNodeID DAEId;
3329     DefAllocator->IgnoreImpCasts()->Profile(DAEId, S.getASTContext(),
3330                                             /*Canonical=*/true);
3331     if (AEId == DAEId) {
3332       AllocatorKindRes = AllocatorKind;
3333       break;
3334     }
3335   }
3336   return AllocatorKindRes;
3337 }
3338 
3339 static bool checkPreviousOMPAllocateAttribute(
3340     Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
3341     OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
3342   if (!VD->hasAttr<OMPAllocateDeclAttr>())
3343     return false;
3344   const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
3345   Expr *PrevAllocator = A->getAllocator();
3346   OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3347       getAllocatorKind(S, Stack, PrevAllocator);
3348   bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3349   if (AllocatorsMatch &&
3350       AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3351       Allocator && PrevAllocator) {
3352     const Expr *AE = Allocator->IgnoreParenImpCasts();
3353     const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
3354     llvm::FoldingSetNodeID AEId, PAEId;
3355     AE->Profile(AEId, S.Context, /*Canonical=*/true);
3356     PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
3357     AllocatorsMatch = AEId == PAEId;
3358   }
3359   if (!AllocatorsMatch) {
3360     SmallString<256> AllocatorBuffer;
3361     llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3362     if (Allocator)
3363       Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
3364     SmallString<256> PrevAllocatorBuffer;
3365     llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3366     if (PrevAllocator)
3367       PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
3368                                  S.getPrintingPolicy());
3369 
3370     SourceLocation AllocatorLoc =
3371         Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
3372     SourceRange AllocatorRange =
3373         Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
3374     SourceLocation PrevAllocatorLoc =
3375         PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3376     SourceRange PrevAllocatorRange =
3377         PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3378     S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3379         << (Allocator ? 1 : 0) << AllocatorStream.str()
3380         << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3381         << AllocatorRange;
3382     S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3383         << PrevAllocatorRange;
3384     return true;
3385   }
3386   return false;
3387 }
3388 
3389 static void
3390 applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
3391                           OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3392                           Expr *Allocator, Expr *Alignment, SourceRange SR) {
3393   if (VD->hasAttr<OMPAllocateDeclAttr>())
3394     return;
3395   if (Alignment &&
3396       (Alignment->isTypeDependent() || Alignment->isValueDependent() ||
3397        Alignment->isInstantiationDependent() ||
3398        Alignment->containsUnexpandedParameterPack()))
3399     // Apply later when we have a usable value.
3400     return;
3401   if (Allocator &&
3402       (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3403        Allocator->isInstantiationDependent() ||
3404        Allocator->containsUnexpandedParameterPack()))
3405     return;
3406   auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
3407                                                 Allocator, Alignment, SR);
3408   VD->addAttr(A);
3409   if (ASTMutationListener *ML = S.Context.getASTMutationListener())
3410     ML->DeclarationMarkedOpenMPAllocate(VD, A);
3411 }
3412 
3413 SemaOpenMP::DeclGroupPtrTy SemaOpenMP::ActOnOpenMPAllocateDirective(
3414     SourceLocation Loc, ArrayRef<Expr *> VarList, ArrayRef<OMPClause *> Clauses,
3415     DeclContext *Owner) {
3416   assert(Clauses.size() <= 2 && "Expected at most two clauses.");
3417   Expr *Alignment = nullptr;
3418   Expr *Allocator = nullptr;
3419   if (Clauses.empty()) {
3420     // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
3421     // allocate directives that appear in a target region must specify an
3422     // allocator clause unless a requires directive with the dynamic_allocators
3423     // clause is present in the same compilation unit.
3424     if (getLangOpts().OpenMPIsTargetDevice &&
3425         !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
3426       SemaRef.targetDiag(Loc, diag::err_expected_allocator_clause);
3427   } else {
3428     for (const OMPClause *C : Clauses)
3429       if (const auto *AC = dyn_cast<OMPAllocatorClause>(C))
3430         Allocator = AC->getAllocator();
3431       else if (const auto *AC = dyn_cast<OMPAlignClause>(C))
3432         Alignment = AC->getAlignment();
3433       else
3434         llvm_unreachable("Unexpected clause on allocate directive");
3435   }
3436   OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3437       getAllocatorKind(SemaRef, DSAStack, Allocator);
3438   SmallVector<Expr *, 8> Vars;
3439   for (Expr *RefExpr : VarList) {
3440     auto *DE = cast<DeclRefExpr>(RefExpr);
3441     auto *VD = cast<VarDecl>(DE->getDecl());
3442 
3443     // Check if this is a TLS variable or global register.
3444     if (VD->getTLSKind() != VarDecl::TLS_None ||
3445         VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
3446         (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3447          !VD->isLocalVarDecl()))
3448       continue;
3449 
3450     // If the used several times in the allocate directive, the same allocator
3451     // must be used.
3452     if (checkPreviousOMPAllocateAttribute(SemaRef, DSAStack, RefExpr, VD,
3453                                           AllocatorKind, Allocator))
3454       continue;
3455 
3456     // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
3457     // If a list item has a static storage type, the allocator expression in the
3458     // allocator clause must be a constant expression that evaluates to one of
3459     // the predefined memory allocator values.
3460     if (Allocator && VD->hasGlobalStorage()) {
3461       if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3462         Diag(Allocator->getExprLoc(),
3463              diag::err_omp_expected_predefined_allocator)
3464             << Allocator->getSourceRange();
3465         bool IsDecl = VD->isThisDeclarationADefinition(getASTContext()) ==
3466                       VarDecl::DeclarationOnly;
3467         Diag(VD->getLocation(),
3468              IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3469             << VD;
3470         continue;
3471       }
3472     }
3473 
3474     Vars.push_back(RefExpr);
3475     applyOMPAllocateAttribute(SemaRef, VD, AllocatorKind, Allocator, Alignment,
3476                               DE->getSourceRange());
3477   }
3478   if (Vars.empty())
3479     return nullptr;
3480   if (!Owner)
3481     Owner = SemaRef.getCurLexicalContext();
3482   auto *D = OMPAllocateDecl::Create(getASTContext(), Owner, Loc, Vars, Clauses);
3483   D->setAccess(AS_public);
3484   Owner->addDecl(D);
3485   return DeclGroupPtrTy::make(DeclGroupRef(D));
3486 }
3487 
3488 SemaOpenMP::DeclGroupPtrTy
3489 SemaOpenMP::ActOnOpenMPRequiresDirective(SourceLocation Loc,
3490                                          ArrayRef<OMPClause *> ClauseList) {
3491   OMPRequiresDecl *D = nullptr;
3492   if (!SemaRef.CurContext->isFileContext()) {
3493     Diag(Loc, diag::err_omp_invalid_scope) << "requires";
3494   } else {
3495     D = CheckOMPRequiresDecl(Loc, ClauseList);
3496     if (D) {
3497       SemaRef.CurContext->addDecl(D);
3498       DSAStack->addRequiresDecl(D);
3499     }
3500   }
3501   return DeclGroupPtrTy::make(DeclGroupRef(D));
3502 }
3503 
3504 void SemaOpenMP::ActOnOpenMPAssumesDirective(SourceLocation Loc,
3505                                              OpenMPDirectiveKind DKind,
3506                                              ArrayRef<std::string> Assumptions,
3507                                              bool SkippedClauses) {
3508   if (!SkippedClauses && Assumptions.empty())
3509     Diag(Loc, diag::err_omp_no_clause_for_directive)
3510         << llvm::omp::getAllAssumeClauseOptions()
3511         << llvm::omp::getOpenMPDirectiveName(DKind);
3512 
3513   auto *AA =
3514       OMPAssumeAttr::Create(getASTContext(), llvm::join(Assumptions, ","), Loc);
3515   if (DKind == llvm::omp::Directive::OMPD_begin_assumes) {
3516     OMPAssumeScoped.push_back(AA);
3517     return;
3518   }
3519 
3520   // Global assumes without assumption clauses are ignored.
3521   if (Assumptions.empty())
3522     return;
3523 
3524   assert(DKind == llvm::omp::Directive::OMPD_assumes &&
3525          "Unexpected omp assumption directive!");
3526   OMPAssumeGlobal.push_back(AA);
3527 
3528   // The OMPAssumeGlobal scope above will take care of new declarations but
3529   // we also want to apply the assumption to existing ones, e.g., to
3530   // declarations in included headers. To this end, we traverse all existing
3531   // declaration contexts and annotate function declarations here.
3532   SmallVector<DeclContext *, 8> DeclContexts;
3533   auto *Ctx = SemaRef.CurContext;
3534   while (Ctx->getLexicalParent())
3535     Ctx = Ctx->getLexicalParent();
3536   DeclContexts.push_back(Ctx);
3537   while (!DeclContexts.empty()) {
3538     DeclContext *DC = DeclContexts.pop_back_val();
3539     for (auto *SubDC : DC->decls()) {
3540       if (SubDC->isInvalidDecl())
3541         continue;
3542       if (auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) {
3543         DeclContexts.push_back(CTD->getTemplatedDecl());
3544         llvm::append_range(DeclContexts, CTD->specializations());
3545         continue;
3546       }
3547       if (auto *DC = dyn_cast<DeclContext>(SubDC))
3548         DeclContexts.push_back(DC);
3549       if (auto *F = dyn_cast<FunctionDecl>(SubDC)) {
3550         F->addAttr(AA);
3551         continue;
3552       }
3553     }
3554   }
3555 }
3556 
3557 void SemaOpenMP::ActOnOpenMPEndAssumesDirective() {
3558   assert(isInOpenMPAssumeScope() && "Not in OpenMP assumes scope!");
3559   OMPAssumeScoped.pop_back();
3560 }
3561 
3562 StmtResult SemaOpenMP::ActOnOpenMPAssumeDirective(ArrayRef<OMPClause *> Clauses,
3563                                                   Stmt *AStmt,
3564                                                   SourceLocation StartLoc,
3565                                                   SourceLocation EndLoc) {
3566   if (!AStmt)
3567     return StmtError();
3568 
3569   return OMPAssumeDirective::Create(getASTContext(), StartLoc, EndLoc, Clauses,
3570                                     AStmt);
3571 }
3572 
3573 OMPRequiresDecl *
3574 SemaOpenMP::CheckOMPRequiresDecl(SourceLocation Loc,
3575                                  ArrayRef<OMPClause *> ClauseList) {
3576   /// For target specific clauses, the requires directive cannot be
3577   /// specified after the handling of any of the target regions in the
3578   /// current compilation unit.
3579   ArrayRef<SourceLocation> TargetLocations =
3580       DSAStack->getEncounteredTargetLocs();
3581   SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc();
3582   if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) {
3583     for (const OMPClause *CNew : ClauseList) {
3584       // Check if any of the requires clauses affect target regions.
3585       if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3586           isa<OMPUnifiedAddressClause>(CNew) ||
3587           isa<OMPReverseOffloadClause>(CNew) ||
3588           isa<OMPDynamicAllocatorsClause>(CNew)) {
3589         Diag(Loc, diag::err_omp_directive_before_requires)
3590             << "target" << getOpenMPClauseName(CNew->getClauseKind());
3591         for (SourceLocation TargetLoc : TargetLocations) {
3592           Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3593               << "target";
3594         }
3595       } else if (!AtomicLoc.isInvalid() &&
3596                  isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3597         Diag(Loc, diag::err_omp_directive_before_requires)
3598             << "atomic" << getOpenMPClauseName(CNew->getClauseKind());
3599         Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3600             << "atomic";
3601       }
3602     }
3603   }
3604 
3605   if (!DSAStack->hasDuplicateRequiresClause(ClauseList))
3606     return OMPRequiresDecl::Create(
3607         getASTContext(), SemaRef.getCurLexicalContext(), Loc, ClauseList);
3608   return nullptr;
3609 }
3610 
3611 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
3612                               const ValueDecl *D,
3613                               const DSAStackTy::DSAVarData &DVar,
3614                               bool IsLoopIterVar) {
3615   if (DVar.RefExpr) {
3616     SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3617         << getOpenMPClauseName(DVar.CKind);
3618     return;
3619   }
3620   enum {
3621     PDSA_StaticMemberShared,
3622     PDSA_StaticLocalVarShared,
3623     PDSA_LoopIterVarPrivate,
3624     PDSA_LoopIterVarLinear,
3625     PDSA_LoopIterVarLastprivate,
3626     PDSA_ConstVarShared,
3627     PDSA_GlobalVarShared,
3628     PDSA_TaskVarFirstprivate,
3629     PDSA_LocalVarPrivate,
3630     PDSA_Implicit
3631   } Reason = PDSA_Implicit;
3632   bool ReportHint = false;
3633   auto ReportLoc = D->getLocation();
3634   auto *VD = dyn_cast<VarDecl>(D);
3635   if (IsLoopIterVar) {
3636     if (DVar.CKind == OMPC_private)
3637       Reason = PDSA_LoopIterVarPrivate;
3638     else if (DVar.CKind == OMPC_lastprivate)
3639       Reason = PDSA_LoopIterVarLastprivate;
3640     else
3641       Reason = PDSA_LoopIterVarLinear;
3642   } else if (isOpenMPTaskingDirective(DVar.DKind) &&
3643              DVar.CKind == OMPC_firstprivate) {
3644     Reason = PDSA_TaskVarFirstprivate;
3645     ReportLoc = DVar.ImplicitDSALoc;
3646   } else if (VD && VD->isStaticLocal())
3647     Reason = PDSA_StaticLocalVarShared;
3648   else if (VD && VD->isStaticDataMember())
3649     Reason = PDSA_StaticMemberShared;
3650   else if (VD && VD->isFileVarDecl())
3651     Reason = PDSA_GlobalVarShared;
3652   else if (D->getType().isConstant(SemaRef.getASTContext()))
3653     Reason = PDSA_ConstVarShared;
3654   else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
3655     ReportHint = true;
3656     Reason = PDSA_LocalVarPrivate;
3657   }
3658   if (Reason != PDSA_Implicit) {
3659     SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3660         << Reason << ReportHint
3661         << getOpenMPDirectiveName(Stack->getCurrentDirective());
3662   } else if (DVar.ImplicitDSALoc.isValid()) {
3663     SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3664         << getOpenMPClauseName(DVar.CKind);
3665   }
3666 }
3667 
3668 static OpenMPMapClauseKind
3669 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,
3670                              bool IsAggregateOrDeclareTarget) {
3671   OpenMPMapClauseKind Kind = OMPC_MAP_unknown;
3672   switch (M) {
3673   case OMPC_DEFAULTMAP_MODIFIER_alloc:
3674     Kind = OMPC_MAP_alloc;
3675     break;
3676   case OMPC_DEFAULTMAP_MODIFIER_to:
3677     Kind = OMPC_MAP_to;
3678     break;
3679   case OMPC_DEFAULTMAP_MODIFIER_from:
3680     Kind = OMPC_MAP_from;
3681     break;
3682   case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3683     Kind = OMPC_MAP_tofrom;
3684     break;
3685   case OMPC_DEFAULTMAP_MODIFIER_present:
3686     // OpenMP 5.1 [2.21.7.3] defaultmap clause, Description]
3687     // If implicit-behavior is present, each variable referenced in the
3688     // construct in the category specified by variable-category is treated as if
3689     // it had been listed in a map clause with the map-type of alloc and
3690     // map-type-modifier of present.
3691     Kind = OMPC_MAP_alloc;
3692     break;
3693   case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3694   case OMPC_DEFAULTMAP_MODIFIER_last:
3695     llvm_unreachable("Unexpected defaultmap implicit behavior");
3696   case OMPC_DEFAULTMAP_MODIFIER_none:
3697   case OMPC_DEFAULTMAP_MODIFIER_default:
3698   case OMPC_DEFAULTMAP_MODIFIER_unknown:
3699     // IsAggregateOrDeclareTarget could be true if:
3700     // 1. the implicit behavior for aggregate is tofrom
3701     // 2. it's a declare target link
3702     if (IsAggregateOrDeclareTarget) {
3703       Kind = OMPC_MAP_tofrom;
3704       break;
3705     }
3706     llvm_unreachable("Unexpected defaultmap implicit behavior");
3707   }
3708   assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known");
3709   return Kind;
3710 }
3711 
3712 namespace {
3713 struct VariableImplicitInfo {
3714   static const unsigned MapKindNum = OMPC_MAP_unknown;
3715   static const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_unknown + 1;
3716 
3717   llvm::SetVector<Expr *> Privates;
3718   llvm::SetVector<Expr *> Firstprivates;
3719   llvm::SetVector<Expr *> Mappings[DefaultmapKindNum][MapKindNum];
3720   llvm::SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
3721       MapModifiers[DefaultmapKindNum];
3722 };
3723 
3724 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
3725   DSAStackTy *Stack;
3726   Sema &SemaRef;
3727   OpenMPDirectiveKind DKind = OMPD_unknown;
3728   bool ErrorFound = false;
3729   bool TryCaptureCXXThisMembers = false;
3730   CapturedStmt *CS = nullptr;
3731 
3732   VariableImplicitInfo ImpInfo;
3733   SemaOpenMP::VarsWithInheritedDSAType VarsWithInheritedDSA;
3734   llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3735 
3736   void VisitSubCaptures(OMPExecutableDirective *S) {
3737     // Check implicitly captured variables.
3738     if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
3739       return;
3740     if (S->getDirectiveKind() == OMPD_atomic ||
3741         S->getDirectiveKind() == OMPD_critical ||
3742         S->getDirectiveKind() == OMPD_section ||
3743         S->getDirectiveKind() == OMPD_master ||
3744         S->getDirectiveKind() == OMPD_masked ||
3745         S->getDirectiveKind() == OMPD_scope ||
3746         S->getDirectiveKind() == OMPD_assume ||
3747         isOpenMPLoopTransformationDirective(S->getDirectiveKind())) {
3748       Visit(S->getAssociatedStmt());
3749       return;
3750     }
3751     visitSubCaptures(S->getInnermostCapturedStmt());
3752     // Try to capture inner this->member references to generate correct mappings
3753     // and diagnostics.
3754     if (TryCaptureCXXThisMembers ||
3755         (isOpenMPTargetExecutionDirective(DKind) &&
3756          llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3757                       [](const CapturedStmt::Capture &C) {
3758                         return C.capturesThis();
3759                       }))) {
3760       bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3761       TryCaptureCXXThisMembers = true;
3762       Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3763       TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3764     }
3765     // In tasks firstprivates are not captured anymore, need to analyze them
3766     // explicitly.
3767     if (isOpenMPTaskingDirective(S->getDirectiveKind()) &&
3768         !isOpenMPTaskLoopDirective(S->getDirectiveKind())) {
3769       for (OMPClause *C : S->clauses())
3770         if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) {
3771           for (Expr *Ref : FC->varlist())
3772             Visit(Ref);
3773         }
3774     }
3775   }
3776 
3777 public:
3778   void VisitDeclRefExpr(DeclRefExpr *E) {
3779     if (TryCaptureCXXThisMembers || E->isTypeDependent() ||
3780         E->isValueDependent() || E->containsUnexpandedParameterPack() ||
3781         E->isInstantiationDependent() ||
3782         E->isNonOdrUse() == clang::NOUR_Unevaluated)
3783       return;
3784     if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3785       // Check the datasharing rules for the expressions in the clauses.
3786       if (!CS || (isa<OMPCapturedExprDecl>(VD) && !CS->capturesVariable(VD) &&
3787                   !Stack->getTopDSA(VD, /*FromParent=*/false).RefExpr &&
3788                   !Stack->isImplicitDefaultFirstprivateFD(VD))) {
3789         if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3790           if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3791             Visit(CED->getInit());
3792             return;
3793           }
3794       } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
3795         // Do not analyze internal variables and do not enclose them into
3796         // implicit clauses.
3797         if (!Stack->isImplicitDefaultFirstprivateFD(VD))
3798           return;
3799       VD = VD->getCanonicalDecl();
3800       // Skip internally declared variables.
3801       if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) &&
3802           !Stack->isImplicitDefaultFirstprivateFD(VD) &&
3803           !Stack->isImplicitTaskFirstprivate(VD))
3804         return;
3805       // Skip allocators in uses_allocators clauses.
3806       if (Stack->isUsesAllocatorsDecl(VD))
3807         return;
3808 
3809       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
3810       // Check if the variable has explicit DSA set and stop analysis if it so.
3811       if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3812         return;
3813 
3814       // Skip internally declared static variables.
3815       std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3816           OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3817       if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
3818           (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
3819            !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3820           !Stack->isImplicitDefaultFirstprivateFD(VD) &&
3821           !Stack->isImplicitTaskFirstprivate(VD))
3822         return;
3823 
3824       SourceLocation ELoc = E->getExprLoc();
3825       // The default(none) clause requires that each variable that is referenced
3826       // in the construct, and does not have a predetermined data-sharing
3827       // attribute, must have its data-sharing attribute explicitly determined
3828       // by being listed in a data-sharing attribute clause.
3829       if (DVar.CKind == OMPC_unknown &&
3830           (Stack->getDefaultDSA() == DSA_none ||
3831            Stack->getDefaultDSA() == DSA_private ||
3832            Stack->getDefaultDSA() == DSA_firstprivate) &&
3833           isImplicitOrExplicitTaskingRegion(DKind) &&
3834           VarsWithInheritedDSA.count(VD) == 0) {
3835         bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3836         if (!InheritedDSA && (Stack->getDefaultDSA() == DSA_firstprivate ||
3837                               Stack->getDefaultDSA() == DSA_private)) {
3838           DSAStackTy::DSAVarData DVar =
3839               Stack->getImplicitDSA(VD, /*FromParent=*/false);
3840           InheritedDSA = DVar.CKind == OMPC_unknown;
3841         }
3842         if (InheritedDSA)
3843           VarsWithInheritedDSA[VD] = E;
3844         if (Stack->getDefaultDSA() == DSA_none)
3845           return;
3846       }
3847 
3848       // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description]
3849       // If implicit-behavior is none, each variable referenced in the
3850       // construct that does not have a predetermined data-sharing attribute
3851       // and does not appear in a to or link clause on a declare target
3852       // directive must be listed in a data-mapping attribute clause, a
3853       // data-sharing attribute clause (including a data-sharing attribute
3854       // clause on a combined construct where target. is one of the
3855       // constituent constructs), or an is_device_ptr clause.
3856       OpenMPDefaultmapClauseKind ClauseKind =
3857           getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD);
3858       if (SemaRef.getLangOpts().OpenMP >= 50) {
3859         bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3860                               OMPC_DEFAULTMAP_MODIFIER_none;
3861         if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3862             VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3863           // Only check for data-mapping attribute and is_device_ptr here
3864           // since we have already make sure that the declaration does not
3865           // have a data-sharing attribute above
3866           if (!Stack->checkMappableExprComponentListsForDecl(
3867                   VD, /*CurrentRegionOnly=*/true,
3868                   [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef
3869                            MapExprComponents,
3870                        OpenMPClauseKind) {
3871                     auto MI = MapExprComponents.rbegin();
3872                     auto ME = MapExprComponents.rend();
3873                     return MI != ME && MI->getAssociatedDeclaration() == VD;
3874                   })) {
3875             VarsWithInheritedDSA[VD] = E;
3876             return;
3877           }
3878         }
3879       }
3880       if (SemaRef.getLangOpts().OpenMP > 50) {
3881         bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) ==
3882                                  OMPC_DEFAULTMAP_MODIFIER_present;
3883         if (IsModifierPresent) {
3884           if (!llvm::is_contained(ImpInfo.MapModifiers[ClauseKind],
3885                                   OMPC_MAP_MODIFIER_present)) {
3886             ImpInfo.MapModifiers[ClauseKind].push_back(
3887                 OMPC_MAP_MODIFIER_present);
3888           }
3889         }
3890       }
3891 
3892       if (isOpenMPTargetExecutionDirective(DKind) &&
3893           !Stack->isLoopControlVariable(VD).first) {
3894         if (!Stack->checkMappableExprComponentListsForDecl(
3895                 VD, /*CurrentRegionOnly=*/true,
3896                 [this](OMPClauseMappableExprCommon::MappableExprComponentListRef
3897                            StackComponents,
3898                        OpenMPClauseKind) {
3899                   if (SemaRef.LangOpts.OpenMP >= 50)
3900                     return !StackComponents.empty();
3901                   // Variable is used if it has been marked as an array, array
3902                   // section, array shaping or the variable itself.
3903                   return StackComponents.size() == 1 ||
3904                          llvm::all_of(
3905                              llvm::drop_begin(llvm::reverse(StackComponents)),
3906                              [](const OMPClauseMappableExprCommon::
3907                                     MappableComponent &MC) {
3908                                return MC.getAssociatedDeclaration() ==
3909                                           nullptr &&
3910                                       (isa<ArraySectionExpr>(
3911                                            MC.getAssociatedExpression()) ||
3912                                        isa<OMPArrayShapingExpr>(
3913                                            MC.getAssociatedExpression()) ||
3914                                        isa<ArraySubscriptExpr>(
3915                                            MC.getAssociatedExpression()));
3916                              });
3917                 })) {
3918           bool IsFirstprivate = false;
3919           // By default lambdas are captured as firstprivates.
3920           if (const auto *RD =
3921                   VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
3922             IsFirstprivate = RD->isLambda();
3923           IsFirstprivate =
3924               IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3925           if (IsFirstprivate) {
3926             ImpInfo.Firstprivates.insert(E);
3927           } else {
3928             OpenMPDefaultmapClauseModifier M =
3929                 Stack->getDefaultmapModifier(ClauseKind);
3930             OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3931                 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3932             ImpInfo.Mappings[ClauseKind][Kind].insert(E);
3933           }
3934           return;
3935         }
3936       }
3937 
3938       // OpenMP [2.9.3.6, Restrictions, p.2]
3939       //  A list item that appears in a reduction clause of the innermost
3940       //  enclosing worksharing or parallel construct may not be accessed in an
3941       //  explicit task.
3942       DVar = Stack->hasInnermostDSA(
3943           VD,
3944           [](OpenMPClauseKind C, bool AppliedToPointee) {
3945             return C == OMPC_reduction && !AppliedToPointee;
3946           },
3947           [](OpenMPDirectiveKind K) {
3948             return isOpenMPParallelDirective(K) ||
3949                    isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3950           },
3951           /*FromParent=*/true);
3952       if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3953         ErrorFound = true;
3954         SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3955         reportOriginalDsa(SemaRef, Stack, VD, DVar);
3956         return;
3957       }
3958 
3959       // Define implicit data-sharing attributes for task.
3960       DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
3961       if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) ||
3962            (((Stack->getDefaultDSA() == DSA_firstprivate &&
3963               DVar.CKind == OMPC_firstprivate) ||
3964              (Stack->getDefaultDSA() == DSA_private &&
3965               DVar.CKind == OMPC_private)) &&
3966             !DVar.RefExpr)) &&
3967           !Stack->isLoopControlVariable(VD).first) {
3968         if (Stack->getDefaultDSA() == DSA_private)
3969           ImpInfo.Privates.insert(E);
3970         else
3971           ImpInfo.Firstprivates.insert(E);
3972         return;
3973       }
3974 
3975       // Store implicitly used globals with declare target link for parent
3976       // target.
3977       if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
3978           *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3979         Stack->addToParentTargetRegionLinkGlobals(E);
3980         return;
3981       }
3982     }
3983   }
3984   void VisitMemberExpr(MemberExpr *E) {
3985     if (E->isTypeDependent() || E->isValueDependent() ||
3986         E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
3987       return;
3988     auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
3989     if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) {
3990       if (!FD)
3991         return;
3992       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
3993       // Check if the variable has explicit DSA set and stop analysis if it
3994       // so.
3995       if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3996         return;
3997 
3998       if (isOpenMPTargetExecutionDirective(DKind) &&
3999           !Stack->isLoopControlVariable(FD).first &&
4000           !Stack->checkMappableExprComponentListsForDecl(
4001               FD, /*CurrentRegionOnly=*/true,
4002               [](OMPClauseMappableExprCommon::MappableExprComponentListRef
4003                      StackComponents,
4004                  OpenMPClauseKind) {
4005                 return isa<CXXThisExpr>(
4006                     cast<MemberExpr>(
4007                         StackComponents.back().getAssociatedExpression())
4008                         ->getBase()
4009                         ->IgnoreParens());
4010               })) {
4011         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
4012         //  A bit-field cannot appear in a map clause.
4013         //
4014         if (FD->isBitField())
4015           return;
4016 
4017         // Check to see if the member expression is referencing a class that
4018         // has already been explicitly mapped
4019         if (Stack->isClassPreviouslyMapped(TE->getType()))
4020           return;
4021 
4022         OpenMPDefaultmapClauseModifier Modifier =
4023             Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
4024         OpenMPDefaultmapClauseKind ClauseKind =
4025             getVariableCategoryFromDecl(SemaRef.getLangOpts(), FD);
4026         OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
4027             Modifier, /*IsAggregateOrDeclareTarget=*/true);
4028         ImpInfo.Mappings[ClauseKind][Kind].insert(E);
4029         return;
4030       }
4031 
4032       SourceLocation ELoc = E->getExprLoc();
4033       // OpenMP [2.9.3.6, Restrictions, p.2]
4034       //  A list item that appears in a reduction clause of the innermost
4035       //  enclosing worksharing or parallel construct may not be accessed in
4036       //  an  explicit task.
4037       DVar = Stack->hasInnermostDSA(
4038           FD,
4039           [](OpenMPClauseKind C, bool AppliedToPointee) {
4040             return C == OMPC_reduction && !AppliedToPointee;
4041           },
4042           [](OpenMPDirectiveKind K) {
4043             return isOpenMPParallelDirective(K) ||
4044                    isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
4045           },
4046           /*FromParent=*/true);
4047       if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
4048         ErrorFound = true;
4049         SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
4050         reportOriginalDsa(SemaRef, Stack, FD, DVar);
4051         return;
4052       }
4053 
4054       // Define implicit data-sharing attributes for task.
4055       DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
4056       if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
4057           !Stack->isLoopControlVariable(FD).first) {
4058         // Check if there is a captured expression for the current field in the
4059         // region. Do not mark it as firstprivate unless there is no captured
4060         // expression.
4061         // TODO: try to make it firstprivate.
4062         if (DVar.CKind != OMPC_unknown)
4063           ImpInfo.Firstprivates.insert(E);
4064       }
4065       return;
4066     }
4067     if (isOpenMPTargetExecutionDirective(DKind)) {
4068       OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
4069       if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
4070                                         DKind, /*NoDiagnose=*/true))
4071         return;
4072       const auto *VD = cast<ValueDecl>(
4073           CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
4074       if (!Stack->checkMappableExprComponentListsForDecl(
4075               VD, /*CurrentRegionOnly=*/true,
4076               [&CurComponents](
4077                   OMPClauseMappableExprCommon::MappableExprComponentListRef
4078                       StackComponents,
4079                   OpenMPClauseKind) {
4080                 auto CCI = CurComponents.rbegin();
4081                 auto CCE = CurComponents.rend();
4082                 for (const auto &SC : llvm::reverse(StackComponents)) {
4083                   // Do both expressions have the same kind?
4084                   if (CCI->getAssociatedExpression()->getStmtClass() !=
4085                       SC.getAssociatedExpression()->getStmtClass())
4086                     if (!((isa<ArraySectionExpr>(
4087                                SC.getAssociatedExpression()) ||
4088                            isa<OMPArrayShapingExpr>(
4089                                SC.getAssociatedExpression())) &&
4090                           isa<ArraySubscriptExpr>(
4091                               CCI->getAssociatedExpression())))
4092                       return false;
4093 
4094                   const Decl *CCD = CCI->getAssociatedDeclaration();
4095                   const Decl *SCD = SC.getAssociatedDeclaration();
4096                   CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
4097                   SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
4098                   if (SCD != CCD)
4099                     return false;
4100                   std::advance(CCI, 1);
4101                   if (CCI == CCE)
4102                     break;
4103                 }
4104                 return true;
4105               })) {
4106         Visit(E->getBase());
4107       }
4108     } else if (!TryCaptureCXXThisMembers) {
4109       Visit(E->getBase());
4110     }
4111   }
4112   void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
4113     for (OMPClause *C : S->clauses()) {
4114       // Skip analysis of arguments of private clauses for task|target
4115       // directives.
4116       if (isa_and_nonnull<OMPPrivateClause>(C))
4117         continue;
4118       // Skip analysis of arguments of implicitly defined firstprivate clause
4119       // for task|target directives.
4120       // Skip analysis of arguments of implicitly defined map clause for target
4121       // directives.
4122       if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
4123                  C->isImplicit() && !isOpenMPTaskingDirective(DKind))) {
4124         for (Stmt *CC : C->children()) {
4125           if (CC)
4126             Visit(CC);
4127         }
4128       }
4129     }
4130     // Check implicitly captured variables.
4131     VisitSubCaptures(S);
4132   }
4133 
4134   void VisitOMPLoopTransformationDirective(OMPLoopTransformationDirective *S) {
4135     // Loop transformation directives do not introduce data sharing
4136     VisitStmt(S);
4137   }
4138 
4139   void VisitCallExpr(CallExpr *S) {
4140     for (Stmt *C : S->arguments()) {
4141       if (C) {
4142         // Check implicitly captured variables in the task-based directives to
4143         // check if they must be firstprivatized.
4144         Visit(C);
4145       }
4146     }
4147     if (Expr *Callee = S->getCallee()) {
4148       auto *CI = Callee->IgnoreParenImpCasts();
4149       if (auto *CE = dyn_cast<MemberExpr>(CI))
4150         Visit(CE->getBase());
4151       else if (auto *CE = dyn_cast<DeclRefExpr>(CI))
4152         Visit(CE);
4153     }
4154   }
4155   void VisitStmt(Stmt *S) {
4156     for (Stmt *C : S->children()) {
4157       if (C) {
4158         // Check implicitly captured variables in the task-based directives to
4159         // check if they must be firstprivatized.
4160         Visit(C);
4161       }
4162     }
4163   }
4164 
4165   void visitSubCaptures(CapturedStmt *S) {
4166     for (const CapturedStmt::Capture &Cap : S->captures()) {
4167       if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
4168         continue;
4169       VarDecl *VD = Cap.getCapturedVar();
4170       // Do not try to map the variable if it or its sub-component was mapped
4171       // already.
4172       if (isOpenMPTargetExecutionDirective(DKind) &&
4173           Stack->checkMappableExprComponentListsForDecl(
4174               VD, /*CurrentRegionOnly=*/true,
4175               [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
4176                  OpenMPClauseKind) { return true; }))
4177         continue;
4178       DeclRefExpr *DRE = buildDeclRefExpr(
4179           SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
4180           Cap.getLocation(), /*RefersToCapture=*/true);
4181       Visit(DRE);
4182     }
4183   }
4184   bool isErrorFound() const { return ErrorFound; }
4185   const VariableImplicitInfo &getImplicitInfo() const { return ImpInfo; }
4186   const SemaOpenMP::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
4187     return VarsWithInheritedDSA;
4188   }
4189 
4190   DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
4191       : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
4192     DKind = S->getCurrentDirective();
4193     // Process declare target link variables for the target directives.
4194     if (isOpenMPTargetExecutionDirective(DKind)) {
4195       for (DeclRefExpr *E : Stack->getLinkGlobals())
4196         Visit(E);
4197     }
4198   }
4199 };
4200 } // namespace
4201 
4202 static void handleDeclareVariantConstructTrait(DSAStackTy *Stack,
4203                                                OpenMPDirectiveKind DKind,
4204                                                bool ScopeEntry) {
4205   SmallVector<llvm::omp::TraitProperty, 8> Traits;
4206   if (isOpenMPTargetExecutionDirective(DKind))
4207     Traits.emplace_back(llvm::omp::TraitProperty::construct_target_target);
4208   if (isOpenMPTeamsDirective(DKind))
4209     Traits.emplace_back(llvm::omp::TraitProperty::construct_teams_teams);
4210   if (isOpenMPParallelDirective(DKind))
4211     Traits.emplace_back(llvm::omp::TraitProperty::construct_parallel_parallel);
4212   if (isOpenMPWorksharingDirective(DKind))
4213     Traits.emplace_back(llvm::omp::TraitProperty::construct_for_for);
4214   if (isOpenMPSimdDirective(DKind))
4215     Traits.emplace_back(llvm::omp::TraitProperty::construct_simd_simd);
4216   Stack->handleConstructTrait(Traits, ScopeEntry);
4217 }
4218 
4219 static SmallVector<SemaOpenMP::CapturedParamNameType>
4220 getParallelRegionParams(Sema &SemaRef, bool LoopBoundSharing) {
4221   ASTContext &Context = SemaRef.getASTContext();
4222   QualType KmpInt32Ty =
4223       Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1).withConst();
4224   QualType KmpInt32PtrTy =
4225       Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4226   SmallVector<SemaOpenMP::CapturedParamNameType> Params{
4227       std::make_pair(".global_tid.", KmpInt32PtrTy),
4228       std::make_pair(".bound_tid.", KmpInt32PtrTy),
4229   };
4230   if (LoopBoundSharing) {
4231     QualType KmpSizeTy = Context.getSizeType().withConst();
4232     Params.push_back(std::make_pair(".previous.lb.", KmpSizeTy));
4233     Params.push_back(std::make_pair(".previous.ub.", KmpSizeTy));
4234   }
4235 
4236   // __context with shared vars
4237   Params.push_back(std::make_pair(StringRef(), QualType()));
4238   return Params;
4239 }
4240 
4241 static SmallVector<SemaOpenMP::CapturedParamNameType>
4242 getTeamsRegionParams(Sema &SemaRef) {
4243   return getParallelRegionParams(SemaRef, /*LoopBoundSharing=*/false);
4244 }
4245 
4246 static SmallVector<SemaOpenMP::CapturedParamNameType>
4247 getTaskRegionParams(Sema &SemaRef) {
4248   ASTContext &Context = SemaRef.getASTContext();
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   SmallVector<SemaOpenMP::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   return Params;
4268 }
4269 
4270 static SmallVector<SemaOpenMP::CapturedParamNameType>
4271 getTargetRegionParams(Sema &SemaRef) {
4272   ASTContext &Context = SemaRef.getASTContext();
4273   SmallVector<SemaOpenMP::CapturedParamNameType> Params;
4274   if (SemaRef.getLangOpts().OpenMPIsTargetDevice) {
4275     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4276     Params.push_back(std::make_pair(StringRef("dyn_ptr"), VoidPtrTy));
4277   }
4278   // __context with shared vars
4279   Params.push_back(std::make_pair(StringRef(), QualType()));
4280   return Params;
4281 }
4282 
4283 static SmallVector<SemaOpenMP::CapturedParamNameType>
4284 getUnknownRegionParams(Sema &SemaRef) {
4285   SmallVector<SemaOpenMP::CapturedParamNameType> Params{
4286       std::make_pair(StringRef(), QualType()) // __context with shared vars
4287   };
4288   return Params;
4289 }
4290 
4291 static SmallVector<SemaOpenMP::CapturedParamNameType>
4292 getTaskloopRegionParams(Sema &SemaRef) {
4293   ASTContext &Context = SemaRef.getASTContext();
4294   QualType KmpInt32Ty =
4295       Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1).withConst();
4296   QualType KmpUInt64Ty =
4297       Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0).withConst();
4298   QualType KmpInt64Ty =
4299       Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1).withConst();
4300   QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4301   QualType KmpInt32PtrTy =
4302       Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4303   QualType Args[] = {VoidPtrTy};
4304   FunctionProtoType::ExtProtoInfo EPI;
4305   EPI.Variadic = true;
4306   QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4307   SmallVector<SemaOpenMP::CapturedParamNameType> Params{
4308       std::make_pair(".global_tid.", KmpInt32Ty),
4309       std::make_pair(".part_id.", KmpInt32PtrTy),
4310       std::make_pair(".privates.", VoidPtrTy),
4311       std::make_pair(
4312           ".copy_fn.",
4313           Context.getPointerType(CopyFnType).withConst().withRestrict()),
4314       std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4315       std::make_pair(".lb.", KmpUInt64Ty),
4316       std::make_pair(".ub.", KmpUInt64Ty),
4317       std::make_pair(".st.", KmpInt64Ty),
4318       std::make_pair(".liter.", KmpInt32Ty),
4319       std::make_pair(".reductions.", VoidPtrTy),
4320       std::make_pair(StringRef(), QualType()) // __context with shared vars
4321   };
4322   return Params;
4323 }
4324 
4325 static void processCapturedRegions(Sema &SemaRef, OpenMPDirectiveKind DKind,
4326                                    Scope *CurScope, SourceLocation Loc) {
4327   SmallVector<OpenMPDirectiveKind> Regions;
4328   getOpenMPCaptureRegions(Regions, DKind);
4329 
4330   bool LoopBoundSharing = isOpenMPLoopBoundSharingDirective(DKind);
4331 
4332   auto MarkAsInlined = [&](CapturedRegionScopeInfo *CSI) {
4333     CSI->TheCapturedDecl->addAttr(AlwaysInlineAttr::CreateImplicit(
4334         SemaRef.getASTContext(), {}, AlwaysInlineAttr::Keyword_forceinline));
4335   };
4336 
4337   for (auto [Level, RKind] : llvm::enumerate(Regions)) {
4338     switch (RKind) {
4339     // All region kinds that can be returned from `getOpenMPCaptureRegions`
4340     // are listed here.
4341     case OMPD_parallel:
4342       SemaRef.ActOnCapturedRegionStart(
4343           Loc, CurScope, CR_OpenMP,
4344           getParallelRegionParams(SemaRef, LoopBoundSharing), Level);
4345       break;
4346     case OMPD_teams:
4347       SemaRef.ActOnCapturedRegionStart(Loc, CurScope, CR_OpenMP,
4348                                        getTeamsRegionParams(SemaRef), Level);
4349       break;
4350     case OMPD_task:
4351       SemaRef.ActOnCapturedRegionStart(Loc, CurScope, CR_OpenMP,
4352                                        getTaskRegionParams(SemaRef), Level);
4353       // Mark this captured region as inlined, because we don't use outlined
4354       // function directly.
4355       MarkAsInlined(SemaRef.getCurCapturedRegion());
4356       break;
4357     case OMPD_taskloop:
4358       SemaRef.ActOnCapturedRegionStart(Loc, CurScope, CR_OpenMP,
4359                                        getTaskloopRegionParams(SemaRef), Level);
4360       // Mark this captured region as inlined, because we don't use outlined
4361       // function directly.
4362       MarkAsInlined(SemaRef.getCurCapturedRegion());
4363       break;
4364     case OMPD_target:
4365       SemaRef.ActOnCapturedRegionStart(Loc, CurScope, CR_OpenMP,
4366                                        getTargetRegionParams(SemaRef), Level);
4367       break;
4368     case OMPD_unknown:
4369       SemaRef.ActOnCapturedRegionStart(Loc, CurScope, CR_OpenMP,
4370                                        getUnknownRegionParams(SemaRef));
4371       break;
4372     case OMPD_metadirective:
4373     case OMPD_nothing:
4374     default:
4375       llvm_unreachable("Unexpected capture region");
4376     }
4377   }
4378 }
4379 
4380 void SemaOpenMP::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind,
4381                                         Scope *CurScope) {
4382   switch (DKind) {
4383   case OMPD_atomic:
4384   case OMPD_critical:
4385   case OMPD_masked:
4386   case OMPD_master:
4387   case OMPD_section:
4388   case OMPD_tile:
4389   case OMPD_unroll:
4390   case OMPD_reverse:
4391   case OMPD_interchange:
4392   case OMPD_assume:
4393     break;
4394   default:
4395     processCapturedRegions(SemaRef, DKind, CurScope,
4396                            DSAStack->getConstructLoc());
4397     break;
4398   }
4399 
4400   DSAStack->setContext(SemaRef.CurContext);
4401   handleDeclareVariantConstructTrait(DSAStack, DKind, /*ScopeEntry=*/true);
4402 }
4403 
4404 int SemaOpenMP::getNumberOfConstructScopes(unsigned Level) const {
4405   return getOpenMPCaptureLevels(DSAStack->getDirective(Level));
4406 }
4407 
4408 int SemaOpenMP::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
4409   SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4410   getOpenMPCaptureRegions(CaptureRegions, DKind);
4411   return CaptureRegions.size();
4412 }
4413 
4414 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
4415                                              Expr *CaptureExpr, bool WithInit,
4416                                              DeclContext *CurContext,
4417                                              bool AsExpression) {
4418   assert(CaptureExpr);
4419   ASTContext &C = S.getASTContext();
4420   Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
4421   QualType Ty = Init->getType();
4422   if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
4423     if (S.getLangOpts().CPlusPlus) {
4424       Ty = C.getLValueReferenceType(Ty);
4425     } else {
4426       Ty = C.getPointerType(Ty);
4427       ExprResult Res =
4428           S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
4429       if (!Res.isUsable())
4430         return nullptr;
4431       Init = Res.get();
4432     }
4433     WithInit = true;
4434   }
4435   auto *CED = OMPCapturedExprDecl::Create(C, CurContext, Id, Ty,
4436                                           CaptureExpr->getBeginLoc());
4437   if (!WithInit)
4438     CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
4439   CurContext->addHiddenDecl(CED);
4440   Sema::TentativeAnalysisScope Trap(S);
4441   S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
4442   return CED;
4443 }
4444 
4445 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
4446                                  bool WithInit) {
4447   OMPCapturedExprDecl *CD;
4448   if (VarDecl *VD = S.OpenMP().isOpenMPCapturedDecl(D))
4449     CD = cast<OMPCapturedExprDecl>(VD);
4450   else
4451     CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
4452                           S.CurContext,
4453                           /*AsExpression=*/false);
4454   return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4455                           CaptureExpr->getExprLoc());
4456 }
4457 
4458 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref,
4459                                StringRef Name) {
4460   CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
4461   if (!Ref) {
4462     OMPCapturedExprDecl *CD = buildCaptureDecl(
4463         S, &S.getASTContext().Idents.get(Name), CaptureExpr,
4464         /*WithInit=*/true, S.CurContext, /*AsExpression=*/true);
4465     Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4466                            CaptureExpr->getExprLoc());
4467   }
4468   ExprResult Res = Ref;
4469   if (!S.getLangOpts().CPlusPlus &&
4470       CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
4471       Ref->getType()->isPointerType()) {
4472     Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
4473     if (!Res.isUsable())
4474       return ExprError();
4475   }
4476   return S.DefaultLvalueConversion(Res.get());
4477 }
4478 
4479 namespace {
4480 // OpenMP directives parsed in this section are represented as a
4481 // CapturedStatement with an associated statement.  If a syntax error
4482 // is detected during the parsing of the associated statement, the
4483 // compiler must abort processing and close the CapturedStatement.
4484 //
4485 // Combined directives such as 'target parallel' have more than one
4486 // nested CapturedStatements.  This RAII ensures that we unwind out
4487 // of all the nested CapturedStatements when an error is found.
4488 class CaptureRegionUnwinderRAII {
4489 private:
4490   Sema &S;
4491   bool &ErrorFound;
4492   OpenMPDirectiveKind DKind = OMPD_unknown;
4493 
4494 public:
4495   CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
4496                             OpenMPDirectiveKind DKind)
4497       : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
4498   ~CaptureRegionUnwinderRAII() {
4499     if (ErrorFound) {
4500       int ThisCaptureLevel = S.OpenMP().getOpenMPCaptureLevels(DKind);
4501       while (--ThisCaptureLevel >= 0)
4502         S.ActOnCapturedRegionError();
4503     }
4504   }
4505 };
4506 } // namespace
4507 
4508 void SemaOpenMP::tryCaptureOpenMPLambdas(ValueDecl *V) {
4509   // Capture variables captured by reference in lambdas for target-based
4510   // directives.
4511   if (!SemaRef.CurContext->isDependentContext() &&
4512       (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) ||
4513        isOpenMPTargetDataManagementDirective(
4514            DSAStack->getCurrentDirective()))) {
4515     QualType Type = V->getType();
4516     if (const auto *RD = Type.getCanonicalType()
4517                              .getNonReferenceType()
4518                              ->getAsCXXRecordDecl()) {
4519       bool SavedForceCaptureByReferenceInTargetExecutable =
4520           DSAStack->isForceCaptureByReferenceInTargetExecutable();
4521       DSAStack->setForceCaptureByReferenceInTargetExecutable(
4522           /*V=*/true);
4523       if (RD->isLambda()) {
4524         llvm::DenseMap<const ValueDecl *, FieldDecl *> Captures;
4525         FieldDecl *ThisCapture;
4526         RD->getCaptureFields(Captures, ThisCapture);
4527         for (const LambdaCapture &LC : RD->captures()) {
4528           if (LC.getCaptureKind() == LCK_ByRef) {
4529             VarDecl *VD = cast<VarDecl>(LC.getCapturedVar());
4530             DeclContext *VDC = VD->getDeclContext();
4531             if (!VDC->Encloses(SemaRef.CurContext))
4532               continue;
4533             SemaRef.MarkVariableReferenced(LC.getLocation(), VD);
4534           } else if (LC.getCaptureKind() == LCK_This) {
4535             QualType ThisTy = SemaRef.getCurrentThisType();
4536             if (!ThisTy.isNull() && getASTContext().typesAreCompatible(
4537                                         ThisTy, ThisCapture->getType()))
4538               SemaRef.CheckCXXThisCapture(LC.getLocation());
4539           }
4540         }
4541       }
4542       DSAStack->setForceCaptureByReferenceInTargetExecutable(
4543           SavedForceCaptureByReferenceInTargetExecutable);
4544     }
4545   }
4546 }
4547 
4548 static bool checkOrderedOrderSpecified(Sema &S,
4549                                        const ArrayRef<OMPClause *> Clauses) {
4550   const OMPOrderedClause *Ordered = nullptr;
4551   const OMPOrderClause *Order = nullptr;
4552 
4553   for (const OMPClause *Clause : Clauses) {
4554     if (Clause->getClauseKind() == OMPC_ordered)
4555       Ordered = cast<OMPOrderedClause>(Clause);
4556     else if (Clause->getClauseKind() == OMPC_order) {
4557       Order = cast<OMPOrderClause>(Clause);
4558       if (Order->getKind() != OMPC_ORDER_concurrent)
4559         Order = nullptr;
4560     }
4561     if (Ordered && Order)
4562       break;
4563   }
4564 
4565   if (Ordered && Order) {
4566     S.Diag(Order->getKindKwLoc(),
4567            diag::err_omp_simple_clause_incompatible_with_ordered)
4568         << getOpenMPClauseName(OMPC_order)
4569         << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent)
4570         << SourceRange(Order->getBeginLoc(), Order->getEndLoc());
4571     S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param)
4572         << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc());
4573     return true;
4574   }
4575   return false;
4576 }
4577 
4578 StmtResult SemaOpenMP::ActOnOpenMPRegionEnd(StmtResult S,
4579                                             ArrayRef<OMPClause *> Clauses) {
4580   handleDeclareVariantConstructTrait(DSAStack, DSAStack->getCurrentDirective(),
4581                                      /*ScopeEntry=*/false);
4582   if (!isOpenMPCapturingDirective(DSAStack->getCurrentDirective()))
4583     return S;
4584 
4585   bool ErrorFound = false;
4586   CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4587       SemaRef, ErrorFound, DSAStack->getCurrentDirective());
4588   if (!S.isUsable()) {
4589     ErrorFound = true;
4590     return StmtError();
4591   }
4592 
4593   SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4594   getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective());
4595   OMPOrderedClause *OC = nullptr;
4596   OMPScheduleClause *SC = nullptr;
4597   SmallVector<const OMPLinearClause *, 4> LCs;
4598   SmallVector<const OMPClauseWithPreInit *, 4> PICs;
4599   // This is required for proper codegen.
4600   for (OMPClause *Clause : Clauses) {
4601     if (!getLangOpts().OpenMPSimd &&
4602         (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) ||
4603          DSAStack->getCurrentDirective() == OMPD_target) &&
4604         Clause->getClauseKind() == OMPC_in_reduction) {
4605       // Capture taskgroup task_reduction descriptors inside the tasking regions
4606       // with the corresponding in_reduction items.
4607       auto *IRC = cast<OMPInReductionClause>(Clause);
4608       for (Expr *E : IRC->taskgroup_descriptors())
4609         if (E)
4610           SemaRef.MarkDeclarationsReferencedInExpr(E);
4611     }
4612     if (isOpenMPPrivate(Clause->getClauseKind()) ||
4613         Clause->getClauseKind() == OMPC_copyprivate ||
4614         (getLangOpts().OpenMPUseTLS &&
4615          getASTContext().getTargetInfo().isTLSSupported() &&
4616          Clause->getClauseKind() == OMPC_copyin)) {
4617       DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
4618       // Mark all variables in private list clauses as used in inner region.
4619       for (Stmt *VarRef : Clause->children()) {
4620         if (auto *E = cast_or_null<Expr>(VarRef)) {
4621           SemaRef.MarkDeclarationsReferencedInExpr(E);
4622         }
4623       }
4624       DSAStack->setForceVarCapturing(/*V=*/false);
4625     } else if (CaptureRegions.size() > 1 ||
4626                CaptureRegions.back() != OMPD_unknown) {
4627       if (auto *C = OMPClauseWithPreInit::get(Clause))
4628         PICs.push_back(C);
4629       if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
4630         if (Expr *E = C->getPostUpdateExpr())
4631           SemaRef.MarkDeclarationsReferencedInExpr(E);
4632       }
4633     }
4634     if (Clause->getClauseKind() == OMPC_schedule)
4635       SC = cast<OMPScheduleClause>(Clause);
4636     else if (Clause->getClauseKind() == OMPC_ordered)
4637       OC = cast<OMPOrderedClause>(Clause);
4638     else if (Clause->getClauseKind() == OMPC_linear)
4639       LCs.push_back(cast<OMPLinearClause>(Clause));
4640   }
4641   // Capture allocator expressions if used.
4642   for (Expr *E : DSAStack->getInnerAllocators())
4643     SemaRef.MarkDeclarationsReferencedInExpr(E);
4644   // OpenMP, 2.7.1 Loop Construct, Restrictions
4645   // The nonmonotonic modifier cannot be specified if an ordered clause is
4646   // specified.
4647   if (SC &&
4648       (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
4649        SC->getSecondScheduleModifier() ==
4650            OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4651       OC) {
4652     Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
4653              ? SC->getFirstScheduleModifierLoc()
4654              : SC->getSecondScheduleModifierLoc(),
4655          diag::err_omp_simple_clause_incompatible_with_ordered)
4656         << getOpenMPClauseName(OMPC_schedule)
4657         << getOpenMPSimpleClauseTypeName(OMPC_schedule,
4658                                          OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4659         << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4660     ErrorFound = true;
4661   }
4662   // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions.
4663   // If an order(concurrent) clause is present, an ordered clause may not appear
4664   // on the same directive.
4665   if (checkOrderedOrderSpecified(SemaRef, Clauses))
4666     ErrorFound = true;
4667   if (!LCs.empty() && OC && OC->getNumForLoops()) {
4668     for (const OMPLinearClause *C : LCs) {
4669       Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
4670           << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4671     }
4672     ErrorFound = true;
4673   }
4674   if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
4675       isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
4676       OC->getNumForLoops()) {
4677     Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
4678         << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
4679     ErrorFound = true;
4680   }
4681   if (ErrorFound) {
4682     return StmtError();
4683   }
4684   StmtResult SR = S;
4685   unsigned CompletedRegions = 0;
4686   for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
4687     // Mark all variables in private list clauses as used in inner region.
4688     // Required for proper codegen of combined directives.
4689     // TODO: add processing for other clauses.
4690     if (ThisCaptureRegion != OMPD_unknown) {
4691       for (const clang::OMPClauseWithPreInit *C : PICs) {
4692         OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
4693         // Find the particular capture region for the clause if the
4694         // directive is a combined one with multiple capture regions.
4695         // If the directive is not a combined one, the capture region
4696         // associated with the clause is OMPD_unknown and is generated
4697         // only once.
4698         if (CaptureRegion == ThisCaptureRegion ||
4699             CaptureRegion == OMPD_unknown) {
4700           if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
4701             for (Decl *D : DS->decls())
4702               SemaRef.MarkVariableReferenced(D->getLocation(),
4703                                              cast<VarDecl>(D));
4704           }
4705         }
4706       }
4707     }
4708     if (ThisCaptureRegion == OMPD_target) {
4709       // Capture allocator traits in the target region. They are used implicitly
4710       // and, thus, are not captured by default.
4711       for (OMPClause *C : Clauses) {
4712         if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) {
4713           for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4714                ++I) {
4715             OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I);
4716             if (Expr *E = D.AllocatorTraits)
4717               SemaRef.MarkDeclarationsReferencedInExpr(E);
4718           }
4719           continue;
4720         }
4721       }
4722     }
4723     if (ThisCaptureRegion == OMPD_parallel) {
4724       // Capture temp arrays for inscan reductions and locals in aligned
4725       // clauses.
4726       for (OMPClause *C : Clauses) {
4727         if (auto *RC = dyn_cast<OMPReductionClause>(C)) {
4728           if (RC->getModifier() != OMPC_REDUCTION_inscan)
4729             continue;
4730           for (Expr *E : RC->copy_array_temps())
4731             if (E)
4732               SemaRef.MarkDeclarationsReferencedInExpr(E);
4733         }
4734         if (auto *AC = dyn_cast<OMPAlignedClause>(C)) {
4735           for (Expr *E : AC->varlist())
4736             SemaRef.MarkDeclarationsReferencedInExpr(E);
4737         }
4738       }
4739     }
4740     if (++CompletedRegions == CaptureRegions.size())
4741       DSAStack->setBodyComplete();
4742     SR = SemaRef.ActOnCapturedRegionEnd(SR.get());
4743   }
4744   return SR;
4745 }
4746 
4747 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
4748                               OpenMPDirectiveKind CancelRegion,
4749                               SourceLocation StartLoc) {
4750   // CancelRegion is only needed for cancel and cancellation_point.
4751   if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4752     return false;
4753 
4754   if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4755       CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4756     return false;
4757 
4758   SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4759       << getOpenMPDirectiveName(CancelRegion);
4760   return true;
4761 }
4762 
4763 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4764                                   OpenMPDirectiveKind CurrentRegion,
4765                                   const DeclarationNameInfo &CurrentName,
4766                                   OpenMPDirectiveKind CancelRegion,
4767                                   OpenMPBindClauseKind BindKind,
4768                                   SourceLocation StartLoc) {
4769   if (!Stack->getCurScope())
4770     return false;
4771 
4772   OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
4773   OpenMPDirectiveKind OffendingRegion = ParentRegion;
4774   bool NestingProhibited = false;
4775   bool CloseNesting = true;
4776   bool OrphanSeen = false;
4777   enum {
4778     NoRecommend,
4779     ShouldBeInParallelRegion,
4780     ShouldBeInOrderedRegion,
4781     ShouldBeInTargetRegion,
4782     ShouldBeInTeamsRegion,
4783     ShouldBeInLoopSimdRegion,
4784   } Recommend = NoRecommend;
4785 
4786   SmallVector<OpenMPDirectiveKind, 4> LeafOrComposite;
4787   ArrayRef<OpenMPDirectiveKind> ParentLOC =
4788       getLeafOrCompositeConstructs(ParentRegion, LeafOrComposite);
4789   OpenMPDirectiveKind EnclosingConstruct = ParentLOC.back();
4790 
4791   if (SemaRef.LangOpts.OpenMP >= 51 && Stack->isParentOrderConcurrent() &&
4792       CurrentRegion != OMPD_simd && CurrentRegion != OMPD_loop &&
4793       CurrentRegion != OMPD_parallel &&
4794       !isOpenMPCombinedParallelADirective(CurrentRegion)) {
4795     SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_order)
4796         << getOpenMPDirectiveName(CurrentRegion);
4797     return true;
4798   }
4799   if (isOpenMPSimdDirective(ParentRegion) &&
4800       ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
4801        (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
4802         CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
4803         CurrentRegion != OMPD_scan))) {
4804     // OpenMP [2.16, Nesting of Regions]
4805     // OpenMP constructs may not be nested inside a simd region.
4806     // OpenMP [2.8.1,simd Construct, Restrictions]
4807     // An ordered construct with the simd clause is the only OpenMP
4808     // construct that can appear in the simd region.
4809     // Allowing a SIMD construct nested in another SIMD construct is an
4810     // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
4811     // message.
4812     // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions]
4813     // The only OpenMP constructs that can be encountered during execution of
4814     // a simd region are the atomic construct, the loop construct, the simd
4815     // construct and the ordered construct with the simd clause.
4816     SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
4817                                ? diag::err_omp_prohibited_region_simd
4818                                : diag::warn_omp_nesting_simd)
4819         << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0);
4820     return CurrentRegion != OMPD_simd;
4821   }
4822   if (EnclosingConstruct == OMPD_atomic) {
4823     // OpenMP [2.16, Nesting of Regions]
4824     // OpenMP constructs may not be nested inside an atomic region.
4825     SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
4826     return true;
4827   }
4828   if (CurrentRegion == OMPD_section) {
4829     // OpenMP [2.7.2, sections Construct, Restrictions]
4830     // Orphaned section directives are prohibited. That is, the section
4831     // directives must appear within the sections construct and must not be
4832     // encountered elsewhere in the sections region.
4833     if (EnclosingConstruct != OMPD_sections) {
4834       SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
4835           << (ParentRegion != OMPD_unknown)
4836           << getOpenMPDirectiveName(ParentRegion);
4837       return true;
4838     }
4839     return false;
4840   }
4841   // Allow some constructs (except teams and cancellation constructs) to be
4842   // orphaned (they could be used in functions, called from OpenMP regions
4843   // with the required preconditions).
4844   if (ParentRegion == OMPD_unknown &&
4845       !isOpenMPNestingTeamsDirective(CurrentRegion) &&
4846       CurrentRegion != OMPD_cancellation_point &&
4847       CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
4848     return false;
4849   // Checks needed for mapping "loop" construct. Please check mapLoopConstruct
4850   // for a detailed explanation
4851   if (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion == OMPD_loop &&
4852       (BindKind == OMPC_BIND_parallel || BindKind == OMPC_BIND_teams) &&
4853       (isOpenMPWorksharingDirective(ParentRegion) ||
4854        EnclosingConstruct == OMPD_loop)) {
4855     int ErrorMsgNumber = (BindKind == OMPC_BIND_parallel) ? 1 : 4;
4856     SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
4857         << true << getOpenMPDirectiveName(ParentRegion) << ErrorMsgNumber
4858         << getOpenMPDirectiveName(CurrentRegion);
4859     return true;
4860   }
4861   if (CurrentRegion == OMPD_cancellation_point ||
4862       CurrentRegion == OMPD_cancel) {
4863     // OpenMP [2.16, Nesting of Regions]
4864     // A cancellation point construct for which construct-type-clause is
4865     // taskgroup must be nested inside a task construct. A cancellation
4866     // point construct for which construct-type-clause is not taskgroup must
4867     // be closely nested inside an OpenMP construct that matches the type
4868     // specified in construct-type-clause.
4869     // A cancel construct for which construct-type-clause is taskgroup must be
4870     // nested inside a task construct. A cancel construct for which
4871     // construct-type-clause is not taskgroup must be closely nested inside an
4872     // OpenMP construct that matches the type specified in
4873     // construct-type-clause.
4874     ArrayRef<OpenMPDirectiveKind> Leafs = getLeafConstructsOrSelf(ParentRegion);
4875     if (CancelRegion == OMPD_taskgroup) {
4876       NestingProhibited = EnclosingConstruct != OMPD_task &&
4877                           (SemaRef.getLangOpts().OpenMP < 50 ||
4878                            EnclosingConstruct != OMPD_taskloop);
4879     } else if (CancelRegion == OMPD_sections) {
4880       NestingProhibited = EnclosingConstruct != OMPD_section &&
4881                           EnclosingConstruct != OMPD_sections;
4882     } else {
4883       NestingProhibited = CancelRegion != Leafs.back();
4884     }
4885     OrphanSeen = ParentRegion == OMPD_unknown;
4886   } else if (CurrentRegion == OMPD_master || CurrentRegion == OMPD_masked) {
4887     // OpenMP 5.1 [2.22, Nesting of Regions]
4888     // A masked region may not be closely nested inside a worksharing, loop,
4889     // atomic, task, or taskloop region.
4890     NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4891                         isOpenMPGenericLoopDirective(ParentRegion) ||
4892                         isOpenMPTaskingDirective(ParentRegion);
4893   } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
4894     // OpenMP [2.16, Nesting of Regions]
4895     // A critical region may not be nested (closely or otherwise) inside a
4896     // critical region with the same name. Note that this restriction is not
4897     // sufficient to prevent deadlock.
4898     SourceLocation PreviousCriticalLoc;
4899     bool DeadLock = Stack->hasDirective(
4900         [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
4901                                             const DeclarationNameInfo &DNI,
4902                                             SourceLocation Loc) {
4903           if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
4904             PreviousCriticalLoc = Loc;
4905             return true;
4906           }
4907           return false;
4908         },
4909         false /* skip top directive */);
4910     if (DeadLock) {
4911       SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_critical_same_name)
4912           << CurrentName.getName();
4913       if (PreviousCriticalLoc.isValid())
4914         SemaRef.Diag(PreviousCriticalLoc,
4915                      diag::note_omp_previous_critical_region);
4916       return true;
4917     }
4918   } else if (CurrentRegion == OMPD_barrier || CurrentRegion == OMPD_scope) {
4919     // OpenMP 5.1 [2.22, Nesting of Regions]
4920     // A scope region may not be closely nested inside a worksharing, loop,
4921     // task, taskloop, critical, ordered, atomic, or masked region.
4922     // OpenMP 5.1 [2.22, Nesting of Regions]
4923     // A barrier region may not be closely nested inside a worksharing, loop,
4924     // task, taskloop, critical, ordered, atomic, or masked region.
4925     NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4926                         isOpenMPGenericLoopDirective(ParentRegion) ||
4927                         isOpenMPTaskingDirective(ParentRegion) ||
4928                         llvm::is_contained({OMPD_masked, OMPD_master,
4929                                             OMPD_critical, OMPD_ordered},
4930                                            EnclosingConstruct);
4931   } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
4932              !isOpenMPParallelDirective(CurrentRegion) &&
4933              !isOpenMPTeamsDirective(CurrentRegion)) {
4934     // OpenMP 5.1 [2.22, Nesting of Regions]
4935     // A loop region that binds to a parallel region or a worksharing region
4936     // may not be closely nested inside a worksharing, loop, task, taskloop,
4937     // critical, ordered, atomic, or masked region.
4938     NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4939                         isOpenMPGenericLoopDirective(ParentRegion) ||
4940                         isOpenMPTaskingDirective(ParentRegion) ||
4941                         llvm::is_contained({OMPD_masked, OMPD_master,
4942                                             OMPD_critical, OMPD_ordered},
4943                                            EnclosingConstruct);
4944     Recommend = ShouldBeInParallelRegion;
4945   } else if (CurrentRegion == OMPD_ordered) {
4946     // OpenMP [2.16, Nesting of Regions]
4947     // An ordered region may not be closely nested inside a critical,
4948     // atomic, or explicit task region.
4949     // An ordered region must be closely nested inside a loop region (or
4950     // parallel loop region) with an ordered clause.
4951     // OpenMP [2.8.1,simd Construct, Restrictions]
4952     // An ordered construct with the simd clause is the only OpenMP construct
4953     // that can appear in the simd region.
4954     NestingProhibited = EnclosingConstruct == OMPD_critical ||
4955                         isOpenMPTaskingDirective(ParentRegion) ||
4956                         !(isOpenMPSimdDirective(ParentRegion) ||
4957                           Stack->isParentOrderedRegion());
4958     Recommend = ShouldBeInOrderedRegion;
4959   } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
4960     // OpenMP [2.16, Nesting of Regions]
4961     // If specified, a teams construct must be contained within a target
4962     // construct.
4963     NestingProhibited =
4964         (SemaRef.LangOpts.OpenMP <= 45 && EnclosingConstruct != OMPD_target) ||
4965         (SemaRef.LangOpts.OpenMP >= 50 && EnclosingConstruct != OMPD_unknown &&
4966          EnclosingConstruct != OMPD_target);
4967     OrphanSeen = ParentRegion == OMPD_unknown;
4968     Recommend = ShouldBeInTargetRegion;
4969   } else if (CurrentRegion == OMPD_scan) {
4970     if (SemaRef.LangOpts.OpenMP >= 50) {
4971       // OpenMP spec 5.0 and 5.1 require scan to be directly enclosed by for,
4972       // simd, or for simd. This has to take into account combined directives.
4973       // In 5.2 this seems to be implied by the fact that the specified
4974       // separated constructs are do, for, and simd.
4975       NestingProhibited = !llvm::is_contained(
4976           {OMPD_for, OMPD_simd, OMPD_for_simd}, EnclosingConstruct);
4977     } else {
4978       NestingProhibited = true;
4979     }
4980     OrphanSeen = ParentRegion == OMPD_unknown;
4981     Recommend = ShouldBeInLoopSimdRegion;
4982   }
4983   if (!NestingProhibited && !isOpenMPTargetExecutionDirective(CurrentRegion) &&
4984       !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
4985       EnclosingConstruct == OMPD_teams) {
4986     // OpenMP [5.1, 2.22, Nesting of Regions]
4987     // distribute, distribute simd, distribute parallel worksharing-loop,
4988     // distribute parallel worksharing-loop SIMD, loop, parallel regions,
4989     // including any parallel regions arising from combined constructs,
4990     // omp_get_num_teams() regions, and omp_get_team_num() regions are the
4991     // only OpenMP regions that may be strictly nested inside the teams
4992     // region.
4993     //
4994     // As an extension, we permit atomic within teams as well.
4995     NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
4996                         !isOpenMPDistributeDirective(CurrentRegion) &&
4997                         CurrentRegion != OMPD_loop &&
4998                         !(SemaRef.getLangOpts().OpenMPExtensions &&
4999                           CurrentRegion == OMPD_atomic);
5000     Recommend = ShouldBeInParallelRegion;
5001   }
5002   if (!NestingProhibited && CurrentRegion == OMPD_loop) {
5003     // OpenMP [5.1, 2.11.7, loop Construct, Restrictions]
5004     // If the bind clause is present on the loop construct and binding is
5005     // teams then the corresponding loop region must be strictly nested inside
5006     // a teams region.
5007     NestingProhibited =
5008         BindKind == OMPC_BIND_teams && EnclosingConstruct != OMPD_teams;
5009     Recommend = ShouldBeInTeamsRegion;
5010   }
5011   if (!NestingProhibited && isOpenMPNestingDistributeDirective(CurrentRegion)) {
5012     // OpenMP 4.5 [2.17 Nesting of Regions]
5013     // The region associated with the distribute construct must be strictly
5014     // nested inside a teams region
5015     NestingProhibited = EnclosingConstruct != OMPD_teams;
5016     Recommend = ShouldBeInTeamsRegion;
5017   }
5018   if (!NestingProhibited &&
5019       (isOpenMPTargetExecutionDirective(CurrentRegion) ||
5020        isOpenMPTargetDataManagementDirective(CurrentRegion))) {
5021     // OpenMP 4.5 [2.17 Nesting of Regions]
5022     // If a target, target update, target data, target enter data, or
5023     // target exit data construct is encountered during execution of a
5024     // target region, the behavior is unspecified.
5025     NestingProhibited = Stack->hasDirective(
5026         [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
5027                            SourceLocation) {
5028           if (isOpenMPTargetExecutionDirective(K)) {
5029             OffendingRegion = K;
5030             return true;
5031           }
5032           return false;
5033         },
5034         false /* don't skip top directive */);
5035     CloseNesting = false;
5036   }
5037   if (NestingProhibited) {
5038     if (OrphanSeen) {
5039       SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
5040           << getOpenMPDirectiveName(CurrentRegion) << Recommend;
5041     } else {
5042       SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
5043           << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
5044           << Recommend << getOpenMPDirectiveName(CurrentRegion);
5045     }
5046     return true;
5047   }
5048   return false;
5049 }
5050 
5051 struct Kind2Unsigned {
5052   using argument_type = OpenMPDirectiveKind;
5053   unsigned operator()(argument_type DK) { return unsigned(DK); }
5054 };
5055 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
5056                            ArrayRef<OMPClause *> Clauses,
5057                            ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
5058   bool ErrorFound = false;
5059   unsigned NamedModifiersNumber = 0;
5060   llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
5061   FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
5062   SmallVector<SourceLocation, 4> NameModifierLoc;
5063   for (const OMPClause *C : Clauses) {
5064     if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
5065       // At most one if clause without a directive-name-modifier can appear on
5066       // the directive.
5067       OpenMPDirectiveKind CurNM = IC->getNameModifier();
5068       if (FoundNameModifiers[CurNM]) {
5069         S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
5070             << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
5071             << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
5072         ErrorFound = true;
5073       } else if (CurNM != OMPD_unknown) {
5074         NameModifierLoc.push_back(IC->getNameModifierLoc());
5075         ++NamedModifiersNumber;
5076       }
5077       FoundNameModifiers[CurNM] = IC;
5078       if (CurNM == OMPD_unknown)
5079         continue;
5080       // Check if the specified name modifier is allowed for the current
5081       // directive.
5082       // At most one if clause with the particular directive-name-modifier can
5083       // appear on the directive.
5084       if (!llvm::is_contained(AllowedNameModifiers, CurNM)) {
5085         S.Diag(IC->getNameModifierLoc(),
5086                diag::err_omp_wrong_if_directive_name_modifier)
5087             << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
5088         ErrorFound = true;
5089       }
5090     }
5091   }
5092   // If any if clause on the directive includes a directive-name-modifier then
5093   // all if clauses on the directive must include a directive-name-modifier.
5094   if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
5095     if (NamedModifiersNumber == AllowedNameModifiers.size()) {
5096       S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
5097              diag::err_omp_no_more_if_clause);
5098     } else {
5099       std::string Values;
5100       std::string Sep(", ");
5101       unsigned AllowedCnt = 0;
5102       unsigned TotalAllowedNum =
5103           AllowedNameModifiers.size() - NamedModifiersNumber;
5104       for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
5105            ++Cnt) {
5106         OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
5107         if (!FoundNameModifiers[NM]) {
5108           Values += "'";
5109           Values += getOpenMPDirectiveName(NM);
5110           Values += "'";
5111           if (AllowedCnt + 2 == TotalAllowedNum)
5112             Values += " or ";
5113           else if (AllowedCnt + 1 != TotalAllowedNum)
5114             Values += Sep;
5115           ++AllowedCnt;
5116         }
5117       }
5118       S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
5119              diag::err_omp_unnamed_if_clause)
5120           << (TotalAllowedNum > 1) << Values;
5121     }
5122     for (SourceLocation Loc : NameModifierLoc) {
5123       S.Diag(Loc, diag::note_omp_previous_named_if_clause);
5124     }
5125     ErrorFound = true;
5126   }
5127   return ErrorFound;
5128 }
5129 
5130 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
5131                                                    SourceLocation &ELoc,
5132                                                    SourceRange &ERange,
5133                                                    bool AllowArraySection,
5134                                                    StringRef DiagType) {
5135   if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
5136       RefExpr->containsUnexpandedParameterPack())
5137     return std::make_pair(nullptr, true);
5138 
5139   // OpenMP [3.1, C/C++]
5140   //  A list item is a variable name.
5141   // OpenMP  [2.9.3.3, Restrictions, p.1]
5142   //  A variable that is part of another variable (as an array or
5143   //  structure element) cannot appear in a private clause.
5144   RefExpr = RefExpr->IgnoreParens();
5145   enum {
5146     NoArrayExpr = -1,
5147     ArraySubscript = 0,
5148     OMPArraySection = 1
5149   } IsArrayExpr = NoArrayExpr;
5150   if (AllowArraySection) {
5151     if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
5152       Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
5153       while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
5154         Base = TempASE->getBase()->IgnoreParenImpCasts();
5155       RefExpr = Base;
5156       IsArrayExpr = ArraySubscript;
5157     } else if (auto *OASE = dyn_cast_or_null<ArraySectionExpr>(RefExpr)) {
5158       Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
5159       while (auto *TempOASE = dyn_cast<ArraySectionExpr>(Base))
5160         Base = TempOASE->getBase()->IgnoreParenImpCasts();
5161       while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
5162         Base = TempASE->getBase()->IgnoreParenImpCasts();
5163       RefExpr = Base;
5164       IsArrayExpr = OMPArraySection;
5165     }
5166   }
5167   ELoc = RefExpr->getExprLoc();
5168   ERange = RefExpr->getSourceRange();
5169   RefExpr = RefExpr->IgnoreParenImpCasts();
5170   auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
5171   auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
5172   if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
5173       (S.getCurrentThisType().isNull() || !ME ||
5174        !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
5175        !isa<FieldDecl>(ME->getMemberDecl()))) {
5176     if (IsArrayExpr != NoArrayExpr) {
5177       S.Diag(ELoc, diag::err_omp_expected_base_var_name)
5178           << IsArrayExpr << ERange;
5179     } else if (!DiagType.empty()) {
5180       unsigned DiagSelect = S.getLangOpts().CPlusPlus
5181                                 ? (S.getCurrentThisType().isNull() ? 1 : 2)
5182                                 : 0;
5183       S.Diag(ELoc, diag::err_omp_expected_var_name_member_expr_with_type)
5184           << DiagSelect << DiagType << ERange;
5185     } else {
5186       S.Diag(ELoc,
5187              AllowArraySection
5188                  ? diag::err_omp_expected_var_name_member_expr_or_array_item
5189                  : diag::err_omp_expected_var_name_member_expr)
5190           << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
5191     }
5192     return std::make_pair(nullptr, false);
5193   }
5194   return std::make_pair(
5195       getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
5196 }
5197 
5198 namespace {
5199 /// Checks if the allocator is used in uses_allocators clause to be allowed in
5200 /// target regions.
5201 class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> {
5202   DSAStackTy *S = nullptr;
5203 
5204 public:
5205   bool VisitDeclRefExpr(const DeclRefExpr *E) {
5206     return S->isUsesAllocatorsDecl(E->getDecl())
5207                .value_or(DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
5208            DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
5209   }
5210   bool VisitStmt(const Stmt *S) {
5211     for (const Stmt *Child : S->children()) {
5212       if (Child && Visit(Child))
5213         return true;
5214     }
5215     return false;
5216   }
5217   explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
5218 };
5219 } // namespace
5220 
5221 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
5222                                  ArrayRef<OMPClause *> Clauses) {
5223   assert(!S.CurContext->isDependentContext() &&
5224          "Expected non-dependent context.");
5225   auto AllocateRange =
5226       llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
5227   llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> DeclToCopy;
5228   auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
5229     return isOpenMPPrivate(C->getClauseKind());
5230   });
5231   for (OMPClause *Cl : PrivateRange) {
5232     MutableArrayRef<Expr *>::iterator I, It, Et;
5233     if (Cl->getClauseKind() == OMPC_private) {
5234       auto *PC = cast<OMPPrivateClause>(Cl);
5235       I = PC->private_copies().begin();
5236       It = PC->varlist_begin();
5237       Et = PC->varlist_end();
5238     } else if (Cl->getClauseKind() == OMPC_firstprivate) {
5239       auto *PC = cast<OMPFirstprivateClause>(Cl);
5240       I = PC->private_copies().begin();
5241       It = PC->varlist_begin();
5242       Et = PC->varlist_end();
5243     } else if (Cl->getClauseKind() == OMPC_lastprivate) {
5244       auto *PC = cast<OMPLastprivateClause>(Cl);
5245       I = PC->private_copies().begin();
5246       It = PC->varlist_begin();
5247       Et = PC->varlist_end();
5248     } else if (Cl->getClauseKind() == OMPC_linear) {
5249       auto *PC = cast<OMPLinearClause>(Cl);
5250       I = PC->privates().begin();
5251       It = PC->varlist_begin();
5252       Et = PC->varlist_end();
5253     } else if (Cl->getClauseKind() == OMPC_reduction) {
5254       auto *PC = cast<OMPReductionClause>(Cl);
5255       I = PC->privates().begin();
5256       It = PC->varlist_begin();
5257       Et = PC->varlist_end();
5258     } else if (Cl->getClauseKind() == OMPC_task_reduction) {
5259       auto *PC = cast<OMPTaskReductionClause>(Cl);
5260       I = PC->privates().begin();
5261       It = PC->varlist_begin();
5262       Et = PC->varlist_end();
5263     } else if (Cl->getClauseKind() == OMPC_in_reduction) {
5264       auto *PC = cast<OMPInReductionClause>(Cl);
5265       I = PC->privates().begin();
5266       It = PC->varlist_begin();
5267       Et = PC->varlist_end();
5268     } else {
5269       llvm_unreachable("Expected private clause.");
5270     }
5271     for (Expr *E : llvm::make_range(It, Et)) {
5272       if (!*I) {
5273         ++I;
5274         continue;
5275       }
5276       SourceLocation ELoc;
5277       SourceRange ERange;
5278       Expr *SimpleRefExpr = E;
5279       auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
5280                                 /*AllowArraySection=*/true);
5281       DeclToCopy.try_emplace(Res.first,
5282                              cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
5283       ++I;
5284     }
5285   }
5286   for (OMPClause *C : AllocateRange) {
5287     auto *AC = cast<OMPAllocateClause>(C);
5288     if (S.getLangOpts().OpenMP >= 50 &&
5289         !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() &&
5290         isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
5291         AC->getAllocator()) {
5292       Expr *Allocator = AC->getAllocator();
5293       // OpenMP, 2.12.5 target Construct
5294       // Memory allocators that do not appear in a uses_allocators clause cannot
5295       // appear as an allocator in an allocate clause or be used in the target
5296       // region unless a requires directive with the dynamic_allocators clause
5297       // is present in the same compilation unit.
5298       AllocatorChecker Checker(Stack);
5299       if (Checker.Visit(Allocator))
5300         S.Diag(Allocator->getExprLoc(),
5301                diag::err_omp_allocator_not_in_uses_allocators)
5302             << Allocator->getSourceRange();
5303     }
5304     OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
5305         getAllocatorKind(S, Stack, AC->getAllocator());
5306     // OpenMP, 2.11.4 allocate Clause, Restrictions.
5307     // For task, taskloop or target directives, allocation requests to memory
5308     // allocators with the trait access set to thread result in unspecified
5309     // behavior.
5310     if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
5311         (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
5312          isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
5313       S.Diag(AC->getAllocator()->getExprLoc(),
5314              diag::warn_omp_allocate_thread_on_task_target_directive)
5315           << getOpenMPDirectiveName(Stack->getCurrentDirective());
5316     }
5317     for (Expr *E : AC->varlist()) {
5318       SourceLocation ELoc;
5319       SourceRange ERange;
5320       Expr *SimpleRefExpr = E;
5321       auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
5322       ValueDecl *VD = Res.first;
5323       if (!VD)
5324         continue;
5325       DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
5326       if (!isOpenMPPrivate(Data.CKind)) {
5327         S.Diag(E->getExprLoc(),
5328                diag::err_omp_expected_private_copy_for_allocate);
5329         continue;
5330       }
5331       VarDecl *PrivateVD = DeclToCopy[VD];
5332       if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
5333                                             AllocatorKind, AC->getAllocator()))
5334         continue;
5335       applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
5336                                 AC->getAlignment(), E->getSourceRange());
5337     }
5338   }
5339 }
5340 
5341 namespace {
5342 /// Rewrite statements and expressions for Sema \p Actions CurContext.
5343 ///
5344 /// Used to wrap already parsed statements/expressions into a new CapturedStmt
5345 /// context. DeclRefExpr used inside the new context are changed to refer to the
5346 /// captured variable instead.
5347 class CaptureVars : public TreeTransform<CaptureVars> {
5348   using BaseTransform = TreeTransform<CaptureVars>;
5349 
5350 public:
5351   CaptureVars(Sema &Actions) : BaseTransform(Actions) {}
5352 
5353   bool AlwaysRebuild() { return true; }
5354 };
5355 } // namespace
5356 
5357 static VarDecl *precomputeExpr(Sema &Actions,
5358                                SmallVectorImpl<Stmt *> &BodyStmts, Expr *E,
5359                                StringRef Name) {
5360   Expr *NewE = AssertSuccess(CaptureVars(Actions).TransformExpr(E));
5361   VarDecl *NewVar = buildVarDecl(Actions, {}, NewE->getType(), Name, nullptr,
5362                                  dyn_cast<DeclRefExpr>(E->IgnoreImplicit()));
5363   auto *NewDeclStmt = cast<DeclStmt>(AssertSuccess(
5364       Actions.ActOnDeclStmt(Actions.ConvertDeclToDeclGroup(NewVar), {}, {})));
5365   Actions.AddInitializerToDecl(NewDeclStmt->getSingleDecl(), NewE, false);
5366   BodyStmts.push_back(NewDeclStmt);
5367   return NewVar;
5368 }
5369 
5370 /// Create a closure that computes the number of iterations of a loop.
5371 ///
5372 /// \param Actions   The Sema object.
5373 /// \param LogicalTy Type for the logical iteration number.
5374 /// \param Rel       Comparison operator of the loop condition.
5375 /// \param StartExpr Value of the loop counter at the first iteration.
5376 /// \param StopExpr  Expression the loop counter is compared against in the loop
5377 /// condition. \param StepExpr      Amount of increment after each iteration.
5378 ///
5379 /// \return Closure (CapturedStmt) of the distance calculation.
5380 static CapturedStmt *buildDistanceFunc(Sema &Actions, QualType LogicalTy,
5381                                        BinaryOperator::Opcode Rel,
5382                                        Expr *StartExpr, Expr *StopExpr,
5383                                        Expr *StepExpr) {
5384   ASTContext &Ctx = Actions.getASTContext();
5385   TypeSourceInfo *LogicalTSI = Ctx.getTrivialTypeSourceInfo(LogicalTy);
5386 
5387   // Captured regions currently don't support return values, we use an
5388   // out-parameter instead. All inputs are implicit captures.
5389   // TODO: Instead of capturing each DeclRefExpr occurring in
5390   // StartExpr/StopExpr/Step, these could also be passed as a value capture.
5391   QualType ResultTy = Ctx.getLValueReferenceType(LogicalTy);
5392   Sema::CapturedParamNameType Params[] = {{"Distance", ResultTy},
5393                                           {StringRef(), QualType()}};
5394   Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5395 
5396   Stmt *Body;
5397   {
5398     Sema::CompoundScopeRAII CompoundScope(Actions);
5399     CapturedDecl *CS = cast<CapturedDecl>(Actions.CurContext);
5400 
5401     // Get the LValue expression for the result.
5402     ImplicitParamDecl *DistParam = CS->getParam(0);
5403     DeclRefExpr *DistRef = Actions.BuildDeclRefExpr(
5404         DistParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5405 
5406     SmallVector<Stmt *, 4> BodyStmts;
5407 
5408     // Capture all referenced variable references.
5409     // TODO: Instead of computing NewStart/NewStop/NewStep inside the
5410     // CapturedStmt, we could compute them before and capture the result, to be
5411     // used jointly with the LoopVar function.
5412     VarDecl *NewStart = precomputeExpr(Actions, BodyStmts, StartExpr, ".start");
5413     VarDecl *NewStop = precomputeExpr(Actions, BodyStmts, StopExpr, ".stop");
5414     VarDecl *NewStep = precomputeExpr(Actions, BodyStmts, StepExpr, ".step");
5415     auto BuildVarRef = [&](VarDecl *VD) {
5416       return buildDeclRefExpr(Actions, VD, VD->getType(), {});
5417     };
5418 
5419     IntegerLiteral *Zero = IntegerLiteral::Create(
5420         Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 0), LogicalTy, {});
5421     IntegerLiteral *One = IntegerLiteral::Create(
5422         Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {});
5423     Expr *Dist;
5424     if (Rel == BO_NE) {
5425       // When using a != comparison, the increment can be +1 or -1. This can be
5426       // dynamic at runtime, so we need to check for the direction.
5427       Expr *IsNegStep = AssertSuccess(
5428           Actions.BuildBinOp(nullptr, {}, BO_LT, BuildVarRef(NewStep), Zero));
5429 
5430       // Positive increment.
5431       Expr *ForwardRange = AssertSuccess(Actions.BuildBinOp(
5432           nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5433       ForwardRange = AssertSuccess(
5434           Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, ForwardRange));
5435       Expr *ForwardDist = AssertSuccess(Actions.BuildBinOp(
5436           nullptr, {}, BO_Div, ForwardRange, BuildVarRef(NewStep)));
5437 
5438       // Negative increment.
5439       Expr *BackwardRange = AssertSuccess(Actions.BuildBinOp(
5440           nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5441       BackwardRange = AssertSuccess(
5442           Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, BackwardRange));
5443       Expr *NegIncAmount = AssertSuccess(
5444           Actions.BuildUnaryOp(nullptr, {}, UO_Minus, BuildVarRef(NewStep)));
5445       Expr *BackwardDist = AssertSuccess(
5446           Actions.BuildBinOp(nullptr, {}, BO_Div, BackwardRange, NegIncAmount));
5447 
5448       // Use the appropriate case.
5449       Dist = AssertSuccess(Actions.ActOnConditionalOp(
5450           {}, {}, IsNegStep, BackwardDist, ForwardDist));
5451     } else {
5452       assert((Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT) &&
5453              "Expected one of these relational operators");
5454 
5455       // We can derive the direction from any other comparison operator. It is
5456       // non well-formed OpenMP if Step increments/decrements in the other
5457       // directions. Whether at least the first iteration passes the loop
5458       // condition.
5459       Expr *HasAnyIteration = AssertSuccess(Actions.BuildBinOp(
5460           nullptr, {}, Rel, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5461 
5462       // Compute the range between first and last counter value.
5463       Expr *Range;
5464       if (Rel == BO_GE || Rel == BO_GT)
5465         Range = AssertSuccess(Actions.BuildBinOp(
5466             nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5467       else
5468         Range = AssertSuccess(Actions.BuildBinOp(
5469             nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5470 
5471       // Ensure unsigned range space.
5472       Range =
5473           AssertSuccess(Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, Range));
5474 
5475       if (Rel == BO_LE || Rel == BO_GE) {
5476         // Add one to the range if the relational operator is inclusive.
5477         Range =
5478             AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, Range, One));
5479       }
5480 
5481       // Divide by the absolute step amount. If the range is not a multiple of
5482       // the step size, rounding-up the effective upper bound ensures that the
5483       // last iteration is included.
5484       // Note that the rounding-up may cause an overflow in a temporary that
5485       // could be avoided, but would have occurred in a C-style for-loop as
5486       // well.
5487       Expr *Divisor = BuildVarRef(NewStep);
5488       if (Rel == BO_GE || Rel == BO_GT)
5489         Divisor =
5490             AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Minus, Divisor));
5491       Expr *DivisorMinusOne =
5492           AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Sub, Divisor, One));
5493       Expr *RangeRoundUp = AssertSuccess(
5494           Actions.BuildBinOp(nullptr, {}, BO_Add, Range, DivisorMinusOne));
5495       Dist = AssertSuccess(
5496           Actions.BuildBinOp(nullptr, {}, BO_Div, RangeRoundUp, Divisor));
5497 
5498       // If there is not at least one iteration, the range contains garbage. Fix
5499       // to zero in this case.
5500       Dist = AssertSuccess(
5501           Actions.ActOnConditionalOp({}, {}, HasAnyIteration, Dist, Zero));
5502     }
5503 
5504     // Assign the result to the out-parameter.
5505     Stmt *ResultAssign = AssertSuccess(Actions.BuildBinOp(
5506         Actions.getCurScope(), {}, BO_Assign, DistRef, Dist));
5507     BodyStmts.push_back(ResultAssign);
5508 
5509     Body = AssertSuccess(Actions.ActOnCompoundStmt({}, {}, BodyStmts, false));
5510   }
5511 
5512   return cast<CapturedStmt>(
5513       AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5514 }
5515 
5516 /// Create a closure that computes the loop variable from the logical iteration
5517 /// number.
5518 ///
5519 /// \param Actions   The Sema object.
5520 /// \param LoopVarTy Type for the loop variable used for result value.
5521 /// \param LogicalTy Type for the logical iteration number.
5522 /// \param StartExpr Value of the loop counter at the first iteration.
5523 /// \param Step      Amount of increment after each iteration.
5524 /// \param Deref     Whether the loop variable is a dereference of the loop
5525 /// counter variable.
5526 ///
5527 /// \return Closure (CapturedStmt) of the loop value calculation.
5528 static CapturedStmt *buildLoopVarFunc(Sema &Actions, QualType LoopVarTy,
5529                                       QualType LogicalTy,
5530                                       DeclRefExpr *StartExpr, Expr *Step,
5531                                       bool Deref) {
5532   ASTContext &Ctx = Actions.getASTContext();
5533 
5534   // Pass the result as an out-parameter. Passing as return value would require
5535   // the OpenMPIRBuilder to know additional C/C++ semantics, such as how to
5536   // invoke a copy constructor.
5537   QualType TargetParamTy = Ctx.getLValueReferenceType(LoopVarTy);
5538   SemaOpenMP::CapturedParamNameType Params[] = {{"LoopVar", TargetParamTy},
5539                                                 {"Logical", LogicalTy},
5540                                                 {StringRef(), QualType()}};
5541   Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5542 
5543   // Capture the initial iterator which represents the LoopVar value at the
5544   // zero's logical iteration. Since the original ForStmt/CXXForRangeStmt update
5545   // it in every iteration, capture it by value before it is modified.
5546   VarDecl *StartVar = cast<VarDecl>(StartExpr->getDecl());
5547   bool Invalid = Actions.tryCaptureVariable(StartVar, {},
5548                                             Sema::TryCapture_ExplicitByVal, {});
5549   (void)Invalid;
5550   assert(!Invalid && "Expecting capture-by-value to work.");
5551 
5552   Expr *Body;
5553   {
5554     Sema::CompoundScopeRAII CompoundScope(Actions);
5555     auto *CS = cast<CapturedDecl>(Actions.CurContext);
5556 
5557     ImplicitParamDecl *TargetParam = CS->getParam(0);
5558     DeclRefExpr *TargetRef = Actions.BuildDeclRefExpr(
5559         TargetParam, LoopVarTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5560     ImplicitParamDecl *IndvarParam = CS->getParam(1);
5561     DeclRefExpr *LogicalRef = Actions.BuildDeclRefExpr(
5562         IndvarParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5563 
5564     // Capture the Start expression.
5565     CaptureVars Recap(Actions);
5566     Expr *NewStart = AssertSuccess(Recap.TransformExpr(StartExpr));
5567     Expr *NewStep = AssertSuccess(Recap.TransformExpr(Step));
5568 
5569     Expr *Skip = AssertSuccess(
5570         Actions.BuildBinOp(nullptr, {}, BO_Mul, NewStep, LogicalRef));
5571     // TODO: Explicitly cast to the iterator's difference_type instead of
5572     // relying on implicit conversion.
5573     Expr *Advanced =
5574         AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, NewStart, Skip));
5575 
5576     if (Deref) {
5577       // For range-based for-loops convert the loop counter value to a concrete
5578       // loop variable value by dereferencing the iterator.
5579       Advanced =
5580           AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Deref, Advanced));
5581     }
5582 
5583     // Assign the result to the output parameter.
5584     Body = AssertSuccess(Actions.BuildBinOp(Actions.getCurScope(), {},
5585                                             BO_Assign, TargetRef, Advanced));
5586   }
5587   return cast<CapturedStmt>(
5588       AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5589 }
5590 
5591 StmtResult SemaOpenMP::ActOnOpenMPCanonicalLoop(Stmt *AStmt) {
5592   ASTContext &Ctx = getASTContext();
5593 
5594   // Extract the common elements of ForStmt and CXXForRangeStmt:
5595   // Loop variable, repeat condition, increment
5596   Expr *Cond, *Inc;
5597   VarDecl *LIVDecl, *LUVDecl;
5598   if (auto *For = dyn_cast<ForStmt>(AStmt)) {
5599     Stmt *Init = For->getInit();
5600     if (auto *LCVarDeclStmt = dyn_cast<DeclStmt>(Init)) {
5601       // For statement declares loop variable.
5602       LIVDecl = cast<VarDecl>(LCVarDeclStmt->getSingleDecl());
5603     } else if (auto *LCAssign = dyn_cast<BinaryOperator>(Init)) {
5604       // For statement reuses variable.
5605       assert(LCAssign->getOpcode() == BO_Assign &&
5606              "init part must be a loop variable assignment");
5607       auto *CounterRef = cast<DeclRefExpr>(LCAssign->getLHS());
5608       LIVDecl = cast<VarDecl>(CounterRef->getDecl());
5609     } else
5610       llvm_unreachable("Cannot determine loop variable");
5611     LUVDecl = LIVDecl;
5612 
5613     Cond = For->getCond();
5614     Inc = For->getInc();
5615   } else if (auto *RangeFor = dyn_cast<CXXForRangeStmt>(AStmt)) {
5616     DeclStmt *BeginStmt = RangeFor->getBeginStmt();
5617     LIVDecl = cast<VarDecl>(BeginStmt->getSingleDecl());
5618     LUVDecl = RangeFor->getLoopVariable();
5619 
5620     Cond = RangeFor->getCond();
5621     Inc = RangeFor->getInc();
5622   } else
5623     llvm_unreachable("unhandled kind of loop");
5624 
5625   QualType CounterTy = LIVDecl->getType();
5626   QualType LVTy = LUVDecl->getType();
5627 
5628   // Analyze the loop condition.
5629   Expr *LHS, *RHS;
5630   BinaryOperator::Opcode CondRel;
5631   Cond = Cond->IgnoreImplicit();
5632   if (auto *CondBinExpr = dyn_cast<BinaryOperator>(Cond)) {
5633     LHS = CondBinExpr->getLHS();
5634     RHS = CondBinExpr->getRHS();
5635     CondRel = CondBinExpr->getOpcode();
5636   } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Cond)) {
5637     assert(CondCXXOp->getNumArgs() == 2 && "Comparison should have 2 operands");
5638     LHS = CondCXXOp->getArg(0);
5639     RHS = CondCXXOp->getArg(1);
5640     switch (CondCXXOp->getOperator()) {
5641     case OO_ExclaimEqual:
5642       CondRel = BO_NE;
5643       break;
5644     case OO_Less:
5645       CondRel = BO_LT;
5646       break;
5647     case OO_LessEqual:
5648       CondRel = BO_LE;
5649       break;
5650     case OO_Greater:
5651       CondRel = BO_GT;
5652       break;
5653     case OO_GreaterEqual:
5654       CondRel = BO_GE;
5655       break;
5656     default:
5657       llvm_unreachable("unexpected iterator operator");
5658     }
5659   } else
5660     llvm_unreachable("unexpected loop condition");
5661 
5662   // Normalize such that the loop counter is on the LHS.
5663   if (!isa<DeclRefExpr>(LHS->IgnoreImplicit()) ||
5664       cast<DeclRefExpr>(LHS->IgnoreImplicit())->getDecl() != LIVDecl) {
5665     std::swap(LHS, RHS);
5666     CondRel = BinaryOperator::reverseComparisonOp(CondRel);
5667   }
5668   auto *CounterRef = cast<DeclRefExpr>(LHS->IgnoreImplicit());
5669 
5670   // Decide the bit width for the logical iteration counter. By default use the
5671   // unsigned ptrdiff_t integer size (for iterators and pointers).
5672   // TODO: For iterators, use iterator::difference_type,
5673   // std::iterator_traits<>::difference_type or decltype(it - end).
5674   QualType LogicalTy = Ctx.getUnsignedPointerDiffType();
5675   if (CounterTy->isIntegerType()) {
5676     unsigned BitWidth = Ctx.getIntWidth(CounterTy);
5677     LogicalTy = Ctx.getIntTypeForBitwidth(BitWidth, false);
5678   }
5679 
5680   // Analyze the loop increment.
5681   Expr *Step;
5682   if (auto *IncUn = dyn_cast<UnaryOperator>(Inc)) {
5683     int Direction;
5684     switch (IncUn->getOpcode()) {
5685     case UO_PreInc:
5686     case UO_PostInc:
5687       Direction = 1;
5688       break;
5689     case UO_PreDec:
5690     case UO_PostDec:
5691       Direction = -1;
5692       break;
5693     default:
5694       llvm_unreachable("unhandled unary increment operator");
5695     }
5696     Step = IntegerLiteral::Create(
5697         Ctx,
5698         llvm::APInt(Ctx.getIntWidth(LogicalTy), Direction, /*isSigned=*/true),
5699         LogicalTy, {});
5700   } else if (auto *IncBin = dyn_cast<BinaryOperator>(Inc)) {
5701     if (IncBin->getOpcode() == BO_AddAssign) {
5702       Step = IncBin->getRHS();
5703     } else if (IncBin->getOpcode() == BO_SubAssign) {
5704       Step = AssertSuccess(
5705           SemaRef.BuildUnaryOp(nullptr, {}, UO_Minus, IncBin->getRHS()));
5706     } else
5707       llvm_unreachable("unhandled binary increment operator");
5708   } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Inc)) {
5709     switch (CondCXXOp->getOperator()) {
5710     case OO_PlusPlus:
5711       Step = IntegerLiteral::Create(
5712           Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {});
5713       break;
5714     case OO_MinusMinus:
5715       Step = IntegerLiteral::Create(
5716           Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), -1), LogicalTy, {});
5717       break;
5718     case OO_PlusEqual:
5719       Step = CondCXXOp->getArg(1);
5720       break;
5721     case OO_MinusEqual:
5722       Step = AssertSuccess(
5723           SemaRef.BuildUnaryOp(nullptr, {}, UO_Minus, CondCXXOp->getArg(1)));
5724       break;
5725     default:
5726       llvm_unreachable("unhandled overloaded increment operator");
5727     }
5728   } else
5729     llvm_unreachable("unknown increment expression");
5730 
5731   CapturedStmt *DistanceFunc =
5732       buildDistanceFunc(SemaRef, LogicalTy, CondRel, LHS, RHS, Step);
5733   CapturedStmt *LoopVarFunc = buildLoopVarFunc(
5734       SemaRef, LVTy, LogicalTy, CounterRef, Step, isa<CXXForRangeStmt>(AStmt));
5735   DeclRefExpr *LVRef =
5736       SemaRef.BuildDeclRefExpr(LUVDecl, LUVDecl->getType(), VK_LValue, {},
5737                                nullptr, nullptr, {}, nullptr);
5738   return OMPCanonicalLoop::create(getASTContext(), AStmt, DistanceFunc,
5739                                   LoopVarFunc, LVRef);
5740 }
5741 
5742 StmtResult SemaOpenMP::ActOnOpenMPLoopnest(Stmt *AStmt) {
5743   // Handle a literal loop.
5744   if (isa<ForStmt>(AStmt) || isa<CXXForRangeStmt>(AStmt))
5745     return ActOnOpenMPCanonicalLoop(AStmt);
5746 
5747   // If not a literal loop, it must be the result of a loop transformation.
5748   OMPExecutableDirective *LoopTransform = cast<OMPExecutableDirective>(AStmt);
5749   assert(
5750       isOpenMPLoopTransformationDirective(LoopTransform->getDirectiveKind()) &&
5751       "Loop transformation directive expected");
5752   return LoopTransform;
5753 }
5754 
5755 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
5756                                             CXXScopeSpec &MapperIdScopeSpec,
5757                                             const DeclarationNameInfo &MapperId,
5758                                             QualType Type,
5759                                             Expr *UnresolvedMapper);
5760 
5761 /// Perform DFS through the structure/class data members trying to find
5762 /// member(s) with user-defined 'default' mapper and generate implicit map
5763 /// clauses for such members with the found 'default' mapper.
5764 static void
5765 processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack,
5766                                       SmallVectorImpl<OMPClause *> &Clauses) {
5767   // Check for the default mapper for data members.
5768   if (S.getLangOpts().OpenMP < 50)
5769     return;
5770   SmallVector<OMPClause *, 4> ImplicitMaps;
5771   for (int Cnt = 0, EndCnt = Clauses.size(); Cnt < EndCnt; ++Cnt) {
5772     auto *C = dyn_cast<OMPMapClause>(Clauses[Cnt]);
5773     if (!C)
5774       continue;
5775     SmallVector<Expr *, 4> SubExprs;
5776     auto *MI = C->mapperlist_begin();
5777     for (auto I = C->varlist_begin(), End = C->varlist_end(); I != End;
5778          ++I, ++MI) {
5779       // Expression is mapped using mapper - skip it.
5780       if (*MI)
5781         continue;
5782       Expr *E = *I;
5783       // Expression is dependent - skip it, build the mapper when it gets
5784       // instantiated.
5785       if (E->isTypeDependent() || E->isValueDependent() ||
5786           E->containsUnexpandedParameterPack())
5787         continue;
5788       // Array section - need to check for the mapping of the array section
5789       // element.
5790       QualType CanonType = E->getType().getCanonicalType();
5791       if (CanonType->isSpecificBuiltinType(BuiltinType::ArraySection)) {
5792         const auto *OASE = cast<ArraySectionExpr>(E->IgnoreParenImpCasts());
5793         QualType BaseType =
5794             ArraySectionExpr::getBaseOriginalType(OASE->getBase());
5795         QualType ElemType;
5796         if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
5797           ElemType = ATy->getElementType();
5798         else
5799           ElemType = BaseType->getPointeeType();
5800         CanonType = ElemType;
5801       }
5802 
5803       // DFS over data members in structures/classes.
5804       SmallVector<std::pair<QualType, FieldDecl *>, 4> Types(
5805           1, {CanonType, nullptr});
5806       llvm::DenseMap<const Type *, Expr *> Visited;
5807       SmallVector<std::pair<FieldDecl *, unsigned>, 4> ParentChain(
5808           1, {nullptr, 1});
5809       while (!Types.empty()) {
5810         QualType BaseType;
5811         FieldDecl *CurFD;
5812         std::tie(BaseType, CurFD) = Types.pop_back_val();
5813         while (ParentChain.back().second == 0)
5814           ParentChain.pop_back();
5815         --ParentChain.back().second;
5816         if (BaseType.isNull())
5817           continue;
5818         // Only structs/classes are allowed to have mappers.
5819         const RecordDecl *RD = BaseType.getCanonicalType()->getAsRecordDecl();
5820         if (!RD)
5821           continue;
5822         auto It = Visited.find(BaseType.getTypePtr());
5823         if (It == Visited.end()) {
5824           // Try to find the associated user-defined mapper.
5825           CXXScopeSpec MapperIdScopeSpec;
5826           DeclarationNameInfo DefaultMapperId;
5827           DefaultMapperId.setName(S.Context.DeclarationNames.getIdentifier(
5828               &S.Context.Idents.get("default")));
5829           DefaultMapperId.setLoc(E->getExprLoc());
5830           ExprResult ER = buildUserDefinedMapperRef(
5831               S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId,
5832               BaseType, /*UnresolvedMapper=*/nullptr);
5833           if (ER.isInvalid())
5834             continue;
5835           It = Visited.try_emplace(BaseType.getTypePtr(), ER.get()).first;
5836         }
5837         // Found default mapper.
5838         if (It->second) {
5839           auto *OE = new (S.Context) OpaqueValueExpr(E->getExprLoc(), CanonType,
5840                                                      VK_LValue, OK_Ordinary, E);
5841           OE->setIsUnique(/*V=*/true);
5842           Expr *BaseExpr = OE;
5843           for (const auto &P : ParentChain) {
5844             if (P.first) {
5845               BaseExpr = S.BuildMemberExpr(
5846                   BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
5847                   NestedNameSpecifierLoc(), SourceLocation(), P.first,
5848                   DeclAccessPair::make(P.first, P.first->getAccess()),
5849                   /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
5850                   P.first->getType(), VK_LValue, OK_Ordinary);
5851               BaseExpr = S.DefaultLvalueConversion(BaseExpr).get();
5852             }
5853           }
5854           if (CurFD)
5855             BaseExpr = S.BuildMemberExpr(
5856                 BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
5857                 NestedNameSpecifierLoc(), SourceLocation(), CurFD,
5858                 DeclAccessPair::make(CurFD, CurFD->getAccess()),
5859                 /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
5860                 CurFD->getType(), VK_LValue, OK_Ordinary);
5861           SubExprs.push_back(BaseExpr);
5862           continue;
5863         }
5864         // Check for the "default" mapper for data members.
5865         bool FirstIter = true;
5866         for (FieldDecl *FD : RD->fields()) {
5867           if (!FD)
5868             continue;
5869           QualType FieldTy = FD->getType();
5870           if (FieldTy.isNull() ||
5871               !(FieldTy->isStructureOrClassType() || FieldTy->isUnionType()))
5872             continue;
5873           if (FirstIter) {
5874             FirstIter = false;
5875             ParentChain.emplace_back(CurFD, 1);
5876           } else {
5877             ++ParentChain.back().second;
5878           }
5879           Types.emplace_back(FieldTy, FD);
5880         }
5881       }
5882     }
5883     if (SubExprs.empty())
5884       continue;
5885     CXXScopeSpec MapperIdScopeSpec;
5886     DeclarationNameInfo MapperId;
5887     if (OMPClause *NewClause = S.OpenMP().ActOnOpenMPMapClause(
5888             nullptr, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
5889             MapperIdScopeSpec, MapperId, C->getMapType(),
5890             /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
5891             SubExprs, OMPVarListLocTy()))
5892       Clauses.push_back(NewClause);
5893   }
5894 }
5895 
5896 namespace {
5897 /// A 'teams loop' with a nested 'loop bind(parallel)' or generic function
5898 /// call in the associated loop-nest cannot be a 'parallel for'.
5899 class TeamsLoopChecker final : public ConstStmtVisitor<TeamsLoopChecker> {
5900   Sema &SemaRef;
5901 
5902 public:
5903   bool teamsLoopCanBeParallelFor() const { return TeamsLoopCanBeParallelFor; }
5904 
5905   // Is there a nested OpenMP loop bind(parallel)
5906   void VisitOMPExecutableDirective(const OMPExecutableDirective *D) {
5907     if (D->getDirectiveKind() == llvm::omp::Directive::OMPD_loop) {
5908       if (const auto *C = D->getSingleClause<OMPBindClause>())
5909         if (C->getBindKind() == OMPC_BIND_parallel) {
5910           TeamsLoopCanBeParallelFor = false;
5911           // No need to continue visiting any more
5912           return;
5913         }
5914     }
5915     for (const Stmt *Child : D->children())
5916       if (Child)
5917         Visit(Child);
5918   }
5919 
5920   void VisitCallExpr(const CallExpr *C) {
5921     // Function calls inhibit parallel loop translation of 'target teams loop'
5922     // unless the assume-no-nested-parallelism flag has been specified.
5923     // OpenMP API runtime library calls do not inhibit parallel loop
5924     // translation, regardless of the assume-no-nested-parallelism.
5925     bool IsOpenMPAPI = false;
5926     auto *FD = dyn_cast_or_null<FunctionDecl>(C->getCalleeDecl());
5927     if (FD) {
5928       std::string Name = FD->getNameInfo().getAsString();
5929       IsOpenMPAPI = Name.find("omp_") == 0;
5930     }
5931     TeamsLoopCanBeParallelFor =
5932         IsOpenMPAPI || SemaRef.getLangOpts().OpenMPNoNestedParallelism;
5933     if (!TeamsLoopCanBeParallelFor)
5934       return;
5935 
5936     for (const Stmt *Child : C->children())
5937       if (Child)
5938         Visit(Child);
5939   }
5940 
5941   void VisitCapturedStmt(const CapturedStmt *S) {
5942     if (!S)
5943       return;
5944     Visit(S->getCapturedDecl()->getBody());
5945   }
5946 
5947   void VisitStmt(const Stmt *S) {
5948     if (!S)
5949       return;
5950     for (const Stmt *Child : S->children())
5951       if (Child)
5952         Visit(Child);
5953   }
5954   explicit TeamsLoopChecker(Sema &SemaRef)
5955       : SemaRef(SemaRef), TeamsLoopCanBeParallelFor(true) {}
5956 
5957 private:
5958   bool TeamsLoopCanBeParallelFor;
5959 };
5960 } // namespace
5961 
5962 static bool teamsLoopCanBeParallelFor(Stmt *AStmt, Sema &SemaRef) {
5963   TeamsLoopChecker Checker(SemaRef);
5964   Checker.Visit(AStmt);
5965   return Checker.teamsLoopCanBeParallelFor();
5966 }
5967 
5968 StmtResult SemaOpenMP::ActOnOpenMPExecutableDirective(
5969     OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
5970     OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
5971     Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
5972   assert(isOpenMPExecutableDirective(Kind) && "Unexpected directive category");
5973 
5974   StmtResult Res = StmtError();
5975   OpenMPBindClauseKind BindKind = OMPC_BIND_unknown;
5976   llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
5977 
5978   if (const OMPBindClause *BC =
5979           OMPExecutableDirective::getSingleClause<OMPBindClause>(Clauses))
5980     BindKind = BC->getBindKind();
5981 
5982   if (Kind == OMPD_loop && BindKind == OMPC_BIND_unknown) {
5983     const OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective();
5984 
5985     // Setting the enclosing teams or parallel construct for the loop
5986     // directive without bind clause.
5987     // [5.0:129:25-28] If the bind clause is not present on the construct and
5988     // the loop construct is closely nested inside a teams or parallel
5989     // construct, the binding region is the corresponding teams or parallel
5990     // region. If none of those conditions hold, the binding region is not
5991     // defined.
5992     BindKind = OMPC_BIND_thread; // Default bind(thread) if binding is unknown
5993     ArrayRef<OpenMPDirectiveKind> ParentLeafs =
5994         getLeafConstructsOrSelf(ParentDirective);
5995 
5996     if (ParentDirective == OMPD_unknown) {
5997       Diag(DSAStack->getDefaultDSALocation(),
5998            diag::err_omp_bind_required_on_loop);
5999     } else if (ParentLeafs.back() == OMPD_parallel) {
6000       BindKind = OMPC_BIND_parallel;
6001     } else if (ParentLeafs.back() == OMPD_teams) {
6002       BindKind = OMPC_BIND_teams;
6003     }
6004 
6005     assert(BindKind != OMPC_BIND_unknown && "Expecting BindKind");
6006 
6007     OMPClause *C =
6008         ActOnOpenMPBindClause(BindKind, SourceLocation(), SourceLocation(),
6009                               SourceLocation(), SourceLocation());
6010     ClausesWithImplicit.push_back(C);
6011   }
6012 
6013   // Diagnose "loop bind(teams)" with "reduction".
6014   if (Kind == OMPD_loop && BindKind == OMPC_BIND_teams) {
6015     for (OMPClause *C : Clauses) {
6016       if (C->getClauseKind() == OMPC_reduction)
6017         Diag(DSAStack->getDefaultDSALocation(),
6018              diag::err_omp_loop_reduction_clause);
6019     }
6020   }
6021 
6022   // First check CancelRegion which is then used in checkNestingOfRegions.
6023   if (checkCancelRegion(SemaRef, Kind, CancelRegion, StartLoc) ||
6024       checkNestingOfRegions(SemaRef, DSAStack, Kind, DirName, CancelRegion,
6025                             BindKind, StartLoc)) {
6026     return StmtError();
6027   }
6028 
6029   // Report affected OpenMP target offloading behavior when in HIP lang-mode.
6030   if (getLangOpts().HIP && (isOpenMPTargetExecutionDirective(Kind) ||
6031                             isOpenMPTargetDataManagementDirective(Kind)))
6032     Diag(StartLoc, diag::warn_hip_omp_target_directives);
6033 
6034   VarsWithInheritedDSAType VarsWithInheritedDSA;
6035   bool ErrorFound = false;
6036   ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
6037 
6038   if (AStmt && !SemaRef.CurContext->isDependentContext() &&
6039       isOpenMPCapturingDirective(Kind)) {
6040     assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6041 
6042     // Check default data sharing attributes for referenced variables.
6043     DSAAttrChecker DSAChecker(DSAStack, SemaRef, cast<CapturedStmt>(AStmt));
6044     int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
6045     Stmt *S = AStmt;
6046     while (--ThisCaptureLevel >= 0)
6047       S = cast<CapturedStmt>(S)->getCapturedStmt();
6048     DSAChecker.Visit(S);
6049     if (!isOpenMPTargetDataManagementDirective(Kind) &&
6050         !isOpenMPTaskingDirective(Kind)) {
6051       // Visit subcaptures to generate implicit clauses for captured vars.
6052       auto *CS = cast<CapturedStmt>(AStmt);
6053       SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
6054       getOpenMPCaptureRegions(CaptureRegions, Kind);
6055       // Ignore outer tasking regions for target directives.
6056       if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
6057         CS = cast<CapturedStmt>(CS->getCapturedStmt());
6058       DSAChecker.visitSubCaptures(CS);
6059     }
6060     if (DSAChecker.isErrorFound())
6061       return StmtError();
6062     // Generate list of implicitly defined firstprivate variables.
6063     VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
6064     VariableImplicitInfo ImpInfo = DSAChecker.getImplicitInfo();
6065 
6066     SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers>
6067         ImplicitMapModifiersLoc[VariableImplicitInfo::DefaultmapKindNum];
6068     // Get the original location of present modifier from Defaultmap clause.
6069     SourceLocation PresentModifierLocs[VariableImplicitInfo::DefaultmapKindNum];
6070     for (OMPClause *C : Clauses) {
6071       if (auto *DMC = dyn_cast<OMPDefaultmapClause>(C))
6072         if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present)
6073           PresentModifierLocs[DMC->getDefaultmapKind()] =
6074               DMC->getDefaultmapModifierLoc();
6075     }
6076 
6077     for (OpenMPDefaultmapClauseKind K :
6078          llvm::enum_seq_inclusive<OpenMPDefaultmapClauseKind>(
6079              OpenMPDefaultmapClauseKind(), OMPC_DEFAULTMAP_unknown)) {
6080       std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[K]),
6081                   ImpInfo.MapModifiers[K].size(), PresentModifierLocs[K]);
6082     }
6083     // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
6084     for (OMPClause *C : Clauses) {
6085       if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
6086         for (Expr *E : IRC->taskgroup_descriptors())
6087           if (E)
6088             ImpInfo.Firstprivates.insert(E);
6089       }
6090       // OpenMP 5.0, 2.10.1 task Construct
6091       // [detach clause]... The event-handle will be considered as if it was
6092       // specified on a firstprivate clause.
6093       if (auto *DC = dyn_cast<OMPDetachClause>(C))
6094         ImpInfo.Firstprivates.insert(DC->getEventHandler());
6095     }
6096     if (!ImpInfo.Firstprivates.empty()) {
6097       if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
6098               ImpInfo.Firstprivates.getArrayRef(), SourceLocation(),
6099               SourceLocation(), SourceLocation())) {
6100         ClausesWithImplicit.push_back(Implicit);
6101         ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
6102                      ImpInfo.Firstprivates.size();
6103       } else {
6104         ErrorFound = true;
6105       }
6106     }
6107     if (!ImpInfo.Privates.empty()) {
6108       if (OMPClause *Implicit = ActOnOpenMPPrivateClause(
6109               ImpInfo.Privates.getArrayRef(), SourceLocation(),
6110               SourceLocation(), SourceLocation())) {
6111         ClausesWithImplicit.push_back(Implicit);
6112         ErrorFound = cast<OMPPrivateClause>(Implicit)->varlist_size() !=
6113                      ImpInfo.Privates.size();
6114       } else {
6115         ErrorFound = true;
6116       }
6117     }
6118     // OpenMP 5.0 [2.19.7]
6119     // If a list item appears in a reduction, lastprivate or linear
6120     // clause on a combined target construct then it is treated as
6121     // if it also appears in a map clause with a map-type of tofrom
6122     if (getLangOpts().OpenMP >= 50 && Kind != OMPD_target &&
6123         isOpenMPTargetExecutionDirective(Kind)) {
6124       SmallVector<Expr *, 4> ImplicitExprs;
6125       for (OMPClause *C : Clauses) {
6126         if (auto *RC = dyn_cast<OMPReductionClause>(C))
6127           for (Expr *E : RC->varlist())
6128             if (!isa<DeclRefExpr>(E->IgnoreParenImpCasts()))
6129               ImplicitExprs.emplace_back(E);
6130       }
6131       if (!ImplicitExprs.empty()) {
6132         ArrayRef<Expr *> Exprs = ImplicitExprs;
6133         CXXScopeSpec MapperIdScopeSpec;
6134         DeclarationNameInfo MapperId;
6135         if (OMPClause *Implicit = ActOnOpenMPMapClause(
6136                 nullptr, OMPC_MAP_MODIFIER_unknown, SourceLocation(),
6137                 MapperIdScopeSpec, MapperId, OMPC_MAP_tofrom,
6138                 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
6139                 Exprs, OMPVarListLocTy(), /*NoDiagnose=*/true))
6140           ClausesWithImplicit.emplace_back(Implicit);
6141       }
6142     }
6143     for (unsigned I = 0; I < VariableImplicitInfo::DefaultmapKindNum; ++I) {
6144       int ClauseKindCnt = -1;
6145       for (unsigned J = 0; J < VariableImplicitInfo::MapKindNum; ++J) {
6146         ArrayRef<Expr *> ImplicitMap = ImpInfo.Mappings[I][J].getArrayRef();
6147         ++ClauseKindCnt;
6148         if (ImplicitMap.empty())
6149           continue;
6150         CXXScopeSpec MapperIdScopeSpec;
6151         DeclarationNameInfo MapperId;
6152         auto K = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
6153         if (OMPClause *Implicit = ActOnOpenMPMapClause(
6154                 nullptr, ImpInfo.MapModifiers[I], ImplicitMapModifiersLoc[I],
6155                 MapperIdScopeSpec, MapperId, K, /*IsMapTypeImplicit=*/true,
6156                 SourceLocation(), SourceLocation(), ImplicitMap,
6157                 OMPVarListLocTy())) {
6158           ClausesWithImplicit.emplace_back(Implicit);
6159           ErrorFound |= cast<OMPMapClause>(Implicit)->varlist_size() !=
6160                         ImplicitMap.size();
6161         } else {
6162           ErrorFound = true;
6163         }
6164       }
6165     }
6166     // Build expressions for implicit maps of data members with 'default'
6167     // mappers.
6168     if (getLangOpts().OpenMP >= 50)
6169       processImplicitMapsWithDefaultMappers(SemaRef, DSAStack,
6170                                             ClausesWithImplicit);
6171   }
6172 
6173   switch (Kind) {
6174   case OMPD_parallel:
6175     Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
6176                                        EndLoc);
6177     break;
6178   case OMPD_simd:
6179     Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
6180                                    VarsWithInheritedDSA);
6181     break;
6182   case OMPD_tile:
6183     Res =
6184         ActOnOpenMPTileDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6185     break;
6186   case OMPD_unroll:
6187     Res = ActOnOpenMPUnrollDirective(ClausesWithImplicit, AStmt, StartLoc,
6188                                      EndLoc);
6189     break;
6190   case OMPD_reverse:
6191     assert(ClausesWithImplicit.empty() &&
6192            "reverse directive does not support any clauses");
6193     Res = ActOnOpenMPReverseDirective(AStmt, StartLoc, EndLoc);
6194     break;
6195   case OMPD_interchange:
6196     Res = ActOnOpenMPInterchangeDirective(ClausesWithImplicit, AStmt, StartLoc,
6197                                           EndLoc);
6198     break;
6199   case OMPD_for:
6200     Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
6201                                   VarsWithInheritedDSA);
6202     break;
6203   case OMPD_for_simd:
6204     Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6205                                       EndLoc, VarsWithInheritedDSA);
6206     break;
6207   case OMPD_sections:
6208     Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
6209                                        EndLoc);
6210     break;
6211   case OMPD_section:
6212     assert(ClausesWithImplicit.empty() &&
6213            "No clauses are allowed for 'omp section' directive");
6214     Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
6215     break;
6216   case OMPD_single:
6217     Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
6218                                      EndLoc);
6219     break;
6220   case OMPD_master:
6221     assert(ClausesWithImplicit.empty() &&
6222            "No clauses are allowed for 'omp master' directive");
6223     Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
6224     break;
6225   case OMPD_masked:
6226     Res = ActOnOpenMPMaskedDirective(ClausesWithImplicit, AStmt, StartLoc,
6227                                      EndLoc);
6228     break;
6229   case OMPD_critical:
6230     Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
6231                                        StartLoc, EndLoc);
6232     break;
6233   case OMPD_parallel_for:
6234     Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
6235                                           EndLoc, VarsWithInheritedDSA);
6236     break;
6237   case OMPD_parallel_for_simd:
6238     Res = ActOnOpenMPParallelForSimdDirective(
6239         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6240     break;
6241   case OMPD_scope:
6242     Res =
6243         ActOnOpenMPScopeDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6244     break;
6245   case OMPD_parallel_master:
6246     Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
6247                                              StartLoc, EndLoc);
6248     break;
6249   case OMPD_parallel_masked:
6250     Res = ActOnOpenMPParallelMaskedDirective(ClausesWithImplicit, AStmt,
6251                                              StartLoc, EndLoc);
6252     break;
6253   case OMPD_parallel_sections:
6254     Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
6255                                                StartLoc, EndLoc);
6256     break;
6257   case OMPD_task:
6258     Res =
6259         ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6260     break;
6261   case OMPD_taskyield:
6262     assert(ClausesWithImplicit.empty() &&
6263            "No clauses are allowed for 'omp taskyield' directive");
6264     assert(AStmt == nullptr &&
6265            "No associated statement allowed for 'omp taskyield' directive");
6266     Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
6267     break;
6268   case OMPD_error:
6269     assert(AStmt == nullptr &&
6270            "No associated statement allowed for 'omp error' directive");
6271     Res = ActOnOpenMPErrorDirective(ClausesWithImplicit, StartLoc, EndLoc);
6272     break;
6273   case OMPD_barrier:
6274     assert(ClausesWithImplicit.empty() &&
6275            "No clauses are allowed for 'omp barrier' directive");
6276     assert(AStmt == nullptr &&
6277            "No associated statement allowed for 'omp barrier' directive");
6278     Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
6279     break;
6280   case OMPD_taskwait:
6281     assert(AStmt == nullptr &&
6282            "No associated statement allowed for 'omp taskwait' directive");
6283     Res = ActOnOpenMPTaskwaitDirective(ClausesWithImplicit, StartLoc, EndLoc);
6284     break;
6285   case OMPD_taskgroup:
6286     Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
6287                                         EndLoc);
6288     break;
6289   case OMPD_flush:
6290     assert(AStmt == nullptr &&
6291            "No associated statement allowed for 'omp flush' directive");
6292     Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
6293     break;
6294   case OMPD_depobj:
6295     assert(AStmt == nullptr &&
6296            "No associated statement allowed for 'omp depobj' directive");
6297     Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc);
6298     break;
6299   case OMPD_scan:
6300     assert(AStmt == nullptr &&
6301            "No associated statement allowed for 'omp scan' directive");
6302     Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc);
6303     break;
6304   case OMPD_ordered:
6305     Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
6306                                       EndLoc);
6307     break;
6308   case OMPD_atomic:
6309     Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
6310                                      EndLoc);
6311     break;
6312   case OMPD_teams:
6313     Res =
6314         ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6315     break;
6316   case OMPD_target:
6317     Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
6318                                      EndLoc);
6319     break;
6320   case OMPD_target_parallel:
6321     Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
6322                                              StartLoc, EndLoc);
6323     break;
6324   case OMPD_target_parallel_for:
6325     Res = ActOnOpenMPTargetParallelForDirective(
6326         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6327     break;
6328   case OMPD_cancellation_point:
6329     assert(ClausesWithImplicit.empty() &&
6330            "No clauses are allowed for 'omp cancellation point' directive");
6331     assert(AStmt == nullptr && "No associated statement allowed for 'omp "
6332                                "cancellation point' directive");
6333     Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
6334     break;
6335   case OMPD_cancel:
6336     assert(AStmt == nullptr &&
6337            "No associated statement allowed for 'omp cancel' directive");
6338     Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
6339                                      CancelRegion);
6340     break;
6341   case OMPD_target_data:
6342     Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
6343                                          EndLoc);
6344     break;
6345   case OMPD_target_enter_data:
6346     Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
6347                                               EndLoc, AStmt);
6348     break;
6349   case OMPD_target_exit_data:
6350     Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
6351                                              EndLoc, AStmt);
6352     break;
6353   case OMPD_taskloop:
6354     Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
6355                                        EndLoc, VarsWithInheritedDSA);
6356     break;
6357   case OMPD_taskloop_simd:
6358     Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6359                                            EndLoc, VarsWithInheritedDSA);
6360     break;
6361   case OMPD_master_taskloop:
6362     Res = ActOnOpenMPMasterTaskLoopDirective(
6363         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6364     break;
6365   case OMPD_masked_taskloop:
6366     Res = ActOnOpenMPMaskedTaskLoopDirective(
6367         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6368     break;
6369   case OMPD_master_taskloop_simd:
6370     Res = ActOnOpenMPMasterTaskLoopSimdDirective(
6371         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6372     break;
6373   case OMPD_masked_taskloop_simd:
6374     Res = ActOnOpenMPMaskedTaskLoopSimdDirective(
6375         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6376     break;
6377   case OMPD_parallel_master_taskloop:
6378     Res = ActOnOpenMPParallelMasterTaskLoopDirective(
6379         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6380     break;
6381   case OMPD_parallel_masked_taskloop:
6382     Res = ActOnOpenMPParallelMaskedTaskLoopDirective(
6383         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6384     break;
6385   case OMPD_parallel_master_taskloop_simd:
6386     Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective(
6387         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6388     break;
6389   case OMPD_parallel_masked_taskloop_simd:
6390     Res = ActOnOpenMPParallelMaskedTaskLoopSimdDirective(
6391         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6392     break;
6393   case OMPD_distribute:
6394     Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
6395                                          EndLoc, VarsWithInheritedDSA);
6396     break;
6397   case OMPD_target_update:
6398     Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
6399                                            EndLoc, AStmt);
6400     break;
6401   case OMPD_distribute_parallel_for:
6402     Res = ActOnOpenMPDistributeParallelForDirective(
6403         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6404     break;
6405   case OMPD_distribute_parallel_for_simd:
6406     Res = ActOnOpenMPDistributeParallelForSimdDirective(
6407         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6408     break;
6409   case OMPD_distribute_simd:
6410     Res = ActOnOpenMPDistributeSimdDirective(
6411         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6412     break;
6413   case OMPD_target_parallel_for_simd:
6414     Res = ActOnOpenMPTargetParallelForSimdDirective(
6415         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6416     break;
6417   case OMPD_target_simd:
6418     Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6419                                          EndLoc, VarsWithInheritedDSA);
6420     break;
6421   case OMPD_teams_distribute:
6422     Res = ActOnOpenMPTeamsDistributeDirective(
6423         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6424     break;
6425   case OMPD_teams_distribute_simd:
6426     Res = ActOnOpenMPTeamsDistributeSimdDirective(
6427         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6428     break;
6429   case OMPD_teams_distribute_parallel_for_simd:
6430     Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
6431         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6432     break;
6433   case OMPD_teams_distribute_parallel_for:
6434     Res = ActOnOpenMPTeamsDistributeParallelForDirective(
6435         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6436     break;
6437   case OMPD_target_teams:
6438     Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
6439                                           EndLoc);
6440     break;
6441   case OMPD_target_teams_distribute:
6442     Res = ActOnOpenMPTargetTeamsDistributeDirective(
6443         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6444     break;
6445   case OMPD_target_teams_distribute_parallel_for:
6446     Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
6447         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6448     break;
6449   case OMPD_target_teams_distribute_parallel_for_simd:
6450     Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
6451         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6452     break;
6453   case OMPD_target_teams_distribute_simd:
6454     Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
6455         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6456     break;
6457   case OMPD_interop:
6458     assert(AStmt == nullptr &&
6459            "No associated statement allowed for 'omp interop' directive");
6460     Res = ActOnOpenMPInteropDirective(ClausesWithImplicit, StartLoc, EndLoc);
6461     break;
6462   case OMPD_dispatch:
6463     Res = ActOnOpenMPDispatchDirective(ClausesWithImplicit, AStmt, StartLoc,
6464                                        EndLoc);
6465     break;
6466   case OMPD_loop:
6467     Res = ActOnOpenMPGenericLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
6468                                           EndLoc, VarsWithInheritedDSA);
6469     break;
6470   case OMPD_teams_loop:
6471     Res = ActOnOpenMPTeamsGenericLoopDirective(
6472         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6473     break;
6474   case OMPD_target_teams_loop:
6475     Res = ActOnOpenMPTargetTeamsGenericLoopDirective(
6476         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6477     break;
6478   case OMPD_parallel_loop:
6479     Res = ActOnOpenMPParallelGenericLoopDirective(
6480         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6481     break;
6482   case OMPD_target_parallel_loop:
6483     Res = ActOnOpenMPTargetParallelGenericLoopDirective(
6484         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6485     break;
6486   case OMPD_declare_target:
6487   case OMPD_end_declare_target:
6488   case OMPD_threadprivate:
6489   case OMPD_allocate:
6490   case OMPD_declare_reduction:
6491   case OMPD_declare_mapper:
6492   case OMPD_declare_simd:
6493   case OMPD_requires:
6494   case OMPD_declare_variant:
6495   case OMPD_begin_declare_variant:
6496   case OMPD_end_declare_variant:
6497     llvm_unreachable("OpenMP Directive is not allowed");
6498   case OMPD_unknown:
6499   default:
6500     llvm_unreachable("Unknown OpenMP directive");
6501   }
6502 
6503   ErrorFound = Res.isInvalid() || ErrorFound;
6504 
6505   // Check variables in the clauses if default(none) or
6506   // default(firstprivate) was specified.
6507   if (DSAStack->getDefaultDSA() == DSA_none ||
6508       DSAStack->getDefaultDSA() == DSA_private ||
6509       DSAStack->getDefaultDSA() == DSA_firstprivate) {
6510     DSAAttrChecker DSAChecker(DSAStack, SemaRef, nullptr);
6511     for (OMPClause *C : Clauses) {
6512       switch (C->getClauseKind()) {
6513       case OMPC_num_threads:
6514       case OMPC_dist_schedule:
6515         // Do not analyze if no parent teams directive.
6516         if (isOpenMPTeamsDirective(Kind))
6517           break;
6518         continue;
6519       case OMPC_if:
6520         if (isOpenMPTeamsDirective(Kind) &&
6521             cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
6522           break;
6523         if (isOpenMPParallelDirective(Kind) &&
6524             isOpenMPTaskLoopDirective(Kind) &&
6525             cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel)
6526           break;
6527         continue;
6528       case OMPC_schedule:
6529       case OMPC_detach:
6530         break;
6531       case OMPC_grainsize:
6532       case OMPC_num_tasks:
6533       case OMPC_final:
6534       case OMPC_priority:
6535       case OMPC_novariants:
6536       case OMPC_nocontext:
6537         // Do not analyze if no parent parallel directive.
6538         if (isOpenMPParallelDirective(Kind))
6539           break;
6540         continue;
6541       case OMPC_ordered:
6542       case OMPC_device:
6543       case OMPC_num_teams:
6544       case OMPC_thread_limit:
6545       case OMPC_hint:
6546       case OMPC_collapse:
6547       case OMPC_safelen:
6548       case OMPC_simdlen:
6549       case OMPC_sizes:
6550       case OMPC_default:
6551       case OMPC_proc_bind:
6552       case OMPC_private:
6553       case OMPC_firstprivate:
6554       case OMPC_lastprivate:
6555       case OMPC_shared:
6556       case OMPC_reduction:
6557       case OMPC_task_reduction:
6558       case OMPC_in_reduction:
6559       case OMPC_linear:
6560       case OMPC_aligned:
6561       case OMPC_copyin:
6562       case OMPC_copyprivate:
6563       case OMPC_nowait:
6564       case OMPC_untied:
6565       case OMPC_mergeable:
6566       case OMPC_allocate:
6567       case OMPC_read:
6568       case OMPC_write:
6569       case OMPC_update:
6570       case OMPC_capture:
6571       case OMPC_compare:
6572       case OMPC_seq_cst:
6573       case OMPC_acq_rel:
6574       case OMPC_acquire:
6575       case OMPC_release:
6576       case OMPC_relaxed:
6577       case OMPC_depend:
6578       case OMPC_threads:
6579       case OMPC_simd:
6580       case OMPC_map:
6581       case OMPC_nogroup:
6582       case OMPC_defaultmap:
6583       case OMPC_to:
6584       case OMPC_from:
6585       case OMPC_use_device_ptr:
6586       case OMPC_use_device_addr:
6587       case OMPC_is_device_ptr:
6588       case OMPC_has_device_addr:
6589       case OMPC_nontemporal:
6590       case OMPC_order:
6591       case OMPC_destroy:
6592       case OMPC_inclusive:
6593       case OMPC_exclusive:
6594       case OMPC_uses_allocators:
6595       case OMPC_affinity:
6596       case OMPC_bind:
6597       case OMPC_filter:
6598         continue;
6599       case OMPC_allocator:
6600       case OMPC_flush:
6601       case OMPC_depobj:
6602       case OMPC_threadprivate:
6603       case OMPC_uniform:
6604       case OMPC_unknown:
6605       case OMPC_unified_address:
6606       case OMPC_unified_shared_memory:
6607       case OMPC_reverse_offload:
6608       case OMPC_dynamic_allocators:
6609       case OMPC_atomic_default_mem_order:
6610       case OMPC_device_type:
6611       case OMPC_match:
6612       case OMPC_when:
6613       case OMPC_at:
6614       case OMPC_severity:
6615       case OMPC_message:
6616       default:
6617         llvm_unreachable("Unexpected clause");
6618       }
6619       for (Stmt *CC : C->children()) {
6620         if (CC)
6621           DSAChecker.Visit(CC);
6622       }
6623     }
6624     for (const auto &P : DSAChecker.getVarsWithInheritedDSA())
6625       VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
6626   }
6627   for (const auto &P : VarsWithInheritedDSA) {
6628     if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
6629       continue;
6630     ErrorFound = true;
6631     if (DSAStack->getDefaultDSA() == DSA_none ||
6632         DSAStack->getDefaultDSA() == DSA_private ||
6633         DSAStack->getDefaultDSA() == DSA_firstprivate) {
6634       Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
6635           << P.first << P.second->getSourceRange();
6636       Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
6637     } else if (getLangOpts().OpenMP >= 50) {
6638       Diag(P.second->getExprLoc(),
6639            diag::err_omp_defaultmap_no_attr_for_variable)
6640           << P.first << P.second->getSourceRange();
6641       Diag(DSAStack->getDefaultDSALocation(),
6642            diag::note_omp_defaultmap_attr_none);
6643     }
6644   }
6645 
6646   llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
6647   for (OpenMPDirectiveKind D : getLeafConstructsOrSelf(Kind)) {
6648     if (isAllowedClauseForDirective(D, OMPC_if, getLangOpts().OpenMP))
6649       AllowedNameModifiers.push_back(D);
6650   }
6651   if (!AllowedNameModifiers.empty())
6652     ErrorFound = checkIfClauses(SemaRef, Kind, Clauses, AllowedNameModifiers) ||
6653                  ErrorFound;
6654 
6655   if (ErrorFound)
6656     return StmtError();
6657 
6658   if (!SemaRef.CurContext->isDependentContext() &&
6659       isOpenMPTargetExecutionDirective(Kind) &&
6660       !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
6661         DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
6662         DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
6663         DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
6664     // Register target to DSA Stack.
6665     DSAStack->addTargetDirLocation(StartLoc);
6666   }
6667 
6668   return Res;
6669 }
6670 
6671 SemaOpenMP::DeclGroupPtrTy SemaOpenMP::ActOnOpenMPDeclareSimdDirective(
6672     DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
6673     ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
6674     ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
6675     ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
6676   assert(Aligneds.size() == Alignments.size());
6677   assert(Linears.size() == LinModifiers.size());
6678   assert(Linears.size() == Steps.size());
6679   if (!DG || DG.get().isNull())
6680     return DeclGroupPtrTy();
6681 
6682   const int SimdId = 0;
6683   if (!DG.get().isSingleDecl()) {
6684     Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
6685         << SimdId;
6686     return DG;
6687   }
6688   Decl *ADecl = DG.get().getSingleDecl();
6689   if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
6690     ADecl = FTD->getTemplatedDecl();
6691 
6692   auto *FD = dyn_cast<FunctionDecl>(ADecl);
6693   if (!FD) {
6694     Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId;
6695     return DeclGroupPtrTy();
6696   }
6697 
6698   // OpenMP [2.8.2, declare simd construct, Description]
6699   // The parameter of the simdlen clause must be a constant positive integer
6700   // expression.
6701   ExprResult SL;
6702   if (Simdlen)
6703     SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
6704   // OpenMP [2.8.2, declare simd construct, Description]
6705   // The special this pointer can be used as if was one of the arguments to the
6706   // function in any of the linear, aligned, or uniform clauses.
6707   // The uniform clause declares one or more arguments to have an invariant
6708   // value for all concurrent invocations of the function in the execution of a
6709   // single SIMD loop.
6710   llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
6711   const Expr *UniformedLinearThis = nullptr;
6712   for (const Expr *E : Uniforms) {
6713     E = E->IgnoreParenImpCasts();
6714     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6715       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
6716         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6717             FD->getParamDecl(PVD->getFunctionScopeIndex())
6718                     ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
6719           UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
6720           continue;
6721         }
6722     if (isa<CXXThisExpr>(E)) {
6723       UniformedLinearThis = E;
6724       continue;
6725     }
6726     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6727         << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6728   }
6729   // OpenMP [2.8.2, declare simd construct, Description]
6730   // The aligned clause declares that the object to which each list item points
6731   // is aligned to the number of bytes expressed in the optional parameter of
6732   // the aligned clause.
6733   // The special this pointer can be used as if was one of the arguments to the
6734   // function in any of the linear, aligned, or uniform clauses.
6735   // The type of list items appearing in the aligned clause must be array,
6736   // pointer, reference to array, or reference to pointer.
6737   llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
6738   const Expr *AlignedThis = nullptr;
6739   for (const Expr *E : Aligneds) {
6740     E = E->IgnoreParenImpCasts();
6741     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6742       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6743         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6744         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6745             FD->getParamDecl(PVD->getFunctionScopeIndex())
6746                     ->getCanonicalDecl() == CanonPVD) {
6747           // OpenMP  [2.8.1, simd construct, Restrictions]
6748           // A list-item cannot appear in more than one aligned clause.
6749           if (AlignedArgs.count(CanonPVD) > 0) {
6750             Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
6751                 << 1 << getOpenMPClauseName(OMPC_aligned)
6752                 << E->getSourceRange();
6753             Diag(AlignedArgs[CanonPVD]->getExprLoc(),
6754                  diag::note_omp_explicit_dsa)
6755                 << getOpenMPClauseName(OMPC_aligned);
6756             continue;
6757           }
6758           AlignedArgs[CanonPVD] = E;
6759           QualType QTy = PVD->getType()
6760                              .getNonReferenceType()
6761                              .getUnqualifiedType()
6762                              .getCanonicalType();
6763           const Type *Ty = QTy.getTypePtrOrNull();
6764           if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
6765             Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
6766                 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
6767             Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
6768           }
6769           continue;
6770         }
6771       }
6772     if (isa<CXXThisExpr>(E)) {
6773       if (AlignedThis) {
6774         Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
6775             << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange();
6776         Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
6777             << getOpenMPClauseName(OMPC_aligned);
6778       }
6779       AlignedThis = E;
6780       continue;
6781     }
6782     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6783         << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6784   }
6785   // The optional parameter of the aligned clause, alignment, must be a constant
6786   // positive integer expression. If no optional parameter is specified,
6787   // implementation-defined default alignments for SIMD instructions on the
6788   // target platforms are assumed.
6789   SmallVector<const Expr *, 4> NewAligns;
6790   for (Expr *E : Alignments) {
6791     ExprResult Align;
6792     if (E)
6793       Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
6794     NewAligns.push_back(Align.get());
6795   }
6796   // OpenMP [2.8.2, declare simd construct, Description]
6797   // The linear clause declares one or more list items to be private to a SIMD
6798   // lane and to have a linear relationship with respect to the iteration space
6799   // of a loop.
6800   // The special this pointer can be used as if was one of the arguments to the
6801   // function in any of the linear, aligned, or uniform clauses.
6802   // When a linear-step expression is specified in a linear clause it must be
6803   // either a constant integer expression or an integer-typed parameter that is
6804   // specified in a uniform clause on the directive.
6805   llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
6806   const bool IsUniformedThis = UniformedLinearThis != nullptr;
6807   auto MI = LinModifiers.begin();
6808   for (const Expr *E : Linears) {
6809     auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
6810     ++MI;
6811     E = E->IgnoreParenImpCasts();
6812     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6813       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6814         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6815         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6816             FD->getParamDecl(PVD->getFunctionScopeIndex())
6817                     ->getCanonicalDecl() == CanonPVD) {
6818           // OpenMP  [2.15.3.7, linear Clause, Restrictions]
6819           // A list-item cannot appear in more than one linear clause.
6820           if (LinearArgs.count(CanonPVD) > 0) {
6821             Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6822                 << getOpenMPClauseName(OMPC_linear)
6823                 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
6824             Diag(LinearArgs[CanonPVD]->getExprLoc(),
6825                  diag::note_omp_explicit_dsa)
6826                 << getOpenMPClauseName(OMPC_linear);
6827             continue;
6828           }
6829           // Each argument can appear in at most one uniform or linear clause.
6830           if (UniformedArgs.count(CanonPVD) > 0) {
6831             Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6832                 << getOpenMPClauseName(OMPC_linear)
6833                 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
6834             Diag(UniformedArgs[CanonPVD]->getExprLoc(),
6835                  diag::note_omp_explicit_dsa)
6836                 << getOpenMPClauseName(OMPC_uniform);
6837             continue;
6838           }
6839           LinearArgs[CanonPVD] = E;
6840           if (E->isValueDependent() || E->isTypeDependent() ||
6841               E->isInstantiationDependent() ||
6842               E->containsUnexpandedParameterPack())
6843             continue;
6844           (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
6845                                       PVD->getOriginalType(),
6846                                       /*IsDeclareSimd=*/true);
6847           continue;
6848         }
6849       }
6850     if (isa<CXXThisExpr>(E)) {
6851       if (UniformedLinearThis) {
6852         Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6853             << getOpenMPClauseName(OMPC_linear)
6854             << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
6855             << E->getSourceRange();
6856         Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
6857             << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
6858                                                    : OMPC_linear);
6859         continue;
6860       }
6861       UniformedLinearThis = E;
6862       if (E->isValueDependent() || E->isTypeDependent() ||
6863           E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
6864         continue;
6865       (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
6866                                   E->getType(), /*IsDeclareSimd=*/true);
6867       continue;
6868     }
6869     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6870         << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6871   }
6872   Expr *Step = nullptr;
6873   Expr *NewStep = nullptr;
6874   SmallVector<Expr *, 4> NewSteps;
6875   for (Expr *E : Steps) {
6876     // Skip the same step expression, it was checked already.
6877     if (Step == E || !E) {
6878       NewSteps.push_back(E ? NewStep : nullptr);
6879       continue;
6880     }
6881     Step = E;
6882     if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
6883       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6884         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6885         if (UniformedArgs.count(CanonPVD) == 0) {
6886           Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
6887               << Step->getSourceRange();
6888         } else if (E->isValueDependent() || E->isTypeDependent() ||
6889                    E->isInstantiationDependent() ||
6890                    E->containsUnexpandedParameterPack() ||
6891                    CanonPVD->getType()->hasIntegerRepresentation()) {
6892           NewSteps.push_back(Step);
6893         } else {
6894           Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
6895               << Step->getSourceRange();
6896         }
6897         continue;
6898       }
6899     NewStep = Step;
6900     if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
6901         !Step->isInstantiationDependent() &&
6902         !Step->containsUnexpandedParameterPack()) {
6903       NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
6904                     .get();
6905       if (NewStep)
6906         NewStep = SemaRef
6907                       .VerifyIntegerConstantExpression(
6908                           NewStep, /*FIXME*/ Sema::AllowFold)
6909                       .get();
6910     }
6911     NewSteps.push_back(NewStep);
6912   }
6913   auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
6914       getASTContext(), BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
6915       Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
6916       const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
6917       const_cast<Expr **>(Linears.data()), Linears.size(),
6918       const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
6919       NewSteps.data(), NewSteps.size(), SR);
6920   ADecl->addAttr(NewAttr);
6921   return DG;
6922 }
6923 
6924 StmtResult SemaOpenMP::ActOnOpenMPInformationalDirective(
6925     OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
6926     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
6927     SourceLocation EndLoc) {
6928   assert(isOpenMPInformationalDirective(Kind) &&
6929          "Unexpected directive category");
6930 
6931   StmtResult Res = StmtError();
6932 
6933   switch (Kind) {
6934   case OMPD_assume:
6935     Res = ActOnOpenMPAssumeDirective(Clauses, AStmt, StartLoc, EndLoc);
6936     break;
6937   default:
6938     llvm_unreachable("Unknown OpenMP directive");
6939   }
6940 
6941   return Res;
6942 }
6943 
6944 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
6945                          QualType NewType) {
6946   assert(NewType->isFunctionProtoType() &&
6947          "Expected function type with prototype.");
6948   assert(FD->getType()->isFunctionNoProtoType() &&
6949          "Expected function with type with no prototype.");
6950   assert(FDWithProto->getType()->isFunctionProtoType() &&
6951          "Expected function with prototype.");
6952   // Synthesize parameters with the same types.
6953   FD->setType(NewType);
6954   SmallVector<ParmVarDecl *, 16> Params;
6955   for (const ParmVarDecl *P : FDWithProto->parameters()) {
6956     auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(),
6957                                       SourceLocation(), nullptr, P->getType(),
6958                                       /*TInfo=*/nullptr, SC_None, nullptr);
6959     Param->setScopeInfo(0, Params.size());
6960     Param->setImplicit();
6961     Params.push_back(Param);
6962   }
6963 
6964   FD->setParams(Params);
6965 }
6966 
6967 void SemaOpenMP::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D) {
6968   if (D->isInvalidDecl())
6969     return;
6970   FunctionDecl *FD = nullptr;
6971   if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
6972     FD = UTemplDecl->getTemplatedDecl();
6973   else
6974     FD = cast<FunctionDecl>(D);
6975   assert(FD && "Expected a function declaration!");
6976 
6977   // If we are instantiating templates we do *not* apply scoped assumptions but
6978   // only global ones. We apply scoped assumption to the template definition
6979   // though.
6980   if (!SemaRef.inTemplateInstantiation()) {
6981     for (OMPAssumeAttr *AA : OMPAssumeScoped)
6982       FD->addAttr(AA);
6983   }
6984   for (OMPAssumeAttr *AA : OMPAssumeGlobal)
6985     FD->addAttr(AA);
6986 }
6987 
6988 SemaOpenMP::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI)
6989     : TI(&TI), NameSuffix(TI.getMangledName()) {}
6990 
6991 void SemaOpenMP::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(
6992     Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists,
6993     SmallVectorImpl<FunctionDecl *> &Bases) {
6994   if (!D.getIdentifier())
6995     return;
6996 
6997   OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
6998 
6999   // Template specialization is an extension, check if we do it.
7000   bool IsTemplated = !TemplateParamLists.empty();
7001   if (IsTemplated &&
7002       !DVScope.TI->isExtensionActive(
7003           llvm::omp::TraitProperty::implementation_extension_allow_templates))
7004     return;
7005 
7006   const IdentifierInfo *BaseII = D.getIdentifier();
7007   LookupResult Lookup(SemaRef, DeclarationName(BaseII), D.getIdentifierLoc(),
7008                       Sema::LookupOrdinaryName);
7009   SemaRef.LookupParsedName(Lookup, S, &D.getCXXScopeSpec(),
7010                            /*ObjectType=*/QualType());
7011 
7012   TypeSourceInfo *TInfo = SemaRef.GetTypeForDeclarator(D);
7013   QualType FType = TInfo->getType();
7014 
7015   bool IsConstexpr =
7016       D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr;
7017   bool IsConsteval =
7018       D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Consteval;
7019 
7020   for (auto *Candidate : Lookup) {
7021     auto *CandidateDecl = Candidate->getUnderlyingDecl();
7022     FunctionDecl *UDecl = nullptr;
7023     if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl)) {
7024       auto *FTD = cast<FunctionTemplateDecl>(CandidateDecl);
7025       if (FTD->getTemplateParameters()->size() == TemplateParamLists.size())
7026         UDecl = FTD->getTemplatedDecl();
7027     } else if (!IsTemplated)
7028       UDecl = dyn_cast<FunctionDecl>(CandidateDecl);
7029     if (!UDecl)
7030       continue;
7031 
7032     // Don't specialize constexpr/consteval functions with
7033     // non-constexpr/consteval functions.
7034     if (UDecl->isConstexpr() && !IsConstexpr)
7035       continue;
7036     if (UDecl->isConsteval() && !IsConsteval)
7037       continue;
7038 
7039     QualType UDeclTy = UDecl->getType();
7040     if (!UDeclTy->isDependentType()) {
7041       QualType NewType = getASTContext().mergeFunctionTypes(
7042           FType, UDeclTy, /*OfBlockPointer=*/false,
7043           /*Unqualified=*/false, /*AllowCXX=*/true);
7044       if (NewType.isNull())
7045         continue;
7046     }
7047 
7048     // Found a base!
7049     Bases.push_back(UDecl);
7050   }
7051 
7052   bool UseImplicitBase = !DVScope.TI->isExtensionActive(
7053       llvm::omp::TraitProperty::implementation_extension_disable_implicit_base);
7054   // If no base was found we create a declaration that we use as base.
7055   if (Bases.empty() && UseImplicitBase) {
7056     D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration);
7057     Decl *BaseD = SemaRef.HandleDeclarator(S, D, TemplateParamLists);
7058     BaseD->setImplicit(true);
7059     if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD))
7060       Bases.push_back(BaseTemplD->getTemplatedDecl());
7061     else
7062       Bases.push_back(cast<FunctionDecl>(BaseD));
7063   }
7064 
7065   std::string MangledName;
7066   MangledName += D.getIdentifier()->getName();
7067   MangledName += getOpenMPVariantManglingSeparatorStr();
7068   MangledName += DVScope.NameSuffix;
7069   IdentifierInfo &VariantII = getASTContext().Idents.get(MangledName);
7070 
7071   VariantII.setMangledOpenMPVariantName(true);
7072   D.SetIdentifier(&VariantII, D.getBeginLoc());
7073 }
7074 
7075 void SemaOpenMP::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(
7076     Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) {
7077   // Do not mark function as is used to prevent its emission if this is the
7078   // only place where it is used.
7079   EnterExpressionEvaluationContext Unevaluated(
7080       SemaRef, Sema::ExpressionEvaluationContext::Unevaluated);
7081 
7082   FunctionDecl *FD = nullptr;
7083   if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
7084     FD = UTemplDecl->getTemplatedDecl();
7085   else
7086     FD = cast<FunctionDecl>(D);
7087   auto *VariantFuncRef = DeclRefExpr::Create(
7088       getASTContext(), NestedNameSpecifierLoc(), SourceLocation(), FD,
7089       /*RefersToEnclosingVariableOrCapture=*/false,
7090       /*NameLoc=*/FD->getLocation(), FD->getType(), ExprValueKind::VK_PRValue);
7091 
7092   OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
7093   auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit(
7094       getASTContext(), VariantFuncRef, DVScope.TI,
7095       /*NothingArgs=*/nullptr, /*NothingArgsSize=*/0,
7096       /*NeedDevicePtrArgs=*/nullptr, /*NeedDevicePtrArgsSize=*/0,
7097       /*AppendArgs=*/nullptr, /*AppendArgsSize=*/0);
7098   for (FunctionDecl *BaseFD : Bases)
7099     BaseFD->addAttr(OMPDeclareVariantA);
7100 }
7101 
7102 ExprResult SemaOpenMP::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
7103                                        SourceLocation LParenLoc,
7104                                        MultiExprArg ArgExprs,
7105                                        SourceLocation RParenLoc,
7106                                        Expr *ExecConfig) {
7107   // The common case is a regular call we do not want to specialize at all. Try
7108   // to make that case fast by bailing early.
7109   CallExpr *CE = dyn_cast<CallExpr>(Call.get());
7110   if (!CE)
7111     return Call;
7112 
7113   FunctionDecl *CalleeFnDecl = CE->getDirectCallee();
7114   if (!CalleeFnDecl)
7115     return Call;
7116 
7117   if (getLangOpts().OpenMP >= 51 && CalleeFnDecl->getIdentifier() &&
7118       CalleeFnDecl->getName().starts_with_insensitive("omp_")) {
7119     // checking for any calls inside an Order region
7120     if (Scope && Scope->isOpenMPOrderClauseScope())
7121       Diag(LParenLoc, diag::err_omp_unexpected_call_to_omp_runtime_api);
7122   }
7123 
7124   if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>())
7125     return Call;
7126 
7127   ASTContext &Context = getASTContext();
7128   std::function<void(StringRef)> DiagUnknownTrait = [this,
7129                                                      CE](StringRef ISATrait) {
7130     // TODO Track the selector locations in a way that is accessible here to
7131     // improve the diagnostic location.
7132     Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait)
7133         << ISATrait;
7134   };
7135   TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait),
7136                           SemaRef.getCurFunctionDecl(),
7137                           DSAStack->getConstructTraits());
7138 
7139   QualType CalleeFnType = CalleeFnDecl->getType();
7140 
7141   SmallVector<Expr *, 4> Exprs;
7142   SmallVector<VariantMatchInfo, 4> VMIs;
7143   while (CalleeFnDecl) {
7144     for (OMPDeclareVariantAttr *A :
7145          CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) {
7146       Expr *VariantRef = A->getVariantFuncRef();
7147 
7148       VariantMatchInfo VMI;
7149       OMPTraitInfo &TI = A->getTraitInfo();
7150       TI.getAsVariantMatchInfo(Context, VMI);
7151       if (!isVariantApplicableInContext(VMI, OMPCtx,
7152                                         /*DeviceSetOnly=*/false))
7153         continue;
7154 
7155       VMIs.push_back(VMI);
7156       Exprs.push_back(VariantRef);
7157     }
7158 
7159     CalleeFnDecl = CalleeFnDecl->getPreviousDecl();
7160   }
7161 
7162   ExprResult NewCall;
7163   do {
7164     int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
7165     if (BestIdx < 0)
7166       return Call;
7167     Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]);
7168     Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl();
7169 
7170     {
7171       // Try to build a (member) call expression for the current best applicable
7172       // variant expression. We allow this to fail in which case we continue
7173       // with the next best variant expression. The fail case is part of the
7174       // implementation defined behavior in the OpenMP standard when it talks
7175       // about what differences in the function prototypes: "Any differences
7176       // that the specific OpenMP context requires in the prototype of the
7177       // variant from the base function prototype are implementation defined."
7178       // This wording is there to allow the specialized variant to have a
7179       // different type than the base function. This is intended and OK but if
7180       // we cannot create a call the difference is not in the "implementation
7181       // defined range" we allow.
7182       Sema::TentativeAnalysisScope Trap(SemaRef);
7183 
7184       if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) {
7185         auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE);
7186         BestExpr = MemberExpr::CreateImplicit(
7187             Context, MemberCall->getImplicitObjectArgument(),
7188             /*IsArrow=*/false, SpecializedMethod, Context.BoundMemberTy,
7189             MemberCall->getValueKind(), MemberCall->getObjectKind());
7190       }
7191       NewCall = SemaRef.BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs,
7192                                       RParenLoc, ExecConfig);
7193       if (NewCall.isUsable()) {
7194         if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) {
7195           FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee();
7196           QualType NewType = getASTContext().mergeFunctionTypes(
7197               CalleeFnType, NewCalleeFnDecl->getType(),
7198               /*OfBlockPointer=*/false,
7199               /*Unqualified=*/false, /*AllowCXX=*/true);
7200           if (!NewType.isNull())
7201             break;
7202           // Don't use the call if the function type was not compatible.
7203           NewCall = nullptr;
7204         }
7205       }
7206     }
7207 
7208     VMIs.erase(VMIs.begin() + BestIdx);
7209     Exprs.erase(Exprs.begin() + BestIdx);
7210   } while (!VMIs.empty());
7211 
7212   if (!NewCall.isUsable())
7213     return Call;
7214   return PseudoObjectExpr::Create(getASTContext(), CE, {NewCall.get()}, 0);
7215 }
7216 
7217 std::optional<std::pair<FunctionDecl *, Expr *>>
7218 SemaOpenMP::checkOpenMPDeclareVariantFunction(SemaOpenMP::DeclGroupPtrTy DG,
7219                                               Expr *VariantRef,
7220                                               OMPTraitInfo &TI,
7221                                               unsigned NumAppendArgs,
7222                                               SourceRange SR) {
7223   ASTContext &Context = getASTContext();
7224   if (!DG || DG.get().isNull())
7225     return std::nullopt;
7226 
7227   const int VariantId = 1;
7228   // Must be applied only to single decl.
7229   if (!DG.get().isSingleDecl()) {
7230     Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
7231         << VariantId << SR;
7232     return std::nullopt;
7233   }
7234   Decl *ADecl = DG.get().getSingleDecl();
7235   if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
7236     ADecl = FTD->getTemplatedDecl();
7237 
7238   // Decl must be a function.
7239   auto *FD = dyn_cast<FunctionDecl>(ADecl);
7240   if (!FD) {
7241     Diag(ADecl->getLocation(), diag::err_omp_function_expected)
7242         << VariantId << SR;
7243     return std::nullopt;
7244   }
7245 
7246   auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
7247     // The 'target' attribute needs to be separately checked because it does
7248     // not always signify a multiversion function declaration.
7249     return FD->isMultiVersion() || FD->hasAttr<TargetAttr>();
7250   };
7251   // OpenMP is not compatible with multiversion function attributes.
7252   if (HasMultiVersionAttributes(FD)) {
7253     Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
7254         << SR;
7255     return std::nullopt;
7256   }
7257 
7258   // Allow #pragma omp declare variant only if the function is not used.
7259   if (FD->isUsed(false))
7260     Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
7261         << FD->getLocation();
7262 
7263   // Check if the function was emitted already.
7264   const FunctionDecl *Definition;
7265   if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) &&
7266       (getLangOpts().EmitAllDecls || Context.DeclMustBeEmitted(Definition)))
7267     Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
7268         << FD->getLocation();
7269 
7270   // The VariantRef must point to function.
7271   if (!VariantRef) {
7272     Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
7273     return std::nullopt;
7274   }
7275 
7276   auto ShouldDelayChecks = [](Expr *&E, bool) {
7277     return E && (E->isTypeDependent() || E->isValueDependent() ||
7278                  E->containsUnexpandedParameterPack() ||
7279                  E->isInstantiationDependent());
7280   };
7281   // Do not check templates, wait until instantiation.
7282   if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) ||
7283       TI.anyScoreOrCondition(ShouldDelayChecks))
7284     return std::make_pair(FD, VariantRef);
7285 
7286   // Deal with non-constant score and user condition expressions.
7287   auto HandleNonConstantScoresAndConditions = [this](Expr *&E,
7288                                                      bool IsScore) -> bool {
7289     if (!E || E->isIntegerConstantExpr(getASTContext()))
7290       return false;
7291 
7292     if (IsScore) {
7293       // We warn on non-constant scores and pretend they were not present.
7294       Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant)
7295           << E;
7296       E = nullptr;
7297     } else {
7298       // We could replace a non-constant user condition with "false" but we
7299       // will soon need to handle these anyway for the dynamic version of
7300       // OpenMP context selectors.
7301       Diag(E->getExprLoc(),
7302            diag::err_omp_declare_variant_user_condition_not_constant)
7303           << E;
7304     }
7305     return true;
7306   };
7307   if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions))
7308     return std::nullopt;
7309 
7310   QualType AdjustedFnType = FD->getType();
7311   if (NumAppendArgs) {
7312     const auto *PTy = AdjustedFnType->getAsAdjusted<FunctionProtoType>();
7313     if (!PTy) {
7314       Diag(FD->getLocation(), diag::err_omp_declare_variant_prototype_required)
7315           << SR;
7316       return std::nullopt;
7317     }
7318     // Adjust the function type to account for an extra omp_interop_t for each
7319     // specified in the append_args clause.
7320     const TypeDecl *TD = nullptr;
7321     LookupResult Result(SemaRef, &Context.Idents.get("omp_interop_t"),
7322                         SR.getBegin(), Sema::LookupOrdinaryName);
7323     if (SemaRef.LookupName(Result, SemaRef.getCurScope())) {
7324       NamedDecl *ND = Result.getFoundDecl();
7325       TD = dyn_cast_or_null<TypeDecl>(ND);
7326     }
7327     if (!TD) {
7328       Diag(SR.getBegin(), diag::err_omp_interop_type_not_found) << SR;
7329       return std::nullopt;
7330     }
7331     QualType InteropType = Context.getTypeDeclType(TD);
7332     if (PTy->isVariadic()) {
7333       Diag(FD->getLocation(), diag::err_omp_append_args_with_varargs) << SR;
7334       return std::nullopt;
7335     }
7336     llvm::SmallVector<QualType, 8> Params;
7337     Params.append(PTy->param_type_begin(), PTy->param_type_end());
7338     Params.insert(Params.end(), NumAppendArgs, InteropType);
7339     AdjustedFnType = Context.getFunctionType(PTy->getReturnType(), Params,
7340                                              PTy->getExtProtoInfo());
7341   }
7342 
7343   // Convert VariantRef expression to the type of the original function to
7344   // resolve possible conflicts.
7345   ExprResult VariantRefCast = VariantRef;
7346   if (getLangOpts().CPlusPlus) {
7347     QualType FnPtrType;
7348     auto *Method = dyn_cast<CXXMethodDecl>(FD);
7349     if (Method && !Method->isStatic()) {
7350       const Type *ClassType =
7351           Context.getTypeDeclType(Method->getParent()).getTypePtr();
7352       FnPtrType = Context.getMemberPointerType(AdjustedFnType, ClassType);
7353       ExprResult ER;
7354       {
7355         // Build addr_of unary op to correctly handle type checks for member
7356         // functions.
7357         Sema::TentativeAnalysisScope Trap(SemaRef);
7358         ER = SemaRef.CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf,
7359                                           VariantRef);
7360       }
7361       if (!ER.isUsable()) {
7362         Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7363             << VariantId << VariantRef->getSourceRange();
7364         return std::nullopt;
7365       }
7366       VariantRef = ER.get();
7367     } else {
7368       FnPtrType = Context.getPointerType(AdjustedFnType);
7369     }
7370     QualType VarianPtrType = Context.getPointerType(VariantRef->getType());
7371     if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) {
7372       ImplicitConversionSequence ICS = SemaRef.TryImplicitConversion(
7373           VariantRef, FnPtrType.getUnqualifiedType(),
7374           /*SuppressUserConversions=*/false, Sema::AllowedExplicit::None,
7375           /*InOverloadResolution=*/false,
7376           /*CStyle=*/false,
7377           /*AllowObjCWritebackConversion=*/false);
7378       if (ICS.isFailure()) {
7379         Diag(VariantRef->getExprLoc(),
7380              diag::err_omp_declare_variant_incompat_types)
7381             << VariantRef->getType()
7382             << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
7383             << (NumAppendArgs ? 1 : 0) << VariantRef->getSourceRange();
7384         return std::nullopt;
7385       }
7386       VariantRefCast = SemaRef.PerformImplicitConversion(
7387           VariantRef, FnPtrType.getUnqualifiedType(),
7388           AssignmentAction::Converting);
7389       if (!VariantRefCast.isUsable())
7390         return std::nullopt;
7391     }
7392     // Drop previously built artificial addr_of unary op for member functions.
7393     if (Method && !Method->isStatic()) {
7394       Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
7395       if (auto *UO = dyn_cast<UnaryOperator>(
7396               PossibleAddrOfVariantRef->IgnoreImplicit()))
7397         VariantRefCast = UO->getSubExpr();
7398     }
7399   }
7400 
7401   ExprResult ER = SemaRef.CheckPlaceholderExpr(VariantRefCast.get());
7402   if (!ER.isUsable() ||
7403       !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
7404     Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7405         << VariantId << VariantRef->getSourceRange();
7406     return std::nullopt;
7407   }
7408 
7409   // The VariantRef must point to function.
7410   auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts());
7411   if (!DRE) {
7412     Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7413         << VariantId << VariantRef->getSourceRange();
7414     return std::nullopt;
7415   }
7416   auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
7417   if (!NewFD) {
7418     Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7419         << VariantId << VariantRef->getSourceRange();
7420     return std::nullopt;
7421   }
7422 
7423   if (FD->getCanonicalDecl() == NewFD->getCanonicalDecl()) {
7424     Diag(VariantRef->getExprLoc(),
7425          diag::err_omp_declare_variant_same_base_function)
7426         << VariantRef->getSourceRange();
7427     return std::nullopt;
7428   }
7429 
7430   // Check if function types are compatible in C.
7431   if (!getLangOpts().CPlusPlus) {
7432     QualType NewType =
7433         Context.mergeFunctionTypes(AdjustedFnType, NewFD->getType());
7434     if (NewType.isNull()) {
7435       Diag(VariantRef->getExprLoc(),
7436            diag::err_omp_declare_variant_incompat_types)
7437           << NewFD->getType() << FD->getType() << (NumAppendArgs ? 1 : 0)
7438           << VariantRef->getSourceRange();
7439       return std::nullopt;
7440     }
7441     if (NewType->isFunctionProtoType()) {
7442       if (FD->getType()->isFunctionNoProtoType())
7443         setPrototype(SemaRef, FD, NewFD, NewType);
7444       else if (NewFD->getType()->isFunctionNoProtoType())
7445         setPrototype(SemaRef, NewFD, FD, NewType);
7446     }
7447   }
7448 
7449   // Check if variant function is not marked with declare variant directive.
7450   if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
7451     Diag(VariantRef->getExprLoc(),
7452          diag::warn_omp_declare_variant_marked_as_declare_variant)
7453         << VariantRef->getSourceRange();
7454     SourceRange SR =
7455         NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
7456     Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
7457     return std::nullopt;
7458   }
7459 
7460   enum DoesntSupport {
7461     VirtFuncs = 1,
7462     Constructors = 3,
7463     Destructors = 4,
7464     DeletedFuncs = 5,
7465     DefaultedFuncs = 6,
7466     ConstexprFuncs = 7,
7467     ConstevalFuncs = 8,
7468   };
7469   if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
7470     if (CXXFD->isVirtual()) {
7471       Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7472           << VirtFuncs;
7473       return std::nullopt;
7474     }
7475 
7476     if (isa<CXXConstructorDecl>(FD)) {
7477       Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7478           << Constructors;
7479       return std::nullopt;
7480     }
7481 
7482     if (isa<CXXDestructorDecl>(FD)) {
7483       Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7484           << Destructors;
7485       return std::nullopt;
7486     }
7487   }
7488 
7489   if (FD->isDeleted()) {
7490     Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7491         << DeletedFuncs;
7492     return std::nullopt;
7493   }
7494 
7495   if (FD->isDefaulted()) {
7496     Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7497         << DefaultedFuncs;
7498     return std::nullopt;
7499   }
7500 
7501   if (FD->isConstexpr()) {
7502     Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7503         << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
7504     return std::nullopt;
7505   }
7506 
7507   // Check general compatibility.
7508   if (SemaRef.areMultiversionVariantFunctionsCompatible(
7509           FD, NewFD, PartialDiagnostic::NullDiagnostic(),
7510           PartialDiagnosticAt(SourceLocation(),
7511                               PartialDiagnostic::NullDiagnostic()),
7512           PartialDiagnosticAt(
7513               VariantRef->getExprLoc(),
7514               SemaRef.PDiag(diag::err_omp_declare_variant_doesnt_support)),
7515           PartialDiagnosticAt(VariantRef->getExprLoc(),
7516                               SemaRef.PDiag(diag::err_omp_declare_variant_diff)
7517                                   << FD->getLocation()),
7518           /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
7519           /*CLinkageMayDiffer=*/true))
7520     return std::nullopt;
7521   return std::make_pair(FD, cast<Expr>(DRE));
7522 }
7523 
7524 void SemaOpenMP::ActOnOpenMPDeclareVariantDirective(
7525     FunctionDecl *FD, Expr *VariantRef, OMPTraitInfo &TI,
7526     ArrayRef<Expr *> AdjustArgsNothing,
7527     ArrayRef<Expr *> AdjustArgsNeedDevicePtr,
7528     ArrayRef<OMPInteropInfo> AppendArgs, SourceLocation AdjustArgsLoc,
7529     SourceLocation AppendArgsLoc, SourceRange SR) {
7530 
7531   // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions]
7532   // An adjust_args clause or append_args clause can only be specified if the
7533   // dispatch selector of the construct selector set appears in the match
7534   // clause.
7535 
7536   SmallVector<Expr *, 8> AllAdjustArgs;
7537   llvm::append_range(AllAdjustArgs, AdjustArgsNothing);
7538   llvm::append_range(AllAdjustArgs, AdjustArgsNeedDevicePtr);
7539 
7540   if (!AllAdjustArgs.empty() || !AppendArgs.empty()) {
7541     VariantMatchInfo VMI;
7542     TI.getAsVariantMatchInfo(getASTContext(), VMI);
7543     if (!llvm::is_contained(
7544             VMI.ConstructTraits,
7545             llvm::omp::TraitProperty::construct_dispatch_dispatch)) {
7546       if (!AllAdjustArgs.empty())
7547         Diag(AdjustArgsLoc, diag::err_omp_clause_requires_dispatch_construct)
7548             << getOpenMPClauseName(OMPC_adjust_args);
7549       if (!AppendArgs.empty())
7550         Diag(AppendArgsLoc, diag::err_omp_clause_requires_dispatch_construct)
7551             << getOpenMPClauseName(OMPC_append_args);
7552       return;
7553     }
7554   }
7555 
7556   // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions]
7557   // Each argument can only appear in a single adjust_args clause for each
7558   // declare variant directive.
7559   llvm::SmallPtrSet<const VarDecl *, 4> AdjustVars;
7560 
7561   for (Expr *E : AllAdjustArgs) {
7562     E = E->IgnoreParenImpCasts();
7563     if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
7564       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7565         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
7566         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
7567             FD->getParamDecl(PVD->getFunctionScopeIndex())
7568                     ->getCanonicalDecl() == CanonPVD) {
7569           // It's a parameter of the function, check duplicates.
7570           if (!AdjustVars.insert(CanonPVD).second) {
7571             Diag(DRE->getLocation(), diag::err_omp_adjust_arg_multiple_clauses)
7572                 << PVD;
7573             return;
7574           }
7575           continue;
7576         }
7577       }
7578     }
7579     // Anything that is not a function parameter is an error.
7580     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) << FD << 0;
7581     return;
7582   }
7583 
7584   auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit(
7585       getASTContext(), VariantRef, &TI,
7586       const_cast<Expr **>(AdjustArgsNothing.data()), AdjustArgsNothing.size(),
7587       const_cast<Expr **>(AdjustArgsNeedDevicePtr.data()),
7588       AdjustArgsNeedDevicePtr.size(),
7589       const_cast<OMPInteropInfo *>(AppendArgs.data()), AppendArgs.size(), SR);
7590   FD->addAttr(NewAttr);
7591 }
7592 
7593 static CapturedStmt *
7594 setBranchProtectedScope(Sema &SemaRef, OpenMPDirectiveKind DKind, Stmt *AStmt) {
7595   auto *CS = dyn_cast<CapturedStmt>(AStmt);
7596   assert(CS && "Captured statement expected");
7597   // 1.2.2 OpenMP Language Terminology
7598   // Structured block - An executable statement with a single entry at the
7599   // top and a single exit at the bottom.
7600   // The point of exit cannot be a branch out of the structured block.
7601   // longjmp() and throw() must not violate the entry/exit criteria.
7602   CS->getCapturedDecl()->setNothrow();
7603 
7604   for (int ThisCaptureLevel = SemaRef.OpenMP().getOpenMPCaptureLevels(DKind);
7605        ThisCaptureLevel > 1; --ThisCaptureLevel) {
7606     CS = cast<CapturedStmt>(CS->getCapturedStmt());
7607     // 1.2.2 OpenMP Language Terminology
7608     // Structured block - An executable statement with a single entry at the
7609     // top and a single exit at the bottom.
7610     // The point of exit cannot be a branch out of the structured block.
7611     // longjmp() and throw() must not violate the entry/exit criteria.
7612     CS->getCapturedDecl()->setNothrow();
7613   }
7614   SemaRef.setFunctionHasBranchProtectedScope();
7615   return CS;
7616 }
7617 
7618 StmtResult
7619 SemaOpenMP::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
7620                                          Stmt *AStmt, SourceLocation StartLoc,
7621                                          SourceLocation EndLoc) {
7622   if (!AStmt)
7623     return StmtError();
7624 
7625   setBranchProtectedScope(SemaRef, OMPD_parallel, AStmt);
7626 
7627   return OMPParallelDirective::Create(
7628       getASTContext(), StartLoc, EndLoc, Clauses, AStmt,
7629       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
7630 }
7631 
7632 namespace {
7633 /// Iteration space of a single for loop.
7634 struct LoopIterationSpace final {
7635   /// True if the condition operator is the strict compare operator (<, > or
7636   /// !=).
7637   bool IsStrictCompare = false;
7638   /// Condition of the loop.
7639   Expr *PreCond = nullptr;
7640   /// This expression calculates the number of iterations in the loop.
7641   /// It is always possible to calculate it before starting the loop.
7642   Expr *NumIterations = nullptr;
7643   /// The loop counter variable.
7644   Expr *CounterVar = nullptr;
7645   /// Private loop counter variable.
7646   Expr *PrivateCounterVar = nullptr;
7647   /// This is initializer for the initial value of #CounterVar.
7648   Expr *CounterInit = nullptr;
7649   /// This is step for the #CounterVar used to generate its update:
7650   /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
7651   Expr *CounterStep = nullptr;
7652   /// Should step be subtracted?
7653   bool Subtract = false;
7654   /// Source range of the loop init.
7655   SourceRange InitSrcRange;
7656   /// Source range of the loop condition.
7657   SourceRange CondSrcRange;
7658   /// Source range of the loop increment.
7659   SourceRange IncSrcRange;
7660   /// Minimum value that can have the loop control variable. Used to support
7661   /// non-rectangular loops. Applied only for LCV with the non-iterator types,
7662   /// since only such variables can be used in non-loop invariant expressions.
7663   Expr *MinValue = nullptr;
7664   /// Maximum value that can have the loop control variable. Used to support
7665   /// non-rectangular loops. Applied only for LCV with the non-iterator type,
7666   /// since only such variables can be used in non-loop invariant expressions.
7667   Expr *MaxValue = nullptr;
7668   /// true, if the lower bound depends on the outer loop control var.
7669   bool IsNonRectangularLB = false;
7670   /// true, if the upper bound depends on the outer loop control var.
7671   bool IsNonRectangularUB = false;
7672   /// Index of the loop this loop depends on and forms non-rectangular loop
7673   /// nest.
7674   unsigned LoopDependentIdx = 0;
7675   /// Final condition for the non-rectangular loop nest support. It is used to
7676   /// check that the number of iterations for this particular counter must be
7677   /// finished.
7678   Expr *FinalCondition = nullptr;
7679 };
7680 
7681 /// Scan an AST subtree, checking that no decls in the CollapsedLoopVarDecls
7682 /// set are referenced.  Used for verifying loop nest structure before
7683 /// performing a loop collapse operation.
7684 class ForSubExprChecker : public DynamicRecursiveASTVisitor {
7685   const llvm::SmallPtrSetImpl<const Decl *> &CollapsedLoopVarDecls;
7686   VarDecl *ForbiddenVar = nullptr;
7687   SourceRange ErrLoc;
7688 
7689 public:
7690   explicit ForSubExprChecker(
7691       const llvm::SmallPtrSetImpl<const Decl *> &CollapsedLoopVarDecls)
7692       : CollapsedLoopVarDecls(CollapsedLoopVarDecls) {
7693     // We want to visit implicit code, i.e. synthetic initialisation statements
7694     // created during range-for lowering.
7695     ShouldVisitImplicitCode = true;
7696   }
7697 
7698   bool VisitDeclRefExpr(DeclRefExpr *E) override {
7699     ValueDecl *VD = E->getDecl();
7700     if (!isa<VarDecl, BindingDecl>(VD))
7701       return true;
7702     VarDecl *V = VD->getPotentiallyDecomposedVarDecl();
7703     if (V->getType()->isReferenceType()) {
7704       VarDecl *VD = V->getDefinition();
7705       if (VD->hasInit()) {
7706         Expr *I = VD->getInit();
7707         DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(I);
7708         if (!DRE)
7709           return true;
7710         V = DRE->getDecl()->getPotentiallyDecomposedVarDecl();
7711       }
7712     }
7713     Decl *Canon = V->getCanonicalDecl();
7714     if (CollapsedLoopVarDecls.contains(Canon)) {
7715       ForbiddenVar = V;
7716       ErrLoc = E->getSourceRange();
7717       return false;
7718     }
7719 
7720     return true;
7721   }
7722 
7723   VarDecl *getForbiddenVar() const { return ForbiddenVar; }
7724   SourceRange getErrRange() const { return ErrLoc; }
7725 };
7726 
7727 /// Helper class for checking canonical form of the OpenMP loops and
7728 /// extracting iteration space of each loop in the loop nest, that will be used
7729 /// for IR generation.
7730 class OpenMPIterationSpaceChecker {
7731   /// Reference to Sema.
7732   Sema &SemaRef;
7733   /// Does the loop associated directive support non-rectangular loops?
7734   bool SupportsNonRectangular;
7735   /// Data-sharing stack.
7736   DSAStackTy &Stack;
7737   /// A location for diagnostics (when there is no some better location).
7738   SourceLocation DefaultLoc;
7739   /// A location for diagnostics (when increment is not compatible).
7740   SourceLocation ConditionLoc;
7741   /// The set of variables declared within the (to be collapsed) loop nest.
7742   const llvm::SmallPtrSetImpl<const Decl *> &CollapsedLoopVarDecls;
7743   /// A source location for referring to loop init later.
7744   SourceRange InitSrcRange;
7745   /// A source location for referring to condition later.
7746   SourceRange ConditionSrcRange;
7747   /// A source location for referring to increment later.
7748   SourceRange IncrementSrcRange;
7749   /// Loop variable.
7750   ValueDecl *LCDecl = nullptr;
7751   /// Reference to loop variable.
7752   Expr *LCRef = nullptr;
7753   /// Lower bound (initializer for the var).
7754   Expr *LB = nullptr;
7755   /// Upper bound.
7756   Expr *UB = nullptr;
7757   /// Loop step (increment).
7758   Expr *Step = nullptr;
7759   /// This flag is true when condition is one of:
7760   ///   Var <  UB
7761   ///   Var <= UB
7762   ///   UB  >  Var
7763   ///   UB  >= Var
7764   /// This will have no value when the condition is !=
7765   std::optional<bool> TestIsLessOp;
7766   /// This flag is true when condition is strict ( < or > ).
7767   bool TestIsStrictOp = false;
7768   /// This flag is true when step is subtracted on each iteration.
7769   bool SubtractStep = false;
7770   /// The outer loop counter this loop depends on (if any).
7771   const ValueDecl *DepDecl = nullptr;
7772   /// Contains number of loop (starts from 1) on which loop counter init
7773   /// expression of this loop depends on.
7774   std::optional<unsigned> InitDependOnLC;
7775   /// Contains number of loop (starts from 1) on which loop counter condition
7776   /// expression of this loop depends on.
7777   std::optional<unsigned> CondDependOnLC;
7778   /// Checks if the provide statement depends on the loop counter.
7779   std::optional<unsigned> doesDependOnLoopCounter(const Stmt *S,
7780                                                   bool IsInitializer);
7781   /// Original condition required for checking of the exit condition for
7782   /// non-rectangular loop.
7783   Expr *Condition = nullptr;
7784 
7785 public:
7786   OpenMPIterationSpaceChecker(
7787       Sema &SemaRef, bool SupportsNonRectangular, DSAStackTy &Stack,
7788       SourceLocation DefaultLoc,
7789       const llvm::SmallPtrSetImpl<const Decl *> &CollapsedLoopDecls)
7790       : SemaRef(SemaRef), SupportsNonRectangular(SupportsNonRectangular),
7791         Stack(Stack), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc),
7792         CollapsedLoopVarDecls(CollapsedLoopDecls) {}
7793   /// Check init-expr for canonical loop form and save loop counter
7794   /// variable - #Var and its initialization value - #LB.
7795   bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
7796   /// Check test-expr for canonical form, save upper-bound (#UB), flags
7797   /// for less/greater and for strict/non-strict comparison.
7798   bool checkAndSetCond(Expr *S);
7799   /// Check incr-expr for canonical loop form and return true if it
7800   /// does not conform, otherwise save loop step (#Step).
7801   bool checkAndSetInc(Expr *S);
7802   /// Return the loop counter variable.
7803   ValueDecl *getLoopDecl() const { return LCDecl; }
7804   /// Return the reference expression to loop counter variable.
7805   Expr *getLoopDeclRefExpr() const { return LCRef; }
7806   /// Source range of the loop init.
7807   SourceRange getInitSrcRange() const { return InitSrcRange; }
7808   /// Source range of the loop condition.
7809   SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
7810   /// Source range of the loop increment.
7811   SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
7812   /// True if the step should be subtracted.
7813   bool shouldSubtractStep() const { return SubtractStep; }
7814   /// True, if the compare operator is strict (<, > or !=).
7815   bool isStrictTestOp() const { return TestIsStrictOp; }
7816   /// Build the expression to calculate the number of iterations.
7817   Expr *buildNumIterations(
7818       Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
7819       llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7820   /// Build the precondition expression for the loops.
7821   Expr *
7822   buildPreCond(Scope *S, Expr *Cond,
7823                llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7824   /// Build reference expression to the counter be used for codegen.
7825   DeclRefExpr *
7826   buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7827                   DSAStackTy &DSA) const;
7828   /// Build reference expression to the private counter be used for
7829   /// codegen.
7830   Expr *buildPrivateCounterVar() const;
7831   /// Build initialization of the counter be used for codegen.
7832   Expr *buildCounterInit() const;
7833   /// Build step of the counter be used for codegen.
7834   Expr *buildCounterStep() const;
7835   /// Build loop data with counter value for depend clauses in ordered
7836   /// directives.
7837   Expr *
7838   buildOrderedLoopData(Scope *S, Expr *Counter,
7839                        llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7840                        SourceLocation Loc, Expr *Inc = nullptr,
7841                        OverloadedOperatorKind OOK = OO_Amp);
7842   /// Builds the minimum value for the loop counter.
7843   std::pair<Expr *, Expr *> buildMinMaxValues(
7844       Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7845   /// Builds final condition for the non-rectangular loops.
7846   Expr *buildFinalCondition(Scope *S) const;
7847   /// Return true if any expression is dependent.
7848   bool dependent() const;
7849   /// Returns true if the initializer forms non-rectangular loop.
7850   bool doesInitDependOnLC() const { return InitDependOnLC.has_value(); }
7851   /// Returns true if the condition forms non-rectangular loop.
7852   bool doesCondDependOnLC() const { return CondDependOnLC.has_value(); }
7853   /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
7854   unsigned getLoopDependentIdx() const {
7855     return InitDependOnLC.value_or(CondDependOnLC.value_or(0));
7856   }
7857 
7858 private:
7859   /// Check the right-hand side of an assignment in the increment
7860   /// expression.
7861   bool checkAndSetIncRHS(Expr *RHS);
7862   /// Helper to set loop counter variable and its initializer.
7863   bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
7864                       bool EmitDiags);
7865   /// Helper to set upper bound.
7866   bool setUB(Expr *NewUB, std::optional<bool> LessOp, bool StrictOp,
7867              SourceRange SR, SourceLocation SL);
7868   /// Helper to set loop increment.
7869   bool setStep(Expr *NewStep, bool Subtract);
7870 };
7871 
7872 bool OpenMPIterationSpaceChecker::dependent() const {
7873   if (!LCDecl) {
7874     assert(!LB && !UB && !Step);
7875     return false;
7876   }
7877   return LCDecl->getType()->isDependentType() ||
7878          (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
7879          (Step && Step->isValueDependent());
7880 }
7881 
7882 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
7883                                                  Expr *NewLCRefExpr,
7884                                                  Expr *NewLB, bool EmitDiags) {
7885   // State consistency checking to ensure correct usage.
7886   assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
7887          UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
7888   if (!NewLCDecl || !NewLB || NewLB->containsErrors())
7889     return true;
7890   LCDecl = getCanonicalDecl(NewLCDecl);
7891   LCRef = NewLCRefExpr;
7892   if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
7893     if (const CXXConstructorDecl *Ctor = CE->getConstructor())
7894       if ((Ctor->isCopyOrMoveConstructor() ||
7895            Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
7896           CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
7897         NewLB = CE->getArg(0)->IgnoreParenImpCasts();
7898   LB = NewLB;
7899   if (EmitDiags)
7900     InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
7901   return false;
7902 }
7903 
7904 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, std::optional<bool> LessOp,
7905                                         bool StrictOp, SourceRange SR,
7906                                         SourceLocation SL) {
7907   // State consistency checking to ensure correct usage.
7908   assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&
7909          Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
7910   if (!NewUB || NewUB->containsErrors())
7911     return true;
7912   UB = NewUB;
7913   if (LessOp)
7914     TestIsLessOp = LessOp;
7915   TestIsStrictOp = StrictOp;
7916   ConditionSrcRange = SR;
7917   ConditionLoc = SL;
7918   CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
7919   return false;
7920 }
7921 
7922 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
7923   // State consistency checking to ensure correct usage.
7924   assert(LCDecl != nullptr && LB != nullptr && Step == nullptr);
7925   if (!NewStep || NewStep->containsErrors())
7926     return true;
7927   if (!NewStep->isValueDependent()) {
7928     // Check that the step is integer expression.
7929     SourceLocation StepLoc = NewStep->getBeginLoc();
7930     ExprResult Val = SemaRef.OpenMP().PerformOpenMPImplicitIntegerConversion(
7931         StepLoc, getExprAsWritten(NewStep));
7932     if (Val.isInvalid())
7933       return true;
7934     NewStep = Val.get();
7935 
7936     // OpenMP [2.6, Canonical Loop Form, Restrictions]
7937     //  If test-expr is of form var relational-op b and relational-op is < or
7938     //  <= then incr-expr must cause var to increase on each iteration of the
7939     //  loop. If test-expr is of form var relational-op b and relational-op is
7940     //  > or >= then incr-expr must cause var to decrease on each iteration of
7941     //  the loop.
7942     //  If test-expr is of form b relational-op var and relational-op is < or
7943     //  <= then incr-expr must cause var to decrease on each iteration of the
7944     //  loop. If test-expr is of form b relational-op var and relational-op is
7945     //  > or >= then incr-expr must cause var to increase on each iteration of
7946     //  the loop.
7947     std::optional<llvm::APSInt> Result =
7948         NewStep->getIntegerConstantExpr(SemaRef.Context);
7949     bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
7950     bool IsConstNeg =
7951         Result && Result->isSigned() && (Subtract != Result->isNegative());
7952     bool IsConstPos =
7953         Result && Result->isSigned() && (Subtract == Result->isNegative());
7954     bool IsConstZero = Result && !Result->getBoolValue();
7955 
7956     // != with increment is treated as <; != with decrement is treated as >
7957     if (!TestIsLessOp)
7958       TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
7959     if (UB && (IsConstZero ||
7960                (*TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract))
7961                               : (IsConstPos || (IsUnsigned && !Subtract))))) {
7962       SemaRef.Diag(NewStep->getExprLoc(),
7963                    diag::err_omp_loop_incr_not_compatible)
7964           << LCDecl << *TestIsLessOp << NewStep->getSourceRange();
7965       SemaRef.Diag(ConditionLoc,
7966                    diag::note_omp_loop_cond_requires_compatible_incr)
7967           << *TestIsLessOp << ConditionSrcRange;
7968       return true;
7969     }
7970     if (*TestIsLessOp == Subtract) {
7971       NewStep =
7972           SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
7973               .get();
7974       Subtract = !Subtract;
7975     }
7976   }
7977 
7978   Step = NewStep;
7979   SubtractStep = Subtract;
7980   return false;
7981 }
7982 
7983 namespace {
7984 /// Checker for the non-rectangular loops. Checks if the initializer or
7985 /// condition expression references loop counter variable.
7986 class LoopCounterRefChecker final
7987     : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
7988   Sema &SemaRef;
7989   DSAStackTy &Stack;
7990   const ValueDecl *CurLCDecl = nullptr;
7991   const ValueDecl *DepDecl = nullptr;
7992   const ValueDecl *PrevDepDecl = nullptr;
7993   bool IsInitializer = true;
7994   bool SupportsNonRectangular;
7995   unsigned BaseLoopId = 0;
7996   bool checkDecl(const Expr *E, const ValueDecl *VD) {
7997     if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
7998       SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
7999           << (IsInitializer ? 0 : 1);
8000       return false;
8001     }
8002     const auto &&Data = Stack.isLoopControlVariable(VD);
8003     // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
8004     // The type of the loop iterator on which we depend may not have a random
8005     // access iterator type.
8006     if (Data.first && VD->getType()->isRecordType()) {
8007       SmallString<128> Name;
8008       llvm::raw_svector_ostream OS(Name);
8009       VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
8010                                /*Qualified=*/true);
8011       SemaRef.Diag(E->getExprLoc(),
8012                    diag::err_omp_wrong_dependency_iterator_type)
8013           << OS.str();
8014       SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
8015       return false;
8016     }
8017     if (Data.first && !SupportsNonRectangular) {
8018       SemaRef.Diag(E->getExprLoc(), diag::err_omp_invariant_dependency);
8019       return false;
8020     }
8021     if (Data.first &&
8022         (DepDecl || (PrevDepDecl &&
8023                      getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
8024       if (!DepDecl && PrevDepDecl)
8025         DepDecl = PrevDepDecl;
8026       SmallString<128> Name;
8027       llvm::raw_svector_ostream OS(Name);
8028       DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
8029                                     /*Qualified=*/true);
8030       SemaRef.Diag(E->getExprLoc(),
8031                    diag::err_omp_invariant_or_linear_dependency)
8032           << OS.str();
8033       return false;
8034     }
8035     if (Data.first) {
8036       DepDecl = VD;
8037       BaseLoopId = Data.first;
8038     }
8039     return Data.first;
8040   }
8041 
8042 public:
8043   bool VisitDeclRefExpr(const DeclRefExpr *E) {
8044     const ValueDecl *VD = E->getDecl();
8045     if (isa<VarDecl>(VD))
8046       return checkDecl(E, VD);
8047     return false;
8048   }
8049   bool VisitMemberExpr(const MemberExpr *E) {
8050     if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
8051       const ValueDecl *VD = E->getMemberDecl();
8052       if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
8053         return checkDecl(E, VD);
8054     }
8055     return false;
8056   }
8057   bool VisitStmt(const Stmt *S) {
8058     bool Res = false;
8059     for (const Stmt *Child : S->children())
8060       Res = (Child && Visit(Child)) || Res;
8061     return Res;
8062   }
8063   explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
8064                                  const ValueDecl *CurLCDecl, bool IsInitializer,
8065                                  const ValueDecl *PrevDepDecl = nullptr,
8066                                  bool SupportsNonRectangular = true)
8067       : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
8068         PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer),
8069         SupportsNonRectangular(SupportsNonRectangular) {}
8070   unsigned getBaseLoopId() const {
8071     assert(CurLCDecl && "Expected loop dependency.");
8072     return BaseLoopId;
8073   }
8074   const ValueDecl *getDepDecl() const {
8075     assert(CurLCDecl && "Expected loop dependency.");
8076     return DepDecl;
8077   }
8078 };
8079 } // namespace
8080 
8081 std::optional<unsigned>
8082 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
8083                                                      bool IsInitializer) {
8084   // Check for the non-rectangular loops.
8085   LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
8086                                         DepDecl, SupportsNonRectangular);
8087   if (LoopStmtChecker.Visit(S)) {
8088     DepDecl = LoopStmtChecker.getDepDecl();
8089     return LoopStmtChecker.getBaseLoopId();
8090   }
8091   return std::nullopt;
8092 }
8093 
8094 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
8095   // Check init-expr for canonical loop form and save loop counter
8096   // variable - #Var and its initialization value - #LB.
8097   // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
8098   //   var = lb
8099   //   integer-type var = lb
8100   //   random-access-iterator-type var = lb
8101   //   pointer-type var = lb
8102   //
8103   if (!S) {
8104     if (EmitDiags) {
8105       SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
8106     }
8107     return true;
8108   }
8109   if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
8110     if (!ExprTemp->cleanupsHaveSideEffects())
8111       S = ExprTemp->getSubExpr();
8112 
8113   if (!CollapsedLoopVarDecls.empty()) {
8114     ForSubExprChecker FSEC{CollapsedLoopVarDecls};
8115     if (!FSEC.TraverseStmt(S)) {
8116       SourceRange Range = FSEC.getErrRange();
8117       SemaRef.Diag(Range.getBegin(), diag::err_omp_loop_bad_collapse_var)
8118           << Range.getEnd() << 0 << FSEC.getForbiddenVar();
8119       return true;
8120     }
8121   }
8122 
8123   InitSrcRange = S->getSourceRange();
8124   if (Expr *E = dyn_cast<Expr>(S))
8125     S = E->IgnoreParens();
8126   if (auto *BO = dyn_cast<BinaryOperator>(S)) {
8127     if (BO->getOpcode() == BO_Assign) {
8128       Expr *LHS = BO->getLHS()->IgnoreParens();
8129       if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
8130         if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
8131           if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
8132             return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8133                                   EmitDiags);
8134         return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
8135       }
8136       if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
8137         if (ME->isArrow() &&
8138             isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8139           return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8140                                 EmitDiags);
8141       }
8142     }
8143   } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
8144     if (DS->isSingleDecl()) {
8145       if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
8146         if (Var->hasInit() && !Var->getType()->isReferenceType()) {
8147           // Accept non-canonical init form here but emit ext. warning.
8148           if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
8149             SemaRef.Diag(S->getBeginLoc(),
8150                          diag::ext_omp_loop_not_canonical_init)
8151                 << S->getSourceRange();
8152           return setLCDeclAndLB(
8153               Var,
8154               buildDeclRefExpr(SemaRef, Var,
8155                                Var->getType().getNonReferenceType(),
8156                                DS->getBeginLoc()),
8157               Var->getInit(), EmitDiags);
8158         }
8159       }
8160     }
8161   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8162     if (CE->getOperator() == OO_Equal) {
8163       Expr *LHS = CE->getArg(0);
8164       if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
8165         if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
8166           if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
8167             return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8168                                   EmitDiags);
8169         return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
8170       }
8171       if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
8172         if (ME->isArrow() &&
8173             isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8174           return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8175                                 EmitDiags);
8176       }
8177     }
8178   }
8179 
8180   if (dependent() || SemaRef.CurContext->isDependentContext())
8181     return false;
8182   if (EmitDiags) {
8183     SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
8184         << S->getSourceRange();
8185   }
8186   return true;
8187 }
8188 
8189 /// Ignore parenthesizes, implicit casts, copy constructor and return the
8190 /// variable (which may be the loop variable) if possible.
8191 static const ValueDecl *getInitLCDecl(const Expr *E) {
8192   if (!E)
8193     return nullptr;
8194   E = getExprAsWritten(E);
8195   if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
8196     if (const CXXConstructorDecl *Ctor = CE->getConstructor())
8197       if ((Ctor->isCopyOrMoveConstructor() ||
8198            Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
8199           CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
8200         E = CE->getArg(0)->IgnoreParenImpCasts();
8201   if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
8202     if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
8203       return getCanonicalDecl(VD);
8204   }
8205   if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
8206     if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8207       return getCanonicalDecl(ME->getMemberDecl());
8208   return nullptr;
8209 }
8210 
8211 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
8212   // Check test-expr for canonical form, save upper-bound UB, flags for
8213   // less/greater and for strict/non-strict comparison.
8214   // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following:
8215   //   var relational-op b
8216   //   b relational-op var
8217   //
8218   bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
8219   if (!S) {
8220     SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
8221         << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
8222     return true;
8223   }
8224   Condition = S;
8225   S = getExprAsWritten(S);
8226 
8227   if (!CollapsedLoopVarDecls.empty()) {
8228     ForSubExprChecker FSEC{CollapsedLoopVarDecls};
8229     if (!FSEC.TraverseStmt(S)) {
8230       SourceRange Range = FSEC.getErrRange();
8231       SemaRef.Diag(Range.getBegin(), diag::err_omp_loop_bad_collapse_var)
8232           << Range.getEnd() << 1 << FSEC.getForbiddenVar();
8233       return true;
8234     }
8235   }
8236 
8237   SourceLocation CondLoc = S->getBeginLoc();
8238   auto &&CheckAndSetCond =
8239       [this, IneqCondIsCanonical](BinaryOperatorKind Opcode, const Expr *LHS,
8240                                   const Expr *RHS, SourceRange SR,
8241                                   SourceLocation OpLoc) -> std::optional<bool> {
8242     if (BinaryOperator::isRelationalOp(Opcode)) {
8243       if (getInitLCDecl(LHS) == LCDecl)
8244         return setUB(const_cast<Expr *>(RHS),
8245                      (Opcode == BO_LT || Opcode == BO_LE),
8246                      (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
8247       if (getInitLCDecl(RHS) == LCDecl)
8248         return setUB(const_cast<Expr *>(LHS),
8249                      (Opcode == BO_GT || Opcode == BO_GE),
8250                      (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
8251     } else if (IneqCondIsCanonical && Opcode == BO_NE) {
8252       return setUB(const_cast<Expr *>(getInitLCDecl(LHS) == LCDecl ? RHS : LHS),
8253                    /*LessOp=*/std::nullopt,
8254                    /*StrictOp=*/true, SR, OpLoc);
8255     }
8256     return std::nullopt;
8257   };
8258   std::optional<bool> Res;
8259   if (auto *RBO = dyn_cast<CXXRewrittenBinaryOperator>(S)) {
8260     CXXRewrittenBinaryOperator::DecomposedForm DF = RBO->getDecomposedForm();
8261     Res = CheckAndSetCond(DF.Opcode, DF.LHS, DF.RHS, RBO->getSourceRange(),
8262                           RBO->getOperatorLoc());
8263   } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
8264     Res = CheckAndSetCond(BO->getOpcode(), BO->getLHS(), BO->getRHS(),
8265                           BO->getSourceRange(), BO->getOperatorLoc());
8266   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8267     if (CE->getNumArgs() == 2) {
8268       Res = CheckAndSetCond(
8269           BinaryOperator::getOverloadedOpcode(CE->getOperator()), CE->getArg(0),
8270           CE->getArg(1), CE->getSourceRange(), CE->getOperatorLoc());
8271     }
8272   }
8273   if (Res)
8274     return *Res;
8275   if (dependent() || SemaRef.CurContext->isDependentContext())
8276     return false;
8277   SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
8278       << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
8279   return true;
8280 }
8281 
8282 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
8283   // RHS of canonical loop form increment can be:
8284   //   var + incr
8285   //   incr + var
8286   //   var - incr
8287   //
8288   RHS = RHS->IgnoreParenImpCasts();
8289   if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
8290     if (BO->isAdditiveOp()) {
8291       bool IsAdd = BO->getOpcode() == BO_Add;
8292       if (getInitLCDecl(BO->getLHS()) == LCDecl)
8293         return setStep(BO->getRHS(), !IsAdd);
8294       if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
8295         return setStep(BO->getLHS(), /*Subtract=*/false);
8296     }
8297   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
8298     bool IsAdd = CE->getOperator() == OO_Plus;
8299     if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
8300       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8301         return setStep(CE->getArg(1), !IsAdd);
8302       if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
8303         return setStep(CE->getArg(0), /*Subtract=*/false);
8304     }
8305   }
8306   if (dependent() || SemaRef.CurContext->isDependentContext())
8307     return false;
8308   SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
8309       << RHS->getSourceRange() << LCDecl;
8310   return true;
8311 }
8312 
8313 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
8314   // Check incr-expr for canonical loop form and return true if it
8315   // does not conform.
8316   // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
8317   //   ++var
8318   //   var++
8319   //   --var
8320   //   var--
8321   //   var += incr
8322   //   var -= incr
8323   //   var = var + incr
8324   //   var = incr + var
8325   //   var = var - incr
8326   //
8327   if (!S) {
8328     SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
8329     return true;
8330   }
8331   if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
8332     if (!ExprTemp->cleanupsHaveSideEffects())
8333       S = ExprTemp->getSubExpr();
8334 
8335   if (!CollapsedLoopVarDecls.empty()) {
8336     ForSubExprChecker FSEC{CollapsedLoopVarDecls};
8337     if (!FSEC.TraverseStmt(S)) {
8338       SourceRange Range = FSEC.getErrRange();
8339       SemaRef.Diag(Range.getBegin(), diag::err_omp_loop_bad_collapse_var)
8340           << Range.getEnd() << 2 << FSEC.getForbiddenVar();
8341       return true;
8342     }
8343   }
8344 
8345   IncrementSrcRange = S->getSourceRange();
8346   S = S->IgnoreParens();
8347   if (auto *UO = dyn_cast<UnaryOperator>(S)) {
8348     if (UO->isIncrementDecrementOp() &&
8349         getInitLCDecl(UO->getSubExpr()) == LCDecl)
8350       return setStep(SemaRef
8351                          .ActOnIntegerConstant(UO->getBeginLoc(),
8352                                                (UO->isDecrementOp() ? -1 : 1))
8353                          .get(),
8354                      /*Subtract=*/false);
8355   } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
8356     switch (BO->getOpcode()) {
8357     case BO_AddAssign:
8358     case BO_SubAssign:
8359       if (getInitLCDecl(BO->getLHS()) == LCDecl)
8360         return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
8361       break;
8362     case BO_Assign:
8363       if (getInitLCDecl(BO->getLHS()) == LCDecl)
8364         return checkAndSetIncRHS(BO->getRHS());
8365       break;
8366     default:
8367       break;
8368     }
8369   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8370     switch (CE->getOperator()) {
8371     case OO_PlusPlus:
8372     case OO_MinusMinus:
8373       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8374         return setStep(SemaRef
8375                            .ActOnIntegerConstant(
8376                                CE->getBeginLoc(),
8377                                ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
8378                            .get(),
8379                        /*Subtract=*/false);
8380       break;
8381     case OO_PlusEqual:
8382     case OO_MinusEqual:
8383       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8384         return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
8385       break;
8386     case OO_Equal:
8387       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8388         return checkAndSetIncRHS(CE->getArg(1));
8389       break;
8390     default:
8391       break;
8392     }
8393   }
8394   if (dependent() || SemaRef.CurContext->isDependentContext())
8395     return false;
8396   SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
8397       << S->getSourceRange() << LCDecl;
8398   return true;
8399 }
8400 
8401 static ExprResult
8402 tryBuildCapture(Sema &SemaRef, Expr *Capture,
8403                 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8404                 StringRef Name = ".capture_expr.") {
8405   if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors())
8406     return Capture;
8407   if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
8408     return SemaRef.PerformImplicitConversion(Capture->IgnoreImpCasts(),
8409                                              Capture->getType(),
8410                                              AssignmentAction::Converting,
8411                                              /*AllowExplicit=*/true);
8412   auto I = Captures.find(Capture);
8413   if (I != Captures.end())
8414     return buildCapture(SemaRef, Capture, I->second, Name);
8415   DeclRefExpr *Ref = nullptr;
8416   ExprResult Res = buildCapture(SemaRef, Capture, Ref, Name);
8417   Captures[Capture] = Ref;
8418   return Res;
8419 }
8420 
8421 /// Calculate number of iterations, transforming to unsigned, if number of
8422 /// iterations may be larger than the original type.
8423 static Expr *
8424 calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc,
8425                   Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy,
8426                   bool TestIsStrictOp, bool RoundToStep,
8427                   llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8428   ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures, ".new_step");
8429   if (!NewStep.isUsable())
8430     return nullptr;
8431   llvm::APSInt LRes, SRes;
8432   bool IsLowerConst = false, IsStepConst = false;
8433   if (std::optional<llvm::APSInt> Res =
8434           Lower->getIntegerConstantExpr(SemaRef.Context)) {
8435     LRes = *Res;
8436     IsLowerConst = true;
8437   }
8438   if (std::optional<llvm::APSInt> Res =
8439           Step->getIntegerConstantExpr(SemaRef.Context)) {
8440     SRes = *Res;
8441     IsStepConst = true;
8442   }
8443   bool NoNeedToConvert = IsLowerConst && !RoundToStep &&
8444                          ((!TestIsStrictOp && LRes.isNonNegative()) ||
8445                           (TestIsStrictOp && LRes.isStrictlyPositive()));
8446   bool NeedToReorganize = false;
8447   // Check if any subexpressions in Lower -Step [+ 1] lead to overflow.
8448   if (!NoNeedToConvert && IsLowerConst &&
8449       (TestIsStrictOp || (RoundToStep && IsStepConst))) {
8450     NoNeedToConvert = true;
8451     if (RoundToStep) {
8452       unsigned BW = LRes.getBitWidth() > SRes.getBitWidth()
8453                         ? LRes.getBitWidth()
8454                         : SRes.getBitWidth();
8455       LRes = LRes.extend(BW + 1);
8456       LRes.setIsSigned(true);
8457       SRes = SRes.extend(BW + 1);
8458       SRes.setIsSigned(true);
8459       LRes -= SRes;
8460       NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes;
8461       LRes = LRes.trunc(BW);
8462     }
8463     if (TestIsStrictOp) {
8464       unsigned BW = LRes.getBitWidth();
8465       LRes = LRes.extend(BW + 1);
8466       LRes.setIsSigned(true);
8467       ++LRes;
8468       NoNeedToConvert =
8469           NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes;
8470       // truncate to the original bitwidth.
8471       LRes = LRes.trunc(BW);
8472     }
8473     NeedToReorganize = NoNeedToConvert;
8474   }
8475   llvm::APSInt URes;
8476   bool IsUpperConst = false;
8477   if (std::optional<llvm::APSInt> Res =
8478           Upper->getIntegerConstantExpr(SemaRef.Context)) {
8479     URes = *Res;
8480     IsUpperConst = true;
8481   }
8482   if (NoNeedToConvert && IsLowerConst && IsUpperConst &&
8483       (!RoundToStep || IsStepConst)) {
8484     unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth()
8485                                                           : URes.getBitWidth();
8486     LRes = LRes.extend(BW + 1);
8487     LRes.setIsSigned(true);
8488     URes = URes.extend(BW + 1);
8489     URes.setIsSigned(true);
8490     URes -= LRes;
8491     NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes;
8492     NeedToReorganize = NoNeedToConvert;
8493   }
8494   // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant
8495   // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to
8496   // unsigned.
8497   if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) &&
8498       !LCTy->isDependentType() && LCTy->isIntegerType()) {
8499     QualType LowerTy = Lower->getType();
8500     QualType UpperTy = Upper->getType();
8501     uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy);
8502     uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy);
8503     if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) ||
8504         (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) {
8505       QualType CastType = SemaRef.Context.getIntTypeForBitwidth(
8506           LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0);
8507       Upper =
8508           SemaRef
8509               .PerformImplicitConversion(
8510                   SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
8511                   CastType, AssignmentAction::Converting)
8512               .get();
8513       Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get();
8514       NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get());
8515     }
8516   }
8517   if (!Lower || !Upper || NewStep.isInvalid())
8518     return nullptr;
8519 
8520   ExprResult Diff;
8521   // If need to reorganize, then calculate the form as Upper - (Lower - Step [+
8522   // 1]).
8523   if (NeedToReorganize) {
8524     Diff = Lower;
8525 
8526     if (RoundToStep) {
8527       // Lower - Step
8528       Diff =
8529           SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get());
8530       if (!Diff.isUsable())
8531         return nullptr;
8532     }
8533 
8534     // Lower - Step [+ 1]
8535     if (TestIsStrictOp)
8536       Diff = SemaRef.BuildBinOp(
8537           S, DefaultLoc, BO_Add, Diff.get(),
8538           SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8539     if (!Diff.isUsable())
8540       return nullptr;
8541 
8542     Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8543     if (!Diff.isUsable())
8544       return nullptr;
8545 
8546     // Upper - (Lower - Step [+ 1]).
8547     Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get());
8548     if (!Diff.isUsable())
8549       return nullptr;
8550   } else {
8551     Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
8552 
8553     if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) {
8554       // BuildBinOp already emitted error, this one is to point user to upper
8555       // and lower bound, and to tell what is passed to 'operator-'.
8556       SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
8557           << Upper->getSourceRange() << Lower->getSourceRange();
8558       return nullptr;
8559     }
8560 
8561     if (!Diff.isUsable())
8562       return nullptr;
8563 
8564     // Upper - Lower [- 1]
8565     if (TestIsStrictOp)
8566       Diff = SemaRef.BuildBinOp(
8567           S, DefaultLoc, BO_Sub, Diff.get(),
8568           SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8569     if (!Diff.isUsable())
8570       return nullptr;
8571 
8572     if (RoundToStep) {
8573       // Upper - Lower [- 1] + Step
8574       Diff =
8575           SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
8576       if (!Diff.isUsable())
8577         return nullptr;
8578     }
8579   }
8580 
8581   // Parentheses (for dumping/debugging purposes only).
8582   Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8583   if (!Diff.isUsable())
8584     return nullptr;
8585 
8586   // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step
8587   Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
8588   if (!Diff.isUsable())
8589     return nullptr;
8590 
8591   return Diff.get();
8592 }
8593 
8594 /// Build the expression to calculate the number of iterations.
8595 Expr *OpenMPIterationSpaceChecker::buildNumIterations(
8596     Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
8597     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8598   QualType VarType = LCDecl->getType().getNonReferenceType();
8599   if (!VarType->isIntegerType() && !VarType->isPointerType() &&
8600       !SemaRef.getLangOpts().CPlusPlus)
8601     return nullptr;
8602   Expr *LBVal = LB;
8603   Expr *UBVal = UB;
8604   // OuterVar = (LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
8605   // max(LB(MinVal), LB(MaxVal)))
8606   if (InitDependOnLC) {
8607     const LoopIterationSpace &IS = ResultIterSpaces[*InitDependOnLC - 1];
8608     if (!IS.MinValue || !IS.MaxValue)
8609       return nullptr;
8610     // OuterVar = Min
8611     ExprResult MinValue =
8612         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8613     if (!MinValue.isUsable())
8614       return nullptr;
8615 
8616     ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8617                                              IS.CounterVar, MinValue.get());
8618     if (!LBMinVal.isUsable())
8619       return nullptr;
8620     // OuterVar = Min, LBVal
8621     LBMinVal =
8622         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal);
8623     if (!LBMinVal.isUsable())
8624       return nullptr;
8625     // (OuterVar = Min, LBVal)
8626     LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get());
8627     if (!LBMinVal.isUsable())
8628       return nullptr;
8629 
8630     // OuterVar = Max
8631     ExprResult MaxValue =
8632         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8633     if (!MaxValue.isUsable())
8634       return nullptr;
8635 
8636     ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8637                                              IS.CounterVar, MaxValue.get());
8638     if (!LBMaxVal.isUsable())
8639       return nullptr;
8640     // OuterVar = Max, LBVal
8641     LBMaxVal =
8642         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal);
8643     if (!LBMaxVal.isUsable())
8644       return nullptr;
8645     // (OuterVar = Max, LBVal)
8646     LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get());
8647     if (!LBMaxVal.isUsable())
8648       return nullptr;
8649 
8650     Expr *LBMin =
8651         tryBuildCapture(SemaRef, LBMinVal.get(), Captures, ".lb_min").get();
8652     Expr *LBMax =
8653         tryBuildCapture(SemaRef, LBMaxVal.get(), Captures, ".lb_max").get();
8654     if (!LBMin || !LBMax)
8655       return nullptr;
8656     // LB(MinVal) < LB(MaxVal)
8657     ExprResult MinLessMaxRes =
8658         SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
8659     if (!MinLessMaxRes.isUsable())
8660       return nullptr;
8661     Expr *MinLessMax =
8662         tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures, ".min_less_max")
8663             .get();
8664     if (!MinLessMax)
8665       return nullptr;
8666     if (*TestIsLessOp) {
8667       // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
8668       // LB(MaxVal))
8669       ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8670                                                     MinLessMax, LBMin, LBMax);
8671       if (!MinLB.isUsable())
8672         return nullptr;
8673       LBVal = MinLB.get();
8674     } else {
8675       // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
8676       // LB(MaxVal))
8677       ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8678                                                     MinLessMax, LBMax, LBMin);
8679       if (!MaxLB.isUsable())
8680         return nullptr;
8681       LBVal = MaxLB.get();
8682     }
8683     // OuterVar = LB
8684     LBMinVal =
8685         SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, IS.CounterVar, LBVal);
8686     if (!LBMinVal.isUsable())
8687       return nullptr;
8688     LBVal = LBMinVal.get();
8689   }
8690   // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
8691   // min(UB(MinVal), UB(MaxVal))
8692   if (CondDependOnLC) {
8693     const LoopIterationSpace &IS = ResultIterSpaces[*CondDependOnLC - 1];
8694     if (!IS.MinValue || !IS.MaxValue)
8695       return nullptr;
8696     // OuterVar = Min
8697     ExprResult MinValue =
8698         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8699     if (!MinValue.isUsable())
8700       return nullptr;
8701 
8702     ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8703                                              IS.CounterVar, MinValue.get());
8704     if (!UBMinVal.isUsable())
8705       return nullptr;
8706     // OuterVar = Min, UBVal
8707     UBMinVal =
8708         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal);
8709     if (!UBMinVal.isUsable())
8710       return nullptr;
8711     // (OuterVar = Min, UBVal)
8712     UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get());
8713     if (!UBMinVal.isUsable())
8714       return nullptr;
8715 
8716     // OuterVar = Max
8717     ExprResult MaxValue =
8718         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8719     if (!MaxValue.isUsable())
8720       return nullptr;
8721 
8722     ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8723                                              IS.CounterVar, MaxValue.get());
8724     if (!UBMaxVal.isUsable())
8725       return nullptr;
8726     // OuterVar = Max, UBVal
8727     UBMaxVal =
8728         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal);
8729     if (!UBMaxVal.isUsable())
8730       return nullptr;
8731     // (OuterVar = Max, UBVal)
8732     UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get());
8733     if (!UBMaxVal.isUsable())
8734       return nullptr;
8735 
8736     Expr *UBMin =
8737         tryBuildCapture(SemaRef, UBMinVal.get(), Captures, ".ub_min").get();
8738     Expr *UBMax =
8739         tryBuildCapture(SemaRef, UBMaxVal.get(), Captures, ".ub_max").get();
8740     if (!UBMin || !UBMax)
8741       return nullptr;
8742     // UB(MinVal) > UB(MaxVal)
8743     ExprResult MinGreaterMaxRes =
8744         SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
8745     if (!MinGreaterMaxRes.isUsable())
8746       return nullptr;
8747     Expr *MinGreaterMax = tryBuildCapture(SemaRef, MinGreaterMaxRes.get(),
8748                                           Captures, ".min_greater_max")
8749                               .get();
8750     if (!MinGreaterMax)
8751       return nullptr;
8752     if (*TestIsLessOp) {
8753       // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
8754       // UB(MaxVal))
8755       ExprResult MaxUB = SemaRef.ActOnConditionalOp(
8756           DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
8757       if (!MaxUB.isUsable())
8758         return nullptr;
8759       UBVal = MaxUB.get();
8760     } else {
8761       // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
8762       // UB(MaxVal))
8763       ExprResult MinUB = SemaRef.ActOnConditionalOp(
8764           DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
8765       if (!MinUB.isUsable())
8766         return nullptr;
8767       UBVal = MinUB.get();
8768     }
8769   }
8770   Expr *UBExpr = *TestIsLessOp ? UBVal : LBVal;
8771   Expr *LBExpr = *TestIsLessOp ? LBVal : UBVal;
8772   Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures, ".upper").get();
8773   Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures, ".lower").get();
8774   if (!Upper || !Lower)
8775     return nullptr;
8776 
8777   ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8778                                       Step, VarType, TestIsStrictOp,
8779                                       /*RoundToStep=*/true, Captures);
8780   if (!Diff.isUsable())
8781     return nullptr;
8782 
8783   // OpenMP runtime requires 32-bit or 64-bit loop variables.
8784   QualType Type = Diff.get()->getType();
8785   ASTContext &C = SemaRef.Context;
8786   bool UseVarType = VarType->hasIntegerRepresentation() &&
8787                     C.getTypeSize(Type) > C.getTypeSize(VarType);
8788   if (!Type->isIntegerType() || UseVarType) {
8789     unsigned NewSize =
8790         UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
8791     bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
8792                                : Type->hasSignedIntegerRepresentation();
8793     Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
8794     if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
8795       Diff = SemaRef.PerformImplicitConversion(Diff.get(), Type,
8796                                                AssignmentAction::Converting,
8797                                                /*AllowExplicit=*/true);
8798       if (!Diff.isUsable())
8799         return nullptr;
8800     }
8801   }
8802   if (LimitedType) {
8803     unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
8804     if (NewSize != C.getTypeSize(Type)) {
8805       if (NewSize < C.getTypeSize(Type)) {
8806         assert(NewSize == 64 && "incorrect loop var size");
8807         SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
8808             << InitSrcRange << ConditionSrcRange;
8809       }
8810       QualType NewType = C.getIntTypeForBitwidth(
8811           NewSize, Type->hasSignedIntegerRepresentation() ||
8812                        C.getTypeSize(Type) < NewSize);
8813       if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
8814         Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
8815                                                  AssignmentAction::Converting,
8816                                                  /*AllowExplicit=*/true);
8817         if (!Diff.isUsable())
8818           return nullptr;
8819       }
8820     }
8821   }
8822 
8823   return Diff.get();
8824 }
8825 
8826 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
8827     Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8828   // Do not build for iterators, they cannot be used in non-rectangular loop
8829   // nests.
8830   if (LCDecl->getType()->isRecordType())
8831     return std::make_pair(nullptr, nullptr);
8832   // If we subtract, the min is in the condition, otherwise the min is in the
8833   // init value.
8834   Expr *MinExpr = nullptr;
8835   Expr *MaxExpr = nullptr;
8836   Expr *LBExpr = *TestIsLessOp ? LB : UB;
8837   Expr *UBExpr = *TestIsLessOp ? UB : LB;
8838   bool LBNonRect =
8839       *TestIsLessOp ? InitDependOnLC.has_value() : CondDependOnLC.has_value();
8840   bool UBNonRect =
8841       *TestIsLessOp ? CondDependOnLC.has_value() : InitDependOnLC.has_value();
8842   Expr *Lower =
8843       LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
8844   Expr *Upper =
8845       UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
8846   if (!Upper || !Lower)
8847     return std::make_pair(nullptr, nullptr);
8848 
8849   if (*TestIsLessOp)
8850     MinExpr = Lower;
8851   else
8852     MaxExpr = Upper;
8853 
8854   // Build minimum/maximum value based on number of iterations.
8855   QualType VarType = LCDecl->getType().getNonReferenceType();
8856 
8857   ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8858                                       Step, VarType, TestIsStrictOp,
8859                                       /*RoundToStep=*/false, Captures);
8860   if (!Diff.isUsable())
8861     return std::make_pair(nullptr, nullptr);
8862 
8863   // ((Upper - Lower [- 1]) / Step) * Step
8864   // Parentheses (for dumping/debugging purposes only).
8865   Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8866   if (!Diff.isUsable())
8867     return std::make_pair(nullptr, nullptr);
8868 
8869   ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures, ".new_step");
8870   if (!NewStep.isUsable())
8871     return std::make_pair(nullptr, nullptr);
8872   Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get());
8873   if (!Diff.isUsable())
8874     return std::make_pair(nullptr, nullptr);
8875 
8876   // Parentheses (for dumping/debugging purposes only).
8877   Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8878   if (!Diff.isUsable())
8879     return std::make_pair(nullptr, nullptr);
8880 
8881   // Convert to the ptrdiff_t, if original type is pointer.
8882   if (VarType->isAnyPointerType() &&
8883       !SemaRef.Context.hasSameType(
8884           Diff.get()->getType(),
8885           SemaRef.Context.getUnsignedPointerDiffType())) {
8886     Diff = SemaRef.PerformImplicitConversion(
8887         Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(),
8888         AssignmentAction::Converting, /*AllowExplicit=*/true);
8889   }
8890   if (!Diff.isUsable())
8891     return std::make_pair(nullptr, nullptr);
8892 
8893   if (*TestIsLessOp) {
8894     // MinExpr = Lower;
8895     // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
8896     Diff = SemaRef.BuildBinOp(
8897         S, DefaultLoc, BO_Add,
8898         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(),
8899         Diff.get());
8900     if (!Diff.isUsable())
8901       return std::make_pair(nullptr, nullptr);
8902   } else {
8903     // MaxExpr = Upper;
8904     // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
8905     Diff = SemaRef.BuildBinOp(
8906         S, DefaultLoc, BO_Sub,
8907         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
8908         Diff.get());
8909     if (!Diff.isUsable())
8910       return std::make_pair(nullptr, nullptr);
8911   }
8912 
8913   // Convert to the original type.
8914   if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType))
8915     Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType,
8916                                              AssignmentAction::Converting,
8917                                              /*AllowExplicit=*/true);
8918   if (!Diff.isUsable())
8919     return std::make_pair(nullptr, nullptr);
8920 
8921   Sema::TentativeAnalysisScope Trap(SemaRef);
8922   Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false);
8923   if (!Diff.isUsable())
8924     return std::make_pair(nullptr, nullptr);
8925 
8926   if (*TestIsLessOp)
8927     MaxExpr = Diff.get();
8928   else
8929     MinExpr = Diff.get();
8930 
8931   return std::make_pair(MinExpr, MaxExpr);
8932 }
8933 
8934 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const {
8935   if (InitDependOnLC || CondDependOnLC)
8936     return Condition;
8937   return nullptr;
8938 }
8939 
8940 Expr *OpenMPIterationSpaceChecker::buildPreCond(
8941     Scope *S, Expr *Cond,
8942     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8943   // Do not build a precondition when the condition/initialization is dependent
8944   // to prevent pessimistic early loop exit.
8945   // TODO: this can be improved by calculating min/max values but not sure that
8946   // it will be very effective.
8947   if (CondDependOnLC || InitDependOnLC)
8948     return SemaRef
8949         .PerformImplicitConversion(
8950             SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(),
8951             SemaRef.Context.BoolTy, /*Action=*/AssignmentAction::Casting,
8952             /*AllowExplicit=*/true)
8953         .get();
8954 
8955   // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
8956   Sema::TentativeAnalysisScope Trap(SemaRef);
8957 
8958   ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
8959   ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
8960   if (!NewLB.isUsable() || !NewUB.isUsable())
8961     return nullptr;
8962 
8963   ExprResult CondExpr =
8964       SemaRef.BuildBinOp(S, DefaultLoc,
8965                          *TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE)
8966                                        : (TestIsStrictOp ? BO_GT : BO_GE),
8967                          NewLB.get(), NewUB.get());
8968   if (CondExpr.isUsable()) {
8969     if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
8970                                                 SemaRef.Context.BoolTy))
8971       CondExpr = SemaRef.PerformImplicitConversion(
8972           CondExpr.get(), SemaRef.Context.BoolTy,
8973           /*Action=*/AssignmentAction::Casting,
8974           /*AllowExplicit=*/true);
8975   }
8976 
8977   // Otherwise use original loop condition and evaluate it in runtime.
8978   return CondExpr.isUsable() ? CondExpr.get() : Cond;
8979 }
8980 
8981 /// Build reference expression to the counter be used for codegen.
8982 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
8983     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8984     DSAStackTy &DSA) const {
8985   auto *VD = dyn_cast<VarDecl>(LCDecl);
8986   if (!VD) {
8987     VD = SemaRef.OpenMP().isOpenMPCapturedDecl(LCDecl);
8988     DeclRefExpr *Ref = buildDeclRefExpr(
8989         SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
8990     const DSAStackTy::DSAVarData Data =
8991         DSA.getTopDSA(LCDecl, /*FromParent=*/false);
8992     // If the loop control decl is explicitly marked as private, do not mark it
8993     // as captured again.
8994     if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
8995       Captures.insert(std::make_pair(LCRef, Ref));
8996     return Ref;
8997   }
8998   return cast<DeclRefExpr>(LCRef);
8999 }
9000 
9001 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
9002   if (LCDecl && !LCDecl->isInvalidDecl()) {
9003     QualType Type = LCDecl->getType().getNonReferenceType();
9004     VarDecl *PrivateVar = buildVarDecl(
9005         SemaRef, DefaultLoc, Type, LCDecl->getName(),
9006         LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
9007         isa<VarDecl>(LCDecl)
9008             ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
9009             : nullptr);
9010     if (PrivateVar->isInvalidDecl())
9011       return nullptr;
9012     return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
9013   }
9014   return nullptr;
9015 }
9016 
9017 /// Build initialization of the counter to be used for codegen.
9018 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
9019 
9020 /// Build step of the counter be used for codegen.
9021 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
9022 
9023 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
9024     Scope *S, Expr *Counter,
9025     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
9026     Expr *Inc, OverloadedOperatorKind OOK) {
9027   Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
9028   if (!Cnt)
9029     return nullptr;
9030   if (Inc) {
9031     assert((OOK == OO_Plus || OOK == OO_Minus) &&
9032            "Expected only + or - operations for depend clauses.");
9033     BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
9034     Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
9035     if (!Cnt)
9036       return nullptr;
9037   }
9038   QualType VarType = LCDecl->getType().getNonReferenceType();
9039   if (!VarType->isIntegerType() && !VarType->isPointerType() &&
9040       !SemaRef.getLangOpts().CPlusPlus)
9041     return nullptr;
9042   // Upper - Lower
9043   Expr *Upper =
9044       *TestIsLessOp ? Cnt : tryBuildCapture(SemaRef, LB, Captures).get();
9045   Expr *Lower =
9046       *TestIsLessOp ? tryBuildCapture(SemaRef, LB, Captures).get() : Cnt;
9047   if (!Upper || !Lower)
9048     return nullptr;
9049 
9050   ExprResult Diff = calculateNumIters(
9051       SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
9052       /*TestIsStrictOp=*/false, /*RoundToStep=*/false, Captures);
9053   if (!Diff.isUsable())
9054     return nullptr;
9055 
9056   return Diff.get();
9057 }
9058 } // namespace
9059 
9060 void SemaOpenMP::ActOnOpenMPLoopInitialization(SourceLocation ForLoc,
9061                                                Stmt *Init) {
9062   assert(getLangOpts().OpenMP && "OpenMP is not active.");
9063   assert(Init && "Expected loop in canonical form.");
9064   unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
9065   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
9066   if (AssociatedLoops == 0 || !isOpenMPLoopDirective(DKind))
9067     return;
9068 
9069   DSAStack->loopStart();
9070   llvm::SmallPtrSet<const Decl *, 1> EmptyDeclSet;
9071   OpenMPIterationSpaceChecker ISC(SemaRef, /*SupportsNonRectangular=*/true,
9072                                   *DSAStack, ForLoc, EmptyDeclSet);
9073   if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
9074     if (ValueDecl *D = ISC.getLoopDecl()) {
9075       auto *VD = dyn_cast<VarDecl>(D);
9076       DeclRefExpr *PrivateRef = nullptr;
9077       if (!VD) {
9078         if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
9079           VD = Private;
9080         } else {
9081           PrivateRef = buildCapture(SemaRef, D, ISC.getLoopDeclRefExpr(),
9082                                     /*WithInit=*/false);
9083           VD = cast<VarDecl>(PrivateRef->getDecl());
9084         }
9085       }
9086       DSAStack->addLoopControlVariable(D, VD);
9087       const Decl *LD = DSAStack->getPossiblyLoopCounter();
9088       if (LD != D->getCanonicalDecl()) {
9089         DSAStack->resetPossibleLoopCounter();
9090         if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
9091           SemaRef.MarkDeclarationsReferencedInExpr(buildDeclRefExpr(
9092               SemaRef, const_cast<VarDecl *>(Var),
9093               Var->getType().getNonLValueExprType(getASTContext()), ForLoc,
9094               /*RefersToCapture=*/true));
9095       }
9096       // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
9097       // Referenced in a Construct, C/C++]. The loop iteration variable in the
9098       // associated for-loop of a simd construct with just one associated
9099       // for-loop may be listed in a linear clause with a constant-linear-step
9100       // that is the increment of the associated for-loop. The loop iteration
9101       // variable(s) in the associated for-loop(s) of a for or parallel for
9102       // construct may be listed in a private or lastprivate clause.
9103       DSAStackTy::DSAVarData DVar =
9104           DSAStack->getTopDSA(D, /*FromParent=*/false);
9105       // If LoopVarRefExpr is nullptr it means the corresponding loop variable
9106       // is declared in the loop and it is predetermined as a private.
9107       Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
9108       OpenMPClauseKind PredeterminedCKind =
9109           isOpenMPSimdDirective(DKind)
9110               ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
9111               : OMPC_private;
9112       auto IsOpenMPTaskloopDirective = [](OpenMPDirectiveKind DK) {
9113         return getLeafConstructsOrSelf(DK).back() == OMPD_taskloop;
9114       };
9115       if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
9116             DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
9117             (getLangOpts().OpenMP <= 45 ||
9118              (DVar.CKind != OMPC_lastprivate && DVar.CKind != OMPC_private))) ||
9119            ((isOpenMPWorksharingDirective(DKind) ||
9120              IsOpenMPTaskloopDirective(DKind) ||
9121              isOpenMPDistributeDirective(DKind)) &&
9122             !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
9123             DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
9124           (DVar.CKind != OMPC_private || DVar.RefExpr)) {
9125         Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
9126             << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind)
9127             << getOpenMPClauseName(PredeterminedCKind);
9128         if (DVar.RefExpr == nullptr)
9129           DVar.CKind = PredeterminedCKind;
9130         reportOriginalDsa(SemaRef, DSAStack, D, DVar, /*IsLoopIterVar=*/true);
9131       } else if (LoopDeclRefExpr) {
9132         // Make the loop iteration variable private (for worksharing
9133         // constructs), linear (for simd directives with the only one
9134         // associated loop) or lastprivate (for simd directives with several
9135         // collapsed or ordered loops).
9136         if (DVar.CKind == OMPC_unknown)
9137           DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, PrivateRef);
9138       }
9139     }
9140   }
9141   DSAStack->setAssociatedLoops(AssociatedLoops - 1);
9142 }
9143 
9144 namespace {
9145 // Utility for OpenMP doacross clause kind
9146 class OMPDoacrossKind {
9147 public:
9148   bool isSource(const OMPDoacrossClause *C) {
9149     return C->getDependenceType() == OMPC_DOACROSS_source ||
9150            C->getDependenceType() == OMPC_DOACROSS_source_omp_cur_iteration;
9151   }
9152   bool isSink(const OMPDoacrossClause *C) {
9153     return C->getDependenceType() == OMPC_DOACROSS_sink;
9154   }
9155   bool isSinkIter(const OMPDoacrossClause *C) {
9156     return C->getDependenceType() == OMPC_DOACROSS_sink_omp_cur_iteration;
9157   }
9158 };
9159 } // namespace
9160 /// Called on a for stmt to check and extract its iteration space
9161 /// for further processing (such as collapsing).
9162 static bool checkOpenMPIterationSpace(
9163     OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
9164     unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
9165     unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
9166     Expr *OrderedLoopCountExpr,
9167     SemaOpenMP::VarsWithInheritedDSAType &VarsWithImplicitDSA,
9168     llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,
9169     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
9170     const llvm::SmallPtrSetImpl<const Decl *> &CollapsedLoopVarDecls) {
9171   bool SupportsNonRectangular = !isOpenMPLoopTransformationDirective(DKind);
9172   // OpenMP [2.9.1, Canonical Loop Form]
9173   //   for (init-expr; test-expr; incr-expr) structured-block
9174   //   for (range-decl: range-expr) structured-block
9175   if (auto *CanonLoop = dyn_cast_or_null<OMPCanonicalLoop>(S))
9176     S = CanonLoop->getLoopStmt();
9177   auto *For = dyn_cast_or_null<ForStmt>(S);
9178   auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
9179   // Ranged for is supported only in OpenMP 5.0.
9180   if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) {
9181     SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
9182         << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
9183         << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
9184         << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
9185     if (TotalNestedLoopCount > 1) {
9186       if (CollapseLoopCountExpr && OrderedLoopCountExpr)
9187         SemaRef.Diag(DSA.getConstructLoc(),
9188                      diag::note_omp_collapse_ordered_expr)
9189             << 2 << CollapseLoopCountExpr->getSourceRange()
9190             << OrderedLoopCountExpr->getSourceRange();
9191       else if (CollapseLoopCountExpr)
9192         SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
9193                      diag::note_omp_collapse_ordered_expr)
9194             << 0 << CollapseLoopCountExpr->getSourceRange();
9195       else if (OrderedLoopCountExpr)
9196         SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
9197                      diag::note_omp_collapse_ordered_expr)
9198             << 1 << OrderedLoopCountExpr->getSourceRange();
9199     }
9200     return true;
9201   }
9202   assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&
9203          "No loop body.");
9204   // Postpone analysis in dependent contexts for ranged for loops.
9205   if (CXXFor && SemaRef.CurContext->isDependentContext())
9206     return false;
9207 
9208   OpenMPIterationSpaceChecker ISC(SemaRef, SupportsNonRectangular, DSA,
9209                                   For ? For->getForLoc() : CXXFor->getForLoc(),
9210                                   CollapsedLoopVarDecls);
9211 
9212   // Check init.
9213   Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt();
9214   if (ISC.checkAndSetInit(Init))
9215     return true;
9216 
9217   bool HasErrors = false;
9218 
9219   // Check loop variable's type.
9220   if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
9221     // OpenMP [2.6, Canonical Loop Form]
9222     // Var is one of the following:
9223     //   A variable of signed or unsigned integer type.
9224     //   For C++, a variable of a random access iterator type.
9225     //   For C, a variable of a pointer type.
9226     QualType VarType = LCDecl->getType().getNonReferenceType();
9227     if (!VarType->isDependentType() && !VarType->isIntegerType() &&
9228         !VarType->isPointerType() &&
9229         !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
9230       SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
9231           << SemaRef.getLangOpts().CPlusPlus;
9232       HasErrors = true;
9233     }
9234 
9235     // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
9236     // a Construct
9237     // The loop iteration variable(s) in the associated for-loop(s) of a for or
9238     // parallel for construct is (are) private.
9239     // The loop iteration variable in the associated for-loop of a simd
9240     // construct with just one associated for-loop is linear with a
9241     // constant-linear-step that is the increment of the associated for-loop.
9242     // Exclude loop var from the list of variables with implicitly defined data
9243     // sharing attributes.
9244     VarsWithImplicitDSA.erase(LCDecl);
9245 
9246     assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
9247 
9248     // Check test-expr.
9249     HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
9250 
9251     // Check incr-expr.
9252     HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
9253   }
9254 
9255   if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
9256     return HasErrors;
9257 
9258   // Build the loop's iteration space representation.
9259   ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
9260       DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
9261   ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
9262       ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
9263                              (isOpenMPWorksharingDirective(DKind) ||
9264                               isOpenMPGenericLoopDirective(DKind) ||
9265                               isOpenMPTaskLoopDirective(DKind) ||
9266                               isOpenMPDistributeDirective(DKind) ||
9267                               isOpenMPLoopTransformationDirective(DKind)),
9268                              Captures);
9269   ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
9270       ISC.buildCounterVar(Captures, DSA);
9271   ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
9272       ISC.buildPrivateCounterVar();
9273   ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
9274   ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
9275   ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
9276   ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
9277       ISC.getConditionSrcRange();
9278   ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
9279       ISC.getIncrementSrcRange();
9280   ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
9281   ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
9282       ISC.isStrictTestOp();
9283   std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
9284            ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
9285       ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
9286   ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
9287       ISC.buildFinalCondition(DSA.getCurScope());
9288   ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
9289       ISC.doesInitDependOnLC();
9290   ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
9291       ISC.doesCondDependOnLC();
9292   ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
9293       ISC.getLoopDependentIdx();
9294 
9295   HasErrors |=
9296       (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr ||
9297        ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr ||
9298        ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr ||
9299        ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr ||
9300        ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr ||
9301        ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr);
9302   if (!HasErrors && DSA.isOrderedRegion()) {
9303     if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
9304       if (CurrentNestedLoopCount <
9305           DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
9306         DSA.getOrderedRegionParam().second->setLoopNumIterations(
9307             CurrentNestedLoopCount,
9308             ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
9309         DSA.getOrderedRegionParam().second->setLoopCounter(
9310             CurrentNestedLoopCount,
9311             ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
9312       }
9313     }
9314     for (auto &Pair : DSA.getDoacrossDependClauses()) {
9315       auto *DependC = dyn_cast<OMPDependClause>(Pair.first);
9316       auto *DoacrossC = dyn_cast<OMPDoacrossClause>(Pair.first);
9317       unsigned NumLoops =
9318           DependC ? DependC->getNumLoops() : DoacrossC->getNumLoops();
9319       if (CurrentNestedLoopCount >= NumLoops) {
9320         // Erroneous case - clause has some problems.
9321         continue;
9322       }
9323       if (DependC && DependC->getDependencyKind() == OMPC_DEPEND_sink &&
9324           Pair.second.size() <= CurrentNestedLoopCount) {
9325         // Erroneous case - clause has some problems.
9326         DependC->setLoopData(CurrentNestedLoopCount, nullptr);
9327         continue;
9328       }
9329       OMPDoacrossKind ODK;
9330       if (DoacrossC && ODK.isSink(DoacrossC) &&
9331           Pair.second.size() <= CurrentNestedLoopCount) {
9332         // Erroneous case - clause has some problems.
9333         DoacrossC->setLoopData(CurrentNestedLoopCount, nullptr);
9334         continue;
9335       }
9336       Expr *CntValue;
9337       SourceLocation DepLoc =
9338           DependC ? DependC->getDependencyLoc() : DoacrossC->getDependenceLoc();
9339       if ((DependC && DependC->getDependencyKind() == OMPC_DEPEND_source) ||
9340           (DoacrossC && ODK.isSource(DoacrossC)))
9341         CntValue = ISC.buildOrderedLoopData(
9342             DSA.getCurScope(),
9343             ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9344             DepLoc);
9345       else if (DoacrossC && ODK.isSinkIter(DoacrossC)) {
9346         Expr *Cnt = SemaRef
9347                         .DefaultLvalueConversion(
9348                             ResultIterSpaces[CurrentNestedLoopCount].CounterVar)
9349                         .get();
9350         if (!Cnt)
9351           continue;
9352         // build CounterVar - 1
9353         Expr *Inc =
9354             SemaRef.ActOnIntegerConstant(DoacrossC->getColonLoc(), /*Val=*/1)
9355                 .get();
9356         CntValue = ISC.buildOrderedLoopData(
9357             DSA.getCurScope(),
9358             ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9359             DepLoc, Inc, clang::OO_Minus);
9360       } else
9361         CntValue = ISC.buildOrderedLoopData(
9362             DSA.getCurScope(),
9363             ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9364             DepLoc, Pair.second[CurrentNestedLoopCount].first,
9365             Pair.second[CurrentNestedLoopCount].second);
9366       if (DependC)
9367         DependC->setLoopData(CurrentNestedLoopCount, CntValue);
9368       else
9369         DoacrossC->setLoopData(CurrentNestedLoopCount, CntValue);
9370     }
9371   }
9372 
9373   return HasErrors;
9374 }
9375 
9376 /// Build 'VarRef = Start.
9377 static ExprResult
9378 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
9379                  ExprResult Start, bool IsNonRectangularLB,
9380                  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9381   // Build 'VarRef = Start.
9382   ExprResult NewStart = IsNonRectangularLB
9383                             ? Start.get()
9384                             : tryBuildCapture(SemaRef, Start.get(), Captures);
9385   if (!NewStart.isUsable())
9386     return ExprError();
9387   if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
9388                                    VarRef.get()->getType())) {
9389     NewStart = SemaRef.PerformImplicitConversion(
9390         NewStart.get(), VarRef.get()->getType(), AssignmentAction::Converting,
9391         /*AllowExplicit=*/true);
9392     if (!NewStart.isUsable())
9393       return ExprError();
9394   }
9395 
9396   ExprResult Init =
9397       SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
9398   return Init;
9399 }
9400 
9401 /// Build 'VarRef = Start + Iter * Step'.
9402 static ExprResult buildCounterUpdate(
9403     Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
9404     ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
9405     bool IsNonRectangularLB,
9406     llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
9407   // Add parentheses (for debugging purposes only).
9408   Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
9409   if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
9410       !Step.isUsable())
9411     return ExprError();
9412 
9413   ExprResult NewStep = Step;
9414   if (Captures)
9415     NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
9416   if (NewStep.isInvalid())
9417     return ExprError();
9418   ExprResult Update =
9419       SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
9420   if (!Update.isUsable())
9421     return ExprError();
9422 
9423   // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
9424   // 'VarRef = Start (+|-) Iter * Step'.
9425   if (!Start.isUsable())
9426     return ExprError();
9427   ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get());
9428   if (!NewStart.isUsable())
9429     return ExprError();
9430   if (Captures && !IsNonRectangularLB)
9431     NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
9432   if (NewStart.isInvalid())
9433     return ExprError();
9434 
9435   // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
9436   ExprResult SavedUpdate = Update;
9437   ExprResult UpdateVal;
9438   if (VarRef.get()->getType()->isOverloadableType() ||
9439       NewStart.get()->getType()->isOverloadableType() ||
9440       Update.get()->getType()->isOverloadableType()) {
9441     Sema::TentativeAnalysisScope Trap(SemaRef);
9442 
9443     Update =
9444         SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
9445     if (Update.isUsable()) {
9446       UpdateVal =
9447           SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
9448                              VarRef.get(), SavedUpdate.get());
9449       if (UpdateVal.isUsable()) {
9450         Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
9451                                             UpdateVal.get());
9452       }
9453     }
9454   }
9455 
9456   // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
9457   if (!Update.isUsable() || !UpdateVal.isUsable()) {
9458     Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
9459                                 NewStart.get(), SavedUpdate.get());
9460     if (!Update.isUsable())
9461       return ExprError();
9462 
9463     if (!SemaRef.Context.hasSameType(Update.get()->getType(),
9464                                      VarRef.get()->getType())) {
9465       Update = SemaRef.PerformImplicitConversion(
9466           Update.get(), VarRef.get()->getType(), AssignmentAction::Converting,
9467           /*AllowExplicit=*/true);
9468       if (!Update.isUsable())
9469         return ExprError();
9470     }
9471 
9472     Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
9473   }
9474   return Update;
9475 }
9476 
9477 /// Convert integer expression \a E to make it have at least \a Bits
9478 /// bits.
9479 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
9480   if (E == nullptr)
9481     return ExprError();
9482   ASTContext &C = SemaRef.Context;
9483   QualType OldType = E->getType();
9484   unsigned HasBits = C.getTypeSize(OldType);
9485   if (HasBits >= Bits)
9486     return ExprResult(E);
9487   // OK to convert to signed, because new type has more bits than old.
9488   QualType NewType = C.getIntTypeForBitwidth(Bits, /*Signed=*/true);
9489   return SemaRef.PerformImplicitConversion(
9490       E, NewType, AssignmentAction::Converting, /*AllowExplicit=*/true);
9491 }
9492 
9493 /// Check if the given expression \a E is a constant integer that fits
9494 /// into \a Bits bits.
9495 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
9496   if (E == nullptr)
9497     return false;
9498   if (std::optional<llvm::APSInt> Result =
9499           E->getIntegerConstantExpr(SemaRef.Context))
9500     return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits);
9501   return false;
9502 }
9503 
9504 /// Build preinits statement for the given declarations.
9505 static Stmt *buildPreInits(ASTContext &Context,
9506                            MutableArrayRef<Decl *> PreInits) {
9507   if (!PreInits.empty()) {
9508     return new (Context) DeclStmt(
9509         DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
9510         SourceLocation(), SourceLocation());
9511   }
9512   return nullptr;
9513 }
9514 
9515 /// Append the \p Item or the content of a CompoundStmt to the list \p
9516 /// TargetList.
9517 ///
9518 /// A CompoundStmt is used as container in case multiple statements need to be
9519 /// stored in lieu of using an explicit list. Flattening is necessary because
9520 /// contained DeclStmts need to be visible after the execution of the list. Used
9521 /// for OpenMP pre-init declarations/statements.
9522 static void appendFlattenedStmtList(SmallVectorImpl<Stmt *> &TargetList,
9523                                     Stmt *Item) {
9524   // nullptr represents an empty list.
9525   if (!Item)
9526     return;
9527 
9528   if (auto *CS = dyn_cast<CompoundStmt>(Item))
9529     llvm::append_range(TargetList, CS->body());
9530   else
9531     TargetList.push_back(Item);
9532 }
9533 
9534 /// Build preinits statement for the given declarations.
9535 static Stmt *
9536 buildPreInits(ASTContext &Context,
9537               const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9538   if (!Captures.empty()) {
9539     SmallVector<Decl *, 16> PreInits;
9540     for (const auto &Pair : Captures)
9541       PreInits.push_back(Pair.second->getDecl());
9542     return buildPreInits(Context, PreInits);
9543   }
9544   return nullptr;
9545 }
9546 
9547 /// Build pre-init statement for the given statements.
9548 static Stmt *buildPreInits(ASTContext &Context, ArrayRef<Stmt *> PreInits) {
9549   if (PreInits.empty())
9550     return nullptr;
9551 
9552   SmallVector<Stmt *> Stmts;
9553   for (Stmt *S : PreInits)
9554     appendFlattenedStmtList(Stmts, S);
9555   return CompoundStmt::Create(Context, PreInits, FPOptionsOverride(), {}, {});
9556 }
9557 
9558 /// Build postupdate expression for the given list of postupdates expressions.
9559 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
9560   Expr *PostUpdate = nullptr;
9561   if (!PostUpdates.empty()) {
9562     for (Expr *E : PostUpdates) {
9563       Expr *ConvE = S.BuildCStyleCastExpr(
9564                          E->getExprLoc(),
9565                          S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
9566                          E->getExprLoc(), E)
9567                         .get();
9568       PostUpdate = PostUpdate
9569                        ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
9570                                               PostUpdate, ConvE)
9571                              .get()
9572                        : ConvE;
9573     }
9574   }
9575   return PostUpdate;
9576 }
9577 
9578 /// Look for variables declared in the body parts of a for-loop nest.  Used
9579 /// for verifying loop nest structure before performing a loop collapse
9580 /// operation.
9581 class ForVarDeclFinder : public DynamicRecursiveASTVisitor {
9582   int NestingDepth = 0;
9583   llvm::SmallPtrSetImpl<const Decl *> &VarDecls;
9584 
9585 public:
9586   explicit ForVarDeclFinder(llvm::SmallPtrSetImpl<const Decl *> &VD)
9587       : VarDecls(VD) {}
9588 
9589   bool VisitForStmt(ForStmt *F) override {
9590     ++NestingDepth;
9591     TraverseStmt(F->getBody());
9592     --NestingDepth;
9593     return false;
9594   }
9595 
9596   bool VisitCXXForRangeStmt(CXXForRangeStmt *RF) override {
9597     ++NestingDepth;
9598     TraverseStmt(RF->getBody());
9599     --NestingDepth;
9600     return false;
9601   }
9602 
9603   bool VisitVarDecl(VarDecl *D) override {
9604     Decl *C = D->getCanonicalDecl();
9605     if (NestingDepth > 0)
9606       VarDecls.insert(C);
9607     return true;
9608   }
9609 };
9610 
9611 /// Called on a for stmt to check itself and nested loops (if any).
9612 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
9613 /// number of collapsed loops otherwise.
9614 static unsigned
9615 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
9616                 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
9617                 DSAStackTy &DSA,
9618                 SemaOpenMP::VarsWithInheritedDSAType &VarsWithImplicitDSA,
9619                 OMPLoopBasedDirective::HelperExprs &Built) {
9620   unsigned NestedLoopCount = 1;
9621   bool SupportsNonPerfectlyNested = (SemaRef.LangOpts.OpenMP >= 50) &&
9622                                     !isOpenMPLoopTransformationDirective(DKind);
9623   llvm::SmallPtrSet<const Decl *, 4> CollapsedLoopVarDecls;
9624 
9625   if (CollapseLoopCountExpr) {
9626     // Found 'collapse' clause - calculate collapse number.
9627     Expr::EvalResult Result;
9628     if (!CollapseLoopCountExpr->isValueDependent() &&
9629         CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
9630       NestedLoopCount = Result.Val.getInt().getLimitedValue();
9631 
9632       ForVarDeclFinder FVDF{CollapsedLoopVarDecls};
9633       FVDF.TraverseStmt(AStmt);
9634     } else {
9635       Built.clear(/*Size=*/1);
9636       return 1;
9637     }
9638   }
9639   unsigned OrderedLoopCount = 1;
9640   if (OrderedLoopCountExpr) {
9641     // Found 'ordered' clause - calculate collapse number.
9642     Expr::EvalResult EVResult;
9643     if (!OrderedLoopCountExpr->isValueDependent() &&
9644         OrderedLoopCountExpr->EvaluateAsInt(EVResult,
9645                                             SemaRef.getASTContext())) {
9646       llvm::APSInt Result = EVResult.Val.getInt();
9647       if (Result.getLimitedValue() < NestedLoopCount) {
9648         SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
9649                      diag::err_omp_wrong_ordered_loop_count)
9650             << OrderedLoopCountExpr->getSourceRange();
9651         SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
9652                      diag::note_collapse_loop_count)
9653             << CollapseLoopCountExpr->getSourceRange();
9654       }
9655       OrderedLoopCount = Result.getLimitedValue();
9656     } else {
9657       Built.clear(/*Size=*/1);
9658       return 1;
9659     }
9660   }
9661   // This is helper routine for loop directives (e.g., 'for', 'simd',
9662   // 'for simd', etc.).
9663   llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
9664   unsigned NumLoops = std::max(OrderedLoopCount, NestedLoopCount);
9665   SmallVector<LoopIterationSpace, 4> IterSpaces(NumLoops);
9666   if (!OMPLoopBasedDirective::doForAllLoops(
9667           AStmt->IgnoreContainers(!isOpenMPLoopTransformationDirective(DKind)),
9668           SupportsNonPerfectlyNested, NumLoops,
9669           [DKind, &SemaRef, &DSA, NumLoops, NestedLoopCount,
9670            CollapseLoopCountExpr, OrderedLoopCountExpr, &VarsWithImplicitDSA,
9671            &IterSpaces, &Captures,
9672            &CollapsedLoopVarDecls](unsigned Cnt, Stmt *CurStmt) {
9673             if (checkOpenMPIterationSpace(
9674                     DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
9675                     NumLoops, CollapseLoopCountExpr, OrderedLoopCountExpr,
9676                     VarsWithImplicitDSA, IterSpaces, Captures,
9677                     CollapsedLoopVarDecls))
9678               return true;
9679             if (Cnt > 0 && Cnt >= NestedLoopCount &&
9680                 IterSpaces[Cnt].CounterVar) {
9681               // Handle initialization of captured loop iterator variables.
9682               auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
9683               if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
9684                 Captures[DRE] = DRE;
9685               }
9686             }
9687             return false;
9688           },
9689           [&SemaRef, &Captures](OMPLoopTransformationDirective *Transform) {
9690             Stmt *DependentPreInits = Transform->getPreInits();
9691             if (!DependentPreInits)
9692               return;
9693 
9694             // Search for pre-init declared variables that need to be captured
9695             // to be referenceable inside the directive.
9696             SmallVector<Stmt *> Constituents;
9697             appendFlattenedStmtList(Constituents, DependentPreInits);
9698             for (Stmt *S : Constituents) {
9699               if (auto *DC = dyn_cast<DeclStmt>(S)) {
9700                 for (Decl *C : DC->decls()) {
9701                   auto *D = cast<VarDecl>(C);
9702                   DeclRefExpr *Ref = buildDeclRefExpr(
9703                       SemaRef, D, D->getType().getNonReferenceType(),
9704                       Transform->getBeginLoc());
9705                   Captures[Ref] = Ref;
9706                 }
9707               }
9708             }
9709           }))
9710     return 0;
9711 
9712   Built.clear(/*size=*/NestedLoopCount);
9713 
9714   if (SemaRef.CurContext->isDependentContext())
9715     return NestedLoopCount;
9716 
9717   // An example of what is generated for the following code:
9718   //
9719   //   #pragma omp simd collapse(2) ordered(2)
9720   //   for (i = 0; i < NI; ++i)
9721   //     for (k = 0; k < NK; ++k)
9722   //       for (j = J0; j < NJ; j+=2) {
9723   //         <loop body>
9724   //       }
9725   //
9726   // We generate the code below.
9727   // Note: the loop body may be outlined in CodeGen.
9728   // Note: some counters may be C++ classes, operator- is used to find number of
9729   // iterations and operator+= to calculate counter value.
9730   // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
9731   // or i64 is currently supported).
9732   //
9733   //   #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
9734   //   for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
9735   //     .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
9736   //     .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
9737   //     // similar updates for vars in clauses (e.g. 'linear')
9738   //     <loop body (using local i and j)>
9739   //   }
9740   //   i = NI; // assign final values of counters
9741   //   j = NJ;
9742   //
9743 
9744   // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
9745   // the iteration counts of the collapsed for loops.
9746   // Precondition tests if there is at least one iteration (all conditions are
9747   // true).
9748   auto PreCond = ExprResult(IterSpaces[0].PreCond);
9749   Expr *N0 = IterSpaces[0].NumIterations;
9750   ExprResult LastIteration32 = widenIterationCount(
9751       /*Bits=*/32,
9752       SemaRef
9753           .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
9754                                      AssignmentAction::Converting,
9755                                      /*AllowExplicit=*/true)
9756           .get(),
9757       SemaRef);
9758   ExprResult LastIteration64 = widenIterationCount(
9759       /*Bits=*/64,
9760       SemaRef
9761           .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
9762                                      AssignmentAction::Converting,
9763                                      /*AllowExplicit=*/true)
9764           .get(),
9765       SemaRef);
9766 
9767   if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
9768     return NestedLoopCount;
9769 
9770   ASTContext &C = SemaRef.Context;
9771   bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
9772 
9773   Scope *CurScope = DSA.getCurScope();
9774   for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
9775     if (PreCond.isUsable()) {
9776       PreCond =
9777           SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
9778                              PreCond.get(), IterSpaces[Cnt].PreCond);
9779     }
9780     Expr *N = IterSpaces[Cnt].NumIterations;
9781     SourceLocation Loc = N->getExprLoc();
9782     AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
9783     if (LastIteration32.isUsable())
9784       LastIteration32 = SemaRef.BuildBinOp(
9785           CurScope, Loc, BO_Mul, LastIteration32.get(),
9786           SemaRef
9787               .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
9788                                          AssignmentAction::Converting,
9789                                          /*AllowExplicit=*/true)
9790               .get());
9791     if (LastIteration64.isUsable())
9792       LastIteration64 = SemaRef.BuildBinOp(
9793           CurScope, Loc, BO_Mul, LastIteration64.get(),
9794           SemaRef
9795               .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
9796                                          AssignmentAction::Converting,
9797                                          /*AllowExplicit=*/true)
9798               .get());
9799   }
9800 
9801   // Choose either the 32-bit or 64-bit version.
9802   ExprResult LastIteration = LastIteration64;
9803   if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
9804       (LastIteration32.isUsable() &&
9805        C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
9806        (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
9807         fitsInto(
9808             /*Bits=*/32,
9809             LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
9810             LastIteration64.get(), SemaRef))))
9811     LastIteration = LastIteration32;
9812   QualType VType = LastIteration.get()->getType();
9813   QualType RealVType = VType;
9814   QualType StrideVType = VType;
9815   if (isOpenMPTaskLoopDirective(DKind)) {
9816     VType =
9817         SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
9818     StrideVType =
9819         SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
9820   }
9821 
9822   if (!LastIteration.isUsable())
9823     return 0;
9824 
9825   // Save the number of iterations.
9826   ExprResult NumIterations = LastIteration;
9827   {
9828     LastIteration = SemaRef.BuildBinOp(
9829         CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
9830         LastIteration.get(),
9831         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9832     if (!LastIteration.isUsable())
9833       return 0;
9834   }
9835 
9836   // Calculate the last iteration number beforehand instead of doing this on
9837   // each iteration. Do not do this if the number of iterations may be kfold-ed.
9838   bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context);
9839   ExprResult CalcLastIteration;
9840   if (!IsConstant) {
9841     ExprResult SaveRef =
9842         tryBuildCapture(SemaRef, LastIteration.get(), Captures);
9843     LastIteration = SaveRef;
9844 
9845     // Prepare SaveRef + 1.
9846     NumIterations = SemaRef.BuildBinOp(
9847         CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
9848         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9849     if (!NumIterations.isUsable())
9850       return 0;
9851   }
9852 
9853   SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
9854 
9855   // Build variables passed into runtime, necessary for worksharing directives.
9856   ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
9857   if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
9858       isOpenMPDistributeDirective(DKind) ||
9859       isOpenMPGenericLoopDirective(DKind) ||
9860       isOpenMPLoopTransformationDirective(DKind)) {
9861     // Lower bound variable, initialized with zero.
9862     VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
9863     LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
9864     SemaRef.AddInitializerToDecl(LBDecl,
9865                                  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9866                                  /*DirectInit=*/false);
9867 
9868     // Upper bound variable, initialized with last iteration number.
9869     VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
9870     UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
9871     SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
9872                                  /*DirectInit=*/false);
9873 
9874     // A 32-bit variable-flag where runtime returns 1 for the last iteration.
9875     // This will be used to implement clause 'lastprivate'.
9876     QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
9877     VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
9878     IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
9879     SemaRef.AddInitializerToDecl(ILDecl,
9880                                  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9881                                  /*DirectInit=*/false);
9882 
9883     // Stride variable returned by runtime (we initialize it to 1 by default).
9884     VarDecl *STDecl =
9885         buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
9886     ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
9887     SemaRef.AddInitializerToDecl(STDecl,
9888                                  SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
9889                                  /*DirectInit=*/false);
9890 
9891     // Build expression: UB = min(UB, LastIteration)
9892     // It is necessary for CodeGen of directives with static scheduling.
9893     ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
9894                                                 UB.get(), LastIteration.get());
9895     ExprResult CondOp = SemaRef.ActOnConditionalOp(
9896         LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
9897         LastIteration.get(), UB.get());
9898     EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
9899                              CondOp.get());
9900     EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue=*/false);
9901 
9902     // If we have a combined directive that combines 'distribute', 'for' or
9903     // 'simd' we need to be able to access the bounds of the schedule of the
9904     // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
9905     // by scheduling 'distribute' have to be passed to the schedule of 'for'.
9906     if (isOpenMPLoopBoundSharingDirective(DKind)) {
9907       // Lower bound variable, initialized with zero.
9908       VarDecl *CombLBDecl =
9909           buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
9910       CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
9911       SemaRef.AddInitializerToDecl(
9912           CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9913           /*DirectInit=*/false);
9914 
9915       // Upper bound variable, initialized with last iteration number.
9916       VarDecl *CombUBDecl =
9917           buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
9918       CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
9919       SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
9920                                    /*DirectInit=*/false);
9921 
9922       ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
9923           CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
9924       ExprResult CombCondOp =
9925           SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
9926                                      LastIteration.get(), CombUB.get());
9927       CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
9928                                    CombCondOp.get());
9929       CombEUB =
9930           SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue=*/false);
9931 
9932       const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
9933       // We expect to have at least 2 more parameters than the 'parallel'
9934       // directive does - the lower and upper bounds of the previous schedule.
9935       assert(CD->getNumParams() >= 4 &&
9936              "Unexpected number of parameters in loop combined directive");
9937 
9938       // Set the proper type for the bounds given what we learned from the
9939       // enclosed loops.
9940       ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
9941       ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
9942 
9943       // Previous lower and upper bounds are obtained from the region
9944       // parameters.
9945       PrevLB =
9946           buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
9947       PrevUB =
9948           buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
9949     }
9950   }
9951 
9952   // Build the iteration variable and its initialization before loop.
9953   ExprResult IV;
9954   ExprResult Init, CombInit;
9955   {
9956     VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
9957     IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
9958     Expr *RHS = (isOpenMPWorksharingDirective(DKind) ||
9959                  isOpenMPGenericLoopDirective(DKind) ||
9960                  isOpenMPTaskLoopDirective(DKind) ||
9961                  isOpenMPDistributeDirective(DKind) ||
9962                  isOpenMPLoopTransformationDirective(DKind))
9963                     ? LB.get()
9964                     : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
9965     Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
9966     Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue=*/false);
9967 
9968     if (isOpenMPLoopBoundSharingDirective(DKind)) {
9969       Expr *CombRHS =
9970           (isOpenMPWorksharingDirective(DKind) ||
9971            isOpenMPGenericLoopDirective(DKind) ||
9972            isOpenMPTaskLoopDirective(DKind) ||
9973            isOpenMPDistributeDirective(DKind))
9974               ? CombLB.get()
9975               : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
9976       CombInit =
9977           SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
9978       CombInit =
9979           SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue=*/false);
9980     }
9981   }
9982 
9983   bool UseStrictCompare =
9984       RealVType->hasUnsignedIntegerRepresentation() &&
9985       llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
9986         return LIS.IsStrictCompare;
9987       });
9988   // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
9989   // unsigned IV)) for worksharing loops.
9990   SourceLocation CondLoc = AStmt->getBeginLoc();
9991   Expr *BoundUB = UB.get();
9992   if (UseStrictCompare) {
9993     BoundUB =
9994         SemaRef
9995             .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
9996                         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9997             .get();
9998     BoundUB =
9999         SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue=*/false).get();
10000   }
10001   ExprResult Cond =
10002       (isOpenMPWorksharingDirective(DKind) ||
10003        isOpenMPGenericLoopDirective(DKind) ||
10004        isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind) ||
10005        isOpenMPLoopTransformationDirective(DKind))
10006           ? SemaRef.BuildBinOp(CurScope, CondLoc,
10007                                UseStrictCompare ? BO_LT : BO_LE, IV.get(),
10008                                BoundUB)
10009           : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
10010                                NumIterations.get());
10011   ExprResult CombDistCond;
10012   if (isOpenMPLoopBoundSharingDirective(DKind)) {
10013     CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
10014                                       NumIterations.get());
10015   }
10016 
10017   ExprResult CombCond;
10018   if (isOpenMPLoopBoundSharingDirective(DKind)) {
10019     Expr *BoundCombUB = CombUB.get();
10020     if (UseStrictCompare) {
10021       BoundCombUB =
10022           SemaRef
10023               .BuildBinOp(
10024                   CurScope, CondLoc, BO_Add, BoundCombUB,
10025                   SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
10026               .get();
10027       BoundCombUB =
10028           SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue=*/false)
10029               .get();
10030     }
10031     CombCond =
10032         SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
10033                            IV.get(), BoundCombUB);
10034   }
10035   // Loop increment (IV = IV + 1)
10036   SourceLocation IncLoc = AStmt->getBeginLoc();
10037   ExprResult Inc =
10038       SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
10039                          SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
10040   if (!Inc.isUsable())
10041     return 0;
10042   Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
10043   Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue=*/false);
10044   if (!Inc.isUsable())
10045     return 0;
10046 
10047   // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
10048   // Used for directives with static scheduling.
10049   // In combined construct, add combined version that use CombLB and CombUB
10050   // base variables for the update
10051   ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
10052   if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
10053       isOpenMPGenericLoopDirective(DKind) ||
10054       isOpenMPDistributeDirective(DKind) ||
10055       isOpenMPLoopTransformationDirective(DKind)) {
10056     // LB + ST
10057     NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
10058     if (!NextLB.isUsable())
10059       return 0;
10060     // LB = LB + ST
10061     NextLB =
10062         SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
10063     NextLB =
10064         SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue=*/false);
10065     if (!NextLB.isUsable())
10066       return 0;
10067     // UB + ST
10068     NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
10069     if (!NextUB.isUsable())
10070       return 0;
10071     // UB = UB + ST
10072     NextUB =
10073         SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
10074     NextUB =
10075         SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue=*/false);
10076     if (!NextUB.isUsable())
10077       return 0;
10078     if (isOpenMPLoopBoundSharingDirective(DKind)) {
10079       CombNextLB =
10080           SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
10081       if (!NextLB.isUsable())
10082         return 0;
10083       // LB = LB + ST
10084       CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
10085                                       CombNextLB.get());
10086       CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
10087                                                /*DiscardedValue=*/false);
10088       if (!CombNextLB.isUsable())
10089         return 0;
10090       // UB + ST
10091       CombNextUB =
10092           SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
10093       if (!CombNextUB.isUsable())
10094         return 0;
10095       // UB = UB + ST
10096       CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
10097                                       CombNextUB.get());
10098       CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
10099                                                /*DiscardedValue=*/false);
10100       if (!CombNextUB.isUsable())
10101         return 0;
10102     }
10103   }
10104 
10105   // Create increment expression for distribute loop when combined in a same
10106   // directive with for as IV = IV + ST; ensure upper bound expression based
10107   // on PrevUB instead of NumIterations - used to implement 'for' when found
10108   // in combination with 'distribute', like in 'distribute parallel for'
10109   SourceLocation DistIncLoc = AStmt->getBeginLoc();
10110   ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
10111   if (isOpenMPLoopBoundSharingDirective(DKind)) {
10112     DistCond = SemaRef.BuildBinOp(
10113         CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
10114     assert(DistCond.isUsable() && "distribute cond expr was not built");
10115 
10116     DistInc =
10117         SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
10118     assert(DistInc.isUsable() && "distribute inc expr was not built");
10119     DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
10120                                  DistInc.get());
10121     DistInc =
10122         SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue=*/false);
10123     assert(DistInc.isUsable() && "distribute inc expr was not built");
10124 
10125     // Build expression: UB = min(UB, prevUB) for #for in composite or combined
10126     // construct
10127     ExprResult NewPrevUB = PrevUB;
10128     SourceLocation DistEUBLoc = AStmt->getBeginLoc();
10129     if (!SemaRef.Context.hasSameType(UB.get()->getType(),
10130                                      PrevUB.get()->getType())) {
10131       NewPrevUB = SemaRef.BuildCStyleCastExpr(
10132           DistEUBLoc,
10133           SemaRef.Context.getTrivialTypeSourceInfo(UB.get()->getType()),
10134           DistEUBLoc, NewPrevUB.get());
10135       if (!NewPrevUB.isUsable())
10136         return 0;
10137     }
10138     ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT,
10139                                                 UB.get(), NewPrevUB.get());
10140     ExprResult CondOp = SemaRef.ActOnConditionalOp(
10141         DistEUBLoc, DistEUBLoc, IsUBGreater.get(), NewPrevUB.get(), UB.get());
10142     PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
10143                                  CondOp.get());
10144     PrevEUB =
10145         SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue=*/false);
10146 
10147     // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
10148     // parallel for is in combination with a distribute directive with
10149     // schedule(static, 1)
10150     Expr *BoundPrevUB = PrevUB.get();
10151     if (UseStrictCompare) {
10152       BoundPrevUB =
10153           SemaRef
10154               .BuildBinOp(
10155                   CurScope, CondLoc, BO_Add, BoundPrevUB,
10156                   SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
10157               .get();
10158       BoundPrevUB =
10159           SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue=*/false)
10160               .get();
10161     }
10162     ParForInDistCond =
10163         SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
10164                            IV.get(), BoundPrevUB);
10165   }
10166 
10167   // Build updates and final values of the loop counters.
10168   bool HasErrors = false;
10169   Built.Counters.resize(NestedLoopCount);
10170   Built.Inits.resize(NestedLoopCount);
10171   Built.Updates.resize(NestedLoopCount);
10172   Built.Finals.resize(NestedLoopCount);
10173   Built.DependentCounters.resize(NestedLoopCount);
10174   Built.DependentInits.resize(NestedLoopCount);
10175   Built.FinalsConditions.resize(NestedLoopCount);
10176   {
10177     // We implement the following algorithm for obtaining the
10178     // original loop iteration variable values based on the
10179     // value of the collapsed loop iteration variable IV.
10180     //
10181     // Let n+1 be the number of collapsed loops in the nest.
10182     // Iteration variables (I0, I1, .... In)
10183     // Iteration counts (N0, N1, ... Nn)
10184     //
10185     // Acc = IV;
10186     //
10187     // To compute Ik for loop k, 0 <= k <= n, generate:
10188     //    Prod = N(k+1) * N(k+2) * ... * Nn;
10189     //    Ik = Acc / Prod;
10190     //    Acc -= Ik * Prod;
10191     //
10192     ExprResult Acc = IV;
10193     for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
10194       LoopIterationSpace &IS = IterSpaces[Cnt];
10195       SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
10196       ExprResult Iter;
10197 
10198       // Compute prod
10199       ExprResult Prod = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
10200       for (unsigned int K = Cnt + 1; K < NestedLoopCount; ++K)
10201         Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
10202                                   IterSpaces[K].NumIterations);
10203 
10204       // Iter = Acc / Prod
10205       // If there is at least one more inner loop to avoid
10206       // multiplication by 1.
10207       if (Cnt + 1 < NestedLoopCount)
10208         Iter =
10209             SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, Acc.get(), Prod.get());
10210       else
10211         Iter = Acc;
10212       if (!Iter.isUsable()) {
10213         HasErrors = true;
10214         break;
10215       }
10216 
10217       // Update Acc:
10218       // Acc -= Iter * Prod
10219       // Check if there is at least one more inner loop to avoid
10220       // multiplication by 1.
10221       if (Cnt + 1 < NestedLoopCount)
10222         Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Iter.get(),
10223                                   Prod.get());
10224       else
10225         Prod = Iter;
10226       Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, Acc.get(), Prod.get());
10227 
10228       // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
10229       auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
10230       DeclRefExpr *CounterVar = buildDeclRefExpr(
10231           SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
10232           /*RefersToCapture=*/true);
10233       ExprResult Init =
10234           buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
10235                            IS.CounterInit, IS.IsNonRectangularLB, Captures);
10236       if (!Init.isUsable()) {
10237         HasErrors = true;
10238         break;
10239       }
10240       ExprResult Update = buildCounterUpdate(
10241           SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
10242           IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
10243       if (!Update.isUsable()) {
10244         HasErrors = true;
10245         break;
10246       }
10247 
10248       // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
10249       ExprResult Final =
10250           buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
10251                              IS.CounterInit, IS.NumIterations, IS.CounterStep,
10252                              IS.Subtract, IS.IsNonRectangularLB, &Captures);
10253       if (!Final.isUsable()) {
10254         HasErrors = true;
10255         break;
10256       }
10257 
10258       if (!Update.isUsable() || !Final.isUsable()) {
10259         HasErrors = true;
10260         break;
10261       }
10262       // Save results
10263       Built.Counters[Cnt] = IS.CounterVar;
10264       Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
10265       Built.Inits[Cnt] = Init.get();
10266       Built.Updates[Cnt] = Update.get();
10267       Built.Finals[Cnt] = Final.get();
10268       Built.DependentCounters[Cnt] = nullptr;
10269       Built.DependentInits[Cnt] = nullptr;
10270       Built.FinalsConditions[Cnt] = nullptr;
10271       if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
10272         Built.DependentCounters[Cnt] = Built.Counters[IS.LoopDependentIdx - 1];
10273         Built.DependentInits[Cnt] = Built.Inits[IS.LoopDependentIdx - 1];
10274         Built.FinalsConditions[Cnt] = IS.FinalCondition;
10275       }
10276     }
10277   }
10278 
10279   if (HasErrors)
10280     return 0;
10281 
10282   // Save results
10283   Built.IterationVarRef = IV.get();
10284   Built.LastIteration = LastIteration.get();
10285   Built.NumIterations = NumIterations.get();
10286   Built.CalcLastIteration = SemaRef
10287                                 .ActOnFinishFullExpr(CalcLastIteration.get(),
10288                                                      /*DiscardedValue=*/false)
10289                                 .get();
10290   Built.PreCond = PreCond.get();
10291   Built.PreInits = buildPreInits(C, Captures);
10292   Built.Cond = Cond.get();
10293   Built.Init = Init.get();
10294   Built.Inc = Inc.get();
10295   Built.LB = LB.get();
10296   Built.UB = UB.get();
10297   Built.IL = IL.get();
10298   Built.ST = ST.get();
10299   Built.EUB = EUB.get();
10300   Built.NLB = NextLB.get();
10301   Built.NUB = NextUB.get();
10302   Built.PrevLB = PrevLB.get();
10303   Built.PrevUB = PrevUB.get();
10304   Built.DistInc = DistInc.get();
10305   Built.PrevEUB = PrevEUB.get();
10306   Built.DistCombinedFields.LB = CombLB.get();
10307   Built.DistCombinedFields.UB = CombUB.get();
10308   Built.DistCombinedFields.EUB = CombEUB.get();
10309   Built.DistCombinedFields.Init = CombInit.get();
10310   Built.DistCombinedFields.Cond = CombCond.get();
10311   Built.DistCombinedFields.NLB = CombNextLB.get();
10312   Built.DistCombinedFields.NUB = CombNextUB.get();
10313   Built.DistCombinedFields.DistCond = CombDistCond.get();
10314   Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
10315 
10316   return NestedLoopCount;
10317 }
10318 
10319 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
10320   auto CollapseClauses =
10321       OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
10322   if (CollapseClauses.begin() != CollapseClauses.end())
10323     return (*CollapseClauses.begin())->getNumForLoops();
10324   return nullptr;
10325 }
10326 
10327 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
10328   auto OrderedClauses =
10329       OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
10330   if (OrderedClauses.begin() != OrderedClauses.end())
10331     return (*OrderedClauses.begin())->getNumForLoops();
10332   return nullptr;
10333 }
10334 
10335 static bool checkSimdlenSafelenSpecified(Sema &S,
10336                                          const ArrayRef<OMPClause *> Clauses) {
10337   const OMPSafelenClause *Safelen = nullptr;
10338   const OMPSimdlenClause *Simdlen = nullptr;
10339 
10340   for (const OMPClause *Clause : Clauses) {
10341     if (Clause->getClauseKind() == OMPC_safelen)
10342       Safelen = cast<OMPSafelenClause>(Clause);
10343     else if (Clause->getClauseKind() == OMPC_simdlen)
10344       Simdlen = cast<OMPSimdlenClause>(Clause);
10345     if (Safelen && Simdlen)
10346       break;
10347   }
10348 
10349   if (Simdlen && Safelen) {
10350     const Expr *SimdlenLength = Simdlen->getSimdlen();
10351     const Expr *SafelenLength = Safelen->getSafelen();
10352     if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
10353         SimdlenLength->isInstantiationDependent() ||
10354         SimdlenLength->containsUnexpandedParameterPack())
10355       return false;
10356     if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
10357         SafelenLength->isInstantiationDependent() ||
10358         SafelenLength->containsUnexpandedParameterPack())
10359       return false;
10360     Expr::EvalResult SimdlenResult, SafelenResult;
10361     SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
10362     SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
10363     llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
10364     llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
10365     // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
10366     // If both simdlen and safelen clauses are specified, the value of the
10367     // simdlen parameter must be less than or equal to the value of the safelen
10368     // parameter.
10369     if (SimdlenRes > SafelenRes) {
10370       S.Diag(SimdlenLength->getExprLoc(),
10371              diag::err_omp_wrong_simdlen_safelen_values)
10372           << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
10373       return true;
10374     }
10375   }
10376   return false;
10377 }
10378 
10379 StmtResult SemaOpenMP::ActOnOpenMPSimdDirective(
10380     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10381     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10382   if (!AStmt)
10383     return StmtError();
10384 
10385   CapturedStmt *CS = setBranchProtectedScope(SemaRef, OMPD_simd, AStmt);
10386 
10387   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10388   OMPLoopBasedDirective::HelperExprs B;
10389   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10390   // define the nested loops number.
10391   unsigned NestedLoopCount = checkOpenMPLoop(
10392       OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
10393       CS, SemaRef, *DSAStack, VarsWithImplicitDSA, B);
10394   if (NestedLoopCount == 0)
10395     return StmtError();
10396 
10397   if (finishLinearClauses(SemaRef, Clauses, B, DSAStack))
10398     return StmtError();
10399 
10400   if (checkSimdlenSafelenSpecified(SemaRef, Clauses))
10401     return StmtError();
10402 
10403   auto *SimdDirective = OMPSimdDirective::Create(
10404       getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10405   return SimdDirective;
10406 }
10407 
10408 StmtResult SemaOpenMP::ActOnOpenMPForDirective(
10409     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10410     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10411   if (!AStmt)
10412     return StmtError();
10413 
10414   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10415   OMPLoopBasedDirective::HelperExprs B;
10416   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10417   // define the nested loops number.
10418   unsigned NestedLoopCount = checkOpenMPLoop(
10419       OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
10420       AStmt, SemaRef, *DSAStack, VarsWithImplicitDSA, B);
10421   if (NestedLoopCount == 0)
10422     return StmtError();
10423 
10424   if (finishLinearClauses(SemaRef, Clauses, B, DSAStack))
10425     return StmtError();
10426 
10427   auto *ForDirective = OMPForDirective::Create(
10428       getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10429       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10430   return ForDirective;
10431 }
10432 
10433 StmtResult SemaOpenMP::ActOnOpenMPForSimdDirective(
10434     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10435     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10436   if (!AStmt)
10437     return StmtError();
10438 
10439   CapturedStmt *CS = setBranchProtectedScope(SemaRef, OMPD_for_simd, AStmt);
10440 
10441   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10442   OMPLoopBasedDirective::HelperExprs B;
10443   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10444   // define the nested loops number.
10445   unsigned NestedLoopCount =
10446       checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
10447                       getOrderedNumberExpr(Clauses), CS, SemaRef, *DSAStack,
10448                       VarsWithImplicitDSA, B);
10449   if (NestedLoopCount == 0)
10450     return StmtError();
10451 
10452   if (finishLinearClauses(SemaRef, Clauses, B, DSAStack))
10453     return StmtError();
10454 
10455   if (checkSimdlenSafelenSpecified(SemaRef, Clauses))
10456     return StmtError();
10457 
10458   return OMPForSimdDirective::Create(getASTContext(), StartLoc, EndLoc,
10459                                      NestedLoopCount, Clauses, AStmt, B);
10460 }
10461 
10462 static bool checkSectionsDirective(Sema &SemaRef, OpenMPDirectiveKind DKind,
10463                                    Stmt *AStmt, DSAStackTy *Stack) {
10464   if (!AStmt)
10465     return true;
10466 
10467   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10468   auto BaseStmt = AStmt;
10469   while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
10470     BaseStmt = CS->getCapturedStmt();
10471   if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
10472     auto S = C->children();
10473     if (S.begin() == S.end())
10474       return true;
10475     // All associated statements must be '#pragma omp section' except for
10476     // the first one.
10477     for (Stmt *SectionStmt : llvm::drop_begin(S)) {
10478       if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
10479         if (SectionStmt)
10480           SemaRef.Diag(SectionStmt->getBeginLoc(),
10481                        diag::err_omp_sections_substmt_not_section)
10482               << getOpenMPDirectiveName(DKind);
10483         return true;
10484       }
10485       cast<OMPSectionDirective>(SectionStmt)
10486           ->setHasCancel(Stack->isCancelRegion());
10487     }
10488   } else {
10489     SemaRef.Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt)
10490         << getOpenMPDirectiveName(DKind);
10491     return true;
10492   }
10493   return false;
10494 }
10495 
10496 StmtResult
10497 SemaOpenMP::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
10498                                          Stmt *AStmt, SourceLocation StartLoc,
10499                                          SourceLocation EndLoc) {
10500   if (checkSectionsDirective(SemaRef, OMPD_sections, AStmt, DSAStack))
10501     return StmtError();
10502 
10503   SemaRef.setFunctionHasBranchProtectedScope();
10504 
10505   return OMPSectionsDirective::Create(
10506       getASTContext(), StartLoc, EndLoc, Clauses, AStmt,
10507       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10508 }
10509 
10510 StmtResult SemaOpenMP::ActOnOpenMPSectionDirective(Stmt *AStmt,
10511                                                    SourceLocation StartLoc,
10512                                                    SourceLocation EndLoc) {
10513   if (!AStmt)
10514     return StmtError();
10515 
10516   SemaRef.setFunctionHasBranchProtectedScope();
10517   DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
10518 
10519   return OMPSectionDirective::Create(getASTContext(), StartLoc, EndLoc, AStmt,
10520                                      DSAStack->isCancelRegion());
10521 }
10522 
10523 static Expr *getDirectCallExpr(Expr *E) {
10524   E = E->IgnoreParenCasts()->IgnoreImplicit();
10525   if (auto *CE = dyn_cast<CallExpr>(E))
10526     if (CE->getDirectCallee())
10527       return E;
10528   return nullptr;
10529 }
10530 
10531 StmtResult
10532 SemaOpenMP::ActOnOpenMPDispatchDirective(ArrayRef<OMPClause *> Clauses,
10533                                          Stmt *AStmt, SourceLocation StartLoc,
10534                                          SourceLocation EndLoc) {
10535   if (!AStmt)
10536     return StmtError();
10537 
10538   Stmt *S = cast<CapturedStmt>(AStmt)->getCapturedStmt();
10539 
10540   // 5.1 OpenMP
10541   // expression-stmt : an expression statement with one of the following forms:
10542   //   expression = target-call ( [expression-list] );
10543   //   target-call ( [expression-list] );
10544 
10545   SourceLocation TargetCallLoc;
10546 
10547   if (!SemaRef.CurContext->isDependentContext()) {
10548     Expr *TargetCall = nullptr;
10549 
10550     auto *E = dyn_cast<Expr>(S);
10551     if (!E) {
10552       Diag(S->getBeginLoc(), diag::err_omp_dispatch_statement_call);
10553       return StmtError();
10554     }
10555 
10556     E = E->IgnoreParenCasts()->IgnoreImplicit();
10557 
10558     if (auto *BO = dyn_cast<BinaryOperator>(E)) {
10559       if (BO->getOpcode() == BO_Assign)
10560         TargetCall = getDirectCallExpr(BO->getRHS());
10561     } else {
10562       if (auto *COCE = dyn_cast<CXXOperatorCallExpr>(E))
10563         if (COCE->getOperator() == OO_Equal)
10564           TargetCall = getDirectCallExpr(COCE->getArg(1));
10565       if (!TargetCall)
10566         TargetCall = getDirectCallExpr(E);
10567     }
10568     if (!TargetCall) {
10569       Diag(E->getBeginLoc(), diag::err_omp_dispatch_statement_call);
10570       return StmtError();
10571     }
10572     TargetCallLoc = TargetCall->getExprLoc();
10573   }
10574 
10575   SemaRef.setFunctionHasBranchProtectedScope();
10576 
10577   return OMPDispatchDirective::Create(getASTContext(), StartLoc, EndLoc,
10578                                       Clauses, AStmt, TargetCallLoc);
10579 }
10580 
10581 static bool checkGenericLoopLastprivate(Sema &S, ArrayRef<OMPClause *> Clauses,
10582                                         OpenMPDirectiveKind K,
10583                                         DSAStackTy *Stack) {
10584   bool ErrorFound = false;
10585   for (OMPClause *C : Clauses) {
10586     if (auto *LPC = dyn_cast<OMPLastprivateClause>(C)) {
10587       for (Expr *RefExpr : LPC->varlist()) {
10588         SourceLocation ELoc;
10589         SourceRange ERange;
10590         Expr *SimpleRefExpr = RefExpr;
10591         auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
10592         if (ValueDecl *D = Res.first) {
10593           auto &&Info = Stack->isLoopControlVariable(D);
10594           if (!Info.first) {
10595             S.Diag(ELoc, diag::err_omp_lastprivate_loop_var_non_loop_iteration)
10596                 << getOpenMPDirectiveName(K);
10597             ErrorFound = true;
10598           }
10599         }
10600       }
10601     }
10602   }
10603   return ErrorFound;
10604 }
10605 
10606 StmtResult SemaOpenMP::ActOnOpenMPGenericLoopDirective(
10607     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10608     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10609   if (!AStmt)
10610     return StmtError();
10611 
10612   // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10613   // A list item may not appear in a lastprivate clause unless it is the
10614   // loop iteration variable of a loop that is associated with the construct.
10615   if (checkGenericLoopLastprivate(SemaRef, Clauses, OMPD_loop, DSAStack))
10616     return StmtError();
10617 
10618   setBranchProtectedScope(SemaRef, OMPD_loop, AStmt);
10619 
10620   OMPLoopDirective::HelperExprs B;
10621   // In presence of clause 'collapse', it will define the nested loops number.
10622   unsigned NestedLoopCount = checkOpenMPLoop(
10623       OMPD_loop, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
10624       AStmt, SemaRef, *DSAStack, VarsWithImplicitDSA, B);
10625   if (NestedLoopCount == 0)
10626     return StmtError();
10627 
10628   assert((SemaRef.CurContext->isDependentContext() || B.builtAll()) &&
10629          "omp loop exprs were not built");
10630 
10631   return OMPGenericLoopDirective::Create(getASTContext(), StartLoc, EndLoc,
10632                                          NestedLoopCount, Clauses, AStmt, B);
10633 }
10634 
10635 StmtResult SemaOpenMP::ActOnOpenMPTeamsGenericLoopDirective(
10636     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10637     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10638   if (!AStmt)
10639     return StmtError();
10640 
10641   // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10642   // A list item may not appear in a lastprivate clause unless it is the
10643   // loop iteration variable of a loop that is associated with the construct.
10644   if (checkGenericLoopLastprivate(SemaRef, Clauses, OMPD_teams_loop, DSAStack))
10645     return StmtError();
10646 
10647   CapturedStmt *CS = setBranchProtectedScope(SemaRef, OMPD_teams_loop, AStmt);
10648 
10649   OMPLoopDirective::HelperExprs B;
10650   // In presence of clause 'collapse', it will define the nested loops number.
10651   unsigned NestedLoopCount =
10652       checkOpenMPLoop(OMPD_teams_loop, getCollapseNumberExpr(Clauses),
10653                       /*OrderedLoopCountExpr=*/nullptr, CS, SemaRef, *DSAStack,
10654                       VarsWithImplicitDSA, B);
10655   if (NestedLoopCount == 0)
10656     return StmtError();
10657 
10658   assert((SemaRef.CurContext->isDependentContext() || B.builtAll()) &&
10659          "omp loop exprs were not built");
10660 
10661   DSAStack->setParentTeamsRegionLoc(StartLoc);
10662 
10663   return OMPTeamsGenericLoopDirective::Create(
10664       getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10665 }
10666 
10667 StmtResult SemaOpenMP::ActOnOpenMPTargetTeamsGenericLoopDirective(
10668     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10669     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10670   if (!AStmt)
10671     return StmtError();
10672 
10673   // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10674   // A list item may not appear in a lastprivate clause unless it is the
10675   // loop iteration variable of a loop that is associated with the construct.
10676   if (checkGenericLoopLastprivate(SemaRef, Clauses, OMPD_target_teams_loop,
10677                                   DSAStack))
10678     return StmtError();
10679 
10680   CapturedStmt *CS =
10681       setBranchProtectedScope(SemaRef, OMPD_target_teams_loop, AStmt);
10682 
10683   OMPLoopDirective::HelperExprs B;
10684   // In presence of clause 'collapse', it will define the nested loops number.
10685   unsigned NestedLoopCount =
10686       checkOpenMPLoop(OMPD_target_teams_loop, getCollapseNumberExpr(Clauses),
10687                       /*OrderedLoopCountExpr=*/nullptr, CS, SemaRef, *DSAStack,
10688                       VarsWithImplicitDSA, B);
10689   if (NestedLoopCount == 0)
10690     return StmtError();
10691 
10692   assert((SemaRef.CurContext->isDependentContext() || B.builtAll()) &&
10693          "omp loop exprs were not built");
10694 
10695   return OMPTargetTeamsGenericLoopDirective::Create(
10696       getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10697       teamsLoopCanBeParallelFor(AStmt, SemaRef));
10698 }
10699 
10700 StmtResult SemaOpenMP::ActOnOpenMPParallelGenericLoopDirective(
10701     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10702     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10703   if (!AStmt)
10704     return StmtError();
10705 
10706   // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10707   // A list item may not appear in a lastprivate clause unless it is the
10708   // loop iteration variable of a loop that is associated with the construct.
10709   if (checkGenericLoopLastprivate(SemaRef, Clauses, OMPD_parallel_loop,
10710                                   DSAStack))
10711     return StmtError();
10712 
10713   CapturedStmt *CS =
10714       setBranchProtectedScope(SemaRef, OMPD_parallel_loop, AStmt);
10715 
10716   OMPLoopDirective::HelperExprs B;
10717   // In presence of clause 'collapse', it will define the nested loops number.
10718   unsigned NestedLoopCount =
10719       checkOpenMPLoop(OMPD_parallel_loop, getCollapseNumberExpr(Clauses),
10720                       /*OrderedLoopCountExpr=*/nullptr, CS, SemaRef, *DSAStack,
10721                       VarsWithImplicitDSA, B);
10722   if (NestedLoopCount == 0)
10723     return StmtError();
10724 
10725   assert((SemaRef.CurContext->isDependentContext() || B.builtAll()) &&
10726          "omp loop exprs were not built");
10727 
10728   return OMPParallelGenericLoopDirective::Create(
10729       getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10730 }
10731 
10732 StmtResult SemaOpenMP::ActOnOpenMPTargetParallelGenericLoopDirective(
10733     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10734     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10735   if (!AStmt)
10736     return StmtError();
10737 
10738   // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10739   // A list item may not appear in a lastprivate clause unless it is the
10740   // loop iteration variable of a loop that is associated with the construct.
10741   if (checkGenericLoopLastprivate(SemaRef, Clauses, OMPD_target_parallel_loop,
10742                                   DSAStack))
10743     return StmtError();
10744 
10745   CapturedStmt *CS =
10746       setBranchProtectedScope(SemaRef, OMPD_target_parallel_loop, AStmt);
10747 
10748   OMPLoopDirective::HelperExprs B;
10749   // In presence of clause 'collapse', it will define the nested loops number.
10750   unsigned NestedLoopCount =
10751       checkOpenMPLoop(OMPD_target_parallel_loop, getCollapseNumberExpr(Clauses),
10752                       /*OrderedLoopCountExpr=*/nullptr, CS, SemaRef, *DSAStack,
10753                       VarsWithImplicitDSA, B);
10754   if (NestedLoopCount == 0)
10755     return StmtError();
10756 
10757   assert((SemaRef.CurContext->isDependentContext() || B.builtAll()) &&
10758          "omp loop exprs were not built");
10759 
10760   return OMPTargetParallelGenericLoopDirective::Create(
10761       getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10762 }
10763 
10764 StmtResult SemaOpenMP::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
10765                                                   Stmt *AStmt,
10766                                                   SourceLocation StartLoc,
10767                                                   SourceLocation EndLoc) {
10768   if (!AStmt)
10769     return StmtError();
10770 
10771   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10772 
10773   SemaRef.setFunctionHasBranchProtectedScope();
10774 
10775   // OpenMP [2.7.3, single Construct, Restrictions]
10776   // The copyprivate clause must not be used with the nowait clause.
10777   const OMPClause *Nowait = nullptr;
10778   const OMPClause *Copyprivate = nullptr;
10779   for (const OMPClause *Clause : Clauses) {
10780     if (Clause->getClauseKind() == OMPC_nowait)
10781       Nowait = Clause;
10782     else if (Clause->getClauseKind() == OMPC_copyprivate)
10783       Copyprivate = Clause;
10784     if (Copyprivate && Nowait) {
10785       Diag(Copyprivate->getBeginLoc(),
10786            diag::err_omp_single_copyprivate_with_nowait);
10787       Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
10788       return StmtError();
10789     }
10790   }
10791 
10792   return OMPSingleDirective::Create(getASTContext(), StartLoc, EndLoc, Clauses,
10793                                     AStmt);
10794 }
10795 
10796 StmtResult SemaOpenMP::ActOnOpenMPMasterDirective(Stmt *AStmt,
10797                                                   SourceLocation StartLoc,
10798                                                   SourceLocation EndLoc) {
10799   if (!AStmt)
10800     return StmtError();
10801 
10802   SemaRef.setFunctionHasBranchProtectedScope();
10803 
10804   return OMPMasterDirective::Create(getASTContext(), StartLoc, EndLoc, AStmt);
10805 }
10806 
10807 StmtResult SemaOpenMP::ActOnOpenMPMaskedDirective(ArrayRef<OMPClause *> Clauses,
10808                                                   Stmt *AStmt,
10809                                                   SourceLocation StartLoc,
10810                                                   SourceLocation EndLoc) {
10811   if (!AStmt)
10812     return StmtError();
10813 
10814   SemaRef.setFunctionHasBranchProtectedScope();
10815 
10816   return OMPMaskedDirective::Create(getASTContext(), StartLoc, EndLoc, Clauses,
10817                                     AStmt);
10818 }
10819 
10820 StmtResult SemaOpenMP::ActOnOpenMPCriticalDirective(
10821     const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
10822     Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
10823   if (!AStmt)
10824     return StmtError();
10825 
10826   bool ErrorFound = false;
10827   llvm::APSInt Hint;
10828   SourceLocation HintLoc;
10829   bool DependentHint = false;
10830   for (const OMPClause *C : Clauses) {
10831     if (C->getClauseKind() == OMPC_hint) {
10832       if (!DirName.getName()) {
10833         Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
10834         ErrorFound = true;
10835       }
10836       Expr *E = cast<OMPHintClause>(C)->getHint();
10837       if (E->isTypeDependent() || E->isValueDependent() ||
10838           E->isInstantiationDependent()) {
10839         DependentHint = true;
10840       } else {
10841         Hint = E->EvaluateKnownConstInt(getASTContext());
10842         HintLoc = C->getBeginLoc();
10843       }
10844     }
10845   }
10846   if (ErrorFound)
10847     return StmtError();
10848   const auto Pair = DSAStack->getCriticalWithHint(DirName);
10849   if (Pair.first && DirName.getName() && !DependentHint) {
10850     if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
10851       Diag(StartLoc, diag::err_omp_critical_with_hint);
10852       if (HintLoc.isValid())
10853         Diag(HintLoc, diag::note_omp_critical_hint_here)
10854             << 0 << toString(Hint, /*Radix=*/10, /*Signed=*/false);
10855       else
10856         Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
10857       if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
10858         Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
10859             << 1
10860             << toString(C->getHint()->EvaluateKnownConstInt(getASTContext()),
10861                         /*Radix=*/10, /*Signed=*/false);
10862       } else {
10863         Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
10864       }
10865     }
10866   }
10867 
10868   SemaRef.setFunctionHasBranchProtectedScope();
10869 
10870   auto *Dir = OMPCriticalDirective::Create(getASTContext(), DirName, StartLoc,
10871                                            EndLoc, Clauses, AStmt);
10872   if (!Pair.first && DirName.getName() && !DependentHint)
10873     DSAStack->addCriticalWithHint(Dir, Hint);
10874   return Dir;
10875 }
10876 
10877 StmtResult SemaOpenMP::ActOnOpenMPParallelForDirective(
10878     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10879     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10880   if (!AStmt)
10881     return StmtError();
10882 
10883   setBranchProtectedScope(SemaRef, OMPD_parallel_for, AStmt);
10884 
10885   OMPLoopBasedDirective::HelperExprs B;
10886   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10887   // define the nested loops number.
10888   unsigned NestedLoopCount =
10889       checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
10890                       getOrderedNumberExpr(Clauses), AStmt, SemaRef, *DSAStack,
10891                       VarsWithImplicitDSA, B);
10892   if (NestedLoopCount == 0)
10893     return StmtError();
10894 
10895   if (finishLinearClauses(SemaRef, Clauses, B, DSAStack))
10896     return StmtError();
10897 
10898   return OMPParallelForDirective::Create(
10899       getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10900       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10901 }
10902 
10903 StmtResult SemaOpenMP::ActOnOpenMPParallelForSimdDirective(
10904     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10905     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10906   if (!AStmt)
10907     return StmtError();
10908 
10909   CapturedStmt *CS =
10910       setBranchProtectedScope(SemaRef, OMPD_parallel_for_simd, AStmt);
10911 
10912   OMPLoopBasedDirective::HelperExprs B;
10913   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10914   // define the nested loops number.
10915   unsigned NestedLoopCount =
10916       checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
10917                       getOrderedNumberExpr(Clauses), CS, SemaRef, *DSAStack,
10918                       VarsWithImplicitDSA, B);
10919   if (NestedLoopCount == 0)
10920     return StmtError();
10921 
10922   if (finishLinearClauses(SemaRef, Clauses, B, DSAStack))
10923     return StmtError();
10924 
10925   if (checkSimdlenSafelenSpecified(SemaRef, Clauses))
10926     return StmtError();
10927 
10928   return OMPParallelForSimdDirective::Create(
10929       getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10930 }
10931 
10932 StmtResult SemaOpenMP::ActOnOpenMPParallelMasterDirective(
10933     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10934     SourceLocation EndLoc) {
10935   if (!AStmt)
10936     return StmtError();
10937 
10938   setBranchProtectedScope(SemaRef, OMPD_parallel_master, AStmt);
10939 
10940   return OMPParallelMasterDirective::Create(
10941       getASTContext(), StartLoc, EndLoc, Clauses, AStmt,
10942       DSAStack->getTaskgroupReductionRef());
10943 }
10944 
10945 StmtResult SemaOpenMP::ActOnOpenMPParallelMaskedDirective(
10946     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10947     SourceLocation EndLoc) {
10948   if (!AStmt)
10949     return StmtError();
10950 
10951   setBranchProtectedScope(SemaRef, OMPD_parallel_masked, AStmt);
10952 
10953   return OMPParallelMaskedDirective::Create(
10954       getASTContext(), StartLoc, EndLoc, Clauses, AStmt,
10955       DSAStack->getTaskgroupReductionRef());
10956 }
10957 
10958 StmtResult SemaOpenMP::ActOnOpenMPParallelSectionsDirective(
10959     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10960     SourceLocation EndLoc) {
10961   if (checkSectionsDirective(SemaRef, OMPD_parallel_sections, AStmt, DSAStack))
10962     return StmtError();
10963 
10964   SemaRef.setFunctionHasBranchProtectedScope();
10965 
10966   return OMPParallelSectionsDirective::Create(
10967       getASTContext(), StartLoc, EndLoc, Clauses, AStmt,
10968       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10969 }
10970 
10971 /// Find and diagnose mutually exclusive clause kinds.
10972 static bool checkMutuallyExclusiveClauses(
10973     Sema &S, ArrayRef<OMPClause *> Clauses,
10974     ArrayRef<OpenMPClauseKind> MutuallyExclusiveClauses) {
10975   const OMPClause *PrevClause = nullptr;
10976   bool ErrorFound = false;
10977   for (const OMPClause *C : Clauses) {
10978     if (llvm::is_contained(MutuallyExclusiveClauses, C->getClauseKind())) {
10979       if (!PrevClause) {
10980         PrevClause = C;
10981       } else if (PrevClause->getClauseKind() != C->getClauseKind()) {
10982         S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
10983             << getOpenMPClauseName(C->getClauseKind())
10984             << getOpenMPClauseName(PrevClause->getClauseKind());
10985         S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
10986             << getOpenMPClauseName(PrevClause->getClauseKind());
10987         ErrorFound = true;
10988       }
10989     }
10990   }
10991   return ErrorFound;
10992 }
10993 
10994 StmtResult SemaOpenMP::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
10995                                                 Stmt *AStmt,
10996                                                 SourceLocation StartLoc,
10997                                                 SourceLocation EndLoc) {
10998   if (!AStmt)
10999     return StmtError();
11000 
11001   // OpenMP 5.0, 2.10.1 task Construct
11002   // If a detach clause appears on the directive, then a mergeable clause cannot
11003   // appear on the same directive.
11004   if (checkMutuallyExclusiveClauses(SemaRef, Clauses,
11005                                     {OMPC_detach, OMPC_mergeable}))
11006     return StmtError();
11007 
11008   setBranchProtectedScope(SemaRef, OMPD_task, AStmt);
11009 
11010   return OMPTaskDirective::Create(getASTContext(), StartLoc, EndLoc, Clauses,
11011                                   AStmt, DSAStack->isCancelRegion());
11012 }
11013 
11014 StmtResult SemaOpenMP::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
11015                                                      SourceLocation EndLoc) {
11016   return OMPTaskyieldDirective::Create(getASTContext(), StartLoc, EndLoc);
11017 }
11018 
11019 StmtResult SemaOpenMP::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
11020                                                    SourceLocation EndLoc) {
11021   return OMPBarrierDirective::Create(getASTContext(), StartLoc, EndLoc);
11022 }
11023 
11024 StmtResult SemaOpenMP::ActOnOpenMPErrorDirective(ArrayRef<OMPClause *> Clauses,
11025                                                  SourceLocation StartLoc,
11026                                                  SourceLocation EndLoc,
11027                                                  bool InExContext) {
11028   const OMPAtClause *AtC =
11029       OMPExecutableDirective::getSingleClause<OMPAtClause>(Clauses);
11030 
11031   if (AtC && !InExContext && AtC->getAtKind() == OMPC_AT_execution) {
11032     Diag(AtC->getAtKindKwLoc(), diag::err_omp_unexpected_execution_modifier);
11033     return StmtError();
11034   }
11035 
11036   const OMPSeverityClause *SeverityC =
11037       OMPExecutableDirective::getSingleClause<OMPSeverityClause>(Clauses);
11038   const OMPMessageClause *MessageC =
11039       OMPExecutableDirective::getSingleClause<OMPMessageClause>(Clauses);
11040   Expr *ME = MessageC ? MessageC->getMessageString() : nullptr;
11041 
11042   if (!AtC || AtC->getAtKind() == OMPC_AT_compilation) {
11043     if (SeverityC && SeverityC->getSeverityKind() == OMPC_SEVERITY_warning)
11044       Diag(SeverityC->getSeverityKindKwLoc(), diag::warn_diagnose_if_succeeded)
11045           << (ME ? cast<StringLiteral>(ME)->getString() : "WARNING");
11046     else
11047       Diag(StartLoc, diag::err_diagnose_if_succeeded)
11048           << (ME ? cast<StringLiteral>(ME)->getString() : "ERROR");
11049     if (!SeverityC || SeverityC->getSeverityKind() != OMPC_SEVERITY_warning)
11050       return StmtError();
11051   }
11052   return OMPErrorDirective::Create(getASTContext(), StartLoc, EndLoc, Clauses);
11053 }
11054 
11055 StmtResult
11056 SemaOpenMP::ActOnOpenMPTaskwaitDirective(ArrayRef<OMPClause *> Clauses,
11057                                          SourceLocation StartLoc,
11058                                          SourceLocation EndLoc) {
11059   const OMPNowaitClause *NowaitC =
11060       OMPExecutableDirective::getSingleClause<OMPNowaitClause>(Clauses);
11061   bool HasDependC =
11062       !OMPExecutableDirective::getClausesOfKind<OMPDependClause>(Clauses)
11063            .empty();
11064   if (NowaitC && !HasDependC) {
11065     Diag(StartLoc, diag::err_omp_nowait_clause_without_depend);
11066     return StmtError();
11067   }
11068 
11069   return OMPTaskwaitDirective::Create(getASTContext(), StartLoc, EndLoc,
11070                                       Clauses);
11071 }
11072 
11073 StmtResult
11074 SemaOpenMP::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
11075                                           Stmt *AStmt, SourceLocation StartLoc,
11076                                           SourceLocation EndLoc) {
11077   if (!AStmt)
11078     return StmtError();
11079 
11080   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11081 
11082   SemaRef.setFunctionHasBranchProtectedScope();
11083 
11084   return OMPTaskgroupDirective::Create(getASTContext(), StartLoc, EndLoc,
11085                                        Clauses, AStmt,
11086                                        DSAStack->getTaskgroupReductionRef());
11087 }
11088 
11089 StmtResult SemaOpenMP::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
11090                                                  SourceLocation StartLoc,
11091                                                  SourceLocation EndLoc) {
11092   OMPFlushClause *FC = nullptr;
11093   OMPClause *OrderClause = nullptr;
11094   for (OMPClause *C : Clauses) {
11095     if (C->getClauseKind() == OMPC_flush)
11096       FC = cast<OMPFlushClause>(C);
11097     else
11098       OrderClause = C;
11099   }
11100   OpenMPClauseKind MemOrderKind = OMPC_unknown;
11101   SourceLocation MemOrderLoc;
11102   for (const OMPClause *C : Clauses) {
11103     if (C->getClauseKind() == OMPC_acq_rel ||
11104         C->getClauseKind() == OMPC_acquire ||
11105         C->getClauseKind() == OMPC_release ||
11106         C->getClauseKind() == OMPC_seq_cst /*OpenMP 5.1*/) {
11107       if (MemOrderKind != OMPC_unknown) {
11108         Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
11109             << getOpenMPDirectiveName(OMPD_flush) << 1
11110             << SourceRange(C->getBeginLoc(), C->getEndLoc());
11111         Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
11112             << getOpenMPClauseName(MemOrderKind);
11113       } else {
11114         MemOrderKind = C->getClauseKind();
11115         MemOrderLoc = C->getBeginLoc();
11116       }
11117     }
11118   }
11119   if (FC && OrderClause) {
11120     Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list)
11121         << getOpenMPClauseName(OrderClause->getClauseKind());
11122     Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here)
11123         << getOpenMPClauseName(OrderClause->getClauseKind());
11124     return StmtError();
11125   }
11126   return OMPFlushDirective::Create(getASTContext(), StartLoc, EndLoc, Clauses);
11127 }
11128 
11129 StmtResult SemaOpenMP::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses,
11130                                                   SourceLocation StartLoc,
11131                                                   SourceLocation EndLoc) {
11132   if (Clauses.empty()) {
11133     Diag(StartLoc, diag::err_omp_depobj_expected);
11134     return StmtError();
11135   } else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
11136     Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
11137     return StmtError();
11138   }
11139   // Only depobj expression and another single clause is allowed.
11140   if (Clauses.size() > 2) {
11141     Diag(Clauses[2]->getBeginLoc(),
11142          diag::err_omp_depobj_single_clause_expected);
11143     return StmtError();
11144   } else if (Clauses.size() < 1) {
11145     Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
11146     return StmtError();
11147   }
11148   return OMPDepobjDirective::Create(getASTContext(), StartLoc, EndLoc, Clauses);
11149 }
11150 
11151 StmtResult SemaOpenMP::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses,
11152                                                 SourceLocation StartLoc,
11153                                                 SourceLocation EndLoc) {
11154   // Check that exactly one clause is specified.
11155   if (Clauses.size() != 1) {
11156     Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
11157          diag::err_omp_scan_single_clause_expected);
11158     return StmtError();
11159   }
11160   // Check that scan directive is used in the scope of the OpenMP loop body.
11161   if (Scope *S = DSAStack->getCurScope()) {
11162     Scope *ParentS = S->getParent();
11163     if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() ||
11164         !ParentS->getBreakParent()->isOpenMPLoopScope())
11165       return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive)
11166                        << getOpenMPDirectiveName(OMPD_scan) << 5);
11167   }
11168   // Check that only one instance of scan directives is used in the same outer
11169   // region.
11170   if (DSAStack->doesParentHasScanDirective()) {
11171     Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan";
11172     Diag(DSAStack->getParentScanDirectiveLoc(),
11173          diag::note_omp_previous_directive)
11174         << "scan";
11175     return StmtError();
11176   }
11177   DSAStack->setParentHasScanDirective(StartLoc);
11178   return OMPScanDirective::Create(getASTContext(), StartLoc, EndLoc, Clauses);
11179 }
11180 
11181 StmtResult
11182 SemaOpenMP::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
11183                                         Stmt *AStmt, SourceLocation StartLoc,
11184                                         SourceLocation EndLoc) {
11185   const OMPClause *DependFound = nullptr;
11186   const OMPClause *DependSourceClause = nullptr;
11187   const OMPClause *DependSinkClause = nullptr;
11188   const OMPClause *DoacrossFound = nullptr;
11189   const OMPClause *DoacrossSourceClause = nullptr;
11190   const OMPClause *DoacrossSinkClause = nullptr;
11191   bool ErrorFound = false;
11192   const OMPThreadsClause *TC = nullptr;
11193   const OMPSIMDClause *SC = nullptr;
11194   for (const OMPClause *C : Clauses) {
11195     auto DOC = dyn_cast<OMPDoacrossClause>(C);
11196     auto DC = dyn_cast<OMPDependClause>(C);
11197     if (DC || DOC) {
11198       DependFound = DC ? C : nullptr;
11199       DoacrossFound = DOC ? C : nullptr;
11200       OMPDoacrossKind ODK;
11201       if ((DC && DC->getDependencyKind() == OMPC_DEPEND_source) ||
11202           (DOC && (ODK.isSource(DOC)))) {
11203         if ((DC && DependSourceClause) || (DOC && DoacrossSourceClause)) {
11204           Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
11205               << getOpenMPDirectiveName(OMPD_ordered)
11206               << getOpenMPClauseName(DC ? OMPC_depend : OMPC_doacross) << 2;
11207           ErrorFound = true;
11208         } else {
11209           if (DC)
11210             DependSourceClause = C;
11211           else
11212             DoacrossSourceClause = C;
11213         }
11214         if ((DC && DependSinkClause) || (DOC && DoacrossSinkClause)) {
11215           Diag(C->getBeginLoc(), diag::err_omp_sink_and_source_not_allowed)
11216               << (DC ? "depend" : "doacross") << 0;
11217           ErrorFound = true;
11218         }
11219       } else if ((DC && DC->getDependencyKind() == OMPC_DEPEND_sink) ||
11220                  (DOC && (ODK.isSink(DOC) || ODK.isSinkIter(DOC)))) {
11221         if (DependSourceClause || DoacrossSourceClause) {
11222           Diag(C->getBeginLoc(), diag::err_omp_sink_and_source_not_allowed)
11223               << (DC ? "depend" : "doacross") << 1;
11224           ErrorFound = true;
11225         }
11226         if (DC)
11227           DependSinkClause = C;
11228         else
11229           DoacrossSinkClause = C;
11230       }
11231     } else if (C->getClauseKind() == OMPC_threads) {
11232       TC = cast<OMPThreadsClause>(C);
11233     } else if (C->getClauseKind() == OMPC_simd) {
11234       SC = cast<OMPSIMDClause>(C);
11235     }
11236   }
11237   if (!ErrorFound && !SC &&
11238       isOpenMPSimdDirective(DSAStack->getParentDirective())) {
11239     // OpenMP [2.8.1,simd Construct, Restrictions]
11240     // An ordered construct with the simd clause is the only OpenMP construct
11241     // that can appear in the simd region.
11242     Diag(StartLoc, diag::err_omp_prohibited_region_simd)
11243         << (getLangOpts().OpenMP >= 50 ? 1 : 0);
11244     ErrorFound = true;
11245   } else if ((DependFound || DoacrossFound) && (TC || SC)) {
11246     SourceLocation Loc =
11247         DependFound ? DependFound->getBeginLoc() : DoacrossFound->getBeginLoc();
11248     Diag(Loc, diag::err_omp_depend_clause_thread_simd)
11249         << getOpenMPClauseName(DependFound ? OMPC_depend : OMPC_doacross)
11250         << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
11251     ErrorFound = true;
11252   } else if ((DependFound || DoacrossFound) &&
11253              !DSAStack->getParentOrderedRegionParam().first) {
11254     SourceLocation Loc =
11255         DependFound ? DependFound->getBeginLoc() : DoacrossFound->getBeginLoc();
11256     Diag(Loc, diag::err_omp_ordered_directive_without_param)
11257         << getOpenMPClauseName(DependFound ? OMPC_depend : OMPC_doacross);
11258     ErrorFound = true;
11259   } else if (TC || Clauses.empty()) {
11260     if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) {
11261       SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
11262       Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
11263           << (TC != nullptr);
11264       Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1;
11265       ErrorFound = true;
11266     }
11267   }
11268   if ((!AStmt && !DependFound && !DoacrossFound) || ErrorFound)
11269     return StmtError();
11270 
11271   // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions.
11272   // During execution of an iteration of a worksharing-loop or a loop nest
11273   // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread
11274   // must not execute more than one ordered region corresponding to an ordered
11275   // construct without a depend clause.
11276   if (!DependFound && !DoacrossFound) {
11277     if (DSAStack->doesParentHasOrderedDirective()) {
11278       Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered";
11279       Diag(DSAStack->getParentOrderedDirectiveLoc(),
11280            diag::note_omp_previous_directive)
11281           << "ordered";
11282       return StmtError();
11283     }
11284     DSAStack->setParentHasOrderedDirective(StartLoc);
11285   }
11286 
11287   if (AStmt) {
11288     assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11289 
11290     SemaRef.setFunctionHasBranchProtectedScope();
11291   }
11292 
11293   return OMPOrderedDirective::Create(getASTContext(), StartLoc, EndLoc, Clauses,
11294                                      AStmt);
11295 }
11296 
11297 namespace {
11298 /// Helper class for checking expression in 'omp atomic [update]'
11299 /// construct.
11300 class OpenMPAtomicUpdateChecker {
11301   /// Error results for atomic update expressions.
11302   enum ExprAnalysisErrorCode {
11303     /// A statement is not an expression statement.
11304     NotAnExpression,
11305     /// Expression is not builtin binary or unary operation.
11306     NotABinaryOrUnaryExpression,
11307     /// Unary operation is not post-/pre- increment/decrement operation.
11308     NotAnUnaryIncDecExpression,
11309     /// An expression is not of scalar type.
11310     NotAScalarType,
11311     /// A binary operation is not an assignment operation.
11312     NotAnAssignmentOp,
11313     /// RHS part of the binary operation is not a binary expression.
11314     NotABinaryExpression,
11315     /// RHS part is not additive/multiplicative/shift/bitwise binary
11316     /// expression.
11317     NotABinaryOperator,
11318     /// RHS binary operation does not have reference to the updated LHS
11319     /// part.
11320     NotAnUpdateExpression,
11321     /// An expression contains semantical error not related to
11322     /// 'omp atomic [update]'
11323     NotAValidExpression,
11324     /// No errors is found.
11325     NoError
11326   };
11327   /// Reference to Sema.
11328   Sema &SemaRef;
11329   /// A location for note diagnostics (when error is found).
11330   SourceLocation NoteLoc;
11331   /// 'x' lvalue part of the source atomic expression.
11332   Expr *X;
11333   /// 'expr' rvalue part of the source atomic expression.
11334   Expr *E;
11335   /// Helper expression of the form
11336   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
11337   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
11338   Expr *UpdateExpr;
11339   /// Is 'x' a LHS in a RHS part of full update expression. It is
11340   /// important for non-associative operations.
11341   bool IsXLHSInRHSPart;
11342   BinaryOperatorKind Op;
11343   SourceLocation OpLoc;
11344   /// true if the source expression is a postfix unary operation, false
11345   /// if it is a prefix unary operation.
11346   bool IsPostfixUpdate;
11347 
11348 public:
11349   OpenMPAtomicUpdateChecker(Sema &SemaRef)
11350       : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
11351         IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
11352   /// Check specified statement that it is suitable for 'atomic update'
11353   /// constructs and extract 'x', 'expr' and Operation from the original
11354   /// expression. If DiagId and NoteId == 0, then only check is performed
11355   /// without error notification.
11356   /// \param DiagId Diagnostic which should be emitted if error is found.
11357   /// \param NoteId Diagnostic note for the main error message.
11358   /// \return true if statement is not an update expression, false otherwise.
11359   bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
11360   /// Return the 'x' lvalue part of the source atomic expression.
11361   Expr *getX() const { return X; }
11362   /// Return the 'expr' rvalue part of the source atomic expression.
11363   Expr *getExpr() const { return E; }
11364   /// Return the update expression used in calculation of the updated
11365   /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
11366   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
11367   Expr *getUpdateExpr() const { return UpdateExpr; }
11368   /// Return true if 'x' is LHS in RHS part of full update expression,
11369   /// false otherwise.
11370   bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
11371 
11372   /// true if the source expression is a postfix unary operation, false
11373   /// if it is a prefix unary operation.
11374   bool isPostfixUpdate() const { return IsPostfixUpdate; }
11375 
11376 private:
11377   bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
11378                             unsigned NoteId = 0);
11379 };
11380 
11381 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
11382     BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
11383   ExprAnalysisErrorCode ErrorFound = NoError;
11384   SourceLocation ErrorLoc, NoteLoc;
11385   SourceRange ErrorRange, NoteRange;
11386   // Allowed constructs are:
11387   //  x = x binop expr;
11388   //  x = expr binop x;
11389   if (AtomicBinOp->getOpcode() == BO_Assign) {
11390     X = AtomicBinOp->getLHS();
11391     if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
11392             AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
11393       if (AtomicInnerBinOp->isMultiplicativeOp() ||
11394           AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
11395           AtomicInnerBinOp->isBitwiseOp()) {
11396         Op = AtomicInnerBinOp->getOpcode();
11397         OpLoc = AtomicInnerBinOp->getOperatorLoc();
11398         Expr *LHS = AtomicInnerBinOp->getLHS();
11399         Expr *RHS = AtomicInnerBinOp->getRHS();
11400         llvm::FoldingSetNodeID XId, LHSId, RHSId;
11401         X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
11402                                           /*Canonical=*/true);
11403         LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
11404                                             /*Canonical=*/true);
11405         RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
11406                                             /*Canonical=*/true);
11407         if (XId == LHSId) {
11408           E = RHS;
11409           IsXLHSInRHSPart = true;
11410         } else if (XId == RHSId) {
11411           E = LHS;
11412           IsXLHSInRHSPart = false;
11413         } else {
11414           ErrorLoc = AtomicInnerBinOp->getExprLoc();
11415           ErrorRange = AtomicInnerBinOp->getSourceRange();
11416           NoteLoc = X->getExprLoc();
11417           NoteRange = X->getSourceRange();
11418           ErrorFound = NotAnUpdateExpression;
11419         }
11420       } else {
11421         ErrorLoc = AtomicInnerBinOp->getExprLoc();
11422         ErrorRange = AtomicInnerBinOp->getSourceRange();
11423         NoteLoc = AtomicInnerBinOp->getOperatorLoc();
11424         NoteRange = SourceRange(NoteLoc, NoteLoc);
11425         ErrorFound = NotABinaryOperator;
11426       }
11427     } else {
11428       NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
11429       NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
11430       ErrorFound = NotABinaryExpression;
11431     }
11432   } else {
11433     ErrorLoc = AtomicBinOp->getExprLoc();
11434     ErrorRange = AtomicBinOp->getSourceRange();
11435     NoteLoc = AtomicBinOp->getOperatorLoc();
11436     NoteRange = SourceRange(NoteLoc, NoteLoc);
11437     ErrorFound = NotAnAssignmentOp;
11438   }
11439   if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
11440     SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
11441     SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
11442     return true;
11443   }
11444   if (SemaRef.CurContext->isDependentContext())
11445     E = X = UpdateExpr = nullptr;
11446   return ErrorFound != NoError;
11447 }
11448 
11449 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
11450                                                unsigned NoteId) {
11451   ExprAnalysisErrorCode ErrorFound = NoError;
11452   SourceLocation ErrorLoc, NoteLoc;
11453   SourceRange ErrorRange, NoteRange;
11454   // Allowed constructs are:
11455   //  x++;
11456   //  x--;
11457   //  ++x;
11458   //  --x;
11459   //  x binop= expr;
11460   //  x = x binop expr;
11461   //  x = expr binop x;
11462   if (auto *AtomicBody = dyn_cast<Expr>(S)) {
11463     AtomicBody = AtomicBody->IgnoreParenImpCasts();
11464     if (AtomicBody->getType()->isScalarType() ||
11465         AtomicBody->isInstantiationDependent()) {
11466       if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
11467               AtomicBody->IgnoreParenImpCasts())) {
11468         // Check for Compound Assignment Operation
11469         Op = BinaryOperator::getOpForCompoundAssignment(
11470             AtomicCompAssignOp->getOpcode());
11471         OpLoc = AtomicCompAssignOp->getOperatorLoc();
11472         E = AtomicCompAssignOp->getRHS();
11473         X = AtomicCompAssignOp->getLHS()->IgnoreParens();
11474         IsXLHSInRHSPart = true;
11475       } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
11476                      AtomicBody->IgnoreParenImpCasts())) {
11477         // Check for Binary Operation
11478         if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
11479           return true;
11480       } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
11481                      AtomicBody->IgnoreParenImpCasts())) {
11482         // Check for Unary Operation
11483         if (AtomicUnaryOp->isIncrementDecrementOp()) {
11484           IsPostfixUpdate = AtomicUnaryOp->isPostfix();
11485           Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
11486           OpLoc = AtomicUnaryOp->getOperatorLoc();
11487           X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
11488           E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
11489           IsXLHSInRHSPart = true;
11490         } else {
11491           ErrorFound = NotAnUnaryIncDecExpression;
11492           ErrorLoc = AtomicUnaryOp->getExprLoc();
11493           ErrorRange = AtomicUnaryOp->getSourceRange();
11494           NoteLoc = AtomicUnaryOp->getOperatorLoc();
11495           NoteRange = SourceRange(NoteLoc, NoteLoc);
11496         }
11497       } else if (!AtomicBody->isInstantiationDependent()) {
11498         ErrorFound = NotABinaryOrUnaryExpression;
11499         NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
11500         NoteRange = ErrorRange = AtomicBody->getSourceRange();
11501       } else if (AtomicBody->containsErrors()) {
11502         ErrorFound = NotAValidExpression;
11503         NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
11504         NoteRange = ErrorRange = AtomicBody->getSourceRange();
11505       }
11506     } else {
11507       ErrorFound = NotAScalarType;
11508       NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
11509       NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
11510     }
11511   } else {
11512     ErrorFound = NotAnExpression;
11513     NoteLoc = ErrorLoc = S->getBeginLoc();
11514     NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
11515   }
11516   if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
11517     SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
11518     SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
11519     return true;
11520   }
11521   if (SemaRef.CurContext->isDependentContext())
11522     E = X = UpdateExpr = nullptr;
11523   if (ErrorFound == NoError && E && X) {
11524     // Build an update expression of form 'OpaqueValueExpr(x) binop
11525     // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
11526     // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
11527     auto *OVEX = new (SemaRef.getASTContext())
11528         OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_PRValue);
11529     auto *OVEExpr = new (SemaRef.getASTContext())
11530         OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_PRValue);
11531     ExprResult Update =
11532         SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
11533                                    IsXLHSInRHSPart ? OVEExpr : OVEX);
11534     if (Update.isInvalid())
11535       return true;
11536     Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
11537                                                AssignmentAction::Casting);
11538     if (Update.isInvalid())
11539       return true;
11540     UpdateExpr = Update.get();
11541   }
11542   return ErrorFound != NoError;
11543 }
11544 
11545 /// Get the node id of the fixed point of an expression \a S.
11546 llvm::FoldingSetNodeID getNodeId(ASTContext &Context, const Expr *S) {
11547   llvm::FoldingSetNodeID Id;
11548   S->IgnoreParenImpCasts()->Profile(Id, Context, true);
11549   return Id;
11550 }
11551 
11552 /// Check if two expressions are same.
11553 bool checkIfTwoExprsAreSame(ASTContext &Context, const Expr *LHS,
11554                             const Expr *RHS) {
11555   return getNodeId(Context, LHS) == getNodeId(Context, RHS);
11556 }
11557 
11558 class OpenMPAtomicCompareChecker {
11559 public:
11560   /// All kinds of errors that can occur in `atomic compare`
11561   enum ErrorTy {
11562     /// Empty compound statement.
11563     NoStmt = 0,
11564     /// More than one statement in a compound statement.
11565     MoreThanOneStmt,
11566     /// Not an assignment binary operator.
11567     NotAnAssignment,
11568     /// Not a conditional operator.
11569     NotCondOp,
11570     /// Wrong false expr. According to the spec, 'x' should be at the false
11571     /// expression of a conditional expression.
11572     WrongFalseExpr,
11573     /// The condition of a conditional expression is not a binary operator.
11574     NotABinaryOp,
11575     /// Invalid binary operator (not <, >, or ==).
11576     InvalidBinaryOp,
11577     /// Invalid comparison (not x == e, e == x, x ordop expr, or expr ordop x).
11578     InvalidComparison,
11579     /// X is not a lvalue.
11580     XNotLValue,
11581     /// Not a scalar.
11582     NotScalar,
11583     /// Not an integer.
11584     NotInteger,
11585     /// 'else' statement is not expected.
11586     UnexpectedElse,
11587     /// Not an equality operator.
11588     NotEQ,
11589     /// Invalid assignment (not v == x).
11590     InvalidAssignment,
11591     /// Not if statement
11592     NotIfStmt,
11593     /// More than two statements in a compound statement.
11594     MoreThanTwoStmts,
11595     /// Not a compound statement.
11596     NotCompoundStmt,
11597     /// No else statement.
11598     NoElse,
11599     /// Not 'if (r)'.
11600     InvalidCondition,
11601     /// No error.
11602     NoError,
11603   };
11604 
11605   struct ErrorInfoTy {
11606     ErrorTy Error;
11607     SourceLocation ErrorLoc;
11608     SourceRange ErrorRange;
11609     SourceLocation NoteLoc;
11610     SourceRange NoteRange;
11611   };
11612 
11613   OpenMPAtomicCompareChecker(Sema &S) : ContextRef(S.getASTContext()) {}
11614 
11615   /// Check if statement \a S is valid for <tt>atomic compare</tt>.
11616   bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
11617 
11618   Expr *getX() const { return X; }
11619   Expr *getE() const { return E; }
11620   Expr *getD() const { return D; }
11621   Expr *getCond() const { return C; }
11622   bool isXBinopExpr() const { return IsXBinopExpr; }
11623 
11624 protected:
11625   /// Reference to ASTContext
11626   ASTContext &ContextRef;
11627   /// 'x' lvalue part of the source atomic expression.
11628   Expr *X = nullptr;
11629   /// 'expr' or 'e' rvalue part of the source atomic expression.
11630   Expr *E = nullptr;
11631   /// 'd' rvalue part of the source atomic expression.
11632   Expr *D = nullptr;
11633   /// 'cond' part of the source atomic expression. It is in one of the following
11634   /// forms:
11635   /// expr ordop x
11636   /// x ordop expr
11637   /// x == e
11638   /// e == x
11639   Expr *C = nullptr;
11640   /// True if the cond expr is in the form of 'x ordop expr'.
11641   bool IsXBinopExpr = true;
11642 
11643   /// Check if it is a valid conditional update statement (cond-update-stmt).
11644   bool checkCondUpdateStmt(IfStmt *S, ErrorInfoTy &ErrorInfo);
11645 
11646   /// Check if it is a valid conditional expression statement (cond-expr-stmt).
11647   bool checkCondExprStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
11648 
11649   /// Check if all captured values have right type.
11650   bool checkType(ErrorInfoTy &ErrorInfo) const;
11651 
11652   static bool CheckValue(const Expr *E, ErrorInfoTy &ErrorInfo,
11653                          bool ShouldBeLValue, bool ShouldBeInteger = false) {
11654     if (E->isInstantiationDependent())
11655       return true;
11656 
11657     if (ShouldBeLValue && !E->isLValue()) {
11658       ErrorInfo.Error = ErrorTy::XNotLValue;
11659       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11660       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11661       return false;
11662     }
11663 
11664     QualType QTy = E->getType();
11665     if (!QTy->isScalarType()) {
11666       ErrorInfo.Error = ErrorTy::NotScalar;
11667       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11668       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11669       return false;
11670     }
11671     if (ShouldBeInteger && !QTy->isIntegerType()) {
11672       ErrorInfo.Error = ErrorTy::NotInteger;
11673       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11674       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11675       return false;
11676     }
11677 
11678     return true;
11679   }
11680 };
11681 
11682 bool OpenMPAtomicCompareChecker::checkCondUpdateStmt(IfStmt *S,
11683                                                      ErrorInfoTy &ErrorInfo) {
11684   auto *Then = S->getThen();
11685   if (auto *CS = dyn_cast<CompoundStmt>(Then)) {
11686     if (CS->body_empty()) {
11687       ErrorInfo.Error = ErrorTy::NoStmt;
11688       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11689       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11690       return false;
11691     }
11692     if (CS->size() > 1) {
11693       ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11694       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11695       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
11696       return false;
11697     }
11698     Then = CS->body_front();
11699   }
11700 
11701   auto *BO = dyn_cast<BinaryOperator>(Then);
11702   if (!BO) {
11703     ErrorInfo.Error = ErrorTy::NotAnAssignment;
11704     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc();
11705     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange();
11706     return false;
11707   }
11708   if (BO->getOpcode() != BO_Assign) {
11709     ErrorInfo.Error = ErrorTy::NotAnAssignment;
11710     ErrorInfo.ErrorLoc = BO->getExprLoc();
11711     ErrorInfo.NoteLoc = BO->getOperatorLoc();
11712     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
11713     return false;
11714   }
11715 
11716   X = BO->getLHS();
11717 
11718   auto *Cond = dyn_cast<BinaryOperator>(S->getCond());
11719   if (!Cond) {
11720     ErrorInfo.Error = ErrorTy::NotABinaryOp;
11721     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc();
11722     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange();
11723     return false;
11724   }
11725 
11726   switch (Cond->getOpcode()) {
11727   case BO_EQ: {
11728     C = Cond;
11729     D = BO->getRHS();
11730     if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
11731       E = Cond->getRHS();
11732     } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11733       E = Cond->getLHS();
11734     } else {
11735       ErrorInfo.Error = ErrorTy::InvalidComparison;
11736       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11737       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11738       return false;
11739     }
11740     break;
11741   }
11742   case BO_LT:
11743   case BO_GT: {
11744     E = BO->getRHS();
11745     if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) &&
11746         checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) {
11747       C = Cond;
11748     } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) &&
11749                checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11750       C = Cond;
11751       IsXBinopExpr = false;
11752     } else {
11753       ErrorInfo.Error = ErrorTy::InvalidComparison;
11754       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11755       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11756       return false;
11757     }
11758     break;
11759   }
11760   default:
11761     ErrorInfo.Error = ErrorTy::InvalidBinaryOp;
11762     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11763     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11764     return false;
11765   }
11766 
11767   if (S->getElse()) {
11768     ErrorInfo.Error = ErrorTy::UnexpectedElse;
11769     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getElse()->getBeginLoc();
11770     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getElse()->getSourceRange();
11771     return false;
11772   }
11773 
11774   return true;
11775 }
11776 
11777 bool OpenMPAtomicCompareChecker::checkCondExprStmt(Stmt *S,
11778                                                    ErrorInfoTy &ErrorInfo) {
11779   auto *BO = dyn_cast<BinaryOperator>(S);
11780   if (!BO) {
11781     ErrorInfo.Error = ErrorTy::NotAnAssignment;
11782     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
11783     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
11784     return false;
11785   }
11786   if (BO->getOpcode() != BO_Assign) {
11787     ErrorInfo.Error = ErrorTy::NotAnAssignment;
11788     ErrorInfo.ErrorLoc = BO->getExprLoc();
11789     ErrorInfo.NoteLoc = BO->getOperatorLoc();
11790     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
11791     return false;
11792   }
11793 
11794   X = BO->getLHS();
11795 
11796   auto *CO = dyn_cast<ConditionalOperator>(BO->getRHS()->IgnoreParenImpCasts());
11797   if (!CO) {
11798     ErrorInfo.Error = ErrorTy::NotCondOp;
11799     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getRHS()->getExprLoc();
11800     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getRHS()->getSourceRange();
11801     return false;
11802   }
11803 
11804   if (!checkIfTwoExprsAreSame(ContextRef, X, CO->getFalseExpr())) {
11805     ErrorInfo.Error = ErrorTy::WrongFalseExpr;
11806     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getFalseExpr()->getExprLoc();
11807     ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
11808         CO->getFalseExpr()->getSourceRange();
11809     return false;
11810   }
11811 
11812   auto *Cond = dyn_cast<BinaryOperator>(CO->getCond());
11813   if (!Cond) {
11814     ErrorInfo.Error = ErrorTy::NotABinaryOp;
11815     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getCond()->getExprLoc();
11816     ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
11817         CO->getCond()->getSourceRange();
11818     return false;
11819   }
11820 
11821   switch (Cond->getOpcode()) {
11822   case BO_EQ: {
11823     C = Cond;
11824     D = CO->getTrueExpr();
11825     if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
11826       E = Cond->getRHS();
11827     } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11828       E = Cond->getLHS();
11829     } else {
11830       ErrorInfo.Error = ErrorTy::InvalidComparison;
11831       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11832       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11833       return false;
11834     }
11835     break;
11836   }
11837   case BO_LT:
11838   case BO_GT: {
11839     E = CO->getTrueExpr();
11840     if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) &&
11841         checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) {
11842       C = Cond;
11843     } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) &&
11844                checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11845       C = Cond;
11846       IsXBinopExpr = false;
11847     } else {
11848       ErrorInfo.Error = ErrorTy::InvalidComparison;
11849       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11850       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11851       return false;
11852     }
11853     break;
11854   }
11855   default:
11856     ErrorInfo.Error = ErrorTy::InvalidBinaryOp;
11857     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11858     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11859     return false;
11860   }
11861 
11862   return true;
11863 }
11864 
11865 bool OpenMPAtomicCompareChecker::checkType(ErrorInfoTy &ErrorInfo) const {
11866   // 'x' and 'e' cannot be nullptr
11867   assert(X && E && "X and E cannot be nullptr");
11868 
11869   if (!CheckValue(X, ErrorInfo, true))
11870     return false;
11871 
11872   if (!CheckValue(E, ErrorInfo, false))
11873     return false;
11874 
11875   if (D && !CheckValue(D, ErrorInfo, false))
11876     return false;
11877 
11878   return true;
11879 }
11880 
11881 bool OpenMPAtomicCompareChecker::checkStmt(
11882     Stmt *S, OpenMPAtomicCompareChecker::ErrorInfoTy &ErrorInfo) {
11883   auto *CS = dyn_cast<CompoundStmt>(S);
11884   if (CS) {
11885     if (CS->body_empty()) {
11886       ErrorInfo.Error = ErrorTy::NoStmt;
11887       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11888       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11889       return false;
11890     }
11891 
11892     if (CS->size() != 1) {
11893       ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11894       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11895       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11896       return false;
11897     }
11898     S = CS->body_front();
11899   }
11900 
11901   auto Res = false;
11902 
11903   if (auto *IS = dyn_cast<IfStmt>(S)) {
11904     // Check if the statement is in one of the following forms
11905     // (cond-update-stmt):
11906     // if (expr ordop x) { x = expr; }
11907     // if (x ordop expr) { x = expr; }
11908     // if (x == e) { x = d; }
11909     Res = checkCondUpdateStmt(IS, ErrorInfo);
11910   } else {
11911     // Check if the statement is in one of the following forms (cond-expr-stmt):
11912     // x = expr ordop x ? expr : x;
11913     // x = x ordop expr ? expr : x;
11914     // x = x == e ? d : x;
11915     Res = checkCondExprStmt(S, ErrorInfo);
11916   }
11917 
11918   if (!Res)
11919     return false;
11920 
11921   return checkType(ErrorInfo);
11922 }
11923 
11924 class OpenMPAtomicCompareCaptureChecker final
11925     : public OpenMPAtomicCompareChecker {
11926 public:
11927   OpenMPAtomicCompareCaptureChecker(Sema &S) : OpenMPAtomicCompareChecker(S) {}
11928 
11929   Expr *getV() const { return V; }
11930   Expr *getR() const { return R; }
11931   bool isFailOnly() const { return IsFailOnly; }
11932   bool isPostfixUpdate() const { return IsPostfixUpdate; }
11933 
11934   /// Check if statement \a S is valid for <tt>atomic compare capture</tt>.
11935   bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
11936 
11937 private:
11938   bool checkType(ErrorInfoTy &ErrorInfo);
11939 
11940   // NOTE: Form 3, 4, 5 in the following comments mean the 3rd, 4th, and 5th
11941   // form of 'conditional-update-capture-atomic' structured block on the v5.2
11942   // spec p.p. 82:
11943   // (1) { v = x; cond-update-stmt }
11944   // (2) { cond-update-stmt v = x; }
11945   // (3) if(x == e) { x = d; } else { v = x; }
11946   // (4) { r = x == e; if(r) { x = d; } }
11947   // (5) { r = x == e; if(r) { x = d; } else { v = x; } }
11948 
11949   /// Check if it is valid 'if(x == e) { x = d; } else { v = x; }' (form 3)
11950   bool checkForm3(IfStmt *S, ErrorInfoTy &ErrorInfo);
11951 
11952   /// Check if it is valid '{ r = x == e; if(r) { x = d; } }',
11953   /// or '{ r = x == e; if(r) { x = d; } else { v = x; } }' (form 4 and 5)
11954   bool checkForm45(Stmt *S, ErrorInfoTy &ErrorInfo);
11955 
11956   /// 'v' lvalue part of the source atomic expression.
11957   Expr *V = nullptr;
11958   /// 'r' lvalue part of the source atomic expression.
11959   Expr *R = nullptr;
11960   /// If 'v' is only updated when the comparison fails.
11961   bool IsFailOnly = false;
11962   /// If original value of 'x' must be stored in 'v', not an updated one.
11963   bool IsPostfixUpdate = false;
11964 };
11965 
11966 bool OpenMPAtomicCompareCaptureChecker::checkType(ErrorInfoTy &ErrorInfo) {
11967   if (!OpenMPAtomicCompareChecker::checkType(ErrorInfo))
11968     return false;
11969 
11970   if (V && !CheckValue(V, ErrorInfo, true))
11971     return false;
11972 
11973   if (R && !CheckValue(R, ErrorInfo, true, true))
11974     return false;
11975 
11976   return true;
11977 }
11978 
11979 bool OpenMPAtomicCompareCaptureChecker::checkForm3(IfStmt *S,
11980                                                    ErrorInfoTy &ErrorInfo) {
11981   IsFailOnly = true;
11982 
11983   auto *Then = S->getThen();
11984   if (auto *CS = dyn_cast<CompoundStmt>(Then)) {
11985     if (CS->body_empty()) {
11986       ErrorInfo.Error = ErrorTy::NoStmt;
11987       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11988       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11989       return false;
11990     }
11991     if (CS->size() > 1) {
11992       ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11993       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11994       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11995       return false;
11996     }
11997     Then = CS->body_front();
11998   }
11999 
12000   auto *BO = dyn_cast<BinaryOperator>(Then);
12001   if (!BO) {
12002     ErrorInfo.Error = ErrorTy::NotAnAssignment;
12003     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc();
12004     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange();
12005     return false;
12006   }
12007   if (BO->getOpcode() != BO_Assign) {
12008     ErrorInfo.Error = ErrorTy::NotAnAssignment;
12009     ErrorInfo.ErrorLoc = BO->getExprLoc();
12010     ErrorInfo.NoteLoc = BO->getOperatorLoc();
12011     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12012     return false;
12013   }
12014 
12015   X = BO->getLHS();
12016   D = BO->getRHS();
12017 
12018   auto *Cond = dyn_cast<BinaryOperator>(S->getCond());
12019   if (!Cond) {
12020     ErrorInfo.Error = ErrorTy::NotABinaryOp;
12021     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc();
12022     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange();
12023     return false;
12024   }
12025   if (Cond->getOpcode() != BO_EQ) {
12026     ErrorInfo.Error = ErrorTy::NotEQ;
12027     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12028     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12029     return false;
12030   }
12031 
12032   if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
12033     E = Cond->getRHS();
12034   } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
12035     E = Cond->getLHS();
12036   } else {
12037     ErrorInfo.Error = ErrorTy::InvalidComparison;
12038     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12039     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12040     return false;
12041   }
12042 
12043   C = Cond;
12044 
12045   if (!S->getElse()) {
12046     ErrorInfo.Error = ErrorTy::NoElse;
12047     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
12048     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12049     return false;
12050   }
12051 
12052   auto *Else = S->getElse();
12053   if (auto *CS = dyn_cast<CompoundStmt>(Else)) {
12054     if (CS->body_empty()) {
12055       ErrorInfo.Error = ErrorTy::NoStmt;
12056       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12057       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12058       return false;
12059     }
12060     if (CS->size() > 1) {
12061       ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12062       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12063       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12064       return false;
12065     }
12066     Else = CS->body_front();
12067   }
12068 
12069   auto *ElseBO = dyn_cast<BinaryOperator>(Else);
12070   if (!ElseBO) {
12071     ErrorInfo.Error = ErrorTy::NotAnAssignment;
12072     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc();
12073     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange();
12074     return false;
12075   }
12076   if (ElseBO->getOpcode() != BO_Assign) {
12077     ErrorInfo.Error = ErrorTy::NotAnAssignment;
12078     ErrorInfo.ErrorLoc = ElseBO->getExprLoc();
12079     ErrorInfo.NoteLoc = ElseBO->getOperatorLoc();
12080     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange();
12081     return false;
12082   }
12083 
12084   if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) {
12085     ErrorInfo.Error = ErrorTy::InvalidAssignment;
12086     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseBO->getRHS()->getExprLoc();
12087     ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12088         ElseBO->getRHS()->getSourceRange();
12089     return false;
12090   }
12091 
12092   V = ElseBO->getLHS();
12093 
12094   return checkType(ErrorInfo);
12095 }
12096 
12097 bool OpenMPAtomicCompareCaptureChecker::checkForm45(Stmt *S,
12098                                                     ErrorInfoTy &ErrorInfo) {
12099   // We don't check here as they should be already done before call this
12100   // function.
12101   auto *CS = cast<CompoundStmt>(S);
12102   assert(CS->size() == 2 && "CompoundStmt size is not expected");
12103   auto *S1 = cast<BinaryOperator>(CS->body_front());
12104   auto *S2 = cast<IfStmt>(CS->body_back());
12105   assert(S1->getOpcode() == BO_Assign && "unexpected binary operator");
12106 
12107   if (!checkIfTwoExprsAreSame(ContextRef, S1->getLHS(), S2->getCond())) {
12108     ErrorInfo.Error = ErrorTy::InvalidCondition;
12109     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getCond()->getExprLoc();
12110     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S1->getLHS()->getSourceRange();
12111     return false;
12112   }
12113 
12114   R = S1->getLHS();
12115 
12116   auto *Then = S2->getThen();
12117   if (auto *ThenCS = dyn_cast<CompoundStmt>(Then)) {
12118     if (ThenCS->body_empty()) {
12119       ErrorInfo.Error = ErrorTy::NoStmt;
12120       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc();
12121       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange();
12122       return false;
12123     }
12124     if (ThenCS->size() > 1) {
12125       ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12126       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc();
12127       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange();
12128       return false;
12129     }
12130     Then = ThenCS->body_front();
12131   }
12132 
12133   auto *ThenBO = dyn_cast<BinaryOperator>(Then);
12134   if (!ThenBO) {
12135     ErrorInfo.Error = ErrorTy::NotAnAssignment;
12136     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getBeginLoc();
12137     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S2->getSourceRange();
12138     return false;
12139   }
12140   if (ThenBO->getOpcode() != BO_Assign) {
12141     ErrorInfo.Error = ErrorTy::NotAnAssignment;
12142     ErrorInfo.ErrorLoc = ThenBO->getExprLoc();
12143     ErrorInfo.NoteLoc = ThenBO->getOperatorLoc();
12144     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenBO->getSourceRange();
12145     return false;
12146   }
12147 
12148   X = ThenBO->getLHS();
12149   D = ThenBO->getRHS();
12150 
12151   auto *BO = cast<BinaryOperator>(S1->getRHS()->IgnoreImpCasts());
12152   if (BO->getOpcode() != BO_EQ) {
12153     ErrorInfo.Error = ErrorTy::NotEQ;
12154     ErrorInfo.ErrorLoc = BO->getExprLoc();
12155     ErrorInfo.NoteLoc = BO->getOperatorLoc();
12156     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12157     return false;
12158   }
12159 
12160   C = BO;
12161 
12162   if (checkIfTwoExprsAreSame(ContextRef, X, BO->getLHS())) {
12163     E = BO->getRHS();
12164   } else if (checkIfTwoExprsAreSame(ContextRef, X, BO->getRHS())) {
12165     E = BO->getLHS();
12166   } else {
12167     ErrorInfo.Error = ErrorTy::InvalidComparison;
12168     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getExprLoc();
12169     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12170     return false;
12171   }
12172 
12173   if (S2->getElse()) {
12174     IsFailOnly = true;
12175 
12176     auto *Else = S2->getElse();
12177     if (auto *ElseCS = dyn_cast<CompoundStmt>(Else)) {
12178       if (ElseCS->body_empty()) {
12179         ErrorInfo.Error = ErrorTy::NoStmt;
12180         ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc();
12181         ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange();
12182         return false;
12183       }
12184       if (ElseCS->size() > 1) {
12185         ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12186         ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc();
12187         ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange();
12188         return false;
12189       }
12190       Else = ElseCS->body_front();
12191     }
12192 
12193     auto *ElseBO = dyn_cast<BinaryOperator>(Else);
12194     if (!ElseBO) {
12195       ErrorInfo.Error = ErrorTy::NotAnAssignment;
12196       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc();
12197       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange();
12198       return false;
12199     }
12200     if (ElseBO->getOpcode() != BO_Assign) {
12201       ErrorInfo.Error = ErrorTy::NotAnAssignment;
12202       ErrorInfo.ErrorLoc = ElseBO->getExprLoc();
12203       ErrorInfo.NoteLoc = ElseBO->getOperatorLoc();
12204       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange();
12205       return false;
12206     }
12207     if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) {
12208       ErrorInfo.Error = ErrorTy::InvalidAssignment;
12209       ErrorInfo.ErrorLoc = ElseBO->getRHS()->getExprLoc();
12210       ErrorInfo.NoteLoc = X->getExprLoc();
12211       ErrorInfo.ErrorRange = ElseBO->getRHS()->getSourceRange();
12212       ErrorInfo.NoteRange = X->getSourceRange();
12213       return false;
12214     }
12215 
12216     V = ElseBO->getLHS();
12217   }
12218 
12219   return checkType(ErrorInfo);
12220 }
12221 
12222 bool OpenMPAtomicCompareCaptureChecker::checkStmt(Stmt *S,
12223                                                   ErrorInfoTy &ErrorInfo) {
12224   // if(x == e) { x = d; } else { v = x; }
12225   if (auto *IS = dyn_cast<IfStmt>(S))
12226     return checkForm3(IS, ErrorInfo);
12227 
12228   auto *CS = dyn_cast<CompoundStmt>(S);
12229   if (!CS) {
12230     ErrorInfo.Error = ErrorTy::NotCompoundStmt;
12231     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
12232     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12233     return false;
12234   }
12235   if (CS->body_empty()) {
12236     ErrorInfo.Error = ErrorTy::NoStmt;
12237     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12238     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12239     return false;
12240   }
12241 
12242   // { if(x == e) { x = d; } else { v = x; } }
12243   if (CS->size() == 1) {
12244     auto *IS = dyn_cast<IfStmt>(CS->body_front());
12245     if (!IS) {
12246       ErrorInfo.Error = ErrorTy::NotIfStmt;
12247       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->body_front()->getBeginLoc();
12248       ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12249           CS->body_front()->getSourceRange();
12250       return false;
12251     }
12252 
12253     return checkForm3(IS, ErrorInfo);
12254   } else if (CS->size() == 2) {
12255     auto *S1 = CS->body_front();
12256     auto *S2 = CS->body_back();
12257 
12258     Stmt *UpdateStmt = nullptr;
12259     Stmt *CondUpdateStmt = nullptr;
12260     Stmt *CondExprStmt = nullptr;
12261 
12262     if (auto *BO = dyn_cast<BinaryOperator>(S1)) {
12263       // It could be one of the following cases:
12264       // { v = x; cond-update-stmt }
12265       // { v = x; cond-expr-stmt }
12266       // { cond-expr-stmt; v = x; }
12267       // form 45
12268       if (isa<BinaryOperator>(BO->getRHS()->IgnoreImpCasts()) ||
12269           isa<ConditionalOperator>(BO->getRHS()->IgnoreImpCasts())) {
12270         // check if form 45
12271         if (isa<IfStmt>(S2))
12272           return checkForm45(CS, ErrorInfo);
12273         // { cond-expr-stmt; v = x; }
12274         CondExprStmt = S1;
12275         UpdateStmt = S2;
12276       } else {
12277         IsPostfixUpdate = true;
12278         UpdateStmt = S1;
12279         if (isa<IfStmt>(S2)) {
12280           // { v = x; cond-update-stmt }
12281           CondUpdateStmt = S2;
12282         } else {
12283           // { v = x; cond-expr-stmt }
12284           CondExprStmt = S2;
12285         }
12286       }
12287     } else {
12288       // { cond-update-stmt v = x; }
12289       UpdateStmt = S2;
12290       CondUpdateStmt = S1;
12291     }
12292 
12293     auto CheckCondUpdateStmt = [this, &ErrorInfo](Stmt *CUS) {
12294       auto *IS = dyn_cast<IfStmt>(CUS);
12295       if (!IS) {
12296         ErrorInfo.Error = ErrorTy::NotIfStmt;
12297         ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CUS->getBeginLoc();
12298         ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CUS->getSourceRange();
12299         return false;
12300       }
12301 
12302       return checkCondUpdateStmt(IS, ErrorInfo);
12303     };
12304 
12305     // CheckUpdateStmt has to be called *after* CheckCondUpdateStmt.
12306     auto CheckUpdateStmt = [this, &ErrorInfo](Stmt *US) {
12307       auto *BO = dyn_cast<BinaryOperator>(US);
12308       if (!BO) {
12309         ErrorInfo.Error = ErrorTy::NotAnAssignment;
12310         ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = US->getBeginLoc();
12311         ErrorInfo.ErrorRange = ErrorInfo.NoteRange = US->getSourceRange();
12312         return false;
12313       }
12314       if (BO->getOpcode() != BO_Assign) {
12315         ErrorInfo.Error = ErrorTy::NotAnAssignment;
12316         ErrorInfo.ErrorLoc = BO->getExprLoc();
12317         ErrorInfo.NoteLoc = BO->getOperatorLoc();
12318         ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12319         return false;
12320       }
12321       if (!checkIfTwoExprsAreSame(ContextRef, this->X, BO->getRHS())) {
12322         ErrorInfo.Error = ErrorTy::InvalidAssignment;
12323         ErrorInfo.ErrorLoc = BO->getRHS()->getExprLoc();
12324         ErrorInfo.NoteLoc = this->X->getExprLoc();
12325         ErrorInfo.ErrorRange = BO->getRHS()->getSourceRange();
12326         ErrorInfo.NoteRange = this->X->getSourceRange();
12327         return false;
12328       }
12329 
12330       this->V = BO->getLHS();
12331 
12332       return true;
12333     };
12334 
12335     if (CondUpdateStmt && !CheckCondUpdateStmt(CondUpdateStmt))
12336       return false;
12337     if (CondExprStmt && !checkCondExprStmt(CondExprStmt, ErrorInfo))
12338       return false;
12339     if (!CheckUpdateStmt(UpdateStmt))
12340       return false;
12341   } else {
12342     ErrorInfo.Error = ErrorTy::MoreThanTwoStmts;
12343     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12344     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12345     return false;
12346   }
12347 
12348   return checkType(ErrorInfo);
12349 }
12350 } // namespace
12351 
12352 StmtResult SemaOpenMP::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
12353                                                   Stmt *AStmt,
12354                                                   SourceLocation StartLoc,
12355                                                   SourceLocation EndLoc) {
12356   ASTContext &Context = getASTContext();
12357   // Register location of the first atomic directive.
12358   DSAStack->addAtomicDirectiveLoc(StartLoc);
12359   if (!AStmt)
12360     return StmtError();
12361 
12362   // 1.2.2 OpenMP Language Terminology
12363   // Structured block - An executable statement with a single entry at the
12364   // top and a single exit at the bottom.
12365   // The point of exit cannot be a branch out of the structured block.
12366   // longjmp() and throw() must not violate the entry/exit criteria.
12367   OpenMPClauseKind AtomicKind = OMPC_unknown;
12368   SourceLocation AtomicKindLoc;
12369   OpenMPClauseKind MemOrderKind = OMPC_unknown;
12370   SourceLocation MemOrderLoc;
12371   bool MutexClauseEncountered = false;
12372   llvm::SmallSet<OpenMPClauseKind, 2> EncounteredAtomicKinds;
12373   for (const OMPClause *C : Clauses) {
12374     switch (C->getClauseKind()) {
12375     case OMPC_read:
12376     case OMPC_write:
12377     case OMPC_update:
12378       MutexClauseEncountered = true;
12379       [[fallthrough]];
12380     case OMPC_capture:
12381     case OMPC_compare: {
12382       if (AtomicKind != OMPC_unknown && MutexClauseEncountered) {
12383         Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
12384             << SourceRange(C->getBeginLoc(), C->getEndLoc());
12385         Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
12386             << getOpenMPClauseName(AtomicKind);
12387       } else {
12388         AtomicKind = C->getClauseKind();
12389         AtomicKindLoc = C->getBeginLoc();
12390         if (!EncounteredAtomicKinds.insert(C->getClauseKind()).second) {
12391           Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
12392               << SourceRange(C->getBeginLoc(), C->getEndLoc());
12393           Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
12394               << getOpenMPClauseName(AtomicKind);
12395         }
12396       }
12397       break;
12398     }
12399     case OMPC_weak:
12400     case OMPC_fail: {
12401       if (!EncounteredAtomicKinds.contains(OMPC_compare)) {
12402         Diag(C->getBeginLoc(), diag::err_omp_atomic_no_compare)
12403             << getOpenMPClauseName(C->getClauseKind())
12404             << SourceRange(C->getBeginLoc(), C->getEndLoc());
12405         return StmtError();
12406       }
12407       break;
12408     }
12409     case OMPC_seq_cst:
12410     case OMPC_acq_rel:
12411     case OMPC_acquire:
12412     case OMPC_release:
12413     case OMPC_relaxed: {
12414       if (MemOrderKind != OMPC_unknown) {
12415         Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
12416             << getOpenMPDirectiveName(OMPD_atomic) << 0
12417             << SourceRange(C->getBeginLoc(), C->getEndLoc());
12418         Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
12419             << getOpenMPClauseName(MemOrderKind);
12420       } else {
12421         MemOrderKind = C->getClauseKind();
12422         MemOrderLoc = C->getBeginLoc();
12423       }
12424       break;
12425     }
12426     // The following clauses are allowed, but we don't need to do anything here.
12427     case OMPC_hint:
12428       break;
12429     default:
12430       llvm_unreachable("unknown clause is encountered");
12431     }
12432   }
12433   bool IsCompareCapture = false;
12434   if (EncounteredAtomicKinds.contains(OMPC_compare) &&
12435       EncounteredAtomicKinds.contains(OMPC_capture)) {
12436     IsCompareCapture = true;
12437     AtomicKind = OMPC_compare;
12438   }
12439   // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions
12440   // If atomic-clause is read then memory-order-clause must not be acq_rel or
12441   // release.
12442   // If atomic-clause is write then memory-order-clause must not be acq_rel or
12443   // acquire.
12444   // If atomic-clause is update or not present then memory-order-clause must not
12445   // be acq_rel or acquire.
12446   if ((AtomicKind == OMPC_read &&
12447        (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) ||
12448       ((AtomicKind == OMPC_write || AtomicKind == OMPC_update ||
12449         AtomicKind == OMPC_unknown) &&
12450        (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) {
12451     SourceLocation Loc = AtomicKindLoc;
12452     if (AtomicKind == OMPC_unknown)
12453       Loc = StartLoc;
12454     Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
12455         << getOpenMPClauseName(AtomicKind)
12456         << (AtomicKind == OMPC_unknown ? 1 : 0)
12457         << getOpenMPClauseName(MemOrderKind);
12458     Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
12459         << getOpenMPClauseName(MemOrderKind);
12460   }
12461 
12462   Stmt *Body = AStmt;
12463   if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
12464     Body = EWC->getSubExpr();
12465 
12466   Expr *X = nullptr;
12467   Expr *V = nullptr;
12468   Expr *E = nullptr;
12469   Expr *UE = nullptr;
12470   Expr *D = nullptr;
12471   Expr *CE = nullptr;
12472   Expr *R = nullptr;
12473   bool IsXLHSInRHSPart = false;
12474   bool IsPostfixUpdate = false;
12475   bool IsFailOnly = false;
12476   // OpenMP [2.12.6, atomic Construct]
12477   // In the next expressions:
12478   // * x and v (as applicable) are both l-value expressions with scalar type.
12479   // * During the execution of an atomic region, multiple syntactic
12480   // occurrences of x must designate the same storage location.
12481   // * Neither of v and expr (as applicable) may access the storage location
12482   // designated by x.
12483   // * Neither of x and expr (as applicable) may access the storage location
12484   // designated by v.
12485   // * expr is an expression with scalar type.
12486   // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
12487   // * binop, binop=, ++, and -- are not overloaded operators.
12488   // * The expression x binop expr must be numerically equivalent to x binop
12489   // (expr). This requirement is satisfied if the operators in expr have
12490   // precedence greater than binop, or by using parentheses around expr or
12491   // subexpressions of expr.
12492   // * The expression expr binop x must be numerically equivalent to (expr)
12493   // binop x. This requirement is satisfied if the operators in expr have
12494   // precedence equal to or greater than binop, or by using parentheses around
12495   // expr or subexpressions of expr.
12496   // * For forms that allow multiple occurrences of x, the number of times
12497   // that x is evaluated is unspecified.
12498   if (AtomicKind == OMPC_read) {
12499     enum {
12500       NotAnExpression,
12501       NotAnAssignmentOp,
12502       NotAScalarType,
12503       NotAnLValue,
12504       NoError
12505     } ErrorFound = NoError;
12506     SourceLocation ErrorLoc, NoteLoc;
12507     SourceRange ErrorRange, NoteRange;
12508     // If clause is read:
12509     //  v = x;
12510     if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12511       const auto *AtomicBinOp =
12512           dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12513       if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
12514         X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
12515         V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
12516         if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
12517             (V->isInstantiationDependent() || V->getType()->isScalarType())) {
12518           if (!X->isLValue() || !V->isLValue()) {
12519             const Expr *NotLValueExpr = X->isLValue() ? V : X;
12520             ErrorFound = NotAnLValue;
12521             ErrorLoc = AtomicBinOp->getExprLoc();
12522             ErrorRange = AtomicBinOp->getSourceRange();
12523             NoteLoc = NotLValueExpr->getExprLoc();
12524             NoteRange = NotLValueExpr->getSourceRange();
12525           }
12526         } else if (!X->isInstantiationDependent() ||
12527                    !V->isInstantiationDependent()) {
12528           const Expr *NotScalarExpr =
12529               (X->isInstantiationDependent() || X->getType()->isScalarType())
12530                   ? V
12531                   : X;
12532           ErrorFound = NotAScalarType;
12533           ErrorLoc = AtomicBinOp->getExprLoc();
12534           ErrorRange = AtomicBinOp->getSourceRange();
12535           NoteLoc = NotScalarExpr->getExprLoc();
12536           NoteRange = NotScalarExpr->getSourceRange();
12537         }
12538       } else if (!AtomicBody->isInstantiationDependent()) {
12539         ErrorFound = NotAnAssignmentOp;
12540         ErrorLoc = AtomicBody->getExprLoc();
12541         ErrorRange = AtomicBody->getSourceRange();
12542         NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
12543                               : AtomicBody->getExprLoc();
12544         NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
12545                                 : AtomicBody->getSourceRange();
12546       }
12547     } else {
12548       ErrorFound = NotAnExpression;
12549       NoteLoc = ErrorLoc = Body->getBeginLoc();
12550       NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
12551     }
12552     if (ErrorFound != NoError) {
12553       Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
12554           << ErrorRange;
12555       Diag(NoteLoc, diag::note_omp_atomic_read_write)
12556           << ErrorFound << NoteRange;
12557       return StmtError();
12558     }
12559     if (SemaRef.CurContext->isDependentContext())
12560       V = X = nullptr;
12561   } else if (AtomicKind == OMPC_write) {
12562     enum {
12563       NotAnExpression,
12564       NotAnAssignmentOp,
12565       NotAScalarType,
12566       NotAnLValue,
12567       NoError
12568     } ErrorFound = NoError;
12569     SourceLocation ErrorLoc, NoteLoc;
12570     SourceRange ErrorRange, NoteRange;
12571     // If clause is write:
12572     //  x = expr;
12573     if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12574       const auto *AtomicBinOp =
12575           dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12576       if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
12577         X = AtomicBinOp->getLHS();
12578         E = AtomicBinOp->getRHS();
12579         if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
12580             (E->isInstantiationDependent() || E->getType()->isScalarType())) {
12581           if (!X->isLValue()) {
12582             ErrorFound = NotAnLValue;
12583             ErrorLoc = AtomicBinOp->getExprLoc();
12584             ErrorRange = AtomicBinOp->getSourceRange();
12585             NoteLoc = X->getExprLoc();
12586             NoteRange = X->getSourceRange();
12587           }
12588         } else if (!X->isInstantiationDependent() ||
12589                    !E->isInstantiationDependent()) {
12590           const Expr *NotScalarExpr =
12591               (X->isInstantiationDependent() || X->getType()->isScalarType())
12592                   ? E
12593                   : X;
12594           ErrorFound = NotAScalarType;
12595           ErrorLoc = AtomicBinOp->getExprLoc();
12596           ErrorRange = AtomicBinOp->getSourceRange();
12597           NoteLoc = NotScalarExpr->getExprLoc();
12598           NoteRange = NotScalarExpr->getSourceRange();
12599         }
12600       } else if (!AtomicBody->isInstantiationDependent()) {
12601         ErrorFound = NotAnAssignmentOp;
12602         ErrorLoc = AtomicBody->getExprLoc();
12603         ErrorRange = AtomicBody->getSourceRange();
12604         NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
12605                               : AtomicBody->getExprLoc();
12606         NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
12607                                 : AtomicBody->getSourceRange();
12608       }
12609     } else {
12610       ErrorFound = NotAnExpression;
12611       NoteLoc = ErrorLoc = Body->getBeginLoc();
12612       NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
12613     }
12614     if (ErrorFound != NoError) {
12615       Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
12616           << ErrorRange;
12617       Diag(NoteLoc, diag::note_omp_atomic_read_write)
12618           << ErrorFound << NoteRange;
12619       return StmtError();
12620     }
12621     if (SemaRef.CurContext->isDependentContext())
12622       E = X = nullptr;
12623   } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
12624     // If clause is update:
12625     //  x++;
12626     //  x--;
12627     //  ++x;
12628     //  --x;
12629     //  x binop= expr;
12630     //  x = x binop expr;
12631     //  x = expr binop x;
12632     OpenMPAtomicUpdateChecker Checker(SemaRef);
12633     if (Checker.checkStatement(
12634             Body,
12635             (AtomicKind == OMPC_update)
12636                 ? diag::err_omp_atomic_update_not_expression_statement
12637                 : diag::err_omp_atomic_not_expression_statement,
12638             diag::note_omp_atomic_update))
12639       return StmtError();
12640     if (!SemaRef.CurContext->isDependentContext()) {
12641       E = Checker.getExpr();
12642       X = Checker.getX();
12643       UE = Checker.getUpdateExpr();
12644       IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12645     }
12646   } else if (AtomicKind == OMPC_capture) {
12647     enum {
12648       NotAnAssignmentOp,
12649       NotACompoundStatement,
12650       NotTwoSubstatements,
12651       NotASpecificExpression,
12652       NoError
12653     } ErrorFound = NoError;
12654     SourceLocation ErrorLoc, NoteLoc;
12655     SourceRange ErrorRange, NoteRange;
12656     if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12657       // If clause is a capture:
12658       //  v = x++;
12659       //  v = x--;
12660       //  v = ++x;
12661       //  v = --x;
12662       //  v = x binop= expr;
12663       //  v = x = x binop expr;
12664       //  v = x = expr binop x;
12665       const auto *AtomicBinOp =
12666           dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12667       if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
12668         V = AtomicBinOp->getLHS();
12669         Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
12670         OpenMPAtomicUpdateChecker Checker(SemaRef);
12671         if (Checker.checkStatement(
12672                 Body, diag::err_omp_atomic_capture_not_expression_statement,
12673                 diag::note_omp_atomic_update))
12674           return StmtError();
12675         E = Checker.getExpr();
12676         X = Checker.getX();
12677         UE = Checker.getUpdateExpr();
12678         IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12679         IsPostfixUpdate = Checker.isPostfixUpdate();
12680       } else if (!AtomicBody->isInstantiationDependent()) {
12681         ErrorLoc = AtomicBody->getExprLoc();
12682         ErrorRange = AtomicBody->getSourceRange();
12683         NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
12684                               : AtomicBody->getExprLoc();
12685         NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
12686                                 : AtomicBody->getSourceRange();
12687         ErrorFound = NotAnAssignmentOp;
12688       }
12689       if (ErrorFound != NoError) {
12690         Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
12691             << ErrorRange;
12692         Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
12693         return StmtError();
12694       }
12695       if (SemaRef.CurContext->isDependentContext())
12696         UE = V = E = X = nullptr;
12697     } else {
12698       // If clause is a capture:
12699       //  { v = x; x = expr; }
12700       //  { v = x; x++; }
12701       //  { v = x; x--; }
12702       //  { v = x; ++x; }
12703       //  { v = x; --x; }
12704       //  { v = x; x binop= expr; }
12705       //  { v = x; x = x binop expr; }
12706       //  { v = x; x = expr binop x; }
12707       //  { x++; v = x; }
12708       //  { x--; v = x; }
12709       //  { ++x; v = x; }
12710       //  { --x; v = x; }
12711       //  { x binop= expr; v = x; }
12712       //  { x = x binop expr; v = x; }
12713       //  { x = expr binop x; v = x; }
12714       if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
12715         // Check that this is { expr1; expr2; }
12716         if (CS->size() == 2) {
12717           Stmt *First = CS->body_front();
12718           Stmt *Second = CS->body_back();
12719           if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
12720             First = EWC->getSubExpr()->IgnoreParenImpCasts();
12721           if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
12722             Second = EWC->getSubExpr()->IgnoreParenImpCasts();
12723           // Need to find what subexpression is 'v' and what is 'x'.
12724           OpenMPAtomicUpdateChecker Checker(SemaRef);
12725           bool IsUpdateExprFound = !Checker.checkStatement(Second);
12726           BinaryOperator *BinOp = nullptr;
12727           if (IsUpdateExprFound) {
12728             BinOp = dyn_cast<BinaryOperator>(First);
12729             IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
12730           }
12731           if (IsUpdateExprFound && !SemaRef.CurContext->isDependentContext()) {
12732             //  { v = x; x++; }
12733             //  { v = x; x--; }
12734             //  { v = x; ++x; }
12735             //  { v = x; --x; }
12736             //  { v = x; x binop= expr; }
12737             //  { v = x; x = x binop expr; }
12738             //  { v = x; x = expr binop x; }
12739             // Check that the first expression has form v = x.
12740             Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
12741             llvm::FoldingSetNodeID XId, PossibleXId;
12742             Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
12743             PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
12744             IsUpdateExprFound = XId == PossibleXId;
12745             if (IsUpdateExprFound) {
12746               V = BinOp->getLHS();
12747               X = Checker.getX();
12748               E = Checker.getExpr();
12749               UE = Checker.getUpdateExpr();
12750               IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12751               IsPostfixUpdate = true;
12752             }
12753           }
12754           if (!IsUpdateExprFound) {
12755             IsUpdateExprFound = !Checker.checkStatement(First);
12756             BinOp = nullptr;
12757             if (IsUpdateExprFound) {
12758               BinOp = dyn_cast<BinaryOperator>(Second);
12759               IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
12760             }
12761             if (IsUpdateExprFound &&
12762                 !SemaRef.CurContext->isDependentContext()) {
12763               //  { x++; v = x; }
12764               //  { x--; v = x; }
12765               //  { ++x; v = x; }
12766               //  { --x; v = x; }
12767               //  { x binop= expr; v = x; }
12768               //  { x = x binop expr; v = x; }
12769               //  { x = expr binop x; v = x; }
12770               // Check that the second expression has form v = x.
12771               Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
12772               llvm::FoldingSetNodeID XId, PossibleXId;
12773               Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
12774               PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
12775               IsUpdateExprFound = XId == PossibleXId;
12776               if (IsUpdateExprFound) {
12777                 V = BinOp->getLHS();
12778                 X = Checker.getX();
12779                 E = Checker.getExpr();
12780                 UE = Checker.getUpdateExpr();
12781                 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12782                 IsPostfixUpdate = false;
12783               }
12784             }
12785           }
12786           if (!IsUpdateExprFound) {
12787             //  { v = x; x = expr; }
12788             auto *FirstExpr = dyn_cast<Expr>(First);
12789             auto *SecondExpr = dyn_cast<Expr>(Second);
12790             if (!FirstExpr || !SecondExpr ||
12791                 !(FirstExpr->isInstantiationDependent() ||
12792                   SecondExpr->isInstantiationDependent())) {
12793               auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
12794               if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
12795                 ErrorFound = NotAnAssignmentOp;
12796                 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
12797                                                 : First->getBeginLoc();
12798                 NoteRange = ErrorRange = FirstBinOp
12799                                              ? FirstBinOp->getSourceRange()
12800                                              : SourceRange(ErrorLoc, ErrorLoc);
12801               } else {
12802                 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
12803                 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
12804                   ErrorFound = NotAnAssignmentOp;
12805                   NoteLoc = ErrorLoc = SecondBinOp
12806                                            ? SecondBinOp->getOperatorLoc()
12807                                            : Second->getBeginLoc();
12808                   NoteRange = ErrorRange =
12809                       SecondBinOp ? SecondBinOp->getSourceRange()
12810                                   : SourceRange(ErrorLoc, ErrorLoc);
12811                 } else {
12812                   Expr *PossibleXRHSInFirst =
12813                       FirstBinOp->getRHS()->IgnoreParenImpCasts();
12814                   Expr *PossibleXLHSInSecond =
12815                       SecondBinOp->getLHS()->IgnoreParenImpCasts();
12816                   llvm::FoldingSetNodeID X1Id, X2Id;
12817                   PossibleXRHSInFirst->Profile(X1Id, Context,
12818                                                /*Canonical=*/true);
12819                   PossibleXLHSInSecond->Profile(X2Id, Context,
12820                                                 /*Canonical=*/true);
12821                   IsUpdateExprFound = X1Id == X2Id;
12822                   if (IsUpdateExprFound) {
12823                     V = FirstBinOp->getLHS();
12824                     X = SecondBinOp->getLHS();
12825                     E = SecondBinOp->getRHS();
12826                     UE = nullptr;
12827                     IsXLHSInRHSPart = false;
12828                     IsPostfixUpdate = true;
12829                   } else {
12830                     ErrorFound = NotASpecificExpression;
12831                     ErrorLoc = FirstBinOp->getExprLoc();
12832                     ErrorRange = FirstBinOp->getSourceRange();
12833                     NoteLoc = SecondBinOp->getLHS()->getExprLoc();
12834                     NoteRange = SecondBinOp->getRHS()->getSourceRange();
12835                   }
12836                 }
12837               }
12838             }
12839           }
12840         } else {
12841           NoteLoc = ErrorLoc = Body->getBeginLoc();
12842           NoteRange = ErrorRange =
12843               SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
12844           ErrorFound = NotTwoSubstatements;
12845         }
12846       } else {
12847         NoteLoc = ErrorLoc = Body->getBeginLoc();
12848         NoteRange = ErrorRange =
12849             SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
12850         ErrorFound = NotACompoundStatement;
12851       }
12852     }
12853     if (ErrorFound != NoError) {
12854       Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
12855           << ErrorRange;
12856       Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
12857       return StmtError();
12858     }
12859     if (SemaRef.CurContext->isDependentContext())
12860       UE = V = E = X = nullptr;
12861   } else if (AtomicKind == OMPC_compare) {
12862     if (IsCompareCapture) {
12863       OpenMPAtomicCompareCaptureChecker::ErrorInfoTy ErrorInfo;
12864       OpenMPAtomicCompareCaptureChecker Checker(SemaRef);
12865       if (!Checker.checkStmt(Body, ErrorInfo)) {
12866         Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare_capture)
12867             << ErrorInfo.ErrorRange;
12868         Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare)
12869             << ErrorInfo.Error << ErrorInfo.NoteRange;
12870         return StmtError();
12871       }
12872       X = Checker.getX();
12873       E = Checker.getE();
12874       D = Checker.getD();
12875       CE = Checker.getCond();
12876       V = Checker.getV();
12877       R = Checker.getR();
12878       // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'.
12879       IsXLHSInRHSPart = Checker.isXBinopExpr();
12880       IsFailOnly = Checker.isFailOnly();
12881       IsPostfixUpdate = Checker.isPostfixUpdate();
12882     } else {
12883       OpenMPAtomicCompareChecker::ErrorInfoTy ErrorInfo;
12884       OpenMPAtomicCompareChecker Checker(SemaRef);
12885       if (!Checker.checkStmt(Body, ErrorInfo)) {
12886         Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare)
12887             << ErrorInfo.ErrorRange;
12888         Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare)
12889             << ErrorInfo.Error << ErrorInfo.NoteRange;
12890         return StmtError();
12891       }
12892       X = Checker.getX();
12893       E = Checker.getE();
12894       D = Checker.getD();
12895       CE = Checker.getCond();
12896       // The weak clause may only appear if the resulting atomic operation is
12897       // an atomic conditional update for which the comparison tests for
12898       // equality. It was not possible to do this check in
12899       // OpenMPAtomicCompareChecker::checkStmt() as the check for OMPC_weak
12900       // could not be performed (Clauses are not available).
12901       auto *It = find_if(Clauses, [](OMPClause *C) {
12902         return C->getClauseKind() == llvm::omp::Clause::OMPC_weak;
12903       });
12904       if (It != Clauses.end()) {
12905         auto *Cond = dyn_cast<BinaryOperator>(CE);
12906         if (Cond->getOpcode() != BO_EQ) {
12907           ErrorInfo.Error = Checker.ErrorTy::NotAnAssignment;
12908           ErrorInfo.ErrorLoc = Cond->getExprLoc();
12909           ErrorInfo.NoteLoc = Cond->getOperatorLoc();
12910           ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12911 
12912           Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_weak_no_equality)
12913               << ErrorInfo.ErrorRange;
12914           return StmtError();
12915         }
12916       }
12917       // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'.
12918       IsXLHSInRHSPart = Checker.isXBinopExpr();
12919     }
12920   }
12921 
12922   SemaRef.setFunctionHasBranchProtectedScope();
12923 
12924   return OMPAtomicDirective::Create(
12925       Context, StartLoc, EndLoc, Clauses, AStmt,
12926       {X, V, R, E, UE, D, CE, IsXLHSInRHSPart, IsPostfixUpdate, IsFailOnly});
12927 }
12928 
12929 StmtResult SemaOpenMP::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
12930                                                   Stmt *AStmt,
12931                                                   SourceLocation StartLoc,
12932                                                   SourceLocation EndLoc) {
12933   if (!AStmt)
12934     return StmtError();
12935 
12936   CapturedStmt *CS = setBranchProtectedScope(SemaRef, OMPD_target, AStmt);
12937 
12938   // OpenMP [2.16, Nesting of Regions]
12939   // If specified, a teams construct must be contained within a target
12940   // construct. That target construct must contain no statements or directives
12941   // outside of the teams construct.
12942   if (DSAStack->hasInnerTeamsRegion()) {
12943     const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
12944     bool OMPTeamsFound = true;
12945     if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
12946       auto I = CS->body_begin();
12947       while (I != CS->body_end()) {
12948         const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
12949         bool IsTeams = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
12950         if (!IsTeams || I != CS->body_begin()) {
12951           OMPTeamsFound = false;
12952           if (IsTeams && I != CS->body_begin()) {
12953             // This is the two teams case. Since the InnerTeamsRegionLoc will
12954             // point to this second one reset the iterator to the other teams.
12955             --I;
12956           }
12957           break;
12958         }
12959         ++I;
12960       }
12961       assert(I != CS->body_end() && "Not found statement");
12962       S = *I;
12963     } else {
12964       const auto *OED = dyn_cast<OMPExecutableDirective>(S);
12965       OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
12966     }
12967     if (!OMPTeamsFound) {
12968       Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
12969       Diag(DSAStack->getInnerTeamsRegionLoc(),
12970            diag::note_omp_nested_teams_construct_here);
12971       Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
12972           << isa<OMPExecutableDirective>(S);
12973       return StmtError();
12974     }
12975   }
12976 
12977   return OMPTargetDirective::Create(getASTContext(), StartLoc, EndLoc, Clauses,
12978                                     AStmt);
12979 }
12980 
12981 StmtResult SemaOpenMP::ActOnOpenMPTargetParallelDirective(
12982     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12983     SourceLocation EndLoc) {
12984   if (!AStmt)
12985     return StmtError();
12986 
12987   setBranchProtectedScope(SemaRef, OMPD_target_parallel, AStmt);
12988 
12989   return OMPTargetParallelDirective::Create(
12990       getASTContext(), StartLoc, EndLoc, Clauses, AStmt,
12991       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
12992 }
12993 
12994 StmtResult SemaOpenMP::ActOnOpenMPTargetParallelForDirective(
12995     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12996     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12997   if (!AStmt)
12998     return StmtError();
12999 
13000   CapturedStmt *CS =
13001       setBranchProtectedScope(SemaRef, OMPD_target_parallel_for, AStmt);
13002 
13003   OMPLoopBasedDirective::HelperExprs B;
13004   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13005   // define the nested loops number.
13006   unsigned NestedLoopCount =
13007       checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
13008                       getOrderedNumberExpr(Clauses), CS, SemaRef, *DSAStack,
13009                       VarsWithImplicitDSA, B);
13010   if (NestedLoopCount == 0)
13011     return StmtError();
13012 
13013   if (finishLinearClauses(SemaRef, Clauses, B, DSAStack))
13014     return StmtError();
13015 
13016   return OMPTargetParallelForDirective::Create(
13017       getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13018       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
13019 }
13020 
13021 /// Check for existence of a map clause in the list of clauses.
13022 static bool hasClauses(ArrayRef<OMPClause *> Clauses,
13023                        const OpenMPClauseKind K) {
13024   return llvm::any_of(
13025       Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
13026 }
13027 
13028 template <typename... Params>
13029 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
13030                        const Params... ClauseTypes) {
13031   return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
13032 }
13033 
13034 /// Check if the variables in the mapping clause are externally visible.
13035 static bool isClauseMappable(ArrayRef<OMPClause *> Clauses) {
13036   for (const OMPClause *C : Clauses) {
13037     if (auto *TC = dyn_cast<OMPToClause>(C))
13038       return llvm::all_of(TC->all_decls(), [](ValueDecl *VD) {
13039         return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
13040                (VD->isExternallyVisible() &&
13041                 VD->getVisibility() != HiddenVisibility);
13042       });
13043     else if (auto *FC = dyn_cast<OMPFromClause>(C))
13044       return llvm::all_of(FC->all_decls(), [](ValueDecl *VD) {
13045         return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
13046                (VD->isExternallyVisible() &&
13047                 VD->getVisibility() != HiddenVisibility);
13048       });
13049   }
13050 
13051   return true;
13052 }
13053 
13054 StmtResult
13055 SemaOpenMP::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
13056                                            Stmt *AStmt, SourceLocation StartLoc,
13057                                            SourceLocation EndLoc) {
13058   if (!AStmt)
13059     return StmtError();
13060 
13061   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13062 
13063   // OpenMP [2.12.2, target data Construct, Restrictions]
13064   // At least one map, use_device_addr or use_device_ptr clause must appear on
13065   // the directive.
13066   if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) &&
13067       (getLangOpts().OpenMP < 50 ||
13068        !hasClauses(Clauses, OMPC_use_device_addr))) {
13069     StringRef Expected;
13070     if (getLangOpts().OpenMP < 50)
13071       Expected = "'map' or 'use_device_ptr'";
13072     else
13073       Expected = "'map', 'use_device_ptr', or 'use_device_addr'";
13074     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13075         << Expected << getOpenMPDirectiveName(OMPD_target_data);
13076     return StmtError();
13077   }
13078 
13079   SemaRef.setFunctionHasBranchProtectedScope();
13080 
13081   return OMPTargetDataDirective::Create(getASTContext(), StartLoc, EndLoc,
13082                                         Clauses, AStmt);
13083 }
13084 
13085 StmtResult SemaOpenMP::ActOnOpenMPTargetEnterDataDirective(
13086     ArrayRef<OMPClause *> Clauses, SourceLocation StartLoc,
13087     SourceLocation EndLoc, Stmt *AStmt) {
13088   if (!AStmt)
13089     return StmtError();
13090 
13091   setBranchProtectedScope(SemaRef, OMPD_target_enter_data, AStmt);
13092 
13093   // OpenMP [2.10.2, Restrictions, p. 99]
13094   // At least one map clause must appear on the directive.
13095   if (!hasClauses(Clauses, OMPC_map)) {
13096     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13097         << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
13098     return StmtError();
13099   }
13100 
13101   return OMPTargetEnterDataDirective::Create(getASTContext(), StartLoc, EndLoc,
13102                                              Clauses, AStmt);
13103 }
13104 
13105 StmtResult SemaOpenMP::ActOnOpenMPTargetExitDataDirective(
13106     ArrayRef<OMPClause *> Clauses, SourceLocation StartLoc,
13107     SourceLocation EndLoc, Stmt *AStmt) {
13108   if (!AStmt)
13109     return StmtError();
13110 
13111   setBranchProtectedScope(SemaRef, OMPD_target_exit_data, AStmt);
13112 
13113   // OpenMP [2.10.3, Restrictions, p. 102]
13114   // At least one map clause must appear on the directive.
13115   if (!hasClauses(Clauses, OMPC_map)) {
13116     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13117         << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
13118     return StmtError();
13119   }
13120 
13121   return OMPTargetExitDataDirective::Create(getASTContext(), StartLoc, EndLoc,
13122                                             Clauses, AStmt);
13123 }
13124 
13125 StmtResult SemaOpenMP::ActOnOpenMPTargetUpdateDirective(
13126     ArrayRef<OMPClause *> Clauses, SourceLocation StartLoc,
13127     SourceLocation EndLoc, Stmt *AStmt) {
13128   if (!AStmt)
13129     return StmtError();
13130 
13131   setBranchProtectedScope(SemaRef, OMPD_target_update, AStmt);
13132 
13133   if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
13134     Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
13135     return StmtError();
13136   }
13137 
13138   if (!isClauseMappable(Clauses)) {
13139     Diag(StartLoc, diag::err_omp_cannot_update_with_internal_linkage);
13140     return StmtError();
13141   }
13142 
13143   return OMPTargetUpdateDirective::Create(getASTContext(), StartLoc, EndLoc,
13144                                           Clauses, AStmt);
13145 }
13146 
13147 /// This checks whether a \p ClauseType clause \p C has at most \p Max
13148 /// expression. If not, a diag of number \p Diag will be emitted.
13149 template <typename ClauseType>
13150 static bool checkNumExprsInClause(SemaBase &SemaRef,
13151                                   ArrayRef<OMPClause *> Clauses,
13152                                   unsigned MaxNum, unsigned Diag) {
13153   auto ClauseItr = llvm::find_if(Clauses, llvm::IsaPred<ClauseType>);
13154   if (ClauseItr == Clauses.end())
13155     return true;
13156   const auto *C = cast<ClauseType>(*ClauseItr);
13157   auto VarList = C->getVarRefs();
13158   if (VarList.size() > MaxNum) {
13159     SemaRef.Diag(VarList[MaxNum]->getBeginLoc(), Diag)
13160         << getOpenMPClauseName(C->getClauseKind());
13161     return false;
13162   }
13163   return true;
13164 }
13165 
13166 StmtResult SemaOpenMP::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
13167                                                  Stmt *AStmt,
13168                                                  SourceLocation StartLoc,
13169                                                  SourceLocation EndLoc) {
13170   if (!AStmt)
13171     return StmtError();
13172 
13173   if (!checkNumExprsInClause<OMPNumTeamsClause>(
13174           *this, Clauses, /*MaxNum=*/1, diag::err_omp_multi_expr_not_allowed) ||
13175       !checkNumExprsInClause<OMPThreadLimitClause>(
13176           *this, Clauses, /*MaxNum=*/1, diag::err_omp_multi_expr_not_allowed))
13177     return StmtError();
13178 
13179   // Report affected OpenMP target offloading behavior when in HIP lang-mode.
13180   if (getLangOpts().HIP && (DSAStack->getParentDirective() == OMPD_target))
13181     Diag(StartLoc, diag::warn_hip_omp_target_directives);
13182 
13183   setBranchProtectedScope(SemaRef, OMPD_teams, AStmt);
13184 
13185   DSAStack->setParentTeamsRegionLoc(StartLoc);
13186 
13187   return OMPTeamsDirective::Create(getASTContext(), StartLoc, EndLoc, Clauses,
13188                                    AStmt);
13189 }
13190 
13191 StmtResult SemaOpenMP::ActOnOpenMPCancellationPointDirective(
13192     SourceLocation StartLoc, SourceLocation EndLoc,
13193     OpenMPDirectiveKind CancelRegion) {
13194   if (DSAStack->isParentNowaitRegion()) {
13195     Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
13196     return StmtError();
13197   }
13198   if (DSAStack->isParentOrderedRegion()) {
13199     Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
13200     return StmtError();
13201   }
13202   return OMPCancellationPointDirective::Create(getASTContext(), StartLoc,
13203                                                EndLoc, CancelRegion);
13204 }
13205 
13206 StmtResult SemaOpenMP::ActOnOpenMPCancelDirective(
13207     ArrayRef<OMPClause *> Clauses, SourceLocation StartLoc,
13208     SourceLocation EndLoc, OpenMPDirectiveKind CancelRegion) {
13209   if (DSAStack->isParentNowaitRegion()) {
13210     Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
13211     return StmtError();
13212   }
13213   if (DSAStack->isParentOrderedRegion()) {
13214     Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
13215     return StmtError();
13216   }
13217   DSAStack->setParentCancelRegion(/*Cancel=*/true);
13218   return OMPCancelDirective::Create(getASTContext(), StartLoc, EndLoc, Clauses,
13219                                     CancelRegion);
13220 }
13221 
13222 static bool checkReductionClauseWithNogroup(Sema &S,
13223                                             ArrayRef<OMPClause *> Clauses) {
13224   const OMPClause *ReductionClause = nullptr;
13225   const OMPClause *NogroupClause = nullptr;
13226   for (const OMPClause *C : Clauses) {
13227     if (C->getClauseKind() == OMPC_reduction) {
13228       ReductionClause = C;
13229       if (NogroupClause)
13230         break;
13231       continue;
13232     }
13233     if (C->getClauseKind() == OMPC_nogroup) {
13234       NogroupClause = C;
13235       if (ReductionClause)
13236         break;
13237       continue;
13238     }
13239   }
13240   if (ReductionClause && NogroupClause) {
13241     S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
13242         << SourceRange(NogroupClause->getBeginLoc(),
13243                        NogroupClause->getEndLoc());
13244     return true;
13245   }
13246   return false;
13247 }
13248 
13249 StmtResult SemaOpenMP::ActOnOpenMPTaskLoopDirective(
13250     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13251     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13252   if (!AStmt)
13253     return StmtError();
13254 
13255   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13256   OMPLoopBasedDirective::HelperExprs B;
13257   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13258   // define the nested loops number.
13259   unsigned NestedLoopCount =
13260       checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
13261                       /*OrderedLoopCountExpr=*/nullptr, AStmt, SemaRef,
13262                       *DSAStack, VarsWithImplicitDSA, B);
13263   if (NestedLoopCount == 0)
13264     return StmtError();
13265 
13266   assert((SemaRef.CurContext->isDependentContext() || B.builtAll()) &&
13267          "omp for loop exprs were not built");
13268 
13269   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13270   // The grainsize clause and num_tasks clause are mutually exclusive and may
13271   // not appear on the same taskloop directive.
13272   if (checkMutuallyExclusiveClauses(SemaRef, Clauses,
13273                                     {OMPC_grainsize, OMPC_num_tasks}))
13274     return StmtError();
13275   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13276   // If a reduction clause is present on the taskloop directive, the nogroup
13277   // clause must not be specified.
13278   if (checkReductionClauseWithNogroup(SemaRef, Clauses))
13279     return StmtError();
13280 
13281   SemaRef.setFunctionHasBranchProtectedScope();
13282   return OMPTaskLoopDirective::Create(getASTContext(), StartLoc, EndLoc,
13283                                       NestedLoopCount, Clauses, AStmt, B,
13284                                       DSAStack->isCancelRegion());
13285 }
13286 
13287 StmtResult SemaOpenMP::ActOnOpenMPTaskLoopSimdDirective(
13288     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13289     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13290   if (!AStmt)
13291     return StmtError();
13292 
13293   CapturedStmt *CS =
13294       setBranchProtectedScope(SemaRef, OMPD_taskloop_simd, AStmt);
13295 
13296   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13297   OMPLoopBasedDirective::HelperExprs B;
13298   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13299   // define the nested loops number.
13300   unsigned NestedLoopCount =
13301       checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
13302                       /*OrderedLoopCountExpr=*/nullptr, CS, SemaRef, *DSAStack,
13303                       VarsWithImplicitDSA, B);
13304   if (NestedLoopCount == 0)
13305     return StmtError();
13306 
13307   if (finishLinearClauses(SemaRef, Clauses, B, DSAStack))
13308     return StmtError();
13309 
13310   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13311   // The grainsize clause and num_tasks clause are mutually exclusive and may
13312   // not appear on the same taskloop directive.
13313   if (checkMutuallyExclusiveClauses(SemaRef, Clauses,
13314                                     {OMPC_grainsize, OMPC_num_tasks}))
13315     return StmtError();
13316   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13317   // If a reduction clause is present on the taskloop directive, the nogroup
13318   // clause must not be specified.
13319   if (checkReductionClauseWithNogroup(SemaRef, Clauses))
13320     return StmtError();
13321   if (checkSimdlenSafelenSpecified(SemaRef, Clauses))
13322     return StmtError();
13323 
13324   return OMPTaskLoopSimdDirective::Create(getASTContext(), StartLoc, EndLoc,
13325                                           NestedLoopCount, Clauses, AStmt, B);
13326 }
13327 
13328 StmtResult SemaOpenMP::ActOnOpenMPMasterTaskLoopDirective(
13329     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13330     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13331   if (!AStmt)
13332     return StmtError();
13333 
13334   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13335   OMPLoopBasedDirective::HelperExprs B;
13336   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13337   // define the nested loops number.
13338   unsigned NestedLoopCount =
13339       checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses),
13340                       /*OrderedLoopCountExpr=*/nullptr, AStmt, SemaRef,
13341                       *DSAStack, VarsWithImplicitDSA, B);
13342   if (NestedLoopCount == 0)
13343     return StmtError();
13344 
13345   assert((SemaRef.CurContext->isDependentContext() || B.builtAll()) &&
13346          "omp for loop exprs were not built");
13347 
13348   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13349   // The grainsize clause and num_tasks clause are mutually exclusive and may
13350   // not appear on the same taskloop directive.
13351   if (checkMutuallyExclusiveClauses(SemaRef, Clauses,
13352                                     {OMPC_grainsize, OMPC_num_tasks}))
13353     return StmtError();
13354   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13355   // If a reduction clause is present on the taskloop directive, the nogroup
13356   // clause must not be specified.
13357   if (checkReductionClauseWithNogroup(SemaRef, Clauses))
13358     return StmtError();
13359 
13360   SemaRef.setFunctionHasBranchProtectedScope();
13361   return OMPMasterTaskLoopDirective::Create(getASTContext(), StartLoc, EndLoc,
13362                                             NestedLoopCount, Clauses, AStmt, B,
13363                                             DSAStack->isCancelRegion());
13364 }
13365 
13366 StmtResult SemaOpenMP::ActOnOpenMPMaskedTaskLoopDirective(
13367     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13368     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13369   if (!AStmt)
13370     return StmtError();
13371 
13372   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13373   OMPLoopBasedDirective::HelperExprs B;
13374   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13375   // define the nested loops number.
13376   unsigned NestedLoopCount =
13377       checkOpenMPLoop(OMPD_masked_taskloop, getCollapseNumberExpr(Clauses),
13378                       /*OrderedLoopCountExpr=*/nullptr, AStmt, SemaRef,
13379                       *DSAStack, VarsWithImplicitDSA, B);
13380   if (NestedLoopCount == 0)
13381     return StmtError();
13382 
13383   assert((SemaRef.CurContext->isDependentContext() || B.builtAll()) &&
13384          "omp for loop exprs were not built");
13385 
13386   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13387   // The grainsize clause and num_tasks clause are mutually exclusive and may
13388   // not appear on the same taskloop directive.
13389   if (checkMutuallyExclusiveClauses(SemaRef, Clauses,
13390                                     {OMPC_grainsize, OMPC_num_tasks}))
13391     return StmtError();
13392   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13393   // If a reduction clause is present on the taskloop directive, the nogroup
13394   // clause must not be specified.
13395   if (checkReductionClauseWithNogroup(SemaRef, Clauses))
13396     return StmtError();
13397 
13398   SemaRef.setFunctionHasBranchProtectedScope();
13399   return OMPMaskedTaskLoopDirective::Create(getASTContext(), StartLoc, EndLoc,
13400                                             NestedLoopCount, Clauses, AStmt, B,
13401                                             DSAStack->isCancelRegion());
13402 }
13403 
13404 StmtResult SemaOpenMP::ActOnOpenMPMasterTaskLoopSimdDirective(
13405     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13406     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13407   if (!AStmt)
13408     return StmtError();
13409 
13410   CapturedStmt *CS =
13411       setBranchProtectedScope(SemaRef, OMPD_master_taskloop_simd, AStmt);
13412 
13413   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13414   OMPLoopBasedDirective::HelperExprs B;
13415   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13416   // define the nested loops number.
13417   unsigned NestedLoopCount =
13418       checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses),
13419                       /*OrderedLoopCountExpr=*/nullptr, CS, SemaRef, *DSAStack,
13420                       VarsWithImplicitDSA, B);
13421   if (NestedLoopCount == 0)
13422     return StmtError();
13423 
13424   if (finishLinearClauses(SemaRef, Clauses, B, DSAStack))
13425     return StmtError();
13426 
13427   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13428   // The grainsize clause and num_tasks clause are mutually exclusive and may
13429   // not appear on the same taskloop directive.
13430   if (checkMutuallyExclusiveClauses(SemaRef, Clauses,
13431                                     {OMPC_grainsize, OMPC_num_tasks}))
13432     return StmtError();
13433   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13434   // If a reduction clause is present on the taskloop directive, the nogroup
13435   // clause must not be specified.
13436   if (checkReductionClauseWithNogroup(SemaRef, Clauses))
13437     return StmtError();
13438   if (checkSimdlenSafelenSpecified(SemaRef, Clauses))
13439     return StmtError();
13440 
13441   return OMPMasterTaskLoopSimdDirective::Create(
13442       getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13443 }
13444 
13445 StmtResult SemaOpenMP::ActOnOpenMPMaskedTaskLoopSimdDirective(
13446     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13447     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13448   if (!AStmt)
13449     return StmtError();
13450 
13451   CapturedStmt *CS =
13452       setBranchProtectedScope(SemaRef, OMPD_masked_taskloop_simd, AStmt);
13453 
13454   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13455   OMPLoopBasedDirective::HelperExprs B;
13456   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13457   // define the nested loops number.
13458   unsigned NestedLoopCount =
13459       checkOpenMPLoop(OMPD_masked_taskloop_simd, getCollapseNumberExpr(Clauses),
13460                       /*OrderedLoopCountExpr=*/nullptr, CS, SemaRef, *DSAStack,
13461                       VarsWithImplicitDSA, B);
13462   if (NestedLoopCount == 0)
13463     return StmtError();
13464 
13465   if (finishLinearClauses(SemaRef, Clauses, B, DSAStack))
13466     return StmtError();
13467 
13468   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13469   // The grainsize clause and num_tasks clause are mutually exclusive and may
13470   // not appear on the same taskloop directive.
13471   if (checkMutuallyExclusiveClauses(SemaRef, Clauses,
13472                                     {OMPC_grainsize, OMPC_num_tasks}))
13473     return StmtError();
13474   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13475   // If a reduction clause is present on the taskloop directive, the nogroup
13476   // clause must not be specified.
13477   if (checkReductionClauseWithNogroup(SemaRef, Clauses))
13478     return StmtError();
13479   if (checkSimdlenSafelenSpecified(SemaRef, Clauses))
13480     return StmtError();
13481 
13482   return OMPMaskedTaskLoopSimdDirective::Create(
13483       getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13484 }
13485 
13486 StmtResult SemaOpenMP::ActOnOpenMPParallelMasterTaskLoopDirective(
13487     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13488     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13489   if (!AStmt)
13490     return StmtError();
13491 
13492   CapturedStmt *CS =
13493       setBranchProtectedScope(SemaRef, OMPD_parallel_master_taskloop, AStmt);
13494 
13495   OMPLoopBasedDirective::HelperExprs B;
13496   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13497   // define the nested loops number.
13498   unsigned NestedLoopCount = checkOpenMPLoop(
13499       OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses),
13500       /*OrderedLoopCountExpr=*/nullptr, CS, SemaRef, *DSAStack,
13501       VarsWithImplicitDSA, B);
13502   if (NestedLoopCount == 0)
13503     return StmtError();
13504 
13505   assert((SemaRef.CurContext->isDependentContext() || B.builtAll()) &&
13506          "omp for loop exprs were not built");
13507 
13508   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13509   // The grainsize clause and num_tasks clause are mutually exclusive and may
13510   // not appear on the same taskloop directive.
13511   if (checkMutuallyExclusiveClauses(SemaRef, Clauses,
13512                                     {OMPC_grainsize, OMPC_num_tasks}))
13513     return StmtError();
13514   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13515   // If a reduction clause is present on the taskloop directive, the nogroup
13516   // clause must not be specified.
13517   if (checkReductionClauseWithNogroup(SemaRef, Clauses))
13518     return StmtError();
13519 
13520   return OMPParallelMasterTaskLoopDirective::Create(
13521       getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13522       DSAStack->isCancelRegion());
13523 }
13524 
13525 StmtResult SemaOpenMP::ActOnOpenMPParallelMaskedTaskLoopDirective(
13526     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13527     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13528   if (!AStmt)
13529     return StmtError();
13530 
13531   CapturedStmt *CS =
13532       setBranchProtectedScope(SemaRef, OMPD_parallel_masked_taskloop, AStmt);
13533 
13534   OMPLoopBasedDirective::HelperExprs B;
13535   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13536   // define the nested loops number.
13537   unsigned NestedLoopCount = checkOpenMPLoop(
13538       OMPD_parallel_masked_taskloop, getCollapseNumberExpr(Clauses),
13539       /*OrderedLoopCountExpr=*/nullptr, CS, SemaRef, *DSAStack,
13540       VarsWithImplicitDSA, B);
13541   if (NestedLoopCount == 0)
13542     return StmtError();
13543 
13544   assert((SemaRef.CurContext->isDependentContext() || B.builtAll()) &&
13545          "omp for loop exprs were not built");
13546 
13547   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13548   // The grainsize clause and num_tasks clause are mutually exclusive and may
13549   // not appear on the same taskloop directive.
13550   if (checkMutuallyExclusiveClauses(SemaRef, Clauses,
13551                                     {OMPC_grainsize, OMPC_num_tasks}))
13552     return StmtError();
13553   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13554   // If a reduction clause is present on the taskloop directive, the nogroup
13555   // clause must not be specified.
13556   if (checkReductionClauseWithNogroup(SemaRef, Clauses))
13557     return StmtError();
13558 
13559   return OMPParallelMaskedTaskLoopDirective::Create(
13560       getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13561       DSAStack->isCancelRegion());
13562 }
13563 
13564 StmtResult SemaOpenMP::ActOnOpenMPParallelMasterTaskLoopSimdDirective(
13565     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13566     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13567   if (!AStmt)
13568     return StmtError();
13569 
13570   CapturedStmt *CS = setBranchProtectedScope(
13571       SemaRef, OMPD_parallel_master_taskloop_simd, AStmt);
13572 
13573   OMPLoopBasedDirective::HelperExprs B;
13574   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13575   // define the nested loops number.
13576   unsigned NestedLoopCount = checkOpenMPLoop(
13577       OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses),
13578       /*OrderedLoopCountExpr=*/nullptr, CS, SemaRef, *DSAStack,
13579       VarsWithImplicitDSA, B);
13580   if (NestedLoopCount == 0)
13581     return StmtError();
13582 
13583   if (finishLinearClauses(SemaRef, Clauses, B, DSAStack))
13584     return StmtError();
13585 
13586   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13587   // The grainsize clause and num_tasks clause are mutually exclusive and may
13588   // not appear on the same taskloop directive.
13589   if (checkMutuallyExclusiveClauses(SemaRef, Clauses,
13590                                     {OMPC_grainsize, OMPC_num_tasks}))
13591     return StmtError();
13592   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13593   // If a reduction clause is present on the taskloop directive, the nogroup
13594   // clause must not be specified.
13595   if (checkReductionClauseWithNogroup(SemaRef, Clauses))
13596     return StmtError();
13597   if (checkSimdlenSafelenSpecified(SemaRef, Clauses))
13598     return StmtError();
13599 
13600   return OMPParallelMasterTaskLoopSimdDirective::Create(
13601       getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13602 }
13603 
13604 StmtResult SemaOpenMP::ActOnOpenMPParallelMaskedTaskLoopSimdDirective(
13605     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13606     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13607   if (!AStmt)
13608     return StmtError();
13609 
13610   CapturedStmt *CS = setBranchProtectedScope(
13611       SemaRef, OMPD_parallel_masked_taskloop_simd, AStmt);
13612 
13613   OMPLoopBasedDirective::HelperExprs B;
13614   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13615   // define the nested loops number.
13616   unsigned NestedLoopCount = checkOpenMPLoop(
13617       OMPD_parallel_masked_taskloop_simd, getCollapseNumberExpr(Clauses),
13618       /*OrderedLoopCountExpr=*/nullptr, CS, SemaRef, *DSAStack,
13619       VarsWithImplicitDSA, B);
13620   if (NestedLoopCount == 0)
13621     return StmtError();
13622 
13623   if (finishLinearClauses(SemaRef, Clauses, B, DSAStack))
13624     return StmtError();
13625 
13626   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13627   // The grainsize clause and num_tasks clause are mutually exclusive and may
13628   // not appear on the same taskloop directive.
13629   if (checkMutuallyExclusiveClauses(SemaRef, Clauses,
13630                                     {OMPC_grainsize, OMPC_num_tasks}))
13631     return StmtError();
13632   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13633   // If a reduction clause is present on the taskloop directive, the nogroup
13634   // clause must not be specified.
13635   if (checkReductionClauseWithNogroup(SemaRef, Clauses))
13636     return StmtError();
13637   if (checkSimdlenSafelenSpecified(SemaRef, Clauses))
13638     return StmtError();
13639 
13640   return OMPParallelMaskedTaskLoopSimdDirective::Create(
13641       getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13642 }
13643 
13644 StmtResult SemaOpenMP::ActOnOpenMPDistributeDirective(
13645     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13646     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13647   if (!AStmt)
13648     return StmtError();
13649 
13650   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13651   OMPLoopBasedDirective::HelperExprs B;
13652   // In presence of clause 'collapse' with number of loops, it will
13653   // define the nested loops number.
13654   unsigned NestedLoopCount =
13655       checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
13656                       nullptr /*ordered not a clause on distribute*/, AStmt,
13657                       SemaRef, *DSAStack, VarsWithImplicitDSA, B);
13658   if (NestedLoopCount == 0)
13659     return StmtError();
13660 
13661   assert((SemaRef.CurContext->isDependentContext() || B.builtAll()) &&
13662          "omp for loop exprs were not built");
13663 
13664   SemaRef.setFunctionHasBranchProtectedScope();
13665   auto *DistributeDirective = OMPDistributeDirective::Create(
13666       getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13667   return DistributeDirective;
13668 }
13669 
13670 StmtResult SemaOpenMP::ActOnOpenMPDistributeParallelForDirective(
13671     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13672     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13673   if (!AStmt)
13674     return StmtError();
13675 
13676   CapturedStmt *CS =
13677       setBranchProtectedScope(SemaRef, OMPD_distribute_parallel_for, AStmt);
13678 
13679   OMPLoopBasedDirective::HelperExprs B;
13680   // In presence of clause 'collapse' with number of loops, it will
13681   // define the nested loops number.
13682   unsigned NestedLoopCount = checkOpenMPLoop(
13683       OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
13684       nullptr /*ordered not a clause on distribute*/, CS, SemaRef, *DSAStack,
13685       VarsWithImplicitDSA, B);
13686   if (NestedLoopCount == 0)
13687     return StmtError();
13688 
13689   assert((SemaRef.CurContext->isDependentContext() || B.builtAll()) &&
13690          "omp for loop exprs were not built");
13691 
13692   return OMPDistributeParallelForDirective::Create(
13693       getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13694       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
13695 }
13696 
13697 StmtResult SemaOpenMP::ActOnOpenMPDistributeParallelForSimdDirective(
13698     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13699     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13700   if (!AStmt)
13701     return StmtError();
13702 
13703   CapturedStmt *CS = setBranchProtectedScope(
13704       SemaRef, OMPD_distribute_parallel_for_simd, AStmt);
13705 
13706   OMPLoopBasedDirective::HelperExprs B;
13707   // In presence of clause 'collapse' with number of loops, it will
13708   // define the nested loops number.
13709   unsigned NestedLoopCount = checkOpenMPLoop(
13710       OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
13711       nullptr /*ordered not a clause on distribute*/, CS, SemaRef, *DSAStack,
13712       VarsWithImplicitDSA, B);
13713   if (NestedLoopCount == 0)
13714     return StmtError();
13715 
13716   if (finishLinearClauses(SemaRef, Clauses, B, DSAStack))
13717     return StmtError();
13718 
13719   if (checkSimdlenSafelenSpecified(SemaRef, Clauses))
13720     return StmtError();
13721 
13722   return OMPDistributeParallelForSimdDirective::Create(
13723       getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13724 }
13725 
13726 StmtResult SemaOpenMP::ActOnOpenMPDistributeSimdDirective(
13727     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13728     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13729   if (!AStmt)
13730     return StmtError();
13731 
13732   CapturedStmt *CS =
13733       setBranchProtectedScope(SemaRef, OMPD_distribute_simd, AStmt);
13734 
13735   OMPLoopBasedDirective::HelperExprs B;
13736   // In presence of clause 'collapse' with number of loops, it will
13737   // define the nested loops number.
13738   unsigned NestedLoopCount =
13739       checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
13740                       nullptr /*ordered not a clause on distribute*/, CS,
13741                       SemaRef, *DSAStack, VarsWithImplicitDSA, B);
13742   if (NestedLoopCount == 0)
13743     return StmtError();
13744 
13745   if (finishLinearClauses(SemaRef, Clauses, B, DSAStack))
13746     return StmtError();
13747 
13748   if (checkSimdlenSafelenSpecified(SemaRef, Clauses))
13749     return StmtError();
13750 
13751   return OMPDistributeSimdDirective::Create(getASTContext(), StartLoc, EndLoc,
13752                                             NestedLoopCount, Clauses, AStmt, B);
13753 }
13754 
13755 StmtResult SemaOpenMP::ActOnOpenMPTargetParallelForSimdDirective(
13756     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13757     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13758   if (!AStmt)
13759     return StmtError();
13760 
13761   CapturedStmt *CS =
13762       setBranchProtectedScope(SemaRef, OMPD_target_parallel_for_simd, AStmt);
13763 
13764   OMPLoopBasedDirective::HelperExprs B;
13765   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13766   // define the nested loops number.
13767   unsigned NestedLoopCount = checkOpenMPLoop(
13768       OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
13769       getOrderedNumberExpr(Clauses), CS, SemaRef, *DSAStack,
13770       VarsWithImplicitDSA, B);
13771   if (NestedLoopCount == 0)
13772     return StmtError();
13773 
13774   if (finishLinearClauses(SemaRef, Clauses, B, DSAStack))
13775     return StmtError();
13776 
13777   if (checkSimdlenSafelenSpecified(SemaRef, Clauses))
13778     return StmtError();
13779 
13780   return OMPTargetParallelForSimdDirective::Create(
13781       getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13782 }
13783 
13784 StmtResult SemaOpenMP::ActOnOpenMPTargetSimdDirective(
13785     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13786     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13787   if (!AStmt)
13788     return StmtError();
13789 
13790   CapturedStmt *CS = setBranchProtectedScope(SemaRef, OMPD_target_simd, AStmt);
13791 
13792   OMPLoopBasedDirective::HelperExprs B;
13793   // In presence of clause 'collapse' with number of loops, it will define the
13794   // nested loops number.
13795   unsigned NestedLoopCount =
13796       checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
13797                       getOrderedNumberExpr(Clauses), CS, SemaRef, *DSAStack,
13798                       VarsWithImplicitDSA, B);
13799   if (NestedLoopCount == 0)
13800     return StmtError();
13801 
13802   if (finishLinearClauses(SemaRef, Clauses, B, DSAStack))
13803     return StmtError();
13804 
13805   if (checkSimdlenSafelenSpecified(SemaRef, Clauses))
13806     return StmtError();
13807 
13808   return OMPTargetSimdDirective::Create(getASTContext(), StartLoc, EndLoc,
13809                                         NestedLoopCount, Clauses, AStmt, B);
13810 }
13811 
13812 StmtResult SemaOpenMP::ActOnOpenMPTeamsDistributeDirective(
13813     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13814     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13815   if (!AStmt)
13816     return StmtError();
13817 
13818   CapturedStmt *CS =
13819       setBranchProtectedScope(SemaRef, OMPD_teams_distribute, AStmt);
13820 
13821   OMPLoopBasedDirective::HelperExprs B;
13822   // In presence of clause 'collapse' with number of loops, it will
13823   // define the nested loops number.
13824   unsigned NestedLoopCount =
13825       checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
13826                       nullptr /*ordered not a clause on distribute*/, CS,
13827                       SemaRef, *DSAStack, VarsWithImplicitDSA, B);
13828   if (NestedLoopCount == 0)
13829     return StmtError();
13830 
13831   assert((SemaRef.CurContext->isDependentContext() || B.builtAll()) &&
13832          "omp teams distribute loop exprs were not built");
13833 
13834   DSAStack->setParentTeamsRegionLoc(StartLoc);
13835 
13836   return OMPTeamsDistributeDirective::Create(
13837       getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13838 }
13839 
13840 StmtResult SemaOpenMP::ActOnOpenMPTeamsDistributeSimdDirective(
13841     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13842     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13843   if (!AStmt)
13844     return StmtError();
13845 
13846   CapturedStmt *CS =
13847       setBranchProtectedScope(SemaRef, OMPD_teams_distribute_simd, AStmt);
13848 
13849   OMPLoopBasedDirective::HelperExprs B;
13850   // In presence of clause 'collapse' with number of loops, it will
13851   // define the nested loops number.
13852   unsigned NestedLoopCount = checkOpenMPLoop(
13853       OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
13854       nullptr /*ordered not a clause on distribute*/, CS, SemaRef, *DSAStack,
13855       VarsWithImplicitDSA, B);
13856   if (NestedLoopCount == 0)
13857     return StmtError();
13858 
13859   if (finishLinearClauses(SemaRef, Clauses, B, DSAStack))
13860     return StmtError();
13861 
13862   if (checkSimdlenSafelenSpecified(SemaRef, Clauses))
13863     return StmtError();
13864 
13865   DSAStack->setParentTeamsRegionLoc(StartLoc);
13866 
13867   return OMPTeamsDistributeSimdDirective::Create(
13868       getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13869 }
13870 
13871 StmtResult SemaOpenMP::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
13872     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13873     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13874   if (!AStmt)
13875     return StmtError();
13876 
13877   CapturedStmt *CS = setBranchProtectedScope(
13878       SemaRef, OMPD_teams_distribute_parallel_for_simd, AStmt);
13879 
13880   OMPLoopBasedDirective::HelperExprs B;
13881   // In presence of clause 'collapse' with number of loops, it will
13882   // define the nested loops number.
13883   unsigned NestedLoopCount = checkOpenMPLoop(
13884       OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
13885       nullptr /*ordered not a clause on distribute*/, CS, SemaRef, *DSAStack,
13886       VarsWithImplicitDSA, B);
13887   if (NestedLoopCount == 0)
13888     return StmtError();
13889 
13890   if (finishLinearClauses(SemaRef, Clauses, B, DSAStack))
13891     return StmtError();
13892 
13893   if (checkSimdlenSafelenSpecified(SemaRef, Clauses))
13894     return StmtError();
13895 
13896   DSAStack->setParentTeamsRegionLoc(StartLoc);
13897 
13898   return OMPTeamsDistributeParallelForSimdDirective::Create(
13899       getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13900 }
13901 
13902 StmtResult SemaOpenMP::ActOnOpenMPTeamsDistributeParallelForDirective(
13903     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13904     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13905   if (!AStmt)
13906     return StmtError();
13907 
13908   CapturedStmt *CS = setBranchProtectedScope(
13909       SemaRef, OMPD_teams_distribute_parallel_for, AStmt);
13910 
13911   OMPLoopBasedDirective::HelperExprs B;
13912   // In presence of clause 'collapse' with number of loops, it will
13913   // define the nested loops number.
13914   unsigned NestedLoopCount = checkOpenMPLoop(
13915       OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
13916       nullptr /*ordered not a clause on distribute*/, CS, SemaRef, *DSAStack,
13917       VarsWithImplicitDSA, B);
13918 
13919   if (NestedLoopCount == 0)
13920     return StmtError();
13921 
13922   assert((SemaRef.CurContext->isDependentContext() || B.builtAll()) &&
13923          "omp for loop exprs were not built");
13924 
13925   DSAStack->setParentTeamsRegionLoc(StartLoc);
13926 
13927   return OMPTeamsDistributeParallelForDirective::Create(
13928       getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13929       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
13930 }
13931 
13932 StmtResult SemaOpenMP::ActOnOpenMPTargetTeamsDirective(
13933     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13934     SourceLocation EndLoc) {
13935   if (!AStmt)
13936     return StmtError();
13937 
13938   setBranchProtectedScope(SemaRef, OMPD_target_teams, AStmt);
13939 
13940   const OMPClause *BareClause = nullptr;
13941   bool HasThreadLimitAndNumTeamsClause = hasClauses(Clauses, OMPC_num_teams) &&
13942                                          hasClauses(Clauses, OMPC_thread_limit);
13943   bool HasBareClause = llvm::any_of(Clauses, [&](const OMPClause *C) {
13944     BareClause = C;
13945     return C->getClauseKind() == OMPC_ompx_bare;
13946   });
13947 
13948   if (HasBareClause && !HasThreadLimitAndNumTeamsClause) {
13949     Diag(BareClause->getBeginLoc(), diag::err_ompx_bare_no_grid);
13950     return StmtError();
13951   }
13952 
13953   unsigned ClauseMaxNumExprs = HasBareClause ? 3 : 1;
13954   unsigned DiagNo = HasBareClause
13955                         ? diag::err_ompx_more_than_three_expr_not_allowed
13956                         : diag::err_omp_multi_expr_not_allowed;
13957   if (!checkNumExprsInClause<OMPNumTeamsClause>(*this, Clauses,
13958                                                 ClauseMaxNumExprs, DiagNo) ||
13959       !checkNumExprsInClause<OMPThreadLimitClause>(*this, Clauses,
13960                                                    ClauseMaxNumExprs, DiagNo))
13961     return StmtError();
13962 
13963   return OMPTargetTeamsDirective::Create(getASTContext(), StartLoc, EndLoc,
13964                                          Clauses, AStmt);
13965 }
13966 
13967 StmtResult SemaOpenMP::ActOnOpenMPTargetTeamsDistributeDirective(
13968     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13969     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13970   if (!AStmt)
13971     return StmtError();
13972 
13973   if (!checkNumExprsInClause<OMPNumTeamsClause>(
13974           *this, Clauses, /*MaxNum=*/1, diag::err_omp_multi_expr_not_allowed) ||
13975       !checkNumExprsInClause<OMPThreadLimitClause>(
13976           *this, Clauses, /*MaxNum=*/1, diag::err_omp_multi_expr_not_allowed))
13977     return StmtError();
13978 
13979   CapturedStmt *CS =
13980       setBranchProtectedScope(SemaRef, OMPD_target_teams_distribute, AStmt);
13981 
13982   OMPLoopBasedDirective::HelperExprs B;
13983   // In presence of clause 'collapse' with number of loops, it will
13984   // define the nested loops number.
13985   unsigned NestedLoopCount = checkOpenMPLoop(
13986       OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
13987       nullptr /*ordered not a clause on distribute*/, CS, SemaRef, *DSAStack,
13988       VarsWithImplicitDSA, B);
13989   if (NestedLoopCount == 0)
13990     return StmtError();
13991 
13992   assert((SemaRef.CurContext->isDependentContext() || B.builtAll()) &&
13993          "omp target teams distribute loop exprs were not built");
13994 
13995   return OMPTargetTeamsDistributeDirective::Create(
13996       getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13997 }
13998 
13999 StmtResult SemaOpenMP::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
14000     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14001     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14002   if (!AStmt)
14003     return StmtError();
14004 
14005   if (!checkNumExprsInClause<OMPNumTeamsClause>(
14006           *this, Clauses, /*MaxNum=*/1, diag::err_omp_multi_expr_not_allowed) ||
14007       !checkNumExprsInClause<OMPThreadLimitClause>(
14008           *this, Clauses, /*MaxNum=*/1, diag::err_omp_multi_expr_not_allowed))
14009     return StmtError();
14010 
14011   CapturedStmt *CS = setBranchProtectedScope(
14012       SemaRef, OMPD_target_teams_distribute_parallel_for, AStmt);
14013 
14014   OMPLoopBasedDirective::HelperExprs B;
14015   // In presence of clause 'collapse' with number of loops, it will
14016   // define the nested loops number.
14017   unsigned NestedLoopCount = checkOpenMPLoop(
14018       OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
14019       nullptr /*ordered not a clause on distribute*/, CS, SemaRef, *DSAStack,
14020       VarsWithImplicitDSA, B);
14021   if (NestedLoopCount == 0)
14022     return StmtError();
14023 
14024   if (finishLinearClauses(SemaRef, Clauses, B, DSAStack))
14025     return StmtError();
14026 
14027   return OMPTargetTeamsDistributeParallelForDirective::Create(
14028       getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14029       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
14030 }
14031 
14032 StmtResult SemaOpenMP::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
14033     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14034     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14035   if (!AStmt)
14036     return StmtError();
14037 
14038   if (!checkNumExprsInClause<OMPNumTeamsClause>(
14039           *this, Clauses, /*MaxNum=*/1, diag::err_omp_multi_expr_not_allowed) ||
14040       !checkNumExprsInClause<OMPThreadLimitClause>(
14041           *this, Clauses, /*MaxNum=*/1, diag::err_omp_multi_expr_not_allowed))
14042     return StmtError();
14043 
14044   CapturedStmt *CS = setBranchProtectedScope(
14045       SemaRef, OMPD_target_teams_distribute_parallel_for_simd, AStmt);
14046 
14047   OMPLoopBasedDirective::HelperExprs B;
14048   // In presence of clause 'collapse' with number of loops, it will
14049   // define the nested loops number.
14050   unsigned NestedLoopCount =
14051       checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
14052                       getCollapseNumberExpr(Clauses),
14053                       nullptr /*ordered not a clause on distribute*/, CS,
14054                       SemaRef, *DSAStack, VarsWithImplicitDSA, B);
14055   if (NestedLoopCount == 0)
14056     return StmtError();
14057 
14058   if (finishLinearClauses(SemaRef, Clauses, B, DSAStack))
14059     return StmtError();
14060 
14061   if (checkSimdlenSafelenSpecified(SemaRef, Clauses))
14062     return StmtError();
14063 
14064   return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
14065       getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14066 }
14067 
14068 StmtResult SemaOpenMP::ActOnOpenMPTargetTeamsDistributeSimdDirective(
14069     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14070     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14071   if (!AStmt)
14072     return StmtError();
14073 
14074   if (!checkNumExprsInClause<OMPNumTeamsClause>(
14075           *this, Clauses, /*MaxNum=*/1, diag::err_omp_multi_expr_not_allowed) ||
14076       !checkNumExprsInClause<OMPThreadLimitClause>(
14077           *this, Clauses, /*MaxNum=*/1, diag::err_omp_multi_expr_not_allowed))
14078     return StmtError();
14079 
14080   CapturedStmt *CS = setBranchProtectedScope(
14081       SemaRef, OMPD_target_teams_distribute_simd, AStmt);
14082 
14083   OMPLoopBasedDirective::HelperExprs B;
14084   // In presence of clause 'collapse' with number of loops, it will
14085   // define the nested loops number.
14086   unsigned NestedLoopCount = checkOpenMPLoop(
14087       OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
14088       nullptr /*ordered not a clause on distribute*/, CS, SemaRef, *DSAStack,
14089       VarsWithImplicitDSA, B);
14090   if (NestedLoopCount == 0)
14091     return StmtError();
14092 
14093   if (finishLinearClauses(SemaRef, Clauses, B, DSAStack))
14094     return StmtError();
14095 
14096   if (checkSimdlenSafelenSpecified(SemaRef, Clauses))
14097     return StmtError();
14098 
14099   return OMPTargetTeamsDistributeSimdDirective::Create(
14100       getASTContext(), StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14101 }
14102 
14103 bool SemaOpenMP::checkTransformableLoopNest(
14104     OpenMPDirectiveKind Kind, Stmt *AStmt, int NumLoops,
14105     SmallVectorImpl<OMPLoopBasedDirective::HelperExprs> &LoopHelpers,
14106     Stmt *&Body, SmallVectorImpl<SmallVector<Stmt *, 0>> &OriginalInits) {
14107   OriginalInits.emplace_back();
14108   bool Result = OMPLoopBasedDirective::doForAllLoops(
14109       AStmt->IgnoreContainers(), /*TryImperfectlyNestedLoops=*/false, NumLoops,
14110       [this, &LoopHelpers, &Body, &OriginalInits, Kind](unsigned Cnt,
14111                                                         Stmt *CurStmt) {
14112         VarsWithInheritedDSAType TmpDSA;
14113         unsigned SingleNumLoops =
14114             checkOpenMPLoop(Kind, nullptr, nullptr, CurStmt, SemaRef, *DSAStack,
14115                             TmpDSA, LoopHelpers[Cnt]);
14116         if (SingleNumLoops == 0)
14117           return true;
14118         assert(SingleNumLoops == 1 && "Expect single loop iteration space");
14119         if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
14120           OriginalInits.back().push_back(For->getInit());
14121           Body = For->getBody();
14122         } else {
14123           assert(isa<CXXForRangeStmt>(CurStmt) &&
14124                  "Expected canonical for or range-based for loops.");
14125           auto *CXXFor = cast<CXXForRangeStmt>(CurStmt);
14126           OriginalInits.back().push_back(CXXFor->getBeginStmt());
14127           Body = CXXFor->getBody();
14128         }
14129         OriginalInits.emplace_back();
14130         return false;
14131       },
14132       [&OriginalInits](OMPLoopBasedDirective *Transform) {
14133         Stmt *DependentPreInits;
14134         if (auto *Dir = dyn_cast<OMPTileDirective>(Transform))
14135           DependentPreInits = Dir->getPreInits();
14136         else if (auto *Dir = dyn_cast<OMPUnrollDirective>(Transform))
14137           DependentPreInits = Dir->getPreInits();
14138         else if (auto *Dir = dyn_cast<OMPReverseDirective>(Transform))
14139           DependentPreInits = Dir->getPreInits();
14140         else if (auto *Dir = dyn_cast<OMPInterchangeDirective>(Transform))
14141           DependentPreInits = Dir->getPreInits();
14142         else
14143           llvm_unreachable("Unhandled loop transformation");
14144 
14145         appendFlattenedStmtList(OriginalInits.back(), DependentPreInits);
14146       });
14147   assert(OriginalInits.back().empty() && "No preinit after innermost loop");
14148   OriginalInits.pop_back();
14149   return Result;
14150 }
14151 
14152 /// Add preinit statements that need to be propageted from the selected loop.
14153 static void addLoopPreInits(ASTContext &Context,
14154                             OMPLoopBasedDirective::HelperExprs &LoopHelper,
14155                             Stmt *LoopStmt, ArrayRef<Stmt *> OriginalInit,
14156                             SmallVectorImpl<Stmt *> &PreInits) {
14157 
14158   // For range-based for-statements, ensure that their syntactic sugar is
14159   // executed by adding them as pre-init statements.
14160   if (auto *CXXRangeFor = dyn_cast<CXXForRangeStmt>(LoopStmt)) {
14161     Stmt *RangeInit = CXXRangeFor->getInit();
14162     if (RangeInit)
14163       PreInits.push_back(RangeInit);
14164 
14165     DeclStmt *RangeStmt = CXXRangeFor->getRangeStmt();
14166     PreInits.push_back(new (Context) DeclStmt(RangeStmt->getDeclGroup(),
14167                                               RangeStmt->getBeginLoc(),
14168                                               RangeStmt->getEndLoc()));
14169 
14170     DeclStmt *RangeEnd = CXXRangeFor->getEndStmt();
14171     PreInits.push_back(new (Context) DeclStmt(RangeEnd->getDeclGroup(),
14172                                               RangeEnd->getBeginLoc(),
14173                                               RangeEnd->getEndLoc()));
14174   }
14175 
14176   llvm::append_range(PreInits, OriginalInit);
14177 
14178   // List of OMPCapturedExprDecl, for __begin, __end, and NumIterations
14179   if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits)) {
14180     PreInits.push_back(new (Context) DeclStmt(
14181         PI->getDeclGroup(), PI->getBeginLoc(), PI->getEndLoc()));
14182   }
14183 
14184   // Gather declarations for the data members used as counters.
14185   for (Expr *CounterRef : LoopHelper.Counters) {
14186     auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
14187     if (isa<OMPCapturedExprDecl>(CounterDecl))
14188       PreInits.push_back(new (Context) DeclStmt(
14189           DeclGroupRef(CounterDecl), SourceLocation(), SourceLocation()));
14190   }
14191 }
14192 
14193 /// Collect the loop statements (ForStmt or CXXRangeForStmt) of the affected
14194 /// loop of a construct.
14195 static void collectLoopStmts(Stmt *AStmt, MutableArrayRef<Stmt *> LoopStmts) {
14196   size_t NumLoops = LoopStmts.size();
14197   OMPLoopBasedDirective::doForAllLoops(
14198       AStmt, /*TryImperfectlyNestedLoops=*/false, NumLoops,
14199       [LoopStmts](unsigned Cnt, Stmt *CurStmt) {
14200         assert(!LoopStmts[Cnt] && "Loop statement must not yet be assigned");
14201         LoopStmts[Cnt] = CurStmt;
14202         return false;
14203       });
14204   assert(!is_contained(LoopStmts, nullptr) &&
14205          "Expecting a loop statement for each affected loop");
14206 }
14207 
14208 StmtResult SemaOpenMP::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses,
14209                                                 Stmt *AStmt,
14210                                                 SourceLocation StartLoc,
14211                                                 SourceLocation EndLoc) {
14212   ASTContext &Context = getASTContext();
14213   Scope *CurScope = SemaRef.getCurScope();
14214 
14215   const auto *SizesClause =
14216       OMPExecutableDirective::getSingleClause<OMPSizesClause>(Clauses);
14217   if (!SizesClause ||
14218       llvm::any_of(SizesClause->getSizesRefs(), [](Expr *E) { return !E; }))
14219     return StmtError();
14220   unsigned NumLoops = SizesClause->getNumSizes();
14221 
14222   // Empty statement should only be possible if there already was an error.
14223   if (!AStmt)
14224     return StmtError();
14225 
14226   // Verify and diagnose loop nest.
14227   SmallVector<OMPLoopBasedDirective::HelperExprs, 4> LoopHelpers(NumLoops);
14228   Stmt *Body = nullptr;
14229   SmallVector<SmallVector<Stmt *, 0>, 4> OriginalInits;
14230   if (!checkTransformableLoopNest(OMPD_tile, AStmt, NumLoops, LoopHelpers, Body,
14231                                   OriginalInits))
14232     return StmtError();
14233 
14234   // Delay tiling to when template is completely instantiated.
14235   if (SemaRef.CurContext->isDependentContext())
14236     return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses,
14237                                     NumLoops, AStmt, nullptr, nullptr);
14238 
14239   assert(LoopHelpers.size() == NumLoops &&
14240          "Expecting loop iteration space dimensionality to match number of "
14241          "affected loops");
14242   assert(OriginalInits.size() == NumLoops &&
14243          "Expecting loop iteration space dimensionality to match number of "
14244          "affected loops");
14245 
14246   // Collect all affected loop statements.
14247   SmallVector<Stmt *> LoopStmts(NumLoops, nullptr);
14248   collectLoopStmts(AStmt, LoopStmts);
14249 
14250   SmallVector<Stmt *, 4> PreInits;
14251   CaptureVars CopyTransformer(SemaRef);
14252 
14253   // Create iteration variables for the generated loops.
14254   SmallVector<VarDecl *, 4> FloorIndVars;
14255   SmallVector<VarDecl *, 4> TileIndVars;
14256   FloorIndVars.resize(NumLoops);
14257   TileIndVars.resize(NumLoops);
14258   for (unsigned I = 0; I < NumLoops; ++I) {
14259     OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
14260 
14261     assert(LoopHelper.Counters.size() == 1 &&
14262            "Expect single-dimensional loop iteration space");
14263     auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
14264     std::string OrigVarName = OrigCntVar->getNameInfo().getAsString();
14265     DeclRefExpr *IterVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
14266     QualType CntTy = IterVarRef->getType();
14267 
14268     // Iteration variable for the floor (i.e. outer) loop.
14269     {
14270       std::string FloorCntName =
14271           (Twine(".floor_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
14272       VarDecl *FloorCntDecl =
14273           buildVarDecl(SemaRef, {}, CntTy, FloorCntName, nullptr, OrigCntVar);
14274       FloorIndVars[I] = FloorCntDecl;
14275     }
14276 
14277     // Iteration variable for the tile (i.e. inner) loop.
14278     {
14279       std::string TileCntName =
14280           (Twine(".tile_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
14281 
14282       // Reuse the iteration variable created by checkOpenMPLoop. It is also
14283       // used by the expressions to derive the original iteration variable's
14284       // value from the logical iteration number.
14285       auto *TileCntDecl = cast<VarDecl>(IterVarRef->getDecl());
14286       TileCntDecl->setDeclName(
14287           &SemaRef.PP.getIdentifierTable().get(TileCntName));
14288       TileIndVars[I] = TileCntDecl;
14289     }
14290 
14291     addLoopPreInits(Context, LoopHelper, LoopStmts[I], OriginalInits[I],
14292                     PreInits);
14293   }
14294 
14295   // Once the original iteration values are set, append the innermost body.
14296   Stmt *Inner = Body;
14297 
14298   auto MakeDimTileSize = [&SemaRef = this->SemaRef, &CopyTransformer, &Context,
14299                           SizesClause, CurScope](int I) -> Expr * {
14300     Expr *DimTileSizeExpr = SizesClause->getSizesRefs()[I];
14301     if (isa<ConstantExpr>(DimTileSizeExpr))
14302       return AssertSuccess(CopyTransformer.TransformExpr(DimTileSizeExpr));
14303 
14304     // When the tile size is not a constant but a variable, it is possible to
14305     // pass non-positive numbers. For instance:
14306     // \code{c}
14307     //   int a = 0;
14308     //   #pragma omp tile sizes(a)
14309     //   for (int i = 0; i < 42; ++i)
14310     //     body(i);
14311     // \endcode
14312     // Although there is no meaningful interpretation of the tile size, the body
14313     // should still be executed 42 times to avoid surprises. To preserve the
14314     // invariant that every loop iteration is executed exactly once and not
14315     // cause an infinite loop, apply a minimum tile size of one.
14316     // Build expr:
14317     // \code{c}
14318     //   (TS <= 0) ? 1 : TS
14319     // \endcode
14320     QualType DimTy = DimTileSizeExpr->getType();
14321     uint64_t DimWidth = Context.getTypeSize(DimTy);
14322     IntegerLiteral *Zero = IntegerLiteral::Create(
14323         Context, llvm::APInt::getZero(DimWidth), DimTy, {});
14324     IntegerLiteral *One =
14325         IntegerLiteral::Create(Context, llvm::APInt(DimWidth, 1), DimTy, {});
14326     Expr *Cond = AssertSuccess(SemaRef.BuildBinOp(
14327         CurScope, {}, BO_LE,
14328         AssertSuccess(CopyTransformer.TransformExpr(DimTileSizeExpr)), Zero));
14329     Expr *MinOne = new (Context) ConditionalOperator(
14330         Cond, {}, One, {},
14331         AssertSuccess(CopyTransformer.TransformExpr(DimTileSizeExpr)), DimTy,
14332         VK_PRValue, OK_Ordinary);
14333     return MinOne;
14334   };
14335 
14336   // Create tile loops from the inside to the outside.
14337   for (int I = NumLoops - 1; I >= 0; --I) {
14338     OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
14339     Expr *NumIterations = LoopHelper.NumIterations;
14340     auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
14341     QualType IVTy = NumIterations->getType();
14342     Stmt *LoopStmt = LoopStmts[I];
14343 
14344     // Commonly used variables. One of the constraints of an AST is that every
14345     // node object must appear at most once, hence we define lamdas that create
14346     // a new AST node at every use.
14347     auto MakeTileIVRef = [&SemaRef = this->SemaRef, &TileIndVars, I, IVTy,
14348                           OrigCntVar]() {
14349       return buildDeclRefExpr(SemaRef, TileIndVars[I], IVTy,
14350                               OrigCntVar->getExprLoc());
14351     };
14352     auto MakeFloorIVRef = [&SemaRef = this->SemaRef, &FloorIndVars, I, IVTy,
14353                            OrigCntVar]() {
14354       return buildDeclRefExpr(SemaRef, FloorIndVars[I], IVTy,
14355                               OrigCntVar->getExprLoc());
14356     };
14357 
14358     // For init-statement: auto .tile.iv = .floor.iv
14359     SemaRef.AddInitializerToDecl(
14360         TileIndVars[I], SemaRef.DefaultLvalueConversion(MakeFloorIVRef()).get(),
14361         /*DirectInit=*/false);
14362     Decl *CounterDecl = TileIndVars[I];
14363     StmtResult InitStmt = new (Context)
14364         DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
14365                  OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
14366     if (!InitStmt.isUsable())
14367       return StmtError();
14368 
14369     // For cond-expression:
14370     //   .tile.iv < min(.floor.iv + DimTileSize, NumIterations)
14371     ExprResult EndOfTile =
14372         SemaRef.BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_Add,
14373                            MakeFloorIVRef(), MakeDimTileSize(I));
14374     if (!EndOfTile.isUsable())
14375       return StmtError();
14376     ExprResult IsPartialTile =
14377         SemaRef.BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT,
14378                            NumIterations, EndOfTile.get());
14379     if (!IsPartialTile.isUsable())
14380       return StmtError();
14381     ExprResult MinTileAndIterSpace = SemaRef.ActOnConditionalOp(
14382         LoopHelper.Cond->getBeginLoc(), LoopHelper.Cond->getEndLoc(),
14383         IsPartialTile.get(), NumIterations, EndOfTile.get());
14384     if (!MinTileAndIterSpace.isUsable())
14385       return StmtError();
14386     ExprResult CondExpr =
14387         SemaRef.BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT,
14388                            MakeTileIVRef(), MinTileAndIterSpace.get());
14389     if (!CondExpr.isUsable())
14390       return StmtError();
14391 
14392     // For incr-statement: ++.tile.iv
14393     ExprResult IncrStmt = SemaRef.BuildUnaryOp(
14394         CurScope, LoopHelper.Inc->getExprLoc(), UO_PreInc, MakeTileIVRef());
14395     if (!IncrStmt.isUsable())
14396       return StmtError();
14397 
14398     // Statements to set the original iteration variable's value from the
14399     // logical iteration number.
14400     // Generated for loop is:
14401     // \code
14402     // Original_for_init;
14403     // for (auto .tile.iv = .floor.iv;
14404     //      .tile.iv < min(.floor.iv + DimTileSize, NumIterations);
14405     //      ++.tile.iv) {
14406     //   Original_Body;
14407     //   Original_counter_update;
14408     // }
14409     // \endcode
14410     // FIXME: If the innermost body is an loop itself, inserting these
14411     // statements stops it being recognized  as a perfectly nested loop (e.g.
14412     // for applying tiling again). If this is the case, sink the expressions
14413     // further into the inner loop.
14414     SmallVector<Stmt *, 4> BodyParts;
14415     BodyParts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
14416     if (auto *SourceCXXFor = dyn_cast<CXXForRangeStmt>(LoopStmt))
14417       BodyParts.push_back(SourceCXXFor->getLoopVarStmt());
14418     BodyParts.push_back(Inner);
14419     Inner = CompoundStmt::Create(Context, BodyParts, FPOptionsOverride(),
14420                                  Inner->getBeginLoc(), Inner->getEndLoc());
14421     Inner = new (Context)
14422         ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
14423                 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
14424                 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
14425   }
14426 
14427   // Create floor loops from the inside to the outside.
14428   for (int I = NumLoops - 1; I >= 0; --I) {
14429     auto &LoopHelper = LoopHelpers[I];
14430     Expr *NumIterations = LoopHelper.NumIterations;
14431     DeclRefExpr *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
14432     QualType IVTy = NumIterations->getType();
14433 
14434     // Commonly used variables. One of the constraints of an AST is that every
14435     // node object must appear at most once, hence we define lamdas that create
14436     // a new AST node at every use.
14437     auto MakeFloorIVRef = [&SemaRef = this->SemaRef, &FloorIndVars, I, IVTy,
14438                            OrigCntVar]() {
14439       return buildDeclRefExpr(SemaRef, FloorIndVars[I], IVTy,
14440                               OrigCntVar->getExprLoc());
14441     };
14442 
14443     // For init-statement: auto .floor.iv = 0
14444     SemaRef.AddInitializerToDecl(
14445         FloorIndVars[I],
14446         SemaRef.ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
14447         /*DirectInit=*/false);
14448     Decl *CounterDecl = FloorIndVars[I];
14449     StmtResult InitStmt = new (Context)
14450         DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
14451                  OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
14452     if (!InitStmt.isUsable())
14453       return StmtError();
14454 
14455     // For cond-expression: .floor.iv < NumIterations
14456     ExprResult CondExpr =
14457         SemaRef.BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT,
14458                            MakeFloorIVRef(), NumIterations);
14459     if (!CondExpr.isUsable())
14460       return StmtError();
14461 
14462     // For incr-statement: .floor.iv += DimTileSize
14463     ExprResult IncrStmt =
14464         SemaRef.BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(), BO_AddAssign,
14465                            MakeFloorIVRef(), MakeDimTileSize(I));
14466     if (!IncrStmt.isUsable())
14467       return StmtError();
14468 
14469     Inner = new (Context)
14470         ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
14471                 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
14472                 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
14473   }
14474 
14475   return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, NumLoops,
14476                                   AStmt, Inner,
14477                                   buildPreInits(Context, PreInits));
14478 }
14479 
14480 StmtResult SemaOpenMP::ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses,
14481                                                   Stmt *AStmt,
14482                                                   SourceLocation StartLoc,
14483                                                   SourceLocation EndLoc) {
14484   ASTContext &Context = getASTContext();
14485   Scope *CurScope = SemaRef.getCurScope();
14486   // Empty statement should only be possible if there already was an error.
14487   if (!AStmt)
14488     return StmtError();
14489 
14490   if (checkMutuallyExclusiveClauses(SemaRef, Clauses,
14491                                     {OMPC_partial, OMPC_full}))
14492     return StmtError();
14493 
14494   const OMPFullClause *FullClause =
14495       OMPExecutableDirective::getSingleClause<OMPFullClause>(Clauses);
14496   const OMPPartialClause *PartialClause =
14497       OMPExecutableDirective::getSingleClause<OMPPartialClause>(Clauses);
14498   assert(!(FullClause && PartialClause) &&
14499          "mutual exclusivity must have been checked before");
14500 
14501   constexpr unsigned NumLoops = 1;
14502   Stmt *Body = nullptr;
14503   SmallVector<OMPLoopBasedDirective::HelperExprs, NumLoops> LoopHelpers(
14504       NumLoops);
14505   SmallVector<SmallVector<Stmt *, 0>, NumLoops + 1> OriginalInits;
14506   if (!checkTransformableLoopNest(OMPD_unroll, AStmt, NumLoops, LoopHelpers,
14507                                   Body, OriginalInits))
14508     return StmtError();
14509 
14510   unsigned NumGeneratedLoops = PartialClause ? 1 : 0;
14511 
14512   // Delay unrolling to when template is completely instantiated.
14513   if (SemaRef.CurContext->isDependentContext())
14514     return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
14515                                       NumGeneratedLoops, nullptr, nullptr);
14516 
14517   assert(LoopHelpers.size() == NumLoops &&
14518          "Expecting a single-dimensional loop iteration space");
14519   assert(OriginalInits.size() == NumLoops &&
14520          "Expecting a single-dimensional loop iteration space");
14521   OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front();
14522 
14523   if (FullClause) {
14524     if (!VerifyPositiveIntegerConstantInClause(
14525              LoopHelper.NumIterations, OMPC_full, /*StrictlyPositive=*/false,
14526              /*SuppressExprDiags=*/true)
14527              .isUsable()) {
14528       Diag(AStmt->getBeginLoc(), diag::err_omp_unroll_full_variable_trip_count);
14529       Diag(FullClause->getBeginLoc(), diag::note_omp_directive_here)
14530           << "#pragma omp unroll full";
14531       return StmtError();
14532     }
14533   }
14534 
14535   // The generated loop may only be passed to other loop-associated directive
14536   // when a partial clause is specified. Without the requirement it is
14537   // sufficient to generate loop unroll metadata at code-generation.
14538   if (NumGeneratedLoops == 0)
14539     return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
14540                                       NumGeneratedLoops, nullptr, nullptr);
14541 
14542   // Otherwise, we need to provide a de-sugared/transformed AST that can be
14543   // associated with another loop directive.
14544   //
14545   // The canonical loop analysis return by checkTransformableLoopNest assumes
14546   // the following structure to be the same loop without transformations or
14547   // directives applied: \code OriginalInits; LoopHelper.PreInits;
14548   // LoopHelper.Counters;
14549   // for (; IV < LoopHelper.NumIterations; ++IV) {
14550   //   LoopHelper.Updates;
14551   //   Body;
14552   // }
14553   // \endcode
14554   // where IV is a variable declared and initialized to 0 in LoopHelper.PreInits
14555   // and referenced by LoopHelper.IterationVarRef.
14556   //
14557   // The unrolling directive transforms this into the following loop:
14558   // \code
14559   // OriginalInits;         \
14560   // LoopHelper.PreInits;    > NewPreInits
14561   // LoopHelper.Counters;   /
14562   // for (auto UIV = 0; UIV < LoopHelper.NumIterations; UIV+=Factor) {
14563   //   #pragma clang loop unroll_count(Factor)
14564   //   for (IV = UIV; IV < UIV + Factor && UIV < LoopHelper.NumIterations; ++IV)
14565   //   {
14566   //     LoopHelper.Updates;
14567   //     Body;
14568   //   }
14569   // }
14570   // \endcode
14571   // where UIV is a new logical iteration counter. IV must be the same VarDecl
14572   // as the original LoopHelper.IterationVarRef because LoopHelper.Updates
14573   // references it. If the partially unrolled loop is associated with another
14574   // loop directive (like an OMPForDirective), it will use checkOpenMPLoop to
14575   // analyze this loop, i.e. the outer loop must fulfill the constraints of an
14576   // OpenMP canonical loop. The inner loop is not an associable canonical loop
14577   // and only exists to defer its unrolling to LLVM's LoopUnroll instead of
14578   // doing it in the frontend (by adding loop metadata). NewPreInits becomes a
14579   // property of the OMPLoopBasedDirective instead of statements in
14580   // CompoundStatement. This is to allow the loop to become a non-outermost loop
14581   // of a canonical loop nest where these PreInits are emitted before the
14582   // outermost directive.
14583 
14584   // Find the loop statement.
14585   Stmt *LoopStmt = nullptr;
14586   collectLoopStmts(AStmt, {LoopStmt});
14587 
14588   // Determine the PreInit declarations.
14589   SmallVector<Stmt *, 4> PreInits;
14590   addLoopPreInits(Context, LoopHelper, LoopStmt, OriginalInits[0], PreInits);
14591 
14592   auto *IterationVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
14593   QualType IVTy = IterationVarRef->getType();
14594   assert(LoopHelper.Counters.size() == 1 &&
14595          "Expecting a single-dimensional loop iteration space");
14596   auto *OrigVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
14597 
14598   // Determine the unroll factor.
14599   uint64_t Factor;
14600   SourceLocation FactorLoc;
14601   if (Expr *FactorVal = PartialClause->getFactor()) {
14602     Factor = FactorVal->getIntegerConstantExpr(Context)->getZExtValue();
14603     FactorLoc = FactorVal->getExprLoc();
14604   } else {
14605     // TODO: Use a better profitability model.
14606     Factor = 2;
14607   }
14608   assert(Factor > 0 && "Expected positive unroll factor");
14609   auto MakeFactorExpr = [this, Factor, IVTy, FactorLoc]() {
14610     return IntegerLiteral::Create(
14611         getASTContext(), llvm::APInt(getASTContext().getIntWidth(IVTy), Factor),
14612         IVTy, FactorLoc);
14613   };
14614 
14615   // Iteration variable SourceLocations.
14616   SourceLocation OrigVarLoc = OrigVar->getExprLoc();
14617   SourceLocation OrigVarLocBegin = OrigVar->getBeginLoc();
14618   SourceLocation OrigVarLocEnd = OrigVar->getEndLoc();
14619 
14620   // Internal variable names.
14621   std::string OrigVarName = OrigVar->getNameInfo().getAsString();
14622   std::string OuterIVName = (Twine(".unrolled.iv.") + OrigVarName).str();
14623   std::string InnerIVName = (Twine(".unroll_inner.iv.") + OrigVarName).str();
14624   std::string InnerTripCountName =
14625       (Twine(".unroll_inner.tripcount.") + OrigVarName).str();
14626 
14627   // Create the iteration variable for the unrolled loop.
14628   VarDecl *OuterIVDecl =
14629       buildVarDecl(SemaRef, {}, IVTy, OuterIVName, nullptr, OrigVar);
14630   auto MakeOuterRef = [this, OuterIVDecl, IVTy, OrigVarLoc]() {
14631     return buildDeclRefExpr(SemaRef, OuterIVDecl, IVTy, OrigVarLoc);
14632   };
14633 
14634   // Iteration variable for the inner loop: Reuse the iteration variable created
14635   // by checkOpenMPLoop.
14636   auto *InnerIVDecl = cast<VarDecl>(IterationVarRef->getDecl());
14637   InnerIVDecl->setDeclName(&SemaRef.PP.getIdentifierTable().get(InnerIVName));
14638   auto MakeInnerRef = [this, InnerIVDecl, IVTy, OrigVarLoc]() {
14639     return buildDeclRefExpr(SemaRef, InnerIVDecl, IVTy, OrigVarLoc);
14640   };
14641 
14642   // Make a copy of the NumIterations expression for each use: By the AST
14643   // constraints, every expression object in a DeclContext must be unique.
14644   CaptureVars CopyTransformer(SemaRef);
14645   auto MakeNumIterations = [&CopyTransformer, &LoopHelper]() -> Expr * {
14646     return AssertSuccess(
14647         CopyTransformer.TransformExpr(LoopHelper.NumIterations));
14648   };
14649 
14650   // Inner For init-statement: auto .unroll_inner.iv = .unrolled.iv
14651   ExprResult LValueConv = SemaRef.DefaultLvalueConversion(MakeOuterRef());
14652   SemaRef.AddInitializerToDecl(InnerIVDecl, LValueConv.get(),
14653                                /*DirectInit=*/false);
14654   StmtResult InnerInit = new (Context)
14655       DeclStmt(DeclGroupRef(InnerIVDecl), OrigVarLocBegin, OrigVarLocEnd);
14656   if (!InnerInit.isUsable())
14657     return StmtError();
14658 
14659   // Inner For cond-expression:
14660   // \code
14661   //   .unroll_inner.iv < .unrolled.iv + Factor &&
14662   //   .unroll_inner.iv < NumIterations
14663   // \endcode
14664   // This conjunction of two conditions allows ScalarEvolution to derive the
14665   // maximum trip count of the inner loop.
14666   ExprResult EndOfTile =
14667       SemaRef.BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_Add,
14668                          MakeOuterRef(), MakeFactorExpr());
14669   if (!EndOfTile.isUsable())
14670     return StmtError();
14671   ExprResult InnerCond1 =
14672       SemaRef.BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT,
14673                          MakeInnerRef(), EndOfTile.get());
14674   if (!InnerCond1.isUsable())
14675     return StmtError();
14676   ExprResult InnerCond2 =
14677       SemaRef.BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT,
14678                          MakeInnerRef(), MakeNumIterations());
14679   if (!InnerCond2.isUsable())
14680     return StmtError();
14681   ExprResult InnerCond =
14682       SemaRef.BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LAnd,
14683                          InnerCond1.get(), InnerCond2.get());
14684   if (!InnerCond.isUsable())
14685     return StmtError();
14686 
14687   // Inner For incr-statement: ++.unroll_inner.iv
14688   ExprResult InnerIncr = SemaRef.BuildUnaryOp(
14689       CurScope, LoopHelper.Inc->getExprLoc(), UO_PreInc, MakeInnerRef());
14690   if (!InnerIncr.isUsable())
14691     return StmtError();
14692 
14693   // Inner For statement.
14694   SmallVector<Stmt *> InnerBodyStmts;
14695   InnerBodyStmts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
14696   if (auto *CXXRangeFor = dyn_cast<CXXForRangeStmt>(LoopStmt))
14697     InnerBodyStmts.push_back(CXXRangeFor->getLoopVarStmt());
14698   InnerBodyStmts.push_back(Body);
14699   CompoundStmt *InnerBody =
14700       CompoundStmt::Create(getASTContext(), InnerBodyStmts, FPOptionsOverride(),
14701                            Body->getBeginLoc(), Body->getEndLoc());
14702   ForStmt *InnerFor = new (Context)
14703       ForStmt(Context, InnerInit.get(), InnerCond.get(), nullptr,
14704               InnerIncr.get(), InnerBody, LoopHelper.Init->getBeginLoc(),
14705               LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
14706 
14707   // Unroll metadata for the inner loop.
14708   // This needs to take into account the remainder portion of the unrolled loop,
14709   // hence `unroll(full)` does not apply here, even though the LoopUnroll pass
14710   // supports multiple loop exits. Instead, unroll using a factor equivalent to
14711   // the maximum trip count, which will also generate a remainder loop. Just
14712   // `unroll(enable)` (which could have been useful if the user has not
14713   // specified a concrete factor; even though the outer loop cannot be
14714   // influenced anymore, would avoid more code bloat than necessary) will refuse
14715   // the loop because "Won't unroll; remainder loop could not be generated when
14716   // assuming runtime trip count". Even if it did work, it must not choose a
14717   // larger unroll factor than the maximum loop length, or it would always just
14718   // execute the remainder loop.
14719   LoopHintAttr *UnrollHintAttr =
14720       LoopHintAttr::CreateImplicit(Context, LoopHintAttr::UnrollCount,
14721                                    LoopHintAttr::Numeric, MakeFactorExpr());
14722   AttributedStmt *InnerUnrolled = AttributedStmt::Create(
14723       getASTContext(), StartLoc, {UnrollHintAttr}, InnerFor);
14724 
14725   // Outer For init-statement: auto .unrolled.iv = 0
14726   SemaRef.AddInitializerToDecl(
14727       OuterIVDecl,
14728       SemaRef.ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
14729       /*DirectInit=*/false);
14730   StmtResult OuterInit = new (Context)
14731       DeclStmt(DeclGroupRef(OuterIVDecl), OrigVarLocBegin, OrigVarLocEnd);
14732   if (!OuterInit.isUsable())
14733     return StmtError();
14734 
14735   // Outer For cond-expression: .unrolled.iv < NumIterations
14736   ExprResult OuterConde =
14737       SemaRef.BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT,
14738                          MakeOuterRef(), MakeNumIterations());
14739   if (!OuterConde.isUsable())
14740     return StmtError();
14741 
14742   // Outer For incr-statement: .unrolled.iv += Factor
14743   ExprResult OuterIncr =
14744       SemaRef.BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(), BO_AddAssign,
14745                          MakeOuterRef(), MakeFactorExpr());
14746   if (!OuterIncr.isUsable())
14747     return StmtError();
14748 
14749   // Outer For statement.
14750   ForStmt *OuterFor = new (Context)
14751       ForStmt(Context, OuterInit.get(), OuterConde.get(), nullptr,
14752               OuterIncr.get(), InnerUnrolled, LoopHelper.Init->getBeginLoc(),
14753               LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
14754 
14755   return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
14756                                     NumGeneratedLoops, OuterFor,
14757                                     buildPreInits(Context, PreInits));
14758 }
14759 
14760 StmtResult SemaOpenMP::ActOnOpenMPReverseDirective(Stmt *AStmt,
14761                                                    SourceLocation StartLoc,
14762                                                    SourceLocation EndLoc) {
14763   ASTContext &Context = getASTContext();
14764   Scope *CurScope = SemaRef.getCurScope();
14765 
14766   // Empty statement should only be possible if there already was an error.
14767   if (!AStmt)
14768     return StmtError();
14769 
14770   constexpr unsigned NumLoops = 1;
14771   Stmt *Body = nullptr;
14772   SmallVector<OMPLoopBasedDirective::HelperExprs, NumLoops> LoopHelpers(
14773       NumLoops);
14774   SmallVector<SmallVector<Stmt *, 0>, NumLoops + 1> OriginalInits;
14775   if (!checkTransformableLoopNest(OMPD_reverse, AStmt, NumLoops, LoopHelpers,
14776                                   Body, OriginalInits))
14777     return StmtError();
14778 
14779   // Delay applying the transformation to when template is completely
14780   // instantiated.
14781   if (SemaRef.CurContext->isDependentContext())
14782     return OMPReverseDirective::Create(Context, StartLoc, EndLoc, AStmt,
14783                                        nullptr, nullptr);
14784 
14785   assert(LoopHelpers.size() == NumLoops &&
14786          "Expecting a single-dimensional loop iteration space");
14787   assert(OriginalInits.size() == NumLoops &&
14788          "Expecting a single-dimensional loop iteration space");
14789   OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front();
14790 
14791   // Find the loop statement.
14792   Stmt *LoopStmt = nullptr;
14793   collectLoopStmts(AStmt, {LoopStmt});
14794 
14795   // Determine the PreInit declarations.
14796   SmallVector<Stmt *> PreInits;
14797   addLoopPreInits(Context, LoopHelper, LoopStmt, OriginalInits[0], PreInits);
14798 
14799   auto *IterationVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
14800   QualType IVTy = IterationVarRef->getType();
14801   uint64_t IVWidth = Context.getTypeSize(IVTy);
14802   auto *OrigVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
14803 
14804   // Iteration variable SourceLocations.
14805   SourceLocation OrigVarLoc = OrigVar->getExprLoc();
14806   SourceLocation OrigVarLocBegin = OrigVar->getBeginLoc();
14807   SourceLocation OrigVarLocEnd = OrigVar->getEndLoc();
14808 
14809   // Locations pointing to the transformation.
14810   SourceLocation TransformLoc = StartLoc;
14811   SourceLocation TransformLocBegin = StartLoc;
14812   SourceLocation TransformLocEnd = EndLoc;
14813 
14814   // Internal variable names.
14815   std::string OrigVarName = OrigVar->getNameInfo().getAsString();
14816   SmallString<64> ForwardIVName(".forward.iv.");
14817   ForwardIVName += OrigVarName;
14818   SmallString<64> ReversedIVName(".reversed.iv.");
14819   ReversedIVName += OrigVarName;
14820 
14821   // LoopHelper.Updates will read the logical iteration number from
14822   // LoopHelper.IterationVarRef, compute the value of the user loop counter of
14823   // that logical iteration from it, then assign it to the user loop counter
14824   // variable. We cannot directly use LoopHelper.IterationVarRef as the
14825   // induction variable of the generated loop because it may cause an underflow:
14826   // \code{.c}
14827   //   for (unsigned i = 0; i < n; ++i)
14828   //     body(i);
14829   // \endcode
14830   //
14831   // Naive reversal:
14832   // \code{.c}
14833   //   for (unsigned i = n-1; i >= 0; --i)
14834   //     body(i);
14835   // \endcode
14836   //
14837   // Instead, we introduce a new iteration variable representing the logical
14838   // iteration counter of the original loop, convert it to the logical iteration
14839   // number of the reversed loop, then let LoopHelper.Updates compute the user's
14840   // loop iteration variable from it.
14841   // \code{.cpp}
14842   //   for (auto .forward.iv = 0; .forward.iv < n; ++.forward.iv) {
14843   //     auto .reversed.iv = n - .forward.iv - 1;
14844   //     i = (.reversed.iv + 0) * 1;                // LoopHelper.Updates
14845   //     body(i);                                   // Body
14846   //   }
14847   // \endcode
14848 
14849   // Subexpressions with more than one use. One of the constraints of an AST is
14850   // that every node object must appear at most once, hence we define a lambda
14851   // that creates a new AST node at every use.
14852   CaptureVars CopyTransformer(SemaRef);
14853   auto MakeNumIterations = [&CopyTransformer, &LoopHelper]() -> Expr * {
14854     return AssertSuccess(
14855         CopyTransformer.TransformExpr(LoopHelper.NumIterations));
14856   };
14857 
14858   // Create the iteration variable for the forward loop (from 0 to n-1).
14859   VarDecl *ForwardIVDecl =
14860       buildVarDecl(SemaRef, {}, IVTy, ForwardIVName, nullptr, OrigVar);
14861   auto MakeForwardRef = [&SemaRef = this->SemaRef, ForwardIVDecl, IVTy,
14862                          OrigVarLoc]() {
14863     return buildDeclRefExpr(SemaRef, ForwardIVDecl, IVTy, OrigVarLoc);
14864   };
14865 
14866   // Iteration variable for the reversed induction variable (from n-1 downto 0):
14867   // Reuse the iteration variable created by checkOpenMPLoop.
14868   auto *ReversedIVDecl = cast<VarDecl>(IterationVarRef->getDecl());
14869   ReversedIVDecl->setDeclName(
14870       &SemaRef.PP.getIdentifierTable().get(ReversedIVName));
14871 
14872   // For init-statement:
14873   // \code{.cpp}
14874   //   auto .forward.iv = 0;
14875   // \endcode
14876   auto *Zero = IntegerLiteral::Create(Context, llvm::APInt::getZero(IVWidth),
14877                                       ForwardIVDecl->getType(), OrigVarLoc);
14878   SemaRef.AddInitializerToDecl(ForwardIVDecl, Zero, /*DirectInit=*/false);
14879   StmtResult Init = new (Context)
14880       DeclStmt(DeclGroupRef(ForwardIVDecl), OrigVarLocBegin, OrigVarLocEnd);
14881   if (!Init.isUsable())
14882     return StmtError();
14883 
14884   // Forward iv cond-expression:
14885   // \code{.cpp}
14886   //   .forward.iv < MakeNumIterations()
14887   // \endcode
14888   ExprResult Cond =
14889       SemaRef.BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT,
14890                          MakeForwardRef(), MakeNumIterations());
14891   if (!Cond.isUsable())
14892     return StmtError();
14893 
14894   // Forward incr-statement:
14895   // \code{.c}
14896   //   ++.forward.iv
14897   // \endcode
14898   ExprResult Incr = SemaRef.BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(),
14899                                          UO_PreInc, MakeForwardRef());
14900   if (!Incr.isUsable())
14901     return StmtError();
14902 
14903   // Reverse the forward-iv:
14904   // \code{.cpp}
14905   //   auto .reversed.iv = MakeNumIterations() - 1 - .forward.iv
14906   // \endcode
14907   auto *One = IntegerLiteral::Create(Context, llvm::APInt(IVWidth, 1), IVTy,
14908                                      TransformLoc);
14909   ExprResult Minus = SemaRef.BuildBinOp(CurScope, TransformLoc, BO_Sub,
14910                                         MakeNumIterations(), One);
14911   if (!Minus.isUsable())
14912     return StmtError();
14913   Minus = SemaRef.BuildBinOp(CurScope, TransformLoc, BO_Sub, Minus.get(),
14914                              MakeForwardRef());
14915   if (!Minus.isUsable())
14916     return StmtError();
14917   StmtResult InitReversed = new (Context) DeclStmt(
14918       DeclGroupRef(ReversedIVDecl), TransformLocBegin, TransformLocEnd);
14919   if (!InitReversed.isUsable())
14920     return StmtError();
14921   SemaRef.AddInitializerToDecl(ReversedIVDecl, Minus.get(),
14922                                /*DirectInit=*/false);
14923 
14924   // The new loop body.
14925   SmallVector<Stmt *, 4> BodyStmts;
14926   BodyStmts.reserve(LoopHelper.Updates.size() + 2 +
14927                     (isa<CXXForRangeStmt>(LoopStmt) ? 1 : 0));
14928   BodyStmts.push_back(InitReversed.get());
14929   llvm::append_range(BodyStmts, LoopHelper.Updates);
14930   if (auto *CXXRangeFor = dyn_cast<CXXForRangeStmt>(LoopStmt))
14931     BodyStmts.push_back(CXXRangeFor->getLoopVarStmt());
14932   BodyStmts.push_back(Body);
14933   auto *ReversedBody =
14934       CompoundStmt::Create(Context, BodyStmts, FPOptionsOverride(),
14935                            Body->getBeginLoc(), Body->getEndLoc());
14936 
14937   // Finally create the reversed For-statement.
14938   auto *ReversedFor = new (Context)
14939       ForStmt(Context, Init.get(), Cond.get(), nullptr, Incr.get(),
14940               ReversedBody, LoopHelper.Init->getBeginLoc(),
14941               LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
14942   return OMPReverseDirective::Create(Context, StartLoc, EndLoc, AStmt,
14943                                      ReversedFor,
14944                                      buildPreInits(Context, PreInits));
14945 }
14946 
14947 StmtResult SemaOpenMP::ActOnOpenMPInterchangeDirective(
14948     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14949     SourceLocation EndLoc) {
14950   ASTContext &Context = getASTContext();
14951   DeclContext *CurContext = SemaRef.CurContext;
14952   Scope *CurScope = SemaRef.getCurScope();
14953 
14954   // Empty statement should only be possible if there already was an error.
14955   if (!AStmt)
14956     return StmtError();
14957 
14958   // interchange without permutation clause swaps two loops.
14959   const OMPPermutationClause *PermutationClause =
14960       OMPExecutableDirective::getSingleClause<OMPPermutationClause>(Clauses);
14961   size_t NumLoops = PermutationClause ? PermutationClause->getNumLoops() : 2;
14962 
14963   // Verify and diagnose loop nest.
14964   SmallVector<OMPLoopBasedDirective::HelperExprs, 4> LoopHelpers(NumLoops);
14965   Stmt *Body = nullptr;
14966   SmallVector<SmallVector<Stmt *, 0>, 2> OriginalInits;
14967   if (!checkTransformableLoopNest(OMPD_interchange, AStmt, NumLoops,
14968                                   LoopHelpers, Body, OriginalInits))
14969     return StmtError();
14970 
14971   // Delay interchange to when template is completely instantiated.
14972   if (CurContext->isDependentContext())
14973     return OMPInterchangeDirective::Create(Context, StartLoc, EndLoc, Clauses,
14974                                            NumLoops, AStmt, nullptr, nullptr);
14975 
14976   // An invalid expression in the permutation clause is set to nullptr in
14977   // ActOnOpenMPPermutationClause.
14978   if (PermutationClause &&
14979       llvm::is_contained(PermutationClause->getArgsRefs(), nullptr))
14980     return StmtError();
14981 
14982   assert(LoopHelpers.size() == NumLoops &&
14983          "Expecting loop iteration space dimensionaly to match number of "
14984          "affected loops");
14985   assert(OriginalInits.size() == NumLoops &&
14986          "Expecting loop iteration space dimensionaly to match number of "
14987          "affected loops");
14988 
14989   // Decode the permutation clause.
14990   SmallVector<uint64_t, 2> Permutation;
14991   if (!PermutationClause) {
14992     Permutation = {1, 0};
14993   } else {
14994     ArrayRef<Expr *> PermArgs = PermutationClause->getArgsRefs();
14995     llvm::BitVector Flags(PermArgs.size());
14996     for (Expr *PermArg : PermArgs) {
14997       std::optional<llvm::APSInt> PermCstExpr =
14998           PermArg->getIntegerConstantExpr(Context);
14999       if (!PermCstExpr)
15000         continue;
15001       uint64_t PermInt = PermCstExpr->getZExtValue();
15002       assert(1 <= PermInt && PermInt <= NumLoops &&
15003              "Must be a permutation; diagnostic emitted in "
15004              "ActOnOpenMPPermutationClause");
15005       if (Flags[PermInt - 1]) {
15006         SourceRange ExprRange(PermArg->getBeginLoc(), PermArg->getEndLoc());
15007         Diag(PermArg->getExprLoc(),
15008              diag::err_omp_interchange_permutation_value_repeated)
15009             << PermInt << ExprRange;
15010         continue;
15011       }
15012       Flags[PermInt - 1] = true;
15013 
15014       Permutation.push_back(PermInt - 1);
15015     }
15016 
15017     if (Permutation.size() != NumLoops)
15018       return StmtError();
15019   }
15020 
15021   // Nothing to transform with trivial permutation.
15022   if (NumLoops <= 1 || llvm::all_of(llvm::enumerate(Permutation), [](auto P) {
15023         auto [Idx, Arg] = P;
15024         return Idx == Arg;
15025       }))
15026     return OMPInterchangeDirective::Create(Context, StartLoc, EndLoc, Clauses,
15027                                            NumLoops, AStmt, AStmt, nullptr);
15028 
15029   // Find the affected loops.
15030   SmallVector<Stmt *> LoopStmts(NumLoops, nullptr);
15031   collectLoopStmts(AStmt, LoopStmts);
15032 
15033   // Collect pre-init statements on the order before the permuation.
15034   SmallVector<Stmt *> PreInits;
15035   for (auto I : llvm::seq<int>(NumLoops)) {
15036     OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
15037 
15038     assert(LoopHelper.Counters.size() == 1 &&
15039            "Single-dimensional loop iteration space expected");
15040     auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
15041 
15042     std::string OrigVarName = OrigCntVar->getNameInfo().getAsString();
15043     addLoopPreInits(Context, LoopHelper, LoopStmts[I], OriginalInits[I],
15044                     PreInits);
15045   }
15046 
15047   SmallVector<VarDecl *> PermutedIndVars(NumLoops);
15048   CaptureVars CopyTransformer(SemaRef);
15049 
15050   // Create the permuted loops from the inside to the outside of the
15051   // interchanged loop nest. Body of the innermost new loop is the original
15052   // innermost body.
15053   Stmt *Inner = Body;
15054   for (auto TargetIdx : llvm::reverse(llvm::seq<int>(NumLoops))) {
15055     // Get the original loop that belongs to this new position.
15056     uint64_t SourceIdx = Permutation[TargetIdx];
15057     OMPLoopBasedDirective::HelperExprs &SourceHelper = LoopHelpers[SourceIdx];
15058     Stmt *SourceLoopStmt = LoopStmts[SourceIdx];
15059     assert(SourceHelper.Counters.size() == 1 &&
15060            "Single-dimensional loop iteration space expected");
15061     auto *OrigCntVar = cast<DeclRefExpr>(SourceHelper.Counters.front());
15062 
15063     // Normalized loop counter variable: From 0 to n-1, always an integer type.
15064     DeclRefExpr *IterVarRef = cast<DeclRefExpr>(SourceHelper.IterationVarRef);
15065     QualType IVTy = IterVarRef->getType();
15066     assert(IVTy->isIntegerType() &&
15067            "Expected the logical iteration counter to be an integer");
15068 
15069     std::string OrigVarName = OrigCntVar->getNameInfo().getAsString();
15070     SourceLocation OrigVarLoc = IterVarRef->getExprLoc();
15071 
15072     // Make a copy of the NumIterations expression for each use: By the AST
15073     // constraints, every expression object in a DeclContext must be unique.
15074     auto MakeNumIterations = [&CopyTransformer, &SourceHelper]() -> Expr * {
15075       return AssertSuccess(
15076           CopyTransformer.TransformExpr(SourceHelper.NumIterations));
15077     };
15078 
15079     // Iteration variable for the permuted loop. Reuse the one from
15080     // checkOpenMPLoop which will also be used to update the original loop
15081     // variable.
15082     SmallString<64> PermutedCntName(".permuted_");
15083     PermutedCntName.append({llvm::utostr(TargetIdx), ".iv.", OrigVarName});
15084     auto *PermutedCntDecl = cast<VarDecl>(IterVarRef->getDecl());
15085     PermutedCntDecl->setDeclName(
15086         &SemaRef.PP.getIdentifierTable().get(PermutedCntName));
15087     PermutedIndVars[TargetIdx] = PermutedCntDecl;
15088     auto MakePermutedRef = [this, PermutedCntDecl, IVTy, OrigVarLoc]() {
15089       return buildDeclRefExpr(SemaRef, PermutedCntDecl, IVTy, OrigVarLoc);
15090     };
15091 
15092     // For init-statement:
15093     // \code
15094     //   auto .permuted_{target}.iv = 0
15095     // \endcode
15096     ExprResult Zero = SemaRef.ActOnIntegerConstant(OrigVarLoc, 0);
15097     if (!Zero.isUsable())
15098       return StmtError();
15099     SemaRef.AddInitializerToDecl(PermutedCntDecl, Zero.get(),
15100                                  /*DirectInit=*/false);
15101     StmtResult InitStmt = new (Context)
15102         DeclStmt(DeclGroupRef(PermutedCntDecl), OrigCntVar->getBeginLoc(),
15103                  OrigCntVar->getEndLoc());
15104     if (!InitStmt.isUsable())
15105       return StmtError();
15106 
15107     // For cond-expression:
15108     // \code
15109     //   .permuted_{target}.iv < MakeNumIterations()
15110     // \endcode
15111     ExprResult CondExpr =
15112         SemaRef.BuildBinOp(CurScope, SourceHelper.Cond->getExprLoc(), BO_LT,
15113                            MakePermutedRef(), MakeNumIterations());
15114     if (!CondExpr.isUsable())
15115       return StmtError();
15116 
15117     // For incr-statement:
15118     // \code
15119     //   ++.tile.iv
15120     // \endcode
15121     ExprResult IncrStmt = SemaRef.BuildUnaryOp(
15122         CurScope, SourceHelper.Inc->getExprLoc(), UO_PreInc, MakePermutedRef());
15123     if (!IncrStmt.isUsable())
15124       return StmtError();
15125 
15126     SmallVector<Stmt *, 4> BodyParts(SourceHelper.Updates.begin(),
15127                                      SourceHelper.Updates.end());
15128     if (auto *SourceCXXFor = dyn_cast<CXXForRangeStmt>(SourceLoopStmt))
15129       BodyParts.push_back(SourceCXXFor->getLoopVarStmt());
15130     BodyParts.push_back(Inner);
15131     Inner = CompoundStmt::Create(Context, BodyParts, FPOptionsOverride(),
15132                                  Inner->getBeginLoc(), Inner->getEndLoc());
15133     Inner = new (Context) ForStmt(
15134         Context, InitStmt.get(), CondExpr.get(), nullptr, IncrStmt.get(), Inner,
15135         SourceHelper.Init->getBeginLoc(), SourceHelper.Init->getBeginLoc(),
15136         SourceHelper.Inc->getEndLoc());
15137   }
15138 
15139   return OMPInterchangeDirective::Create(Context, StartLoc, EndLoc, Clauses,
15140                                          NumLoops, AStmt, Inner,
15141                                          buildPreInits(Context, PreInits));
15142 }
15143 
15144 OMPClause *SemaOpenMP::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,
15145                                                    Expr *Expr,
15146                                                    SourceLocation StartLoc,
15147                                                    SourceLocation LParenLoc,
15148                                                    SourceLocation EndLoc) {
15149   OMPClause *Res = nullptr;
15150   switch (Kind) {
15151   case OMPC_final:
15152     Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
15153     break;
15154   case OMPC_num_threads:
15155     Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
15156     break;
15157   case OMPC_safelen:
15158     Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
15159     break;
15160   case OMPC_simdlen:
15161     Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
15162     break;
15163   case OMPC_allocator:
15164     Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
15165     break;
15166   case OMPC_collapse:
15167     Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
15168     break;
15169   case OMPC_ordered:
15170     Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
15171     break;
15172   case OMPC_priority:
15173     Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
15174     break;
15175   case OMPC_hint:
15176     Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
15177     break;
15178   case OMPC_depobj:
15179     Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc);
15180     break;
15181   case OMPC_detach:
15182     Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc);
15183     break;
15184   case OMPC_novariants:
15185     Res = ActOnOpenMPNovariantsClause(Expr, StartLoc, LParenLoc, EndLoc);
15186     break;
15187   case OMPC_nocontext:
15188     Res = ActOnOpenMPNocontextClause(Expr, StartLoc, LParenLoc, EndLoc);
15189     break;
15190   case OMPC_filter:
15191     Res = ActOnOpenMPFilterClause(Expr, StartLoc, LParenLoc, EndLoc);
15192     break;
15193   case OMPC_partial:
15194     Res = ActOnOpenMPPartialClause(Expr, StartLoc, LParenLoc, EndLoc);
15195     break;
15196   case OMPC_message:
15197     Res = ActOnOpenMPMessageClause(Expr, StartLoc, LParenLoc, EndLoc);
15198     break;
15199   case OMPC_align:
15200     Res = ActOnOpenMPAlignClause(Expr, StartLoc, LParenLoc, EndLoc);
15201     break;
15202   case OMPC_ompx_dyn_cgroup_mem:
15203     Res = ActOnOpenMPXDynCGroupMemClause(Expr, StartLoc, LParenLoc, EndLoc);
15204     break;
15205   case OMPC_holds:
15206     Res = ActOnOpenMPHoldsClause(Expr, StartLoc, LParenLoc, EndLoc);
15207     break;
15208   case OMPC_grainsize:
15209   case OMPC_num_tasks:
15210   case OMPC_device:
15211   case OMPC_if:
15212   case OMPC_default:
15213   case OMPC_proc_bind:
15214   case OMPC_schedule:
15215   case OMPC_private:
15216   case OMPC_firstprivate:
15217   case OMPC_lastprivate:
15218   case OMPC_shared:
15219   case OMPC_reduction:
15220   case OMPC_task_reduction:
15221   case OMPC_in_reduction:
15222   case OMPC_linear:
15223   case OMPC_aligned:
15224   case OMPC_copyin:
15225   case OMPC_copyprivate:
15226   case OMPC_nowait:
15227   case OMPC_untied:
15228   case OMPC_mergeable:
15229   case OMPC_threadprivate:
15230   case OMPC_sizes:
15231   case OMPC_allocate:
15232   case OMPC_flush:
15233   case OMPC_read:
15234   case OMPC_write:
15235   case OMPC_update:
15236   case OMPC_capture:
15237   case OMPC_compare:
15238   case OMPC_seq_cst:
15239   case OMPC_acq_rel:
15240   case OMPC_acquire:
15241   case OMPC_release:
15242   case OMPC_relaxed:
15243   case OMPC_depend:
15244   case OMPC_threads:
15245   case OMPC_simd:
15246   case OMPC_map:
15247   case OMPC_nogroup:
15248   case OMPC_dist_schedule:
15249   case OMPC_defaultmap:
15250   case OMPC_unknown:
15251   case OMPC_uniform:
15252   case OMPC_to:
15253   case OMPC_from:
15254   case OMPC_use_device_ptr:
15255   case OMPC_use_device_addr:
15256   case OMPC_is_device_ptr:
15257   case OMPC_unified_address:
15258   case OMPC_unified_shared_memory:
15259   case OMPC_reverse_offload:
15260   case OMPC_dynamic_allocators:
15261   case OMPC_atomic_default_mem_order:
15262   case OMPC_device_type:
15263   case OMPC_match:
15264   case OMPC_nontemporal:
15265   case OMPC_order:
15266   case OMPC_at:
15267   case OMPC_severity:
15268   case OMPC_destroy:
15269   case OMPC_inclusive:
15270   case OMPC_exclusive:
15271   case OMPC_uses_allocators:
15272   case OMPC_affinity:
15273   case OMPC_when:
15274   case OMPC_bind:
15275   case OMPC_num_teams:
15276   case OMPC_thread_limit:
15277   default:
15278     llvm_unreachable("Clause is not allowed.");
15279   }
15280   return Res;
15281 }
15282 
15283 // An OpenMP directive such as 'target parallel' has two captured regions:
15284 // for the 'target' and 'parallel' respectively.  This function returns
15285 // the region in which to capture expressions associated with a clause.
15286 // A return value of OMPD_unknown signifies that the expression should not
15287 // be captured.
15288 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
15289     OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion,
15290     OpenMPDirectiveKind NameModifier = OMPD_unknown) {
15291   assert(isAllowedClauseForDirective(DKind, CKind, OpenMPVersion) &&
15292          "Invalid directive with CKind-clause");
15293 
15294   // Invalid modifier will be diagnosed separately, just return OMPD_unknown.
15295   if (NameModifier != OMPD_unknown &&
15296       !isAllowedClauseForDirective(NameModifier, CKind, OpenMPVersion))
15297     return OMPD_unknown;
15298 
15299   ArrayRef<OpenMPDirectiveKind> Leafs = getLeafConstructsOrSelf(DKind);
15300 
15301   // [5.2:341:24-30]
15302   // If the clauses have expressions on them, such as for various clauses where
15303   // the argument of the clause is an expression, or lower-bound, length, or
15304   // stride expressions inside array sections (or subscript and stride
15305   // expressions in subscript-triplet for Fortran), or linear-step or alignment
15306   // expressions, the expressions are evaluated immediately before the construct
15307   // to which the clause has been split or duplicated per the above rules
15308   // (therefore inside of the outer leaf constructs). However, the expressions
15309   // inside the num_teams and thread_limit clauses are always evaluated before
15310   // the outermost leaf construct.
15311 
15312   // Process special cases first.
15313   switch (CKind) {
15314   case OMPC_if:
15315     switch (DKind) {
15316     case OMPD_teams_loop:
15317     case OMPD_target_teams_loop:
15318       // For [target] teams loop, assume capture region is 'teams' so it's
15319       // available for codegen later to use if/when necessary.
15320       return OMPD_teams;
15321     case OMPD_target_update:
15322     case OMPD_target_enter_data:
15323     case OMPD_target_exit_data:
15324       return OMPD_task;
15325     default:
15326       break;
15327     }
15328     break;
15329   case OMPC_num_teams:
15330   case OMPC_thread_limit:
15331   case OMPC_ompx_dyn_cgroup_mem:
15332     if (Leafs[0] == OMPD_target)
15333       return OMPD_target;
15334     break;
15335   case OMPC_device:
15336     if (Leafs[0] == OMPD_target ||
15337         llvm::is_contained({OMPD_dispatch, OMPD_target_update,
15338                             OMPD_target_enter_data, OMPD_target_exit_data},
15339                            DKind))
15340       return OMPD_task;
15341     break;
15342   case OMPC_novariants:
15343   case OMPC_nocontext:
15344     if (DKind == OMPD_dispatch)
15345       return OMPD_task;
15346     break;
15347   case OMPC_when:
15348     if (DKind == OMPD_metadirective)
15349       return OMPD_metadirective;
15350     break;
15351   case OMPC_filter:
15352     return OMPD_unknown;
15353   default:
15354     break;
15355   }
15356 
15357   // If none of the special cases above applied, and DKind is a capturing
15358   // directive, find the innermost enclosing leaf construct that allows the
15359   // clause, and returns the corresponding capture region.
15360 
15361   auto GetEnclosingRegion = [&](int EndIdx, OpenMPClauseKind Clause) {
15362     // Find the index in "Leafs" of the last leaf that allows the given
15363     // clause. The search will only include indexes [0, EndIdx).
15364     // EndIdx may be set to the index of the NameModifier, if present.
15365     int InnermostIdx = [&]() {
15366       for (int I = EndIdx - 1; I >= 0; --I) {
15367         if (isAllowedClauseForDirective(Leafs[I], Clause, OpenMPVersion))
15368           return I;
15369       }
15370       return -1;
15371     }();
15372 
15373     // Find the nearest enclosing capture region.
15374     SmallVector<OpenMPDirectiveKind, 2> Regions;
15375     for (int I = InnermostIdx - 1; I >= 0; --I) {
15376       if (!isOpenMPCapturingDirective(Leafs[I]))
15377         continue;
15378       Regions.clear();
15379       getOpenMPCaptureRegions(Regions, Leafs[I]);
15380       if (Regions[0] != OMPD_unknown)
15381         return Regions.back();
15382     }
15383     return OMPD_unknown;
15384   };
15385 
15386   if (isOpenMPCapturingDirective(DKind)) {
15387     auto GetLeafIndex = [&](OpenMPDirectiveKind Dir) {
15388       for (int I = 0, E = Leafs.size(); I != E; ++I) {
15389         if (Leafs[I] == Dir)
15390           return I + 1;
15391       }
15392       return 0;
15393     };
15394 
15395     int End = NameModifier == OMPD_unknown ? Leafs.size()
15396                                            : GetLeafIndex(NameModifier);
15397     return GetEnclosingRegion(End, CKind);
15398   }
15399 
15400   return OMPD_unknown;
15401 }
15402 
15403 OMPClause *SemaOpenMP::ActOnOpenMPIfClause(
15404     OpenMPDirectiveKind NameModifier, Expr *Condition, SourceLocation StartLoc,
15405     SourceLocation LParenLoc, SourceLocation NameModifierLoc,
15406     SourceLocation ColonLoc, SourceLocation EndLoc) {
15407   Expr *ValExpr = Condition;
15408   Stmt *HelperValStmt = nullptr;
15409   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
15410   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
15411       !Condition->isInstantiationDependent() &&
15412       !Condition->containsUnexpandedParameterPack()) {
15413     ExprResult Val = SemaRef.CheckBooleanCondition(StartLoc, Condition);
15414     if (Val.isInvalid())
15415       return nullptr;
15416 
15417     ValExpr = Val.get();
15418 
15419     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
15420     CaptureRegion = getOpenMPCaptureRegionForClause(
15421         DKind, OMPC_if, getLangOpts().OpenMP, NameModifier);
15422     if (CaptureRegion != OMPD_unknown &&
15423         !SemaRef.CurContext->isDependentContext()) {
15424       ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
15425       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15426       ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
15427       HelperValStmt = buildPreInits(getASTContext(), Captures);
15428     }
15429   }
15430 
15431   return new (getASTContext())
15432       OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
15433                   LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
15434 }
15435 
15436 OMPClause *SemaOpenMP::ActOnOpenMPFinalClause(Expr *Condition,
15437                                               SourceLocation StartLoc,
15438                                               SourceLocation LParenLoc,
15439                                               SourceLocation EndLoc) {
15440   Expr *ValExpr = Condition;
15441   Stmt *HelperValStmt = nullptr;
15442   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
15443   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
15444       !Condition->isInstantiationDependent() &&
15445       !Condition->containsUnexpandedParameterPack()) {
15446     ExprResult Val = SemaRef.CheckBooleanCondition(StartLoc, Condition);
15447     if (Val.isInvalid())
15448       return nullptr;
15449 
15450     ValExpr = SemaRef.MakeFullExpr(Val.get()).get();
15451 
15452     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
15453     CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_final,
15454                                                     getLangOpts().OpenMP);
15455     if (CaptureRegion != OMPD_unknown &&
15456         !SemaRef.CurContext->isDependentContext()) {
15457       ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
15458       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15459       ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
15460       HelperValStmt = buildPreInits(getASTContext(), Captures);
15461     }
15462   }
15463 
15464   return new (getASTContext()) OMPFinalClause(
15465       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
15466 }
15467 
15468 ExprResult
15469 SemaOpenMP::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
15470                                                    Expr *Op) {
15471   if (!Op)
15472     return ExprError();
15473 
15474   class IntConvertDiagnoser : public Sema::ICEConvertDiagnoser {
15475   public:
15476     IntConvertDiagnoser()
15477         : ICEConvertDiagnoser(/*AllowScopedEnumerations=*/false, false, true) {}
15478     SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
15479                                          QualType T) override {
15480       return S.Diag(Loc, diag::err_omp_not_integral) << T;
15481     }
15482     SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
15483                                              QualType T) override {
15484       return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
15485     }
15486     SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
15487                                                QualType T,
15488                                                QualType ConvTy) override {
15489       return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
15490     }
15491     SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
15492                                            QualType ConvTy) override {
15493       return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
15494              << ConvTy->isEnumeralType() << ConvTy;
15495     }
15496     SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
15497                                             QualType T) override {
15498       return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
15499     }
15500     SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
15501                                         QualType ConvTy) override {
15502       return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
15503              << ConvTy->isEnumeralType() << ConvTy;
15504     }
15505     SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
15506                                              QualType) override {
15507       llvm_unreachable("conversion functions are permitted");
15508     }
15509   } ConvertDiagnoser;
15510   return SemaRef.PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
15511 }
15512 
15513 static bool
15514 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind,
15515                           bool StrictlyPositive, bool BuildCapture = false,
15516                           OpenMPDirectiveKind DKind = OMPD_unknown,
15517                           OpenMPDirectiveKind *CaptureRegion = nullptr,
15518                           Stmt **HelperValStmt = nullptr) {
15519   if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
15520       !ValExpr->isInstantiationDependent()) {
15521     SourceLocation Loc = ValExpr->getExprLoc();
15522     ExprResult Value =
15523         SemaRef.OpenMP().PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
15524     if (Value.isInvalid())
15525       return false;
15526 
15527     ValExpr = Value.get();
15528     // The expression must evaluate to a non-negative integer value.
15529     if (std::optional<llvm::APSInt> Result =
15530             ValExpr->getIntegerConstantExpr(SemaRef.Context)) {
15531       if (Result->isSigned() &&
15532           !((!StrictlyPositive && Result->isNonNegative()) ||
15533             (StrictlyPositive && Result->isStrictlyPositive()))) {
15534         SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
15535             << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
15536             << ValExpr->getSourceRange();
15537         return false;
15538       }
15539     }
15540     if (!BuildCapture)
15541       return true;
15542     *CaptureRegion =
15543         getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP);
15544     if (*CaptureRegion != OMPD_unknown &&
15545         !SemaRef.CurContext->isDependentContext()) {
15546       ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
15547       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15548       ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
15549       *HelperValStmt = buildPreInits(SemaRef.Context, Captures);
15550     }
15551   }
15552   return true;
15553 }
15554 
15555 OMPClause *SemaOpenMP::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
15556                                                    SourceLocation StartLoc,
15557                                                    SourceLocation LParenLoc,
15558                                                    SourceLocation EndLoc) {
15559   Expr *ValExpr = NumThreads;
15560   Stmt *HelperValStmt = nullptr;
15561 
15562   // OpenMP [2.5, Restrictions]
15563   //  The num_threads expression must evaluate to a positive integer value.
15564   if (!isNonNegativeIntegerValue(ValExpr, SemaRef, OMPC_num_threads,
15565                                  /*StrictlyPositive=*/true))
15566     return nullptr;
15567 
15568   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
15569   OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
15570       DKind, OMPC_num_threads, getLangOpts().OpenMP);
15571   if (CaptureRegion != OMPD_unknown &&
15572       !SemaRef.CurContext->isDependentContext()) {
15573     ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
15574     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15575     ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
15576     HelperValStmt = buildPreInits(getASTContext(), Captures);
15577   }
15578 
15579   return new (getASTContext()) OMPNumThreadsClause(
15580       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
15581 }
15582 
15583 ExprResult SemaOpenMP::VerifyPositiveIntegerConstantInClause(
15584     Expr *E, OpenMPClauseKind CKind, bool StrictlyPositive,
15585     bool SuppressExprDiags) {
15586   if (!E)
15587     return ExprError();
15588   if (E->isValueDependent() || E->isTypeDependent() ||
15589       E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
15590     return E;
15591 
15592   llvm::APSInt Result;
15593   ExprResult ICE;
15594   if (SuppressExprDiags) {
15595     // Use a custom diagnoser that suppresses 'note' diagnostics about the
15596     // expression.
15597     struct SuppressedDiagnoser : public Sema::VerifyICEDiagnoser {
15598       SuppressedDiagnoser() : VerifyICEDiagnoser(/*Suppress=*/true) {}
15599       SemaBase::SemaDiagnosticBuilder
15600       diagnoseNotICE(Sema &S, SourceLocation Loc) override {
15601         llvm_unreachable("Diagnostic suppressed");
15602       }
15603     } Diagnoser;
15604     ICE = SemaRef.VerifyIntegerConstantExpression(E, &Result, Diagnoser,
15605                                                   Sema::AllowFold);
15606   } else {
15607     ICE = SemaRef.VerifyIntegerConstantExpression(E, &Result,
15608                                                   /*FIXME*/ Sema::AllowFold);
15609   }
15610   if (ICE.isInvalid())
15611     return ExprError();
15612 
15613   if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
15614       (!StrictlyPositive && !Result.isNonNegative())) {
15615     Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
15616         << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
15617         << E->getSourceRange();
15618     return ExprError();
15619   }
15620   if ((CKind == OMPC_aligned || CKind == OMPC_align ||
15621        CKind == OMPC_allocate) &&
15622       !Result.isPowerOf2()) {
15623     Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
15624         << E->getSourceRange();
15625     return ExprError();
15626   }
15627   if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
15628     DSAStack->setAssociatedLoops(Result.getExtValue());
15629   else if (CKind == OMPC_ordered)
15630     DSAStack->setAssociatedLoops(Result.getExtValue());
15631   return ICE;
15632 }
15633 
15634 OMPClause *SemaOpenMP::ActOnOpenMPSafelenClause(Expr *Len,
15635                                                 SourceLocation StartLoc,
15636                                                 SourceLocation LParenLoc,
15637                                                 SourceLocation EndLoc) {
15638   // OpenMP [2.8.1, simd construct, Description]
15639   // The parameter of the safelen clause must be a constant
15640   // positive integer expression.
15641   ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
15642   if (Safelen.isInvalid())
15643     return nullptr;
15644   return new (getASTContext())
15645       OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
15646 }
15647 
15648 OMPClause *SemaOpenMP::ActOnOpenMPSimdlenClause(Expr *Len,
15649                                                 SourceLocation StartLoc,
15650                                                 SourceLocation LParenLoc,
15651                                                 SourceLocation EndLoc) {
15652   // OpenMP [2.8.1, simd construct, Description]
15653   // The parameter of the simdlen clause must be a constant
15654   // positive integer expression.
15655   ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
15656   if (Simdlen.isInvalid())
15657     return nullptr;
15658   return new (getASTContext())
15659       OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
15660 }
15661 
15662 /// Tries to find omp_allocator_handle_t type.
15663 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
15664                                     DSAStackTy *Stack) {
15665   if (!Stack->getOMPAllocatorHandleT().isNull())
15666     return true;
15667 
15668   // Set the allocator handle type.
15669   IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_allocator_handle_t");
15670   ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
15671   if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
15672     S.Diag(Loc, diag::err_omp_implied_type_not_found)
15673         << "omp_allocator_handle_t";
15674     return false;
15675   }
15676   QualType AllocatorHandleEnumTy = PT.get();
15677   AllocatorHandleEnumTy.addConst();
15678   Stack->setOMPAllocatorHandleT(AllocatorHandleEnumTy);
15679 
15680   // Fill the predefined allocator map.
15681   bool ErrorFound = false;
15682   for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
15683     auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
15684     StringRef Allocator =
15685         OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
15686     DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
15687     auto *VD = dyn_cast_or_null<ValueDecl>(
15688         S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
15689     if (!VD) {
15690       ErrorFound = true;
15691       break;
15692     }
15693     QualType AllocatorType =
15694         VD->getType().getNonLValueExprType(S.getASTContext());
15695     ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
15696     if (!Res.isUsable()) {
15697       ErrorFound = true;
15698       break;
15699     }
15700     Res = S.PerformImplicitConversion(Res.get(), AllocatorHandleEnumTy,
15701                                       AssignmentAction::Initializing,
15702                                       /*AllowExplicit=*/true);
15703     if (!Res.isUsable()) {
15704       ErrorFound = true;
15705       break;
15706     }
15707     Stack->setAllocator(AllocatorKind, Res.get());
15708   }
15709   if (ErrorFound) {
15710     S.Diag(Loc, diag::err_omp_implied_type_not_found)
15711         << "omp_allocator_handle_t";
15712     return false;
15713   }
15714 
15715   return true;
15716 }
15717 
15718 OMPClause *SemaOpenMP::ActOnOpenMPAllocatorClause(Expr *A,
15719                                                   SourceLocation StartLoc,
15720                                                   SourceLocation LParenLoc,
15721                                                   SourceLocation EndLoc) {
15722   // OpenMP [2.11.3, allocate Directive, Description]
15723   // allocator is an expression of omp_allocator_handle_t type.
15724   if (!findOMPAllocatorHandleT(SemaRef, A->getExprLoc(), DSAStack))
15725     return nullptr;
15726 
15727   ExprResult Allocator = SemaRef.DefaultLvalueConversion(A);
15728   if (Allocator.isInvalid())
15729     return nullptr;
15730   Allocator = SemaRef.PerformImplicitConversion(
15731       Allocator.get(), DSAStack->getOMPAllocatorHandleT(),
15732       AssignmentAction::Initializing,
15733       /*AllowExplicit=*/true);
15734   if (Allocator.isInvalid())
15735     return nullptr;
15736   return new (getASTContext())
15737       OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
15738 }
15739 
15740 OMPClause *SemaOpenMP::ActOnOpenMPCollapseClause(Expr *NumForLoops,
15741                                                  SourceLocation StartLoc,
15742                                                  SourceLocation LParenLoc,
15743                                                  SourceLocation EndLoc) {
15744   // OpenMP [2.7.1, loop construct, Description]
15745   // OpenMP [2.8.1, simd construct, Description]
15746   // OpenMP [2.9.6, distribute construct, Description]
15747   // The parameter of the collapse clause must be a constant
15748   // positive integer expression.
15749   ExprResult NumForLoopsResult =
15750       VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
15751   if (NumForLoopsResult.isInvalid())
15752     return nullptr;
15753   return new (getASTContext())
15754       OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
15755 }
15756 
15757 OMPClause *SemaOpenMP::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
15758                                                 SourceLocation EndLoc,
15759                                                 SourceLocation LParenLoc,
15760                                                 Expr *NumForLoops) {
15761   // OpenMP [2.7.1, loop construct, Description]
15762   // OpenMP [2.8.1, simd construct, Description]
15763   // OpenMP [2.9.6, distribute construct, Description]
15764   // The parameter of the ordered clause must be a constant
15765   // positive integer expression if any.
15766   if (NumForLoops && LParenLoc.isValid()) {
15767     ExprResult NumForLoopsResult =
15768         VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
15769     if (NumForLoopsResult.isInvalid())
15770       return nullptr;
15771     NumForLoops = NumForLoopsResult.get();
15772   } else {
15773     NumForLoops = nullptr;
15774   }
15775   auto *Clause =
15776       OMPOrderedClause::Create(getASTContext(), NumForLoops,
15777                                NumForLoops ? DSAStack->getAssociatedLoops() : 0,
15778                                StartLoc, LParenLoc, EndLoc);
15779   DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
15780   return Clause;
15781 }
15782 
15783 OMPClause *SemaOpenMP::ActOnOpenMPSimpleClause(
15784     OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
15785     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
15786   OMPClause *Res = nullptr;
15787   switch (Kind) {
15788   case OMPC_default:
15789     Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument),
15790                                    ArgumentLoc, StartLoc, LParenLoc, EndLoc);
15791     break;
15792   case OMPC_proc_bind:
15793     Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument),
15794                                     ArgumentLoc, StartLoc, LParenLoc, EndLoc);
15795     break;
15796   case OMPC_atomic_default_mem_order:
15797     Res = ActOnOpenMPAtomicDefaultMemOrderClause(
15798         static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
15799         ArgumentLoc, StartLoc, LParenLoc, EndLoc);
15800     break;
15801   case OMPC_fail:
15802     Res = ActOnOpenMPFailClause(static_cast<OpenMPClauseKind>(Argument),
15803                                 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
15804     break;
15805   case OMPC_update:
15806     Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
15807                                   ArgumentLoc, StartLoc, LParenLoc, EndLoc);
15808     break;
15809   case OMPC_bind:
15810     Res = ActOnOpenMPBindClause(static_cast<OpenMPBindClauseKind>(Argument),
15811                                 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
15812     break;
15813   case OMPC_at:
15814     Res = ActOnOpenMPAtClause(static_cast<OpenMPAtClauseKind>(Argument),
15815                               ArgumentLoc, StartLoc, LParenLoc, EndLoc);
15816     break;
15817   case OMPC_severity:
15818     Res = ActOnOpenMPSeverityClause(
15819         static_cast<OpenMPSeverityClauseKind>(Argument), ArgumentLoc, StartLoc,
15820         LParenLoc, EndLoc);
15821     break;
15822   case OMPC_if:
15823   case OMPC_final:
15824   case OMPC_num_threads:
15825   case OMPC_safelen:
15826   case OMPC_simdlen:
15827   case OMPC_sizes:
15828   case OMPC_allocator:
15829   case OMPC_collapse:
15830   case OMPC_schedule:
15831   case OMPC_private:
15832   case OMPC_firstprivate:
15833   case OMPC_lastprivate:
15834   case OMPC_shared:
15835   case OMPC_reduction:
15836   case OMPC_task_reduction:
15837   case OMPC_in_reduction:
15838   case OMPC_linear:
15839   case OMPC_aligned:
15840   case OMPC_copyin:
15841   case OMPC_copyprivate:
15842   case OMPC_ordered:
15843   case OMPC_nowait:
15844   case OMPC_untied:
15845   case OMPC_mergeable:
15846   case OMPC_threadprivate:
15847   case OMPC_allocate:
15848   case OMPC_flush:
15849   case OMPC_depobj:
15850   case OMPC_read:
15851   case OMPC_write:
15852   case OMPC_capture:
15853   case OMPC_compare:
15854   case OMPC_seq_cst:
15855   case OMPC_acq_rel:
15856   case OMPC_acquire:
15857   case OMPC_release:
15858   case OMPC_relaxed:
15859   case OMPC_depend:
15860   case OMPC_device:
15861   case OMPC_threads:
15862   case OMPC_simd:
15863   case OMPC_map:
15864   case OMPC_num_teams:
15865   case OMPC_thread_limit:
15866   case OMPC_priority:
15867   case OMPC_grainsize:
15868   case OMPC_nogroup:
15869   case OMPC_num_tasks:
15870   case OMPC_hint:
15871   case OMPC_dist_schedule:
15872   case OMPC_defaultmap:
15873   case OMPC_unknown:
15874   case OMPC_uniform:
15875   case OMPC_to:
15876   case OMPC_from:
15877   case OMPC_use_device_ptr:
15878   case OMPC_use_device_addr:
15879   case OMPC_is_device_ptr:
15880   case OMPC_has_device_addr:
15881   case OMPC_unified_address:
15882   case OMPC_unified_shared_memory:
15883   case OMPC_reverse_offload:
15884   case OMPC_dynamic_allocators:
15885   case OMPC_device_type:
15886   case OMPC_match:
15887   case OMPC_nontemporal:
15888   case OMPC_destroy:
15889   case OMPC_novariants:
15890   case OMPC_nocontext:
15891   case OMPC_detach:
15892   case OMPC_inclusive:
15893   case OMPC_exclusive:
15894   case OMPC_uses_allocators:
15895   case OMPC_affinity:
15896   case OMPC_when:
15897   case OMPC_message:
15898   default:
15899     llvm_unreachable("Clause is not allowed.");
15900   }
15901   return Res;
15902 }
15903 
15904 static std::string getListOfPossibleValues(OpenMPClauseKind K, unsigned First,
15905                                            unsigned Last,
15906                                            ArrayRef<unsigned> Exclude = {}) {
15907   SmallString<256> Buffer;
15908   llvm::raw_svector_ostream Out(Buffer);
15909   unsigned Skipped = Exclude.size();
15910   for (unsigned I = First; I < Last; ++I) {
15911     if (llvm::is_contained(Exclude, I)) {
15912       --Skipped;
15913       continue;
15914     }
15915     Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
15916     if (I + Skipped + 2 == Last)
15917       Out << " or ";
15918     else if (I + Skipped + 1 != Last)
15919       Out << ", ";
15920   }
15921   return std::string(Out.str());
15922 }
15923 
15924 OMPClause *SemaOpenMP::ActOnOpenMPDefaultClause(DefaultKind Kind,
15925                                                 SourceLocation KindKwLoc,
15926                                                 SourceLocation StartLoc,
15927                                                 SourceLocation LParenLoc,
15928                                                 SourceLocation EndLoc) {
15929   if (Kind == OMP_DEFAULT_unknown) {
15930     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
15931         << getListOfPossibleValues(OMPC_default, /*First=*/0,
15932                                    /*Last=*/unsigned(OMP_DEFAULT_unknown))
15933         << getOpenMPClauseName(OMPC_default);
15934     return nullptr;
15935   }
15936 
15937   switch (Kind) {
15938   case OMP_DEFAULT_none:
15939     DSAStack->setDefaultDSANone(KindKwLoc);
15940     break;
15941   case OMP_DEFAULT_shared:
15942     DSAStack->setDefaultDSAShared(KindKwLoc);
15943     break;
15944   case OMP_DEFAULT_firstprivate:
15945     DSAStack->setDefaultDSAFirstPrivate(KindKwLoc);
15946     break;
15947   case OMP_DEFAULT_private:
15948     DSAStack->setDefaultDSAPrivate(KindKwLoc);
15949     break;
15950   default:
15951     llvm_unreachable("DSA unexpected in OpenMP default clause");
15952   }
15953 
15954   return new (getASTContext())
15955       OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
15956 }
15957 
15958 OMPClause *SemaOpenMP::ActOnOpenMPProcBindClause(ProcBindKind Kind,
15959                                                  SourceLocation KindKwLoc,
15960                                                  SourceLocation StartLoc,
15961                                                  SourceLocation LParenLoc,
15962                                                  SourceLocation EndLoc) {
15963   if (Kind == OMP_PROC_BIND_unknown) {
15964     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
15965         << getListOfPossibleValues(OMPC_proc_bind,
15966                                    /*First=*/unsigned(OMP_PROC_BIND_master),
15967                                    /*Last=*/
15968                                    unsigned(getLangOpts().OpenMP > 50
15969                                                 ? OMP_PROC_BIND_primary
15970                                                 : OMP_PROC_BIND_spread) +
15971                                        1)
15972         << getOpenMPClauseName(OMPC_proc_bind);
15973     return nullptr;
15974   }
15975   if (Kind == OMP_PROC_BIND_primary && getLangOpts().OpenMP < 51)
15976     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
15977         << getListOfPossibleValues(OMPC_proc_bind,
15978                                    /*First=*/unsigned(OMP_PROC_BIND_master),
15979                                    /*Last=*/
15980                                    unsigned(OMP_PROC_BIND_spread) + 1)
15981         << getOpenMPClauseName(OMPC_proc_bind);
15982   return new (getASTContext())
15983       OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
15984 }
15985 
15986 OMPClause *SemaOpenMP::ActOnOpenMPAtomicDefaultMemOrderClause(
15987     OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc,
15988     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
15989   if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) {
15990     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
15991         << getListOfPossibleValues(
15992                OMPC_atomic_default_mem_order, /*First=*/0,
15993                /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown)
15994         << getOpenMPClauseName(OMPC_atomic_default_mem_order);
15995     return nullptr;
15996   }
15997   return new (getASTContext()) OMPAtomicDefaultMemOrderClause(
15998       Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
15999 }
16000 
16001 OMPClause *SemaOpenMP::ActOnOpenMPAtClause(OpenMPAtClauseKind Kind,
16002                                            SourceLocation KindKwLoc,
16003                                            SourceLocation StartLoc,
16004                                            SourceLocation LParenLoc,
16005                                            SourceLocation EndLoc) {
16006   if (Kind == OMPC_AT_unknown) {
16007     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16008         << getListOfPossibleValues(OMPC_at, /*First=*/0,
16009                                    /*Last=*/OMPC_AT_unknown)
16010         << getOpenMPClauseName(OMPC_at);
16011     return nullptr;
16012   }
16013   return new (getASTContext())
16014       OMPAtClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
16015 }
16016 
16017 OMPClause *SemaOpenMP::ActOnOpenMPSeverityClause(OpenMPSeverityClauseKind Kind,
16018                                                  SourceLocation KindKwLoc,
16019                                                  SourceLocation StartLoc,
16020                                                  SourceLocation LParenLoc,
16021                                                  SourceLocation EndLoc) {
16022   if (Kind == OMPC_SEVERITY_unknown) {
16023     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16024         << getListOfPossibleValues(OMPC_severity, /*First=*/0,
16025                                    /*Last=*/OMPC_SEVERITY_unknown)
16026         << getOpenMPClauseName(OMPC_severity);
16027     return nullptr;
16028   }
16029   return new (getASTContext())
16030       OMPSeverityClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
16031 }
16032 
16033 OMPClause *SemaOpenMP::ActOnOpenMPMessageClause(Expr *ME,
16034                                                 SourceLocation StartLoc,
16035                                                 SourceLocation LParenLoc,
16036                                                 SourceLocation EndLoc) {
16037   assert(ME && "NULL expr in Message clause");
16038   if (!isa<StringLiteral>(ME)) {
16039     Diag(ME->getBeginLoc(), diag::warn_clause_expected_string)
16040         << getOpenMPClauseName(OMPC_message);
16041     return nullptr;
16042   }
16043   return new (getASTContext())
16044       OMPMessageClause(ME, StartLoc, LParenLoc, EndLoc);
16045 }
16046 
16047 OMPClause *SemaOpenMP::ActOnOpenMPOrderClause(
16048     OpenMPOrderClauseModifier Modifier, OpenMPOrderClauseKind Kind,
16049     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
16050     SourceLocation KindLoc, SourceLocation EndLoc) {
16051   if (Kind != OMPC_ORDER_concurrent ||
16052       (getLangOpts().OpenMP < 51 && MLoc.isValid())) {
16053     // Kind should be concurrent,
16054     // Modifiers introduced in OpenMP 5.1
16055     static_assert(OMPC_ORDER_unknown > 0,
16056                   "OMPC_ORDER_unknown not greater than 0");
16057 
16058     Diag(KindLoc, diag::err_omp_unexpected_clause_value)
16059         << getListOfPossibleValues(OMPC_order,
16060                                    /*First=*/0,
16061                                    /*Last=*/OMPC_ORDER_unknown)
16062         << getOpenMPClauseName(OMPC_order);
16063     return nullptr;
16064   }
16065   if (getLangOpts().OpenMP >= 51) {
16066     if (Modifier == OMPC_ORDER_MODIFIER_unknown && MLoc.isValid()) {
16067       Diag(MLoc, diag::err_omp_unexpected_clause_value)
16068           << getListOfPossibleValues(OMPC_order,
16069                                      /*First=*/OMPC_ORDER_MODIFIER_unknown + 1,
16070                                      /*Last=*/OMPC_ORDER_MODIFIER_last)
16071           << getOpenMPClauseName(OMPC_order);
16072     } else {
16073       DSAStack->setRegionHasOrderConcurrent(/*HasOrderConcurrent=*/true);
16074       if (DSAStack->getCurScope()) {
16075         // mark the current scope with 'order' flag
16076         unsigned existingFlags = DSAStack->getCurScope()->getFlags();
16077         DSAStack->getCurScope()->setFlags(existingFlags |
16078                                           Scope::OpenMPOrderClauseScope);
16079       }
16080     }
16081   }
16082   return new (getASTContext()) OMPOrderClause(
16083       Kind, KindLoc, StartLoc, LParenLoc, EndLoc, Modifier, MLoc);
16084 }
16085 
16086 OMPClause *SemaOpenMP::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,
16087                                                SourceLocation KindKwLoc,
16088                                                SourceLocation StartLoc,
16089                                                SourceLocation LParenLoc,
16090                                                SourceLocation EndLoc) {
16091   if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source ||
16092       Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) {
16093     SmallVector<unsigned> Except = {
16094         OMPC_DEPEND_source, OMPC_DEPEND_sink, OMPC_DEPEND_depobj,
16095         OMPC_DEPEND_outallmemory, OMPC_DEPEND_inoutallmemory};
16096     if (getLangOpts().OpenMP < 51)
16097       Except.push_back(OMPC_DEPEND_inoutset);
16098     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
16099         << getListOfPossibleValues(OMPC_depend, /*First=*/0,
16100                                    /*Last=*/OMPC_DEPEND_unknown, Except)
16101         << getOpenMPClauseName(OMPC_update);
16102     return nullptr;
16103   }
16104   return OMPUpdateClause::Create(getASTContext(), StartLoc, LParenLoc,
16105                                  KindKwLoc, Kind, EndLoc);
16106 }
16107 
16108 OMPClause *SemaOpenMP::ActOnOpenMPSizesClause(ArrayRef<Expr *> SizeExprs,
16109                                               SourceLocation StartLoc,
16110                                               SourceLocation LParenLoc,
16111                                               SourceLocation EndLoc) {
16112   SmallVector<Expr *> SanitizedSizeExprs(SizeExprs);
16113 
16114   for (Expr *&SizeExpr : SanitizedSizeExprs) {
16115     // Skip if already sanitized, e.g. during a partial template instantiation.
16116     if (!SizeExpr)
16117       continue;
16118 
16119     bool IsValid = isNonNegativeIntegerValue(SizeExpr, SemaRef, OMPC_sizes,
16120                                              /*StrictlyPositive=*/true);
16121 
16122     // isNonNegativeIntegerValue returns true for non-integral types (but still
16123     // emits error diagnostic), so check for the expected type explicitly.
16124     QualType SizeTy = SizeExpr->getType();
16125     if (!SizeTy->isIntegerType())
16126       IsValid = false;
16127 
16128     // Handling in templates is tricky. There are four possibilities to
16129     // consider:
16130     //
16131     // 1a. The expression is valid and we are in a instantiated template or not
16132     //     in a template:
16133     //       Pass valid expression to be further analysed later in Sema.
16134     // 1b. The expression is valid and we are in a template (including partial
16135     //     instantiation):
16136     //       isNonNegativeIntegerValue skipped any checks so there is no
16137     //       guarantee it will be correct after instantiation.
16138     //       ActOnOpenMPSizesClause will be called again at instantiation when
16139     //       it is not in a dependent context anymore. This may cause warnings
16140     //       to be emitted multiple times.
16141     // 2a. The expression is invalid and we are in an instantiated template or
16142     //     not in a template:
16143     //       Invalidate the expression with a clearly wrong value (nullptr) so
16144     //       later in Sema we do not have to do the same validity analysis again
16145     //       or crash from unexpected data. Error diagnostics have already been
16146     //       emitted.
16147     // 2b. The expression is invalid and we are in a template (including partial
16148     //     instantiation):
16149     //       Pass the invalid expression as-is, template instantiation may
16150     //       replace unexpected types/values with valid ones. The directives
16151     //       with this clause must not try to use these expressions in dependent
16152     //       contexts, but delay analysis until full instantiation.
16153     if (!SizeExpr->isInstantiationDependent() && !IsValid)
16154       SizeExpr = nullptr;
16155   }
16156 
16157   return OMPSizesClause::Create(getASTContext(), StartLoc, LParenLoc, EndLoc,
16158                                 SanitizedSizeExprs);
16159 }
16160 
16161 OMPClause *SemaOpenMP::ActOnOpenMPPermutationClause(ArrayRef<Expr *> PermExprs,
16162                                                     SourceLocation StartLoc,
16163                                                     SourceLocation LParenLoc,
16164                                                     SourceLocation EndLoc) {
16165   size_t NumLoops = PermExprs.size();
16166   SmallVector<Expr *> SanitizedPermExprs;
16167   llvm::append_range(SanitizedPermExprs, PermExprs);
16168 
16169   for (Expr *&PermExpr : SanitizedPermExprs) {
16170     // Skip if template-dependent or already sanitized, e.g. during a partial
16171     // template instantiation.
16172     if (!PermExpr || PermExpr->isInstantiationDependent())
16173       continue;
16174 
16175     llvm::APSInt PermVal;
16176     ExprResult PermEvalExpr = SemaRef.VerifyIntegerConstantExpression(
16177         PermExpr, &PermVal, Sema::AllowFold);
16178     bool IsValid = PermEvalExpr.isUsable();
16179     if (IsValid)
16180       PermExpr = PermEvalExpr.get();
16181 
16182     if (IsValid && (PermVal < 1 || NumLoops < PermVal)) {
16183       SourceRange ExprRange(PermEvalExpr.get()->getBeginLoc(),
16184                             PermEvalExpr.get()->getEndLoc());
16185       Diag(PermEvalExpr.get()->getExprLoc(),
16186            diag::err_omp_interchange_permutation_value_range)
16187           << NumLoops << ExprRange;
16188       IsValid = false;
16189     }
16190 
16191     if (!PermExpr->isInstantiationDependent() && !IsValid)
16192       PermExpr = nullptr;
16193   }
16194 
16195   return OMPPermutationClause::Create(getASTContext(), StartLoc, LParenLoc,
16196                                       EndLoc, SanitizedPermExprs);
16197 }
16198 
16199 OMPClause *SemaOpenMP::ActOnOpenMPFullClause(SourceLocation StartLoc,
16200                                              SourceLocation EndLoc) {
16201   return OMPFullClause::Create(getASTContext(), StartLoc, EndLoc);
16202 }
16203 
16204 OMPClause *SemaOpenMP::ActOnOpenMPPartialClause(Expr *FactorExpr,
16205                                                 SourceLocation StartLoc,
16206                                                 SourceLocation LParenLoc,
16207                                                 SourceLocation EndLoc) {
16208   if (FactorExpr) {
16209     // If an argument is specified, it must be a constant (or an unevaluated
16210     // template expression).
16211     ExprResult FactorResult = VerifyPositiveIntegerConstantInClause(
16212         FactorExpr, OMPC_partial, /*StrictlyPositive=*/true);
16213     if (FactorResult.isInvalid())
16214       return nullptr;
16215     FactorExpr = FactorResult.get();
16216   }
16217 
16218   return OMPPartialClause::Create(getASTContext(), StartLoc, LParenLoc, EndLoc,
16219                                   FactorExpr);
16220 }
16221 
16222 OMPClause *SemaOpenMP::ActOnOpenMPAlignClause(Expr *A, SourceLocation StartLoc,
16223                                               SourceLocation LParenLoc,
16224                                               SourceLocation EndLoc) {
16225   ExprResult AlignVal;
16226   AlignVal = VerifyPositiveIntegerConstantInClause(A, OMPC_align);
16227   if (AlignVal.isInvalid())
16228     return nullptr;
16229   return OMPAlignClause::Create(getASTContext(), AlignVal.get(), StartLoc,
16230                                 LParenLoc, EndLoc);
16231 }
16232 
16233 OMPClause *SemaOpenMP::ActOnOpenMPSingleExprWithArgClause(
16234     OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
16235     SourceLocation StartLoc, SourceLocation LParenLoc,
16236     ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
16237     SourceLocation EndLoc) {
16238   OMPClause *Res = nullptr;
16239   switch (Kind) {
16240   case OMPC_schedule:
16241     enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
16242     assert(Argument.size() == NumberOfElements &&
16243            ArgumentLoc.size() == NumberOfElements);
16244     Res = ActOnOpenMPScheduleClause(
16245         static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
16246         static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
16247         static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
16248         StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
16249         ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
16250     break;
16251   case OMPC_if:
16252     assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
16253     Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
16254                               Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
16255                               DelimLoc, EndLoc);
16256     break;
16257   case OMPC_dist_schedule:
16258     Res = ActOnOpenMPDistScheduleClause(
16259         static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
16260         StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
16261     break;
16262   case OMPC_defaultmap:
16263     enum { Modifier, DefaultmapKind };
16264     Res = ActOnOpenMPDefaultmapClause(
16265         static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
16266         static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
16267         StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
16268         EndLoc);
16269     break;
16270   case OMPC_order:
16271     enum { OrderModifier, OrderKind };
16272     Res = ActOnOpenMPOrderClause(
16273         static_cast<OpenMPOrderClauseModifier>(Argument[OrderModifier]),
16274         static_cast<OpenMPOrderClauseKind>(Argument[OrderKind]), StartLoc,
16275         LParenLoc, ArgumentLoc[OrderModifier], ArgumentLoc[OrderKind], EndLoc);
16276     break;
16277   case OMPC_device:
16278     assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
16279     Res = ActOnOpenMPDeviceClause(
16280         static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr,
16281         StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
16282     break;
16283   case OMPC_grainsize:
16284     assert(Argument.size() == 1 && ArgumentLoc.size() == 1 &&
16285            "Modifier for grainsize clause and its location are expected.");
16286     Res = ActOnOpenMPGrainsizeClause(
16287         static_cast<OpenMPGrainsizeClauseModifier>(Argument.back()), Expr,
16288         StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
16289     break;
16290   case OMPC_num_tasks:
16291     assert(Argument.size() == 1 && ArgumentLoc.size() == 1 &&
16292            "Modifier for num_tasks clause and its location are expected.");
16293     Res = ActOnOpenMPNumTasksClause(
16294         static_cast<OpenMPNumTasksClauseModifier>(Argument.back()), Expr,
16295         StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
16296     break;
16297   case OMPC_final:
16298   case OMPC_num_threads:
16299   case OMPC_safelen:
16300   case OMPC_simdlen:
16301   case OMPC_sizes:
16302   case OMPC_allocator:
16303   case OMPC_collapse:
16304   case OMPC_default:
16305   case OMPC_proc_bind:
16306   case OMPC_private:
16307   case OMPC_firstprivate:
16308   case OMPC_lastprivate:
16309   case OMPC_shared:
16310   case OMPC_reduction:
16311   case OMPC_task_reduction:
16312   case OMPC_in_reduction:
16313   case OMPC_linear:
16314   case OMPC_aligned:
16315   case OMPC_copyin:
16316   case OMPC_copyprivate:
16317   case OMPC_ordered:
16318   case OMPC_nowait:
16319   case OMPC_untied:
16320   case OMPC_mergeable:
16321   case OMPC_threadprivate:
16322   case OMPC_allocate:
16323   case OMPC_flush:
16324   case OMPC_depobj:
16325   case OMPC_read:
16326   case OMPC_write:
16327   case OMPC_update:
16328   case OMPC_capture:
16329   case OMPC_compare:
16330   case OMPC_seq_cst:
16331   case OMPC_acq_rel:
16332   case OMPC_acquire:
16333   case OMPC_release:
16334   case OMPC_relaxed:
16335   case OMPC_depend:
16336   case OMPC_threads:
16337   case OMPC_simd:
16338   case OMPC_map:
16339   case OMPC_num_teams:
16340   case OMPC_thread_limit:
16341   case OMPC_priority:
16342   case OMPC_nogroup:
16343   case OMPC_hint:
16344   case OMPC_unknown:
16345   case OMPC_uniform:
16346   case OMPC_to:
16347   case OMPC_from:
16348   case OMPC_use_device_ptr:
16349   case OMPC_use_device_addr:
16350   case OMPC_is_device_ptr:
16351   case OMPC_has_device_addr:
16352   case OMPC_unified_address:
16353   case OMPC_unified_shared_memory:
16354   case OMPC_reverse_offload:
16355   case OMPC_dynamic_allocators:
16356   case OMPC_atomic_default_mem_order:
16357   case OMPC_device_type:
16358   case OMPC_match:
16359   case OMPC_nontemporal:
16360   case OMPC_at:
16361   case OMPC_severity:
16362   case OMPC_message:
16363   case OMPC_destroy:
16364   case OMPC_novariants:
16365   case OMPC_nocontext:
16366   case OMPC_detach:
16367   case OMPC_inclusive:
16368   case OMPC_exclusive:
16369   case OMPC_uses_allocators:
16370   case OMPC_affinity:
16371   case OMPC_when:
16372   case OMPC_bind:
16373   default:
16374     llvm_unreachable("Clause is not allowed.");
16375   }
16376   return Res;
16377 }
16378 
16379 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
16380                                    OpenMPScheduleClauseModifier M2,
16381                                    SourceLocation M1Loc, SourceLocation M2Loc) {
16382   if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
16383     SmallVector<unsigned, 2> Excluded;
16384     if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
16385       Excluded.push_back(M2);
16386     if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
16387       Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
16388     if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
16389       Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
16390     S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
16391         << getListOfPossibleValues(OMPC_schedule,
16392                                    /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
16393                                    /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
16394                                    Excluded)
16395         << getOpenMPClauseName(OMPC_schedule);
16396     return true;
16397   }
16398   return false;
16399 }
16400 
16401 OMPClause *SemaOpenMP::ActOnOpenMPScheduleClause(
16402     OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
16403     OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
16404     SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
16405     SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
16406   if (checkScheduleModifiers(SemaRef, M1, M2, M1Loc, M2Loc) ||
16407       checkScheduleModifiers(SemaRef, M2, M1, M2Loc, M1Loc))
16408     return nullptr;
16409   // OpenMP, 2.7.1, Loop Construct, Restrictions
16410   // Either the monotonic modifier or the nonmonotonic modifier can be specified
16411   // but not both.
16412   if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
16413       (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
16414        M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
16415       (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
16416        M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
16417     Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
16418         << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
16419         << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
16420     return nullptr;
16421   }
16422   if (Kind == OMPC_SCHEDULE_unknown) {
16423     std::string Values;
16424     if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
16425       unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
16426       Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
16427                                        /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
16428                                        Exclude);
16429     } else {
16430       Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
16431                                        /*Last=*/OMPC_SCHEDULE_unknown);
16432     }
16433     Diag(KindLoc, diag::err_omp_unexpected_clause_value)
16434         << Values << getOpenMPClauseName(OMPC_schedule);
16435     return nullptr;
16436   }
16437   // OpenMP, 2.7.1, Loop Construct, Restrictions
16438   // The nonmonotonic modifier can only be specified with schedule(dynamic) or
16439   // schedule(guided).
16440   // OpenMP 5.0 does not have this restriction.
16441   if (getLangOpts().OpenMP < 50 &&
16442       (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
16443        M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
16444       Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
16445     Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
16446          diag::err_omp_schedule_nonmonotonic_static);
16447     return nullptr;
16448   }
16449   Expr *ValExpr = ChunkSize;
16450   Stmt *HelperValStmt = nullptr;
16451   if (ChunkSize) {
16452     if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
16453         !ChunkSize->isInstantiationDependent() &&
16454         !ChunkSize->containsUnexpandedParameterPack()) {
16455       SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
16456       ExprResult Val =
16457           PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
16458       if (Val.isInvalid())
16459         return nullptr;
16460 
16461       ValExpr = Val.get();
16462 
16463       // OpenMP [2.7.1, Restrictions]
16464       //  chunk_size must be a loop invariant integer expression with a positive
16465       //  value.
16466       if (std::optional<llvm::APSInt> Result =
16467               ValExpr->getIntegerConstantExpr(getASTContext())) {
16468         if (Result->isSigned() && !Result->isStrictlyPositive()) {
16469           Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
16470               << "schedule" << 1 << ChunkSize->getSourceRange();
16471           return nullptr;
16472         }
16473       } else if (getOpenMPCaptureRegionForClause(
16474                      DSAStack->getCurrentDirective(), OMPC_schedule,
16475                      getLangOpts().OpenMP) != OMPD_unknown &&
16476                  !SemaRef.CurContext->isDependentContext()) {
16477         ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
16478         llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16479         ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
16480         HelperValStmt = buildPreInits(getASTContext(), Captures);
16481       }
16482     }
16483   }
16484 
16485   return new (getASTContext())
16486       OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
16487                         ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
16488 }
16489 
16490 OMPClause *SemaOpenMP::ActOnOpenMPClause(OpenMPClauseKind Kind,
16491                                          SourceLocation StartLoc,
16492                                          SourceLocation EndLoc) {
16493   OMPClause *Res = nullptr;
16494   switch (Kind) {
16495   case OMPC_ordered:
16496     Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
16497     break;
16498   case OMPC_nowait:
16499     Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
16500     break;
16501   case OMPC_untied:
16502     Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
16503     break;
16504   case OMPC_mergeable:
16505     Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
16506     break;
16507   case OMPC_read:
16508     Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
16509     break;
16510   case OMPC_write:
16511     Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
16512     break;
16513   case OMPC_update:
16514     Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
16515     break;
16516   case OMPC_capture:
16517     Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
16518     break;
16519   case OMPC_compare:
16520     Res = ActOnOpenMPCompareClause(StartLoc, EndLoc);
16521     break;
16522   case OMPC_fail:
16523     Res = ActOnOpenMPFailClause(StartLoc, EndLoc);
16524     break;
16525   case OMPC_seq_cst:
16526     Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
16527     break;
16528   case OMPC_acq_rel:
16529     Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc);
16530     break;
16531   case OMPC_acquire:
16532     Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc);
16533     break;
16534   case OMPC_release:
16535     Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc);
16536     break;
16537   case OMPC_relaxed:
16538     Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc);
16539     break;
16540   case OMPC_weak:
16541     Res = ActOnOpenMPWeakClause(StartLoc, EndLoc);
16542     break;
16543   case OMPC_threads:
16544     Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
16545     break;
16546   case OMPC_simd:
16547     Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
16548     break;
16549   case OMPC_nogroup:
16550     Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
16551     break;
16552   case OMPC_unified_address:
16553     Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
16554     break;
16555   case OMPC_unified_shared_memory:
16556     Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
16557     break;
16558   case OMPC_reverse_offload:
16559     Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
16560     break;
16561   case OMPC_dynamic_allocators:
16562     Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
16563     break;
16564   case OMPC_destroy:
16565     Res = ActOnOpenMPDestroyClause(/*InteropVar=*/nullptr, StartLoc,
16566                                    /*LParenLoc=*/SourceLocation(),
16567                                    /*VarLoc=*/SourceLocation(), EndLoc);
16568     break;
16569   case OMPC_full:
16570     Res = ActOnOpenMPFullClause(StartLoc, EndLoc);
16571     break;
16572   case OMPC_partial:
16573     Res = ActOnOpenMPPartialClause(nullptr, StartLoc, /*LParenLoc=*/{}, EndLoc);
16574     break;
16575   case OMPC_ompx_bare:
16576     Res = ActOnOpenMPXBareClause(StartLoc, EndLoc);
16577     break;
16578   case OMPC_if:
16579   case OMPC_final:
16580   case OMPC_num_threads:
16581   case OMPC_safelen:
16582   case OMPC_simdlen:
16583   case OMPC_sizes:
16584   case OMPC_allocator:
16585   case OMPC_collapse:
16586   case OMPC_schedule:
16587   case OMPC_private:
16588   case OMPC_firstprivate:
16589   case OMPC_lastprivate:
16590   case OMPC_shared:
16591   case OMPC_reduction:
16592   case OMPC_task_reduction:
16593   case OMPC_in_reduction:
16594   case OMPC_linear:
16595   case OMPC_aligned:
16596   case OMPC_copyin:
16597   case OMPC_copyprivate:
16598   case OMPC_default:
16599   case OMPC_proc_bind:
16600   case OMPC_threadprivate:
16601   case OMPC_allocate:
16602   case OMPC_flush:
16603   case OMPC_depobj:
16604   case OMPC_depend:
16605   case OMPC_device:
16606   case OMPC_map:
16607   case OMPC_num_teams:
16608   case OMPC_thread_limit:
16609   case OMPC_priority:
16610   case OMPC_grainsize:
16611   case OMPC_num_tasks:
16612   case OMPC_hint:
16613   case OMPC_dist_schedule:
16614   case OMPC_defaultmap:
16615   case OMPC_unknown:
16616   case OMPC_uniform:
16617   case OMPC_to:
16618   case OMPC_from:
16619   case OMPC_use_device_ptr:
16620   case OMPC_use_device_addr:
16621   case OMPC_is_device_ptr:
16622   case OMPC_has_device_addr:
16623   case OMPC_atomic_default_mem_order:
16624   case OMPC_device_type:
16625   case OMPC_match:
16626   case OMPC_nontemporal:
16627   case OMPC_order:
16628   case OMPC_at:
16629   case OMPC_severity:
16630   case OMPC_message:
16631   case OMPC_novariants:
16632   case OMPC_nocontext:
16633   case OMPC_detach:
16634   case OMPC_inclusive:
16635   case OMPC_exclusive:
16636   case OMPC_uses_allocators:
16637   case OMPC_affinity:
16638   case OMPC_when:
16639   case OMPC_ompx_dyn_cgroup_mem:
16640   default:
16641     llvm_unreachable("Clause is not allowed.");
16642   }
16643   return Res;
16644 }
16645 
16646 OMPClause *SemaOpenMP::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
16647                                                SourceLocation EndLoc) {
16648   DSAStack->setNowaitRegion();
16649   return new (getASTContext()) OMPNowaitClause(StartLoc, EndLoc);
16650 }
16651 
16652 OMPClause *SemaOpenMP::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
16653                                                SourceLocation EndLoc) {
16654   DSAStack->setUntiedRegion();
16655   return new (getASTContext()) OMPUntiedClause(StartLoc, EndLoc);
16656 }
16657 
16658 OMPClause *SemaOpenMP::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
16659                                                   SourceLocation EndLoc) {
16660   return new (getASTContext()) OMPMergeableClause(StartLoc, EndLoc);
16661 }
16662 
16663 OMPClause *SemaOpenMP::ActOnOpenMPReadClause(SourceLocation StartLoc,
16664                                              SourceLocation EndLoc) {
16665   return new (getASTContext()) OMPReadClause(StartLoc, EndLoc);
16666 }
16667 
16668 OMPClause *SemaOpenMP::ActOnOpenMPWriteClause(SourceLocation StartLoc,
16669                                               SourceLocation EndLoc) {
16670   return new (getASTContext()) OMPWriteClause(StartLoc, EndLoc);
16671 }
16672 
16673 OMPClause *SemaOpenMP::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
16674                                                SourceLocation EndLoc) {
16675   return OMPUpdateClause::Create(getASTContext(), StartLoc, EndLoc);
16676 }
16677 
16678 OMPClause *SemaOpenMP::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
16679                                                 SourceLocation EndLoc) {
16680   return new (getASTContext()) OMPCaptureClause(StartLoc, EndLoc);
16681 }
16682 
16683 OMPClause *SemaOpenMP::ActOnOpenMPCompareClause(SourceLocation StartLoc,
16684                                                 SourceLocation EndLoc) {
16685   return new (getASTContext()) OMPCompareClause(StartLoc, EndLoc);
16686 }
16687 
16688 OMPClause *SemaOpenMP::ActOnOpenMPFailClause(SourceLocation StartLoc,
16689                                              SourceLocation EndLoc) {
16690   return new (getASTContext()) OMPFailClause(StartLoc, EndLoc);
16691 }
16692 
16693 OMPClause *SemaOpenMP::ActOnOpenMPFailClause(OpenMPClauseKind Parameter,
16694                                              SourceLocation KindLoc,
16695                                              SourceLocation StartLoc,
16696                                              SourceLocation LParenLoc,
16697                                              SourceLocation EndLoc) {
16698 
16699   if (!checkFailClauseParameter(Parameter)) {
16700     Diag(KindLoc, diag::err_omp_atomic_fail_wrong_or_no_clauses);
16701     return nullptr;
16702   }
16703   return new (getASTContext())
16704       OMPFailClause(Parameter, KindLoc, StartLoc, LParenLoc, EndLoc);
16705 }
16706 
16707 OMPClause *SemaOpenMP::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
16708                                                SourceLocation EndLoc) {
16709   return new (getASTContext()) OMPSeqCstClause(StartLoc, EndLoc);
16710 }
16711 
16712 OMPClause *SemaOpenMP::ActOnOpenMPAcqRelClause(SourceLocation StartLoc,
16713                                                SourceLocation EndLoc) {
16714   return new (getASTContext()) OMPAcqRelClause(StartLoc, EndLoc);
16715 }
16716 
16717 OMPClause *SemaOpenMP::ActOnOpenMPAcquireClause(SourceLocation StartLoc,
16718                                                 SourceLocation EndLoc) {
16719   return new (getASTContext()) OMPAcquireClause(StartLoc, EndLoc);
16720 }
16721 
16722 OMPClause *SemaOpenMP::ActOnOpenMPReleaseClause(SourceLocation StartLoc,
16723                                                 SourceLocation EndLoc) {
16724   return new (getASTContext()) OMPReleaseClause(StartLoc, EndLoc);
16725 }
16726 
16727 OMPClause *SemaOpenMP::ActOnOpenMPRelaxedClause(SourceLocation StartLoc,
16728                                                 SourceLocation EndLoc) {
16729   return new (getASTContext()) OMPRelaxedClause(StartLoc, EndLoc);
16730 }
16731 
16732 OMPClause *SemaOpenMP::ActOnOpenMPWeakClause(SourceLocation StartLoc,
16733                                              SourceLocation EndLoc) {
16734   return new (getASTContext()) OMPWeakClause(StartLoc, EndLoc);
16735 }
16736 
16737 OMPClause *SemaOpenMP::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
16738                                                 SourceLocation EndLoc) {
16739   return new (getASTContext()) OMPThreadsClause(StartLoc, EndLoc);
16740 }
16741 
16742 OMPClause *SemaOpenMP::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
16743                                              SourceLocation EndLoc) {
16744   return new (getASTContext()) OMPSIMDClause(StartLoc, EndLoc);
16745 }
16746 
16747 OMPClause *SemaOpenMP::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
16748                                                 SourceLocation EndLoc) {
16749   return new (getASTContext()) OMPNogroupClause(StartLoc, EndLoc);
16750 }
16751 
16752 OMPClause *SemaOpenMP::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
16753                                                        SourceLocation EndLoc) {
16754   return new (getASTContext()) OMPUnifiedAddressClause(StartLoc, EndLoc);
16755 }
16756 
16757 OMPClause *
16758 SemaOpenMP::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
16759                                                  SourceLocation EndLoc) {
16760   return new (getASTContext()) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
16761 }
16762 
16763 OMPClause *SemaOpenMP::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
16764                                                        SourceLocation EndLoc) {
16765   return new (getASTContext()) OMPReverseOffloadClause(StartLoc, EndLoc);
16766 }
16767 
16768 OMPClause *
16769 SemaOpenMP::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
16770                                                SourceLocation EndLoc) {
16771   return new (getASTContext()) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
16772 }
16773 
16774 StmtResult
16775 SemaOpenMP::ActOnOpenMPInteropDirective(ArrayRef<OMPClause *> Clauses,
16776                                         SourceLocation StartLoc,
16777                                         SourceLocation EndLoc) {
16778 
16779   // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
16780   // At least one action-clause must appear on a directive.
16781   if (!hasClauses(Clauses, OMPC_init, OMPC_use, OMPC_destroy, OMPC_nowait)) {
16782     StringRef Expected = "'init', 'use', 'destroy', or 'nowait'";
16783     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
16784         << Expected << getOpenMPDirectiveName(OMPD_interop);
16785     return StmtError();
16786   }
16787 
16788   // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
16789   // A depend clause can only appear on the directive if a targetsync
16790   // interop-type is present or the interop-var was initialized with
16791   // the targetsync interop-type.
16792 
16793   // If there is any 'init' clause diagnose if there is no 'init' clause with
16794   // interop-type of 'targetsync'. Cases involving other directives cannot be
16795   // diagnosed.
16796   const OMPDependClause *DependClause = nullptr;
16797   bool HasInitClause = false;
16798   bool IsTargetSync = false;
16799   for (const OMPClause *C : Clauses) {
16800     if (IsTargetSync)
16801       break;
16802     if (const auto *InitClause = dyn_cast<OMPInitClause>(C)) {
16803       HasInitClause = true;
16804       if (InitClause->getIsTargetSync())
16805         IsTargetSync = true;
16806     } else if (const auto *DC = dyn_cast<OMPDependClause>(C)) {
16807       DependClause = DC;
16808     }
16809   }
16810   if (DependClause && HasInitClause && !IsTargetSync) {
16811     Diag(DependClause->getBeginLoc(), diag::err_omp_interop_bad_depend_clause);
16812     return StmtError();
16813   }
16814 
16815   // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
16816   // Each interop-var may be specified for at most one action-clause of each
16817   // interop construct.
16818   llvm::SmallPtrSet<const ValueDecl *, 4> InteropVars;
16819   for (OMPClause *C : Clauses) {
16820     OpenMPClauseKind ClauseKind = C->getClauseKind();
16821     std::pair<ValueDecl *, bool> DeclResult;
16822     SourceLocation ELoc;
16823     SourceRange ERange;
16824 
16825     if (ClauseKind == OMPC_init) {
16826       auto *E = cast<OMPInitClause>(C)->getInteropVar();
16827       DeclResult = getPrivateItem(SemaRef, E, ELoc, ERange);
16828     } else if (ClauseKind == OMPC_use) {
16829       auto *E = cast<OMPUseClause>(C)->getInteropVar();
16830       DeclResult = getPrivateItem(SemaRef, E, ELoc, ERange);
16831     } else if (ClauseKind == OMPC_destroy) {
16832       auto *E = cast<OMPDestroyClause>(C)->getInteropVar();
16833       DeclResult = getPrivateItem(SemaRef, E, ELoc, ERange);
16834     }
16835 
16836     if (DeclResult.first) {
16837       if (!InteropVars.insert(DeclResult.first).second) {
16838         Diag(ELoc, diag::err_omp_interop_var_multiple_actions)
16839             << DeclResult.first;
16840         return StmtError();
16841       }
16842     }
16843   }
16844 
16845   return OMPInteropDirective::Create(getASTContext(), StartLoc, EndLoc,
16846                                      Clauses);
16847 }
16848 
16849 static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr,
16850                                    SourceLocation VarLoc,
16851                                    OpenMPClauseKind Kind) {
16852   SourceLocation ELoc;
16853   SourceRange ERange;
16854   Expr *RefExpr = InteropVarExpr;
16855   auto Res =
16856       getPrivateItem(SemaRef, RefExpr, ELoc, ERange,
16857                      /*AllowArraySection=*/false, /*DiagType=*/"omp_interop_t");
16858 
16859   if (Res.second) {
16860     // It will be analyzed later.
16861     return true;
16862   }
16863 
16864   if (!Res.first)
16865     return false;
16866 
16867   // Interop variable should be of type omp_interop_t.
16868   bool HasError = false;
16869   QualType InteropType;
16870   LookupResult Result(SemaRef, &SemaRef.Context.Idents.get("omp_interop_t"),
16871                       VarLoc, Sema::LookupOrdinaryName);
16872   if (SemaRef.LookupName(Result, SemaRef.getCurScope())) {
16873     NamedDecl *ND = Result.getFoundDecl();
16874     if (const auto *TD = dyn_cast<TypeDecl>(ND)) {
16875       InteropType = QualType(TD->getTypeForDecl(), 0);
16876     } else {
16877       HasError = true;
16878     }
16879   } else {
16880     HasError = true;
16881   }
16882 
16883   if (HasError) {
16884     SemaRef.Diag(VarLoc, diag::err_omp_implied_type_not_found)
16885         << "omp_interop_t";
16886     return false;
16887   }
16888 
16889   QualType VarType = InteropVarExpr->getType().getUnqualifiedType();
16890   if (!SemaRef.Context.hasSameType(InteropType, VarType)) {
16891     SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_wrong_type);
16892     return false;
16893   }
16894 
16895   // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
16896   // The interop-var passed to init or destroy must be non-const.
16897   if ((Kind == OMPC_init || Kind == OMPC_destroy) &&
16898       isConstNotMutableType(SemaRef, InteropVarExpr->getType())) {
16899     SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected)
16900         << /*non-const*/ 1;
16901     return false;
16902   }
16903   return true;
16904 }
16905 
16906 OMPClause *SemaOpenMP::ActOnOpenMPInitClause(
16907     Expr *InteropVar, OMPInteropInfo &InteropInfo, SourceLocation StartLoc,
16908     SourceLocation LParenLoc, SourceLocation VarLoc, SourceLocation EndLoc) {
16909 
16910   if (!isValidInteropVariable(SemaRef, InteropVar, VarLoc, OMPC_init))
16911     return nullptr;
16912 
16913   // Check prefer_type values.  These foreign-runtime-id values are either
16914   // string literals or constant integral expressions.
16915   for (const Expr *E : InteropInfo.PreferTypes) {
16916     if (E->isValueDependent() || E->isTypeDependent() ||
16917         E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
16918       continue;
16919     if (E->isIntegerConstantExpr(getASTContext()))
16920       continue;
16921     if (isa<StringLiteral>(E))
16922       continue;
16923     Diag(E->getExprLoc(), diag::err_omp_interop_prefer_type);
16924     return nullptr;
16925   }
16926 
16927   return OMPInitClause::Create(getASTContext(), InteropVar, InteropInfo,
16928                                StartLoc, LParenLoc, VarLoc, EndLoc);
16929 }
16930 
16931 OMPClause *SemaOpenMP::ActOnOpenMPUseClause(Expr *InteropVar,
16932                                             SourceLocation StartLoc,
16933                                             SourceLocation LParenLoc,
16934                                             SourceLocation VarLoc,
16935                                             SourceLocation EndLoc) {
16936 
16937   if (!isValidInteropVariable(SemaRef, InteropVar, VarLoc, OMPC_use))
16938     return nullptr;
16939 
16940   return new (getASTContext())
16941       OMPUseClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
16942 }
16943 
16944 OMPClause *SemaOpenMP::ActOnOpenMPDestroyClause(Expr *InteropVar,
16945                                                 SourceLocation StartLoc,
16946                                                 SourceLocation LParenLoc,
16947                                                 SourceLocation VarLoc,
16948                                                 SourceLocation EndLoc) {
16949   if (!InteropVar && getLangOpts().OpenMP >= 52 &&
16950       DSAStack->getCurrentDirective() == OMPD_depobj) {
16951     Diag(StartLoc, diag::err_omp_expected_clause_argument)
16952         << getOpenMPClauseName(OMPC_destroy)
16953         << getOpenMPDirectiveName(OMPD_depobj);
16954     return nullptr;
16955   }
16956   if (InteropVar &&
16957       !isValidInteropVariable(SemaRef, InteropVar, VarLoc, OMPC_destroy))
16958     return nullptr;
16959 
16960   return new (getASTContext())
16961       OMPDestroyClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
16962 }
16963 
16964 OMPClause *SemaOpenMP::ActOnOpenMPNovariantsClause(Expr *Condition,
16965                                                    SourceLocation StartLoc,
16966                                                    SourceLocation LParenLoc,
16967                                                    SourceLocation EndLoc) {
16968   Expr *ValExpr = Condition;
16969   Stmt *HelperValStmt = nullptr;
16970   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
16971   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
16972       !Condition->isInstantiationDependent() &&
16973       !Condition->containsUnexpandedParameterPack()) {
16974     ExprResult Val = SemaRef.CheckBooleanCondition(StartLoc, Condition);
16975     if (Val.isInvalid())
16976       return nullptr;
16977 
16978     ValExpr = SemaRef.MakeFullExpr(Val.get()).get();
16979 
16980     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16981     CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_novariants,
16982                                                     getLangOpts().OpenMP);
16983     if (CaptureRegion != OMPD_unknown &&
16984         !SemaRef.CurContext->isDependentContext()) {
16985       ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
16986       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16987       ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
16988       HelperValStmt = buildPreInits(getASTContext(), Captures);
16989     }
16990   }
16991 
16992   return new (getASTContext()) OMPNovariantsClause(
16993       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
16994 }
16995 
16996 OMPClause *SemaOpenMP::ActOnOpenMPNocontextClause(Expr *Condition,
16997                                                   SourceLocation StartLoc,
16998                                                   SourceLocation LParenLoc,
16999                                                   SourceLocation EndLoc) {
17000   Expr *ValExpr = Condition;
17001   Stmt *HelperValStmt = nullptr;
17002   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
17003   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
17004       !Condition->isInstantiationDependent() &&
17005       !Condition->containsUnexpandedParameterPack()) {
17006     ExprResult Val = SemaRef.CheckBooleanCondition(StartLoc, Condition);
17007     if (Val.isInvalid())
17008       return nullptr;
17009 
17010     ValExpr = SemaRef.MakeFullExpr(Val.get()).get();
17011 
17012     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
17013     CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_nocontext,
17014                                                     getLangOpts().OpenMP);
17015     if (CaptureRegion != OMPD_unknown &&
17016         !SemaRef.CurContext->isDependentContext()) {
17017       ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
17018       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
17019       ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
17020       HelperValStmt = buildPreInits(getASTContext(), Captures);
17021     }
17022   }
17023 
17024   return new (getASTContext()) OMPNocontextClause(
17025       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
17026 }
17027 
17028 OMPClause *SemaOpenMP::ActOnOpenMPFilterClause(Expr *ThreadID,
17029                                                SourceLocation StartLoc,
17030                                                SourceLocation LParenLoc,
17031                                                SourceLocation EndLoc) {
17032   Expr *ValExpr = ThreadID;
17033   Stmt *HelperValStmt = nullptr;
17034 
17035   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
17036   OpenMPDirectiveKind CaptureRegion =
17037       getOpenMPCaptureRegionForClause(DKind, OMPC_filter, getLangOpts().OpenMP);
17038   if (CaptureRegion != OMPD_unknown &&
17039       !SemaRef.CurContext->isDependentContext()) {
17040     ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
17041     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
17042     ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
17043     HelperValStmt = buildPreInits(getASTContext(), Captures);
17044   }
17045 
17046   return new (getASTContext()) OMPFilterClause(
17047       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
17048 }
17049 
17050 OMPClause *SemaOpenMP::ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
17051                                                 ArrayRef<Expr *> VarList,
17052                                                 const OMPVarListLocTy &Locs,
17053                                                 OpenMPVarListDataTy &Data) {
17054   SourceLocation StartLoc = Locs.StartLoc;
17055   SourceLocation LParenLoc = Locs.LParenLoc;
17056   SourceLocation EndLoc = Locs.EndLoc;
17057   OMPClause *Res = nullptr;
17058   int ExtraModifier = Data.ExtraModifier;
17059   SourceLocation ExtraModifierLoc = Data.ExtraModifierLoc;
17060   SourceLocation ColonLoc = Data.ColonLoc;
17061   switch (Kind) {
17062   case OMPC_private:
17063     Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
17064     break;
17065   case OMPC_firstprivate:
17066     Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
17067     break;
17068   case OMPC_lastprivate:
17069     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown &&
17070            "Unexpected lastprivate modifier.");
17071     Res = ActOnOpenMPLastprivateClause(
17072         VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier),
17073         ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
17074     break;
17075   case OMPC_shared:
17076     Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
17077     break;
17078   case OMPC_reduction:
17079     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown &&
17080            "Unexpected lastprivate modifier.");
17081     Res = ActOnOpenMPReductionClause(
17082         VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier),
17083         StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
17084         Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId);
17085     break;
17086   case OMPC_task_reduction:
17087     Res = ActOnOpenMPTaskReductionClause(
17088         VarList, StartLoc, LParenLoc, ColonLoc, EndLoc,
17089         Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId);
17090     break;
17091   case OMPC_in_reduction:
17092     Res = ActOnOpenMPInReductionClause(
17093         VarList, StartLoc, LParenLoc, ColonLoc, EndLoc,
17094         Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId);
17095     break;
17096   case OMPC_linear:
17097     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown &&
17098            "Unexpected linear modifier.");
17099     Res = ActOnOpenMPLinearClause(
17100         VarList, Data.DepModOrTailExpr, StartLoc, LParenLoc,
17101         static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc,
17102         ColonLoc, Data.StepModifierLoc, EndLoc);
17103     break;
17104   case OMPC_aligned:
17105     Res = ActOnOpenMPAlignedClause(VarList, Data.DepModOrTailExpr, StartLoc,
17106                                    LParenLoc, ColonLoc, EndLoc);
17107     break;
17108   case OMPC_copyin:
17109     Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
17110     break;
17111   case OMPC_copyprivate:
17112     Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
17113     break;
17114   case OMPC_flush:
17115     Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
17116     break;
17117   case OMPC_depend:
17118     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown &&
17119            "Unexpected depend modifier.");
17120     Res = ActOnOpenMPDependClause(
17121         {static_cast<OpenMPDependClauseKind>(ExtraModifier), ExtraModifierLoc,
17122          ColonLoc, Data.OmpAllMemoryLoc},
17123         Data.DepModOrTailExpr, VarList, StartLoc, LParenLoc, EndLoc);
17124     break;
17125   case OMPC_map:
17126     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown &&
17127            "Unexpected map modifier.");
17128     Res = ActOnOpenMPMapClause(
17129         Data.IteratorExpr, Data.MapTypeModifiers, Data.MapTypeModifiersLoc,
17130         Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId,
17131         static_cast<OpenMPMapClauseKind>(ExtraModifier), Data.IsMapTypeImplicit,
17132         ExtraModifierLoc, ColonLoc, VarList, Locs);
17133     break;
17134   case OMPC_to:
17135     Res =
17136         ActOnOpenMPToClause(Data.MotionModifiers, Data.MotionModifiersLoc,
17137                             Data.ReductionOrMapperIdScopeSpec,
17138                             Data.ReductionOrMapperId, ColonLoc, VarList, Locs);
17139     break;
17140   case OMPC_from:
17141     Res = ActOnOpenMPFromClause(Data.MotionModifiers, Data.MotionModifiersLoc,
17142                                 Data.ReductionOrMapperIdScopeSpec,
17143                                 Data.ReductionOrMapperId, ColonLoc, VarList,
17144                                 Locs);
17145     break;
17146   case OMPC_use_device_ptr:
17147     Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
17148     break;
17149   case OMPC_use_device_addr:
17150     Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
17151     break;
17152   case OMPC_is_device_ptr:
17153     Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
17154     break;
17155   case OMPC_has_device_addr:
17156     Res = ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
17157     break;
17158   case OMPC_allocate: {
17159     OpenMPAllocateClauseModifier Modifier1 = OMPC_ALLOCATE_unknown;
17160     OpenMPAllocateClauseModifier Modifier2 = OMPC_ALLOCATE_unknown;
17161     SourceLocation Modifier1Loc, Modifier2Loc;
17162     if (!Data.AllocClauseModifiers.empty()) {
17163       assert(Data.AllocClauseModifiers.size() <= 2 &&
17164              "More allocate modifiers than expected");
17165       Modifier1 = Data.AllocClauseModifiers[0];
17166       Modifier1Loc = Data.AllocClauseModifiersLoc[0];
17167       if (Data.AllocClauseModifiers.size() == 2) {
17168         Modifier2 = Data.AllocClauseModifiers[1];
17169         Modifier2Loc = Data.AllocClauseModifiersLoc[1];
17170       }
17171     }
17172     Res = ActOnOpenMPAllocateClause(
17173         Data.DepModOrTailExpr, Data.AllocateAlignment, Modifier1, Modifier1Loc,
17174         Modifier2, Modifier2Loc, VarList, StartLoc, LParenLoc, ColonLoc,
17175         EndLoc);
17176     break;
17177   }
17178   case OMPC_nontemporal:
17179     Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc);
17180     break;
17181   case OMPC_inclusive:
17182     Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
17183     break;
17184   case OMPC_exclusive:
17185     Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
17186     break;
17187   case OMPC_affinity:
17188     Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc,
17189                                     Data.DepModOrTailExpr, VarList);
17190     break;
17191   case OMPC_doacross:
17192     Res = ActOnOpenMPDoacrossClause(
17193         static_cast<OpenMPDoacrossClauseModifier>(ExtraModifier),
17194         ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
17195     break;
17196   case OMPC_num_teams:
17197     Res = ActOnOpenMPNumTeamsClause(VarList, StartLoc, LParenLoc, EndLoc);
17198     break;
17199   case OMPC_thread_limit:
17200     Res = ActOnOpenMPThreadLimitClause(VarList, StartLoc, LParenLoc, EndLoc);
17201     break;
17202   case OMPC_if:
17203   case OMPC_depobj:
17204   case OMPC_final:
17205   case OMPC_num_threads:
17206   case OMPC_safelen:
17207   case OMPC_simdlen:
17208   case OMPC_sizes:
17209   case OMPC_allocator:
17210   case OMPC_collapse:
17211   case OMPC_default:
17212   case OMPC_proc_bind:
17213   case OMPC_schedule:
17214   case OMPC_ordered:
17215   case OMPC_nowait:
17216   case OMPC_untied:
17217   case OMPC_mergeable:
17218   case OMPC_threadprivate:
17219   case OMPC_read:
17220   case OMPC_write:
17221   case OMPC_update:
17222   case OMPC_capture:
17223   case OMPC_compare:
17224   case OMPC_seq_cst:
17225   case OMPC_acq_rel:
17226   case OMPC_acquire:
17227   case OMPC_release:
17228   case OMPC_relaxed:
17229   case OMPC_device:
17230   case OMPC_threads:
17231   case OMPC_simd:
17232   case OMPC_priority:
17233   case OMPC_grainsize:
17234   case OMPC_nogroup:
17235   case OMPC_num_tasks:
17236   case OMPC_hint:
17237   case OMPC_dist_schedule:
17238   case OMPC_defaultmap:
17239   case OMPC_unknown:
17240   case OMPC_uniform:
17241   case OMPC_unified_address:
17242   case OMPC_unified_shared_memory:
17243   case OMPC_reverse_offload:
17244   case OMPC_dynamic_allocators:
17245   case OMPC_atomic_default_mem_order:
17246   case OMPC_device_type:
17247   case OMPC_match:
17248   case OMPC_order:
17249   case OMPC_at:
17250   case OMPC_severity:
17251   case OMPC_message:
17252   case OMPC_destroy:
17253   case OMPC_novariants:
17254   case OMPC_nocontext:
17255   case OMPC_detach:
17256   case OMPC_uses_allocators:
17257   case OMPC_when:
17258   case OMPC_bind:
17259   default:
17260     llvm_unreachable("Clause is not allowed.");
17261   }
17262   return Res;
17263 }
17264 
17265 ExprResult SemaOpenMP::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
17266                                              ExprObjectKind OK,
17267                                              SourceLocation Loc) {
17268   ExprResult Res = SemaRef.BuildDeclRefExpr(
17269       Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
17270   if (!Res.isUsable())
17271     return ExprError();
17272   if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
17273     Res = SemaRef.CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
17274     if (!Res.isUsable())
17275       return ExprError();
17276   }
17277   if (VK != VK_LValue && Res.get()->isGLValue()) {
17278     Res = SemaRef.DefaultLvalueConversion(Res.get());
17279     if (!Res.isUsable())
17280       return ExprError();
17281   }
17282   return Res;
17283 }
17284 
17285 OMPClause *SemaOpenMP::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
17286                                                 SourceLocation StartLoc,
17287                                                 SourceLocation LParenLoc,
17288                                                 SourceLocation EndLoc) {
17289   SmallVector<Expr *, 8> Vars;
17290   SmallVector<Expr *, 8> PrivateCopies;
17291   bool IsImplicitClause =
17292       StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
17293   for (Expr *RefExpr : VarList) {
17294     assert(RefExpr && "NULL expr in OpenMP private clause.");
17295     SourceLocation ELoc;
17296     SourceRange ERange;
17297     Expr *SimpleRefExpr = RefExpr;
17298     auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
17299     if (Res.second) {
17300       // It will be analyzed later.
17301       Vars.push_back(RefExpr);
17302       PrivateCopies.push_back(nullptr);
17303     }
17304     ValueDecl *D = Res.first;
17305     if (!D)
17306       continue;
17307 
17308     QualType Type = D->getType();
17309     auto *VD = dyn_cast<VarDecl>(D);
17310 
17311     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
17312     //  A variable that appears in a private clause must not have an incomplete
17313     //  type or a reference type.
17314     if (SemaRef.RequireCompleteType(ELoc, Type,
17315                                     diag::err_omp_private_incomplete_type))
17316       continue;
17317     Type = Type.getNonReferenceType();
17318 
17319     // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
17320     // A variable that is privatized must not have a const-qualified type
17321     // unless it is of class type with a mutable member. This restriction does
17322     // not apply to the firstprivate clause.
17323     //
17324     // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
17325     // A variable that appears in a private clause must not have a
17326     // const-qualified type unless it is of class type with a mutable member.
17327     if (rejectConstNotMutableType(SemaRef, D, Type, OMPC_private, ELoc))
17328       continue;
17329 
17330     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
17331     // in a Construct]
17332     //  Variables with the predetermined data-sharing attributes may not be
17333     //  listed in data-sharing attributes clauses, except for the cases
17334     //  listed below. For these exceptions only, listing a predetermined
17335     //  variable in a data-sharing attribute clause is allowed and overrides
17336     //  the variable's predetermined data-sharing attributes.
17337     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
17338     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
17339       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
17340                                           << getOpenMPClauseName(OMPC_private);
17341       reportOriginalDsa(SemaRef, DSAStack, D, DVar);
17342       continue;
17343     }
17344 
17345     OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
17346     // Variably modified types are not supported for tasks.
17347     if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
17348         isOpenMPTaskingDirective(CurrDir)) {
17349       Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
17350           << getOpenMPClauseName(OMPC_private) << Type
17351           << getOpenMPDirectiveName(CurrDir);
17352       bool IsDecl = !VD || VD->isThisDeclarationADefinition(getASTContext()) ==
17353                                VarDecl::DeclarationOnly;
17354       Diag(D->getLocation(),
17355            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17356           << D;
17357       continue;
17358     }
17359 
17360     // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
17361     // A list item cannot appear in both a map clause and a data-sharing
17362     // attribute clause on the same construct
17363     //
17364     // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
17365     // A list item cannot appear in both a map clause and a data-sharing
17366     // attribute clause on the same construct unless the construct is a
17367     // combined construct.
17368     if ((getLangOpts().OpenMP <= 45 &&
17369          isOpenMPTargetExecutionDirective(CurrDir)) ||
17370         CurrDir == OMPD_target) {
17371       OpenMPClauseKind ConflictKind;
17372       if (DSAStack->checkMappableExprComponentListsForDecl(
17373               VD, /*CurrentRegionOnly=*/true,
17374               [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
17375                   OpenMPClauseKind WhereFoundClauseKind) -> bool {
17376                 ConflictKind = WhereFoundClauseKind;
17377                 return true;
17378               })) {
17379         Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
17380             << getOpenMPClauseName(OMPC_private)
17381             << getOpenMPClauseName(ConflictKind)
17382             << getOpenMPDirectiveName(CurrDir);
17383         reportOriginalDsa(SemaRef, DSAStack, D, DVar);
17384         continue;
17385       }
17386     }
17387 
17388     // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
17389     //  A variable of class type (or array thereof) that appears in a private
17390     //  clause requires an accessible, unambiguous default constructor for the
17391     //  class type.
17392     // Generate helper private variable and initialize it with the default
17393     // value. The address of the original variable is replaced by the address of
17394     // the new private variable in CodeGen. This new variable is not added to
17395     // IdResolver, so the code in the OpenMP region uses original variable for
17396     // proper diagnostics.
17397     Type = Type.getUnqualifiedType();
17398     VarDecl *VDPrivate =
17399         buildVarDecl(SemaRef, ELoc, Type, D->getName(),
17400                      D->hasAttrs() ? &D->getAttrs() : nullptr,
17401                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
17402     SemaRef.ActOnUninitializedDecl(VDPrivate);
17403     if (VDPrivate->isInvalidDecl())
17404       continue;
17405     DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
17406         SemaRef, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
17407 
17408     DeclRefExpr *Ref = nullptr;
17409     if (!VD && !SemaRef.CurContext->isDependentContext()) {
17410       auto *FD = dyn_cast<FieldDecl>(D);
17411       VarDecl *VD = FD ? DSAStack->getImplicitFDCapExprDecl(FD) : nullptr;
17412       if (VD)
17413         Ref = buildDeclRefExpr(SemaRef, VD, VD->getType().getNonReferenceType(),
17414                                RefExpr->getExprLoc());
17415       else
17416         Ref = buildCapture(SemaRef, D, SimpleRefExpr, /*WithInit=*/false);
17417     }
17418     if (!IsImplicitClause)
17419       DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
17420     Vars.push_back((VD || SemaRef.CurContext->isDependentContext())
17421                        ? RefExpr->IgnoreParens()
17422                        : Ref);
17423     PrivateCopies.push_back(VDPrivateRefExpr);
17424   }
17425 
17426   if (Vars.empty())
17427     return nullptr;
17428 
17429   return OMPPrivateClause::Create(getASTContext(), StartLoc, LParenLoc, EndLoc,
17430                                   Vars, PrivateCopies);
17431 }
17432 
17433 OMPClause *SemaOpenMP::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
17434                                                      SourceLocation StartLoc,
17435                                                      SourceLocation LParenLoc,
17436                                                      SourceLocation EndLoc) {
17437   SmallVector<Expr *, 8> Vars;
17438   SmallVector<Expr *, 8> PrivateCopies;
17439   SmallVector<Expr *, 8> Inits;
17440   SmallVector<Decl *, 4> ExprCaptures;
17441   bool IsImplicitClause =
17442       StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
17443   SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc();
17444 
17445   for (Expr *RefExpr : VarList) {
17446     assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
17447     SourceLocation ELoc;
17448     SourceRange ERange;
17449     Expr *SimpleRefExpr = RefExpr;
17450     auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
17451     if (Res.second) {
17452       // It will be analyzed later.
17453       Vars.push_back(RefExpr);
17454       PrivateCopies.push_back(nullptr);
17455       Inits.push_back(nullptr);
17456     }
17457     ValueDecl *D = Res.first;
17458     if (!D)
17459       continue;
17460 
17461     ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
17462     QualType Type = D->getType();
17463     auto *VD = dyn_cast<VarDecl>(D);
17464 
17465     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
17466     //  A variable that appears in a private clause must not have an incomplete
17467     //  type or a reference type.
17468     if (SemaRef.RequireCompleteType(ELoc, Type,
17469                                     diag::err_omp_firstprivate_incomplete_type))
17470       continue;
17471     Type = Type.getNonReferenceType();
17472 
17473     // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
17474     //  A variable of class type (or array thereof) that appears in a private
17475     //  clause requires an accessible, unambiguous copy constructor for the
17476     //  class type.
17477     QualType ElemType =
17478         getASTContext().getBaseElementType(Type).getNonReferenceType();
17479 
17480     // If an implicit firstprivate variable found it was checked already.
17481     DSAStackTy::DSAVarData TopDVar;
17482     if (!IsImplicitClause) {
17483       DSAStackTy::DSAVarData DVar =
17484           DSAStack->getTopDSA(D, /*FromParent=*/false);
17485       TopDVar = DVar;
17486       OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
17487       bool IsConstant = ElemType.isConstant(getASTContext());
17488       // OpenMP [2.4.13, Data-sharing Attribute Clauses]
17489       //  A list item that specifies a given variable may not appear in more
17490       // than one clause on the same directive, except that a variable may be
17491       //  specified in both firstprivate and lastprivate clauses.
17492       // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
17493       // A list item may appear in a firstprivate or lastprivate clause but not
17494       // both.
17495       if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
17496           (isOpenMPDistributeDirective(CurrDir) ||
17497            DVar.CKind != OMPC_lastprivate) &&
17498           DVar.RefExpr) {
17499         Diag(ELoc, diag::err_omp_wrong_dsa)
17500             << getOpenMPClauseName(DVar.CKind)
17501             << getOpenMPClauseName(OMPC_firstprivate);
17502         reportOriginalDsa(SemaRef, DSAStack, D, DVar);
17503         continue;
17504       }
17505 
17506       // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
17507       // in a Construct]
17508       //  Variables with the predetermined data-sharing attributes may not be
17509       //  listed in data-sharing attributes clauses, except for the cases
17510       //  listed below. For these exceptions only, listing a predetermined
17511       //  variable in a data-sharing attribute clause is allowed and overrides
17512       //  the variable's predetermined data-sharing attributes.
17513       // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
17514       // in a Construct, C/C++, p.2]
17515       //  Variables with const-qualified type having no mutable member may be
17516       //  listed in a firstprivate clause, even if they are static data members.
17517       if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
17518           DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
17519         Diag(ELoc, diag::err_omp_wrong_dsa)
17520             << getOpenMPClauseName(DVar.CKind)
17521             << getOpenMPClauseName(OMPC_firstprivate);
17522         reportOriginalDsa(SemaRef, DSAStack, D, DVar);
17523         continue;
17524       }
17525 
17526       // OpenMP [2.9.3.4, Restrictions, p.2]
17527       //  A list item that is private within a parallel region must not appear
17528       //  in a firstprivate clause on a worksharing construct if any of the
17529       //  worksharing regions arising from the worksharing construct ever bind
17530       //  to any of the parallel regions arising from the parallel construct.
17531       // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
17532       // A list item that is private within a teams region must not appear in a
17533       // firstprivate clause on a distribute construct if any of the distribute
17534       // regions arising from the distribute construct ever bind to any of the
17535       // teams regions arising from the teams construct.
17536       // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
17537       // A list item that appears in a reduction clause of a teams construct
17538       // must not appear in a firstprivate clause on a distribute construct if
17539       // any of the distribute regions arising from the distribute construct
17540       // ever bind to any of the teams regions arising from the teams construct.
17541       if ((isOpenMPWorksharingDirective(CurrDir) ||
17542            isOpenMPDistributeDirective(CurrDir)) &&
17543           !isOpenMPParallelDirective(CurrDir) &&
17544           !isOpenMPTeamsDirective(CurrDir)) {
17545         DVar = DSAStack->getImplicitDSA(D, true);
17546         if (DVar.CKind != OMPC_shared &&
17547             (isOpenMPParallelDirective(DVar.DKind) ||
17548              isOpenMPTeamsDirective(DVar.DKind) ||
17549              DVar.DKind == OMPD_unknown)) {
17550           Diag(ELoc, diag::err_omp_required_access)
17551               << getOpenMPClauseName(OMPC_firstprivate)
17552               << getOpenMPClauseName(OMPC_shared);
17553           reportOriginalDsa(SemaRef, DSAStack, D, DVar);
17554           continue;
17555         }
17556       }
17557       // OpenMP [2.9.3.4, Restrictions, p.3]
17558       //  A list item that appears in a reduction clause of a parallel construct
17559       //  must not appear in a firstprivate clause on a worksharing or task
17560       //  construct if any of the worksharing or task regions arising from the
17561       //  worksharing or task construct ever bind to any of the parallel regions
17562       //  arising from the parallel construct.
17563       // OpenMP [2.9.3.4, Restrictions, p.4]
17564       //  A list item that appears in a reduction clause in worksharing
17565       //  construct must not appear in a firstprivate clause in a task construct
17566       //  encountered during execution of any of the worksharing regions arising
17567       //  from the worksharing construct.
17568       if (isOpenMPTaskingDirective(CurrDir)) {
17569         DVar = DSAStack->hasInnermostDSA(
17570             D,
17571             [](OpenMPClauseKind C, bool AppliedToPointee) {
17572               return C == OMPC_reduction && !AppliedToPointee;
17573             },
17574             [](OpenMPDirectiveKind K) {
17575               return isOpenMPParallelDirective(K) ||
17576                      isOpenMPWorksharingDirective(K) ||
17577                      isOpenMPTeamsDirective(K);
17578             },
17579             /*FromParent=*/true);
17580         if (DVar.CKind == OMPC_reduction &&
17581             (isOpenMPParallelDirective(DVar.DKind) ||
17582              isOpenMPWorksharingDirective(DVar.DKind) ||
17583              isOpenMPTeamsDirective(DVar.DKind))) {
17584           Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
17585               << getOpenMPDirectiveName(DVar.DKind);
17586           reportOriginalDsa(SemaRef, DSAStack, D, DVar);
17587           continue;
17588         }
17589       }
17590 
17591       // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
17592       // A list item cannot appear in both a map clause and a data-sharing
17593       // attribute clause on the same construct
17594       //
17595       // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
17596       // A list item cannot appear in both a map clause and a data-sharing
17597       // attribute clause on the same construct unless the construct is a
17598       // combined construct.
17599       if ((getLangOpts().OpenMP <= 45 &&
17600            isOpenMPTargetExecutionDirective(CurrDir)) ||
17601           CurrDir == OMPD_target) {
17602         OpenMPClauseKind ConflictKind;
17603         if (DSAStack->checkMappableExprComponentListsForDecl(
17604                 VD, /*CurrentRegionOnly=*/true,
17605                 [&ConflictKind](
17606                     OMPClauseMappableExprCommon::MappableExprComponentListRef,
17607                     OpenMPClauseKind WhereFoundClauseKind) {
17608                   ConflictKind = WhereFoundClauseKind;
17609                   return true;
17610                 })) {
17611           Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
17612               << getOpenMPClauseName(OMPC_firstprivate)
17613               << getOpenMPClauseName(ConflictKind)
17614               << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
17615           reportOriginalDsa(SemaRef, DSAStack, D, DVar);
17616           continue;
17617         }
17618       }
17619     }
17620 
17621     // Variably modified types are not supported for tasks.
17622     if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
17623         isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
17624       Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
17625           << getOpenMPClauseName(OMPC_firstprivate) << Type
17626           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
17627       bool IsDecl = !VD || VD->isThisDeclarationADefinition(getASTContext()) ==
17628                                VarDecl::DeclarationOnly;
17629       Diag(D->getLocation(),
17630            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17631           << D;
17632       continue;
17633     }
17634 
17635     Type = Type.getUnqualifiedType();
17636     VarDecl *VDPrivate =
17637         buildVarDecl(SemaRef, ELoc, Type, D->getName(),
17638                      D->hasAttrs() ? &D->getAttrs() : nullptr,
17639                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
17640     // Generate helper private variable and initialize it with the value of the
17641     // original variable. The address of the original variable is replaced by
17642     // the address of the new private variable in the CodeGen. This new variable
17643     // is not added to IdResolver, so the code in the OpenMP region uses
17644     // original variable for proper diagnostics and variable capturing.
17645     Expr *VDInitRefExpr = nullptr;
17646     // For arrays generate initializer for single element and replace it by the
17647     // original array element in CodeGen.
17648     if (Type->isArrayType()) {
17649       VarDecl *VDInit =
17650           buildVarDecl(SemaRef, RefExpr->getExprLoc(), ElemType, D->getName());
17651       VDInitRefExpr = buildDeclRefExpr(SemaRef, VDInit, ElemType, ELoc);
17652       Expr *Init = SemaRef.DefaultLvalueConversion(VDInitRefExpr).get();
17653       ElemType = ElemType.getUnqualifiedType();
17654       VarDecl *VDInitTemp = buildVarDecl(SemaRef, RefExpr->getExprLoc(),
17655                                          ElemType, ".firstprivate.temp");
17656       InitializedEntity Entity =
17657           InitializedEntity::InitializeVariable(VDInitTemp);
17658       InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
17659 
17660       InitializationSequence InitSeq(SemaRef, Entity, Kind, Init);
17661       ExprResult Result = InitSeq.Perform(SemaRef, Entity, Kind, Init);
17662       if (Result.isInvalid())
17663         VDPrivate->setInvalidDecl();
17664       else
17665         VDPrivate->setInit(Result.getAs<Expr>());
17666       // Remove temp variable declaration.
17667       getASTContext().Deallocate(VDInitTemp);
17668     } else {
17669       VarDecl *VDInit = buildVarDecl(SemaRef, RefExpr->getExprLoc(), Type,
17670                                      ".firstprivate.temp");
17671       VDInitRefExpr = buildDeclRefExpr(SemaRef, VDInit, RefExpr->getType(),
17672                                        RefExpr->getExprLoc());
17673       SemaRef.AddInitializerToDecl(
17674           VDPrivate, SemaRef.DefaultLvalueConversion(VDInitRefExpr).get(),
17675           /*DirectInit=*/false);
17676     }
17677     if (VDPrivate->isInvalidDecl()) {
17678       if (IsImplicitClause) {
17679         Diag(RefExpr->getExprLoc(),
17680              diag::note_omp_task_predetermined_firstprivate_here);
17681       }
17682       continue;
17683     }
17684     SemaRef.CurContext->addDecl(VDPrivate);
17685     DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
17686         SemaRef, VDPrivate, RefExpr->getType().getUnqualifiedType(),
17687         RefExpr->getExprLoc());
17688     DeclRefExpr *Ref = nullptr;
17689     if (!VD && !SemaRef.CurContext->isDependentContext()) {
17690       if (TopDVar.CKind == OMPC_lastprivate) {
17691         Ref = TopDVar.PrivateCopy;
17692       } else {
17693         auto *FD = dyn_cast<FieldDecl>(D);
17694         VarDecl *VD = FD ? DSAStack->getImplicitFDCapExprDecl(FD) : nullptr;
17695         if (VD)
17696           Ref =
17697               buildDeclRefExpr(SemaRef, VD, VD->getType().getNonReferenceType(),
17698                                RefExpr->getExprLoc());
17699         else
17700           Ref = buildCapture(SemaRef, D, SimpleRefExpr, /*WithInit=*/true);
17701         if (VD || !isOpenMPCapturedDecl(D))
17702           ExprCaptures.push_back(Ref->getDecl());
17703       }
17704     }
17705     if (!IsImplicitClause)
17706       DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
17707     Vars.push_back((VD || SemaRef.CurContext->isDependentContext())
17708                        ? RefExpr->IgnoreParens()
17709                        : Ref);
17710     PrivateCopies.push_back(VDPrivateRefExpr);
17711     Inits.push_back(VDInitRefExpr);
17712   }
17713 
17714   if (Vars.empty())
17715     return nullptr;
17716 
17717   return OMPFirstprivateClause::Create(
17718       getASTContext(), StartLoc, LParenLoc, EndLoc, Vars, PrivateCopies, Inits,
17719       buildPreInits(getASTContext(), ExprCaptures));
17720 }
17721 
17722 OMPClause *SemaOpenMP::ActOnOpenMPLastprivateClause(
17723     ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind,
17724     SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc,
17725     SourceLocation LParenLoc, SourceLocation EndLoc) {
17726   if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) {
17727     assert(ColonLoc.isValid() && "Colon location must be valid.");
17728     Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
17729         << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0,
17730                                    /*Last=*/OMPC_LASTPRIVATE_unknown)
17731         << getOpenMPClauseName(OMPC_lastprivate);
17732     return nullptr;
17733   }
17734 
17735   SmallVector<Expr *, 8> Vars;
17736   SmallVector<Expr *, 8> SrcExprs;
17737   SmallVector<Expr *, 8> DstExprs;
17738   SmallVector<Expr *, 8> AssignmentOps;
17739   SmallVector<Decl *, 4> ExprCaptures;
17740   SmallVector<Expr *, 4> ExprPostUpdates;
17741   for (Expr *RefExpr : VarList) {
17742     assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
17743     SourceLocation ELoc;
17744     SourceRange ERange;
17745     Expr *SimpleRefExpr = RefExpr;
17746     auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
17747     if (Res.second) {
17748       // It will be analyzed later.
17749       Vars.push_back(RefExpr);
17750       SrcExprs.push_back(nullptr);
17751       DstExprs.push_back(nullptr);
17752       AssignmentOps.push_back(nullptr);
17753     }
17754     ValueDecl *D = Res.first;
17755     if (!D)
17756       continue;
17757 
17758     QualType Type = D->getType();
17759     auto *VD = dyn_cast<VarDecl>(D);
17760 
17761     // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
17762     //  A variable that appears in a lastprivate clause must not have an
17763     //  incomplete type or a reference type.
17764     if (SemaRef.RequireCompleteType(ELoc, Type,
17765                                     diag::err_omp_lastprivate_incomplete_type))
17766       continue;
17767     Type = Type.getNonReferenceType();
17768 
17769     // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
17770     // A variable that is privatized must not have a const-qualified type
17771     // unless it is of class type with a mutable member. This restriction does
17772     // not apply to the firstprivate clause.
17773     //
17774     // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
17775     // A variable that appears in a lastprivate clause must not have a
17776     // const-qualified type unless it is of class type with a mutable member.
17777     if (rejectConstNotMutableType(SemaRef, D, Type, OMPC_lastprivate, ELoc))
17778       continue;
17779 
17780     // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions]
17781     // A list item that appears in a lastprivate clause with the conditional
17782     // modifier must be a scalar variable.
17783     if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) {
17784       Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
17785       bool IsDecl = !VD || VD->isThisDeclarationADefinition(getASTContext()) ==
17786                                VarDecl::DeclarationOnly;
17787       Diag(D->getLocation(),
17788            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17789           << D;
17790       continue;
17791     }
17792 
17793     OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
17794     // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
17795     // in a Construct]
17796     //  Variables with the predetermined data-sharing attributes may not be
17797     //  listed in data-sharing attributes clauses, except for the cases
17798     //  listed below.
17799     // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
17800     // A list item may appear in a firstprivate or lastprivate clause but not
17801     // both.
17802     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
17803     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
17804         (isOpenMPDistributeDirective(CurrDir) ||
17805          DVar.CKind != OMPC_firstprivate) &&
17806         (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
17807       Diag(ELoc, diag::err_omp_wrong_dsa)
17808           << getOpenMPClauseName(DVar.CKind)
17809           << getOpenMPClauseName(OMPC_lastprivate);
17810       reportOriginalDsa(SemaRef, DSAStack, D, DVar);
17811       continue;
17812     }
17813 
17814     // OpenMP [2.14.3.5, Restrictions, p.2]
17815     // A list item that is private within a parallel region, or that appears in
17816     // the reduction clause of a parallel construct, must not appear in a
17817     // lastprivate clause on a worksharing construct if any of the corresponding
17818     // worksharing regions ever binds to any of the corresponding parallel
17819     // regions.
17820     DSAStackTy::DSAVarData TopDVar = DVar;
17821     if (isOpenMPWorksharingDirective(CurrDir) &&
17822         !isOpenMPParallelDirective(CurrDir) &&
17823         !isOpenMPTeamsDirective(CurrDir)) {
17824       DVar = DSAStack->getImplicitDSA(D, true);
17825       if (DVar.CKind != OMPC_shared) {
17826         Diag(ELoc, diag::err_omp_required_access)
17827             << getOpenMPClauseName(OMPC_lastprivate)
17828             << getOpenMPClauseName(OMPC_shared);
17829         reportOriginalDsa(SemaRef, DSAStack, D, DVar);
17830         continue;
17831       }
17832     }
17833 
17834     // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
17835     //  A variable of class type (or array thereof) that appears in a
17836     //  lastprivate clause requires an accessible, unambiguous default
17837     //  constructor for the class type, unless the list item is also specified
17838     //  in a firstprivate clause.
17839     //  A variable of class type (or array thereof) that appears in a
17840     //  lastprivate clause requires an accessible, unambiguous copy assignment
17841     //  operator for the class type.
17842     Type = getASTContext().getBaseElementType(Type).getNonReferenceType();
17843     VarDecl *SrcVD = buildVarDecl(SemaRef, ERange.getBegin(),
17844                                   Type.getUnqualifiedType(), ".lastprivate.src",
17845                                   D->hasAttrs() ? &D->getAttrs() : nullptr);
17846     DeclRefExpr *PseudoSrcExpr =
17847         buildDeclRefExpr(SemaRef, SrcVD, Type.getUnqualifiedType(), ELoc);
17848     VarDecl *DstVD =
17849         buildVarDecl(SemaRef, ERange.getBegin(), Type, ".lastprivate.dst",
17850                      D->hasAttrs() ? &D->getAttrs() : nullptr);
17851     DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(SemaRef, DstVD, Type, ELoc);
17852     // For arrays generate assignment operation for single element and replace
17853     // it by the original array element in CodeGen.
17854     ExprResult AssignmentOp = SemaRef.BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
17855                                                  PseudoDstExpr, PseudoSrcExpr);
17856     if (AssignmentOp.isInvalid())
17857       continue;
17858     AssignmentOp = SemaRef.ActOnFinishFullExpr(AssignmentOp.get(), ELoc,
17859                                                /*DiscardedValue=*/false);
17860     if (AssignmentOp.isInvalid())
17861       continue;
17862 
17863     DeclRefExpr *Ref = nullptr;
17864     if (!VD && !SemaRef.CurContext->isDependentContext()) {
17865       if (TopDVar.CKind == OMPC_firstprivate) {
17866         Ref = TopDVar.PrivateCopy;
17867       } else {
17868         Ref = buildCapture(SemaRef, D, SimpleRefExpr, /*WithInit=*/false);
17869         if (!isOpenMPCapturedDecl(D))
17870           ExprCaptures.push_back(Ref->getDecl());
17871       }
17872       if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) ||
17873           (!isOpenMPCapturedDecl(D) &&
17874            Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
17875         ExprResult RefRes = SemaRef.DefaultLvalueConversion(Ref);
17876         if (!RefRes.isUsable())
17877           continue;
17878         ExprResult PostUpdateRes =
17879             SemaRef.BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
17880                                SimpleRefExpr, RefRes.get());
17881         if (!PostUpdateRes.isUsable())
17882           continue;
17883         ExprPostUpdates.push_back(
17884             SemaRef.IgnoredValueConversions(PostUpdateRes.get()).get());
17885       }
17886     }
17887     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
17888     Vars.push_back((VD || SemaRef.CurContext->isDependentContext())
17889                        ? RefExpr->IgnoreParens()
17890                        : Ref);
17891     SrcExprs.push_back(PseudoSrcExpr);
17892     DstExprs.push_back(PseudoDstExpr);
17893     AssignmentOps.push_back(AssignmentOp.get());
17894   }
17895 
17896   if (Vars.empty())
17897     return nullptr;
17898 
17899   return OMPLastprivateClause::Create(
17900       getASTContext(), StartLoc, LParenLoc, EndLoc, Vars, SrcExprs, DstExprs,
17901       AssignmentOps, LPKind, LPKindLoc, ColonLoc,
17902       buildPreInits(getASTContext(), ExprCaptures),
17903       buildPostUpdate(SemaRef, ExprPostUpdates));
17904 }
17905 
17906 OMPClause *SemaOpenMP::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
17907                                                SourceLocation StartLoc,
17908                                                SourceLocation LParenLoc,
17909                                                SourceLocation EndLoc) {
17910   SmallVector<Expr *, 8> Vars;
17911   for (Expr *RefExpr : VarList) {
17912     assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
17913     SourceLocation ELoc;
17914     SourceRange ERange;
17915     Expr *SimpleRefExpr = RefExpr;
17916     auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
17917     if (Res.second) {
17918       // It will be analyzed later.
17919       Vars.push_back(RefExpr);
17920     }
17921     ValueDecl *D = Res.first;
17922     if (!D)
17923       continue;
17924 
17925     auto *VD = dyn_cast<VarDecl>(D);
17926     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
17927     // in a Construct]
17928     //  Variables with the predetermined data-sharing attributes may not be
17929     //  listed in data-sharing attributes clauses, except for the cases
17930     //  listed below. For these exceptions only, listing a predetermined
17931     //  variable in a data-sharing attribute clause is allowed and overrides
17932     //  the variable's predetermined data-sharing attributes.
17933     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
17934     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
17935         DVar.RefExpr) {
17936       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
17937                                           << getOpenMPClauseName(OMPC_shared);
17938       reportOriginalDsa(SemaRef, DSAStack, D, DVar);
17939       continue;
17940     }
17941 
17942     DeclRefExpr *Ref = nullptr;
17943     if (!VD && isOpenMPCapturedDecl(D) &&
17944         !SemaRef.CurContext->isDependentContext())
17945       Ref = buildCapture(SemaRef, D, SimpleRefExpr, /*WithInit=*/true);
17946     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
17947     Vars.push_back((VD || !Ref || SemaRef.CurContext->isDependentContext())
17948                        ? RefExpr->IgnoreParens()
17949                        : Ref);
17950   }
17951 
17952   if (Vars.empty())
17953     return nullptr;
17954 
17955   return OMPSharedClause::Create(getASTContext(), StartLoc, LParenLoc, EndLoc,
17956                                  Vars);
17957 }
17958 
17959 namespace {
17960 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
17961   DSAStackTy *Stack;
17962 
17963 public:
17964   bool VisitDeclRefExpr(DeclRefExpr *E) {
17965     if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
17966       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
17967       if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
17968         return false;
17969       if (DVar.CKind != OMPC_unknown)
17970         return true;
17971       DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
17972           VD,
17973           [](OpenMPClauseKind C, bool AppliedToPointee, bool) {
17974             return isOpenMPPrivate(C) && !AppliedToPointee;
17975           },
17976           [](OpenMPDirectiveKind) { return true; },
17977           /*FromParent=*/true);
17978       return DVarPrivate.CKind != OMPC_unknown;
17979     }
17980     return false;
17981   }
17982   bool VisitStmt(Stmt *S) {
17983     for (Stmt *Child : S->children()) {
17984       if (Child && Visit(Child))
17985         return true;
17986     }
17987     return false;
17988   }
17989   explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
17990 };
17991 } // namespace
17992 
17993 namespace {
17994 // Transform MemberExpression for specified FieldDecl of current class to
17995 // DeclRefExpr to specified OMPCapturedExprDecl.
17996 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
17997   typedef TreeTransform<TransformExprToCaptures> BaseTransform;
17998   ValueDecl *Field = nullptr;
17999   DeclRefExpr *CapturedExpr = nullptr;
18000 
18001 public:
18002   TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
18003       : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
18004 
18005   ExprResult TransformMemberExpr(MemberExpr *E) {
18006     if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
18007         E->getMemberDecl() == Field) {
18008       CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
18009       return CapturedExpr;
18010     }
18011     return BaseTransform::TransformMemberExpr(E);
18012   }
18013   DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
18014 };
18015 } // namespace
18016 
18017 template <typename T, typename U>
18018 static T filterLookupForUDReductionAndMapper(
18019     SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
18020   for (U &Set : Lookups) {
18021     for (auto *D : Set) {
18022       if (T Res = Gen(cast<ValueDecl>(D)))
18023         return Res;
18024     }
18025   }
18026   return T();
18027 }
18028 
18029 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
18030   assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case");
18031 
18032   for (auto *RD : D->redecls()) {
18033     // Don't bother with extra checks if we already know this one isn't visible.
18034     if (RD == D)
18035       continue;
18036 
18037     auto ND = cast<NamedDecl>(RD);
18038     if (LookupResult::isVisible(SemaRef, ND))
18039       return ND;
18040   }
18041 
18042   return nullptr;
18043 }
18044 
18045 static void
18046 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id,
18047                         SourceLocation Loc, QualType Ty,
18048                         SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
18049   // Find all of the associated namespaces and classes based on the
18050   // arguments we have.
18051   Sema::AssociatedNamespaceSet AssociatedNamespaces;
18052   Sema::AssociatedClassSet AssociatedClasses;
18053   OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
18054   SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
18055                                              AssociatedClasses);
18056 
18057   // C++ [basic.lookup.argdep]p3:
18058   //   Let X be the lookup set produced by unqualified lookup (3.4.1)
18059   //   and let Y be the lookup set produced by argument dependent
18060   //   lookup (defined as follows). If X contains [...] then Y is
18061   //   empty. Otherwise Y is the set of declarations found in the
18062   //   namespaces associated with the argument types as described
18063   //   below. The set of declarations found by the lookup of the name
18064   //   is the union of X and Y.
18065   //
18066   // Here, we compute Y and add its members to the overloaded
18067   // candidate set.
18068   for (auto *NS : AssociatedNamespaces) {
18069     //   When considering an associated namespace, the lookup is the
18070     //   same as the lookup performed when the associated namespace is
18071     //   used as a qualifier (3.4.3.2) except that:
18072     //
18073     //     -- Any using-directives in the associated namespace are
18074     //        ignored.
18075     //
18076     //     -- Any namespace-scope friend functions declared in
18077     //        associated classes are visible within their respective
18078     //        namespaces even if they are not visible during an ordinary
18079     //        lookup (11.4).
18080     DeclContext::lookup_result R = NS->lookup(Id.getName());
18081     for (auto *D : R) {
18082       auto *Underlying = D;
18083       if (auto *USD = dyn_cast<UsingShadowDecl>(D))
18084         Underlying = USD->getTargetDecl();
18085 
18086       if (!isa<OMPDeclareReductionDecl>(Underlying) &&
18087           !isa<OMPDeclareMapperDecl>(Underlying))
18088         continue;
18089 
18090       if (!SemaRef.isVisible(D)) {
18091         D = findAcceptableDecl(SemaRef, D);
18092         if (!D)
18093           continue;
18094         if (auto *USD = dyn_cast<UsingShadowDecl>(D))
18095           Underlying = USD->getTargetDecl();
18096       }
18097       Lookups.emplace_back();
18098       Lookups.back().addDecl(Underlying);
18099     }
18100   }
18101 }
18102 
18103 static ExprResult
18104 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
18105                          Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
18106                          const DeclarationNameInfo &ReductionId, QualType Ty,
18107                          CXXCastPath &BasePath, Expr *UnresolvedReduction) {
18108   if (ReductionIdScopeSpec.isInvalid())
18109     return ExprError();
18110   SmallVector<UnresolvedSet<8>, 4> Lookups;
18111   if (S) {
18112     LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
18113     Lookup.suppressDiagnostics();
18114     while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec,
18115                                          /*ObjectType=*/QualType())) {
18116       NamedDecl *D = Lookup.getRepresentativeDecl();
18117       do {
18118         S = S->getParent();
18119       } while (S && !S->isDeclScope(D));
18120       if (S)
18121         S = S->getParent();
18122       Lookups.emplace_back();
18123       Lookups.back().append(Lookup.begin(), Lookup.end());
18124       Lookup.clear();
18125     }
18126   } else if (auto *ULE =
18127                  cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
18128     Lookups.push_back(UnresolvedSet<8>());
18129     Decl *PrevD = nullptr;
18130     for (NamedDecl *D : ULE->decls()) {
18131       if (D == PrevD)
18132         Lookups.push_back(UnresolvedSet<8>());
18133       else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
18134         Lookups.back().addDecl(DRD);
18135       PrevD = D;
18136     }
18137   }
18138   if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
18139       Ty->isInstantiationDependentType() ||
18140       Ty->containsUnexpandedParameterPack() ||
18141       filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
18142         return !D->isInvalidDecl() &&
18143                (D->getType()->isDependentType() ||
18144                 D->getType()->isInstantiationDependentType() ||
18145                 D->getType()->containsUnexpandedParameterPack());
18146       })) {
18147     UnresolvedSet<8> ResSet;
18148     for (const UnresolvedSet<8> &Set : Lookups) {
18149       if (Set.empty())
18150         continue;
18151       ResSet.append(Set.begin(), Set.end());
18152       // The last item marks the end of all declarations at the specified scope.
18153       ResSet.addDecl(Set[Set.size() - 1]);
18154     }
18155     return UnresolvedLookupExpr::Create(
18156         SemaRef.Context, /*NamingClass=*/nullptr,
18157         ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
18158         /*ADL=*/true, ResSet.begin(), ResSet.end(), /*KnownDependent=*/false,
18159         /*KnownInstantiationDependent=*/false);
18160   }
18161   // Lookup inside the classes.
18162   // C++ [over.match.oper]p3:
18163   //   For a unary operator @ with an operand of a type whose
18164   //   cv-unqualified version is T1, and for a binary operator @ with
18165   //   a left operand of a type whose cv-unqualified version is T1 and
18166   //   a right operand of a type whose cv-unqualified version is T2,
18167   //   three sets of candidate functions, designated member
18168   //   candidates, non-member candidates and built-in candidates, are
18169   //   constructed as follows:
18170   //     -- If T1 is a complete class type or a class currently being
18171   //        defined, the set of member candidates is the result of the
18172   //        qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
18173   //        the set of member candidates is empty.
18174   LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
18175   Lookup.suppressDiagnostics();
18176   if (const auto *TyRec = Ty->getAs<RecordType>()) {
18177     // Complete the type if it can be completed.
18178     // If the type is neither complete nor being defined, bail out now.
18179     if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
18180         TyRec->getDecl()->getDefinition()) {
18181       Lookup.clear();
18182       SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
18183       if (Lookup.empty()) {
18184         Lookups.emplace_back();
18185         Lookups.back().append(Lookup.begin(), Lookup.end());
18186       }
18187     }
18188   }
18189   // Perform ADL.
18190   if (SemaRef.getLangOpts().CPlusPlus)
18191     argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
18192   if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
18193           Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
18194             if (!D->isInvalidDecl() &&
18195                 SemaRef.Context.hasSameType(D->getType(), Ty))
18196               return D;
18197             return nullptr;
18198           }))
18199     return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
18200                                     VK_LValue, Loc);
18201   if (SemaRef.getLangOpts().CPlusPlus) {
18202     if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
18203             Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
18204               if (!D->isInvalidDecl() &&
18205                   SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
18206                   !Ty.isMoreQualifiedThan(D->getType(),
18207                                           SemaRef.getASTContext()))
18208                 return D;
18209               return nullptr;
18210             })) {
18211       CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
18212                          /*DetectVirtual=*/false);
18213       if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
18214         if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
18215                 VD->getType().getUnqualifiedType()))) {
18216           if (SemaRef.CheckBaseClassAccess(
18217                   Loc, VD->getType(), Ty, Paths.front(),
18218                   /*DiagID=*/0) != Sema::AR_inaccessible) {
18219             SemaRef.BuildBasePathArray(Paths, BasePath);
18220             return SemaRef.BuildDeclRefExpr(
18221                 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
18222           }
18223         }
18224       }
18225     }
18226   }
18227   if (ReductionIdScopeSpec.isSet()) {
18228     SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
18229         << Ty << Range;
18230     return ExprError();
18231   }
18232   return ExprEmpty();
18233 }
18234 
18235 namespace {
18236 /// Data for the reduction-based clauses.
18237 struct ReductionData {
18238   /// List of original reduction items.
18239   SmallVector<Expr *, 8> Vars;
18240   /// List of private copies of the reduction items.
18241   SmallVector<Expr *, 8> Privates;
18242   /// LHS expressions for the reduction_op expressions.
18243   SmallVector<Expr *, 8> LHSs;
18244   /// RHS expressions for the reduction_op expressions.
18245   SmallVector<Expr *, 8> RHSs;
18246   /// Reduction operation expression.
18247   SmallVector<Expr *, 8> ReductionOps;
18248   /// inscan copy operation expressions.
18249   SmallVector<Expr *, 8> InscanCopyOps;
18250   /// inscan copy temp array expressions for prefix sums.
18251   SmallVector<Expr *, 8> InscanCopyArrayTemps;
18252   /// inscan copy temp array element expressions for prefix sums.
18253   SmallVector<Expr *, 8> InscanCopyArrayElems;
18254   /// Taskgroup descriptors for the corresponding reduction items in
18255   /// in_reduction clauses.
18256   SmallVector<Expr *, 8> TaskgroupDescriptors;
18257   /// List of captures for clause.
18258   SmallVector<Decl *, 4> ExprCaptures;
18259   /// List of postupdate expressions.
18260   SmallVector<Expr *, 4> ExprPostUpdates;
18261   /// Reduction modifier.
18262   unsigned RedModifier = 0;
18263   ReductionData() = delete;
18264   /// Reserves required memory for the reduction data.
18265   ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) {
18266     Vars.reserve(Size);
18267     Privates.reserve(Size);
18268     LHSs.reserve(Size);
18269     RHSs.reserve(Size);
18270     ReductionOps.reserve(Size);
18271     if (RedModifier == OMPC_REDUCTION_inscan) {
18272       InscanCopyOps.reserve(Size);
18273       InscanCopyArrayTemps.reserve(Size);
18274       InscanCopyArrayElems.reserve(Size);
18275     }
18276     TaskgroupDescriptors.reserve(Size);
18277     ExprCaptures.reserve(Size);
18278     ExprPostUpdates.reserve(Size);
18279   }
18280   /// Stores reduction item and reduction operation only (required for dependent
18281   /// reduction item).
18282   void push(Expr *Item, Expr *ReductionOp) {
18283     Vars.emplace_back(Item);
18284     Privates.emplace_back(nullptr);
18285     LHSs.emplace_back(nullptr);
18286     RHSs.emplace_back(nullptr);
18287     ReductionOps.emplace_back(ReductionOp);
18288     TaskgroupDescriptors.emplace_back(nullptr);
18289     if (RedModifier == OMPC_REDUCTION_inscan) {
18290       InscanCopyOps.push_back(nullptr);
18291       InscanCopyArrayTemps.push_back(nullptr);
18292       InscanCopyArrayElems.push_back(nullptr);
18293     }
18294   }
18295   /// Stores reduction data.
18296   void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
18297             Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp,
18298             Expr *CopyArrayElem) {
18299     Vars.emplace_back(Item);
18300     Privates.emplace_back(Private);
18301     LHSs.emplace_back(LHS);
18302     RHSs.emplace_back(RHS);
18303     ReductionOps.emplace_back(ReductionOp);
18304     TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
18305     if (RedModifier == OMPC_REDUCTION_inscan) {
18306       InscanCopyOps.push_back(CopyOp);
18307       InscanCopyArrayTemps.push_back(CopyArrayTemp);
18308       InscanCopyArrayElems.push_back(CopyArrayElem);
18309     } else {
18310       assert(CopyOp == nullptr && CopyArrayTemp == nullptr &&
18311              CopyArrayElem == nullptr &&
18312              "Copy operation must be used for inscan reductions only.");
18313     }
18314   }
18315 };
18316 } // namespace
18317 
18318 static bool checkOMPArraySectionConstantForReduction(
18319     ASTContext &Context, const ArraySectionExpr *OASE, bool &SingleElement,
18320     SmallVectorImpl<llvm::APSInt> &ArraySizes) {
18321   const Expr *Length = OASE->getLength();
18322   if (Length == nullptr) {
18323     // For array sections of the form [1:] or [:], we would need to analyze
18324     // the lower bound...
18325     if (OASE->getColonLocFirst().isValid())
18326       return false;
18327 
18328     // This is an array subscript which has implicit length 1!
18329     SingleElement = true;
18330     ArraySizes.push_back(llvm::APSInt::get(1));
18331   } else {
18332     Expr::EvalResult Result;
18333     if (!Length->EvaluateAsInt(Result, Context))
18334       return false;
18335 
18336     llvm::APSInt ConstantLengthValue = Result.Val.getInt();
18337     SingleElement = (ConstantLengthValue.getSExtValue() == 1);
18338     ArraySizes.push_back(ConstantLengthValue);
18339   }
18340 
18341   // Get the base of this array section and walk up from there.
18342   const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
18343 
18344   // We require length = 1 for all array sections except the right-most to
18345   // guarantee that the memory region is contiguous and has no holes in it.
18346   while (const auto *TempOASE = dyn_cast<ArraySectionExpr>(Base)) {
18347     Length = TempOASE->getLength();
18348     if (Length == nullptr) {
18349       // For array sections of the form [1:] or [:], we would need to analyze
18350       // the lower bound...
18351       if (OASE->getColonLocFirst().isValid())
18352         return false;
18353 
18354       // This is an array subscript which has implicit length 1!
18355       llvm::APSInt ConstantOne = llvm::APSInt::get(1);
18356       ArraySizes.push_back(ConstantOne);
18357     } else {
18358       Expr::EvalResult Result;
18359       if (!Length->EvaluateAsInt(Result, Context))
18360         return false;
18361 
18362       llvm::APSInt ConstantLengthValue = Result.Val.getInt();
18363       if (ConstantLengthValue.getSExtValue() != 1)
18364         return false;
18365 
18366       ArraySizes.push_back(ConstantLengthValue);
18367     }
18368     Base = TempOASE->getBase()->IgnoreParenImpCasts();
18369   }
18370 
18371   // If we have a single element, we don't need to add the implicit lengths.
18372   if (!SingleElement) {
18373     while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
18374       // Has implicit length 1!
18375       llvm::APSInt ConstantOne = llvm::APSInt::get(1);
18376       ArraySizes.push_back(ConstantOne);
18377       Base = TempASE->getBase()->IgnoreParenImpCasts();
18378     }
18379   }
18380 
18381   // This array section can be privatized as a single value or as a constant
18382   // sized array.
18383   return true;
18384 }
18385 
18386 static BinaryOperatorKind
18387 getRelatedCompoundReductionOp(BinaryOperatorKind BOK) {
18388   if (BOK == BO_Add)
18389     return BO_AddAssign;
18390   if (BOK == BO_Mul)
18391     return BO_MulAssign;
18392   if (BOK == BO_And)
18393     return BO_AndAssign;
18394   if (BOK == BO_Or)
18395     return BO_OrAssign;
18396   if (BOK == BO_Xor)
18397     return BO_XorAssign;
18398   return BOK;
18399 }
18400 
18401 static bool actOnOMPReductionKindClause(
18402     Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
18403     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
18404     SourceLocation ColonLoc, SourceLocation EndLoc,
18405     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
18406     ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
18407   DeclarationName DN = ReductionId.getName();
18408   OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator();
18409   BinaryOperatorKind BOK = BO_Comma;
18410 
18411   ASTContext &Context = S.Context;
18412   // OpenMP [2.14.3.6, reduction clause]
18413   // C
18414   // reduction-identifier is either an identifier or one of the following
18415   // operators: +, -, *,  &, |, ^, && and ||
18416   // C++
18417   // reduction-identifier is either an id-expression or one of the following
18418   // operators: +, -, *, &, |, ^, && and ||
18419   switch (OOK) {
18420   case OO_Plus:
18421     BOK = BO_Add;
18422     break;
18423   case OO_Minus:
18424     // Minus(-) operator is not supported in TR11 (OpenMP 6.0). Setting BOK to
18425     // BO_Comma will automatically diagnose it for OpenMP > 52 as not allowed
18426     // reduction identifier.
18427     if (S.LangOpts.OpenMP > 52)
18428       BOK = BO_Comma;
18429     else
18430       BOK = BO_Add;
18431     break;
18432   case OO_Star:
18433     BOK = BO_Mul;
18434     break;
18435   case OO_Amp:
18436     BOK = BO_And;
18437     break;
18438   case OO_Pipe:
18439     BOK = BO_Or;
18440     break;
18441   case OO_Caret:
18442     BOK = BO_Xor;
18443     break;
18444   case OO_AmpAmp:
18445     BOK = BO_LAnd;
18446     break;
18447   case OO_PipePipe:
18448     BOK = BO_LOr;
18449     break;
18450   case OO_New:
18451   case OO_Delete:
18452   case OO_Array_New:
18453   case OO_Array_Delete:
18454   case OO_Slash:
18455   case OO_Percent:
18456   case OO_Tilde:
18457   case OO_Exclaim:
18458   case OO_Equal:
18459   case OO_Less:
18460   case OO_Greater:
18461   case OO_LessEqual:
18462   case OO_GreaterEqual:
18463   case OO_PlusEqual:
18464   case OO_MinusEqual:
18465   case OO_StarEqual:
18466   case OO_SlashEqual:
18467   case OO_PercentEqual:
18468   case OO_CaretEqual:
18469   case OO_AmpEqual:
18470   case OO_PipeEqual:
18471   case OO_LessLess:
18472   case OO_GreaterGreater:
18473   case OO_LessLessEqual:
18474   case OO_GreaterGreaterEqual:
18475   case OO_EqualEqual:
18476   case OO_ExclaimEqual:
18477   case OO_Spaceship:
18478   case OO_PlusPlus:
18479   case OO_MinusMinus:
18480   case OO_Comma:
18481   case OO_ArrowStar:
18482   case OO_Arrow:
18483   case OO_Call:
18484   case OO_Subscript:
18485   case OO_Conditional:
18486   case OO_Coawait:
18487   case NUM_OVERLOADED_OPERATORS:
18488     llvm_unreachable("Unexpected reduction identifier");
18489   case OO_None:
18490     if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
18491       if (II->isStr("max"))
18492         BOK = BO_GT;
18493       else if (II->isStr("min"))
18494         BOK = BO_LT;
18495     }
18496     break;
18497   }
18498 
18499   // OpenMP 5.2, 5.5.5 (see page 627, line 18) reduction Clause, Restrictions
18500   // A reduction clause with the minus (-) operator was deprecated
18501   if (OOK == OO_Minus && S.LangOpts.OpenMP == 52)
18502     S.Diag(ReductionId.getLoc(), diag::warn_omp_minus_in_reduction_deprecated);
18503 
18504   SourceRange ReductionIdRange;
18505   if (ReductionIdScopeSpec.isValid())
18506     ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
18507   else
18508     ReductionIdRange.setBegin(ReductionId.getBeginLoc());
18509   ReductionIdRange.setEnd(ReductionId.getEndLoc());
18510 
18511   auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
18512   bool FirstIter = true;
18513   for (Expr *RefExpr : VarList) {
18514     assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
18515     // OpenMP [2.1, C/C++]
18516     //  A list item is a variable or array section, subject to the restrictions
18517     //  specified in Section 2.4 on page 42 and in each of the sections
18518     // describing clauses and directives for which a list appears.
18519     // OpenMP  [2.14.3.3, Restrictions, p.1]
18520     //  A variable that is part of another variable (as an array or
18521     //  structure element) cannot appear in a private clause.
18522     if (!FirstIter && IR != ER)
18523       ++IR;
18524     FirstIter = false;
18525     SourceLocation ELoc;
18526     SourceRange ERange;
18527     Expr *SimpleRefExpr = RefExpr;
18528     auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
18529                               /*AllowArraySection=*/true);
18530     if (Res.second) {
18531       // Try to find 'declare reduction' corresponding construct before using
18532       // builtin/overloaded operators.
18533       QualType Type = Context.DependentTy;
18534       CXXCastPath BasePath;
18535       ExprResult DeclareReductionRef = buildDeclareReductionRef(
18536           S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
18537           ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
18538       Expr *ReductionOp = nullptr;
18539       if (S.CurContext->isDependentContext() &&
18540           (DeclareReductionRef.isUnset() ||
18541            isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
18542         ReductionOp = DeclareReductionRef.get();
18543       // It will be analyzed later.
18544       RD.push(RefExpr, ReductionOp);
18545     }
18546     ValueDecl *D = Res.first;
18547     if (!D)
18548       continue;
18549 
18550     Expr *TaskgroupDescriptor = nullptr;
18551     QualType Type;
18552     auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
18553     auto *OASE = dyn_cast<ArraySectionExpr>(RefExpr->IgnoreParens());
18554     if (ASE) {
18555       Type = ASE->getType().getNonReferenceType();
18556     } else if (OASE) {
18557       QualType BaseType =
18558           ArraySectionExpr::getBaseOriginalType(OASE->getBase());
18559       if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
18560         Type = ATy->getElementType();
18561       else
18562         Type = BaseType->getPointeeType();
18563       Type = Type.getNonReferenceType();
18564     } else {
18565       Type = Context.getBaseElementType(D->getType().getNonReferenceType());
18566     }
18567     auto *VD = dyn_cast<VarDecl>(D);
18568 
18569     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
18570     //  A variable that appears in a private clause must not have an incomplete
18571     //  type or a reference type.
18572     if (S.RequireCompleteType(ELoc, D->getType(),
18573                               diag::err_omp_reduction_incomplete_type))
18574       continue;
18575     // OpenMP [2.14.3.6, reduction clause, Restrictions]
18576     // A list item that appears in a reduction clause must not be
18577     // const-qualified.
18578     if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
18579                                   /*AcceptIfMutable=*/false, ASE || OASE))
18580       continue;
18581 
18582     OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
18583     // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
18584     //  If a list-item is a reference type then it must bind to the same object
18585     //  for all threads of the team.
18586     if (!ASE && !OASE) {
18587       if (VD) {
18588         VarDecl *VDDef = VD->getDefinition();
18589         if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
18590           DSARefChecker Check(Stack);
18591           if (Check.Visit(VDDef->getInit())) {
18592             S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
18593                 << getOpenMPClauseName(ClauseKind) << ERange;
18594             S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
18595             continue;
18596           }
18597         }
18598       }
18599 
18600       // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
18601       // in a Construct]
18602       //  Variables with the predetermined data-sharing attributes may not be
18603       //  listed in data-sharing attributes clauses, except for the cases
18604       //  listed below. For these exceptions only, listing a predetermined
18605       //  variable in a data-sharing attribute clause is allowed and overrides
18606       //  the variable's predetermined data-sharing attributes.
18607       // OpenMP [2.14.3.6, Restrictions, p.3]
18608       //  Any number of reduction clauses can be specified on the directive,
18609       //  but a list item can appear only once in the reduction clauses for that
18610       //  directive.
18611       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
18612       if (DVar.CKind == OMPC_reduction) {
18613         S.Diag(ELoc, diag::err_omp_once_referenced)
18614             << getOpenMPClauseName(ClauseKind);
18615         if (DVar.RefExpr)
18616           S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
18617         continue;
18618       }
18619       if (DVar.CKind != OMPC_unknown) {
18620         S.Diag(ELoc, diag::err_omp_wrong_dsa)
18621             << getOpenMPClauseName(DVar.CKind)
18622             << getOpenMPClauseName(OMPC_reduction);
18623         reportOriginalDsa(S, Stack, D, DVar);
18624         continue;
18625       }
18626 
18627       // OpenMP [2.14.3.6, Restrictions, p.1]
18628       //  A list item that appears in a reduction clause of a worksharing
18629       //  construct must be shared in the parallel regions to which any of the
18630       //  worksharing regions arising from the worksharing construct bind.
18631       if (isOpenMPWorksharingDirective(CurrDir) &&
18632           !isOpenMPParallelDirective(CurrDir) &&
18633           !isOpenMPTeamsDirective(CurrDir)) {
18634         DVar = Stack->getImplicitDSA(D, true);
18635         if (DVar.CKind != OMPC_shared) {
18636           S.Diag(ELoc, diag::err_omp_required_access)
18637               << getOpenMPClauseName(OMPC_reduction)
18638               << getOpenMPClauseName(OMPC_shared);
18639           reportOriginalDsa(S, Stack, D, DVar);
18640           continue;
18641         }
18642       }
18643     } else {
18644       // Threadprivates cannot be shared between threads, so dignose if the base
18645       // is a threadprivate variable.
18646       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
18647       if (DVar.CKind == OMPC_threadprivate) {
18648         S.Diag(ELoc, diag::err_omp_wrong_dsa)
18649             << getOpenMPClauseName(DVar.CKind)
18650             << getOpenMPClauseName(OMPC_reduction);
18651         reportOriginalDsa(S, Stack, D, DVar);
18652         continue;
18653       }
18654     }
18655 
18656     // Try to find 'declare reduction' corresponding construct before using
18657     // builtin/overloaded operators.
18658     CXXCastPath BasePath;
18659     ExprResult DeclareReductionRef = buildDeclareReductionRef(
18660         S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
18661         ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
18662     if (DeclareReductionRef.isInvalid())
18663       continue;
18664     if (S.CurContext->isDependentContext() &&
18665         (DeclareReductionRef.isUnset() ||
18666          isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
18667       RD.push(RefExpr, DeclareReductionRef.get());
18668       continue;
18669     }
18670     if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
18671       // Not allowed reduction identifier is found.
18672       if (S.LangOpts.OpenMP > 52)
18673         S.Diag(ReductionId.getBeginLoc(),
18674                diag::err_omp_unknown_reduction_identifier_since_omp_6_0)
18675             << Type << ReductionIdRange;
18676       else
18677         S.Diag(ReductionId.getBeginLoc(),
18678                diag::err_omp_unknown_reduction_identifier_prior_omp_6_0)
18679             << Type << ReductionIdRange;
18680       continue;
18681     }
18682 
18683     // OpenMP [2.14.3.6, reduction clause, Restrictions]
18684     // The type of a list item that appears in a reduction clause must be valid
18685     // for the reduction-identifier. For a max or min reduction in C, the type
18686     // of the list item must be an allowed arithmetic data type: char, int,
18687     // float, double, or _Bool, possibly modified with long, short, signed, or
18688     // unsigned. For a max or min reduction in C++, the type of the list item
18689     // must be an allowed arithmetic data type: char, wchar_t, int, float,
18690     // double, or bool, possibly modified with long, short, signed, or unsigned.
18691     if (DeclareReductionRef.isUnset()) {
18692       if ((BOK == BO_GT || BOK == BO_LT) &&
18693           !(Type->isScalarType() ||
18694             (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
18695         S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
18696             << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
18697         if (!ASE && !OASE) {
18698           bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18699                                    VarDecl::DeclarationOnly;
18700           S.Diag(D->getLocation(),
18701                  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18702               << D;
18703         }
18704         continue;
18705       }
18706       if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
18707           !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
18708         S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
18709             << getOpenMPClauseName(ClauseKind);
18710         if (!ASE && !OASE) {
18711           bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18712                                    VarDecl::DeclarationOnly;
18713           S.Diag(D->getLocation(),
18714                  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18715               << D;
18716         }
18717         continue;
18718       }
18719     }
18720 
18721     Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
18722     VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
18723                                   D->hasAttrs() ? &D->getAttrs() : nullptr);
18724     VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
18725                                   D->hasAttrs() ? &D->getAttrs() : nullptr);
18726     QualType PrivateTy = Type;
18727 
18728     // Try if we can determine constant lengths for all array sections and avoid
18729     // the VLA.
18730     bool ConstantLengthOASE = false;
18731     if (OASE) {
18732       bool SingleElement;
18733       llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
18734       ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
18735           Context, OASE, SingleElement, ArraySizes);
18736 
18737       // If we don't have a single element, we must emit a constant array type.
18738       if (ConstantLengthOASE && !SingleElement) {
18739         for (llvm::APSInt &Size : ArraySizes)
18740           PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr,
18741                                                    ArraySizeModifier::Normal,
18742                                                    /*IndexTypeQuals=*/0);
18743       }
18744     }
18745 
18746     if ((OASE && !ConstantLengthOASE) ||
18747         (!OASE && !ASE &&
18748          D->getType().getNonReferenceType()->isVariablyModifiedType())) {
18749       if (!Context.getTargetInfo().isVLASupported()) {
18750         if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) {
18751           S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
18752           S.Diag(ELoc, diag::note_vla_unsupported);
18753           continue;
18754         } else {
18755           S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
18756           S.targetDiag(ELoc, diag::note_vla_unsupported);
18757         }
18758       }
18759       // For arrays/array sections only:
18760       // Create pseudo array type for private copy. The size for this array will
18761       // be generated during codegen.
18762       // For array subscripts or single variables Private Ty is the same as Type
18763       // (type of the variable or single array element).
18764       PrivateTy = Context.getVariableArrayType(
18765           Type,
18766           new (Context)
18767               OpaqueValueExpr(ELoc, Context.getSizeType(), VK_PRValue),
18768           ArraySizeModifier::Normal, /*IndexTypeQuals=*/0, SourceRange());
18769     } else if (!ASE && !OASE &&
18770                Context.getAsArrayType(D->getType().getNonReferenceType())) {
18771       PrivateTy = D->getType().getNonReferenceType();
18772     }
18773     // Private copy.
18774     VarDecl *PrivateVD =
18775         buildVarDecl(S, ELoc, PrivateTy, D->getName(),
18776                      D->hasAttrs() ? &D->getAttrs() : nullptr,
18777                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
18778     // Add initializer for private variable.
18779     Expr *Init = nullptr;
18780     DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
18781     DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
18782     if (DeclareReductionRef.isUsable()) {
18783       auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
18784       auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
18785       if (DRD->getInitializer()) {
18786         Init = DRDRef;
18787         RHSVD->setInit(DRDRef);
18788         RHSVD->setInitStyle(VarDecl::CallInit);
18789       }
18790     } else {
18791       switch (BOK) {
18792       case BO_Add:
18793       case BO_Xor:
18794       case BO_Or:
18795       case BO_LOr:
18796         // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
18797         if (Type->isScalarType() || Type->isAnyComplexType())
18798           Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
18799         break;
18800       case BO_Mul:
18801       case BO_LAnd:
18802         if (Type->isScalarType() || Type->isAnyComplexType()) {
18803           // '*' and '&&' reduction ops - initializer is '1'.
18804           Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
18805         }
18806         break;
18807       case BO_And: {
18808         // '&' reduction op - initializer is '~0'.
18809         QualType OrigType = Type;
18810         if (auto *ComplexTy = OrigType->getAs<ComplexType>())
18811           Type = ComplexTy->getElementType();
18812         if (Type->isRealFloatingType()) {
18813           llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue(
18814               Context.getFloatTypeSemantics(Type));
18815           Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
18816                                          Type, ELoc);
18817         } else if (Type->isScalarType()) {
18818           uint64_t Size = Context.getTypeSize(Type);
18819           QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
18820           llvm::APInt InitValue = llvm::APInt::getAllOnes(Size);
18821           Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
18822         }
18823         if (Init && OrigType->isAnyComplexType()) {
18824           // Init = 0xFFFF + 0xFFFFi;
18825           auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
18826           Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
18827         }
18828         Type = OrigType;
18829         break;
18830       }
18831       case BO_LT:
18832       case BO_GT: {
18833         // 'min' reduction op - initializer is 'Largest representable number in
18834         // the reduction list item type'.
18835         // 'max' reduction op - initializer is 'Least representable number in
18836         // the reduction list item type'.
18837         if (Type->isIntegerType() || Type->isPointerType()) {
18838           bool IsSigned = Type->hasSignedIntegerRepresentation();
18839           uint64_t Size = Context.getTypeSize(Type);
18840           QualType IntTy =
18841               Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
18842           llvm::APInt InitValue =
18843               (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
18844                                         : llvm::APInt::getMinValue(Size)
18845               : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
18846                              : llvm::APInt::getMaxValue(Size);
18847           Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
18848           if (Type->isPointerType()) {
18849             // Cast to pointer type.
18850             ExprResult CastExpr = S.BuildCStyleCastExpr(
18851                 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
18852             if (CastExpr.isInvalid())
18853               continue;
18854             Init = CastExpr.get();
18855           }
18856         } else if (Type->isRealFloatingType()) {
18857           llvm::APFloat InitValue = llvm::APFloat::getLargest(
18858               Context.getFloatTypeSemantics(Type), BOK != BO_LT);
18859           Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
18860                                          Type, ELoc);
18861         }
18862         break;
18863       }
18864       case BO_PtrMemD:
18865       case BO_PtrMemI:
18866       case BO_MulAssign:
18867       case BO_Div:
18868       case BO_Rem:
18869       case BO_Sub:
18870       case BO_Shl:
18871       case BO_Shr:
18872       case BO_LE:
18873       case BO_GE:
18874       case BO_EQ:
18875       case BO_NE:
18876       case BO_Cmp:
18877       case BO_AndAssign:
18878       case BO_XorAssign:
18879       case BO_OrAssign:
18880       case BO_Assign:
18881       case BO_AddAssign:
18882       case BO_SubAssign:
18883       case BO_DivAssign:
18884       case BO_RemAssign:
18885       case BO_ShlAssign:
18886       case BO_ShrAssign:
18887       case BO_Comma:
18888         llvm_unreachable("Unexpected reduction operation");
18889       }
18890     }
18891     if (Init && DeclareReductionRef.isUnset()) {
18892       S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
18893       // Store initializer for single element in private copy. Will be used
18894       // during codegen.
18895       PrivateVD->setInit(RHSVD->getInit());
18896       PrivateVD->setInitStyle(RHSVD->getInitStyle());
18897     } else if (!Init) {
18898       S.ActOnUninitializedDecl(RHSVD);
18899       // Store initializer for single element in private copy. Will be used
18900       // during codegen.
18901       PrivateVD->setInit(RHSVD->getInit());
18902       PrivateVD->setInitStyle(RHSVD->getInitStyle());
18903     }
18904     if (RHSVD->isInvalidDecl())
18905       continue;
18906     if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) {
18907       S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
18908           << Type << ReductionIdRange;
18909       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18910                                VarDecl::DeclarationOnly;
18911       S.Diag(D->getLocation(),
18912              IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18913           << D;
18914       continue;
18915     }
18916     DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
18917     ExprResult ReductionOp;
18918     if (DeclareReductionRef.isUsable()) {
18919       QualType RedTy = DeclareReductionRef.get()->getType();
18920       QualType PtrRedTy = Context.getPointerType(RedTy);
18921       ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
18922       ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
18923       if (!BasePath.empty()) {
18924         LHS = S.DefaultLvalueConversion(LHS.get());
18925         RHS = S.DefaultLvalueConversion(RHS.get());
18926         LHS = ImplicitCastExpr::Create(
18927             Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath,
18928             LHS.get()->getValueKind(), FPOptionsOverride());
18929         RHS = ImplicitCastExpr::Create(
18930             Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath,
18931             RHS.get()->getValueKind(), FPOptionsOverride());
18932       }
18933       FunctionProtoType::ExtProtoInfo EPI;
18934       QualType Params[] = {PtrRedTy, PtrRedTy};
18935       QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
18936       auto *OVE = new (Context) OpaqueValueExpr(
18937           ELoc, Context.getPointerType(FnTy), VK_PRValue, OK_Ordinary,
18938           S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
18939       Expr *Args[] = {LHS.get(), RHS.get()};
18940       ReductionOp =
18941           CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_PRValue, ELoc,
18942                            S.CurFPFeatureOverrides());
18943     } else {
18944       BinaryOperatorKind CombBOK = getRelatedCompoundReductionOp(BOK);
18945       if (Type->isRecordType() && CombBOK != BOK) {
18946         Sema::TentativeAnalysisScope Trap(S);
18947         ReductionOp =
18948             S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
18949                          CombBOK, LHSDRE, RHSDRE);
18950       }
18951       if (!ReductionOp.isUsable()) {
18952         ReductionOp =
18953             S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), BOK,
18954                          LHSDRE, RHSDRE);
18955         if (ReductionOp.isUsable()) {
18956           if (BOK != BO_LT && BOK != BO_GT) {
18957             ReductionOp =
18958                 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
18959                              BO_Assign, LHSDRE, ReductionOp.get());
18960           } else {
18961             auto *ConditionalOp = new (Context)
18962                 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc,
18963                                     RHSDRE, Type, VK_LValue, OK_Ordinary);
18964             ReductionOp =
18965                 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
18966                              BO_Assign, LHSDRE, ConditionalOp);
18967           }
18968         }
18969       }
18970       if (ReductionOp.isUsable())
18971         ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
18972                                             /*DiscardedValue=*/false);
18973       if (!ReductionOp.isUsable())
18974         continue;
18975     }
18976 
18977     // Add copy operations for inscan reductions.
18978     // LHS = RHS;
18979     ExprResult CopyOpRes, TempArrayRes, TempArrayElem;
18980     if (ClauseKind == OMPC_reduction &&
18981         RD.RedModifier == OMPC_REDUCTION_inscan) {
18982       ExprResult RHS = S.DefaultLvalueConversion(RHSDRE);
18983       CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE,
18984                                RHS.get());
18985       if (!CopyOpRes.isUsable())
18986         continue;
18987       CopyOpRes =
18988           S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true);
18989       if (!CopyOpRes.isUsable())
18990         continue;
18991       // For simd directive and simd-based directives in simd mode no need to
18992       // construct temp array, need just a single temp element.
18993       if (Stack->getCurrentDirective() == OMPD_simd ||
18994           (S.getLangOpts().OpenMPSimd &&
18995            isOpenMPSimdDirective(Stack->getCurrentDirective()))) {
18996         VarDecl *TempArrayVD =
18997             buildVarDecl(S, ELoc, PrivateTy, D->getName(),
18998                          D->hasAttrs() ? &D->getAttrs() : nullptr);
18999         // Add a constructor to the temp decl.
19000         S.ActOnUninitializedDecl(TempArrayVD);
19001         TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc);
19002       } else {
19003         // Build temp array for prefix sum.
19004         auto *Dim = new (S.Context)
19005             OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue);
19006         QualType ArrayTy = S.Context.getVariableArrayType(
19007             PrivateTy, Dim, ArraySizeModifier::Normal,
19008             /*IndexTypeQuals=*/0, {ELoc, ELoc});
19009         VarDecl *TempArrayVD =
19010             buildVarDecl(S, ELoc, ArrayTy, D->getName(),
19011                          D->hasAttrs() ? &D->getAttrs() : nullptr);
19012         // Add a constructor to the temp decl.
19013         S.ActOnUninitializedDecl(TempArrayVD);
19014         TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc);
19015         TempArrayElem =
19016             S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get());
19017         auto *Idx = new (S.Context)
19018             OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue);
19019         TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(),
19020                                                           ELoc, Idx, ELoc);
19021       }
19022     }
19023 
19024     // OpenMP [2.15.4.6, Restrictions, p.2]
19025     // A list item that appears in an in_reduction clause of a task construct
19026     // must appear in a task_reduction clause of a construct associated with a
19027     // taskgroup region that includes the participating task in its taskgroup
19028     // set. The construct associated with the innermost region that meets this
19029     // condition must specify the same reduction-identifier as the in_reduction
19030     // clause.
19031     if (ClauseKind == OMPC_in_reduction) {
19032       SourceRange ParentSR;
19033       BinaryOperatorKind ParentBOK;
19034       const Expr *ParentReductionOp = nullptr;
19035       Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr;
19036       DSAStackTy::DSAVarData ParentBOKDSA =
19037           Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
19038                                                   ParentBOKTD);
19039       DSAStackTy::DSAVarData ParentReductionOpDSA =
19040           Stack->getTopMostTaskgroupReductionData(
19041               D, ParentSR, ParentReductionOp, ParentReductionOpTD);
19042       bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
19043       bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
19044       if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
19045           (DeclareReductionRef.isUsable() && IsParentBOK) ||
19046           (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) {
19047         bool EmitError = true;
19048         if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
19049           llvm::FoldingSetNodeID RedId, ParentRedId;
19050           ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
19051           DeclareReductionRef.get()->Profile(RedId, Context,
19052                                              /*Canonical=*/true);
19053           EmitError = RedId != ParentRedId;
19054         }
19055         if (EmitError) {
19056           S.Diag(ReductionId.getBeginLoc(),
19057                  diag::err_omp_reduction_identifier_mismatch)
19058               << ReductionIdRange << RefExpr->getSourceRange();
19059           S.Diag(ParentSR.getBegin(),
19060                  diag::note_omp_previous_reduction_identifier)
19061               << ParentSR
19062               << (IsParentBOK ? ParentBOKDSA.RefExpr
19063                               : ParentReductionOpDSA.RefExpr)
19064                      ->getSourceRange();
19065           continue;
19066         }
19067       }
19068       TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
19069     }
19070 
19071     DeclRefExpr *Ref = nullptr;
19072     Expr *VarsExpr = RefExpr->IgnoreParens();
19073     if (!VD && !S.CurContext->isDependentContext()) {
19074       if (ASE || OASE) {
19075         TransformExprToCaptures RebuildToCapture(S, D);
19076         VarsExpr =
19077             RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
19078         Ref = RebuildToCapture.getCapturedExpr();
19079       } else {
19080         VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
19081       }
19082       if (!S.OpenMP().isOpenMPCapturedDecl(D)) {
19083         RD.ExprCaptures.emplace_back(Ref->getDecl());
19084         if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
19085           ExprResult RefRes = S.DefaultLvalueConversion(Ref);
19086           if (!RefRes.isUsable())
19087             continue;
19088           ExprResult PostUpdateRes =
19089               S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
19090                            RefRes.get());
19091           if (!PostUpdateRes.isUsable())
19092             continue;
19093           if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
19094               Stack->getCurrentDirective() == OMPD_taskgroup) {
19095             S.Diag(RefExpr->getExprLoc(),
19096                    diag::err_omp_reduction_non_addressable_expression)
19097                 << RefExpr->getSourceRange();
19098             continue;
19099           }
19100           RD.ExprPostUpdates.emplace_back(
19101               S.IgnoredValueConversions(PostUpdateRes.get()).get());
19102         }
19103       }
19104     }
19105     // All reduction items are still marked as reduction (to do not increase
19106     // code base size).
19107     unsigned Modifier = RD.RedModifier;
19108     // Consider task_reductions as reductions with task modifier. Required for
19109     // correct analysis of in_reduction clauses.
19110     if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction)
19111       Modifier = OMPC_REDUCTION_task;
19112     Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier,
19113                   ASE || OASE);
19114     if (Modifier == OMPC_REDUCTION_task &&
19115         (CurrDir == OMPD_taskgroup ||
19116          ((isOpenMPParallelDirective(CurrDir) ||
19117            isOpenMPWorksharingDirective(CurrDir)) &&
19118           !isOpenMPSimdDirective(CurrDir)))) {
19119       if (DeclareReductionRef.isUsable())
19120         Stack->addTaskgroupReductionData(D, ReductionIdRange,
19121                                          DeclareReductionRef.get());
19122       else
19123         Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
19124     }
19125     RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
19126             TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(),
19127             TempArrayElem.get());
19128   }
19129   return RD.Vars.empty();
19130 }
19131 
19132 OMPClause *SemaOpenMP::ActOnOpenMPReductionClause(
19133     ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
19134     SourceLocation StartLoc, SourceLocation LParenLoc,
19135     SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
19136     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
19137     ArrayRef<Expr *> UnresolvedReductions) {
19138   if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) {
19139     Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
19140         << getListOfPossibleValues(OMPC_reduction, /*First=*/0,
19141                                    /*Last=*/OMPC_REDUCTION_unknown)
19142         << getOpenMPClauseName(OMPC_reduction);
19143     return nullptr;
19144   }
19145   // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions
19146   // A reduction clause with the inscan reduction-modifier may only appear on a
19147   // worksharing-loop construct, a worksharing-loop SIMD construct, a simd
19148   // construct, a parallel worksharing-loop construct or a parallel
19149   // worksharing-loop SIMD construct.
19150   if (Modifier == OMPC_REDUCTION_inscan &&
19151       (DSAStack->getCurrentDirective() != OMPD_for &&
19152        DSAStack->getCurrentDirective() != OMPD_for_simd &&
19153        DSAStack->getCurrentDirective() != OMPD_simd &&
19154        DSAStack->getCurrentDirective() != OMPD_parallel_for &&
19155        DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) {
19156     Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
19157     return nullptr;
19158   }
19159 
19160   ReductionData RD(VarList.size(), Modifier);
19161   if (actOnOMPReductionKindClause(SemaRef, DSAStack, OMPC_reduction, VarList,
19162                                   StartLoc, LParenLoc, ColonLoc, EndLoc,
19163                                   ReductionIdScopeSpec, ReductionId,
19164                                   UnresolvedReductions, RD))
19165     return nullptr;
19166 
19167   return OMPReductionClause::Create(
19168       getASTContext(), StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc,
19169       Modifier, RD.Vars,
19170       ReductionIdScopeSpec.getWithLocInContext(getASTContext()), ReductionId,
19171       RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps,
19172       RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems,
19173       buildPreInits(getASTContext(), RD.ExprCaptures),
19174       buildPostUpdate(SemaRef, RD.ExprPostUpdates));
19175 }
19176 
19177 OMPClause *SemaOpenMP::ActOnOpenMPTaskReductionClause(
19178     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
19179     SourceLocation ColonLoc, SourceLocation EndLoc,
19180     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
19181     ArrayRef<Expr *> UnresolvedReductions) {
19182   ReductionData RD(VarList.size());
19183   if (actOnOMPReductionKindClause(SemaRef, DSAStack, OMPC_task_reduction,
19184                                   VarList, StartLoc, LParenLoc, ColonLoc,
19185                                   EndLoc, ReductionIdScopeSpec, ReductionId,
19186                                   UnresolvedReductions, RD))
19187     return nullptr;
19188 
19189   return OMPTaskReductionClause::Create(
19190       getASTContext(), StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
19191       ReductionIdScopeSpec.getWithLocInContext(getASTContext()), ReductionId,
19192       RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
19193       buildPreInits(getASTContext(), RD.ExprCaptures),
19194       buildPostUpdate(SemaRef, RD.ExprPostUpdates));
19195 }
19196 
19197 OMPClause *SemaOpenMP::ActOnOpenMPInReductionClause(
19198     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
19199     SourceLocation ColonLoc, SourceLocation EndLoc,
19200     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
19201     ArrayRef<Expr *> UnresolvedReductions) {
19202   ReductionData RD(VarList.size());
19203   if (actOnOMPReductionKindClause(SemaRef, DSAStack, OMPC_in_reduction, VarList,
19204                                   StartLoc, LParenLoc, ColonLoc, EndLoc,
19205                                   ReductionIdScopeSpec, ReductionId,
19206                                   UnresolvedReductions, RD))
19207     return nullptr;
19208 
19209   return OMPInReductionClause::Create(
19210       getASTContext(), StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
19211       ReductionIdScopeSpec.getWithLocInContext(getASTContext()), ReductionId,
19212       RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
19213       buildPreInits(getASTContext(), RD.ExprCaptures),
19214       buildPostUpdate(SemaRef, RD.ExprPostUpdates));
19215 }
19216 
19217 bool SemaOpenMP::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
19218                                            SourceLocation LinLoc) {
19219   if ((!getLangOpts().CPlusPlus && LinKind != OMPC_LINEAR_val) ||
19220       LinKind == OMPC_LINEAR_unknown || LinKind == OMPC_LINEAR_step) {
19221     Diag(LinLoc, diag::err_omp_wrong_linear_modifier)
19222         << getLangOpts().CPlusPlus;
19223     return true;
19224   }
19225   return false;
19226 }
19227 
19228 bool SemaOpenMP::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
19229                                        OpenMPLinearClauseKind LinKind,
19230                                        QualType Type, bool IsDeclareSimd) {
19231   const auto *VD = dyn_cast_or_null<VarDecl>(D);
19232   // A variable must not have an incomplete type or a reference type.
19233   if (SemaRef.RequireCompleteType(ELoc, Type,
19234                                   diag::err_omp_linear_incomplete_type))
19235     return true;
19236   if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
19237       !Type->isReferenceType()) {
19238     Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
19239         << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
19240     return true;
19241   }
19242   Type = Type.getNonReferenceType();
19243 
19244   // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
19245   // A variable that is privatized must not have a const-qualified type
19246   // unless it is of class type with a mutable member. This restriction does
19247   // not apply to the firstprivate clause, nor to the linear clause on
19248   // declarative directives (like declare simd).
19249   if (!IsDeclareSimd &&
19250       rejectConstNotMutableType(SemaRef, D, Type, OMPC_linear, ELoc))
19251     return true;
19252 
19253   // A list item must be of integral or pointer type.
19254   Type = Type.getUnqualifiedType().getCanonicalType();
19255   const auto *Ty = Type.getTypePtrOrNull();
19256   if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
19257               !Ty->isIntegralType(getASTContext()) && !Ty->isPointerType())) {
19258     Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
19259     if (D) {
19260       bool IsDecl = !VD || VD->isThisDeclarationADefinition(getASTContext()) ==
19261                                VarDecl::DeclarationOnly;
19262       Diag(D->getLocation(),
19263            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19264           << D;
19265     }
19266     return true;
19267   }
19268   return false;
19269 }
19270 
19271 OMPClause *SemaOpenMP::ActOnOpenMPLinearClause(
19272     ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
19273     SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
19274     SourceLocation LinLoc, SourceLocation ColonLoc,
19275     SourceLocation StepModifierLoc, SourceLocation EndLoc) {
19276   SmallVector<Expr *, 8> Vars;
19277   SmallVector<Expr *, 8> Privates;
19278   SmallVector<Expr *, 8> Inits;
19279   SmallVector<Decl *, 4> ExprCaptures;
19280   SmallVector<Expr *, 4> ExprPostUpdates;
19281   // OpenMP 5.2 [Section 5.4.6, linear clause]
19282   // step-simple-modifier is exclusive, can't be used with 'val', 'uval', or
19283   // 'ref'
19284   if (LinLoc.isValid() && StepModifierLoc.isInvalid() && Step &&
19285       getLangOpts().OpenMP >= 52)
19286     Diag(Step->getBeginLoc(), diag::err_omp_step_simple_modifier_exclusive);
19287   if (CheckOpenMPLinearModifier(LinKind, LinLoc))
19288     LinKind = OMPC_LINEAR_val;
19289   for (Expr *RefExpr : VarList) {
19290     assert(RefExpr && "NULL expr in OpenMP linear clause.");
19291     SourceLocation ELoc;
19292     SourceRange ERange;
19293     Expr *SimpleRefExpr = RefExpr;
19294     auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
19295     if (Res.second) {
19296       // It will be analyzed later.
19297       Vars.push_back(RefExpr);
19298       Privates.push_back(nullptr);
19299       Inits.push_back(nullptr);
19300     }
19301     ValueDecl *D = Res.first;
19302     if (!D)
19303       continue;
19304 
19305     QualType Type = D->getType();
19306     auto *VD = dyn_cast<VarDecl>(D);
19307 
19308     // OpenMP [2.14.3.7, linear clause]
19309     //  A list-item cannot appear in more than one linear clause.
19310     //  A list-item that appears in a linear clause cannot appear in any
19311     //  other data-sharing attribute clause.
19312     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
19313     if (DVar.RefExpr) {
19314       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
19315                                           << getOpenMPClauseName(OMPC_linear);
19316       reportOriginalDsa(SemaRef, DSAStack, D, DVar);
19317       continue;
19318     }
19319 
19320     if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
19321       continue;
19322     Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
19323 
19324     // Build private copy of original var.
19325     VarDecl *Private =
19326         buildVarDecl(SemaRef, ELoc, Type, D->getName(),
19327                      D->hasAttrs() ? &D->getAttrs() : nullptr,
19328                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
19329     DeclRefExpr *PrivateRef = buildDeclRefExpr(SemaRef, Private, Type, ELoc);
19330     // Build var to save initial value.
19331     VarDecl *Init = buildVarDecl(SemaRef, ELoc, Type, ".linear.start");
19332     Expr *InitExpr;
19333     DeclRefExpr *Ref = nullptr;
19334     if (!VD && !SemaRef.CurContext->isDependentContext()) {
19335       Ref = buildCapture(SemaRef, D, SimpleRefExpr, /*WithInit=*/false);
19336       if (!isOpenMPCapturedDecl(D)) {
19337         ExprCaptures.push_back(Ref->getDecl());
19338         if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
19339           ExprResult RefRes = SemaRef.DefaultLvalueConversion(Ref);
19340           if (!RefRes.isUsable())
19341             continue;
19342           ExprResult PostUpdateRes =
19343               SemaRef.BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
19344                                  SimpleRefExpr, RefRes.get());
19345           if (!PostUpdateRes.isUsable())
19346             continue;
19347           ExprPostUpdates.push_back(
19348               SemaRef.IgnoredValueConversions(PostUpdateRes.get()).get());
19349         }
19350       }
19351     }
19352     if (LinKind == OMPC_LINEAR_uval)
19353       InitExpr = VD ? VD->getInit() : SimpleRefExpr;
19354     else
19355       InitExpr = VD ? SimpleRefExpr : Ref;
19356     SemaRef.AddInitializerToDecl(
19357         Init, SemaRef.DefaultLvalueConversion(InitExpr).get(),
19358         /*DirectInit=*/false);
19359     DeclRefExpr *InitRef = buildDeclRefExpr(SemaRef, Init, Type, ELoc);
19360 
19361     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
19362     Vars.push_back((VD || SemaRef.CurContext->isDependentContext())
19363                        ? RefExpr->IgnoreParens()
19364                        : Ref);
19365     Privates.push_back(PrivateRef);
19366     Inits.push_back(InitRef);
19367   }
19368 
19369   if (Vars.empty())
19370     return nullptr;
19371 
19372   Expr *StepExpr = Step;
19373   Expr *CalcStepExpr = nullptr;
19374   if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
19375       !Step->isInstantiationDependent() &&
19376       !Step->containsUnexpandedParameterPack()) {
19377     SourceLocation StepLoc = Step->getBeginLoc();
19378     ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
19379     if (Val.isInvalid())
19380       return nullptr;
19381     StepExpr = Val.get();
19382 
19383     // Build var to save the step value.
19384     VarDecl *SaveVar =
19385         buildVarDecl(SemaRef, StepLoc, StepExpr->getType(), ".linear.step");
19386     ExprResult SaveRef =
19387         buildDeclRefExpr(SemaRef, SaveVar, StepExpr->getType(), StepLoc);
19388     ExprResult CalcStep = SemaRef.BuildBinOp(
19389         SemaRef.getCurScope(), StepLoc, BO_Assign, SaveRef.get(), StepExpr);
19390     CalcStep =
19391         SemaRef.ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue=*/false);
19392 
19393     // Warn about zero linear step (it would be probably better specified as
19394     // making corresponding variables 'const').
19395     if (std::optional<llvm::APSInt> Result =
19396             StepExpr->getIntegerConstantExpr(getASTContext())) {
19397       if (!Result->isNegative() && !Result->isStrictlyPositive())
19398         Diag(StepLoc, diag::warn_omp_linear_step_zero)
19399             << Vars[0] << (Vars.size() > 1);
19400     } else if (CalcStep.isUsable()) {
19401       // Calculate the step beforehand instead of doing this on each iteration.
19402       // (This is not used if the number of iterations may be kfold-ed).
19403       CalcStepExpr = CalcStep.get();
19404     }
19405   }
19406 
19407   return OMPLinearClause::Create(getASTContext(), StartLoc, LParenLoc, LinKind,
19408                                  LinLoc, ColonLoc, StepModifierLoc, EndLoc,
19409                                  Vars, Privates, Inits, StepExpr, CalcStepExpr,
19410                                  buildPreInits(getASTContext(), ExprCaptures),
19411                                  buildPostUpdate(SemaRef, ExprPostUpdates));
19412 }
19413 
19414 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
19415                                      Expr *NumIterations, Sema &SemaRef,
19416                                      Scope *S, DSAStackTy *Stack) {
19417   // Walk the vars and build update/final expressions for the CodeGen.
19418   SmallVector<Expr *, 8> Updates;
19419   SmallVector<Expr *, 8> Finals;
19420   SmallVector<Expr *, 8> UsedExprs;
19421   Expr *Step = Clause.getStep();
19422   Expr *CalcStep = Clause.getCalcStep();
19423   // OpenMP [2.14.3.7, linear clause]
19424   // If linear-step is not specified it is assumed to be 1.
19425   if (!Step)
19426     Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
19427   else if (CalcStep)
19428     Step = cast<BinaryOperator>(CalcStep)->getLHS();
19429   bool HasErrors = false;
19430   auto CurInit = Clause.inits().begin();
19431   auto CurPrivate = Clause.privates().begin();
19432   OpenMPLinearClauseKind LinKind = Clause.getModifier();
19433   for (Expr *RefExpr : Clause.varlist()) {
19434     SourceLocation ELoc;
19435     SourceRange ERange;
19436     Expr *SimpleRefExpr = RefExpr;
19437     auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
19438     ValueDecl *D = Res.first;
19439     if (Res.second || !D) {
19440       Updates.push_back(nullptr);
19441       Finals.push_back(nullptr);
19442       HasErrors = true;
19443       continue;
19444     }
19445     auto &&Info = Stack->isLoopControlVariable(D);
19446     // OpenMP [2.15.11, distribute simd Construct]
19447     // A list item may not appear in a linear clause, unless it is the loop
19448     // iteration variable.
19449     if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
19450         isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
19451       SemaRef.Diag(ELoc,
19452                    diag::err_omp_linear_distribute_var_non_loop_iteration);
19453       Updates.push_back(nullptr);
19454       Finals.push_back(nullptr);
19455       HasErrors = true;
19456       continue;
19457     }
19458     Expr *InitExpr = *CurInit;
19459 
19460     // Build privatized reference to the current linear var.
19461     auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
19462     Expr *CapturedRef;
19463     if (LinKind == OMPC_LINEAR_uval)
19464       CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
19465     else
19466       CapturedRef =
19467           buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
19468                            DE->getType().getUnqualifiedType(), DE->getExprLoc(),
19469                            /*RefersToCapture=*/true);
19470 
19471     // Build update: Var = InitExpr + IV * Step
19472     ExprResult Update;
19473     if (!Info.first)
19474       Update = buildCounterUpdate(
19475           SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
19476           /*Subtract=*/false, /*IsNonRectangularLB=*/false);
19477     else
19478       Update = *CurPrivate;
19479     Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
19480                                          /*DiscardedValue=*/false);
19481 
19482     // Build final: Var = PrivCopy;
19483     ExprResult Final;
19484     if (!Info.first)
19485       Final = SemaRef.BuildBinOp(
19486           S, RefExpr->getExprLoc(), BO_Assign, CapturedRef,
19487           SemaRef.DefaultLvalueConversion(*CurPrivate).get());
19488     else
19489       Final = *CurPrivate;
19490     Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
19491                                         /*DiscardedValue=*/false);
19492 
19493     if (!Update.isUsable() || !Final.isUsable()) {
19494       Updates.push_back(nullptr);
19495       Finals.push_back(nullptr);
19496       UsedExprs.push_back(nullptr);
19497       HasErrors = true;
19498     } else {
19499       Updates.push_back(Update.get());
19500       Finals.push_back(Final.get());
19501       if (!Info.first)
19502         UsedExprs.push_back(SimpleRefExpr);
19503     }
19504     ++CurInit;
19505     ++CurPrivate;
19506   }
19507   if (Expr *S = Clause.getStep())
19508     UsedExprs.push_back(S);
19509   // Fill the remaining part with the nullptr.
19510   UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr);
19511   Clause.setUpdates(Updates);
19512   Clause.setFinals(Finals);
19513   Clause.setUsedExprs(UsedExprs);
19514   return HasErrors;
19515 }
19516 
19517 OMPClause *SemaOpenMP::ActOnOpenMPAlignedClause(
19518     ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
19519     SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
19520   SmallVector<Expr *, 8> Vars;
19521   for (Expr *RefExpr : VarList) {
19522     assert(RefExpr && "NULL expr in OpenMP linear clause.");
19523     SourceLocation ELoc;
19524     SourceRange ERange;
19525     Expr *SimpleRefExpr = RefExpr;
19526     auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
19527     if (Res.second) {
19528       // It will be analyzed later.
19529       Vars.push_back(RefExpr);
19530     }
19531     ValueDecl *D = Res.first;
19532     if (!D)
19533       continue;
19534 
19535     QualType QType = D->getType();
19536     auto *VD = dyn_cast<VarDecl>(D);
19537 
19538     // OpenMP  [2.8.1, simd construct, Restrictions]
19539     // The type of list items appearing in the aligned clause must be
19540     // array, pointer, reference to array, or reference to pointer.
19541     QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
19542     const Type *Ty = QType.getTypePtrOrNull();
19543     if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
19544       Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
19545           << QType << getLangOpts().CPlusPlus << ERange;
19546       bool IsDecl = !VD || VD->isThisDeclarationADefinition(getASTContext()) ==
19547                                VarDecl::DeclarationOnly;
19548       Diag(D->getLocation(),
19549            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19550           << D;
19551       continue;
19552     }
19553 
19554     // OpenMP  [2.8.1, simd construct, Restrictions]
19555     // A list-item cannot appear in more than one aligned clause.
19556     if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
19557       Diag(ELoc, diag::err_omp_used_in_clause_twice)
19558           << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
19559       Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
19560           << getOpenMPClauseName(OMPC_aligned);
19561       continue;
19562     }
19563 
19564     DeclRefExpr *Ref = nullptr;
19565     if (!VD && isOpenMPCapturedDecl(D))
19566       Ref = buildCapture(SemaRef, D, SimpleRefExpr, /*WithInit=*/true);
19567     Vars.push_back(SemaRef
19568                        .DefaultFunctionArrayConversion(
19569                            (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
19570                        .get());
19571   }
19572 
19573   // OpenMP [2.8.1, simd construct, Description]
19574   // The parameter of the aligned clause, alignment, must be a constant
19575   // positive integer expression.
19576   // If no optional parameter is specified, implementation-defined default
19577   // alignments for SIMD instructions on the target platforms are assumed.
19578   if (Alignment != nullptr) {
19579     ExprResult AlignResult =
19580         VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
19581     if (AlignResult.isInvalid())
19582       return nullptr;
19583     Alignment = AlignResult.get();
19584   }
19585   if (Vars.empty())
19586     return nullptr;
19587 
19588   return OMPAlignedClause::Create(getASTContext(), StartLoc, LParenLoc,
19589                                   ColonLoc, EndLoc, Vars, Alignment);
19590 }
19591 
19592 OMPClause *SemaOpenMP::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
19593                                                SourceLocation StartLoc,
19594                                                SourceLocation LParenLoc,
19595                                                SourceLocation EndLoc) {
19596   SmallVector<Expr *, 8> Vars;
19597   SmallVector<Expr *, 8> SrcExprs;
19598   SmallVector<Expr *, 8> DstExprs;
19599   SmallVector<Expr *, 8> AssignmentOps;
19600   for (Expr *RefExpr : VarList) {
19601     assert(RefExpr && "NULL expr in OpenMP copyin clause.");
19602     if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
19603       // It will be analyzed later.
19604       Vars.push_back(RefExpr);
19605       SrcExprs.push_back(nullptr);
19606       DstExprs.push_back(nullptr);
19607       AssignmentOps.push_back(nullptr);
19608       continue;
19609     }
19610 
19611     SourceLocation ELoc = RefExpr->getExprLoc();
19612     // OpenMP [2.1, C/C++]
19613     //  A list item is a variable name.
19614     // OpenMP  [2.14.4.1, Restrictions, p.1]
19615     //  A list item that appears in a copyin clause must be threadprivate.
19616     auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
19617     if (!DE || !isa<VarDecl>(DE->getDecl())) {
19618       Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
19619           << 0 << RefExpr->getSourceRange();
19620       continue;
19621     }
19622 
19623     Decl *D = DE->getDecl();
19624     auto *VD = cast<VarDecl>(D);
19625 
19626     QualType Type = VD->getType();
19627     if (Type->isDependentType() || Type->isInstantiationDependentType()) {
19628       // It will be analyzed later.
19629       Vars.push_back(DE);
19630       SrcExprs.push_back(nullptr);
19631       DstExprs.push_back(nullptr);
19632       AssignmentOps.push_back(nullptr);
19633       continue;
19634     }
19635 
19636     // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
19637     //  A list item that appears in a copyin clause must be threadprivate.
19638     if (!DSAStack->isThreadPrivate(VD)) {
19639       Diag(ELoc, diag::err_omp_required_access)
19640           << getOpenMPClauseName(OMPC_copyin)
19641           << getOpenMPDirectiveName(OMPD_threadprivate);
19642       continue;
19643     }
19644 
19645     // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
19646     //  A variable of class type (or array thereof) that appears in a
19647     //  copyin clause requires an accessible, unambiguous copy assignment
19648     //  operator for the class type.
19649     QualType ElemType =
19650         getASTContext().getBaseElementType(Type).getNonReferenceType();
19651     VarDecl *SrcVD =
19652         buildVarDecl(SemaRef, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
19653                      ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
19654     DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
19655         SemaRef, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
19656     VarDecl *DstVD =
19657         buildVarDecl(SemaRef, DE->getBeginLoc(), ElemType, ".copyin.dst",
19658                      VD->hasAttrs() ? &VD->getAttrs() : nullptr);
19659     DeclRefExpr *PseudoDstExpr =
19660         buildDeclRefExpr(SemaRef, DstVD, ElemType, DE->getExprLoc());
19661     // For arrays generate assignment operation for single element and replace
19662     // it by the original array element in CodeGen.
19663     ExprResult AssignmentOp =
19664         SemaRef.BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign,
19665                            PseudoDstExpr, PseudoSrcExpr);
19666     if (AssignmentOp.isInvalid())
19667       continue;
19668     AssignmentOp =
19669         SemaRef.ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
19670                                     /*DiscardedValue=*/false);
19671     if (AssignmentOp.isInvalid())
19672       continue;
19673 
19674     DSAStack->addDSA(VD, DE, OMPC_copyin);
19675     Vars.push_back(DE);
19676     SrcExprs.push_back(PseudoSrcExpr);
19677     DstExprs.push_back(PseudoDstExpr);
19678     AssignmentOps.push_back(AssignmentOp.get());
19679   }
19680 
19681   if (Vars.empty())
19682     return nullptr;
19683 
19684   return OMPCopyinClause::Create(getASTContext(), StartLoc, LParenLoc, EndLoc,
19685                                  Vars, SrcExprs, DstExprs, AssignmentOps);
19686 }
19687 
19688 OMPClause *SemaOpenMP::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
19689                                                     SourceLocation StartLoc,
19690                                                     SourceLocation LParenLoc,
19691                                                     SourceLocation EndLoc) {
19692   SmallVector<Expr *, 8> Vars;
19693   SmallVector<Expr *, 8> SrcExprs;
19694   SmallVector<Expr *, 8> DstExprs;
19695   SmallVector<Expr *, 8> AssignmentOps;
19696   for (Expr *RefExpr : VarList) {
19697     assert(RefExpr && "NULL expr in OpenMP linear clause.");
19698     SourceLocation ELoc;
19699     SourceRange ERange;
19700     Expr *SimpleRefExpr = RefExpr;
19701     auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
19702     if (Res.second) {
19703       // It will be analyzed later.
19704       Vars.push_back(RefExpr);
19705       SrcExprs.push_back(nullptr);
19706       DstExprs.push_back(nullptr);
19707       AssignmentOps.push_back(nullptr);
19708     }
19709     ValueDecl *D = Res.first;
19710     if (!D)
19711       continue;
19712 
19713     QualType Type = D->getType();
19714     auto *VD = dyn_cast<VarDecl>(D);
19715 
19716     // OpenMP [2.14.4.2, Restrictions, p.2]
19717     //  A list item that appears in a copyprivate clause may not appear in a
19718     //  private or firstprivate clause on the single construct.
19719     if (!VD || !DSAStack->isThreadPrivate(VD)) {
19720       DSAStackTy::DSAVarData DVar =
19721           DSAStack->getTopDSA(D, /*FromParent=*/false);
19722       if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
19723           DVar.RefExpr) {
19724         Diag(ELoc, diag::err_omp_wrong_dsa)
19725             << getOpenMPClauseName(DVar.CKind)
19726             << getOpenMPClauseName(OMPC_copyprivate);
19727         reportOriginalDsa(SemaRef, DSAStack, D, DVar);
19728         continue;
19729       }
19730 
19731       // OpenMP [2.11.4.2, Restrictions, p.1]
19732       //  All list items that appear in a copyprivate clause must be either
19733       //  threadprivate or private in the enclosing context.
19734       if (DVar.CKind == OMPC_unknown) {
19735         DVar = DSAStack->getImplicitDSA(D, false);
19736         if (DVar.CKind == OMPC_shared) {
19737           Diag(ELoc, diag::err_omp_required_access)
19738               << getOpenMPClauseName(OMPC_copyprivate)
19739               << "threadprivate or private in the enclosing context";
19740           reportOriginalDsa(SemaRef, DSAStack, D, DVar);
19741           continue;
19742         }
19743       }
19744     }
19745 
19746     // Variably modified types are not supported.
19747     if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
19748       Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
19749           << getOpenMPClauseName(OMPC_copyprivate) << Type
19750           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
19751       bool IsDecl = !VD || VD->isThisDeclarationADefinition(getASTContext()) ==
19752                                VarDecl::DeclarationOnly;
19753       Diag(D->getLocation(),
19754            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19755           << D;
19756       continue;
19757     }
19758 
19759     // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
19760     //  A variable of class type (or array thereof) that appears in a
19761     //  copyin clause requires an accessible, unambiguous copy assignment
19762     //  operator for the class type.
19763     Type = getASTContext()
19764                .getBaseElementType(Type.getNonReferenceType())
19765                .getUnqualifiedType();
19766     VarDecl *SrcVD =
19767         buildVarDecl(SemaRef, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
19768                      D->hasAttrs() ? &D->getAttrs() : nullptr);
19769     DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(SemaRef, SrcVD, Type, ELoc);
19770     VarDecl *DstVD =
19771         buildVarDecl(SemaRef, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
19772                      D->hasAttrs() ? &D->getAttrs() : nullptr);
19773     DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(SemaRef, DstVD, Type, ELoc);
19774     ExprResult AssignmentOp = SemaRef.BuildBinOp(
19775         DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
19776     if (AssignmentOp.isInvalid())
19777       continue;
19778     AssignmentOp = SemaRef.ActOnFinishFullExpr(AssignmentOp.get(), ELoc,
19779                                                /*DiscardedValue=*/false);
19780     if (AssignmentOp.isInvalid())
19781       continue;
19782 
19783     // No need to mark vars as copyprivate, they are already threadprivate or
19784     // implicitly private.
19785     assert(VD || isOpenMPCapturedDecl(D));
19786     Vars.push_back(
19787         VD ? RefExpr->IgnoreParens()
19788            : buildCapture(SemaRef, D, SimpleRefExpr, /*WithInit=*/false));
19789     SrcExprs.push_back(PseudoSrcExpr);
19790     DstExprs.push_back(PseudoDstExpr);
19791     AssignmentOps.push_back(AssignmentOp.get());
19792   }
19793 
19794   if (Vars.empty())
19795     return nullptr;
19796 
19797   return OMPCopyprivateClause::Create(getASTContext(), StartLoc, LParenLoc,
19798                                       EndLoc, Vars, SrcExprs, DstExprs,
19799                                       AssignmentOps);
19800 }
19801 
19802 OMPClause *SemaOpenMP::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
19803                                               SourceLocation StartLoc,
19804                                               SourceLocation LParenLoc,
19805                                               SourceLocation EndLoc) {
19806   if (VarList.empty())
19807     return nullptr;
19808 
19809   return OMPFlushClause::Create(getASTContext(), StartLoc, LParenLoc, EndLoc,
19810                                 VarList);
19811 }
19812 
19813 /// Tries to find omp_depend_t. type.
19814 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack,
19815                            bool Diagnose = true) {
19816   QualType OMPDependT = Stack->getOMPDependT();
19817   if (!OMPDependT.isNull())
19818     return true;
19819   IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t");
19820   ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
19821   if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
19822     if (Diagnose)
19823       S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t";
19824     return false;
19825   }
19826   Stack->setOMPDependT(PT.get());
19827   return true;
19828 }
19829 
19830 OMPClause *SemaOpenMP::ActOnOpenMPDepobjClause(Expr *Depobj,
19831                                                SourceLocation StartLoc,
19832                                                SourceLocation LParenLoc,
19833                                                SourceLocation EndLoc) {
19834   if (!Depobj)
19835     return nullptr;
19836 
19837   bool OMPDependTFound = findOMPDependT(SemaRef, StartLoc, DSAStack);
19838 
19839   // OpenMP 5.0, 2.17.10.1 depobj Construct
19840   // depobj is an lvalue expression of type omp_depend_t.
19841   if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() &&
19842       !Depobj->isInstantiationDependent() &&
19843       !Depobj->containsUnexpandedParameterPack() &&
19844       (OMPDependTFound && !getASTContext().typesAreCompatible(
19845                               DSAStack->getOMPDependT(), Depobj->getType(),
19846                               /*CompareUnqualified=*/true))) {
19847     Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
19848         << 0 << Depobj->getType() << Depobj->getSourceRange();
19849   }
19850 
19851   if (!Depobj->isLValue()) {
19852     Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
19853         << 1 << Depobj->getSourceRange();
19854   }
19855 
19856   return OMPDepobjClause::Create(getASTContext(), StartLoc, LParenLoc, EndLoc,
19857                                  Depobj);
19858 }
19859 
19860 namespace {
19861 // Utility struct that gathers the related info for doacross clause.
19862 struct DoacrossDataInfoTy {
19863   // The list of expressions.
19864   SmallVector<Expr *, 8> Vars;
19865   // The OperatorOffset for doacross loop.
19866   DSAStackTy::OperatorOffsetTy OpsOffs;
19867   // The depended loop count.
19868   llvm::APSInt TotalDepCount;
19869 };
19870 } // namespace
19871 static DoacrossDataInfoTy
19872 ProcessOpenMPDoacrossClauseCommon(Sema &SemaRef, bool IsSource,
19873                                   ArrayRef<Expr *> VarList, DSAStackTy *Stack,
19874                                   SourceLocation EndLoc) {
19875 
19876   SmallVector<Expr *, 8> Vars;
19877   DSAStackTy::OperatorOffsetTy OpsOffs;
19878   llvm::APSInt DepCounter(/*BitWidth=*/32);
19879   llvm::APSInt TotalDepCount(/*BitWidth=*/32);
19880 
19881   if (const Expr *OrderedCountExpr =
19882           Stack->getParentOrderedRegionParam().first) {
19883     TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(SemaRef.Context);
19884     TotalDepCount.setIsUnsigned(/*Val=*/true);
19885   }
19886 
19887   for (Expr *RefExpr : VarList) {
19888     assert(RefExpr && "NULL expr in OpenMP doacross clause.");
19889     if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
19890       // It will be analyzed later.
19891       Vars.push_back(RefExpr);
19892       continue;
19893     }
19894 
19895     SourceLocation ELoc = RefExpr->getExprLoc();
19896     Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
19897     if (!IsSource) {
19898       if (Stack->getParentOrderedRegionParam().first &&
19899           DepCounter >= TotalDepCount) {
19900         SemaRef.Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
19901         continue;
19902       }
19903       ++DepCounter;
19904       // OpenMP  [2.13.9, Summary]
19905       // depend(dependence-type : vec), where dependence-type is:
19906       // 'sink' and where vec is the iteration vector, which has the form:
19907       //  x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
19908       // where n is the value specified by the ordered clause in the loop
19909       // directive, xi denotes the loop iteration variable of the i-th nested
19910       // loop associated with the loop directive, and di is a constant
19911       // non-negative integer.
19912       if (SemaRef.CurContext->isDependentContext()) {
19913         // It will be analyzed later.
19914         Vars.push_back(RefExpr);
19915         continue;
19916       }
19917       SimpleExpr = SimpleExpr->IgnoreImplicit();
19918       OverloadedOperatorKind OOK = OO_None;
19919       SourceLocation OOLoc;
19920       Expr *LHS = SimpleExpr;
19921       Expr *RHS = nullptr;
19922       if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
19923         OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
19924         OOLoc = BO->getOperatorLoc();
19925         LHS = BO->getLHS()->IgnoreParenImpCasts();
19926         RHS = BO->getRHS()->IgnoreParenImpCasts();
19927       } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
19928         OOK = OCE->getOperator();
19929         OOLoc = OCE->getOperatorLoc();
19930         LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
19931         RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
19932       } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
19933         OOK = MCE->getMethodDecl()
19934                   ->getNameInfo()
19935                   .getName()
19936                   .getCXXOverloadedOperator();
19937         OOLoc = MCE->getCallee()->getExprLoc();
19938         LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
19939         RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
19940       }
19941       SourceLocation ELoc;
19942       SourceRange ERange;
19943       auto Res = getPrivateItem(SemaRef, LHS, ELoc, ERange);
19944       if (Res.second) {
19945         // It will be analyzed later.
19946         Vars.push_back(RefExpr);
19947       }
19948       ValueDecl *D = Res.first;
19949       if (!D)
19950         continue;
19951 
19952       if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
19953         SemaRef.Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
19954         continue;
19955       }
19956       if (RHS) {
19957         ExprResult RHSRes =
19958             SemaRef.OpenMP().VerifyPositiveIntegerConstantInClause(
19959                 RHS, OMPC_depend, /*StrictlyPositive=*/false);
19960         if (RHSRes.isInvalid())
19961           continue;
19962       }
19963       if (!SemaRef.CurContext->isDependentContext() &&
19964           Stack->getParentOrderedRegionParam().first &&
19965           DepCounter != Stack->isParentLoopControlVariable(D).first) {
19966         const ValueDecl *VD =
19967             Stack->getParentLoopControlVariable(DepCounter.getZExtValue());
19968         if (VD)
19969           SemaRef.Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
19970               << 1 << VD;
19971         else
19972           SemaRef.Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
19973               << 0;
19974         continue;
19975       }
19976       OpsOffs.emplace_back(RHS, OOK);
19977     }
19978     Vars.push_back(RefExpr->IgnoreParenImpCasts());
19979   }
19980   if (!SemaRef.CurContext->isDependentContext() && !IsSource &&
19981       TotalDepCount > VarList.size() &&
19982       Stack->getParentOrderedRegionParam().first &&
19983       Stack->getParentLoopControlVariable(VarList.size() + 1)) {
19984     SemaRef.Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
19985         << 1 << Stack->getParentLoopControlVariable(VarList.size() + 1);
19986   }
19987   return {Vars, OpsOffs, TotalDepCount};
19988 }
19989 
19990 OMPClause *SemaOpenMP::ActOnOpenMPDependClause(
19991     const OMPDependClause::DependDataTy &Data, Expr *DepModifier,
19992     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
19993     SourceLocation EndLoc) {
19994   OpenMPDependClauseKind DepKind = Data.DepKind;
19995   SourceLocation DepLoc = Data.DepLoc;
19996   if (DSAStack->getCurrentDirective() == OMPD_ordered &&
19997       DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
19998     Diag(DepLoc, diag::err_omp_unexpected_clause_value)
19999         << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
20000     return nullptr;
20001   }
20002   if (DSAStack->getCurrentDirective() == OMPD_taskwait &&
20003       DepKind == OMPC_DEPEND_mutexinoutset) {
20004     Diag(DepLoc, diag::err_omp_taskwait_depend_mutexinoutset_not_allowed);
20005     return nullptr;
20006   }
20007   if ((DSAStack->getCurrentDirective() != OMPD_ordered ||
20008        DSAStack->getCurrentDirective() == OMPD_depobj) &&
20009       (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
20010        DepKind == OMPC_DEPEND_sink ||
20011        ((getLangOpts().OpenMP < 50 ||
20012          DSAStack->getCurrentDirective() == OMPD_depobj) &&
20013         DepKind == OMPC_DEPEND_depobj))) {
20014     SmallVector<unsigned, 6> Except = {OMPC_DEPEND_source, OMPC_DEPEND_sink,
20015                                        OMPC_DEPEND_outallmemory,
20016                                        OMPC_DEPEND_inoutallmemory};
20017     if (getLangOpts().OpenMP < 50 ||
20018         DSAStack->getCurrentDirective() == OMPD_depobj)
20019       Except.push_back(OMPC_DEPEND_depobj);
20020     if (getLangOpts().OpenMP < 51)
20021       Except.push_back(OMPC_DEPEND_inoutset);
20022     std::string Expected = (getLangOpts().OpenMP >= 50 && !DepModifier)
20023                                ? "depend modifier(iterator) or "
20024                                : "";
20025     Diag(DepLoc, diag::err_omp_unexpected_clause_value)
20026         << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0,
20027                                               /*Last=*/OMPC_DEPEND_unknown,
20028                                               Except)
20029         << getOpenMPClauseName(OMPC_depend);
20030     return nullptr;
20031   }
20032   if (DepModifier &&
20033       (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) {
20034     Diag(DepModifier->getExprLoc(),
20035          diag::err_omp_depend_sink_source_with_modifier);
20036     return nullptr;
20037   }
20038   if (DepModifier &&
20039       !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator))
20040     Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator);
20041 
20042   SmallVector<Expr *, 8> Vars;
20043   DSAStackTy::OperatorOffsetTy OpsOffs;
20044   llvm::APSInt TotalDepCount(/*BitWidth=*/32);
20045 
20046   if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
20047     DoacrossDataInfoTy VarOffset = ProcessOpenMPDoacrossClauseCommon(
20048         SemaRef, DepKind == OMPC_DEPEND_source, VarList, DSAStack, EndLoc);
20049     Vars = VarOffset.Vars;
20050     OpsOffs = VarOffset.OpsOffs;
20051     TotalDepCount = VarOffset.TotalDepCount;
20052   } else {
20053     for (Expr *RefExpr : VarList) {
20054       assert(RefExpr && "NULL expr in OpenMP shared clause.");
20055       if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
20056         // It will be analyzed later.
20057         Vars.push_back(RefExpr);
20058         continue;
20059       }
20060 
20061       SourceLocation ELoc = RefExpr->getExprLoc();
20062       Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
20063       if (DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) {
20064         bool OMPDependTFound = getLangOpts().OpenMP >= 50;
20065         if (OMPDependTFound)
20066           OMPDependTFound = findOMPDependT(SemaRef, StartLoc, DSAStack,
20067                                            DepKind == OMPC_DEPEND_depobj);
20068         if (DepKind == OMPC_DEPEND_depobj) {
20069           // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
20070           // List items used in depend clauses with the depobj dependence type
20071           // must be expressions of the omp_depend_t type.
20072           if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
20073               !RefExpr->isInstantiationDependent() &&
20074               !RefExpr->containsUnexpandedParameterPack() &&
20075               (OMPDependTFound &&
20076                !getASTContext().hasSameUnqualifiedType(
20077                    DSAStack->getOMPDependT(), RefExpr->getType()))) {
20078             Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
20079                 << 0 << RefExpr->getType() << RefExpr->getSourceRange();
20080             continue;
20081           }
20082           if (!RefExpr->isLValue()) {
20083             Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
20084                 << 1 << RefExpr->getType() << RefExpr->getSourceRange();
20085             continue;
20086           }
20087         } else {
20088           // OpenMP 5.0 [2.17.11, Restrictions]
20089           // List items used in depend clauses cannot be zero-length array
20090           // sections.
20091           QualType ExprTy = RefExpr->getType().getNonReferenceType();
20092           const auto *OASE = dyn_cast<ArraySectionExpr>(SimpleExpr);
20093           if (OASE) {
20094             QualType BaseType =
20095                 ArraySectionExpr::getBaseOriginalType(OASE->getBase());
20096             if (BaseType.isNull())
20097               return nullptr;
20098             if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
20099               ExprTy = ATy->getElementType();
20100             else
20101               ExprTy = BaseType->getPointeeType();
20102             if (BaseType.isNull() || ExprTy.isNull())
20103               return nullptr;
20104             ExprTy = ExprTy.getNonReferenceType();
20105             const Expr *Length = OASE->getLength();
20106             Expr::EvalResult Result;
20107             if (Length && !Length->isValueDependent() &&
20108                 Length->EvaluateAsInt(Result, getASTContext()) &&
20109                 Result.Val.getInt().isZero()) {
20110               Diag(ELoc,
20111                    diag::err_omp_depend_zero_length_array_section_not_allowed)
20112                   << SimpleExpr->getSourceRange();
20113               continue;
20114             }
20115           }
20116 
20117           // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
20118           // List items used in depend clauses with the in, out, inout,
20119           // inoutset, or mutexinoutset dependence types cannot be
20120           // expressions of the omp_depend_t type.
20121           if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
20122               !RefExpr->isInstantiationDependent() &&
20123               !RefExpr->containsUnexpandedParameterPack() &&
20124               (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
20125                (OMPDependTFound && DSAStack->getOMPDependT().getTypePtr() ==
20126                                        ExprTy.getTypePtr()))) {
20127             Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
20128                 << (getLangOpts().OpenMP >= 50 ? 1 : 0)
20129                 << (getLangOpts().OpenMP >= 50 ? 1 : 0)
20130                 << RefExpr->getSourceRange();
20131             continue;
20132           }
20133 
20134           auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
20135           if (ASE && !ASE->getBase()->isTypeDependent() &&
20136               !ASE->getBase()
20137                    ->getType()
20138                    .getNonReferenceType()
20139                    ->isPointerType() &&
20140               !ASE->getBase()->getType().getNonReferenceType()->isArrayType()) {
20141             Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
20142                 << (getLangOpts().OpenMP >= 50 ? 1 : 0)
20143                 << (getLangOpts().OpenMP >= 50 ? 1 : 0)
20144                 << RefExpr->getSourceRange();
20145             continue;
20146           }
20147 
20148           ExprResult Res;
20149           {
20150             Sema::TentativeAnalysisScope Trap(SemaRef);
20151             Res = SemaRef.CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
20152                                                RefExpr->IgnoreParenImpCasts());
20153           }
20154           if (!Res.isUsable() && !isa<ArraySectionExpr>(SimpleExpr) &&
20155               !isa<OMPArrayShapingExpr>(SimpleExpr)) {
20156             Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
20157                 << (getLangOpts().OpenMP >= 50 ? 1 : 0)
20158                 << (getLangOpts().OpenMP >= 50 ? 1 : 0)
20159                 << RefExpr->getSourceRange();
20160             continue;
20161           }
20162         }
20163       }
20164       Vars.push_back(RefExpr->IgnoreParenImpCasts());
20165     }
20166   }
20167 
20168   if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
20169       DepKind != OMPC_DEPEND_outallmemory &&
20170       DepKind != OMPC_DEPEND_inoutallmemory && Vars.empty())
20171     return nullptr;
20172 
20173   auto *C = OMPDependClause::Create(
20174       getASTContext(), StartLoc, LParenLoc, EndLoc,
20175       {DepKind, DepLoc, Data.ColonLoc, Data.OmpAllMemoryLoc}, DepModifier, Vars,
20176       TotalDepCount.getZExtValue());
20177   if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
20178       DSAStack->isParentOrderedRegion())
20179     DSAStack->addDoacrossDependClause(C, OpsOffs);
20180   return C;
20181 }
20182 
20183 OMPClause *SemaOpenMP::ActOnOpenMPDeviceClause(
20184     OpenMPDeviceClauseModifier Modifier, Expr *Device, SourceLocation StartLoc,
20185     SourceLocation LParenLoc, SourceLocation ModifierLoc,
20186     SourceLocation EndLoc) {
20187   assert((ModifierLoc.isInvalid() || getLangOpts().OpenMP >= 50) &&
20188          "Unexpected device modifier in OpenMP < 50.");
20189 
20190   bool ErrorFound = false;
20191   if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) {
20192     std::string Values =
20193         getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown);
20194     Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
20195         << Values << getOpenMPClauseName(OMPC_device);
20196     ErrorFound = true;
20197   }
20198 
20199   Expr *ValExpr = Device;
20200   Stmt *HelperValStmt = nullptr;
20201 
20202   // OpenMP [2.9.1, Restrictions]
20203   // The device expression must evaluate to a non-negative integer value.
20204   ErrorFound = !isNonNegativeIntegerValue(ValExpr, SemaRef, OMPC_device,
20205                                           /*StrictlyPositive=*/false) ||
20206                ErrorFound;
20207   if (ErrorFound)
20208     return nullptr;
20209 
20210   // OpenMP 5.0 [2.12.5, Restrictions]
20211   // In case of ancestor device-modifier, a requires directive with
20212   // the reverse_offload clause must be specified.
20213   if (Modifier == OMPC_DEVICE_ancestor) {
20214     if (!DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>()) {
20215       SemaRef.targetDiag(
20216           StartLoc,
20217           diag::err_omp_device_ancestor_without_requires_reverse_offload);
20218       ErrorFound = true;
20219     }
20220   }
20221 
20222   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
20223   OpenMPDirectiveKind CaptureRegion =
20224       getOpenMPCaptureRegionForClause(DKind, OMPC_device, getLangOpts().OpenMP);
20225   if (CaptureRegion != OMPD_unknown &&
20226       !SemaRef.CurContext->isDependentContext()) {
20227     ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
20228     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
20229     ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
20230     HelperValStmt = buildPreInits(getASTContext(), Captures);
20231   }
20232 
20233   return new (getASTContext())
20234       OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
20235                       LParenLoc, ModifierLoc, EndLoc);
20236 }
20237 
20238 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
20239                               DSAStackTy *Stack, QualType QTy,
20240                               bool FullCheck = true) {
20241   if (SemaRef.RequireCompleteType(SL, QTy, diag::err_incomplete_type))
20242     return false;
20243   if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
20244       !QTy.isTriviallyCopyableType(SemaRef.Context))
20245     SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
20246   return true;
20247 }
20248 
20249 /// Return true if it can be proven that the provided array expression
20250 /// (array section or array subscript) does NOT specify the whole size of the
20251 /// array whose base type is \a BaseQTy.
20252 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
20253                                                         const Expr *E,
20254                                                         QualType BaseQTy) {
20255   const auto *OASE = dyn_cast<ArraySectionExpr>(E);
20256 
20257   // If this is an array subscript, it refers to the whole size if the size of
20258   // the dimension is constant and equals 1. Also, an array section assumes the
20259   // format of an array subscript if no colon is used.
20260   if (isa<ArraySubscriptExpr>(E) ||
20261       (OASE && OASE->getColonLocFirst().isInvalid())) {
20262     if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
20263       return ATy->getSExtSize() != 1;
20264     // Size can't be evaluated statically.
20265     return false;
20266   }
20267 
20268   assert(OASE && "Expecting array section if not an array subscript.");
20269   const Expr *LowerBound = OASE->getLowerBound();
20270   const Expr *Length = OASE->getLength();
20271 
20272   // If there is a lower bound that does not evaluates to zero, we are not
20273   // covering the whole dimension.
20274   if (LowerBound) {
20275     Expr::EvalResult Result;
20276     if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
20277       return false; // Can't get the integer value as a constant.
20278 
20279     llvm::APSInt ConstLowerBound = Result.Val.getInt();
20280     if (ConstLowerBound.getSExtValue())
20281       return true;
20282   }
20283 
20284   // If we don't have a length we covering the whole dimension.
20285   if (!Length)
20286     return false;
20287 
20288   // If the base is a pointer, we don't have a way to get the size of the
20289   // pointee.
20290   if (BaseQTy->isPointerType())
20291     return false;
20292 
20293   // We can only check if the length is the same as the size of the dimension
20294   // if we have a constant array.
20295   const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
20296   if (!CATy)
20297     return false;
20298 
20299   Expr::EvalResult Result;
20300   if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
20301     return false; // Can't get the integer value as a constant.
20302 
20303   llvm::APSInt ConstLength = Result.Val.getInt();
20304   return CATy->getSExtSize() != ConstLength.getSExtValue();
20305 }
20306 
20307 // Return true if it can be proven that the provided array expression (array
20308 // section or array subscript) does NOT specify a single element of the array
20309 // whose base type is \a BaseQTy.
20310 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
20311                                                         const Expr *E,
20312                                                         QualType BaseQTy) {
20313   const auto *OASE = dyn_cast<ArraySectionExpr>(E);
20314 
20315   // An array subscript always refer to a single element. Also, an array section
20316   // assumes the format of an array subscript if no colon is used.
20317   if (isa<ArraySubscriptExpr>(E) ||
20318       (OASE && OASE->getColonLocFirst().isInvalid()))
20319     return false;
20320 
20321   assert(OASE && "Expecting array section if not an array subscript.");
20322   const Expr *Length = OASE->getLength();
20323 
20324   // If we don't have a length we have to check if the array has unitary size
20325   // for this dimension. Also, we should always expect a length if the base type
20326   // is pointer.
20327   if (!Length) {
20328     if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
20329       return ATy->getSExtSize() != 1;
20330     // We cannot assume anything.
20331     return false;
20332   }
20333 
20334   // Check if the length evaluates to 1.
20335   Expr::EvalResult Result;
20336   if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
20337     return false; // Can't get the integer value as a constant.
20338 
20339   llvm::APSInt ConstLength = Result.Val.getInt();
20340   return ConstLength.getSExtValue() != 1;
20341 }
20342 
20343 // The base of elements of list in a map clause have to be either:
20344 //  - a reference to variable or field.
20345 //  - a member expression.
20346 //  - an array expression.
20347 //
20348 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
20349 // reference to 'r'.
20350 //
20351 // If we have:
20352 //
20353 // struct SS {
20354 //   Bla S;
20355 //   foo() {
20356 //     #pragma omp target map (S.Arr[:12]);
20357 //   }
20358 // }
20359 //
20360 // We want to retrieve the member expression 'this->S';
20361 
20362 // OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2]
20363 //  If a list item is an array section, it must specify contiguous storage.
20364 //
20365 // For this restriction it is sufficient that we make sure only references
20366 // to variables or fields and array expressions, and that no array sections
20367 // exist except in the rightmost expression (unless they cover the whole
20368 // dimension of the array). E.g. these would be invalid:
20369 //
20370 //   r.ArrS[3:5].Arr[6:7]
20371 //
20372 //   r.ArrS[3:5].x
20373 //
20374 // but these would be valid:
20375 //   r.ArrS[3].Arr[6:7]
20376 //
20377 //   r.ArrS[3].x
20378 namespace {
20379 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> {
20380   Sema &SemaRef;
20381   OpenMPClauseKind CKind = OMPC_unknown;
20382   OpenMPDirectiveKind DKind = OMPD_unknown;
20383   OMPClauseMappableExprCommon::MappableExprComponentList &Components;
20384   bool IsNonContiguous = false;
20385   bool NoDiagnose = false;
20386   const Expr *RelevantExpr = nullptr;
20387   bool AllowUnitySizeArraySection = true;
20388   bool AllowWholeSizeArraySection = true;
20389   bool AllowAnotherPtr = true;
20390   SourceLocation ELoc;
20391   SourceRange ERange;
20392 
20393   void emitErrorMsg() {
20394     // If nothing else worked, this is not a valid map clause expression.
20395     if (SemaRef.getLangOpts().OpenMP < 50) {
20396       SemaRef.Diag(ELoc,
20397                    diag::err_omp_expected_named_var_member_or_array_expression)
20398           << ERange;
20399     } else {
20400       SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
20401           << getOpenMPClauseName(CKind) << ERange;
20402     }
20403   }
20404 
20405 public:
20406   bool VisitDeclRefExpr(DeclRefExpr *DRE) {
20407     if (!isa<VarDecl>(DRE->getDecl())) {
20408       emitErrorMsg();
20409       return false;
20410     }
20411     assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
20412     RelevantExpr = DRE;
20413     // Record the component.
20414     Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous);
20415     return true;
20416   }
20417 
20418   bool VisitMemberExpr(MemberExpr *ME) {
20419     Expr *E = ME;
20420     Expr *BaseE = ME->getBase()->IgnoreParenCasts();
20421 
20422     if (isa<CXXThisExpr>(BaseE)) {
20423       assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
20424       // We found a base expression: this->Val.
20425       RelevantExpr = ME;
20426     } else {
20427       E = BaseE;
20428     }
20429 
20430     if (!isa<FieldDecl>(ME->getMemberDecl())) {
20431       if (!NoDiagnose) {
20432         SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
20433             << ME->getSourceRange();
20434         return false;
20435       }
20436       if (RelevantExpr)
20437         return false;
20438       return Visit(E);
20439     }
20440 
20441     auto *FD = cast<FieldDecl>(ME->getMemberDecl());
20442 
20443     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
20444     //  A bit-field cannot appear in a map clause.
20445     //
20446     if (FD->isBitField()) {
20447       if (!NoDiagnose) {
20448         SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
20449             << ME->getSourceRange() << getOpenMPClauseName(CKind);
20450         return false;
20451       }
20452       if (RelevantExpr)
20453         return false;
20454       return Visit(E);
20455     }
20456 
20457     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
20458     //  If the type of a list item is a reference to a type T then the type
20459     //  will be considered to be T for all purposes of this clause.
20460     QualType CurType = BaseE->getType().getNonReferenceType();
20461 
20462     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
20463     //  A list item cannot be a variable that is a member of a structure with
20464     //  a union type.
20465     //
20466     if (CurType->isUnionType()) {
20467       if (!NoDiagnose) {
20468         SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
20469             << ME->getSourceRange();
20470         return false;
20471       }
20472       return RelevantExpr || Visit(E);
20473     }
20474 
20475     // If we got a member expression, we should not expect any array section
20476     // before that:
20477     //
20478     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
20479     //  If a list item is an element of a structure, only the rightmost symbol
20480     //  of the variable reference can be an array section.
20481     //
20482     AllowUnitySizeArraySection = false;
20483     AllowWholeSizeArraySection = false;
20484 
20485     // Record the component.
20486     Components.emplace_back(ME, FD, IsNonContiguous);
20487     return RelevantExpr || Visit(E);
20488   }
20489 
20490   bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) {
20491     Expr *E = AE->getBase()->IgnoreParenImpCasts();
20492 
20493     if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
20494       if (!NoDiagnose) {
20495         SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
20496             << 0 << AE->getSourceRange();
20497         return false;
20498       }
20499       return RelevantExpr || Visit(E);
20500     }
20501 
20502     // If we got an array subscript that express the whole dimension we
20503     // can have any array expressions before. If it only expressing part of
20504     // the dimension, we can only have unitary-size array expressions.
20505     if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, E->getType()))
20506       AllowWholeSizeArraySection = false;
20507 
20508     if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) {
20509       Expr::EvalResult Result;
20510       if (!AE->getIdx()->isValueDependent() &&
20511           AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) &&
20512           !Result.Val.getInt().isZero()) {
20513         SemaRef.Diag(AE->getIdx()->getExprLoc(),
20514                      diag::err_omp_invalid_map_this_expr);
20515         SemaRef.Diag(AE->getIdx()->getExprLoc(),
20516                      diag::note_omp_invalid_subscript_on_this_ptr_map);
20517       }
20518       assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
20519       RelevantExpr = TE;
20520     }
20521 
20522     // Record the component - we don't have any declaration associated.
20523     Components.emplace_back(AE, nullptr, IsNonContiguous);
20524 
20525     return RelevantExpr || Visit(E);
20526   }
20527 
20528   bool VisitArraySectionExpr(ArraySectionExpr *OASE) {
20529     // After OMP 5.0  Array section in reduction clause will be implicitly
20530     // mapped
20531     assert(!(SemaRef.getLangOpts().OpenMP < 50 && NoDiagnose) &&
20532            "Array sections cannot be implicitly mapped.");
20533     Expr *E = OASE->getBase()->IgnoreParenImpCasts();
20534     QualType CurType =
20535         ArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
20536 
20537     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
20538     //  If the type of a list item is a reference to a type T then the type
20539     //  will be considered to be T for all purposes of this clause.
20540     if (CurType->isReferenceType())
20541       CurType = CurType->getPointeeType();
20542 
20543     bool IsPointer = CurType->isAnyPointerType();
20544 
20545     if (!IsPointer && !CurType->isArrayType()) {
20546       SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
20547           << 0 << OASE->getSourceRange();
20548       return false;
20549     }
20550 
20551     bool NotWhole =
20552         checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType);
20553     bool NotUnity =
20554         checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType);
20555 
20556     if (AllowWholeSizeArraySection) {
20557       // Any array section is currently allowed. Allowing a whole size array
20558       // section implies allowing a unity array section as well.
20559       //
20560       // If this array section refers to the whole dimension we can still
20561       // accept other array sections before this one, except if the base is a
20562       // pointer. Otherwise, only unitary sections are accepted.
20563       if (NotWhole || IsPointer)
20564         AllowWholeSizeArraySection = false;
20565     } else if (DKind == OMPD_target_update &&
20566                SemaRef.getLangOpts().OpenMP >= 50) {
20567       if (IsPointer && !AllowAnotherPtr)
20568         SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined)
20569             << /*array of unknown bound */ 1;
20570       else
20571         IsNonContiguous = true;
20572     } else if (AllowUnitySizeArraySection && NotUnity) {
20573       // A unity or whole array section is not allowed and that is not
20574       // compatible with the properties of the current array section.
20575       if (NoDiagnose)
20576         return false;
20577       SemaRef.Diag(ELoc,
20578                    diag::err_array_section_does_not_specify_contiguous_storage)
20579           << OASE->getSourceRange();
20580       return false;
20581     }
20582 
20583     if (IsPointer)
20584       AllowAnotherPtr = false;
20585 
20586     if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
20587       Expr::EvalResult ResultR;
20588       Expr::EvalResult ResultL;
20589       if (!OASE->getLength()->isValueDependent() &&
20590           OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) &&
20591           !ResultR.Val.getInt().isOne()) {
20592         SemaRef.Diag(OASE->getLength()->getExprLoc(),
20593                      diag::err_omp_invalid_map_this_expr);
20594         SemaRef.Diag(OASE->getLength()->getExprLoc(),
20595                      diag::note_omp_invalid_length_on_this_ptr_mapping);
20596       }
20597       if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() &&
20598           OASE->getLowerBound()->EvaluateAsInt(ResultL,
20599                                                SemaRef.getASTContext()) &&
20600           !ResultL.Val.getInt().isZero()) {
20601         SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
20602                      diag::err_omp_invalid_map_this_expr);
20603         SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
20604                      diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
20605       }
20606       assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
20607       RelevantExpr = TE;
20608     }
20609 
20610     // Record the component - we don't have any declaration associated.
20611     Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false);
20612     return RelevantExpr || Visit(E);
20613   }
20614   bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
20615     Expr *Base = E->getBase();
20616 
20617     // Record the component - we don't have any declaration associated.
20618     Components.emplace_back(E, nullptr, IsNonContiguous);
20619 
20620     return Visit(Base->IgnoreParenImpCasts());
20621   }
20622 
20623   bool VisitUnaryOperator(UnaryOperator *UO) {
20624     if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() ||
20625         UO->getOpcode() != UO_Deref) {
20626       emitErrorMsg();
20627       return false;
20628     }
20629     if (!RelevantExpr) {
20630       // Record the component if haven't found base decl.
20631       Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false);
20632     }
20633     return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts());
20634   }
20635   bool VisitBinaryOperator(BinaryOperator *BO) {
20636     if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) {
20637       emitErrorMsg();
20638       return false;
20639     }
20640 
20641     // Pointer arithmetic is the only thing we expect to happen here so after we
20642     // make sure the binary operator is a pointer type, the only thing we need
20643     // to do is to visit the subtree that has the same type as root (so that we
20644     // know the other subtree is just an offset)
20645     Expr *LE = BO->getLHS()->IgnoreParenImpCasts();
20646     Expr *RE = BO->getRHS()->IgnoreParenImpCasts();
20647     Components.emplace_back(BO, nullptr, false);
20648     assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() ||
20649             RE->getType().getTypePtr() == BO->getType().getTypePtr()) &&
20650            "Either LHS or RHS have base decl inside");
20651     if (BO->getType().getTypePtr() == LE->getType().getTypePtr())
20652       return RelevantExpr || Visit(LE);
20653     return RelevantExpr || Visit(RE);
20654   }
20655   bool VisitCXXThisExpr(CXXThisExpr *CTE) {
20656     assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
20657     RelevantExpr = CTE;
20658     Components.emplace_back(CTE, nullptr, IsNonContiguous);
20659     return true;
20660   }
20661   bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) {
20662     assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
20663     Components.emplace_back(COCE, nullptr, IsNonContiguous);
20664     return true;
20665   }
20666   bool VisitOpaqueValueExpr(OpaqueValueExpr *E) {
20667     Expr *Source = E->getSourceExpr();
20668     if (!Source) {
20669       emitErrorMsg();
20670       return false;
20671     }
20672     return Visit(Source);
20673   }
20674   bool VisitStmt(Stmt *) {
20675     emitErrorMsg();
20676     return false;
20677   }
20678   const Expr *getFoundBase() const { return RelevantExpr; }
20679   explicit MapBaseChecker(
20680       Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind,
20681       OMPClauseMappableExprCommon::MappableExprComponentList &Components,
20682       bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange)
20683       : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components),
20684         NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
20685 };
20686 } // namespace
20687 
20688 /// Return the expression of the base of the mappable expression or null if it
20689 /// cannot be determined and do all the necessary checks to see if the
20690 /// expression is valid as a standalone mappable expression. In the process,
20691 /// record all the components of the expression.
20692 static const Expr *checkMapClauseExpressionBase(
20693     Sema &SemaRef, Expr *E,
20694     OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
20695     OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) {
20696   SourceLocation ELoc = E->getExprLoc();
20697   SourceRange ERange = E->getSourceRange();
20698   MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc,
20699                          ERange);
20700   if (Checker.Visit(E->IgnoreParens())) {
20701     // Check if the highest dimension array section has length specified
20702     if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() &&
20703         (CKind == OMPC_to || CKind == OMPC_from)) {
20704       auto CI = CurComponents.rbegin();
20705       auto CE = CurComponents.rend();
20706       for (; CI != CE; ++CI) {
20707         const auto *OASE =
20708             dyn_cast<ArraySectionExpr>(CI->getAssociatedExpression());
20709         if (!OASE)
20710           continue;
20711         if (OASE && OASE->getLength())
20712           break;
20713         SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length)
20714             << ERange;
20715       }
20716     }
20717     return Checker.getFoundBase();
20718   }
20719   return nullptr;
20720 }
20721 
20722 // Return true if expression E associated with value VD has conflicts with other
20723 // map information.
20724 static bool checkMapConflicts(
20725     Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
20726     bool CurrentRegionOnly,
20727     OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
20728     OpenMPClauseKind CKind) {
20729   assert(VD && E);
20730   SourceLocation ELoc = E->getExprLoc();
20731   SourceRange ERange = E->getSourceRange();
20732 
20733   // In order to easily check the conflicts we need to match each component of
20734   // the expression under test with the components of the expressions that are
20735   // already in the stack.
20736 
20737   assert(!CurComponents.empty() && "Map clause expression with no components!");
20738   assert(CurComponents.back().getAssociatedDeclaration() == VD &&
20739          "Map clause expression with unexpected base!");
20740 
20741   // Variables to help detecting enclosing problems in data environment nests.
20742   bool IsEnclosedByDataEnvironmentExpr = false;
20743   const Expr *EnclosingExpr = nullptr;
20744 
20745   bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
20746       VD, CurrentRegionOnly,
20747       [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
20748        ERange, CKind, &EnclosingExpr,
20749        CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef
20750                           StackComponents,
20751                       OpenMPClauseKind Kind) {
20752         if (CKind == Kind && SemaRef.LangOpts.OpenMP >= 50)
20753           return false;
20754         assert(!StackComponents.empty() &&
20755                "Map clause expression with no components!");
20756         assert(StackComponents.back().getAssociatedDeclaration() == VD &&
20757                "Map clause expression with unexpected base!");
20758         (void)VD;
20759 
20760         // The whole expression in the stack.
20761         const Expr *RE = StackComponents.front().getAssociatedExpression();
20762 
20763         // Expressions must start from the same base. Here we detect at which
20764         // point both expressions diverge from each other and see if we can
20765         // detect if the memory referred to both expressions is contiguous and
20766         // do not overlap.
20767         auto CI = CurComponents.rbegin();
20768         auto CE = CurComponents.rend();
20769         auto SI = StackComponents.rbegin();
20770         auto SE = StackComponents.rend();
20771         for (; CI != CE && SI != SE; ++CI, ++SI) {
20772 
20773           // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
20774           //  At most one list item can be an array item derived from a given
20775           //  variable in map clauses of the same construct.
20776           if (CurrentRegionOnly &&
20777               (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
20778                isa<ArraySectionExpr>(CI->getAssociatedExpression()) ||
20779                isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) &&
20780               (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
20781                isa<ArraySectionExpr>(SI->getAssociatedExpression()) ||
20782                isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) {
20783             SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
20784                          diag::err_omp_multiple_array_items_in_map_clause)
20785                 << CI->getAssociatedExpression()->getSourceRange();
20786             SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
20787                          diag::note_used_here)
20788                 << SI->getAssociatedExpression()->getSourceRange();
20789             return true;
20790           }
20791 
20792           // Do both expressions have the same kind?
20793           if (CI->getAssociatedExpression()->getStmtClass() !=
20794               SI->getAssociatedExpression()->getStmtClass())
20795             break;
20796 
20797           // Are we dealing with different variables/fields?
20798           if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
20799             break;
20800         }
20801         // Check if the extra components of the expressions in the enclosing
20802         // data environment are redundant for the current base declaration.
20803         // If they are, the maps completely overlap, which is legal.
20804         for (; SI != SE; ++SI) {
20805           QualType Type;
20806           if (const auto *ASE =
20807                   dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
20808             Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
20809           } else if (const auto *OASE = dyn_cast<ArraySectionExpr>(
20810                          SI->getAssociatedExpression())) {
20811             const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
20812             Type = ArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
20813           } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>(
20814                          SI->getAssociatedExpression())) {
20815             Type = OASE->getBase()->getType()->getPointeeType();
20816           }
20817           if (Type.isNull() || Type->isAnyPointerType() ||
20818               checkArrayExpressionDoesNotReferToWholeSize(
20819                   SemaRef, SI->getAssociatedExpression(), Type))
20820             break;
20821         }
20822 
20823         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
20824         //  List items of map clauses in the same construct must not share
20825         //  original storage.
20826         //
20827         // If the expressions are exactly the same or one is a subset of the
20828         // other, it means they are sharing storage.
20829         if (CI == CE && SI == SE) {
20830           if (CurrentRegionOnly) {
20831             if (CKind == OMPC_map) {
20832               SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
20833             } else {
20834               assert(CKind == OMPC_to || CKind == OMPC_from);
20835               SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
20836                   << ERange;
20837             }
20838             SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
20839                 << RE->getSourceRange();
20840             return true;
20841           }
20842           // If we find the same expression in the enclosing data environment,
20843           // that is legal.
20844           IsEnclosedByDataEnvironmentExpr = true;
20845           return false;
20846         }
20847 
20848         QualType DerivedType =
20849             std::prev(CI)->getAssociatedDeclaration()->getType();
20850         SourceLocation DerivedLoc =
20851             std::prev(CI)->getAssociatedExpression()->getExprLoc();
20852 
20853         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
20854         //  If the type of a list item is a reference to a type T then the type
20855         //  will be considered to be T for all purposes of this clause.
20856         DerivedType = DerivedType.getNonReferenceType();
20857 
20858         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
20859         //  A variable for which the type is pointer and an array section
20860         //  derived from that variable must not appear as list items of map
20861         //  clauses of the same construct.
20862         //
20863         // Also, cover one of the cases in:
20864         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
20865         //  If any part of the original storage of a list item has corresponding
20866         //  storage in the device data environment, all of the original storage
20867         //  must have corresponding storage in the device data environment.
20868         //
20869         if (DerivedType->isAnyPointerType()) {
20870           if (CI == CE || SI == SE) {
20871             SemaRef.Diag(
20872                 DerivedLoc,
20873                 diag::err_omp_pointer_mapped_along_with_derived_section)
20874                 << DerivedLoc;
20875             SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
20876                 << RE->getSourceRange();
20877             return true;
20878           }
20879           if (CI->getAssociatedExpression()->getStmtClass() !=
20880                   SI->getAssociatedExpression()->getStmtClass() ||
20881               CI->getAssociatedDeclaration()->getCanonicalDecl() ==
20882                   SI->getAssociatedDeclaration()->getCanonicalDecl()) {
20883             assert(CI != CE && SI != SE);
20884             SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
20885                 << DerivedLoc;
20886             SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
20887                 << RE->getSourceRange();
20888             return true;
20889           }
20890         }
20891 
20892         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
20893         //  List items of map clauses in the same construct must not share
20894         //  original storage.
20895         //
20896         // An expression is a subset of the other.
20897         if (CurrentRegionOnly && (CI == CE || SI == SE)) {
20898           if (CKind == OMPC_map) {
20899             if (CI != CE || SI != SE) {
20900               // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
20901               // a pointer.
20902               auto Begin =
20903                   CI != CE ? CurComponents.begin() : StackComponents.begin();
20904               auto End = CI != CE ? CurComponents.end() : StackComponents.end();
20905               auto It = Begin;
20906               while (It != End && !It->getAssociatedDeclaration())
20907                 std::advance(It, 1);
20908               assert(It != End &&
20909                      "Expected at least one component with the declaration.");
20910               if (It != Begin && It->getAssociatedDeclaration()
20911                                      ->getType()
20912                                      .getCanonicalType()
20913                                      ->isAnyPointerType()) {
20914                 IsEnclosedByDataEnvironmentExpr = false;
20915                 EnclosingExpr = nullptr;
20916                 return false;
20917               }
20918             }
20919             SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
20920           } else {
20921             assert(CKind == OMPC_to || CKind == OMPC_from);
20922             SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
20923                 << ERange;
20924           }
20925           SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
20926               << RE->getSourceRange();
20927           return true;
20928         }
20929 
20930         // The current expression uses the same base as other expression in the
20931         // data environment but does not contain it completely.
20932         if (!CurrentRegionOnly && SI != SE)
20933           EnclosingExpr = RE;
20934 
20935         // The current expression is a subset of the expression in the data
20936         // environment.
20937         IsEnclosedByDataEnvironmentExpr |=
20938             (!CurrentRegionOnly && CI != CE && SI == SE);
20939 
20940         return false;
20941       });
20942 
20943   if (CurrentRegionOnly)
20944     return FoundError;
20945 
20946   // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
20947   //  If any part of the original storage of a list item has corresponding
20948   //  storage in the device data environment, all of the original storage must
20949   //  have corresponding storage in the device data environment.
20950   // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
20951   //  If a list item is an element of a structure, and a different element of
20952   //  the structure has a corresponding list item in the device data environment
20953   //  prior to a task encountering the construct associated with the map clause,
20954   //  then the list item must also have a corresponding list item in the device
20955   //  data environment prior to the task encountering the construct.
20956   //
20957   if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
20958     SemaRef.Diag(ELoc,
20959                  diag::err_omp_original_storage_is_shared_and_does_not_contain)
20960         << ERange;
20961     SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
20962         << EnclosingExpr->getSourceRange();
20963     return true;
20964   }
20965 
20966   return FoundError;
20967 }
20968 
20969 // Look up the user-defined mapper given the mapper name and mapped type, and
20970 // build a reference to it.
20971 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
20972                                             CXXScopeSpec &MapperIdScopeSpec,
20973                                             const DeclarationNameInfo &MapperId,
20974                                             QualType Type,
20975                                             Expr *UnresolvedMapper) {
20976   if (MapperIdScopeSpec.isInvalid())
20977     return ExprError();
20978   // Get the actual type for the array type.
20979   if (Type->isArrayType()) {
20980     assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type");
20981     Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType();
20982   }
20983   // Find all user-defined mappers with the given MapperId.
20984   SmallVector<UnresolvedSet<8>, 4> Lookups;
20985   LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
20986   Lookup.suppressDiagnostics();
20987   if (S) {
20988     while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec,
20989                                          /*ObjectType=*/QualType())) {
20990       NamedDecl *D = Lookup.getRepresentativeDecl();
20991       while (S && !S->isDeclScope(D))
20992         S = S->getParent();
20993       if (S)
20994         S = S->getParent();
20995       Lookups.emplace_back();
20996       Lookups.back().append(Lookup.begin(), Lookup.end());
20997       Lookup.clear();
20998     }
20999   } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
21000     // Extract the user-defined mappers with the given MapperId.
21001     Lookups.push_back(UnresolvedSet<8>());
21002     for (NamedDecl *D : ULE->decls()) {
21003       auto *DMD = cast<OMPDeclareMapperDecl>(D);
21004       assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation.");
21005       Lookups.back().addDecl(DMD);
21006     }
21007   }
21008   // Defer the lookup for dependent types. The results will be passed through
21009   // UnresolvedMapper on instantiation.
21010   if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
21011       Type->isInstantiationDependentType() ||
21012       Type->containsUnexpandedParameterPack() ||
21013       filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
21014         return !D->isInvalidDecl() &&
21015                (D->getType()->isDependentType() ||
21016                 D->getType()->isInstantiationDependentType() ||
21017                 D->getType()->containsUnexpandedParameterPack());
21018       })) {
21019     UnresolvedSet<8> URS;
21020     for (const UnresolvedSet<8> &Set : Lookups) {
21021       if (Set.empty())
21022         continue;
21023       URS.append(Set.begin(), Set.end());
21024     }
21025     return UnresolvedLookupExpr::Create(
21026         SemaRef.Context, /*NamingClass=*/nullptr,
21027         MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
21028         /*ADL=*/false, URS.begin(), URS.end(), /*KnownDependent=*/false,
21029         /*KnownInstantiationDependent=*/false);
21030   }
21031   SourceLocation Loc = MapperId.getLoc();
21032   // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
21033   //  The type must be of struct, union or class type in C and C++
21034   if (!Type->isStructureOrClassType() && !Type->isUnionType() &&
21035       (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) {
21036     SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type);
21037     return ExprError();
21038   }
21039   // Perform argument dependent lookup.
21040   if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
21041     argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
21042   // Return the first user-defined mapper with the desired type.
21043   if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
21044           Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
21045             if (!D->isInvalidDecl() &&
21046                 SemaRef.Context.hasSameType(D->getType(), Type))
21047               return D;
21048             return nullptr;
21049           }))
21050     return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
21051   // Find the first user-defined mapper with a type derived from the desired
21052   // type.
21053   if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
21054           Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
21055             if (!D->isInvalidDecl() &&
21056                 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
21057                 !Type.isMoreQualifiedThan(D->getType(),
21058                                           SemaRef.getASTContext()))
21059               return D;
21060             return nullptr;
21061           })) {
21062     CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
21063                        /*DetectVirtual=*/false);
21064     if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
21065       if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
21066               VD->getType().getUnqualifiedType()))) {
21067         if (SemaRef.CheckBaseClassAccess(
21068                 Loc, VD->getType(), Type, Paths.front(),
21069                 /*DiagID=*/0) != Sema::AR_inaccessible) {
21070           return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
21071         }
21072       }
21073     }
21074   }
21075   // Report error if a mapper is specified, but cannot be found.
21076   if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
21077     SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
21078         << Type << MapperId.getName();
21079     return ExprError();
21080   }
21081   return ExprEmpty();
21082 }
21083 
21084 namespace {
21085 // Utility struct that gathers all the related lists associated with a mappable
21086 // expression.
21087 struct MappableVarListInfo {
21088   // The list of expressions.
21089   ArrayRef<Expr *> VarList;
21090   // The list of processed expressions.
21091   SmallVector<Expr *, 16> ProcessedVarList;
21092   // The mappble components for each expression.
21093   OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
21094   // The base declaration of the variable.
21095   SmallVector<ValueDecl *, 16> VarBaseDeclarations;
21096   // The reference to the user-defined mapper associated with every expression.
21097   SmallVector<Expr *, 16> UDMapperList;
21098 
21099   MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
21100     // We have a list of components and base declarations for each entry in the
21101     // variable list.
21102     VarComponents.reserve(VarList.size());
21103     VarBaseDeclarations.reserve(VarList.size());
21104   }
21105 };
21106 } // namespace
21107 
21108 static DeclRefExpr *buildImplicitMap(Sema &S, QualType BaseType,
21109                                      DSAStackTy *Stack,
21110                                      SmallVectorImpl<OMPClause *> &Maps) {
21111 
21112   const RecordDecl *RD = BaseType->getAsRecordDecl();
21113   SourceRange Range = RD->getSourceRange();
21114   DeclarationNameInfo ImplicitName;
21115   // Dummy variable _s for Mapper.
21116   VarDecl *VD = buildVarDecl(S, Range.getEnd(), BaseType, "_s");
21117   DeclRefExpr *MapperVarRef =
21118       buildDeclRefExpr(S, VD, BaseType, SourceLocation());
21119 
21120   // Create implicit map clause for mapper.
21121   SmallVector<Expr *, 4> SExprs;
21122   for (auto *FD : RD->fields()) {
21123     Expr *BE = S.BuildMemberExpr(
21124         MapperVarRef, /*IsArrow=*/false, Range.getBegin(),
21125         NestedNameSpecifierLoc(), Range.getBegin(), FD,
21126         DeclAccessPair::make(FD, FD->getAccess()),
21127         /*HadMultipleCandidates=*/false,
21128         DeclarationNameInfo(FD->getDeclName(), FD->getSourceRange().getBegin()),
21129         FD->getType(), VK_LValue, OK_Ordinary);
21130     SExprs.push_back(BE);
21131   }
21132   CXXScopeSpec MapperIdScopeSpec;
21133   DeclarationNameInfo MapperId;
21134   OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
21135 
21136   OMPClause *MapClause = S.OpenMP().ActOnOpenMPMapClause(
21137       nullptr, OMPC_MAP_MODIFIER_unknown, SourceLocation(), MapperIdScopeSpec,
21138       MapperId, DKind == OMPD_target_enter_data ? OMPC_MAP_to : OMPC_MAP_tofrom,
21139       /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), SExprs,
21140       OMPVarListLocTy());
21141   Maps.push_back(MapClause);
21142   return MapperVarRef;
21143 }
21144 
21145 static ExprResult buildImplicitMapper(Sema &S, QualType BaseType,
21146                                       DSAStackTy *Stack) {
21147 
21148   // Build impilicit map for mapper
21149   SmallVector<OMPClause *, 4> Maps;
21150   DeclRefExpr *MapperVarRef = buildImplicitMap(S, BaseType, Stack, Maps);
21151 
21152   const RecordDecl *RD = BaseType->getAsRecordDecl();
21153   // AST context is RD's ParentASTContext().
21154   ASTContext &Ctx = RD->getParentASTContext();
21155   // DeclContext is RD's DeclContext.
21156   DeclContext *DCT = const_cast<DeclContext *>(RD->getDeclContext());
21157 
21158   // Create implicit default mapper for "RD".
21159   DeclarationName MapperId;
21160   auto &DeclNames = Ctx.DeclarationNames;
21161   MapperId = DeclNames.getIdentifier(&Ctx.Idents.get("default"));
21162   auto *DMD = OMPDeclareMapperDecl::Create(Ctx, DCT, SourceLocation(), MapperId,
21163                                            BaseType, MapperId, Maps, nullptr);
21164   Scope *Scope = S.getScopeForContext(DCT);
21165   if (Scope)
21166     S.PushOnScopeChains(DMD, Scope, /*AddToContext=*/false);
21167   DCT->addDecl(DMD);
21168   DMD->setAccess(clang::AS_none);
21169   auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl();
21170   VD->setDeclContext(DMD);
21171   VD->setLexicalDeclContext(DMD);
21172   DMD->addDecl(VD);
21173   DMD->setMapperVarRef(MapperVarRef);
21174   FieldDecl *FD = *RD->field_begin();
21175   // create mapper refence.
21176   return DeclRefExpr::Create(Ctx, NestedNameSpecifierLoc{}, FD->getLocation(),
21177                              DMD, false, SourceLocation(), BaseType, VK_LValue);
21178 }
21179 
21180 // Look up the user-defined mapper given the mapper name and mapper type,
21181 // return true if found one.
21182 static bool hasUserDefinedMapper(Sema &SemaRef, Scope *S,
21183                                  CXXScopeSpec &MapperIdScopeSpec,
21184                                  const DeclarationNameInfo &MapperId,
21185                                  QualType Type) {
21186   // Find all user-defined mappers with the given MapperId.
21187   SmallVector<UnresolvedSet<8>, 4> Lookups;
21188   LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
21189   Lookup.suppressDiagnostics();
21190   while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec,
21191                                        /*ObjectType=*/QualType())) {
21192     NamedDecl *D = Lookup.getRepresentativeDecl();
21193     while (S && !S->isDeclScope(D))
21194       S = S->getParent();
21195     if (S)
21196       S = S->getParent();
21197     Lookups.emplace_back();
21198     Lookups.back().append(Lookup.begin(), Lookup.end());
21199     Lookup.clear();
21200   }
21201   if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
21202       Type->isInstantiationDependentType() ||
21203       Type->containsUnexpandedParameterPack() ||
21204       filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
21205         return !D->isInvalidDecl() &&
21206                (D->getType()->isDependentType() ||
21207                 D->getType()->isInstantiationDependentType() ||
21208                 D->getType()->containsUnexpandedParameterPack());
21209       }))
21210     return false;
21211   // Perform argument dependent lookup.
21212   SourceLocation Loc = MapperId.getLoc();
21213   if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
21214     argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
21215   if (filterLookupForUDReductionAndMapper<ValueDecl *>(
21216           Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
21217             if (!D->isInvalidDecl() &&
21218                 SemaRef.Context.hasSameType(D->getType(), Type))
21219               return D;
21220             return nullptr;
21221           }))
21222     return true;
21223   // Find the first user-defined mapper with a type derived from the desired
21224   // type.
21225   auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
21226       Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
21227         if (!D->isInvalidDecl() &&
21228             SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
21229             !Type.isMoreQualifiedThan(D->getType(), SemaRef.getASTContext()))
21230           return D;
21231         return nullptr;
21232       });
21233   if (!VD)
21234     return false;
21235   CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
21236                      /*DetectVirtual=*/false);
21237   if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
21238     bool IsAmbiguous = !Paths.isAmbiguous(
21239         SemaRef.Context.getCanonicalType(VD->getType().getUnqualifiedType()));
21240     if (IsAmbiguous)
21241       return false;
21242     if (SemaRef.CheckBaseClassAccess(Loc, VD->getType(), Type, Paths.front(),
21243                                      /*DiagID=*/0) != Sema::AR_inaccessible)
21244       return true;
21245   }
21246   return false;
21247 }
21248 
21249 static bool isImplicitMapperNeeded(Sema &S, DSAStackTy *Stack,
21250                                    QualType CanonType, const Expr *E) {
21251 
21252   // DFS over data members in structures/classes.
21253   SmallVector<std::pair<QualType, FieldDecl *>, 4> Types(1,
21254                                                          {CanonType, nullptr});
21255   llvm::DenseMap<const Type *, bool> Visited;
21256   SmallVector<std::pair<FieldDecl *, unsigned>, 4> ParentChain(1, {nullptr, 1});
21257   while (!Types.empty()) {
21258     auto [BaseType, CurFD] = Types.pop_back_val();
21259     while (ParentChain.back().second == 0)
21260       ParentChain.pop_back();
21261     --ParentChain.back().second;
21262     if (BaseType.isNull())
21263       continue;
21264     // Only structs/classes are allowed to have mappers.
21265     const RecordDecl *RD = BaseType.getCanonicalType()->getAsRecordDecl();
21266     if (!RD)
21267       continue;
21268     auto It = Visited.find(BaseType.getTypePtr());
21269     if (It == Visited.end()) {
21270       // Try to find the associated user-defined mapper.
21271       CXXScopeSpec MapperIdScopeSpec;
21272       DeclarationNameInfo DefaultMapperId;
21273       DefaultMapperId.setName(S.Context.DeclarationNames.getIdentifier(
21274           &S.Context.Idents.get("default")));
21275       DefaultMapperId.setLoc(E->getExprLoc());
21276       bool HasUDMapper =
21277           hasUserDefinedMapper(S, Stack->getCurScope(), MapperIdScopeSpec,
21278                                DefaultMapperId, BaseType);
21279       It = Visited.try_emplace(BaseType.getTypePtr(), HasUDMapper).first;
21280     }
21281     // Found default mapper.
21282     if (It->second)
21283       return true;
21284     // Check for the "default" mapper for data members.
21285     bool FirstIter = true;
21286     for (FieldDecl *FD : RD->fields()) {
21287       if (!FD)
21288         continue;
21289       QualType FieldTy = FD->getType();
21290       if (FieldTy.isNull() ||
21291           !(FieldTy->isStructureOrClassType() || FieldTy->isUnionType()))
21292         continue;
21293       if (FirstIter) {
21294         FirstIter = false;
21295         ParentChain.emplace_back(CurFD, 1);
21296       } else {
21297         ++ParentChain.back().second;
21298       }
21299       Types.emplace_back(FieldTy, FD);
21300     }
21301   }
21302   return false;
21303 }
21304 
21305 // Check the validity of the provided variable list for the provided clause kind
21306 // \a CKind. In the check process the valid expressions, mappable expression
21307 // components, variables, and user-defined mappers are extracted and used to
21308 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
21309 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
21310 // and \a MapperId are expected to be valid if the clause kind is 'map'.
21311 static void checkMappableExpressionList(
21312     Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
21313     MappableVarListInfo &MVLI, SourceLocation StartLoc,
21314     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
21315     ArrayRef<Expr *> UnresolvedMappers,
21316     OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
21317     ArrayRef<OpenMPMapModifierKind> Modifiers = {},
21318     bool IsMapTypeImplicit = false, bool NoDiagnose = false) {
21319   // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
21320   assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
21321          "Unexpected clause kind with mappable expressions!");
21322 
21323   // If the identifier of user-defined mapper is not specified, it is "default".
21324   // We do not change the actual name in this clause to distinguish whether a
21325   // mapper is specified explicitly, i.e., it is not explicitly specified when
21326   // MapperId.getName() is empty.
21327   if (!MapperId.getName() || MapperId.getName().isEmpty()) {
21328     auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
21329     MapperId.setName(DeclNames.getIdentifier(
21330         &SemaRef.getASTContext().Idents.get("default")));
21331     MapperId.setLoc(StartLoc);
21332   }
21333 
21334   // Iterators to find the current unresolved mapper expression.
21335   auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
21336   bool UpdateUMIt = false;
21337   Expr *UnresolvedMapper = nullptr;
21338 
21339   bool HasHoldModifier =
21340       llvm::is_contained(Modifiers, OMPC_MAP_MODIFIER_ompx_hold);
21341 
21342   // Keep track of the mappable components and base declarations in this clause.
21343   // Each entry in the list is going to have a list of components associated. We
21344   // record each set of the components so that we can build the clause later on.
21345   // In the end we should have the same amount of declarations and component
21346   // lists.
21347 
21348   for (Expr *RE : MVLI.VarList) {
21349     assert(RE && "Null expr in omp to/from/map clause");
21350     SourceLocation ELoc = RE->getExprLoc();
21351 
21352     // Find the current unresolved mapper expression.
21353     if (UpdateUMIt && UMIt != UMEnd) {
21354       UMIt++;
21355       assert(
21356           UMIt != UMEnd &&
21357           "Expect the size of UnresolvedMappers to match with that of VarList");
21358     }
21359     UpdateUMIt = true;
21360     if (UMIt != UMEnd)
21361       UnresolvedMapper = *UMIt;
21362 
21363     const Expr *VE = RE->IgnoreParenLValueCasts();
21364 
21365     if (VE->isValueDependent() || VE->isTypeDependent() ||
21366         VE->isInstantiationDependent() ||
21367         VE->containsUnexpandedParameterPack()) {
21368       // Try to find the associated user-defined mapper.
21369       ExprResult ER = buildUserDefinedMapperRef(
21370           SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
21371           VE->getType().getCanonicalType(), UnresolvedMapper);
21372       if (ER.isInvalid())
21373         continue;
21374       MVLI.UDMapperList.push_back(ER.get());
21375       // We can only analyze this information once the missing information is
21376       // resolved.
21377       MVLI.ProcessedVarList.push_back(RE);
21378       continue;
21379     }
21380 
21381     Expr *SimpleExpr = RE->IgnoreParenCasts();
21382 
21383     if (!RE->isLValue()) {
21384       if (SemaRef.getLangOpts().OpenMP < 50) {
21385         SemaRef.Diag(
21386             ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
21387             << RE->getSourceRange();
21388       } else {
21389         SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
21390             << getOpenMPClauseName(CKind) << RE->getSourceRange();
21391       }
21392       continue;
21393     }
21394 
21395     OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
21396     ValueDecl *CurDeclaration = nullptr;
21397 
21398     // Obtain the array or member expression bases if required. Also, fill the
21399     // components array with all the components identified in the process.
21400     const Expr *BE =
21401         checkMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents, CKind,
21402                                      DSAS->getCurrentDirective(), NoDiagnose);
21403     if (!BE)
21404       continue;
21405 
21406     assert(!CurComponents.empty() &&
21407            "Invalid mappable expression information.");
21408 
21409     if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
21410       // Add store "this" pointer to class in DSAStackTy for future checking
21411       DSAS->addMappedClassesQualTypes(TE->getType());
21412       // Try to find the associated user-defined mapper.
21413       ExprResult ER = buildUserDefinedMapperRef(
21414           SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
21415           VE->getType().getCanonicalType(), UnresolvedMapper);
21416       if (ER.isInvalid())
21417         continue;
21418       MVLI.UDMapperList.push_back(ER.get());
21419       // Skip restriction checking for variable or field declarations
21420       MVLI.ProcessedVarList.push_back(RE);
21421       MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
21422       MVLI.VarComponents.back().append(CurComponents.begin(),
21423                                        CurComponents.end());
21424       MVLI.VarBaseDeclarations.push_back(nullptr);
21425       continue;
21426     }
21427 
21428     // For the following checks, we rely on the base declaration which is
21429     // expected to be associated with the last component. The declaration is
21430     // expected to be a variable or a field (if 'this' is being mapped).
21431     CurDeclaration = CurComponents.back().getAssociatedDeclaration();
21432     assert(CurDeclaration && "Null decl on map clause.");
21433     assert(
21434         CurDeclaration->isCanonicalDecl() &&
21435         "Expecting components to have associated only canonical declarations.");
21436 
21437     auto *VD = dyn_cast<VarDecl>(CurDeclaration);
21438     const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
21439 
21440     assert((VD || FD) && "Only variables or fields are expected here!");
21441     (void)FD;
21442 
21443     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
21444     // threadprivate variables cannot appear in a map clause.
21445     // OpenMP 4.5 [2.10.5, target update Construct]
21446     // threadprivate variables cannot appear in a from clause.
21447     if (VD && DSAS->isThreadPrivate(VD)) {
21448       if (NoDiagnose)
21449         continue;
21450       DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
21451       SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
21452           << getOpenMPClauseName(CKind);
21453       reportOriginalDsa(SemaRef, DSAS, VD, DVar);
21454       continue;
21455     }
21456 
21457     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
21458     //  A list item cannot appear in both a map clause and a data-sharing
21459     //  attribute clause on the same construct.
21460 
21461     // Check conflicts with other map clause expressions. We check the conflicts
21462     // with the current construct separately from the enclosing data
21463     // environment, because the restrictions are different. We only have to
21464     // check conflicts across regions for the map clauses.
21465     if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
21466                           /*CurrentRegionOnly=*/true, CurComponents, CKind))
21467       break;
21468     if (CKind == OMPC_map &&
21469         (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) &&
21470         checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
21471                           /*CurrentRegionOnly=*/false, CurComponents, CKind))
21472       break;
21473 
21474     // OpenMP 4.5 [2.10.5, target update Construct]
21475     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
21476     //  If the type of a list item is a reference to a type T then the type will
21477     //  be considered to be T for all purposes of this clause.
21478     auto I = llvm::find_if(
21479         CurComponents,
21480         [](const OMPClauseMappableExprCommon::MappableComponent &MC) {
21481           return MC.getAssociatedDeclaration();
21482         });
21483     assert(I != CurComponents.end() && "Null decl on map clause.");
21484     (void)I;
21485     QualType Type;
21486     auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens());
21487     auto *OASE = dyn_cast<ArraySectionExpr>(VE->IgnoreParens());
21488     auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens());
21489     if (ASE) {
21490       Type = ASE->getType().getNonReferenceType();
21491     } else if (OASE) {
21492       QualType BaseType =
21493           ArraySectionExpr::getBaseOriginalType(OASE->getBase());
21494       if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
21495         Type = ATy->getElementType();
21496       else
21497         Type = BaseType->getPointeeType();
21498       Type = Type.getNonReferenceType();
21499     } else if (OAShE) {
21500       Type = OAShE->getBase()->getType()->getPointeeType();
21501     } else {
21502       Type = VE->getType();
21503     }
21504 
21505     // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
21506     // A list item in a to or from clause must have a mappable type.
21507     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
21508     //  A list item must have a mappable type.
21509     if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
21510                            DSAS, Type, /*FullCheck=*/true))
21511       continue;
21512 
21513     if (CKind == OMPC_map) {
21514       // target enter data
21515       // OpenMP [2.10.2, Restrictions, p. 99]
21516       // A map-type must be specified in all map clauses and must be either
21517       // to or alloc. Starting with OpenMP 5.2 the default map type is `to` if
21518       // no map type is present.
21519       OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
21520       if (DKind == OMPD_target_enter_data &&
21521           !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc ||
21522             SemaRef.getLangOpts().OpenMP >= 52)) {
21523         SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
21524             << (IsMapTypeImplicit ? 1 : 0)
21525             << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
21526             << getOpenMPDirectiveName(DKind);
21527         continue;
21528       }
21529 
21530       // target exit_data
21531       // OpenMP [2.10.3, Restrictions, p. 102]
21532       // A map-type must be specified in all map clauses and must be either
21533       // from, release, or delete. Starting with OpenMP 5.2 the default map
21534       // type is `from` if no map type is present.
21535       if (DKind == OMPD_target_exit_data &&
21536           !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
21537             MapType == OMPC_MAP_delete || SemaRef.getLangOpts().OpenMP >= 52)) {
21538         SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
21539             << (IsMapTypeImplicit ? 1 : 0)
21540             << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
21541             << getOpenMPDirectiveName(DKind);
21542         continue;
21543       }
21544 
21545       // The 'ompx_hold' modifier is specifically intended to be used on a
21546       // 'target' or 'target data' directive to prevent data from being unmapped
21547       // during the associated statement.  It is not permitted on a 'target
21548       // enter data' or 'target exit data' directive, which have no associated
21549       // statement.
21550       if ((DKind == OMPD_target_enter_data || DKind == OMPD_target_exit_data) &&
21551           HasHoldModifier) {
21552         SemaRef.Diag(StartLoc,
21553                      diag::err_omp_invalid_map_type_modifier_for_directive)
21554             << getOpenMPSimpleClauseTypeName(OMPC_map,
21555                                              OMPC_MAP_MODIFIER_ompx_hold)
21556             << getOpenMPDirectiveName(DKind);
21557         continue;
21558       }
21559 
21560       // target, target data
21561       // OpenMP 5.0 [2.12.2, Restrictions, p. 163]
21562       // OpenMP 5.0 [2.12.5, Restrictions, p. 174]
21563       // A map-type in a map clause must be to, from, tofrom or alloc
21564       if ((DKind == OMPD_target_data ||
21565            isOpenMPTargetExecutionDirective(DKind)) &&
21566           !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
21567             MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) {
21568         SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
21569             << (IsMapTypeImplicit ? 1 : 0)
21570             << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
21571             << getOpenMPDirectiveName(DKind);
21572         continue;
21573       }
21574 
21575       // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
21576       // A list item cannot appear in both a map clause and a data-sharing
21577       // attribute clause on the same construct
21578       //
21579       // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
21580       // A list item cannot appear in both a map clause and a data-sharing
21581       // attribute clause on the same construct unless the construct is a
21582       // combined construct.
21583       if (VD && ((SemaRef.LangOpts.OpenMP <= 45 &&
21584                   isOpenMPTargetExecutionDirective(DKind)) ||
21585                  DKind == OMPD_target)) {
21586         DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
21587         if (isOpenMPPrivate(DVar.CKind)) {
21588           SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
21589               << getOpenMPClauseName(DVar.CKind)
21590               << getOpenMPClauseName(OMPC_map)
21591               << getOpenMPDirectiveName(DSAS->getCurrentDirective());
21592           reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
21593           continue;
21594         }
21595       }
21596     }
21597 
21598     // Try to find the associated user-defined mapper.
21599     ExprResult ER = buildUserDefinedMapperRef(
21600         SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
21601         Type.getCanonicalType(), UnresolvedMapper);
21602     if (ER.isInvalid())
21603       continue;
21604     if (!ER.get() && isa<ArraySectionExpr>(VE)) {
21605       // Create implicit mapper as needed.
21606       QualType BaseType = VE->getType().getCanonicalType();
21607       if (BaseType->isSpecificBuiltinType(BuiltinType::ArraySection)) {
21608         const auto *OASE = cast<ArraySectionExpr>(VE->IgnoreParenImpCasts());
21609         QualType BType = ArraySectionExpr::getBaseOriginalType(OASE->getBase());
21610         QualType ElemType;
21611         if (const auto *ATy = BType->getAsArrayTypeUnsafe())
21612           ElemType = ATy->getElementType();
21613         else
21614           ElemType = BType->getPointeeType();
21615         BaseType = ElemType.getCanonicalType();
21616       }
21617       if (BaseType->getAsRecordDecl() &&
21618           isImplicitMapperNeeded(SemaRef, DSAS, BaseType, VE)) {
21619         ER = buildImplicitMapper(SemaRef, BaseType, DSAS);
21620       }
21621     }
21622     MVLI.UDMapperList.push_back(ER.get());
21623 
21624     // Save the current expression.
21625     MVLI.ProcessedVarList.push_back(RE);
21626 
21627     // Store the components in the stack so that they can be used to check
21628     // against other clauses later on.
21629     DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
21630                                           /*WhereFoundClauseKind=*/OMPC_map);
21631 
21632     // Save the components and declaration to create the clause. For purposes of
21633     // the clause creation, any component list that has base 'this' uses
21634     // null as base declaration.
21635     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
21636     MVLI.VarComponents.back().append(CurComponents.begin(),
21637                                      CurComponents.end());
21638     MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
21639                                                            : CurDeclaration);
21640   }
21641 }
21642 
21643 OMPClause *SemaOpenMP::ActOnOpenMPMapClause(
21644     Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
21645     ArrayRef<SourceLocation> MapTypeModifiersLoc,
21646     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
21647     OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
21648     SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
21649     const OMPVarListLocTy &Locs, bool NoDiagnose,
21650     ArrayRef<Expr *> UnresolvedMappers) {
21651   OpenMPMapModifierKind Modifiers[] = {
21652       OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
21653       OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
21654       OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown};
21655   SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers];
21656 
21657   if (IteratorModifier && !IteratorModifier->getType()->isSpecificBuiltinType(
21658                               BuiltinType::OMPIterator))
21659     Diag(IteratorModifier->getExprLoc(),
21660          diag::err_omp_map_modifier_not_iterator);
21661 
21662   // Process map-type-modifiers, flag errors for duplicate modifiers.
21663   unsigned Count = 0;
21664   for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
21665     if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
21666         llvm::is_contained(Modifiers, MapTypeModifiers[I])) {
21667       Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
21668       continue;
21669     }
21670     assert(Count < NumberOfOMPMapClauseModifiers &&
21671            "Modifiers exceed the allowed number of map type modifiers");
21672     Modifiers[Count] = MapTypeModifiers[I];
21673     ModifiersLoc[Count] = MapTypeModifiersLoc[I];
21674     ++Count;
21675   }
21676 
21677   MappableVarListInfo MVLI(VarList);
21678   checkMappableExpressionList(SemaRef, DSAStack, OMPC_map, MVLI, Locs.StartLoc,
21679                               MapperIdScopeSpec, MapperId, UnresolvedMappers,
21680                               MapType, Modifiers, IsMapTypeImplicit,
21681                               NoDiagnose);
21682 
21683   // We need to produce a map clause even if we don't have variables so that
21684   // other diagnostics related with non-existing map clauses are accurate.
21685   return OMPMapClause::Create(
21686       getASTContext(), Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
21687       MVLI.VarComponents, MVLI.UDMapperList, IteratorModifier, Modifiers,
21688       ModifiersLoc, MapperIdScopeSpec.getWithLocInContext(getASTContext()),
21689       MapperId, MapType, IsMapTypeImplicit, MapLoc);
21690 }
21691 
21692 QualType SemaOpenMP::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
21693                                                      TypeResult ParsedType) {
21694   assert(ParsedType.isUsable());
21695 
21696   QualType ReductionType = SemaRef.GetTypeFromParser(ParsedType.get());
21697   if (ReductionType.isNull())
21698     return QualType();
21699 
21700   // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
21701   // A type name in a declare reduction directive cannot be a function type, an
21702   // array type, a reference type, or a type qualified with const, volatile or
21703   // restrict.
21704   if (ReductionType.hasQualifiers()) {
21705     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
21706     return QualType();
21707   }
21708 
21709   if (ReductionType->isFunctionType()) {
21710     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
21711     return QualType();
21712   }
21713   if (ReductionType->isReferenceType()) {
21714     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
21715     return QualType();
21716   }
21717   if (ReductionType->isArrayType()) {
21718     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
21719     return QualType();
21720   }
21721   return ReductionType;
21722 }
21723 
21724 SemaOpenMP::DeclGroupPtrTy
21725 SemaOpenMP::ActOnOpenMPDeclareReductionDirectiveStart(
21726     Scope *S, DeclContext *DC, DeclarationName Name,
21727     ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
21728     AccessSpecifier AS, Decl *PrevDeclInScope) {
21729   SmallVector<Decl *, 8> Decls;
21730   Decls.reserve(ReductionTypes.size());
21731 
21732   LookupResult Lookup(SemaRef, Name, SourceLocation(),
21733                       Sema::LookupOMPReductionName,
21734                       SemaRef.forRedeclarationInCurContext());
21735   // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
21736   // A reduction-identifier may not be re-declared in the current scope for the
21737   // same type or for a type that is compatible according to the base language
21738   // rules.
21739   llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
21740   OMPDeclareReductionDecl *PrevDRD = nullptr;
21741   bool InCompoundScope = true;
21742   if (S != nullptr) {
21743     // Find previous declaration with the same name not referenced in other
21744     // declarations.
21745     FunctionScopeInfo *ParentFn = SemaRef.getEnclosingFunction();
21746     InCompoundScope =
21747         (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
21748     SemaRef.LookupName(Lookup, S);
21749     SemaRef.FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
21750                                  /*AllowInlineNamespace=*/false);
21751     llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
21752     LookupResult::Filter Filter = Lookup.makeFilter();
21753     while (Filter.hasNext()) {
21754       auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
21755       if (InCompoundScope) {
21756         UsedAsPrevious.try_emplace(PrevDecl, false);
21757         if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
21758           UsedAsPrevious[D] = true;
21759       }
21760       PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
21761           PrevDecl->getLocation();
21762     }
21763     Filter.done();
21764     if (InCompoundScope) {
21765       for (const auto &PrevData : UsedAsPrevious) {
21766         if (!PrevData.second) {
21767           PrevDRD = PrevData.first;
21768           break;
21769         }
21770       }
21771     }
21772   } else if (PrevDeclInScope != nullptr) {
21773     auto *PrevDRDInScope = PrevDRD =
21774         cast<OMPDeclareReductionDecl>(PrevDeclInScope);
21775     do {
21776       PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
21777           PrevDRDInScope->getLocation();
21778       PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
21779     } while (PrevDRDInScope != nullptr);
21780   }
21781   for (const auto &TyData : ReductionTypes) {
21782     const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
21783     bool Invalid = false;
21784     if (I != PreviousRedeclTypes.end()) {
21785       Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
21786           << TyData.first;
21787       Diag(I->second, diag::note_previous_definition);
21788       Invalid = true;
21789     }
21790     PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
21791     auto *DRD = OMPDeclareReductionDecl::Create(
21792         getASTContext(), DC, TyData.second, Name, TyData.first, PrevDRD);
21793     DC->addDecl(DRD);
21794     DRD->setAccess(AS);
21795     Decls.push_back(DRD);
21796     if (Invalid)
21797       DRD->setInvalidDecl();
21798     else
21799       PrevDRD = DRD;
21800   }
21801 
21802   return DeclGroupPtrTy::make(
21803       DeclGroupRef::Create(getASTContext(), Decls.begin(), Decls.size()));
21804 }
21805 
21806 void SemaOpenMP::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
21807   auto *DRD = cast<OMPDeclareReductionDecl>(D);
21808 
21809   // Enter new function scope.
21810   SemaRef.PushFunctionScope();
21811   SemaRef.setFunctionHasBranchProtectedScope();
21812   SemaRef.getCurFunction()->setHasOMPDeclareReductionCombiner();
21813 
21814   if (S != nullptr)
21815     SemaRef.PushDeclContext(S, DRD);
21816   else
21817     SemaRef.CurContext = DRD;
21818 
21819   SemaRef.PushExpressionEvaluationContext(
21820       Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
21821 
21822   QualType ReductionType = DRD->getType();
21823   // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
21824   // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
21825   // uses semantics of argument handles by value, but it should be passed by
21826   // reference. C lang does not support references, so pass all parameters as
21827   // pointers.
21828   // Create 'T omp_in;' variable.
21829   VarDecl *OmpInParm =
21830       buildVarDecl(SemaRef, D->getLocation(), ReductionType, "omp_in");
21831   // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
21832   // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
21833   // uses semantics of argument handles by value, but it should be passed by
21834   // reference. C lang does not support references, so pass all parameters as
21835   // pointers.
21836   // Create 'T omp_out;' variable.
21837   VarDecl *OmpOutParm =
21838       buildVarDecl(SemaRef, D->getLocation(), ReductionType, "omp_out");
21839   if (S != nullptr) {
21840     SemaRef.PushOnScopeChains(OmpInParm, S);
21841     SemaRef.PushOnScopeChains(OmpOutParm, S);
21842   } else {
21843     DRD->addDecl(OmpInParm);
21844     DRD->addDecl(OmpOutParm);
21845   }
21846   Expr *InE =
21847       ::buildDeclRefExpr(SemaRef, OmpInParm, ReductionType, D->getLocation());
21848   Expr *OutE =
21849       ::buildDeclRefExpr(SemaRef, OmpOutParm, ReductionType, D->getLocation());
21850   DRD->setCombinerData(InE, OutE);
21851 }
21852 
21853 void SemaOpenMP::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D,
21854                                                         Expr *Combiner) {
21855   auto *DRD = cast<OMPDeclareReductionDecl>(D);
21856   SemaRef.DiscardCleanupsInEvaluationContext();
21857   SemaRef.PopExpressionEvaluationContext();
21858 
21859   SemaRef.PopDeclContext();
21860   SemaRef.PopFunctionScopeInfo();
21861 
21862   if (Combiner != nullptr)
21863     DRD->setCombiner(Combiner);
21864   else
21865     DRD->setInvalidDecl();
21866 }
21867 
21868 VarDecl *SemaOpenMP::ActOnOpenMPDeclareReductionInitializerStart(Scope *S,
21869                                                                  Decl *D) {
21870   auto *DRD = cast<OMPDeclareReductionDecl>(D);
21871 
21872   // Enter new function scope.
21873   SemaRef.PushFunctionScope();
21874   SemaRef.setFunctionHasBranchProtectedScope();
21875 
21876   if (S != nullptr)
21877     SemaRef.PushDeclContext(S, DRD);
21878   else
21879     SemaRef.CurContext = DRD;
21880 
21881   SemaRef.PushExpressionEvaluationContext(
21882       Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
21883 
21884   QualType ReductionType = DRD->getType();
21885   // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
21886   // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
21887   // uses semantics of argument handles by value, but it should be passed by
21888   // reference. C lang does not support references, so pass all parameters as
21889   // pointers.
21890   // Create 'T omp_priv;' variable.
21891   VarDecl *OmpPrivParm =
21892       buildVarDecl(SemaRef, D->getLocation(), ReductionType, "omp_priv");
21893   // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
21894   // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
21895   // uses semantics of argument handles by value, but it should be passed by
21896   // reference. C lang does not support references, so pass all parameters as
21897   // pointers.
21898   // Create 'T omp_orig;' variable.
21899   VarDecl *OmpOrigParm =
21900       buildVarDecl(SemaRef, D->getLocation(), ReductionType, "omp_orig");
21901   if (S != nullptr) {
21902     SemaRef.PushOnScopeChains(OmpPrivParm, S);
21903     SemaRef.PushOnScopeChains(OmpOrigParm, S);
21904   } else {
21905     DRD->addDecl(OmpPrivParm);
21906     DRD->addDecl(OmpOrigParm);
21907   }
21908   Expr *OrigE =
21909       ::buildDeclRefExpr(SemaRef, OmpOrigParm, ReductionType, D->getLocation());
21910   Expr *PrivE =
21911       ::buildDeclRefExpr(SemaRef, OmpPrivParm, ReductionType, D->getLocation());
21912   DRD->setInitializerData(OrigE, PrivE);
21913   return OmpPrivParm;
21914 }
21915 
21916 void SemaOpenMP::ActOnOpenMPDeclareReductionInitializerEnd(
21917     Decl *D, Expr *Initializer, VarDecl *OmpPrivParm) {
21918   auto *DRD = cast<OMPDeclareReductionDecl>(D);
21919   SemaRef.DiscardCleanupsInEvaluationContext();
21920   SemaRef.PopExpressionEvaluationContext();
21921 
21922   SemaRef.PopDeclContext();
21923   SemaRef.PopFunctionScopeInfo();
21924 
21925   if (Initializer != nullptr) {
21926     DRD->setInitializer(Initializer, OMPDeclareReductionInitKind::Call);
21927   } else if (OmpPrivParm->hasInit()) {
21928     DRD->setInitializer(OmpPrivParm->getInit(),
21929                         OmpPrivParm->isDirectInit()
21930                             ? OMPDeclareReductionInitKind::Direct
21931                             : OMPDeclareReductionInitKind::Copy);
21932   } else {
21933     DRD->setInvalidDecl();
21934   }
21935 }
21936 
21937 SemaOpenMP::DeclGroupPtrTy SemaOpenMP::ActOnOpenMPDeclareReductionDirectiveEnd(
21938     Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
21939   for (Decl *D : DeclReductions.get()) {
21940     if (IsValid) {
21941       if (S)
21942         SemaRef.PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
21943                                   /*AddToContext=*/false);
21944     } else {
21945       D->setInvalidDecl();
21946     }
21947   }
21948   return DeclReductions;
21949 }
21950 
21951 TypeResult SemaOpenMP::ActOnOpenMPDeclareMapperVarDecl(Scope *S,
21952                                                        Declarator &D) {
21953   TypeSourceInfo *TInfo = SemaRef.GetTypeForDeclarator(D);
21954   QualType T = TInfo->getType();
21955   if (D.isInvalidType())
21956     return true;
21957 
21958   if (getLangOpts().CPlusPlus) {
21959     // Check that there are no default arguments (C++ only).
21960     SemaRef.CheckExtraCXXDefaultArguments(D);
21961   }
21962 
21963   return SemaRef.CreateParsedType(T, TInfo);
21964 }
21965 
21966 QualType SemaOpenMP::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
21967                                                   TypeResult ParsedType) {
21968   assert(ParsedType.isUsable() && "Expect usable parsed mapper type");
21969 
21970   QualType MapperType = SemaRef.GetTypeFromParser(ParsedType.get());
21971   assert(!MapperType.isNull() && "Expect valid mapper type");
21972 
21973   // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
21974   //  The type must be of struct, union or class type in C and C++
21975   if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
21976     Diag(TyLoc, diag::err_omp_mapper_wrong_type);
21977     return QualType();
21978   }
21979   return MapperType;
21980 }
21981 
21982 SemaOpenMP::DeclGroupPtrTy SemaOpenMP::ActOnOpenMPDeclareMapperDirective(
21983     Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
21984     SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
21985     Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) {
21986   LookupResult Lookup(SemaRef, Name, SourceLocation(),
21987                       Sema::LookupOMPMapperName,
21988                       SemaRef.forRedeclarationInCurContext());
21989   // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
21990   //  A mapper-identifier may not be redeclared in the current scope for the
21991   //  same type or for a type that is compatible according to the base language
21992   //  rules.
21993   llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
21994   OMPDeclareMapperDecl *PrevDMD = nullptr;
21995   bool InCompoundScope = true;
21996   if (S != nullptr) {
21997     // Find previous declaration with the same name not referenced in other
21998     // declarations.
21999     FunctionScopeInfo *ParentFn = SemaRef.getEnclosingFunction();
22000     InCompoundScope =
22001         (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
22002     SemaRef.LookupName(Lookup, S);
22003     SemaRef.FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
22004                                  /*AllowInlineNamespace=*/false);
22005     llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
22006     LookupResult::Filter Filter = Lookup.makeFilter();
22007     while (Filter.hasNext()) {
22008       auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
22009       if (InCompoundScope) {
22010         UsedAsPrevious.try_emplace(PrevDecl, false);
22011         if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
22012           UsedAsPrevious[D] = true;
22013       }
22014       PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
22015           PrevDecl->getLocation();
22016     }
22017     Filter.done();
22018     if (InCompoundScope) {
22019       for (const auto &PrevData : UsedAsPrevious) {
22020         if (!PrevData.second) {
22021           PrevDMD = PrevData.first;
22022           break;
22023         }
22024       }
22025     }
22026   } else if (PrevDeclInScope) {
22027     auto *PrevDMDInScope = PrevDMD =
22028         cast<OMPDeclareMapperDecl>(PrevDeclInScope);
22029     do {
22030       PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
22031           PrevDMDInScope->getLocation();
22032       PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
22033     } while (PrevDMDInScope != nullptr);
22034   }
22035   const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
22036   bool Invalid = false;
22037   if (I != PreviousRedeclTypes.end()) {
22038     Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
22039         << MapperType << Name;
22040     Diag(I->second, diag::note_previous_definition);
22041     Invalid = true;
22042   }
22043   // Build expressions for implicit maps of data members with 'default'
22044   // mappers.
22045   SmallVector<OMPClause *, 4> ClausesWithImplicit(Clauses);
22046   if (getLangOpts().OpenMP >= 50)
22047     processImplicitMapsWithDefaultMappers(SemaRef, DSAStack,
22048                                           ClausesWithImplicit);
22049   auto *DMD = OMPDeclareMapperDecl::Create(getASTContext(), DC, StartLoc, Name,
22050                                            MapperType, VN, ClausesWithImplicit,
22051                                            PrevDMD);
22052   if (S)
22053     SemaRef.PushOnScopeChains(DMD, S);
22054   else
22055     DC->addDecl(DMD);
22056   DMD->setAccess(AS);
22057   if (Invalid)
22058     DMD->setInvalidDecl();
22059 
22060   auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl();
22061   VD->setDeclContext(DMD);
22062   VD->setLexicalDeclContext(DMD);
22063   DMD->addDecl(VD);
22064   DMD->setMapperVarRef(MapperVarRef);
22065 
22066   return DeclGroupPtrTy::make(DeclGroupRef(DMD));
22067 }
22068 
22069 ExprResult SemaOpenMP::ActOnOpenMPDeclareMapperDirectiveVarDecl(
22070     Scope *S, QualType MapperType, SourceLocation StartLoc,
22071     DeclarationName VN) {
22072   TypeSourceInfo *TInfo =
22073       getASTContext().getTrivialTypeSourceInfo(MapperType, StartLoc);
22074   auto *VD = VarDecl::Create(
22075       getASTContext(), getASTContext().getTranslationUnitDecl(), StartLoc,
22076       StartLoc, VN.getAsIdentifierInfo(), MapperType, TInfo, SC_None);
22077   if (S)
22078     SemaRef.PushOnScopeChains(VD, S, /*AddToContext=*/false);
22079   Expr *E = buildDeclRefExpr(SemaRef, VD, MapperType, StartLoc);
22080   DSAStack->addDeclareMapperVarRef(E);
22081   return E;
22082 }
22083 
22084 void SemaOpenMP::ActOnOpenMPIteratorVarDecl(VarDecl *VD) {
22085   if (DSAStack->getDeclareMapperVarRef())
22086     DSAStack->addIteratorVarDecl(VD);
22087 }
22088 
22089 bool SemaOpenMP::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const {
22090   assert(getLangOpts().OpenMP && "Expected OpenMP mode.");
22091   const Expr *Ref = DSAStack->getDeclareMapperVarRef();
22092   if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref)) {
22093     if (VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl())
22094       return true;
22095     if (VD->isUsableInConstantExpressions(getASTContext()))
22096       return true;
22097     if (getLangOpts().OpenMP >= 52 && DSAStack->isIteratorVarDecl(VD))
22098       return true;
22099     return false;
22100   }
22101   return true;
22102 }
22103 
22104 const ValueDecl *SemaOpenMP::getOpenMPDeclareMapperVarName() const {
22105   assert(getLangOpts().OpenMP && "Expected OpenMP mode.");
22106   return cast<DeclRefExpr>(DSAStack->getDeclareMapperVarRef())->getDecl();
22107 }
22108 
22109 OMPClause *SemaOpenMP::ActOnOpenMPNumTeamsClause(ArrayRef<Expr *> VarList,
22110                                                  SourceLocation StartLoc,
22111                                                  SourceLocation LParenLoc,
22112                                                  SourceLocation EndLoc) {
22113   if (VarList.empty())
22114     return nullptr;
22115 
22116   for (Expr *ValExpr : VarList) {
22117     // OpenMP [teams Constrcut, Restrictions]
22118     // The num_teams expression must evaluate to a positive integer value.
22119     if (!isNonNegativeIntegerValue(ValExpr, SemaRef, OMPC_num_teams,
22120                                    /*StrictlyPositive=*/true))
22121       return nullptr;
22122   }
22123 
22124   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
22125   OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
22126       DKind, OMPC_num_teams, getLangOpts().OpenMP);
22127   if (CaptureRegion == OMPD_unknown || SemaRef.CurContext->isDependentContext())
22128     return OMPNumTeamsClause::Create(getASTContext(), CaptureRegion, StartLoc,
22129                                      LParenLoc, EndLoc, VarList,
22130                                      /*PreInit=*/nullptr);
22131 
22132   llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
22133   SmallVector<Expr *, 3> Vars;
22134   for (Expr *ValExpr : VarList) {
22135     ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
22136     ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
22137     Vars.push_back(ValExpr);
22138   }
22139 
22140   Stmt *PreInit = buildPreInits(getASTContext(), Captures);
22141   return OMPNumTeamsClause::Create(getASTContext(), CaptureRegion, StartLoc,
22142                                    LParenLoc, EndLoc, Vars, PreInit);
22143 }
22144 
22145 OMPClause *SemaOpenMP::ActOnOpenMPThreadLimitClause(ArrayRef<Expr *> VarList,
22146                                                     SourceLocation StartLoc,
22147                                                     SourceLocation LParenLoc,
22148                                                     SourceLocation EndLoc) {
22149   if (VarList.empty())
22150     return nullptr;
22151 
22152   for (Expr *ValExpr : VarList) {
22153     // OpenMP [teams Constrcut, Restrictions]
22154     // The thread_limit expression must evaluate to a positive integer value.
22155     if (!isNonNegativeIntegerValue(ValExpr, SemaRef, OMPC_thread_limit,
22156                                    /*StrictlyPositive=*/true))
22157       return nullptr;
22158   }
22159 
22160   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
22161   OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
22162       DKind, OMPC_thread_limit, getLangOpts().OpenMP);
22163   if (CaptureRegion == OMPD_unknown || SemaRef.CurContext->isDependentContext())
22164     return OMPThreadLimitClause::Create(getASTContext(), CaptureRegion,
22165                                         StartLoc, LParenLoc, EndLoc, VarList,
22166                                         /*PreInit=*/nullptr);
22167 
22168   llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
22169   SmallVector<Expr *, 3> Vars;
22170   for (Expr *ValExpr : VarList) {
22171     ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
22172     ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
22173     Vars.push_back(ValExpr);
22174   }
22175 
22176   Stmt *PreInit = buildPreInits(getASTContext(), Captures);
22177   return OMPThreadLimitClause::Create(getASTContext(), CaptureRegion, StartLoc,
22178                                       LParenLoc, EndLoc, Vars, PreInit);
22179 }
22180 
22181 OMPClause *SemaOpenMP::ActOnOpenMPPriorityClause(Expr *Priority,
22182                                                  SourceLocation StartLoc,
22183                                                  SourceLocation LParenLoc,
22184                                                  SourceLocation EndLoc) {
22185   Expr *ValExpr = Priority;
22186   Stmt *HelperValStmt = nullptr;
22187   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
22188 
22189   // OpenMP [2.9.1, task Constrcut]
22190   // The priority-value is a non-negative numerical scalar expression.
22191   if (!isNonNegativeIntegerValue(
22192           ValExpr, SemaRef, OMPC_priority,
22193           /*StrictlyPositive=*/false, /*BuildCapture=*/true,
22194           DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
22195     return nullptr;
22196 
22197   return new (getASTContext()) OMPPriorityClause(
22198       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
22199 }
22200 
22201 OMPClause *SemaOpenMP::ActOnOpenMPGrainsizeClause(
22202     OpenMPGrainsizeClauseModifier Modifier, Expr *Grainsize,
22203     SourceLocation StartLoc, SourceLocation LParenLoc,
22204     SourceLocation ModifierLoc, SourceLocation EndLoc) {
22205   assert((ModifierLoc.isInvalid() || getLangOpts().OpenMP >= 51) &&
22206          "Unexpected grainsize modifier in OpenMP < 51.");
22207 
22208   if (ModifierLoc.isValid() && Modifier == OMPC_GRAINSIZE_unknown) {
22209     std::string Values = getListOfPossibleValues(OMPC_grainsize, /*First=*/0,
22210                                                  OMPC_GRAINSIZE_unknown);
22211     Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
22212         << Values << getOpenMPClauseName(OMPC_grainsize);
22213     return nullptr;
22214   }
22215 
22216   Expr *ValExpr = Grainsize;
22217   Stmt *HelperValStmt = nullptr;
22218   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
22219 
22220   // OpenMP [2.9.2, taskloop Constrcut]
22221   // The parameter of the grainsize clause must be a positive integer
22222   // expression.
22223   if (!isNonNegativeIntegerValue(ValExpr, SemaRef, OMPC_grainsize,
22224                                  /*StrictlyPositive=*/true,
22225                                  /*BuildCapture=*/true,
22226                                  DSAStack->getCurrentDirective(),
22227                                  &CaptureRegion, &HelperValStmt))
22228     return nullptr;
22229 
22230   return new (getASTContext())
22231       OMPGrainsizeClause(Modifier, ValExpr, HelperValStmt, CaptureRegion,
22232                          StartLoc, LParenLoc, ModifierLoc, EndLoc);
22233 }
22234 
22235 OMPClause *SemaOpenMP::ActOnOpenMPNumTasksClause(
22236     OpenMPNumTasksClauseModifier Modifier, Expr *NumTasks,
22237     SourceLocation StartLoc, SourceLocation LParenLoc,
22238     SourceLocation ModifierLoc, SourceLocation EndLoc) {
22239   assert((ModifierLoc.isInvalid() || getLangOpts().OpenMP >= 51) &&
22240          "Unexpected num_tasks modifier in OpenMP < 51.");
22241 
22242   if (ModifierLoc.isValid() && Modifier == OMPC_NUMTASKS_unknown) {
22243     std::string Values = getListOfPossibleValues(OMPC_num_tasks, /*First=*/0,
22244                                                  OMPC_NUMTASKS_unknown);
22245     Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
22246         << Values << getOpenMPClauseName(OMPC_num_tasks);
22247     return nullptr;
22248   }
22249 
22250   Expr *ValExpr = NumTasks;
22251   Stmt *HelperValStmt = nullptr;
22252   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
22253 
22254   // OpenMP [2.9.2, taskloop Constrcut]
22255   // The parameter of the num_tasks clause must be a positive integer
22256   // expression.
22257   if (!isNonNegativeIntegerValue(
22258           ValExpr, SemaRef, OMPC_num_tasks,
22259           /*StrictlyPositive=*/true, /*BuildCapture=*/true,
22260           DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
22261     return nullptr;
22262 
22263   return new (getASTContext())
22264       OMPNumTasksClause(Modifier, ValExpr, HelperValStmt, CaptureRegion,
22265                         StartLoc, LParenLoc, ModifierLoc, EndLoc);
22266 }
22267 
22268 OMPClause *SemaOpenMP::ActOnOpenMPHintClause(Expr *Hint,
22269                                              SourceLocation StartLoc,
22270                                              SourceLocation LParenLoc,
22271                                              SourceLocation EndLoc) {
22272   // OpenMP [2.13.2, critical construct, Description]
22273   // ... where hint-expression is an integer constant expression that evaluates
22274   // to a valid lock hint.
22275   ExprResult HintExpr =
22276       VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint, false);
22277   if (HintExpr.isInvalid())
22278     return nullptr;
22279   return new (getASTContext())
22280       OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
22281 }
22282 
22283 /// Tries to find omp_event_handle_t type.
22284 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc,
22285                                 DSAStackTy *Stack) {
22286   QualType OMPEventHandleT = Stack->getOMPEventHandleT();
22287   if (!OMPEventHandleT.isNull())
22288     return true;
22289   IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t");
22290   ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
22291   if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
22292     S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t";
22293     return false;
22294   }
22295   Stack->setOMPEventHandleT(PT.get());
22296   return true;
22297 }
22298 
22299 OMPClause *SemaOpenMP::ActOnOpenMPDetachClause(Expr *Evt,
22300                                                SourceLocation StartLoc,
22301                                                SourceLocation LParenLoc,
22302                                                SourceLocation EndLoc) {
22303   if (!Evt->isValueDependent() && !Evt->isTypeDependent() &&
22304       !Evt->isInstantiationDependent() &&
22305       !Evt->containsUnexpandedParameterPack()) {
22306     if (!findOMPEventHandleT(SemaRef, Evt->getExprLoc(), DSAStack))
22307       return nullptr;
22308     // OpenMP 5.0, 2.10.1 task Construct.
22309     // event-handle is a variable of the omp_event_handle_t type.
22310     auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts());
22311     if (!Ref) {
22312       Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
22313           << "omp_event_handle_t" << 0 << Evt->getSourceRange();
22314       return nullptr;
22315     }
22316     auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl());
22317     if (!VD) {
22318       Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
22319           << "omp_event_handle_t" << 0 << Evt->getSourceRange();
22320       return nullptr;
22321     }
22322     if (!getASTContext().hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(),
22323                                                 VD->getType()) ||
22324         VD->getType().isConstant(getASTContext())) {
22325       Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
22326           << "omp_event_handle_t" << 1 << VD->getType()
22327           << Evt->getSourceRange();
22328       return nullptr;
22329     }
22330     // OpenMP 5.0, 2.10.1 task Construct
22331     // [detach clause]... The event-handle will be considered as if it was
22332     // specified on a firstprivate clause.
22333     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false);
22334     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
22335         DVar.RefExpr) {
22336       Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa)
22337           << getOpenMPClauseName(DVar.CKind)
22338           << getOpenMPClauseName(OMPC_firstprivate);
22339       reportOriginalDsa(SemaRef, DSAStack, VD, DVar);
22340       return nullptr;
22341     }
22342   }
22343 
22344   return new (getASTContext())
22345       OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc);
22346 }
22347 
22348 OMPClause *SemaOpenMP::ActOnOpenMPDistScheduleClause(
22349     OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
22350     SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
22351     SourceLocation EndLoc) {
22352   if (Kind == OMPC_DIST_SCHEDULE_unknown) {
22353     std::string Values;
22354     Values += "'";
22355     Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
22356     Values += "'";
22357     Diag(KindLoc, diag::err_omp_unexpected_clause_value)
22358         << Values << getOpenMPClauseName(OMPC_dist_schedule);
22359     return nullptr;
22360   }
22361   Expr *ValExpr = ChunkSize;
22362   Stmt *HelperValStmt = nullptr;
22363   if (ChunkSize) {
22364     if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
22365         !ChunkSize->isInstantiationDependent() &&
22366         !ChunkSize->containsUnexpandedParameterPack()) {
22367       SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
22368       ExprResult Val =
22369           PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
22370       if (Val.isInvalid())
22371         return nullptr;
22372 
22373       ValExpr = Val.get();
22374 
22375       // OpenMP [2.7.1, Restrictions]
22376       //  chunk_size must be a loop invariant integer expression with a positive
22377       //  value.
22378       if (std::optional<llvm::APSInt> Result =
22379               ValExpr->getIntegerConstantExpr(getASTContext())) {
22380         if (Result->isSigned() && !Result->isStrictlyPositive()) {
22381           Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
22382               << "dist_schedule" << ChunkSize->getSourceRange();
22383           return nullptr;
22384         }
22385       } else if (getOpenMPCaptureRegionForClause(
22386                      DSAStack->getCurrentDirective(), OMPC_dist_schedule,
22387                      getLangOpts().OpenMP) != OMPD_unknown &&
22388                  !SemaRef.CurContext->isDependentContext()) {
22389         ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
22390         llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
22391         ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
22392         HelperValStmt = buildPreInits(getASTContext(), Captures);
22393       }
22394     }
22395   }
22396 
22397   return new (getASTContext())
22398       OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
22399                             Kind, ValExpr, HelperValStmt);
22400 }
22401 
22402 OMPClause *SemaOpenMP::ActOnOpenMPDefaultmapClause(
22403     OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
22404     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
22405     SourceLocation KindLoc, SourceLocation EndLoc) {
22406   if (getLangOpts().OpenMP < 50) {
22407     if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
22408         Kind != OMPC_DEFAULTMAP_scalar) {
22409       std::string Value;
22410       SourceLocation Loc;
22411       Value += "'";
22412       if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
22413         Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
22414                                                OMPC_DEFAULTMAP_MODIFIER_tofrom);
22415         Loc = MLoc;
22416       } else {
22417         Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
22418                                                OMPC_DEFAULTMAP_scalar);
22419         Loc = KindLoc;
22420       }
22421       Value += "'";
22422       Diag(Loc, diag::err_omp_unexpected_clause_value)
22423           << Value << getOpenMPClauseName(OMPC_defaultmap);
22424       return nullptr;
22425     }
22426   } else {
22427     bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown);
22428     bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) ||
22429                             (getLangOpts().OpenMP >= 50 && KindLoc.isInvalid());
22430     if (!isDefaultmapKind || !isDefaultmapModifier) {
22431       StringRef KindValue = getLangOpts().OpenMP < 52
22432                                 ? "'scalar', 'aggregate', 'pointer'"
22433                                 : "'scalar', 'aggregate', 'pointer', 'all'";
22434       if (getLangOpts().OpenMP == 50) {
22435         StringRef ModifierValue = "'alloc', 'from', 'to', 'tofrom', "
22436                                   "'firstprivate', 'none', 'default'";
22437         if (!isDefaultmapKind && isDefaultmapModifier) {
22438           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
22439               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
22440         } else if (isDefaultmapKind && !isDefaultmapModifier) {
22441           Diag(MLoc, diag::err_omp_unexpected_clause_value)
22442               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
22443         } else {
22444           Diag(MLoc, diag::err_omp_unexpected_clause_value)
22445               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
22446           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
22447               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
22448         }
22449       } else {
22450         StringRef ModifierValue =
22451             "'alloc', 'from', 'to', 'tofrom', "
22452             "'firstprivate', 'none', 'default', 'present'";
22453         if (!isDefaultmapKind && isDefaultmapModifier) {
22454           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
22455               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
22456         } else if (isDefaultmapKind && !isDefaultmapModifier) {
22457           Diag(MLoc, diag::err_omp_unexpected_clause_value)
22458               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
22459         } else {
22460           Diag(MLoc, diag::err_omp_unexpected_clause_value)
22461               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
22462           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
22463               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
22464         }
22465       }
22466       return nullptr;
22467     }
22468 
22469     // OpenMP [5.0, 2.12.5, Restrictions, p. 174]
22470     //  At most one defaultmap clause for each category can appear on the
22471     //  directive.
22472     if (DSAStack->checkDefaultmapCategory(Kind)) {
22473       Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
22474       return nullptr;
22475     }
22476   }
22477   if (Kind == OMPC_DEFAULTMAP_unknown || Kind == OMPC_DEFAULTMAP_all) {
22478     // Variable category is not specified - mark all categories.
22479     DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc);
22480     DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc);
22481     DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc);
22482   } else {
22483     DSAStack->setDefaultDMAAttr(M, Kind, StartLoc);
22484   }
22485 
22486   return new (getASTContext())
22487       OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
22488 }
22489 
22490 bool SemaOpenMP::ActOnStartOpenMPDeclareTargetContext(
22491     DeclareTargetContextInfo &DTCI) {
22492   DeclContext *CurLexicalContext = SemaRef.getCurLexicalContext();
22493   if (!CurLexicalContext->isFileContext() &&
22494       !CurLexicalContext->isExternCContext() &&
22495       !CurLexicalContext->isExternCXXContext() &&
22496       !isa<CXXRecordDecl>(CurLexicalContext) &&
22497       !isa<ClassTemplateDecl>(CurLexicalContext) &&
22498       !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
22499       !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
22500     Diag(DTCI.Loc, diag::err_omp_region_not_file_context);
22501     return false;
22502   }
22503 
22504   // Report affected OpenMP target offloading behavior when in HIP lang-mode.
22505   if (getLangOpts().HIP)
22506     Diag(DTCI.Loc, diag::warn_hip_omp_target_directives);
22507 
22508   DeclareTargetNesting.push_back(DTCI);
22509   return true;
22510 }
22511 
22512 const SemaOpenMP::DeclareTargetContextInfo
22513 SemaOpenMP::ActOnOpenMPEndDeclareTargetDirective() {
22514   assert(!DeclareTargetNesting.empty() &&
22515          "check isInOpenMPDeclareTargetContext() first!");
22516   return DeclareTargetNesting.pop_back_val();
22517 }
22518 
22519 void SemaOpenMP::ActOnFinishedOpenMPDeclareTargetContext(
22520     DeclareTargetContextInfo &DTCI) {
22521   for (auto &It : DTCI.ExplicitlyMapped)
22522     ActOnOpenMPDeclareTargetName(It.first, It.second.Loc, It.second.MT, DTCI);
22523 }
22524 
22525 void SemaOpenMP::DiagnoseUnterminatedOpenMPDeclareTarget() {
22526   if (DeclareTargetNesting.empty())
22527     return;
22528   DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back();
22529   Diag(DTCI.Loc, diag::warn_omp_unterminated_declare_target)
22530       << getOpenMPDirectiveName(DTCI.Kind);
22531 }
22532 
22533 NamedDecl *SemaOpenMP::lookupOpenMPDeclareTargetName(
22534     Scope *CurScope, CXXScopeSpec &ScopeSpec, const DeclarationNameInfo &Id) {
22535   LookupResult Lookup(SemaRef, Id, Sema::LookupOrdinaryName);
22536   SemaRef.LookupParsedName(Lookup, CurScope, &ScopeSpec,
22537                            /*ObjectType=*/QualType(),
22538                            /*AllowBuiltinCreation=*/true);
22539 
22540   if (Lookup.isAmbiguous())
22541     return nullptr;
22542   Lookup.suppressDiagnostics();
22543 
22544   if (!Lookup.isSingleResult()) {
22545     VarOrFuncDeclFilterCCC CCC(SemaRef);
22546     if (TypoCorrection Corrected =
22547             SemaRef.CorrectTypo(Id, Sema::LookupOrdinaryName, CurScope, nullptr,
22548                                 CCC, Sema::CTK_ErrorRecovery)) {
22549       SemaRef.diagnoseTypo(Corrected,
22550                            SemaRef.PDiag(diag::err_undeclared_var_use_suggest)
22551                                << Id.getName());
22552       checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
22553       return nullptr;
22554     }
22555 
22556     Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
22557     return nullptr;
22558   }
22559 
22560   NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
22561   if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
22562       !isa<FunctionTemplateDecl>(ND)) {
22563     Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
22564     return nullptr;
22565   }
22566   return ND;
22567 }
22568 
22569 void SemaOpenMP::ActOnOpenMPDeclareTargetName(
22570     NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT,
22571     DeclareTargetContextInfo &DTCI) {
22572   assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
22573           isa<FunctionTemplateDecl>(ND)) &&
22574          "Expected variable, function or function template.");
22575 
22576   if (auto *VD = dyn_cast<VarDecl>(ND)) {
22577     // Only global variables can be marked as declare target.
22578     if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
22579         !VD->isStaticDataMember()) {
22580       Diag(Loc, diag::err_omp_declare_target_has_local_vars)
22581           << VD->getNameAsString();
22582       return;
22583     }
22584   }
22585   // Diagnose marking after use as it may lead to incorrect diagnosis and
22586   // codegen.
22587   if (getLangOpts().OpenMP >= 50 &&
22588       (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced()))
22589     Diag(Loc, diag::warn_omp_declare_target_after_first_use);
22590 
22591   // Report affected OpenMP target offloading behavior when in HIP lang-mode.
22592   if (getLangOpts().HIP)
22593     Diag(Loc, diag::warn_hip_omp_target_directives);
22594 
22595   // Explicit declare target lists have precedence.
22596   const unsigned Level = -1;
22597 
22598   auto *VD = cast<ValueDecl>(ND);
22599   std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
22600       OMPDeclareTargetDeclAttr::getActiveAttr(VD);
22601   if (ActiveAttr && (*ActiveAttr)->getDevType() != DTCI.DT &&
22602       (*ActiveAttr)->getLevel() == Level) {
22603     Diag(Loc, diag::err_omp_device_type_mismatch)
22604         << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DTCI.DT)
22605         << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(
22606                (*ActiveAttr)->getDevType());
22607     return;
22608   }
22609   if (ActiveAttr && (*ActiveAttr)->getMapType() != MT &&
22610       (*ActiveAttr)->getLevel() == Level) {
22611     Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
22612     return;
22613   }
22614 
22615   if (ActiveAttr && (*ActiveAttr)->getLevel() == Level)
22616     return;
22617 
22618   Expr *IndirectE = nullptr;
22619   bool IsIndirect = false;
22620   if (DTCI.Indirect) {
22621     IndirectE = *DTCI.Indirect;
22622     if (!IndirectE)
22623       IsIndirect = true;
22624   }
22625   auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
22626       getASTContext(), MT, DTCI.DT, IndirectE, IsIndirect, Level,
22627       SourceRange(Loc, Loc));
22628   ND->addAttr(A);
22629   if (ASTMutationListener *ML = getASTContext().getASTMutationListener())
22630     ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
22631   checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc);
22632   if (auto *VD = dyn_cast<VarDecl>(ND);
22633       getLangOpts().OpenMP && VD && VD->hasAttr<OMPDeclareTargetDeclAttr>() &&
22634       VD->hasGlobalStorage())
22635     ActOnOpenMPDeclareTargetInitializer(ND);
22636 }
22637 
22638 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
22639                                      Sema &SemaRef, Decl *D) {
22640   if (!D || !isa<VarDecl>(D))
22641     return;
22642   auto *VD = cast<VarDecl>(D);
22643   std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
22644       OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
22645   if (SemaRef.LangOpts.OpenMP >= 50 &&
22646       (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) ||
22647        SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) &&
22648       VD->hasGlobalStorage()) {
22649     if (!MapTy || (*MapTy != OMPDeclareTargetDeclAttr::MT_To &&
22650                    *MapTy != OMPDeclareTargetDeclAttr::MT_Enter)) {
22651       // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
22652       // If a lambda declaration and definition appears between a
22653       // declare target directive and the matching end declare target
22654       // directive, all variables that are captured by the lambda
22655       // expression must also appear in a to clause.
22656       SemaRef.Diag(VD->getLocation(),
22657                    diag::err_omp_lambda_capture_in_declare_target_not_to);
22658       SemaRef.Diag(SL, diag::note_var_explicitly_captured_here)
22659           << VD << 0 << SR;
22660       return;
22661     }
22662   }
22663   if (MapTy)
22664     return;
22665   SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
22666   SemaRef.Diag(SL, diag::note_used_here) << SR;
22667 }
22668 
22669 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
22670                                    Sema &SemaRef, DSAStackTy *Stack,
22671                                    ValueDecl *VD) {
22672   return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
22673          checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
22674                            /*FullCheck=*/false);
22675 }
22676 
22677 void SemaOpenMP::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
22678                                                   SourceLocation IdLoc) {
22679   if (!D || D->isInvalidDecl())
22680     return;
22681   SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
22682   SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
22683   if (auto *VD = dyn_cast<VarDecl>(D)) {
22684     // Only global variables can be marked as declare target.
22685     if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
22686         !VD->isStaticDataMember())
22687       return;
22688     // 2.10.6: threadprivate variable cannot appear in a declare target
22689     // directive.
22690     if (DSAStack->isThreadPrivate(VD)) {
22691       Diag(SL, diag::err_omp_threadprivate_in_target);
22692       reportOriginalDsa(SemaRef, DSAStack, VD, DSAStack->getTopDSA(VD, false));
22693       return;
22694     }
22695   }
22696   if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
22697     D = FTD->getTemplatedDecl();
22698   if (auto *FD = dyn_cast<FunctionDecl>(D)) {
22699     std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
22700         OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
22701     if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
22702       Diag(IdLoc, diag::err_omp_function_in_link_clause);
22703       Diag(FD->getLocation(), diag::note_defined_here) << FD;
22704       return;
22705     }
22706   }
22707   if (auto *VD = dyn_cast<ValueDecl>(D)) {
22708     // Problem if any with var declared with incomplete type will be reported
22709     // as normal, so no need to check it here.
22710     if ((E || !VD->getType()->isIncompleteType()) &&
22711         !checkValueDeclInTarget(SL, SR, SemaRef, DSAStack, VD))
22712       return;
22713     if (!E && isInOpenMPDeclareTargetContext()) {
22714       // Checking declaration inside declare target region.
22715       if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
22716           isa<FunctionTemplateDecl>(D)) {
22717         std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
22718             OMPDeclareTargetDeclAttr::getActiveAttr(VD);
22719         unsigned Level = DeclareTargetNesting.size();
22720         if (ActiveAttr && (*ActiveAttr)->getLevel() >= Level)
22721           return;
22722         DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back();
22723         Expr *IndirectE = nullptr;
22724         bool IsIndirect = false;
22725         if (DTCI.Indirect) {
22726           IndirectE = *DTCI.Indirect;
22727           if (!IndirectE)
22728             IsIndirect = true;
22729         }
22730         auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
22731             getASTContext(),
22732             getLangOpts().OpenMP >= 52 ? OMPDeclareTargetDeclAttr::MT_Enter
22733                                        : OMPDeclareTargetDeclAttr::MT_To,
22734             DTCI.DT, IndirectE, IsIndirect, Level,
22735             SourceRange(DTCI.Loc, DTCI.Loc));
22736         D->addAttr(A);
22737         if (ASTMutationListener *ML = getASTContext().getASTMutationListener())
22738           ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
22739       }
22740       return;
22741     }
22742   }
22743   if (!E)
22744     return;
22745   checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), SemaRef, D);
22746 }
22747 
22748 /// This class visits every VarDecl that the initializer references and adds
22749 /// OMPDeclareTargetDeclAttr to each of them.
22750 class GlobalDeclRefChecker final : public StmtVisitor<GlobalDeclRefChecker> {
22751   SmallVector<VarDecl *> DeclVector;
22752   Attr *A;
22753 
22754 public:
22755   /// A StmtVisitor class function that visits all DeclRefExpr and adds
22756   /// OMPDeclareTargetDeclAttr to them.
22757   void VisitDeclRefExpr(DeclRefExpr *Node) {
22758     if (auto *VD = dyn_cast<VarDecl>(Node->getDecl())) {
22759       VD->addAttr(A);
22760       DeclVector.push_back(VD);
22761     }
22762   }
22763   /// A function that iterates across each of the Expr's children.
22764   void VisitExpr(Expr *Ex) {
22765     for (auto *Child : Ex->children()) {
22766       Visit(Child);
22767     }
22768   }
22769   /// A function that keeps a record of all the Decls that are variables, has
22770   /// OMPDeclareTargetDeclAttr, and has global storage in the DeclVector. Pop
22771   /// each Decl one at a time and use the inherited 'visit' functions to look
22772   /// for DeclRefExpr.
22773   void declareTargetInitializer(Decl *TD) {
22774     A = TD->getAttr<OMPDeclareTargetDeclAttr>();
22775     DeclVector.push_back(cast<VarDecl>(TD));
22776     while (!DeclVector.empty()) {
22777       VarDecl *TargetVarDecl = DeclVector.pop_back_val();
22778       if (TargetVarDecl->hasAttr<OMPDeclareTargetDeclAttr>() &&
22779           TargetVarDecl->hasInit() && TargetVarDecl->hasGlobalStorage()) {
22780         if (Expr *Ex = TargetVarDecl->getInit())
22781           Visit(Ex);
22782       }
22783     }
22784   }
22785 };
22786 
22787 /// Adding OMPDeclareTargetDeclAttr to variables with static storage
22788 /// duration that are referenced in the initializer expression list of
22789 /// variables with static storage duration in declare target directive.
22790 void SemaOpenMP::ActOnOpenMPDeclareTargetInitializer(Decl *TargetDecl) {
22791   GlobalDeclRefChecker Checker;
22792   if (isa<VarDecl>(TargetDecl))
22793     Checker.declareTargetInitializer(TargetDecl);
22794 }
22795 
22796 OMPClause *SemaOpenMP::ActOnOpenMPToClause(
22797     ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
22798     ArrayRef<SourceLocation> MotionModifiersLoc,
22799     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
22800     SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
22801     const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
22802   OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
22803                                           OMPC_MOTION_MODIFIER_unknown};
22804   SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
22805 
22806   // Process motion-modifiers, flag errors for duplicate modifiers.
22807   unsigned Count = 0;
22808   for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
22809     if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
22810         llvm::is_contained(Modifiers, MotionModifiers[I])) {
22811       Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
22812       continue;
22813     }
22814     assert(Count < NumberOfOMPMotionModifiers &&
22815            "Modifiers exceed the allowed number of motion modifiers");
22816     Modifiers[Count] = MotionModifiers[I];
22817     ModifiersLoc[Count] = MotionModifiersLoc[I];
22818     ++Count;
22819   }
22820 
22821   MappableVarListInfo MVLI(VarList);
22822   checkMappableExpressionList(SemaRef, DSAStack, OMPC_to, MVLI, Locs.StartLoc,
22823                               MapperIdScopeSpec, MapperId, UnresolvedMappers);
22824   if (MVLI.ProcessedVarList.empty())
22825     return nullptr;
22826 
22827   return OMPToClause::Create(
22828       getASTContext(), Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
22829       MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
22830       MapperIdScopeSpec.getWithLocInContext(getASTContext()), MapperId);
22831 }
22832 
22833 OMPClause *SemaOpenMP::ActOnOpenMPFromClause(
22834     ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
22835     ArrayRef<SourceLocation> MotionModifiersLoc,
22836     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
22837     SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
22838     const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
22839   OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
22840                                           OMPC_MOTION_MODIFIER_unknown};
22841   SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
22842 
22843   // Process motion-modifiers, flag errors for duplicate modifiers.
22844   unsigned Count = 0;
22845   for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
22846     if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
22847         llvm::is_contained(Modifiers, MotionModifiers[I])) {
22848       Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
22849       continue;
22850     }
22851     assert(Count < NumberOfOMPMotionModifiers &&
22852            "Modifiers exceed the allowed number of motion modifiers");
22853     Modifiers[Count] = MotionModifiers[I];
22854     ModifiersLoc[Count] = MotionModifiersLoc[I];
22855     ++Count;
22856   }
22857 
22858   MappableVarListInfo MVLI(VarList);
22859   checkMappableExpressionList(SemaRef, DSAStack, OMPC_from, MVLI, Locs.StartLoc,
22860                               MapperIdScopeSpec, MapperId, UnresolvedMappers);
22861   if (MVLI.ProcessedVarList.empty())
22862     return nullptr;
22863 
22864   return OMPFromClause::Create(
22865       getASTContext(), Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
22866       MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
22867       MapperIdScopeSpec.getWithLocInContext(getASTContext()), MapperId);
22868 }
22869 
22870 OMPClause *
22871 SemaOpenMP::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
22872                                           const OMPVarListLocTy &Locs) {
22873   MappableVarListInfo MVLI(VarList);
22874   SmallVector<Expr *, 8> PrivateCopies;
22875   SmallVector<Expr *, 8> Inits;
22876 
22877   for (Expr *RefExpr : VarList) {
22878     assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
22879     SourceLocation ELoc;
22880     SourceRange ERange;
22881     Expr *SimpleRefExpr = RefExpr;
22882     auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
22883     if (Res.second) {
22884       // It will be analyzed later.
22885       MVLI.ProcessedVarList.push_back(RefExpr);
22886       PrivateCopies.push_back(nullptr);
22887       Inits.push_back(nullptr);
22888     }
22889     ValueDecl *D = Res.first;
22890     if (!D)
22891       continue;
22892 
22893     QualType Type = D->getType();
22894     Type = Type.getNonReferenceType().getUnqualifiedType();
22895 
22896     auto *VD = dyn_cast<VarDecl>(D);
22897 
22898     // Item should be a pointer or reference to pointer.
22899     if (!Type->isPointerType()) {
22900       Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
22901           << 0 << RefExpr->getSourceRange();
22902       continue;
22903     }
22904 
22905     // Build the private variable and the expression that refers to it.
22906     auto VDPrivate =
22907         buildVarDecl(SemaRef, ELoc, Type, D->getName(),
22908                      D->hasAttrs() ? &D->getAttrs() : nullptr,
22909                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
22910     if (VDPrivate->isInvalidDecl())
22911       continue;
22912 
22913     SemaRef.CurContext->addDecl(VDPrivate);
22914     DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
22915         SemaRef, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
22916 
22917     // Add temporary variable to initialize the private copy of the pointer.
22918     VarDecl *VDInit =
22919         buildVarDecl(SemaRef, RefExpr->getExprLoc(), Type, ".devptr.temp");
22920     DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
22921         SemaRef, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
22922     SemaRef.AddInitializerToDecl(
22923         VDPrivate, SemaRef.DefaultLvalueConversion(VDInitRefExpr).get(),
22924         /*DirectInit=*/false);
22925 
22926     // If required, build a capture to implement the privatization initialized
22927     // with the current list item value.
22928     DeclRefExpr *Ref = nullptr;
22929     if (!VD)
22930       Ref = buildCapture(SemaRef, D, SimpleRefExpr, /*WithInit=*/true);
22931     MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
22932     PrivateCopies.push_back(VDPrivateRefExpr);
22933     Inits.push_back(VDInitRefExpr);
22934 
22935     // We need to add a data sharing attribute for this variable to make sure it
22936     // is correctly captured. A variable that shows up in a use_device_ptr has
22937     // similar properties of a first private variable.
22938     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
22939 
22940     // Create a mappable component for the list item. List items in this clause
22941     // only need a component.
22942     MVLI.VarBaseDeclarations.push_back(D);
22943     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
22944     MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D,
22945                                            /*IsNonContiguous=*/false);
22946   }
22947 
22948   if (MVLI.ProcessedVarList.empty())
22949     return nullptr;
22950 
22951   return OMPUseDevicePtrClause::Create(
22952       getASTContext(), Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
22953       MVLI.VarBaseDeclarations, MVLI.VarComponents);
22954 }
22955 
22956 OMPClause *
22957 SemaOpenMP::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
22958                                            const OMPVarListLocTy &Locs) {
22959   MappableVarListInfo MVLI(VarList);
22960 
22961   for (Expr *RefExpr : VarList) {
22962     assert(RefExpr && "NULL expr in OpenMP use_device_addr clause.");
22963     SourceLocation ELoc;
22964     SourceRange ERange;
22965     Expr *SimpleRefExpr = RefExpr;
22966     auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange,
22967                               /*AllowArraySection=*/true);
22968     if (Res.second) {
22969       // It will be analyzed later.
22970       MVLI.ProcessedVarList.push_back(RefExpr);
22971     }
22972     ValueDecl *D = Res.first;
22973     if (!D)
22974       continue;
22975     auto *VD = dyn_cast<VarDecl>(D);
22976 
22977     // If required, build a capture to implement the privatization initialized
22978     // with the current list item value.
22979     DeclRefExpr *Ref = nullptr;
22980     if (!VD)
22981       Ref = buildCapture(SemaRef, D, SimpleRefExpr, /*WithInit=*/true);
22982     MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
22983 
22984     // We need to add a data sharing attribute for this variable to make sure it
22985     // is correctly captured. A variable that shows up in a use_device_addr has
22986     // similar properties of a first private variable.
22987     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
22988 
22989     // Create a mappable component for the list item. List items in this clause
22990     // only need a component.
22991     MVLI.VarBaseDeclarations.push_back(D);
22992     MVLI.VarComponents.emplace_back();
22993     Expr *Component = SimpleRefExpr;
22994     if (VD && (isa<ArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
22995                isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
22996       Component =
22997           SemaRef.DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
22998     MVLI.VarComponents.back().emplace_back(Component, D,
22999                                            /*IsNonContiguous=*/false);
23000   }
23001 
23002   if (MVLI.ProcessedVarList.empty())
23003     return nullptr;
23004 
23005   return OMPUseDeviceAddrClause::Create(
23006       getASTContext(), Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
23007       MVLI.VarComponents);
23008 }
23009 
23010 OMPClause *
23011 SemaOpenMP::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
23012                                          const OMPVarListLocTy &Locs) {
23013   MappableVarListInfo MVLI(VarList);
23014   for (Expr *RefExpr : VarList) {
23015     assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
23016     SourceLocation ELoc;
23017     SourceRange ERange;
23018     Expr *SimpleRefExpr = RefExpr;
23019     auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
23020     if (Res.second) {
23021       // It will be analyzed later.
23022       MVLI.ProcessedVarList.push_back(RefExpr);
23023     }
23024     ValueDecl *D = Res.first;
23025     if (!D)
23026       continue;
23027 
23028     QualType Type = D->getType();
23029     // item should be a pointer or array or reference to pointer or array
23030     if (!Type.getNonReferenceType()->isPointerType() &&
23031         !Type.getNonReferenceType()->isArrayType()) {
23032       Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
23033           << 0 << RefExpr->getSourceRange();
23034       continue;
23035     }
23036 
23037     // Check if the declaration in the clause does not show up in any data
23038     // sharing attribute.
23039     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
23040     if (isOpenMPPrivate(DVar.CKind)) {
23041       Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
23042           << getOpenMPClauseName(DVar.CKind)
23043           << getOpenMPClauseName(OMPC_is_device_ptr)
23044           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
23045       reportOriginalDsa(SemaRef, DSAStack, D, DVar);
23046       continue;
23047     }
23048 
23049     const Expr *ConflictExpr;
23050     if (DSAStack->checkMappableExprComponentListsForDecl(
23051             D, /*CurrentRegionOnly=*/true,
23052             [&ConflictExpr](
23053                 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
23054                 OpenMPClauseKind) -> bool {
23055               ConflictExpr = R.front().getAssociatedExpression();
23056               return true;
23057             })) {
23058       Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
23059       Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
23060           << ConflictExpr->getSourceRange();
23061       continue;
23062     }
23063 
23064     // Store the components in the stack so that they can be used to check
23065     // against other clauses later on.
23066     OMPClauseMappableExprCommon::MappableComponent MC(
23067         SimpleRefExpr, D, /*IsNonContiguous=*/false);
23068     DSAStack->addMappableExpressionComponents(
23069         D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
23070 
23071     // Record the expression we've just processed.
23072     MVLI.ProcessedVarList.push_back(SimpleRefExpr);
23073 
23074     // Create a mappable component for the list item. List items in this clause
23075     // only need a component. We use a null declaration to signal fields in
23076     // 'this'.
23077     assert((isa<DeclRefExpr>(SimpleRefExpr) ||
23078             isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
23079            "Unexpected device pointer expression!");
23080     MVLI.VarBaseDeclarations.push_back(
23081         isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
23082     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
23083     MVLI.VarComponents.back().push_back(MC);
23084   }
23085 
23086   if (MVLI.ProcessedVarList.empty())
23087     return nullptr;
23088 
23089   return OMPIsDevicePtrClause::Create(
23090       getASTContext(), Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
23091       MVLI.VarComponents);
23092 }
23093 
23094 OMPClause *
23095 SemaOpenMP::ActOnOpenMPHasDeviceAddrClause(ArrayRef<Expr *> VarList,
23096                                            const OMPVarListLocTy &Locs) {
23097   MappableVarListInfo MVLI(VarList);
23098   for (Expr *RefExpr : VarList) {
23099     assert(RefExpr && "NULL expr in OpenMP has_device_addr clause.");
23100     SourceLocation ELoc;
23101     SourceRange ERange;
23102     Expr *SimpleRefExpr = RefExpr;
23103     auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange,
23104                               /*AllowArraySection=*/true);
23105     if (Res.second) {
23106       // It will be analyzed later.
23107       MVLI.ProcessedVarList.push_back(RefExpr);
23108     }
23109     ValueDecl *D = Res.first;
23110     if (!D)
23111       continue;
23112 
23113     // Check if the declaration in the clause does not show up in any data
23114     // sharing attribute.
23115     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
23116     if (isOpenMPPrivate(DVar.CKind)) {
23117       Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
23118           << getOpenMPClauseName(DVar.CKind)
23119           << getOpenMPClauseName(OMPC_has_device_addr)
23120           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
23121       reportOriginalDsa(SemaRef, DSAStack, D, DVar);
23122       continue;
23123     }
23124 
23125     const Expr *ConflictExpr;
23126     if (DSAStack->checkMappableExprComponentListsForDecl(
23127             D, /*CurrentRegionOnly=*/true,
23128             [&ConflictExpr](
23129                 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
23130                 OpenMPClauseKind) -> bool {
23131               ConflictExpr = R.front().getAssociatedExpression();
23132               return true;
23133             })) {
23134       Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
23135       Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
23136           << ConflictExpr->getSourceRange();
23137       continue;
23138     }
23139 
23140     // Store the components in the stack so that they can be used to check
23141     // against other clauses later on.
23142     Expr *Component = SimpleRefExpr;
23143     auto *VD = dyn_cast<VarDecl>(D);
23144     if (VD && (isa<ArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
23145                isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
23146       Component =
23147           SemaRef.DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
23148     OMPClauseMappableExprCommon::MappableComponent MC(
23149         Component, D, /*IsNonContiguous=*/false);
23150     DSAStack->addMappableExpressionComponents(
23151         D, MC, /*WhereFoundClauseKind=*/OMPC_has_device_addr);
23152 
23153     // Record the expression we've just processed.
23154     if (!VD && !SemaRef.CurContext->isDependentContext()) {
23155       DeclRefExpr *Ref =
23156           buildCapture(SemaRef, D, SimpleRefExpr, /*WithInit=*/true);
23157       assert(Ref && "has_device_addr capture failed");
23158       MVLI.ProcessedVarList.push_back(Ref);
23159     } else
23160       MVLI.ProcessedVarList.push_back(RefExpr->IgnoreParens());
23161 
23162     // Create a mappable component for the list item. List items in this clause
23163     // only need a component. We use a null declaration to signal fields in
23164     // 'this'.
23165     assert((isa<DeclRefExpr>(SimpleRefExpr) ||
23166             isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
23167            "Unexpected device pointer expression!");
23168     MVLI.VarBaseDeclarations.push_back(
23169         isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
23170     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
23171     MVLI.VarComponents.back().push_back(MC);
23172   }
23173 
23174   if (MVLI.ProcessedVarList.empty())
23175     return nullptr;
23176 
23177   return OMPHasDeviceAddrClause::Create(
23178       getASTContext(), Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
23179       MVLI.VarComponents);
23180 }
23181 
23182 OMPClause *SemaOpenMP::ActOnOpenMPAllocateClause(
23183     Expr *Allocator, Expr *Alignment,
23184     OpenMPAllocateClauseModifier FirstAllocateModifier,
23185     SourceLocation FirstAllocateModifierLoc,
23186     OpenMPAllocateClauseModifier SecondAllocateModifier,
23187     SourceLocation SecondAllocateModifierLoc, ArrayRef<Expr *> VarList,
23188     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
23189     SourceLocation EndLoc) {
23190   if (Allocator) {
23191     // Allocator expression is dependent - skip it for now and build the
23192     // allocator when instantiated.
23193     bool AllocDependent =
23194         (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
23195          Allocator->isInstantiationDependent() ||
23196          Allocator->containsUnexpandedParameterPack());
23197     if (!AllocDependent) {
23198       // OpenMP [2.11.4 allocate Clause, Description]
23199       // allocator is an expression of omp_allocator_handle_t type.
23200       if (!findOMPAllocatorHandleT(SemaRef, Allocator->getExprLoc(), DSAStack))
23201         return nullptr;
23202 
23203       ExprResult AllocatorRes = SemaRef.DefaultLvalueConversion(Allocator);
23204       if (AllocatorRes.isInvalid())
23205         return nullptr;
23206       AllocatorRes = SemaRef.PerformImplicitConversion(
23207           AllocatorRes.get(), DSAStack->getOMPAllocatorHandleT(),
23208           AssignmentAction::Initializing,
23209           /*AllowExplicit=*/true);
23210       if (AllocatorRes.isInvalid())
23211         return nullptr;
23212       Allocator = AllocatorRes.isUsable() ? AllocatorRes.get() : nullptr;
23213     }
23214   } else {
23215     // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
23216     // allocate clauses that appear on a target construct or on constructs in a
23217     // target region must specify an allocator expression unless a requires
23218     // directive with the dynamic_allocators clause is present in the same
23219     // compilation unit.
23220     if (getLangOpts().OpenMPIsTargetDevice &&
23221         !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
23222       SemaRef.targetDiag(StartLoc, diag::err_expected_allocator_expression);
23223   }
23224   if (Alignment) {
23225     bool AlignmentDependent = Alignment->isTypeDependent() ||
23226                               Alignment->isValueDependent() ||
23227                               Alignment->isInstantiationDependent() ||
23228                               Alignment->containsUnexpandedParameterPack();
23229     if (!AlignmentDependent) {
23230       ExprResult AlignResult =
23231           VerifyPositiveIntegerConstantInClause(Alignment, OMPC_allocate);
23232       Alignment = AlignResult.isUsable() ? AlignResult.get() : nullptr;
23233     }
23234   }
23235   // Analyze and build list of variables.
23236   SmallVector<Expr *, 8> Vars;
23237   for (Expr *RefExpr : VarList) {
23238     assert(RefExpr && "NULL expr in OpenMP private clause.");
23239     SourceLocation ELoc;
23240     SourceRange ERange;
23241     Expr *SimpleRefExpr = RefExpr;
23242     auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
23243     if (Res.second) {
23244       // It will be analyzed later.
23245       Vars.push_back(RefExpr);
23246     }
23247     ValueDecl *D = Res.first;
23248     if (!D)
23249       continue;
23250 
23251     auto *VD = dyn_cast<VarDecl>(D);
23252     DeclRefExpr *Ref = nullptr;
23253     if (!VD && !SemaRef.CurContext->isDependentContext())
23254       Ref = buildCapture(SemaRef, D, SimpleRefExpr, /*WithInit=*/false);
23255     Vars.push_back((VD || SemaRef.CurContext->isDependentContext())
23256                        ? RefExpr->IgnoreParens()
23257                        : Ref);
23258   }
23259 
23260   if (Vars.empty())
23261     return nullptr;
23262 
23263   if (Allocator)
23264     DSAStack->addInnerAllocatorExpr(Allocator);
23265 
23266   return OMPAllocateClause::Create(
23267       getASTContext(), StartLoc, LParenLoc, Allocator, Alignment, ColonLoc,
23268       FirstAllocateModifier, FirstAllocateModifierLoc, SecondAllocateModifier,
23269       SecondAllocateModifierLoc, EndLoc, Vars);
23270 }
23271 
23272 OMPClause *SemaOpenMP::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
23273                                                     SourceLocation StartLoc,
23274                                                     SourceLocation LParenLoc,
23275                                                     SourceLocation EndLoc) {
23276   SmallVector<Expr *, 8> Vars;
23277   for (Expr *RefExpr : VarList) {
23278     assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
23279     SourceLocation ELoc;
23280     SourceRange ERange;
23281     Expr *SimpleRefExpr = RefExpr;
23282     auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
23283     if (Res.second)
23284       // It will be analyzed later.
23285       Vars.push_back(RefExpr);
23286     ValueDecl *D = Res.first;
23287     if (!D)
23288       continue;
23289 
23290     // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions.
23291     // A list-item cannot appear in more than one nontemporal clause.
23292     if (const Expr *PrevRef =
23293             DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) {
23294       Diag(ELoc, diag::err_omp_used_in_clause_twice)
23295           << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
23296       Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
23297           << getOpenMPClauseName(OMPC_nontemporal);
23298       continue;
23299     }
23300 
23301     Vars.push_back(RefExpr);
23302   }
23303 
23304   if (Vars.empty())
23305     return nullptr;
23306 
23307   return OMPNontemporalClause::Create(getASTContext(), StartLoc, LParenLoc,
23308                                       EndLoc, Vars);
23309 }
23310 
23311 StmtResult SemaOpenMP::ActOnOpenMPScopeDirective(ArrayRef<OMPClause *> Clauses,
23312                                                  Stmt *AStmt,
23313                                                  SourceLocation StartLoc,
23314                                                  SourceLocation EndLoc) {
23315   if (!AStmt)
23316     return StmtError();
23317 
23318   SemaRef.setFunctionHasBranchProtectedScope();
23319 
23320   return OMPScopeDirective::Create(getASTContext(), StartLoc, EndLoc, Clauses,
23321                                    AStmt);
23322 }
23323 
23324 OMPClause *SemaOpenMP::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList,
23325                                                   SourceLocation StartLoc,
23326                                                   SourceLocation LParenLoc,
23327                                                   SourceLocation EndLoc) {
23328   SmallVector<Expr *, 8> Vars;
23329   for (Expr *RefExpr : VarList) {
23330     assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
23331     SourceLocation ELoc;
23332     SourceRange ERange;
23333     Expr *SimpleRefExpr = RefExpr;
23334     auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange,
23335                               /*AllowArraySection=*/true);
23336     if (Res.second)
23337       // It will be analyzed later.
23338       Vars.push_back(RefExpr);
23339     ValueDecl *D = Res.first;
23340     if (!D)
23341       continue;
23342 
23343     const DSAStackTy::DSAVarData DVar =
23344         DSAStack->getTopDSA(D, /*FromParent=*/true);
23345     // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
23346     // A list item that appears in the inclusive or exclusive clause must appear
23347     // in a reduction clause with the inscan modifier on the enclosing
23348     // worksharing-loop, worksharing-loop SIMD, or simd construct.
23349     if (DVar.CKind != OMPC_reduction || DVar.Modifier != OMPC_REDUCTION_inscan)
23350       Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
23351           << RefExpr->getSourceRange();
23352 
23353     if (DSAStack->getParentDirective() != OMPD_unknown)
23354       DSAStack->markDeclAsUsedInScanDirective(D);
23355     Vars.push_back(RefExpr);
23356   }
23357 
23358   if (Vars.empty())
23359     return nullptr;
23360 
23361   return OMPInclusiveClause::Create(getASTContext(), StartLoc, LParenLoc,
23362                                     EndLoc, Vars);
23363 }
23364 
23365 OMPClause *SemaOpenMP::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList,
23366                                                   SourceLocation StartLoc,
23367                                                   SourceLocation LParenLoc,
23368                                                   SourceLocation EndLoc) {
23369   SmallVector<Expr *, 8> Vars;
23370   for (Expr *RefExpr : VarList) {
23371     assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
23372     SourceLocation ELoc;
23373     SourceRange ERange;
23374     Expr *SimpleRefExpr = RefExpr;
23375     auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange,
23376                               /*AllowArraySection=*/true);
23377     if (Res.second)
23378       // It will be analyzed later.
23379       Vars.push_back(RefExpr);
23380     ValueDecl *D = Res.first;
23381     if (!D)
23382       continue;
23383 
23384     OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective();
23385     DSAStackTy::DSAVarData DVar;
23386     if (ParentDirective != OMPD_unknown)
23387       DVar = DSAStack->getTopDSA(D, /*FromParent=*/true);
23388     // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
23389     // A list item that appears in the inclusive or exclusive clause must appear
23390     // in a reduction clause with the inscan modifier on the enclosing
23391     // worksharing-loop, worksharing-loop SIMD, or simd construct.
23392     if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction ||
23393         DVar.Modifier != OMPC_REDUCTION_inscan) {
23394       Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
23395           << RefExpr->getSourceRange();
23396     } else {
23397       DSAStack->markDeclAsUsedInScanDirective(D);
23398     }
23399     Vars.push_back(RefExpr);
23400   }
23401 
23402   if (Vars.empty())
23403     return nullptr;
23404 
23405   return OMPExclusiveClause::Create(getASTContext(), StartLoc, LParenLoc,
23406                                     EndLoc, Vars);
23407 }
23408 
23409 /// Tries to find omp_alloctrait_t type.
23410 static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) {
23411   QualType OMPAlloctraitT = Stack->getOMPAlloctraitT();
23412   if (!OMPAlloctraitT.isNull())
23413     return true;
23414   IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t");
23415   ParsedType PT = S.getTypeName(II, Loc, S.getCurScope());
23416   if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
23417     S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t";
23418     return false;
23419   }
23420   Stack->setOMPAlloctraitT(PT.get());
23421   return true;
23422 }
23423 
23424 OMPClause *SemaOpenMP::ActOnOpenMPUsesAllocatorClause(
23425     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
23426     ArrayRef<UsesAllocatorsData> Data) {
23427   ASTContext &Context = getASTContext();
23428   // OpenMP [2.12.5, target Construct]
23429   // allocator is an identifier of omp_allocator_handle_t type.
23430   if (!findOMPAllocatorHandleT(SemaRef, StartLoc, DSAStack))
23431     return nullptr;
23432   // OpenMP [2.12.5, target Construct]
23433   // allocator-traits-array is an identifier of const omp_alloctrait_t * type.
23434   if (llvm::any_of(
23435           Data,
23436           [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) &&
23437       !findOMPAlloctraitT(SemaRef, StartLoc, DSAStack))
23438     return nullptr;
23439   llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators;
23440   for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
23441     auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
23442     StringRef Allocator =
23443         OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
23444     DeclarationName AllocatorName = &Context.Idents.get(Allocator);
23445     PredefinedAllocators.insert(SemaRef.LookupSingleName(
23446         SemaRef.TUScope, AllocatorName, StartLoc, Sema::LookupAnyName));
23447   }
23448 
23449   SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData;
23450   for (const UsesAllocatorsData &D : Data) {
23451     Expr *AllocatorExpr = nullptr;
23452     // Check allocator expression.
23453     if (D.Allocator->isTypeDependent()) {
23454       AllocatorExpr = D.Allocator;
23455     } else {
23456       // Traits were specified - need to assign new allocator to the specified
23457       // allocator, so it must be an lvalue.
23458       AllocatorExpr = D.Allocator->IgnoreParenImpCasts();
23459       auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr);
23460       bool IsPredefinedAllocator = false;
23461       if (DRE) {
23462         OMPAllocateDeclAttr::AllocatorTypeTy AllocatorTy =
23463             getAllocatorKind(SemaRef, DSAStack, AllocatorExpr);
23464         IsPredefinedAllocator =
23465             AllocatorTy !=
23466             OMPAllocateDeclAttr::AllocatorTypeTy::OMPUserDefinedMemAlloc;
23467       }
23468       QualType OMPAllocatorHandleT = DSAStack->getOMPAllocatorHandleT();
23469       QualType AllocatorExprType = AllocatorExpr->getType();
23470       bool IsTypeCompatible = IsPredefinedAllocator;
23471       IsTypeCompatible = IsTypeCompatible ||
23472                          Context.hasSameUnqualifiedType(AllocatorExprType,
23473                                                         OMPAllocatorHandleT);
23474       IsTypeCompatible =
23475           IsTypeCompatible ||
23476           Context.typesAreCompatible(AllocatorExprType, OMPAllocatorHandleT);
23477       bool IsNonConstantLValue =
23478           !AllocatorExprType.isConstant(Context) && AllocatorExpr->isLValue();
23479       if (!DRE || !IsTypeCompatible ||
23480           (!IsPredefinedAllocator && !IsNonConstantLValue)) {
23481         Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected)
23482             << "omp_allocator_handle_t" << (DRE ? 1 : 0)
23483             << AllocatorExpr->getType() << D.Allocator->getSourceRange();
23484         continue;
23485       }
23486       // OpenMP [2.12.5, target Construct]
23487       // Predefined allocators appearing in a uses_allocators clause cannot have
23488       // traits specified.
23489       if (IsPredefinedAllocator && D.AllocatorTraits) {
23490         Diag(D.AllocatorTraits->getExprLoc(),
23491              diag::err_omp_predefined_allocator_with_traits)
23492             << D.AllocatorTraits->getSourceRange();
23493         Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator)
23494             << cast<NamedDecl>(DRE->getDecl())->getName()
23495             << D.Allocator->getSourceRange();
23496         continue;
23497       }
23498       // OpenMP [2.12.5, target Construct]
23499       // Non-predefined allocators appearing in a uses_allocators clause must
23500       // have traits specified.
23501       if (!IsPredefinedAllocator && !D.AllocatorTraits) {
23502         Diag(D.Allocator->getExprLoc(),
23503              diag::err_omp_nonpredefined_allocator_without_traits);
23504         continue;
23505       }
23506       // No allocator traits - just convert it to rvalue.
23507       if (!D.AllocatorTraits)
23508         AllocatorExpr = SemaRef.DefaultLvalueConversion(AllocatorExpr).get();
23509       DSAStack->addUsesAllocatorsDecl(
23510           DRE->getDecl(),
23511           IsPredefinedAllocator
23512               ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator
23513               : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator);
23514     }
23515     Expr *AllocatorTraitsExpr = nullptr;
23516     if (D.AllocatorTraits) {
23517       if (D.AllocatorTraits->isTypeDependent()) {
23518         AllocatorTraitsExpr = D.AllocatorTraits;
23519       } else {
23520         // OpenMP [2.12.5, target Construct]
23521         // Arrays that contain allocator traits that appear in a uses_allocators
23522         // clause must be constant arrays, have constant values and be defined
23523         // in the same scope as the construct in which the clause appears.
23524         AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts();
23525         // Check that traits expr is a constant array.
23526         QualType TraitTy;
23527         if (const ArrayType *Ty =
23528                 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe())
23529           if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty))
23530             TraitTy = ConstArrayTy->getElementType();
23531         if (TraitTy.isNull() ||
23532             !(Context.hasSameUnqualifiedType(TraitTy,
23533                                              DSAStack->getOMPAlloctraitT()) ||
23534               Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(),
23535                                          /*CompareUnqualified=*/true))) {
23536           Diag(D.AllocatorTraits->getExprLoc(),
23537                diag::err_omp_expected_array_alloctraits)
23538               << AllocatorTraitsExpr->getType();
23539           continue;
23540         }
23541         // Do not map by default allocator traits if it is a standalone
23542         // variable.
23543         if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr))
23544           DSAStack->addUsesAllocatorsDecl(
23545               DRE->getDecl(),
23546               DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait);
23547       }
23548     }
23549     OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back();
23550     NewD.Allocator = AllocatorExpr;
23551     NewD.AllocatorTraits = AllocatorTraitsExpr;
23552     NewD.LParenLoc = D.LParenLoc;
23553     NewD.RParenLoc = D.RParenLoc;
23554   }
23555   return OMPUsesAllocatorsClause::Create(getASTContext(), StartLoc, LParenLoc,
23556                                          EndLoc, NewData);
23557 }
23558 
23559 OMPClause *SemaOpenMP::ActOnOpenMPAffinityClause(
23560     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
23561     SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) {
23562   SmallVector<Expr *, 8> Vars;
23563   for (Expr *RefExpr : Locators) {
23564     assert(RefExpr && "NULL expr in OpenMP shared clause.");
23565     if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) {
23566       // It will be analyzed later.
23567       Vars.push_back(RefExpr);
23568       continue;
23569     }
23570 
23571     SourceLocation ELoc = RefExpr->getExprLoc();
23572     Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts();
23573 
23574     if (!SimpleExpr->isLValue()) {
23575       Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
23576           << 1 << 0 << RefExpr->getSourceRange();
23577       continue;
23578     }
23579 
23580     ExprResult Res;
23581     {
23582       Sema::TentativeAnalysisScope Trap(SemaRef);
23583       Res = SemaRef.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr);
23584     }
23585     if (!Res.isUsable() && !isa<ArraySectionExpr>(SimpleExpr) &&
23586         !isa<OMPArrayShapingExpr>(SimpleExpr)) {
23587       Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
23588           << 1 << 0 << RefExpr->getSourceRange();
23589       continue;
23590     }
23591     Vars.push_back(SimpleExpr);
23592   }
23593 
23594   return OMPAffinityClause::Create(getASTContext(), StartLoc, LParenLoc,
23595                                    ColonLoc, EndLoc, Modifier, Vars);
23596 }
23597 
23598 OMPClause *SemaOpenMP::ActOnOpenMPBindClause(OpenMPBindClauseKind Kind,
23599                                              SourceLocation KindLoc,
23600                                              SourceLocation StartLoc,
23601                                              SourceLocation LParenLoc,
23602                                              SourceLocation EndLoc) {
23603   if (Kind == OMPC_BIND_unknown) {
23604     Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23605         << getListOfPossibleValues(OMPC_bind, /*First=*/0,
23606                                    /*Last=*/unsigned(OMPC_BIND_unknown))
23607         << getOpenMPClauseName(OMPC_bind);
23608     return nullptr;
23609   }
23610 
23611   return OMPBindClause::Create(getASTContext(), Kind, KindLoc, StartLoc,
23612                                LParenLoc, EndLoc);
23613 }
23614 
23615 OMPClause *SemaOpenMP::ActOnOpenMPXDynCGroupMemClause(Expr *Size,
23616                                                       SourceLocation StartLoc,
23617                                                       SourceLocation LParenLoc,
23618                                                       SourceLocation EndLoc) {
23619   Expr *ValExpr = Size;
23620   Stmt *HelperValStmt = nullptr;
23621 
23622   // OpenMP [2.5, Restrictions]
23623   //  The ompx_dyn_cgroup_mem expression must evaluate to a positive integer
23624   //  value.
23625   if (!isNonNegativeIntegerValue(ValExpr, SemaRef, OMPC_ompx_dyn_cgroup_mem,
23626                                  /*StrictlyPositive=*/false))
23627     return nullptr;
23628 
23629   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
23630   OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
23631       DKind, OMPC_ompx_dyn_cgroup_mem, getLangOpts().OpenMP);
23632   if (CaptureRegion != OMPD_unknown &&
23633       !SemaRef.CurContext->isDependentContext()) {
23634     ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
23635     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
23636     ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
23637     HelperValStmt = buildPreInits(getASTContext(), Captures);
23638   }
23639 
23640   return new (getASTContext()) OMPXDynCGroupMemClause(
23641       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
23642 }
23643 
23644 OMPClause *SemaOpenMP::ActOnOpenMPDoacrossClause(
23645     OpenMPDoacrossClauseModifier DepType, SourceLocation DepLoc,
23646     SourceLocation ColonLoc, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
23647     SourceLocation LParenLoc, SourceLocation EndLoc) {
23648 
23649   if (DSAStack->getCurrentDirective() == OMPD_ordered &&
23650       DepType != OMPC_DOACROSS_source && DepType != OMPC_DOACROSS_sink &&
23651       DepType != OMPC_DOACROSS_sink_omp_cur_iteration &&
23652       DepType != OMPC_DOACROSS_source_omp_cur_iteration) {
23653     Diag(DepLoc, diag::err_omp_unexpected_clause_value)
23654         << "'source' or 'sink'" << getOpenMPClauseName(OMPC_doacross);
23655     return nullptr;
23656   }
23657 
23658   SmallVector<Expr *, 8> Vars;
23659   DSAStackTy::OperatorOffsetTy OpsOffs;
23660   llvm::APSInt TotalDepCount(/*BitWidth=*/32);
23661   DoacrossDataInfoTy VarOffset = ProcessOpenMPDoacrossClauseCommon(
23662       SemaRef,
23663       DepType == OMPC_DOACROSS_source ||
23664           DepType == OMPC_DOACROSS_source_omp_cur_iteration ||
23665           DepType == OMPC_DOACROSS_sink_omp_cur_iteration,
23666       VarList, DSAStack, EndLoc);
23667   Vars = VarOffset.Vars;
23668   OpsOffs = VarOffset.OpsOffs;
23669   TotalDepCount = VarOffset.TotalDepCount;
23670   auto *C = OMPDoacrossClause::Create(getASTContext(), StartLoc, LParenLoc,
23671                                       EndLoc, DepType, DepLoc, ColonLoc, Vars,
23672                                       TotalDepCount.getZExtValue());
23673   if (DSAStack->isParentOrderedRegion())
23674     DSAStack->addDoacrossDependClause(C, OpsOffs);
23675   return C;
23676 }
23677 
23678 OMPClause *SemaOpenMP::ActOnOpenMPXAttributeClause(ArrayRef<const Attr *> Attrs,
23679                                                    SourceLocation StartLoc,
23680                                                    SourceLocation LParenLoc,
23681                                                    SourceLocation EndLoc) {
23682   return new (getASTContext())
23683       OMPXAttributeClause(Attrs, StartLoc, LParenLoc, EndLoc);
23684 }
23685 
23686 OMPClause *SemaOpenMP::ActOnOpenMPXBareClause(SourceLocation StartLoc,
23687                                               SourceLocation EndLoc) {
23688   return new (getASTContext()) OMPXBareClause(StartLoc, EndLoc);
23689 }
23690 
23691 OMPClause *SemaOpenMP::ActOnOpenMPHoldsClause(Expr *E, SourceLocation StartLoc,
23692                                               SourceLocation LParenLoc,
23693                                               SourceLocation EndLoc) {
23694   return new (getASTContext()) OMPHoldsClause(E, StartLoc, LParenLoc, EndLoc);
23695 }
23696 
23697 OMPClause *SemaOpenMP::ActOnOpenMPDirectivePresenceClause(
23698     OpenMPClauseKind CK, llvm::ArrayRef<OpenMPDirectiveKind> DKVec,
23699     SourceLocation Loc, SourceLocation LLoc, SourceLocation RLoc) {
23700   switch (CK) {
23701   case OMPC_absent:
23702     return OMPAbsentClause::Create(getASTContext(), DKVec, Loc, LLoc, RLoc);
23703   case OMPC_contains:
23704     return OMPContainsClause::Create(getASTContext(), DKVec, Loc, LLoc, RLoc);
23705   default:
23706     llvm_unreachable("Unexpected OpenMP clause");
23707   }
23708 }
23709 
23710 OMPClause *SemaOpenMP::ActOnOpenMPNullaryAssumptionClause(OpenMPClauseKind CK,
23711                                                           SourceLocation Loc,
23712                                                           SourceLocation RLoc) {
23713   switch (CK) {
23714   case OMPC_no_openmp:
23715     return new (getASTContext()) OMPNoOpenMPClause(Loc, RLoc);
23716   case OMPC_no_openmp_routines:
23717     return new (getASTContext()) OMPNoOpenMPRoutinesClause(Loc, RLoc);
23718   case OMPC_no_parallelism:
23719     return new (getASTContext()) OMPNoParallelismClause(Loc, RLoc);
23720   default:
23721     llvm_unreachable("Unexpected OpenMP clause");
23722   }
23723 }
23724 
23725 ExprResult SemaOpenMP::ActOnOMPArraySectionExpr(
23726     Expr *Base, SourceLocation LBLoc, Expr *LowerBound,
23727     SourceLocation ColonLocFirst, SourceLocation ColonLocSecond, Expr *Length,
23728     Expr *Stride, SourceLocation RBLoc) {
23729   ASTContext &Context = getASTContext();
23730   if (Base->hasPlaceholderType() &&
23731       !Base->hasPlaceholderType(BuiltinType::ArraySection)) {
23732     ExprResult Result = SemaRef.CheckPlaceholderExpr(Base);
23733     if (Result.isInvalid())
23734       return ExprError();
23735     Base = Result.get();
23736   }
23737   if (LowerBound && LowerBound->getType()->isNonOverloadPlaceholderType()) {
23738     ExprResult Result = SemaRef.CheckPlaceholderExpr(LowerBound);
23739     if (Result.isInvalid())
23740       return ExprError();
23741     Result = SemaRef.DefaultLvalueConversion(Result.get());
23742     if (Result.isInvalid())
23743       return ExprError();
23744     LowerBound = Result.get();
23745   }
23746   if (Length && Length->getType()->isNonOverloadPlaceholderType()) {
23747     ExprResult Result = SemaRef.CheckPlaceholderExpr(Length);
23748     if (Result.isInvalid())
23749       return ExprError();
23750     Result = SemaRef.DefaultLvalueConversion(Result.get());
23751     if (Result.isInvalid())
23752       return ExprError();
23753     Length = Result.get();
23754   }
23755   if (Stride && Stride->getType()->isNonOverloadPlaceholderType()) {
23756     ExprResult Result = SemaRef.CheckPlaceholderExpr(Stride);
23757     if (Result.isInvalid())
23758       return ExprError();
23759     Result = SemaRef.DefaultLvalueConversion(Result.get());
23760     if (Result.isInvalid())
23761       return ExprError();
23762     Stride = Result.get();
23763   }
23764 
23765   // Build an unanalyzed expression if either operand is type-dependent.
23766   if (Base->isTypeDependent() ||
23767       (LowerBound &&
23768        (LowerBound->isTypeDependent() || LowerBound->isValueDependent())) ||
23769       (Length && (Length->isTypeDependent() || Length->isValueDependent())) ||
23770       (Stride && (Stride->isTypeDependent() || Stride->isValueDependent()))) {
23771     return new (Context) ArraySectionExpr(
23772         Base, LowerBound, Length, Stride, Context.DependentTy, VK_LValue,
23773         OK_Ordinary, ColonLocFirst, ColonLocSecond, RBLoc);
23774   }
23775 
23776   // Perform default conversions.
23777   QualType OriginalTy = ArraySectionExpr::getBaseOriginalType(Base);
23778   QualType ResultTy;
23779   if (OriginalTy->isAnyPointerType()) {
23780     ResultTy = OriginalTy->getPointeeType();
23781   } else if (OriginalTy->isArrayType()) {
23782     ResultTy = OriginalTy->getAsArrayTypeUnsafe()->getElementType();
23783   } else {
23784     return ExprError(
23785         Diag(Base->getExprLoc(), diag::err_omp_typecheck_section_value)
23786         << Base->getSourceRange());
23787   }
23788   // C99 6.5.2.1p1
23789   if (LowerBound) {
23790     auto Res = PerformOpenMPImplicitIntegerConversion(LowerBound->getExprLoc(),
23791                                                       LowerBound);
23792     if (Res.isInvalid())
23793       return ExprError(Diag(LowerBound->getExprLoc(),
23794                             diag::err_omp_typecheck_section_not_integer)
23795                        << 0 << LowerBound->getSourceRange());
23796     LowerBound = Res.get();
23797 
23798     if (LowerBound->getType()->isSpecificBuiltinType(BuiltinType::Char_S) ||
23799         LowerBound->getType()->isSpecificBuiltinType(BuiltinType::Char_U))
23800       Diag(LowerBound->getExprLoc(), diag::warn_omp_section_is_char)
23801           << 0 << LowerBound->getSourceRange();
23802   }
23803   if (Length) {
23804     auto Res =
23805         PerformOpenMPImplicitIntegerConversion(Length->getExprLoc(), Length);
23806     if (Res.isInvalid())
23807       return ExprError(Diag(Length->getExprLoc(),
23808                             diag::err_omp_typecheck_section_not_integer)
23809                        << 1 << Length->getSourceRange());
23810     Length = Res.get();
23811 
23812     if (Length->getType()->isSpecificBuiltinType(BuiltinType::Char_S) ||
23813         Length->getType()->isSpecificBuiltinType(BuiltinType::Char_U))
23814       Diag(Length->getExprLoc(), diag::warn_omp_section_is_char)
23815           << 1 << Length->getSourceRange();
23816   }
23817   if (Stride) {
23818     ExprResult Res =
23819         PerformOpenMPImplicitIntegerConversion(Stride->getExprLoc(), Stride);
23820     if (Res.isInvalid())
23821       return ExprError(Diag(Stride->getExprLoc(),
23822                             diag::err_omp_typecheck_section_not_integer)
23823                        << 1 << Stride->getSourceRange());
23824     Stride = Res.get();
23825 
23826     if (Stride->getType()->isSpecificBuiltinType(BuiltinType::Char_S) ||
23827         Stride->getType()->isSpecificBuiltinType(BuiltinType::Char_U))
23828       Diag(Stride->getExprLoc(), diag::warn_omp_section_is_char)
23829           << 1 << Stride->getSourceRange();
23830   }
23831 
23832   // C99 6.5.2.1p1: "shall have type "pointer to *object* type". Similarly,
23833   // C++ [expr.sub]p1: The type "T" shall be a completely-defined object
23834   // type. Note that functions are not objects, and that (in C99 parlance)
23835   // incomplete types are not object types.
23836   if (ResultTy->isFunctionType()) {
23837     Diag(Base->getExprLoc(), diag::err_omp_section_function_type)
23838         << ResultTy << Base->getSourceRange();
23839     return ExprError();
23840   }
23841 
23842   if (SemaRef.RequireCompleteType(Base->getExprLoc(), ResultTy,
23843                                   diag::err_omp_section_incomplete_type, Base))
23844     return ExprError();
23845 
23846   if (LowerBound && !OriginalTy->isAnyPointerType()) {
23847     Expr::EvalResult Result;
23848     if (LowerBound->EvaluateAsInt(Result, Context)) {
23849       // OpenMP 5.0, [2.1.5 Array Sections]
23850       // The array section must be a subset of the original array.
23851       llvm::APSInt LowerBoundValue = Result.Val.getInt();
23852       if (LowerBoundValue.isNegative()) {
23853         Diag(LowerBound->getExprLoc(),
23854              diag::err_omp_section_not_subset_of_array)
23855             << LowerBound->getSourceRange();
23856         return ExprError();
23857       }
23858     }
23859   }
23860 
23861   if (Length) {
23862     Expr::EvalResult Result;
23863     if (Length->EvaluateAsInt(Result, Context)) {
23864       // OpenMP 5.0, [2.1.5 Array Sections]
23865       // The length must evaluate to non-negative integers.
23866       llvm::APSInt LengthValue = Result.Val.getInt();
23867       if (LengthValue.isNegative()) {
23868         Diag(Length->getExprLoc(), diag::err_omp_section_length_negative)
23869             << toString(LengthValue, /*Radix=*/10, /*Signed=*/true)
23870             << Length->getSourceRange();
23871         return ExprError();
23872       }
23873     }
23874   } else if (ColonLocFirst.isValid() &&
23875              (OriginalTy.isNull() || (!OriginalTy->isConstantArrayType() &&
23876                                       !OriginalTy->isVariableArrayType()))) {
23877     // OpenMP 5.0, [2.1.5 Array Sections]
23878     // When the size of the array dimension is not known, the length must be
23879     // specified explicitly.
23880     Diag(ColonLocFirst, diag::err_omp_section_length_undefined)
23881         << (!OriginalTy.isNull() && OriginalTy->isArrayType());
23882     return ExprError();
23883   }
23884 
23885   if (Stride) {
23886     Expr::EvalResult Result;
23887     if (Stride->EvaluateAsInt(Result, Context)) {
23888       // OpenMP 5.0, [2.1.5 Array Sections]
23889       // The stride must evaluate to a positive integer.
23890       llvm::APSInt StrideValue = Result.Val.getInt();
23891       if (!StrideValue.isStrictlyPositive()) {
23892         Diag(Stride->getExprLoc(), diag::err_omp_section_stride_non_positive)
23893             << toString(StrideValue, /*Radix=*/10, /*Signed=*/true)
23894             << Stride->getSourceRange();
23895         return ExprError();
23896       }
23897     }
23898   }
23899 
23900   if (!Base->hasPlaceholderType(BuiltinType::ArraySection)) {
23901     ExprResult Result = SemaRef.DefaultFunctionArrayLvalueConversion(Base);
23902     if (Result.isInvalid())
23903       return ExprError();
23904     Base = Result.get();
23905   }
23906   return new (Context) ArraySectionExpr(
23907       Base, LowerBound, Length, Stride, Context.ArraySectionTy, VK_LValue,
23908       OK_Ordinary, ColonLocFirst, ColonLocSecond, RBLoc);
23909 }
23910 
23911 ExprResult SemaOpenMP::ActOnOMPArrayShapingExpr(
23912     Expr *Base, SourceLocation LParenLoc, SourceLocation RParenLoc,
23913     ArrayRef<Expr *> Dims, ArrayRef<SourceRange> Brackets) {
23914   ASTContext &Context = getASTContext();
23915   if (Base->hasPlaceholderType()) {
23916     ExprResult Result = SemaRef.CheckPlaceholderExpr(Base);
23917     if (Result.isInvalid())
23918       return ExprError();
23919     Result = SemaRef.DefaultLvalueConversion(Result.get());
23920     if (Result.isInvalid())
23921       return ExprError();
23922     Base = Result.get();
23923   }
23924   QualType BaseTy = Base->getType();
23925   // Delay analysis of the types/expressions if instantiation/specialization is
23926   // required.
23927   if (!BaseTy->isPointerType() && Base->isTypeDependent())
23928     return OMPArrayShapingExpr::Create(Context, Context.DependentTy, Base,
23929                                        LParenLoc, RParenLoc, Dims, Brackets);
23930   if (!BaseTy->isPointerType() ||
23931       (!Base->isTypeDependent() &&
23932        BaseTy->getPointeeType()->isIncompleteType()))
23933     return ExprError(Diag(Base->getExprLoc(),
23934                           diag::err_omp_non_pointer_type_array_shaping_base)
23935                      << Base->getSourceRange());
23936 
23937   SmallVector<Expr *, 4> NewDims;
23938   bool ErrorFound = false;
23939   for (Expr *Dim : Dims) {
23940     if (Dim->hasPlaceholderType()) {
23941       ExprResult Result = SemaRef.CheckPlaceholderExpr(Dim);
23942       if (Result.isInvalid()) {
23943         ErrorFound = true;
23944         continue;
23945       }
23946       Result = SemaRef.DefaultLvalueConversion(Result.get());
23947       if (Result.isInvalid()) {
23948         ErrorFound = true;
23949         continue;
23950       }
23951       Dim = Result.get();
23952     }
23953     if (!Dim->isTypeDependent()) {
23954       ExprResult Result =
23955           PerformOpenMPImplicitIntegerConversion(Dim->getExprLoc(), Dim);
23956       if (Result.isInvalid()) {
23957         ErrorFound = true;
23958         Diag(Dim->getExprLoc(), diag::err_omp_typecheck_shaping_not_integer)
23959             << Dim->getSourceRange();
23960         continue;
23961       }
23962       Dim = Result.get();
23963       Expr::EvalResult EvResult;
23964       if (!Dim->isValueDependent() && Dim->EvaluateAsInt(EvResult, Context)) {
23965         // OpenMP 5.0, [2.1.4 Array Shaping]
23966         // Each si is an integral type expression that must evaluate to a
23967         // positive integer.
23968         llvm::APSInt Value = EvResult.Val.getInt();
23969         if (!Value.isStrictlyPositive()) {
23970           Diag(Dim->getExprLoc(), diag::err_omp_shaping_dimension_not_positive)
23971               << toString(Value, /*Radix=*/10, /*Signed=*/true)
23972               << Dim->getSourceRange();
23973           ErrorFound = true;
23974           continue;
23975         }
23976       }
23977     }
23978     NewDims.push_back(Dim);
23979   }
23980   if (ErrorFound)
23981     return ExprError();
23982   return OMPArrayShapingExpr::Create(Context, Context.OMPArrayShapingTy, Base,
23983                                      LParenLoc, RParenLoc, NewDims, Brackets);
23984 }
23985 
23986 ExprResult SemaOpenMP::ActOnOMPIteratorExpr(Scope *S,
23987                                             SourceLocation IteratorKwLoc,
23988                                             SourceLocation LLoc,
23989                                             SourceLocation RLoc,
23990                                             ArrayRef<OMPIteratorData> Data) {
23991   ASTContext &Context = getASTContext();
23992   SmallVector<OMPIteratorExpr::IteratorDefinition, 4> ID;
23993   bool IsCorrect = true;
23994   for (const OMPIteratorData &D : Data) {
23995     TypeSourceInfo *TInfo = nullptr;
23996     SourceLocation StartLoc;
23997     QualType DeclTy;
23998     if (!D.Type.getAsOpaquePtr()) {
23999       // OpenMP 5.0, 2.1.6 Iterators
24000       // In an iterator-specifier, if the iterator-type is not specified then
24001       // the type of that iterator is of int type.
24002       DeclTy = Context.IntTy;
24003       StartLoc = D.DeclIdentLoc;
24004     } else {
24005       DeclTy = Sema::GetTypeFromParser(D.Type, &TInfo);
24006       StartLoc = TInfo->getTypeLoc().getBeginLoc();
24007     }
24008 
24009     bool IsDeclTyDependent = DeclTy->isDependentType() ||
24010                              DeclTy->containsUnexpandedParameterPack() ||
24011                              DeclTy->isInstantiationDependentType();
24012     if (!IsDeclTyDependent) {
24013       if (!DeclTy->isIntegralType(Context) && !DeclTy->isAnyPointerType()) {
24014         // OpenMP 5.0, 2.1.6 Iterators, Restrictions, C/C++
24015         // The iterator-type must be an integral or pointer type.
24016         Diag(StartLoc, diag::err_omp_iterator_not_integral_or_pointer)
24017             << DeclTy;
24018         IsCorrect = false;
24019         continue;
24020       }
24021       if (DeclTy.isConstant(Context)) {
24022         // OpenMP 5.0, 2.1.6 Iterators, Restrictions, C/C++
24023         // The iterator-type must not be const qualified.
24024         Diag(StartLoc, diag::err_omp_iterator_not_integral_or_pointer)
24025             << DeclTy;
24026         IsCorrect = false;
24027         continue;
24028       }
24029     }
24030 
24031     // Iterator declaration.
24032     assert(D.DeclIdent && "Identifier expected.");
24033     // Always try to create iterator declarator to avoid extra error messages
24034     // about unknown declarations use.
24035     auto *VD =
24036         VarDecl::Create(Context, SemaRef.CurContext, StartLoc, D.DeclIdentLoc,
24037                         D.DeclIdent, DeclTy, TInfo, SC_None);
24038     VD->setImplicit();
24039     if (S) {
24040       // Check for conflicting previous declaration.
24041       DeclarationNameInfo NameInfo(VD->getDeclName(), D.DeclIdentLoc);
24042       LookupResult Previous(SemaRef, NameInfo, Sema::LookupOrdinaryName,
24043                             RedeclarationKind::ForVisibleRedeclaration);
24044       Previous.suppressDiagnostics();
24045       SemaRef.LookupName(Previous, S);
24046 
24047       SemaRef.FilterLookupForScope(Previous, SemaRef.CurContext, S,
24048                                    /*ConsiderLinkage=*/false,
24049                                    /*AllowInlineNamespace=*/false);
24050       if (!Previous.empty()) {
24051         NamedDecl *Old = Previous.getRepresentativeDecl();
24052         Diag(D.DeclIdentLoc, diag::err_redefinition) << VD->getDeclName();
24053         Diag(Old->getLocation(), diag::note_previous_definition);
24054       } else {
24055         SemaRef.PushOnScopeChains(VD, S);
24056       }
24057     } else {
24058       SemaRef.CurContext->addDecl(VD);
24059     }
24060 
24061     /// Act on the iterator variable declaration.
24062     ActOnOpenMPIteratorVarDecl(VD);
24063 
24064     Expr *Begin = D.Range.Begin;
24065     if (!IsDeclTyDependent && Begin && !Begin->isTypeDependent()) {
24066       ExprResult BeginRes = SemaRef.PerformImplicitConversion(
24067           Begin, DeclTy, AssignmentAction::Converting);
24068       Begin = BeginRes.get();
24069     }
24070     Expr *End = D.Range.End;
24071     if (!IsDeclTyDependent && End && !End->isTypeDependent()) {
24072       ExprResult EndRes = SemaRef.PerformImplicitConversion(
24073           End, DeclTy, AssignmentAction::Converting);
24074       End = EndRes.get();
24075     }
24076     Expr *Step = D.Range.Step;
24077     if (!IsDeclTyDependent && Step && !Step->isTypeDependent()) {
24078       if (!Step->getType()->isIntegralType(Context)) {
24079         Diag(Step->getExprLoc(), diag::err_omp_iterator_step_not_integral)
24080             << Step << Step->getSourceRange();
24081         IsCorrect = false;
24082         continue;
24083       }
24084       std::optional<llvm::APSInt> Result =
24085           Step->getIntegerConstantExpr(Context);
24086       // OpenMP 5.0, 2.1.6 Iterators, Restrictions
24087       // If the step expression of a range-specification equals zero, the
24088       // behavior is unspecified.
24089       if (Result && Result->isZero()) {
24090         Diag(Step->getExprLoc(), diag::err_omp_iterator_step_constant_zero)
24091             << Step << Step->getSourceRange();
24092         IsCorrect = false;
24093         continue;
24094       }
24095     }
24096     if (!Begin || !End || !IsCorrect) {
24097       IsCorrect = false;
24098       continue;
24099     }
24100     OMPIteratorExpr::IteratorDefinition &IDElem = ID.emplace_back();
24101     IDElem.IteratorDecl = VD;
24102     IDElem.AssignmentLoc = D.AssignLoc;
24103     IDElem.Range.Begin = Begin;
24104     IDElem.Range.End = End;
24105     IDElem.Range.Step = Step;
24106     IDElem.ColonLoc = D.ColonLoc;
24107     IDElem.SecondColonLoc = D.SecColonLoc;
24108   }
24109   if (!IsCorrect) {
24110     // Invalidate all created iterator declarations if error is found.
24111     for (const OMPIteratorExpr::IteratorDefinition &D : ID) {
24112       if (Decl *ID = D.IteratorDecl)
24113         ID->setInvalidDecl();
24114     }
24115     return ExprError();
24116   }
24117   SmallVector<OMPIteratorHelperData, 4> Helpers;
24118   if (!SemaRef.CurContext->isDependentContext()) {
24119     // Build number of ityeration for each iteration range.
24120     // Ni = ((Stepi > 0) ? ((Endi + Stepi -1 - Begini)/Stepi) :
24121     // ((Begini-Stepi-1-Endi) / -Stepi);
24122     for (OMPIteratorExpr::IteratorDefinition &D : ID) {
24123       // (Endi - Begini)
24124       ExprResult Res = SemaRef.CreateBuiltinBinOp(D.AssignmentLoc, BO_Sub,
24125                                                   D.Range.End, D.Range.Begin);
24126       if (!Res.isUsable()) {
24127         IsCorrect = false;
24128         continue;
24129       }
24130       ExprResult St, St1;
24131       if (D.Range.Step) {
24132         St = D.Range.Step;
24133         // (Endi - Begini) + Stepi
24134         Res = SemaRef.CreateBuiltinBinOp(D.AssignmentLoc, BO_Add, Res.get(),
24135                                          St.get());
24136         if (!Res.isUsable()) {
24137           IsCorrect = false;
24138           continue;
24139         }
24140         // (Endi - Begini) + Stepi - 1
24141         Res = SemaRef.CreateBuiltinBinOp(
24142             D.AssignmentLoc, BO_Sub, Res.get(),
24143             SemaRef.ActOnIntegerConstant(D.AssignmentLoc, 1).get());
24144         if (!Res.isUsable()) {
24145           IsCorrect = false;
24146           continue;
24147         }
24148         // ((Endi - Begini) + Stepi - 1) / Stepi
24149         Res = SemaRef.CreateBuiltinBinOp(D.AssignmentLoc, BO_Div, Res.get(),
24150                                          St.get());
24151         if (!Res.isUsable()) {
24152           IsCorrect = false;
24153           continue;
24154         }
24155         St1 = SemaRef.CreateBuiltinUnaryOp(D.AssignmentLoc, UO_Minus,
24156                                            D.Range.Step);
24157         // (Begini - Endi)
24158         ExprResult Res1 = SemaRef.CreateBuiltinBinOp(
24159             D.AssignmentLoc, BO_Sub, D.Range.Begin, D.Range.End);
24160         if (!Res1.isUsable()) {
24161           IsCorrect = false;
24162           continue;
24163         }
24164         // (Begini - Endi) - Stepi
24165         Res1 = SemaRef.CreateBuiltinBinOp(D.AssignmentLoc, BO_Add, Res1.get(),
24166                                           St1.get());
24167         if (!Res1.isUsable()) {
24168           IsCorrect = false;
24169           continue;
24170         }
24171         // (Begini - Endi) - Stepi - 1
24172         Res1 = SemaRef.CreateBuiltinBinOp(
24173             D.AssignmentLoc, BO_Sub, Res1.get(),
24174             SemaRef.ActOnIntegerConstant(D.AssignmentLoc, 1).get());
24175         if (!Res1.isUsable()) {
24176           IsCorrect = false;
24177           continue;
24178         }
24179         // ((Begini - Endi) - Stepi - 1) / (-Stepi)
24180         Res1 = SemaRef.CreateBuiltinBinOp(D.AssignmentLoc, BO_Div, Res1.get(),
24181                                           St1.get());
24182         if (!Res1.isUsable()) {
24183           IsCorrect = false;
24184           continue;
24185         }
24186         // Stepi > 0.
24187         ExprResult CmpRes = SemaRef.CreateBuiltinBinOp(
24188             D.AssignmentLoc, BO_GT, D.Range.Step,
24189             SemaRef.ActOnIntegerConstant(D.AssignmentLoc, 0).get());
24190         if (!CmpRes.isUsable()) {
24191           IsCorrect = false;
24192           continue;
24193         }
24194         Res = SemaRef.ActOnConditionalOp(D.AssignmentLoc, D.AssignmentLoc,
24195                                          CmpRes.get(), Res.get(), Res1.get());
24196         if (!Res.isUsable()) {
24197           IsCorrect = false;
24198           continue;
24199         }
24200       }
24201       Res = SemaRef.ActOnFinishFullExpr(Res.get(), /*DiscardedValue=*/false);
24202       if (!Res.isUsable()) {
24203         IsCorrect = false;
24204         continue;
24205       }
24206 
24207       // Build counter update.
24208       // Build counter.
24209       auto *CounterVD = VarDecl::Create(Context, SemaRef.CurContext,
24210                                         D.IteratorDecl->getBeginLoc(),
24211                                         D.IteratorDecl->getBeginLoc(), nullptr,
24212                                         Res.get()->getType(), nullptr, SC_None);
24213       CounterVD->setImplicit();
24214       ExprResult RefRes =
24215           SemaRef.BuildDeclRefExpr(CounterVD, CounterVD->getType(), VK_LValue,
24216                                    D.IteratorDecl->getBeginLoc());
24217       // Build counter update.
24218       // I = Begini + counter * Stepi;
24219       ExprResult UpdateRes;
24220       if (D.Range.Step) {
24221         UpdateRes = SemaRef.CreateBuiltinBinOp(
24222             D.AssignmentLoc, BO_Mul,
24223             SemaRef.DefaultLvalueConversion(RefRes.get()).get(), St.get());
24224       } else {
24225         UpdateRes = SemaRef.DefaultLvalueConversion(RefRes.get());
24226       }
24227       if (!UpdateRes.isUsable()) {
24228         IsCorrect = false;
24229         continue;
24230       }
24231       UpdateRes = SemaRef.CreateBuiltinBinOp(D.AssignmentLoc, BO_Add,
24232                                              D.Range.Begin, UpdateRes.get());
24233       if (!UpdateRes.isUsable()) {
24234         IsCorrect = false;
24235         continue;
24236       }
24237       ExprResult VDRes =
24238           SemaRef.BuildDeclRefExpr(cast<VarDecl>(D.IteratorDecl),
24239                                    cast<VarDecl>(D.IteratorDecl)->getType(),
24240                                    VK_LValue, D.IteratorDecl->getBeginLoc());
24241       UpdateRes = SemaRef.CreateBuiltinBinOp(D.AssignmentLoc, BO_Assign,
24242                                              VDRes.get(), UpdateRes.get());
24243       if (!UpdateRes.isUsable()) {
24244         IsCorrect = false;
24245         continue;
24246       }
24247       UpdateRes =
24248           SemaRef.ActOnFinishFullExpr(UpdateRes.get(), /*DiscardedValue=*/true);
24249       if (!UpdateRes.isUsable()) {
24250         IsCorrect = false;
24251         continue;
24252       }
24253       ExprResult CounterUpdateRes = SemaRef.CreateBuiltinUnaryOp(
24254           D.AssignmentLoc, UO_PreInc, RefRes.get());
24255       if (!CounterUpdateRes.isUsable()) {
24256         IsCorrect = false;
24257         continue;
24258       }
24259       CounterUpdateRes = SemaRef.ActOnFinishFullExpr(CounterUpdateRes.get(),
24260                                                      /*DiscardedValue=*/true);
24261       if (!CounterUpdateRes.isUsable()) {
24262         IsCorrect = false;
24263         continue;
24264       }
24265       OMPIteratorHelperData &HD = Helpers.emplace_back();
24266       HD.CounterVD = CounterVD;
24267       HD.Upper = Res.get();
24268       HD.Update = UpdateRes.get();
24269       HD.CounterUpdate = CounterUpdateRes.get();
24270     }
24271   } else {
24272     Helpers.assign(ID.size(), {});
24273   }
24274   if (!IsCorrect) {
24275     // Invalidate all created iterator declarations if error is found.
24276     for (const OMPIteratorExpr::IteratorDefinition &D : ID) {
24277       if (Decl *ID = D.IteratorDecl)
24278         ID->setInvalidDecl();
24279     }
24280     return ExprError();
24281   }
24282   return OMPIteratorExpr::Create(Context, Context.OMPIteratorTy, IteratorKwLoc,
24283                                  LLoc, RLoc, ID, Helpers);
24284 }
24285 
24286 /// Check if \p AssumptionStr is a known assumption and warn if not.
24287 static void checkOMPAssumeAttr(Sema &S, SourceLocation Loc,
24288                                StringRef AssumptionStr) {
24289   if (llvm::KnownAssumptionStrings.count(AssumptionStr))
24290     return;
24291 
24292   unsigned BestEditDistance = 3;
24293   StringRef Suggestion;
24294   for (const auto &KnownAssumptionIt : llvm::KnownAssumptionStrings) {
24295     unsigned EditDistance =
24296         AssumptionStr.edit_distance(KnownAssumptionIt.getKey());
24297     if (EditDistance < BestEditDistance) {
24298       Suggestion = KnownAssumptionIt.getKey();
24299       BestEditDistance = EditDistance;
24300     }
24301   }
24302 
24303   if (!Suggestion.empty())
24304     S.Diag(Loc, diag::warn_omp_assume_attribute_string_unknown_suggested)
24305         << AssumptionStr << Suggestion;
24306   else
24307     S.Diag(Loc, diag::warn_omp_assume_attribute_string_unknown)
24308         << AssumptionStr;
24309 }
24310 
24311 void SemaOpenMP::handleOMPAssumeAttr(Decl *D, const ParsedAttr &AL) {
24312   // Handle the case where the attribute has a text message.
24313   StringRef Str;
24314   SourceLocation AttrStrLoc;
24315   if (!SemaRef.checkStringLiteralArgumentAttr(AL, 0, Str, &AttrStrLoc))
24316     return;
24317 
24318   checkOMPAssumeAttr(SemaRef, AttrStrLoc, Str);
24319 
24320   D->addAttr(::new (getASTContext()) OMPAssumeAttr(getASTContext(), AL, Str));
24321 }
24322 
24323 SemaOpenMP::SemaOpenMP(Sema &S)
24324     : SemaBase(S), VarDataSharingAttributesStack(nullptr) {}
24325