1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// This file implements semantic analysis for OpenMP directives and
10 /// clauses.
11 ///
12 //===----------------------------------------------------------------------===//
13 
14 #include "TreeTransform.h"
15 #include "clang/AST/ASTContext.h"
16 #include "clang/AST/ASTMutationListener.h"
17 #include "clang/AST/CXXInheritance.h"
18 #include "clang/AST/Decl.h"
19 #include "clang/AST/DeclCXX.h"
20 #include "clang/AST/DeclOpenMP.h"
21 #include "clang/AST/OpenMPClause.h"
22 #include "clang/AST/StmtCXX.h"
23 #include "clang/AST/StmtOpenMP.h"
24 #include "clang/AST/StmtVisitor.h"
25 #include "clang/AST/TypeOrdering.h"
26 #include "clang/Basic/DiagnosticSema.h"
27 #include "clang/Basic/OpenMPKinds.h"
28 #include "clang/Basic/PartialDiagnostic.h"
29 #include "clang/Basic/TargetInfo.h"
30 #include "clang/Sema/EnterExpressionEvaluationContext.h"
31 #include "clang/Sema/Initialization.h"
32 #include "clang/Sema/Lookup.h"
33 #include "clang/Sema/ParsedAttr.h"
34 #include "clang/Sema/Scope.h"
35 #include "clang/Sema/ScopeInfo.h"
36 #include "clang/Sema/SemaInternal.h"
37 #include "llvm/ADT/IndexedMap.h"
38 #include "llvm/ADT/PointerEmbeddedInt.h"
39 #include "llvm/ADT/STLExtras.h"
40 #include "llvm/ADT/SmallSet.h"
41 #include "llvm/ADT/StringExtras.h"
42 #include "llvm/Frontend/OpenMP/OMPAssume.h"
43 #include "llvm/Frontend/OpenMP/OMPConstants.h"
44 #include <optional>
45 #include <set>
46 
47 using namespace clang;
48 using namespace llvm::omp;
49 
50 //===----------------------------------------------------------------------===//
51 // Stack of data-sharing attributes for variables
52 //===----------------------------------------------------------------------===//
53 
54 static const Expr *checkMapClauseExpressionBase(
55     Sema &SemaRef, Expr *E,
56     OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
57     OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose);
58 
59 namespace {
60 /// Default data sharing attributes, which can be applied to directive.
61 enum DefaultDataSharingAttributes {
62   DSA_unspecified = 0,       /// Data sharing attribute not specified.
63   DSA_none = 1 << 0,         /// Default data sharing attribute 'none'.
64   DSA_shared = 1 << 1,       /// Default data sharing attribute 'shared'.
65   DSA_private = 1 << 2,      /// Default data sharing attribute 'private'.
66   DSA_firstprivate = 1 << 3, /// Default data sharing attribute 'firstprivate'.
67 };
68 
69 /// Stack for tracking declarations used in OpenMP directives and
70 /// clauses and their data-sharing attributes.
71 class DSAStackTy {
72 public:
73   struct DSAVarData {
74     OpenMPDirectiveKind DKind = OMPD_unknown;
75     OpenMPClauseKind CKind = OMPC_unknown;
76     unsigned Modifier = 0;
77     const Expr *RefExpr = nullptr;
78     DeclRefExpr *PrivateCopy = nullptr;
79     SourceLocation ImplicitDSALoc;
80     bool AppliedToPointee = false;
81     DSAVarData() = default;
82     DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
83                const Expr *RefExpr, DeclRefExpr *PrivateCopy,
84                SourceLocation ImplicitDSALoc, unsigned Modifier,
85                bool AppliedToPointee)
86         : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr),
87           PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc),
88           AppliedToPointee(AppliedToPointee) {}
89   };
90   using OperatorOffsetTy =
91       llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>;
92   using DoacrossClauseMapTy = llvm::DenseMap<OMPClause *, OperatorOffsetTy>;
93   /// Kind of the declaration used in the uses_allocators clauses.
94   enum class UsesAllocatorsDeclKind {
95     /// Predefined allocator
96     PredefinedAllocator,
97     /// User-defined allocator
98     UserDefinedAllocator,
99     /// The declaration that represent allocator trait
100     AllocatorTrait,
101   };
102 
103 private:
104   struct DSAInfo {
105     OpenMPClauseKind Attributes = OMPC_unknown;
106     unsigned Modifier = 0;
107     /// Pointer to a reference expression and a flag which shows that the
108     /// variable is marked as lastprivate(true) or not (false).
109     llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
110     DeclRefExpr *PrivateCopy = nullptr;
111     /// true if the attribute is applied to the pointee, not the variable
112     /// itself.
113     bool AppliedToPointee = false;
114   };
115   using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
116   using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
117   using LCDeclInfo = std::pair<unsigned, VarDecl *>;
118   using LoopControlVariablesMapTy =
119       llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
120   /// Struct that associates a component with the clause kind where they are
121   /// found.
122   struct MappedExprComponentTy {
123     OMPClauseMappableExprCommon::MappableExprComponentLists Components;
124     OpenMPClauseKind Kind = OMPC_unknown;
125   };
126   using MappedExprComponentsTy =
127       llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
128   using CriticalsWithHintsTy =
129       llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
130   struct ReductionData {
131     using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
132     SourceRange ReductionRange;
133     llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
134     ReductionData() = default;
135     void set(BinaryOperatorKind BO, SourceRange RR) {
136       ReductionRange = RR;
137       ReductionOp = BO;
138     }
139     void set(const Expr *RefExpr, SourceRange RR) {
140       ReductionRange = RR;
141       ReductionOp = RefExpr;
142     }
143   };
144   using DeclReductionMapTy =
145       llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
146   struct DefaultmapInfo {
147     OpenMPDefaultmapClauseModifier ImplicitBehavior =
148         OMPC_DEFAULTMAP_MODIFIER_unknown;
149     SourceLocation SLoc;
150     DefaultmapInfo() = default;
151     DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc)
152         : ImplicitBehavior(M), SLoc(Loc) {}
153   };
154 
155   struct SharingMapTy {
156     DeclSAMapTy SharingMap;
157     DeclReductionMapTy ReductionMap;
158     UsedRefMapTy AlignedMap;
159     UsedRefMapTy NontemporalMap;
160     MappedExprComponentsTy MappedExprComponents;
161     LoopControlVariablesMapTy LCVMap;
162     DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
163     SourceLocation DefaultAttrLoc;
164     DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown + 1];
165     OpenMPDirectiveKind Directive = OMPD_unknown;
166     /// GenericLoopDirective with bind clause is mapped to other directives,
167     /// like for, distribute and simd. Presently, set MappedDirective to
168     /// OMPLoop. This may also be used in a similar way for other constructs.
169     OpenMPDirectiveKind MappedDirective = 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 *getPossiblyLoopCunter() 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   OpenMPDirectiveKind getMappedDirective() const {
644     const SharingMapTy *Top = getTopOfStackOrNull();
645     return Top ? Top->MappedDirective : OMPD_unknown;
646   }
647   void setCurrentDirective(OpenMPDirectiveKind NewDK) {
648     SharingMapTy *Top = getTopOfStackOrNull();
649     assert(Top &&
650            "Before calling setCurrentDirective Top of Stack not to be NULL.");
651     // Store the old into MappedDirective & assign argument NewDK to Directive.
652     Top->Directive = NewDK;
653   }
654   void setMappedDirective(OpenMPDirectiveKind NewDK) {
655     SharingMapTy *Top = getTopOfStackOrNull();
656     assert(Top &&
657            "Before calling setMappedDirective Top of Stack not to be NULL.");
658     // Store the old into MappedDirective & assign argument NewDK to Directive.
659     Top->MappedDirective = NewDK;
660   }
661   /// Returns directive kind at specified level.
662   OpenMPDirectiveKind getDirective(unsigned Level) const {
663     assert(!isStackEmpty() && "No directive at specified level.");
664     return getStackElemAtLevel(Level).Directive;
665   }
666   /// Returns the capture region at the specified level.
667   OpenMPDirectiveKind getCaptureRegion(unsigned Level,
668                                        unsigned OpenMPCaptureLevel) const {
669     SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
670     getOpenMPCaptureRegions(CaptureRegions, getDirective(Level));
671     return CaptureRegions[OpenMPCaptureLevel];
672   }
673   /// Returns parent directive.
674   OpenMPDirectiveKind getParentDirective() const {
675     const SharingMapTy *Parent = getSecondOnStackOrNull();
676     return Parent ? Parent->Directive : OMPD_unknown;
677   }
678 
679   /// Add requires decl to internal vector
680   void addRequiresDecl(OMPRequiresDecl *RD) { RequiresDecls.push_back(RD); }
681 
682   /// Checks if the defined 'requires' directive has specified type of clause.
683   template <typename ClauseType> bool hasRequiresDeclWithClause() const {
684     return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
685       return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
686         return isa<ClauseType>(C);
687       });
688     });
689   }
690 
691   /// Checks for a duplicate clause amongst previously declared requires
692   /// directives
693   bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const {
694     bool IsDuplicate = false;
695     for (OMPClause *CNew : ClauseList) {
696       for (const OMPRequiresDecl *D : RequiresDecls) {
697         for (const OMPClause *CPrev : D->clauselists()) {
698           if (CNew->getClauseKind() == CPrev->getClauseKind()) {
699             SemaRef.Diag(CNew->getBeginLoc(),
700                          diag::err_omp_requires_clause_redeclaration)
701                 << getOpenMPClauseName(CNew->getClauseKind());
702             SemaRef.Diag(CPrev->getBeginLoc(),
703                          diag::note_omp_requires_previous_clause)
704                 << getOpenMPClauseName(CPrev->getClauseKind());
705             IsDuplicate = true;
706           }
707         }
708       }
709     }
710     return IsDuplicate;
711   }
712 
713   /// Add location of previously encountered target to internal vector
714   void addTargetDirLocation(SourceLocation LocStart) {
715     TargetLocations.push_back(LocStart);
716   }
717 
718   /// Add location for the first encountered atomicc directive.
719   void addAtomicDirectiveLoc(SourceLocation Loc) {
720     if (AtomicLocation.isInvalid())
721       AtomicLocation = Loc;
722   }
723 
724   /// Returns the location of the first encountered atomic directive in the
725   /// module.
726   SourceLocation getAtomicDirectiveLoc() const { return AtomicLocation; }
727 
728   // Return previously encountered target region locations.
729   ArrayRef<SourceLocation> getEncounteredTargetLocs() const {
730     return TargetLocations;
731   }
732 
733   /// Set default data sharing attribute to none.
734   void setDefaultDSANone(SourceLocation Loc) {
735     getTopOfStack().DefaultAttr = DSA_none;
736     getTopOfStack().DefaultAttrLoc = Loc;
737   }
738   /// Set default data sharing attribute to shared.
739   void setDefaultDSAShared(SourceLocation Loc) {
740     getTopOfStack().DefaultAttr = DSA_shared;
741     getTopOfStack().DefaultAttrLoc = Loc;
742   }
743   /// Set default data sharing attribute to private.
744   void setDefaultDSAPrivate(SourceLocation Loc) {
745     getTopOfStack().DefaultAttr = DSA_private;
746     getTopOfStack().DefaultAttrLoc = Loc;
747   }
748   /// Set default data sharing attribute to firstprivate.
749   void setDefaultDSAFirstPrivate(SourceLocation Loc) {
750     getTopOfStack().DefaultAttr = DSA_firstprivate;
751     getTopOfStack().DefaultAttrLoc = Loc;
752   }
753   /// Set default data mapping attribute to Modifier:Kind
754   void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,
755                          OpenMPDefaultmapClauseKind Kind, SourceLocation Loc) {
756     DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind];
757     DMI.ImplicitBehavior = M;
758     DMI.SLoc = Loc;
759   }
760   /// Check whether the implicit-behavior has been set in defaultmap
761   bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) {
762     if (VariableCategory == OMPC_DEFAULTMAP_unknown)
763       return getTopOfStack()
764                      .DefaultmapMap[OMPC_DEFAULTMAP_aggregate]
765                      .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
766              getTopOfStack()
767                      .DefaultmapMap[OMPC_DEFAULTMAP_scalar]
768                      .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
769              getTopOfStack()
770                      .DefaultmapMap[OMPC_DEFAULTMAP_pointer]
771                      .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown;
772     return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
773            OMPC_DEFAULTMAP_MODIFIER_unknown;
774   }
775 
776   ArrayRef<llvm::omp::TraitProperty> getConstructTraits() {
777     return ConstructTraits;
778   }
779   void handleConstructTrait(ArrayRef<llvm::omp::TraitProperty> Traits,
780                             bool ScopeEntry) {
781     if (ScopeEntry)
782       ConstructTraits.append(Traits.begin(), Traits.end());
783     else
784       for (llvm::omp::TraitProperty Trait : llvm::reverse(Traits)) {
785         llvm::omp::TraitProperty Top = ConstructTraits.pop_back_val();
786         assert(Top == Trait && "Something left a trait on the stack!");
787         (void)Trait;
788         (void)Top;
789       }
790   }
791 
792   DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const {
793     return getStackSize() <= Level ? DSA_unspecified
794                                    : getStackElemAtLevel(Level).DefaultAttr;
795   }
796   DefaultDataSharingAttributes getDefaultDSA() const {
797     return isStackEmpty() ? DSA_unspecified : getTopOfStack().DefaultAttr;
798   }
799   SourceLocation getDefaultDSALocation() const {
800     return isStackEmpty() ? SourceLocation() : getTopOfStack().DefaultAttrLoc;
801   }
802   OpenMPDefaultmapClauseModifier
803   getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const {
804     return isStackEmpty()
805                ? OMPC_DEFAULTMAP_MODIFIER_unknown
806                : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior;
807   }
808   OpenMPDefaultmapClauseModifier
809   getDefaultmapModifierAtLevel(unsigned Level,
810                                OpenMPDefaultmapClauseKind Kind) const {
811     return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior;
812   }
813   bool isDefaultmapCapturedByRef(unsigned Level,
814                                  OpenMPDefaultmapClauseKind Kind) const {
815     OpenMPDefaultmapClauseModifier M =
816         getDefaultmapModifierAtLevel(Level, Kind);
817     if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) {
818       return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
819              (M == OMPC_DEFAULTMAP_MODIFIER_to) ||
820              (M == OMPC_DEFAULTMAP_MODIFIER_from) ||
821              (M == OMPC_DEFAULTMAP_MODIFIER_tofrom);
822     }
823     return true;
824   }
825   static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M,
826                                      OpenMPDefaultmapClauseKind Kind) {
827     switch (Kind) {
828     case OMPC_DEFAULTMAP_scalar:
829     case OMPC_DEFAULTMAP_pointer:
830       return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) ||
831              (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) ||
832              (M == OMPC_DEFAULTMAP_MODIFIER_default);
833     case OMPC_DEFAULTMAP_aggregate:
834       return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
835     default:
836       break;
837     }
838     llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum");
839   }
840   bool mustBeFirstprivateAtLevel(unsigned Level,
841                                  OpenMPDefaultmapClauseKind Kind) const {
842     OpenMPDefaultmapClauseModifier M =
843         getDefaultmapModifierAtLevel(Level, Kind);
844     return mustBeFirstprivateBase(M, Kind);
845   }
846   bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const {
847     OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind);
848     return mustBeFirstprivateBase(M, Kind);
849   }
850 
851   /// Checks if the specified variable is a threadprivate.
852   bool isThreadPrivate(VarDecl *D) {
853     const DSAVarData DVar = getTopDSA(D, false);
854     return isOpenMPThreadPrivate(DVar.CKind);
855   }
856 
857   /// Marks current region as ordered (it has an 'ordered' clause).
858   void setOrderedRegion(bool IsOrdered, const Expr *Param,
859                         OMPOrderedClause *Clause) {
860     if (IsOrdered)
861       getTopOfStack().OrderedRegion.emplace(Param, Clause);
862     else
863       getTopOfStack().OrderedRegion.reset();
864   }
865   /// Returns true, if region is ordered (has associated 'ordered' clause),
866   /// false - otherwise.
867   bool isOrderedRegion() const {
868     if (const SharingMapTy *Top = getTopOfStackOrNull())
869       return Top->OrderedRegion.has_value();
870     return false;
871   }
872   /// Returns optional parameter for the ordered region.
873   std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
874     if (const SharingMapTy *Top = getTopOfStackOrNull())
875       if (Top->OrderedRegion)
876         return *Top->OrderedRegion;
877     return std::make_pair(nullptr, nullptr);
878   }
879   /// Returns true, if parent region is ordered (has associated
880   /// 'ordered' clause), false - otherwise.
881   bool isParentOrderedRegion() const {
882     if (const SharingMapTy *Parent = getSecondOnStackOrNull())
883       return Parent->OrderedRegion.has_value();
884     return false;
885   }
886   /// Returns optional parameter for the ordered region.
887   std::pair<const Expr *, OMPOrderedClause *>
888   getParentOrderedRegionParam() const {
889     if (const SharingMapTy *Parent = getSecondOnStackOrNull())
890       if (Parent->OrderedRegion)
891         return *Parent->OrderedRegion;
892     return std::make_pair(nullptr, nullptr);
893   }
894   /// Marks current region as having an 'order' clause.
895   void setRegionHasOrderConcurrent(bool HasOrderConcurrent) {
896     getTopOfStack().RegionHasOrderConcurrent = HasOrderConcurrent;
897   }
898   /// Returns true, if parent region is order (has associated
899   /// 'order' clause), false - otherwise.
900   bool isParentOrderConcurrent() const {
901     if (const SharingMapTy *Parent = getSecondOnStackOrNull())
902       return Parent->RegionHasOrderConcurrent;
903     return false;
904   }
905   /// Marks current region as nowait (it has a 'nowait' clause).
906   void setNowaitRegion(bool IsNowait = true) {
907     getTopOfStack().NowaitRegion = IsNowait;
908   }
909   /// Returns true, if parent region is nowait (has associated
910   /// 'nowait' clause), false - otherwise.
911   bool isParentNowaitRegion() const {
912     if (const SharingMapTy *Parent = getSecondOnStackOrNull())
913       return Parent->NowaitRegion;
914     return false;
915   }
916   /// Marks current region as untied (it has a 'untied' clause).
917   void setUntiedRegion(bool IsUntied = true) {
918     getTopOfStack().UntiedRegion = IsUntied;
919   }
920   /// Return true if current region is untied.
921   bool isUntiedRegion() const {
922     const SharingMapTy *Top = getTopOfStackOrNull();
923     return Top ? Top->UntiedRegion : false;
924   }
925   /// Marks parent region as cancel region.
926   void setParentCancelRegion(bool Cancel = true) {
927     if (SharingMapTy *Parent = getSecondOnStackOrNull())
928       Parent->CancelRegion |= Cancel;
929   }
930   /// Return true if current region has inner cancel construct.
931   bool isCancelRegion() const {
932     const SharingMapTy *Top = getTopOfStackOrNull();
933     return Top ? Top->CancelRegion : false;
934   }
935 
936   /// Mark that parent region already has scan directive.
937   void setParentHasScanDirective(SourceLocation Loc) {
938     if (SharingMapTy *Parent = getSecondOnStackOrNull())
939       Parent->PrevScanLocation = Loc;
940   }
941   /// Return true if current region has inner cancel construct.
942   bool doesParentHasScanDirective() const {
943     const SharingMapTy *Top = getSecondOnStackOrNull();
944     return Top ? Top->PrevScanLocation.isValid() : false;
945   }
946   /// Return true if current region has inner cancel construct.
947   SourceLocation getParentScanDirectiveLoc() const {
948     const SharingMapTy *Top = getSecondOnStackOrNull();
949     return Top ? Top->PrevScanLocation : SourceLocation();
950   }
951   /// Mark that parent region already has ordered directive.
952   void setParentHasOrderedDirective(SourceLocation Loc) {
953     if (SharingMapTy *Parent = getSecondOnStackOrNull())
954       Parent->PrevOrderedLocation = Loc;
955   }
956   /// Return true if current region has inner ordered construct.
957   bool doesParentHasOrderedDirective() const {
958     const SharingMapTy *Top = getSecondOnStackOrNull();
959     return Top ? Top->PrevOrderedLocation.isValid() : false;
960   }
961   /// Returns the location of the previously specified ordered directive.
962   SourceLocation getParentOrderedDirectiveLoc() const {
963     const SharingMapTy *Top = getSecondOnStackOrNull();
964     return Top ? Top->PrevOrderedLocation : SourceLocation();
965   }
966 
967   /// Set collapse value for the region.
968   void setAssociatedLoops(unsigned Val) {
969     getTopOfStack().AssociatedLoops = Val;
970     if (Val > 1)
971       getTopOfStack().HasMutipleLoops = true;
972   }
973   /// Return collapse value for region.
974   unsigned getAssociatedLoops() const {
975     const SharingMapTy *Top = getTopOfStackOrNull();
976     return Top ? Top->AssociatedLoops : 0;
977   }
978   /// Returns true if the construct is associated with multiple loops.
979   bool hasMutipleLoops() const {
980     const SharingMapTy *Top = getTopOfStackOrNull();
981     return Top ? Top->HasMutipleLoops : false;
982   }
983 
984   /// Marks current target region as one with closely nested teams
985   /// region.
986   void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
987     if (SharingMapTy *Parent = getSecondOnStackOrNull())
988       Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
989   }
990   /// Returns true, if current region has closely nested teams region.
991   bool hasInnerTeamsRegion() const {
992     return getInnerTeamsRegionLoc().isValid();
993   }
994   /// Returns location of the nested teams region (if any).
995   SourceLocation getInnerTeamsRegionLoc() const {
996     const SharingMapTy *Top = getTopOfStackOrNull();
997     return Top ? Top->InnerTeamsRegionLoc : SourceLocation();
998   }
999 
1000   Scope *getCurScope() const {
1001     const SharingMapTy *Top = getTopOfStackOrNull();
1002     return Top ? Top->CurScope : nullptr;
1003   }
1004   void setContext(DeclContext *DC) { getTopOfStack().Context = DC; }
1005   SourceLocation getConstructLoc() const {
1006     const SharingMapTy *Top = getTopOfStackOrNull();
1007     return Top ? Top->ConstructLoc : SourceLocation();
1008   }
1009 
1010   /// Do the check specified in \a Check to all component lists and return true
1011   /// if any issue is found.
1012   bool checkMappableExprComponentListsForDecl(
1013       const ValueDecl *VD, bool CurrentRegionOnly,
1014       const llvm::function_ref<
1015           bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
1016                OpenMPClauseKind)>
1017           Check) const {
1018     if (isStackEmpty())
1019       return false;
1020     auto SI = begin();
1021     auto SE = end();
1022 
1023     if (SI == SE)
1024       return false;
1025 
1026     if (CurrentRegionOnly)
1027       SE = std::next(SI);
1028     else
1029       std::advance(SI, 1);
1030 
1031     for (; SI != SE; ++SI) {
1032       auto MI = SI->MappedExprComponents.find(VD);
1033       if (MI != SI->MappedExprComponents.end())
1034         for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
1035              MI->second.Components)
1036           if (Check(L, MI->second.Kind))
1037             return true;
1038     }
1039     return false;
1040   }
1041 
1042   /// Do the check specified in \a Check to all component lists at a given level
1043   /// and return true if any issue is found.
1044   bool checkMappableExprComponentListsForDeclAtLevel(
1045       const ValueDecl *VD, unsigned Level,
1046       const llvm::function_ref<
1047           bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
1048                OpenMPClauseKind)>
1049           Check) const {
1050     if (getStackSize() <= Level)
1051       return false;
1052 
1053     const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1054     auto MI = StackElem.MappedExprComponents.find(VD);
1055     if (MI != StackElem.MappedExprComponents.end())
1056       for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
1057            MI->second.Components)
1058         if (Check(L, MI->second.Kind))
1059           return true;
1060     return false;
1061   }
1062 
1063   /// Create a new mappable expression component list associated with a given
1064   /// declaration and initialize it with the provided list of components.
1065   void addMappableExpressionComponents(
1066       const ValueDecl *VD,
1067       OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
1068       OpenMPClauseKind WhereFoundClauseKind) {
1069     MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
1070     // Create new entry and append the new components there.
1071     MEC.Components.resize(MEC.Components.size() + 1);
1072     MEC.Components.back().append(Components.begin(), Components.end());
1073     MEC.Kind = WhereFoundClauseKind;
1074   }
1075 
1076   unsigned getNestingLevel() const {
1077     assert(!isStackEmpty());
1078     return getStackSize() - 1;
1079   }
1080   void addDoacrossDependClause(OMPClause *C, const OperatorOffsetTy &OpsOffs) {
1081     SharingMapTy *Parent = getSecondOnStackOrNull();
1082     assert(Parent && isOpenMPWorksharingDirective(Parent->Directive));
1083     Parent->DoacrossDepends.try_emplace(C, OpsOffs);
1084   }
1085   llvm::iterator_range<DoacrossClauseMapTy::const_iterator>
1086   getDoacrossDependClauses() const {
1087     const SharingMapTy &StackElem = getTopOfStack();
1088     if (isOpenMPWorksharingDirective(StackElem.Directive)) {
1089       const DoacrossClauseMapTy &Ref = StackElem.DoacrossDepends;
1090       return llvm::make_range(Ref.begin(), Ref.end());
1091     }
1092     return llvm::make_range(StackElem.DoacrossDepends.end(),
1093                             StackElem.DoacrossDepends.end());
1094   }
1095 
1096   // Store types of classes which have been explicitly mapped
1097   void addMappedClassesQualTypes(QualType QT) {
1098     SharingMapTy &StackElem = getTopOfStack();
1099     StackElem.MappedClassesQualTypes.insert(QT);
1100   }
1101 
1102   // Return set of mapped classes types
1103   bool isClassPreviouslyMapped(QualType QT) const {
1104     const SharingMapTy &StackElem = getTopOfStack();
1105     return StackElem.MappedClassesQualTypes.contains(QT);
1106   }
1107 
1108   /// Adds global declare target to the parent target region.
1109   void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) {
1110     assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
1111                E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
1112            "Expected declare target link global.");
1113     for (auto &Elem : *this) {
1114       if (isOpenMPTargetExecutionDirective(Elem.Directive)) {
1115         Elem.DeclareTargetLinkVarDecls.push_back(E);
1116         return;
1117       }
1118     }
1119   }
1120 
1121   /// Returns the list of globals with declare target link if current directive
1122   /// is target.
1123   ArrayRef<DeclRefExpr *> getLinkGlobals() const {
1124     assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) &&
1125            "Expected target executable directive.");
1126     return getTopOfStack().DeclareTargetLinkVarDecls;
1127   }
1128 
1129   /// Adds list of allocators expressions.
1130   void addInnerAllocatorExpr(Expr *E) {
1131     getTopOfStack().InnerUsedAllocators.push_back(E);
1132   }
1133   /// Return list of used allocators.
1134   ArrayRef<Expr *> getInnerAllocators() const {
1135     return getTopOfStack().InnerUsedAllocators;
1136   }
1137   /// Marks the declaration as implicitly firstprivate nin the task-based
1138   /// regions.
1139   void addImplicitTaskFirstprivate(unsigned Level, Decl *D) {
1140     getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D);
1141   }
1142   /// Checks if the decl is implicitly firstprivate in the task-based region.
1143   bool isImplicitTaskFirstprivate(Decl *D) const {
1144     return getTopOfStack().ImplicitTaskFirstprivates.contains(D);
1145   }
1146 
1147   /// Marks decl as used in uses_allocators clause as the allocator.
1148   void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) {
1149     getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind);
1150   }
1151   /// Checks if specified decl is used in uses allocator clause as the
1152   /// allocator.
1153   std::optional<UsesAllocatorsDeclKind>
1154   isUsesAllocatorsDecl(unsigned Level, const Decl *D) const {
1155     const SharingMapTy &StackElem = getTopOfStack();
1156     auto I = StackElem.UsesAllocatorsDecls.find(D);
1157     if (I == StackElem.UsesAllocatorsDecls.end())
1158       return std::nullopt;
1159     return I->getSecond();
1160   }
1161   std::optional<UsesAllocatorsDeclKind>
1162   isUsesAllocatorsDecl(const Decl *D) const {
1163     const SharingMapTy &StackElem = getTopOfStack();
1164     auto I = StackElem.UsesAllocatorsDecls.find(D);
1165     if (I == StackElem.UsesAllocatorsDecls.end())
1166       return std::nullopt;
1167     return I->getSecond();
1168   }
1169 
1170   void addDeclareMapperVarRef(Expr *Ref) {
1171     SharingMapTy &StackElem = getTopOfStack();
1172     StackElem.DeclareMapperVar = Ref;
1173   }
1174   const Expr *getDeclareMapperVarRef() const {
1175     const SharingMapTy *Top = getTopOfStackOrNull();
1176     return Top ? Top->DeclareMapperVar : nullptr;
1177   }
1178 
1179   /// Add a new iterator variable.
1180   void addIteratorVarDecl(VarDecl *VD) {
1181     SharingMapTy &StackElem = getTopOfStack();
1182     StackElem.IteratorVarDecls.push_back(VD->getCanonicalDecl());
1183   }
1184   /// Check if variable declaration is an iterator VarDecl.
1185   bool isIteratorVarDecl(const VarDecl *VD) const {
1186     const SharingMapTy *Top = getTopOfStackOrNull();
1187     if (!Top)
1188       return false;
1189 
1190     return llvm::is_contained(Top->IteratorVarDecls, VD->getCanonicalDecl());
1191   }
1192   /// get captured field from ImplicitDefaultFirstprivateFDs
1193   VarDecl *getImplicitFDCapExprDecl(const FieldDecl *FD) const {
1194     const_iterator I = begin();
1195     const_iterator EndI = end();
1196     size_t StackLevel = getStackSize();
1197     for (; I != EndI; ++I) {
1198       if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private)
1199         break;
1200       StackLevel--;
1201     }
1202     assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI));
1203     if (I == EndI)
1204       return nullptr;
1205     for (const auto &IFD : I->ImplicitDefaultFirstprivateFDs)
1206       if (IFD.FD == FD && IFD.StackLevel == StackLevel)
1207         return IFD.VD;
1208     return nullptr;
1209   }
1210   /// Check if capture decl is field captured in ImplicitDefaultFirstprivateFDs
1211   bool isImplicitDefaultFirstprivateFD(VarDecl *VD) const {
1212     const_iterator I = begin();
1213     const_iterator EndI = end();
1214     for (; I != EndI; ++I)
1215       if (I->DefaultAttr == DSA_firstprivate || I->DefaultAttr == DSA_private)
1216         break;
1217     if (I == EndI)
1218       return false;
1219     for (const auto &IFD : I->ImplicitDefaultFirstprivateFDs)
1220       if (IFD.VD == VD)
1221         return true;
1222     return false;
1223   }
1224   /// Store capture FD info in ImplicitDefaultFirstprivateFDs
1225   void addImplicitDefaultFirstprivateFD(const FieldDecl *FD, VarDecl *VD) {
1226     iterator I = begin();
1227     const_iterator EndI = end();
1228     size_t StackLevel = getStackSize();
1229     for (; I != EndI; ++I) {
1230       if (I->DefaultAttr == DSA_private || I->DefaultAttr == DSA_firstprivate) {
1231         I->ImplicitDefaultFirstprivateFDs.emplace_back(FD, StackLevel, VD);
1232         break;
1233       }
1234       StackLevel--;
1235     }
1236     assert((StackLevel > 0 && I != EndI) || (StackLevel == 0 && I == EndI));
1237   }
1238 };
1239 
1240 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1241   return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
1242 }
1243 
1244 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1245   return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) ||
1246          DKind == OMPD_unknown;
1247 }
1248 
1249 } // namespace
1250 
1251 static const Expr *getExprAsWritten(const Expr *E) {
1252   if (const auto *FE = dyn_cast<FullExpr>(E))
1253     E = FE->getSubExpr();
1254 
1255   if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
1256     E = MTE->getSubExpr();
1257 
1258   while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
1259     E = Binder->getSubExpr();
1260 
1261   if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
1262     E = ICE->getSubExprAsWritten();
1263   return E->IgnoreParens();
1264 }
1265 
1266 static Expr *getExprAsWritten(Expr *E) {
1267   return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
1268 }
1269 
1270 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
1271   if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
1272     if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
1273       D = ME->getMemberDecl();
1274   const auto *VD = dyn_cast<VarDecl>(D);
1275   const auto *FD = dyn_cast<FieldDecl>(D);
1276   if (VD != nullptr) {
1277     VD = VD->getCanonicalDecl();
1278     D = VD;
1279   } else {
1280     assert(FD);
1281     FD = FD->getCanonicalDecl();
1282     D = FD;
1283   }
1284   return D;
1285 }
1286 
1287 static ValueDecl *getCanonicalDecl(ValueDecl *D) {
1288   return const_cast<ValueDecl *>(
1289       getCanonicalDecl(const_cast<const ValueDecl *>(D)));
1290 }
1291 
1292 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
1293                                           ValueDecl *D) const {
1294   D = getCanonicalDecl(D);
1295   auto *VD = dyn_cast<VarDecl>(D);
1296   const auto *FD = dyn_cast<FieldDecl>(D);
1297   DSAVarData DVar;
1298   if (Iter == end()) {
1299     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1300     // in a region but not in construct]
1301     //  File-scope or namespace-scope variables referenced in called routines
1302     //  in the region are shared unless they appear in a threadprivate
1303     //  directive.
1304     if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
1305       DVar.CKind = OMPC_shared;
1306 
1307     // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
1308     // in a region but not in construct]
1309     //  Variables with static storage duration that are declared in called
1310     //  routines in the region are shared.
1311     if (VD && VD->hasGlobalStorage())
1312       DVar.CKind = OMPC_shared;
1313 
1314     // Non-static data members are shared by default.
1315     if (FD)
1316       DVar.CKind = OMPC_shared;
1317 
1318     return DVar;
1319   }
1320 
1321   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1322   // in a Construct, C/C++, predetermined, p.1]
1323   // Variables with automatic storage duration that are declared in a scope
1324   // inside the construct are private.
1325   if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
1326       (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
1327     DVar.CKind = OMPC_private;
1328     return DVar;
1329   }
1330 
1331   DVar.DKind = Iter->Directive;
1332   // Explicitly specified attributes and local variables with predetermined
1333   // attributes.
1334   if (Iter->SharingMap.count(D)) {
1335     const DSAInfo &Data = Iter->SharingMap.lookup(D);
1336     DVar.RefExpr = Data.RefExpr.getPointer();
1337     DVar.PrivateCopy = Data.PrivateCopy;
1338     DVar.CKind = Data.Attributes;
1339     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1340     DVar.Modifier = Data.Modifier;
1341     DVar.AppliedToPointee = Data.AppliedToPointee;
1342     return DVar;
1343   }
1344 
1345   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1346   // in a Construct, C/C++, implicitly determined, p.1]
1347   //  In a parallel or task construct, the data-sharing attributes of these
1348   //  variables are determined by the default clause, if present.
1349   switch (Iter->DefaultAttr) {
1350   case DSA_shared:
1351     DVar.CKind = OMPC_shared;
1352     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1353     return DVar;
1354   case DSA_none:
1355     return DVar;
1356   case DSA_firstprivate:
1357     if (VD && VD->getStorageDuration() == SD_Static &&
1358         VD->getDeclContext()->isFileContext()) {
1359       DVar.CKind = OMPC_unknown;
1360     } else {
1361       DVar.CKind = OMPC_firstprivate;
1362     }
1363     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1364     return DVar;
1365   case DSA_private:
1366     // each variable with static storage duration that is declared
1367     // in a namespace or global scope and referenced in the construct,
1368     // and that does not have a predetermined data-sharing attribute
1369     if (VD && VD->getStorageDuration() == SD_Static &&
1370         VD->getDeclContext()->isFileContext()) {
1371       DVar.CKind = OMPC_unknown;
1372     } else {
1373       DVar.CKind = OMPC_private;
1374     }
1375     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1376     return DVar;
1377   case DSA_unspecified:
1378     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1379     // in a Construct, implicitly determined, p.2]
1380     //  In a parallel construct, if no default clause is present, these
1381     //  variables are shared.
1382     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1383     if ((isOpenMPParallelDirective(DVar.DKind) &&
1384          !isOpenMPTaskLoopDirective(DVar.DKind)) ||
1385         isOpenMPTeamsDirective(DVar.DKind)) {
1386       DVar.CKind = OMPC_shared;
1387       return DVar;
1388     }
1389 
1390     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1391     // in a Construct, implicitly determined, p.4]
1392     //  In a task construct, if no default clause is present, a variable that in
1393     //  the enclosing context is determined to be shared by all implicit tasks
1394     //  bound to the current team is shared.
1395     if (isOpenMPTaskingDirective(DVar.DKind)) {
1396       DSAVarData DVarTemp;
1397       const_iterator I = Iter, E = end();
1398       do {
1399         ++I;
1400         // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
1401         // Referenced in a Construct, implicitly determined, p.6]
1402         //  In a task construct, if no default clause is present, a variable
1403         //  whose data-sharing attribute is not determined by the rules above is
1404         //  firstprivate.
1405         DVarTemp = getDSA(I, D);
1406         if (DVarTemp.CKind != OMPC_shared) {
1407           DVar.RefExpr = nullptr;
1408           DVar.CKind = OMPC_firstprivate;
1409           return DVar;
1410         }
1411       } while (I != E && !isImplicitTaskingRegion(I->Directive));
1412       DVar.CKind =
1413           (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1414       return DVar;
1415     }
1416   }
1417   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1418   // in a Construct, implicitly determined, p.3]
1419   //  For constructs other than task, if no default clause is present, these
1420   //  variables inherit their data-sharing attributes from the enclosing
1421   //  context.
1422   return getDSA(++Iter, D);
1423 }
1424 
1425 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
1426                                          const Expr *NewDE) {
1427   assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1428   D = getCanonicalDecl(D);
1429   SharingMapTy &StackElem = getTopOfStack();
1430   auto It = StackElem.AlignedMap.find(D);
1431   if (It == StackElem.AlignedMap.end()) {
1432     assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1433     StackElem.AlignedMap[D] = NewDE;
1434     return nullptr;
1435   }
1436   assert(It->second && "Unexpected nullptr expr in the aligned map");
1437   return It->second;
1438 }
1439 
1440 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D,
1441                                              const Expr *NewDE) {
1442   assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1443   D = getCanonicalDecl(D);
1444   SharingMapTy &StackElem = getTopOfStack();
1445   auto It = StackElem.NontemporalMap.find(D);
1446   if (It == StackElem.NontemporalMap.end()) {
1447     assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1448     StackElem.NontemporalMap[D] = NewDE;
1449     return nullptr;
1450   }
1451   assert(It->second && "Unexpected nullptr expr in the aligned map");
1452   return It->second;
1453 }
1454 
1455 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
1456   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1457   D = getCanonicalDecl(D);
1458   SharingMapTy &StackElem = getTopOfStack();
1459   StackElem.LCVMap.try_emplace(
1460       D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
1461 }
1462 
1463 const DSAStackTy::LCDeclInfo
1464 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
1465   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1466   D = getCanonicalDecl(D);
1467   const SharingMapTy &StackElem = getTopOfStack();
1468   auto It = StackElem.LCVMap.find(D);
1469   if (It != StackElem.LCVMap.end())
1470     return It->second;
1471   return {0, nullptr};
1472 }
1473 
1474 const DSAStackTy::LCDeclInfo
1475 DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const {
1476   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1477   D = getCanonicalDecl(D);
1478   for (unsigned I = Level + 1; I > 0; --I) {
1479     const SharingMapTy &StackElem = getStackElemAtLevel(I - 1);
1480     auto It = StackElem.LCVMap.find(D);
1481     if (It != StackElem.LCVMap.end())
1482       return It->second;
1483   }
1484   return {0, nullptr};
1485 }
1486 
1487 const DSAStackTy::LCDeclInfo
1488 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
1489   const SharingMapTy *Parent = getSecondOnStackOrNull();
1490   assert(Parent && "Data-sharing attributes stack is empty");
1491   D = getCanonicalDecl(D);
1492   auto It = Parent->LCVMap.find(D);
1493   if (It != Parent->LCVMap.end())
1494     return It->second;
1495   return {0, nullptr};
1496 }
1497 
1498 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
1499   const SharingMapTy *Parent = getSecondOnStackOrNull();
1500   assert(Parent && "Data-sharing attributes stack is empty");
1501   if (Parent->LCVMap.size() < I)
1502     return nullptr;
1503   for (const auto &Pair : Parent->LCVMap)
1504     if (Pair.second.first == I)
1505       return Pair.first;
1506   return nullptr;
1507 }
1508 
1509 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
1510                         DeclRefExpr *PrivateCopy, unsigned Modifier,
1511                         bool AppliedToPointee) {
1512   D = getCanonicalDecl(D);
1513   if (A == OMPC_threadprivate) {
1514     DSAInfo &Data = Threadprivates[D];
1515     Data.Attributes = A;
1516     Data.RefExpr.setPointer(E);
1517     Data.PrivateCopy = nullptr;
1518     Data.Modifier = Modifier;
1519   } else {
1520     DSAInfo &Data = getTopOfStack().SharingMap[D];
1521     assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
1522            (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
1523            (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
1524            (isLoopControlVariable(D).first && A == OMPC_private));
1525     Data.Modifier = Modifier;
1526     if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
1527       Data.RefExpr.setInt(/*IntVal=*/true);
1528       return;
1529     }
1530     const bool IsLastprivate =
1531         A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
1532     Data.Attributes = A;
1533     Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1534     Data.PrivateCopy = PrivateCopy;
1535     Data.AppliedToPointee = AppliedToPointee;
1536     if (PrivateCopy) {
1537       DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()];
1538       Data.Modifier = Modifier;
1539       Data.Attributes = A;
1540       Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1541       Data.PrivateCopy = nullptr;
1542       Data.AppliedToPointee = AppliedToPointee;
1543     }
1544   }
1545 }
1546 
1547 /// Build a variable declaration for OpenMP loop iteration variable.
1548 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
1549                              StringRef Name, const AttrVec *Attrs = nullptr,
1550                              DeclRefExpr *OrigRef = nullptr) {
1551   DeclContext *DC = SemaRef.CurContext;
1552   IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
1553   TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
1554   auto *Decl =
1555       VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
1556   if (Attrs) {
1557     for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
1558          I != E; ++I)
1559       Decl->addAttr(*I);
1560   }
1561   Decl->setImplicit();
1562   if (OrigRef) {
1563     Decl->addAttr(
1564         OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
1565   }
1566   return Decl;
1567 }
1568 
1569 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
1570                                      SourceLocation Loc,
1571                                      bool RefersToCapture = false) {
1572   D->setReferenced();
1573   D->markUsed(S.Context);
1574   return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
1575                              SourceLocation(), D, RefersToCapture, Loc, Ty,
1576                              VK_LValue);
1577 }
1578 
1579 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1580                                            BinaryOperatorKind BOK) {
1581   D = getCanonicalDecl(D);
1582   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1583   assert(
1584       getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1585       "Additional reduction info may be specified only for reduction items.");
1586   ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1587   assert(ReductionData.ReductionRange.isInvalid() &&
1588          (getTopOfStack().Directive == OMPD_taskgroup ||
1589           ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1590             isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1591            !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1592          "Additional reduction info may be specified only once for reduction "
1593          "items.");
1594   ReductionData.set(BOK, SR);
1595   Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1596   if (!TaskgroupReductionRef) {
1597     VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1598                                SemaRef.Context.VoidPtrTy, ".task_red.");
1599     TaskgroupReductionRef =
1600         buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1601   }
1602 }
1603 
1604 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1605                                            const Expr *ReductionRef) {
1606   D = getCanonicalDecl(D);
1607   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1608   assert(
1609       getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1610       "Additional reduction info may be specified only for reduction items.");
1611   ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1612   assert(ReductionData.ReductionRange.isInvalid() &&
1613          (getTopOfStack().Directive == OMPD_taskgroup ||
1614           ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1615             isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1616            !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1617          "Additional reduction info may be specified only once for reduction "
1618          "items.");
1619   ReductionData.set(ReductionRef, SR);
1620   Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1621   if (!TaskgroupReductionRef) {
1622     VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1623                                SemaRef.Context.VoidPtrTy, ".task_red.");
1624     TaskgroupReductionRef =
1625         buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1626   }
1627 }
1628 
1629 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1630     const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
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         ReductionData.ReductionOp.is<const Expr *>())
1642       return DSAVarData();
1643     SR = ReductionData.ReductionRange;
1644     BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
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 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1657     const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
1658     Expr *&TaskgroupDescriptor) const {
1659   D = getCanonicalDecl(D);
1660   assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1661   for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1662     const DSAInfo &Data = I->SharingMap.lookup(D);
1663     if (Data.Attributes != OMPC_reduction ||
1664         Data.Modifier != OMPC_REDUCTION_task)
1665       continue;
1666     const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1667     if (!ReductionData.ReductionOp ||
1668         !ReductionData.ReductionOp.is<const Expr *>())
1669       return DSAVarData();
1670     SR = ReductionData.ReductionRange;
1671     ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
1672     assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1673                                        "expression for the descriptor is not "
1674                                        "set.");
1675     TaskgroupDescriptor = I->TaskgroupReductionRef;
1676     return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1677                       Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1678                       /*AppliedToPointee=*/false);
1679   }
1680   return DSAVarData();
1681 }
1682 
1683 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const {
1684   D = D->getCanonicalDecl();
1685   for (const_iterator E = end(); I != E; ++I) {
1686     if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1687         isOpenMPTargetExecutionDirective(I->Directive)) {
1688       if (I->CurScope) {
1689         Scope *TopScope = I->CurScope->getParent();
1690         Scope *CurScope = getCurScope();
1691         while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D))
1692           CurScope = CurScope->getParent();
1693         return CurScope != TopScope;
1694       }
1695       for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent())
1696         if (I->Context == DC)
1697           return true;
1698       return false;
1699     }
1700   }
1701   return false;
1702 }
1703 
1704 static bool isConstNotMutableType(Sema &SemaRef, QualType Type,
1705                                   bool AcceptIfMutable = true,
1706                                   bool *IsClassType = nullptr) {
1707   ASTContext &Context = SemaRef.getASTContext();
1708   Type = Type.getNonReferenceType().getCanonicalType();
1709   bool IsConstant = Type.isConstant(Context);
1710   Type = Context.getBaseElementType(Type);
1711   const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus
1712                                 ? Type->getAsCXXRecordDecl()
1713                                 : nullptr;
1714   if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1715     if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1716       RD = CTD->getTemplatedDecl();
1717   if (IsClassType)
1718     *IsClassType = RD;
1719   return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD &&
1720                          RD->hasDefinition() && RD->hasMutableFields());
1721 }
1722 
1723 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D,
1724                                       QualType Type, OpenMPClauseKind CKind,
1725                                       SourceLocation ELoc,
1726                                       bool AcceptIfMutable = true,
1727                                       bool ListItemNotVar = false) {
1728   ASTContext &Context = SemaRef.getASTContext();
1729   bool IsClassType;
1730   if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) {
1731     unsigned Diag = ListItemNotVar ? diag::err_omp_const_list_item
1732                     : IsClassType  ? diag::err_omp_const_not_mutable_variable
1733                                    : diag::err_omp_const_variable;
1734     SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind);
1735     if (!ListItemNotVar && D) {
1736       const VarDecl *VD = dyn_cast<VarDecl>(D);
1737       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
1738                                VarDecl::DeclarationOnly;
1739       SemaRef.Diag(D->getLocation(),
1740                    IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1741           << D;
1742     }
1743     return true;
1744   }
1745   return false;
1746 }
1747 
1748 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1749                                                    bool FromParent) {
1750   D = getCanonicalDecl(D);
1751   DSAVarData DVar;
1752 
1753   auto *VD = dyn_cast<VarDecl>(D);
1754   auto TI = Threadprivates.find(D);
1755   if (TI != Threadprivates.end()) {
1756     DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1757     DVar.CKind = OMPC_threadprivate;
1758     DVar.Modifier = TI->getSecond().Modifier;
1759     return DVar;
1760   }
1761   if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1762     DVar.RefExpr = buildDeclRefExpr(
1763         SemaRef, VD, D->getType().getNonReferenceType(),
1764         VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1765     DVar.CKind = OMPC_threadprivate;
1766     addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1767     return DVar;
1768   }
1769   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1770   // in a Construct, C/C++, predetermined, p.1]
1771   //  Variables appearing in threadprivate directives are threadprivate.
1772   if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1773        !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1774          SemaRef.getLangOpts().OpenMPUseTLS &&
1775          SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1776       (VD && VD->getStorageClass() == SC_Register &&
1777        VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1778     DVar.RefExpr = buildDeclRefExpr(
1779         SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1780     DVar.CKind = OMPC_threadprivate;
1781     addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1782     return DVar;
1783   }
1784   if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1785       VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1786       !isLoopControlVariable(D).first) {
1787     const_iterator IterTarget =
1788         std::find_if(begin(), end(), [](const SharingMapTy &Data) {
1789           return isOpenMPTargetExecutionDirective(Data.Directive);
1790         });
1791     if (IterTarget != end()) {
1792       const_iterator ParentIterTarget = IterTarget + 1;
1793       for (const_iterator Iter = begin(); Iter != ParentIterTarget; ++Iter) {
1794         if (isOpenMPLocal(VD, Iter)) {
1795           DVar.RefExpr =
1796               buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1797                                D->getLocation());
1798           DVar.CKind = OMPC_threadprivate;
1799           return DVar;
1800         }
1801       }
1802       if (!isClauseParsingMode() || IterTarget != begin()) {
1803         auto DSAIter = IterTarget->SharingMap.find(D);
1804         if (DSAIter != IterTarget->SharingMap.end() &&
1805             isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1806           DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1807           DVar.CKind = OMPC_threadprivate;
1808           return DVar;
1809         }
1810         const_iterator End = end();
1811         if (!SemaRef.isOpenMPCapturedByRef(D,
1812                                            std::distance(ParentIterTarget, End),
1813                                            /*OpenMPCaptureLevel=*/0)) {
1814           DVar.RefExpr =
1815               buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1816                                IterTarget->ConstructLoc);
1817           DVar.CKind = OMPC_threadprivate;
1818           return DVar;
1819         }
1820       }
1821     }
1822   }
1823 
1824   if (isStackEmpty())
1825     // Not in OpenMP execution region and top scope was already checked.
1826     return DVar;
1827 
1828   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1829   // in a Construct, C/C++, predetermined, p.4]
1830   //  Static data members are shared.
1831   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1832   // in a Construct, C/C++, predetermined, p.7]
1833   //  Variables with static storage duration that are declared in a scope
1834   //  inside the construct are shared.
1835   if (VD && VD->isStaticDataMember()) {
1836     // Check for explicitly specified attributes.
1837     const_iterator I = begin();
1838     const_iterator EndI = end();
1839     if (FromParent && I != EndI)
1840       ++I;
1841     if (I != EndI) {
1842       auto It = I->SharingMap.find(D);
1843       if (It != I->SharingMap.end()) {
1844         const DSAInfo &Data = It->getSecond();
1845         DVar.RefExpr = Data.RefExpr.getPointer();
1846         DVar.PrivateCopy = Data.PrivateCopy;
1847         DVar.CKind = Data.Attributes;
1848         DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1849         DVar.DKind = I->Directive;
1850         DVar.Modifier = Data.Modifier;
1851         DVar.AppliedToPointee = Data.AppliedToPointee;
1852         return DVar;
1853       }
1854     }
1855 
1856     DVar.CKind = OMPC_shared;
1857     return DVar;
1858   }
1859 
1860   auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
1861   // The predetermined shared attribute for const-qualified types having no
1862   // mutable members was removed after OpenMP 3.1.
1863   if (SemaRef.LangOpts.OpenMP <= 31) {
1864     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1865     // in a Construct, C/C++, predetermined, p.6]
1866     //  Variables with const qualified type having no mutable member are
1867     //  shared.
1868     if (isConstNotMutableType(SemaRef, D->getType())) {
1869       // Variables with const-qualified type having no mutable member may be
1870       // listed in a firstprivate clause, even if they are static data members.
1871       DSAVarData DVarTemp = hasInnermostDSA(
1872           D,
1873           [](OpenMPClauseKind C, bool) {
1874             return C == OMPC_firstprivate || C == OMPC_shared;
1875           },
1876           MatchesAlways, FromParent);
1877       if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1878         return DVarTemp;
1879 
1880       DVar.CKind = OMPC_shared;
1881       return DVar;
1882     }
1883   }
1884 
1885   // Explicitly specified attributes and local variables with predetermined
1886   // attributes.
1887   const_iterator I = begin();
1888   const_iterator EndI = end();
1889   if (FromParent && I != EndI)
1890     ++I;
1891   if (I == EndI)
1892     return DVar;
1893   auto It = I->SharingMap.find(D);
1894   if (It != I->SharingMap.end()) {
1895     const DSAInfo &Data = It->getSecond();
1896     DVar.RefExpr = Data.RefExpr.getPointer();
1897     DVar.PrivateCopy = Data.PrivateCopy;
1898     DVar.CKind = Data.Attributes;
1899     DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1900     DVar.DKind = I->Directive;
1901     DVar.Modifier = Data.Modifier;
1902     DVar.AppliedToPointee = Data.AppliedToPointee;
1903   }
1904 
1905   return DVar;
1906 }
1907 
1908 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1909                                                         bool FromParent) const {
1910   if (isStackEmpty()) {
1911     const_iterator I;
1912     return getDSA(I, D);
1913   }
1914   D = getCanonicalDecl(D);
1915   const_iterator StartI = begin();
1916   const_iterator EndI = end();
1917   if (FromParent && StartI != EndI)
1918     ++StartI;
1919   return getDSA(StartI, D);
1920 }
1921 
1922 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1923                                                         unsigned Level) const {
1924   if (getStackSize() <= Level)
1925     return DSAVarData();
1926   D = getCanonicalDecl(D);
1927   const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level);
1928   return getDSA(StartI, D);
1929 }
1930 
1931 const DSAStackTy::DSAVarData
1932 DSAStackTy::hasDSA(ValueDecl *D,
1933                    const llvm::function_ref<bool(OpenMPClauseKind, bool,
1934                                                  DefaultDataSharingAttributes)>
1935                        CPred,
1936                    const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1937                    bool FromParent) const {
1938   if (isStackEmpty())
1939     return {};
1940   D = getCanonicalDecl(D);
1941   const_iterator I = begin();
1942   const_iterator EndI = end();
1943   if (FromParent && I != EndI)
1944     ++I;
1945   for (; I != EndI; ++I) {
1946     if (!DPred(I->Directive) &&
1947         !isImplicitOrExplicitTaskingRegion(I->Directive))
1948       continue;
1949     const_iterator NewI = I;
1950     DSAVarData DVar = getDSA(NewI, D);
1951     if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee, I->DefaultAttr))
1952       return DVar;
1953   }
1954   return {};
1955 }
1956 
1957 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1958     ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1959     const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1960     bool FromParent) const {
1961   if (isStackEmpty())
1962     return {};
1963   D = getCanonicalDecl(D);
1964   const_iterator StartI = begin();
1965   const_iterator EndI = end();
1966   if (FromParent && StartI != EndI)
1967     ++StartI;
1968   if (StartI == EndI || !DPred(StartI->Directive))
1969     return {};
1970   const_iterator NewI = StartI;
1971   DSAVarData DVar = getDSA(NewI, D);
1972   return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee))
1973              ? DVar
1974              : DSAVarData();
1975 }
1976 
1977 bool DSAStackTy::hasExplicitDSA(
1978     const ValueDecl *D,
1979     const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1980     unsigned Level, bool NotLastprivate) const {
1981   if (getStackSize() <= Level)
1982     return false;
1983   D = getCanonicalDecl(D);
1984   const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1985   auto I = StackElem.SharingMap.find(D);
1986   if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() &&
1987       CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) &&
1988       (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1989     return true;
1990   // Check predetermined rules for the loop control variables.
1991   auto LI = StackElem.LCVMap.find(D);
1992   if (LI != StackElem.LCVMap.end())
1993     return CPred(OMPC_private, /*AppliedToPointee=*/false);
1994   return false;
1995 }
1996 
1997 bool DSAStackTy::hasExplicitDirective(
1998     const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1999     unsigned Level) const {
2000   if (getStackSize() <= Level)
2001     return false;
2002   const SharingMapTy &StackElem = getStackElemAtLevel(Level);
2003   return DPred(StackElem.Directive);
2004 }
2005 
2006 bool DSAStackTy::hasDirective(
2007     const llvm::function_ref<bool(OpenMPDirectiveKind,
2008                                   const DeclarationNameInfo &, SourceLocation)>
2009         DPred,
2010     bool FromParent) const {
2011   // We look only in the enclosing region.
2012   size_t Skip = FromParent ? 2 : 1;
2013   for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
2014        I != E; ++I) {
2015     if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
2016       return true;
2017   }
2018   return false;
2019 }
2020 
2021 void Sema::InitDataSharingAttributesStack() {
2022   VarDataSharingAttributesStack = new DSAStackTy(*this);
2023 }
2024 
2025 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
2026 
2027 void Sema::pushOpenMPFunctionRegion() { DSAStack->pushFunction(); }
2028 
2029 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
2030   DSAStack->popFunction(OldFSI);
2031 }
2032 
2033 static bool isOpenMPDeviceDelayedContext(Sema &S) {
2034   assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsTargetDevice &&
2035          "Expected OpenMP device compilation.");
2036   return !S.isInOpenMPTargetExecutionDirective();
2037 }
2038 
2039 namespace {
2040 /// Status of the function emission on the host/device.
2041 enum class FunctionEmissionStatus {
2042   Emitted,
2043   Discarded,
2044   Unknown,
2045 };
2046 } // anonymous namespace
2047 
2048 Sema::SemaDiagnosticBuilder
2049 Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, unsigned DiagID,
2050                              const FunctionDecl *FD) {
2051   assert(LangOpts.OpenMP && LangOpts.OpenMPIsTargetDevice &&
2052          "Expected OpenMP device compilation.");
2053 
2054   SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
2055   if (FD) {
2056     FunctionEmissionStatus FES = getEmissionStatus(FD);
2057     switch (FES) {
2058     case FunctionEmissionStatus::Emitted:
2059       Kind = SemaDiagnosticBuilder::K_Immediate;
2060       break;
2061     case FunctionEmissionStatus::Unknown:
2062       // TODO: We should always delay diagnostics here in case a target
2063       //       region is in a function we do not emit. However, as the
2064       //       current diagnostics are associated with the function containing
2065       //       the target region and we do not emit that one, we would miss out
2066       //       on diagnostics for the target region itself. We need to anchor
2067       //       the diagnostics with the new generated function *or* ensure we
2068       //       emit diagnostics associated with the surrounding function.
2069       Kind = isOpenMPDeviceDelayedContext(*this)
2070                  ? SemaDiagnosticBuilder::K_Deferred
2071                  : SemaDiagnosticBuilder::K_Immediate;
2072       break;
2073     case FunctionEmissionStatus::TemplateDiscarded:
2074     case FunctionEmissionStatus::OMPDiscarded:
2075       Kind = SemaDiagnosticBuilder::K_Nop;
2076       break;
2077     case FunctionEmissionStatus::CUDADiscarded:
2078       llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation");
2079       break;
2080     }
2081   }
2082 
2083   return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this);
2084 }
2085 
2086 Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc,
2087                                                        unsigned DiagID,
2088                                                        const FunctionDecl *FD) {
2089   assert(LangOpts.OpenMP && !LangOpts.OpenMPIsTargetDevice &&
2090          "Expected OpenMP host compilation.");
2091 
2092   SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
2093   if (FD) {
2094     FunctionEmissionStatus FES = getEmissionStatus(FD);
2095     switch (FES) {
2096     case FunctionEmissionStatus::Emitted:
2097       Kind = SemaDiagnosticBuilder::K_Immediate;
2098       break;
2099     case FunctionEmissionStatus::Unknown:
2100       Kind = SemaDiagnosticBuilder::K_Deferred;
2101       break;
2102     case FunctionEmissionStatus::TemplateDiscarded:
2103     case FunctionEmissionStatus::OMPDiscarded:
2104     case FunctionEmissionStatus::CUDADiscarded:
2105       Kind = SemaDiagnosticBuilder::K_Nop;
2106       break;
2107     }
2108   }
2109 
2110   return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this);
2111 }
2112 
2113 static OpenMPDefaultmapClauseKind
2114 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) {
2115   if (LO.OpenMP <= 45) {
2116     if (VD->getType().getNonReferenceType()->isScalarType())
2117       return OMPC_DEFAULTMAP_scalar;
2118     return OMPC_DEFAULTMAP_aggregate;
2119   }
2120   if (VD->getType().getNonReferenceType()->isAnyPointerType())
2121     return OMPC_DEFAULTMAP_pointer;
2122   if (VD->getType().getNonReferenceType()->isScalarType())
2123     return OMPC_DEFAULTMAP_scalar;
2124   return OMPC_DEFAULTMAP_aggregate;
2125 }
2126 
2127 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
2128                                  unsigned OpenMPCaptureLevel) const {
2129   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2130 
2131   ASTContext &Ctx = getASTContext();
2132   bool IsByRef = true;
2133 
2134   // Find the directive that is associated with the provided scope.
2135   D = cast<ValueDecl>(D->getCanonicalDecl());
2136   QualType Ty = D->getType();
2137 
2138   bool IsVariableUsedInMapClause = false;
2139   if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
2140     // This table summarizes how a given variable should be passed to the device
2141     // given its type and the clauses where it appears. This table is based on
2142     // the description in OpenMP 4.5 [2.10.4, target Construct] and
2143     // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
2144     //
2145     // =========================================================================
2146     // | type |  defaultmap   | pvt | first | is_device_ptr |    map   | res.  |
2147     // |      |(tofrom:scalar)|     |  pvt  |               |has_dv_adr|       |
2148     // =========================================================================
2149     // | scl  |               |     |       |       -       |          | bycopy|
2150     // | scl  |               |  -  |   x   |       -       |     -    | bycopy|
2151     // | scl  |               |  x  |   -   |       -       |     -    | null  |
2152     // | scl  |       x       |     |       |       -       |          | byref |
2153     // | scl  |       x       |  -  |   x   |       -       |     -    | bycopy|
2154     // | scl  |       x       |  x  |   -   |       -       |     -    | null  |
2155     // | scl  |               |  -  |   -   |       -       |     x    | byref |
2156     // | scl  |       x       |  -  |   -   |       -       |     x    | byref |
2157     //
2158     // | agg  |      n.a.     |     |       |       -       |          | byref |
2159     // | agg  |      n.a.     |  -  |   x   |       -       |     -    | byref |
2160     // | agg  |      n.a.     |  x  |   -   |       -       |     -    | null  |
2161     // | agg  |      n.a.     |  -  |   -   |       -       |     x    | byref |
2162     // | agg  |      n.a.     |  -  |   -   |       -       |    x[]   | byref |
2163     //
2164     // | ptr  |      n.a.     |     |       |       -       |          | bycopy|
2165     // | ptr  |      n.a.     |  -  |   x   |       -       |     -    | bycopy|
2166     // | ptr  |      n.a.     |  x  |   -   |       -       |     -    | null  |
2167     // | ptr  |      n.a.     |  -  |   -   |       -       |     x    | byref |
2168     // | ptr  |      n.a.     |  -  |   -   |       -       |    x[]   | bycopy|
2169     // | ptr  |      n.a.     |  -  |   -   |       x       |          | bycopy|
2170     // | ptr  |      n.a.     |  -  |   -   |       x       |     x    | bycopy|
2171     // | ptr  |      n.a.     |  -  |   -   |       x       |    x[]   | bycopy|
2172     // =========================================================================
2173     // Legend:
2174     //  scl - scalar
2175     //  ptr - pointer
2176     //  agg - aggregate
2177     //  x - applies
2178     //  - - invalid in this combination
2179     //  [] - mapped with an array section
2180     //  byref - should be mapped by reference
2181     //  byval - should be mapped by value
2182     //  null - initialize a local variable to null on the device
2183     //
2184     // Observations:
2185     //  - All scalar declarations that show up in a map clause have to be passed
2186     //    by reference, because they may have been mapped in the enclosing data
2187     //    environment.
2188     //  - If the scalar value does not fit the size of uintptr, it has to be
2189     //    passed by reference, regardless the result in the table above.
2190     //  - For pointers mapped by value that have either an implicit map or an
2191     //    array section, the runtime library may pass the NULL value to the
2192     //    device instead of the value passed to it by the compiler.
2193 
2194     if (Ty->isReferenceType())
2195       Ty = Ty->castAs<ReferenceType>()->getPointeeType();
2196 
2197     // Locate map clauses and see if the variable being captured is referred to
2198     // in any of those clauses. Here we only care about variables, not fields,
2199     // because fields are part of aggregates.
2200     bool IsVariableAssociatedWithSection = false;
2201 
2202     DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2203         D, Level,
2204         [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection,
2205          D](OMPClauseMappableExprCommon::MappableExprComponentListRef
2206                 MapExprComponents,
2207             OpenMPClauseKind WhereFoundClauseKind) {
2208           // Both map and has_device_addr clauses information influences how a
2209           // variable is captured. E.g. is_device_ptr does not require changing
2210           // the default behavior.
2211           if (WhereFoundClauseKind != OMPC_map &&
2212               WhereFoundClauseKind != OMPC_has_device_addr)
2213             return false;
2214 
2215           auto EI = MapExprComponents.rbegin();
2216           auto EE = MapExprComponents.rend();
2217 
2218           assert(EI != EE && "Invalid map expression!");
2219 
2220           if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2221             IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
2222 
2223           ++EI;
2224           if (EI == EE)
2225             return false;
2226           auto Last = std::prev(EE);
2227           const auto *UO =
2228               dyn_cast<UnaryOperator>(Last->getAssociatedExpression());
2229           if ((UO && UO->getOpcode() == UO_Deref) ||
2230               isa<ArraySubscriptExpr>(Last->getAssociatedExpression()) ||
2231               isa<OMPArraySectionExpr>(Last->getAssociatedExpression()) ||
2232               isa<MemberExpr>(EI->getAssociatedExpression()) ||
2233               isa<OMPArrayShapingExpr>(Last->getAssociatedExpression())) {
2234             IsVariableAssociatedWithSection = true;
2235             // There is nothing more we need to know about this variable.
2236             return true;
2237           }
2238 
2239           // Keep looking for more map info.
2240           return false;
2241         });
2242 
2243     if (IsVariableUsedInMapClause) {
2244       // If variable is identified in a map clause it is always captured by
2245       // reference except if it is a pointer that is dereferenced somehow.
2246       IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
2247     } else {
2248       // By default, all the data that has a scalar type is mapped by copy
2249       // (except for reduction variables).
2250       // Defaultmap scalar is mutual exclusive to defaultmap pointer
2251       IsByRef = (DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
2252                  !Ty->isAnyPointerType()) ||
2253                 !Ty->isScalarType() ||
2254                 DSAStack->isDefaultmapCapturedByRef(
2255                     Level, getVariableCategoryFromDecl(LangOpts, D)) ||
2256                 DSAStack->hasExplicitDSA(
2257                     D,
2258                     [](OpenMPClauseKind K, bool AppliedToPointee) {
2259                       return K == OMPC_reduction && !AppliedToPointee;
2260                     },
2261                     Level);
2262     }
2263   }
2264 
2265   if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
2266     IsByRef =
2267         ((IsVariableUsedInMapClause &&
2268           DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) ==
2269               OMPD_target) ||
2270          !(DSAStack->hasExplicitDSA(
2271                D,
2272                [](OpenMPClauseKind K, bool AppliedToPointee) -> bool {
2273                  return K == OMPC_firstprivate ||
2274                         (K == OMPC_reduction && AppliedToPointee);
2275                },
2276                Level, /*NotLastprivate=*/true) ||
2277            DSAStack->isUsesAllocatorsDecl(Level, D))) &&
2278         // If the variable is artificial and must be captured by value - try to
2279         // capture by value.
2280         !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
2281           !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) &&
2282         // If the variable is implicitly firstprivate and scalar - capture by
2283         // copy
2284         !((DSAStack->getDefaultDSA() == DSA_firstprivate ||
2285            DSAStack->getDefaultDSA() == DSA_private) &&
2286           !DSAStack->hasExplicitDSA(
2287               D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; },
2288               Level) &&
2289           !DSAStack->isLoopControlVariable(D, Level).first);
2290   }
2291 
2292   // When passing data by copy, we need to make sure it fits the uintptr size
2293   // and alignment, because the runtime library only deals with uintptr types.
2294   // If it does not fit the uintptr size, we need to pass the data by reference
2295   // instead.
2296   if (!IsByRef && (Ctx.getTypeSizeInChars(Ty) >
2297                        Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
2298                    Ctx.getAlignOfGlobalVarInChars(Ty) >
2299                        Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
2300     IsByRef = true;
2301   }
2302 
2303   return IsByRef;
2304 }
2305 
2306 unsigned Sema::getOpenMPNestingLevel() const {
2307   assert(getLangOpts().OpenMP);
2308   return DSAStack->getNestingLevel();
2309 }
2310 
2311 bool Sema::isInOpenMPTaskUntiedContext() const {
2312   return isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
2313          DSAStack->isUntiedRegion();
2314 }
2315 
2316 bool Sema::isInOpenMPTargetExecutionDirective() const {
2317   return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) &&
2318           !DSAStack->isClauseParsingMode()) ||
2319          DSAStack->hasDirective(
2320              [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2321                 SourceLocation) -> bool {
2322                return isOpenMPTargetExecutionDirective(K);
2323              },
2324              false);
2325 }
2326 
2327 bool Sema::isOpenMPRebuildMemberExpr(ValueDecl *D) {
2328   // Only rebuild for Field.
2329   if (!dyn_cast<FieldDecl>(D))
2330     return false;
2331   DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2332       D,
2333       [](OpenMPClauseKind C, bool AppliedToPointee,
2334          DefaultDataSharingAttributes DefaultAttr) {
2335         return isOpenMPPrivate(C) && !AppliedToPointee &&
2336                (DefaultAttr == DSA_firstprivate || DefaultAttr == DSA_private);
2337       },
2338       [](OpenMPDirectiveKind) { return true; },
2339       DSAStack->isClauseParsingMode());
2340   if (DVarPrivate.CKind != OMPC_unknown)
2341     return true;
2342   return false;
2343 }
2344 
2345 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
2346                                              Expr *CaptureExpr, bool WithInit,
2347                                              DeclContext *CurContext,
2348                                              bool AsExpression);
2349 
2350 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
2351                                     unsigned StopAt) {
2352   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2353   D = getCanonicalDecl(D);
2354 
2355   auto *VD = dyn_cast<VarDecl>(D);
2356   // Do not capture constexpr variables.
2357   if (VD && VD->isConstexpr())
2358     return nullptr;
2359 
2360   // If we want to determine whether the variable should be captured from the
2361   // perspective of the current capturing scope, and we've already left all the
2362   // capturing scopes of the top directive on the stack, check from the
2363   // perspective of its parent directive (if any) instead.
2364   DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2365       *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete());
2366 
2367   // If we are attempting to capture a global variable in a directive with
2368   // 'target' we return true so that this global is also mapped to the device.
2369   //
2370   if (VD && !VD->hasLocalStorage() &&
2371       (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
2372     if (isInOpenMPTargetExecutionDirective()) {
2373       DSAStackTy::DSAVarData DVarTop =
2374           DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
2375       if (DVarTop.CKind != OMPC_unknown && DVarTop.RefExpr)
2376         return VD;
2377       // If the declaration is enclosed in a 'declare target' directive,
2378       // then it should not be captured.
2379       //
2380       if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2381         return nullptr;
2382       CapturedRegionScopeInfo *CSI = nullptr;
2383       for (FunctionScopeInfo *FSI : llvm::drop_begin(
2384                llvm::reverse(FunctionScopes),
2385                CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) {
2386         if (!isa<CapturingScopeInfo>(FSI))
2387           return nullptr;
2388         if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2389           if (RSI->CapRegionKind == CR_OpenMP) {
2390             CSI = RSI;
2391             break;
2392           }
2393       }
2394       assert(CSI && "Failed to find CapturedRegionScopeInfo");
2395       SmallVector<OpenMPDirectiveKind, 4> Regions;
2396       getOpenMPCaptureRegions(Regions,
2397                               DSAStack->getDirective(CSI->OpenMPLevel));
2398       if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task)
2399         return VD;
2400     }
2401     if (isInOpenMPDeclareTargetContext()) {
2402       // Try to mark variable as declare target if it is used in capturing
2403       // regions.
2404       if (LangOpts.OpenMP <= 45 &&
2405           !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2406         checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
2407       return nullptr;
2408     }
2409   }
2410 
2411   if (CheckScopeInfo) {
2412     bool OpenMPFound = false;
2413     for (unsigned I = StopAt + 1; I > 0; --I) {
2414       FunctionScopeInfo *FSI = FunctionScopes[I - 1];
2415       if (!isa<CapturingScopeInfo>(FSI))
2416         return nullptr;
2417       if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2418         if (RSI->CapRegionKind == CR_OpenMP) {
2419           OpenMPFound = true;
2420           break;
2421         }
2422     }
2423     if (!OpenMPFound)
2424       return nullptr;
2425   }
2426 
2427   if (DSAStack->getCurrentDirective() != OMPD_unknown &&
2428       (!DSAStack->isClauseParsingMode() ||
2429        DSAStack->getParentDirective() != OMPD_unknown)) {
2430     auto &&Info = DSAStack->isLoopControlVariable(D);
2431     if (Info.first ||
2432         (VD && VD->hasLocalStorage() &&
2433          isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) ||
2434         (VD && DSAStack->isForceVarCapturing()))
2435       return VD ? VD : Info.second;
2436     DSAStackTy::DSAVarData DVarTop =
2437         DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
2438     if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) &&
2439         (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee))
2440       return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
2441     // Threadprivate variables must not be captured.
2442     if (isOpenMPThreadPrivate(DVarTop.CKind))
2443       return nullptr;
2444     // The variable is not private or it is the variable in the directive with
2445     // default(none) clause and not used in any clause.
2446     DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2447         D,
2448         [](OpenMPClauseKind C, bool AppliedToPointee, bool) {
2449           return isOpenMPPrivate(C) && !AppliedToPointee;
2450         },
2451         [](OpenMPDirectiveKind) { return true; },
2452         DSAStack->isClauseParsingMode());
2453     // Global shared must not be captured.
2454     if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2455         ((DSAStack->getDefaultDSA() != DSA_none &&
2456           DSAStack->getDefaultDSA() != DSA_private &&
2457           DSAStack->getDefaultDSA() != DSA_firstprivate) ||
2458          DVarTop.CKind == OMPC_shared))
2459       return nullptr;
2460     auto *FD = dyn_cast<FieldDecl>(D);
2461     if (DVarPrivate.CKind != OMPC_unknown && !VD && FD &&
2462         !DVarPrivate.PrivateCopy) {
2463       DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2464           D,
2465           [](OpenMPClauseKind C, bool AppliedToPointee,
2466              DefaultDataSharingAttributes DefaultAttr) {
2467             return isOpenMPPrivate(C) && !AppliedToPointee &&
2468                    (DefaultAttr == DSA_firstprivate ||
2469                     DefaultAttr == DSA_private);
2470           },
2471           [](OpenMPDirectiveKind) { return true; },
2472           DSAStack->isClauseParsingMode());
2473       if (DVarPrivate.CKind == OMPC_unknown)
2474         return nullptr;
2475 
2476       VarDecl *VD = DSAStack->getImplicitFDCapExprDecl(FD);
2477       if (VD)
2478         return VD;
2479       if (getCurrentThisType().isNull())
2480         return nullptr;
2481       Expr *ThisExpr = BuildCXXThisExpr(SourceLocation(), getCurrentThisType(),
2482                                         /*IsImplicit=*/true);
2483       const CXXScopeSpec CS = CXXScopeSpec();
2484       Expr *ME = BuildMemberExpr(ThisExpr, /*IsArrow=*/true, SourceLocation(),
2485                                  NestedNameSpecifierLoc(), SourceLocation(), FD,
2486                                  DeclAccessPair::make(FD, FD->getAccess()),
2487                                  /*HadMultipleCandidates=*/false,
2488                                  DeclarationNameInfo(), FD->getType(),
2489                                  VK_LValue, OK_Ordinary);
2490       OMPCapturedExprDecl *CD = buildCaptureDecl(
2491           *this, FD->getIdentifier(), ME, DVarPrivate.CKind != OMPC_private,
2492           CurContext->getParent(), /*AsExpression=*/false);
2493       DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
2494           *this, CD, CD->getType().getNonReferenceType(), SourceLocation());
2495       VD = cast<VarDecl>(VDPrivateRefExpr->getDecl());
2496       DSAStack->addImplicitDefaultFirstprivateFD(FD, VD);
2497       return VD;
2498     }
2499     if (DVarPrivate.CKind != OMPC_unknown ||
2500         (VD && (DSAStack->getDefaultDSA() == DSA_none ||
2501                 DSAStack->getDefaultDSA() == DSA_private ||
2502                 DSAStack->getDefaultDSA() == DSA_firstprivate)))
2503       return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2504   }
2505   return nullptr;
2506 }
2507 
2508 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
2509                                         unsigned Level) const {
2510   FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2511 }
2512 
2513 void Sema::startOpenMPLoop() {
2514   assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2515   if (isOpenMPLoopDirective(DSAStack->getCurrentDirective()))
2516     DSAStack->loopInit();
2517 }
2518 
2519 void Sema::startOpenMPCXXRangeFor() {
2520   assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2521   if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2522     DSAStack->resetPossibleLoopCounter();
2523     DSAStack->loopStart();
2524   }
2525 }
2526 
2527 OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level,
2528                                            unsigned CapLevel) const {
2529   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2530   if (DSAStack->getCurrentDirective() != OMPD_unknown &&
2531       (!DSAStack->isClauseParsingMode() ||
2532        DSAStack->getParentDirective() != OMPD_unknown)) {
2533     DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2534         D,
2535         [](OpenMPClauseKind C, bool AppliedToPointee,
2536            DefaultDataSharingAttributes DefaultAttr) {
2537           return isOpenMPPrivate(C) && !AppliedToPointee &&
2538                  DefaultAttr == DSA_private;
2539         },
2540         [](OpenMPDirectiveKind) { return true; },
2541         DSAStack->isClauseParsingMode());
2542     if (DVarPrivate.CKind == OMPC_private && isa<OMPCapturedExprDecl>(D) &&
2543         DSAStack->isImplicitDefaultFirstprivateFD(cast<VarDecl>(D)) &&
2544         !DSAStack->isLoopControlVariable(D).first)
2545       return OMPC_private;
2546   }
2547   if (DSAStack->hasExplicitDirective(isOpenMPTaskingDirective, Level)) {
2548     bool IsTriviallyCopyable =
2549         D->getType().getNonReferenceType().isTriviallyCopyableType(Context) &&
2550         !D->getType()
2551              .getNonReferenceType()
2552              .getCanonicalType()
2553              ->getAsCXXRecordDecl();
2554     OpenMPDirectiveKind DKind = DSAStack->getDirective(Level);
2555     SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2556     getOpenMPCaptureRegions(CaptureRegions, DKind);
2557     if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) &&
2558         (IsTriviallyCopyable ||
2559          !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) {
2560       if (DSAStack->hasExplicitDSA(
2561               D,
2562               [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; },
2563               Level, /*NotLastprivate=*/true))
2564         return OMPC_firstprivate;
2565       DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2566       if (DVar.CKind != OMPC_shared &&
2567           !DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) {
2568         DSAStack->addImplicitTaskFirstprivate(Level, D);
2569         return OMPC_firstprivate;
2570       }
2571     }
2572   }
2573   if (isOpenMPLoopDirective(DSAStack->getCurrentDirective()) &&
2574       !isOpenMPLoopTransformationDirective(DSAStack->getCurrentDirective())) {
2575     if (DSAStack->getAssociatedLoops() > 0 && !DSAStack->isLoopStarted()) {
2576       DSAStack->resetPossibleLoopCounter(D);
2577       DSAStack->loopStart();
2578       return OMPC_private;
2579     }
2580     if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
2581          DSAStack->isLoopControlVariable(D).first) &&
2582         !DSAStack->hasExplicitDSA(
2583             D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; },
2584             Level) &&
2585         !isOpenMPSimdDirective(DSAStack->getCurrentDirective()))
2586       return OMPC_private;
2587   }
2588   if (const auto *VD = dyn_cast<VarDecl>(D)) {
2589     if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2590         DSAStack->isForceVarCapturing() &&
2591         !DSAStack->hasExplicitDSA(
2592             D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; },
2593             Level))
2594       return OMPC_private;
2595   }
2596   // User-defined allocators are private since they must be defined in the
2597   // context of target region.
2598   if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) &&
2599       DSAStack->isUsesAllocatorsDecl(Level, D).value_or(
2600           DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2601           DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2602     return OMPC_private;
2603   return (DSAStack->hasExplicitDSA(
2604               D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; },
2605               Level) ||
2606           (DSAStack->isClauseParsingMode() &&
2607            DSAStack->getClauseParsingMode() == OMPC_private) ||
2608           // Consider taskgroup reduction descriptor variable a private
2609           // to avoid possible capture in the region.
2610           (DSAStack->hasExplicitDirective(
2611                [](OpenMPDirectiveKind K) {
2612                  return K == OMPD_taskgroup ||
2613                         ((isOpenMPParallelDirective(K) ||
2614                           isOpenMPWorksharingDirective(K)) &&
2615                          !isOpenMPSimdDirective(K));
2616                },
2617                Level) &&
2618            DSAStack->isTaskgroupReductionRef(D, Level)))
2619              ? OMPC_private
2620              : OMPC_unknown;
2621 }
2622 
2623 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
2624                                 unsigned Level) {
2625   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2626   D = getCanonicalDecl(D);
2627   OpenMPClauseKind OMPC = OMPC_unknown;
2628   for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) {
2629     const unsigned NewLevel = I - 1;
2630     if (DSAStack->hasExplicitDSA(
2631             D,
2632             [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) {
2633               if (isOpenMPPrivate(K) && !AppliedToPointee) {
2634                 OMPC = K;
2635                 return true;
2636               }
2637               return false;
2638             },
2639             NewLevel))
2640       break;
2641     if (DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2642             D, NewLevel,
2643             [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
2644                OpenMPClauseKind) { return true; })) {
2645       OMPC = OMPC_map;
2646       break;
2647     }
2648     if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2649                                        NewLevel)) {
2650       OMPC = OMPC_map;
2651       if (DSAStack->mustBeFirstprivateAtLevel(
2652               NewLevel, getVariableCategoryFromDecl(LangOpts, D)))
2653         OMPC = OMPC_firstprivate;
2654       break;
2655     }
2656   }
2657   if (OMPC != OMPC_unknown)
2658     FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC)));
2659 }
2660 
2661 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level,
2662                                       unsigned CaptureLevel) const {
2663   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2664   // Return true if the current level is no longer enclosed in a target region.
2665 
2666   SmallVector<OpenMPDirectiveKind, 4> Regions;
2667   getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level));
2668   const auto *VD = dyn_cast<VarDecl>(D);
2669   return VD && !VD->hasLocalStorage() &&
2670          DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2671                                         Level) &&
2672          Regions[CaptureLevel] != OMPD_task;
2673 }
2674 
2675 bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level,
2676                                       unsigned CaptureLevel) const {
2677   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2678   // Return true if the current level is no longer enclosed in a target region.
2679 
2680   if (const auto *VD = dyn_cast<VarDecl>(D)) {
2681     if (!VD->hasLocalStorage()) {
2682       if (isInOpenMPTargetExecutionDirective())
2683         return true;
2684       DSAStackTy::DSAVarData TopDVar =
2685           DSAStack->getTopDSA(D, /*FromParent=*/false);
2686       unsigned NumLevels =
2687           getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2688       if (Level == 0)
2689         // non-file scope static variale with default(firstprivate)
2690         // should be gloabal captured.
2691         return (NumLevels == CaptureLevel + 1 &&
2692                 (TopDVar.CKind != OMPC_shared ||
2693                  DSAStack->getDefaultDSA() == DSA_firstprivate));
2694       do {
2695         --Level;
2696         DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2697         if (DVar.CKind != OMPC_shared)
2698           return true;
2699       } while (Level > 0);
2700     }
2701   }
2702   return true;
2703 }
2704 
2705 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
2706 
2707 void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,
2708                                           OMPTraitInfo &TI) {
2709   OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2710 }
2711 
2712 void Sema::ActOnOpenMPEndDeclareVariant() {
2713   assert(isInOpenMPDeclareVariantScope() &&
2714          "Not in OpenMP declare variant scope!");
2715 
2716   OMPDeclareVariantScopes.pop_back();
2717 }
2718 
2719 void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller,
2720                                          const FunctionDecl *Callee,
2721                                          SourceLocation Loc) {
2722   assert(LangOpts.OpenMP && "Expected OpenMP compilation mode.");
2723   std::optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2724       OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl());
2725   // Ignore host functions during device analyzis.
2726   if (LangOpts.OpenMPIsTargetDevice &&
2727       (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host))
2728     return;
2729   // Ignore nohost functions during host analyzis.
2730   if (!LangOpts.OpenMPIsTargetDevice && DevTy &&
2731       *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2732     return;
2733   const FunctionDecl *FD = Callee->getMostRecentDecl();
2734   DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2735   if (LangOpts.OpenMPIsTargetDevice && DevTy &&
2736       *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2737     // Diagnose host function called during device codegen.
2738     StringRef HostDevTy =
2739         getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host);
2740     Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2741     Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2742          diag::note_omp_marked_device_type_here)
2743         << HostDevTy;
2744     return;
2745   }
2746   if (!LangOpts.OpenMPIsTargetDevice && !LangOpts.OpenMPOffloadMandatory &&
2747       DevTy && *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2748     // In OpenMP 5.2 or later, if the function has a host variant then allow
2749     // that to be called instead
2750     auto &&HasHostAttr = [](const FunctionDecl *Callee) {
2751       for (OMPDeclareVariantAttr *A :
2752            Callee->specific_attrs<OMPDeclareVariantAttr>()) {
2753         auto *DeclRefVariant = cast<DeclRefExpr>(A->getVariantFuncRef());
2754         auto *VariantFD = cast<FunctionDecl>(DeclRefVariant->getDecl());
2755         std::optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2756             OMPDeclareTargetDeclAttr::getDeviceType(
2757                 VariantFD->getMostRecentDecl());
2758         if (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host)
2759           return true;
2760       }
2761       return false;
2762     };
2763     if (getLangOpts().OpenMP >= 52 &&
2764         Callee->hasAttr<OMPDeclareVariantAttr>() && HasHostAttr(Callee))
2765       return;
2766     // Diagnose nohost function called during host codegen.
2767     StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
2768         OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2769     Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
2770     Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2771          diag::note_omp_marked_device_type_here)
2772         << NoHostDevTy;
2773   }
2774 }
2775 
2776 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
2777                                const DeclarationNameInfo &DirName,
2778                                Scope *CurScope, SourceLocation Loc) {
2779   DSAStack->push(DKind, DirName, CurScope, Loc);
2780   PushExpressionEvaluationContext(
2781       ExpressionEvaluationContext::PotentiallyEvaluated);
2782 }
2783 
2784 void Sema::StartOpenMPClause(OpenMPClauseKind K) {
2785   DSAStack->setClauseParsingMode(K);
2786 }
2787 
2788 void Sema::EndOpenMPClause() {
2789   DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
2790   CleanupVarDeclMarking();
2791 }
2792 
2793 static std::pair<ValueDecl *, bool>
2794 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
2795                SourceRange &ERange, bool AllowArraySection = false,
2796                StringRef DiagType = "");
2797 
2798 /// Check consistency of the reduction clauses.
2799 static void checkReductionClauses(Sema &S, DSAStackTy *Stack,
2800                                   ArrayRef<OMPClause *> Clauses) {
2801   bool InscanFound = false;
2802   SourceLocation InscanLoc;
2803   // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions.
2804   // A reduction clause without the inscan reduction-modifier may not appear on
2805   // a construct on which a reduction clause with the inscan reduction-modifier
2806   // appears.
2807   for (OMPClause *C : Clauses) {
2808     if (C->getClauseKind() != OMPC_reduction)
2809       continue;
2810     auto *RC = cast<OMPReductionClause>(C);
2811     if (RC->getModifier() == OMPC_REDUCTION_inscan) {
2812       InscanFound = true;
2813       InscanLoc = RC->getModifierLoc();
2814       continue;
2815     }
2816     if (RC->getModifier() == OMPC_REDUCTION_task) {
2817       // OpenMP 5.0, 2.19.5.4 reduction Clause.
2818       // A reduction clause with the task reduction-modifier may only appear on
2819       // a parallel construct, a worksharing construct or a combined or
2820       // composite construct for which any of the aforementioned constructs is a
2821       // constituent construct and simd or loop are not constituent constructs.
2822       OpenMPDirectiveKind CurDir = Stack->getCurrentDirective();
2823       if (!(isOpenMPParallelDirective(CurDir) ||
2824             isOpenMPWorksharingDirective(CurDir)) ||
2825           isOpenMPSimdDirective(CurDir))
2826         S.Diag(RC->getModifierLoc(),
2827                diag::err_omp_reduction_task_not_parallel_or_worksharing);
2828       continue;
2829     }
2830   }
2831   if (InscanFound) {
2832     for (OMPClause *C : Clauses) {
2833       if (C->getClauseKind() != OMPC_reduction)
2834         continue;
2835       auto *RC = cast<OMPReductionClause>(C);
2836       if (RC->getModifier() != OMPC_REDUCTION_inscan) {
2837         S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown
2838                    ? RC->getBeginLoc()
2839                    : RC->getModifierLoc(),
2840                diag::err_omp_inscan_reduction_expected);
2841         S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction);
2842         continue;
2843       }
2844       for (Expr *Ref : RC->varlists()) {
2845         assert(Ref && "NULL expr in OpenMP nontemporal clause.");
2846         SourceLocation ELoc;
2847         SourceRange ERange;
2848         Expr *SimpleRefExpr = Ref;
2849         auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
2850                                   /*AllowArraySection=*/true);
2851         ValueDecl *D = Res.first;
2852         if (!D)
2853           continue;
2854         if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) {
2855           S.Diag(Ref->getExprLoc(),
2856                  diag::err_omp_reduction_not_inclusive_exclusive)
2857               << Ref->getSourceRange();
2858         }
2859       }
2860     }
2861   }
2862 }
2863 
2864 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
2865                                  ArrayRef<OMPClause *> Clauses);
2866 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2867                                  bool WithInit);
2868 
2869 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2870                               const ValueDecl *D,
2871                               const DSAStackTy::DSAVarData &DVar,
2872                               bool IsLoopIterVar = false);
2873 
2874 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
2875   // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
2876   //  A variable of class type (or array thereof) that appears in a lastprivate
2877   //  clause requires an accessible, unambiguous default constructor for the
2878   //  class type, unless the list item is also specified in a firstprivate
2879   //  clause.
2880   if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2881     for (OMPClause *C : D->clauses()) {
2882       if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2883         SmallVector<Expr *, 8> PrivateCopies;
2884         for (Expr *DE : Clause->varlists()) {
2885           if (DE->isValueDependent() || DE->isTypeDependent()) {
2886             PrivateCopies.push_back(nullptr);
2887             continue;
2888           }
2889           auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2890           auto *VD = cast<VarDecl>(DRE->getDecl());
2891           QualType Type = VD->getType().getNonReferenceType();
2892           const DSAStackTy::DSAVarData DVar =
2893               DSAStack->getTopDSA(VD, /*FromParent=*/false);
2894           if (DVar.CKind == OMPC_lastprivate) {
2895             // Generate helper private variable and initialize it with the
2896             // default value. The address of the original variable is replaced
2897             // by the address of the new private variable in CodeGen. This new
2898             // variable is not added to IdResolver, so the code in the OpenMP
2899             // region uses original variable for proper diagnostics.
2900             VarDecl *VDPrivate = buildVarDecl(
2901                 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
2902                 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
2903             ActOnUninitializedDecl(VDPrivate);
2904             if (VDPrivate->isInvalidDecl()) {
2905               PrivateCopies.push_back(nullptr);
2906               continue;
2907             }
2908             PrivateCopies.push_back(buildDeclRefExpr(
2909                 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
2910           } else {
2911             // The variable is also a firstprivate, so initialization sequence
2912             // for private copy is generated already.
2913             PrivateCopies.push_back(nullptr);
2914           }
2915         }
2916         Clause->setPrivateCopies(PrivateCopies);
2917         continue;
2918       }
2919       // Finalize nontemporal clause by handling private copies, if any.
2920       if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) {
2921         SmallVector<Expr *, 8> PrivateRefs;
2922         for (Expr *RefExpr : Clause->varlists()) {
2923           assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
2924           SourceLocation ELoc;
2925           SourceRange ERange;
2926           Expr *SimpleRefExpr = RefExpr;
2927           auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
2928           if (Res.second)
2929             // It will be analyzed later.
2930             PrivateRefs.push_back(RefExpr);
2931           ValueDecl *D = Res.first;
2932           if (!D)
2933             continue;
2934 
2935           const DSAStackTy::DSAVarData DVar =
2936               DSAStack->getTopDSA(D, /*FromParent=*/false);
2937           PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2938                                                  : SimpleRefExpr);
2939         }
2940         Clause->setPrivateRefs(PrivateRefs);
2941         continue;
2942       }
2943       if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) {
2944         for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) {
2945           OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I);
2946           auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts());
2947           if (!DRE)
2948             continue;
2949           ValueDecl *VD = DRE->getDecl();
2950           if (!VD || !isa<VarDecl>(VD))
2951             continue;
2952           DSAStackTy::DSAVarData DVar =
2953               DSAStack->getTopDSA(VD, /*FromParent=*/false);
2954           // OpenMP [2.12.5, target Construct]
2955           // Memory allocators that appear in a uses_allocators clause cannot
2956           // appear in other data-sharing attribute clauses or data-mapping
2957           // attribute clauses in the same construct.
2958           Expr *MapExpr = nullptr;
2959           if (DVar.RefExpr ||
2960               DSAStack->checkMappableExprComponentListsForDecl(
2961                   VD, /*CurrentRegionOnly=*/true,
2962                   [VD, &MapExpr](
2963                       OMPClauseMappableExprCommon::MappableExprComponentListRef
2964                           MapExprComponents,
2965                       OpenMPClauseKind C) {
2966                     auto MI = MapExprComponents.rbegin();
2967                     auto ME = MapExprComponents.rend();
2968                     if (MI != ME &&
2969                         MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2970                             VD->getCanonicalDecl()) {
2971                       MapExpr = MI->getAssociatedExpression();
2972                       return true;
2973                     }
2974                     return false;
2975                   })) {
2976             Diag(D.Allocator->getExprLoc(),
2977                  diag::err_omp_allocator_used_in_clauses)
2978                 << D.Allocator->getSourceRange();
2979             if (DVar.RefExpr)
2980               reportOriginalDsa(*this, DSAStack, VD, DVar);
2981             else
2982               Diag(MapExpr->getExprLoc(), diag::note_used_here)
2983                   << MapExpr->getSourceRange();
2984           }
2985         }
2986         continue;
2987       }
2988     }
2989     // Check allocate clauses.
2990     if (!CurContext->isDependentContext())
2991       checkAllocateClauses(*this, DSAStack, D->clauses());
2992     checkReductionClauses(*this, DSAStack, D->clauses());
2993   }
2994 
2995   DSAStack->pop();
2996   DiscardCleanupsInEvaluationContext();
2997   PopExpressionEvaluationContext();
2998 }
2999 
3000 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
3001                                      Expr *NumIterations, Sema &SemaRef,
3002                                      Scope *S, DSAStackTy *Stack);
3003 
3004 namespace {
3005 
3006 class VarDeclFilterCCC final : public CorrectionCandidateCallback {
3007 private:
3008   Sema &SemaRef;
3009 
3010 public:
3011   explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
3012   bool ValidateCandidate(const TypoCorrection &Candidate) override {
3013     NamedDecl *ND = Candidate.getCorrectionDecl();
3014     if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
3015       return VD->hasGlobalStorage() &&
3016              SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
3017                                    SemaRef.getCurScope());
3018     }
3019     return false;
3020   }
3021 
3022   std::unique_ptr<CorrectionCandidateCallback> clone() override {
3023     return std::make_unique<VarDeclFilterCCC>(*this);
3024   }
3025 };
3026 
3027 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
3028 private:
3029   Sema &SemaRef;
3030 
3031 public:
3032   explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
3033   bool ValidateCandidate(const TypoCorrection &Candidate) override {
3034     NamedDecl *ND = Candidate.getCorrectionDecl();
3035     if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
3036                isa<FunctionDecl>(ND))) {
3037       return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
3038                                    SemaRef.getCurScope());
3039     }
3040     return false;
3041   }
3042 
3043   std::unique_ptr<CorrectionCandidateCallback> clone() override {
3044     return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
3045   }
3046 };
3047 
3048 } // namespace
3049 
3050 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
3051                                          CXXScopeSpec &ScopeSpec,
3052                                          const DeclarationNameInfo &Id,
3053                                          OpenMPDirectiveKind Kind) {
3054   LookupResult Lookup(*this, Id, LookupOrdinaryName);
3055   LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
3056 
3057   if (Lookup.isAmbiguous())
3058     return ExprError();
3059 
3060   VarDecl *VD;
3061   if (!Lookup.isSingleResult()) {
3062     VarDeclFilterCCC CCC(*this);
3063     if (TypoCorrection Corrected =
3064             CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
3065                         CTK_ErrorRecovery)) {
3066       diagnoseTypo(Corrected,
3067                    PDiag(Lookup.empty()
3068                              ? diag::err_undeclared_var_use_suggest
3069                              : diag::err_omp_expected_var_arg_suggest)
3070                        << Id.getName());
3071       VD = Corrected.getCorrectionDeclAs<VarDecl>();
3072     } else {
3073       Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
3074                                        : diag::err_omp_expected_var_arg)
3075           << Id.getName();
3076       return ExprError();
3077     }
3078   } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
3079     Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
3080     Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
3081     return ExprError();
3082   }
3083   Lookup.suppressDiagnostics();
3084 
3085   // OpenMP [2.9.2, Syntax, C/C++]
3086   //   Variables must be file-scope, namespace-scope, or static block-scope.
3087   if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
3088     Diag(Id.getLoc(), diag::err_omp_global_var_arg)
3089         << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
3090     bool IsDecl =
3091         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3092     Diag(VD->getLocation(),
3093          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3094         << VD;
3095     return ExprError();
3096   }
3097 
3098   VarDecl *CanonicalVD = VD->getCanonicalDecl();
3099   NamedDecl *ND = CanonicalVD;
3100   // OpenMP [2.9.2, Restrictions, C/C++, p.2]
3101   //   A threadprivate directive for file-scope variables must appear outside
3102   //   any definition or declaration.
3103   if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
3104       !getCurLexicalContext()->isTranslationUnit()) {
3105     Diag(Id.getLoc(), diag::err_omp_var_scope)
3106         << getOpenMPDirectiveName(Kind) << VD;
3107     bool IsDecl =
3108         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3109     Diag(VD->getLocation(),
3110          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3111         << VD;
3112     return ExprError();
3113   }
3114   // OpenMP [2.9.2, Restrictions, C/C++, p.3]
3115   //   A threadprivate directive for static class member variables must appear
3116   //   in the class definition, in the same scope in which the member
3117   //   variables are declared.
3118   if (CanonicalVD->isStaticDataMember() &&
3119       !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
3120     Diag(Id.getLoc(), diag::err_omp_var_scope)
3121         << getOpenMPDirectiveName(Kind) << VD;
3122     bool IsDecl =
3123         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3124     Diag(VD->getLocation(),
3125          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3126         << VD;
3127     return ExprError();
3128   }
3129   // OpenMP [2.9.2, Restrictions, C/C++, p.4]
3130   //   A threadprivate directive for namespace-scope variables must appear
3131   //   outside any definition or declaration other than the namespace
3132   //   definition itself.
3133   if (CanonicalVD->getDeclContext()->isNamespace() &&
3134       (!getCurLexicalContext()->isFileContext() ||
3135        !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
3136     Diag(Id.getLoc(), diag::err_omp_var_scope)
3137         << getOpenMPDirectiveName(Kind) << VD;
3138     bool IsDecl =
3139         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3140     Diag(VD->getLocation(),
3141          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3142         << VD;
3143     return ExprError();
3144   }
3145   // OpenMP [2.9.2, Restrictions, C/C++, p.6]
3146   //   A threadprivate directive for static block-scope variables must appear
3147   //   in the scope of the variable and not in a nested scope.
3148   if (CanonicalVD->isLocalVarDecl() && CurScope &&
3149       !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
3150     Diag(Id.getLoc(), diag::err_omp_var_scope)
3151         << getOpenMPDirectiveName(Kind) << VD;
3152     bool IsDecl =
3153         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3154     Diag(VD->getLocation(),
3155          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3156         << VD;
3157     return ExprError();
3158   }
3159 
3160   // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
3161   //   A threadprivate directive must lexically precede all references to any
3162   //   of the variables in its list.
3163   if (Kind == OMPD_threadprivate && VD->isUsed() &&
3164       !DSAStack->isThreadPrivate(VD)) {
3165     Diag(Id.getLoc(), diag::err_omp_var_used)
3166         << getOpenMPDirectiveName(Kind) << VD;
3167     return ExprError();
3168   }
3169 
3170   QualType ExprType = VD->getType().getNonReferenceType();
3171   return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
3172                              SourceLocation(), VD,
3173                              /*RefersToEnclosingVariableOrCapture=*/false,
3174                              Id.getLoc(), ExprType, VK_LValue);
3175 }
3176 
3177 Sema::DeclGroupPtrTy
3178 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
3179                                         ArrayRef<Expr *> VarList) {
3180   if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
3181     CurContext->addDecl(D);
3182     return DeclGroupPtrTy::make(DeclGroupRef(D));
3183   }
3184   return nullptr;
3185 }
3186 
3187 namespace {
3188 class LocalVarRefChecker final
3189     : public ConstStmtVisitor<LocalVarRefChecker, bool> {
3190   Sema &SemaRef;
3191 
3192 public:
3193   bool VisitDeclRefExpr(const DeclRefExpr *E) {
3194     if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3195       if (VD->hasLocalStorage()) {
3196         SemaRef.Diag(E->getBeginLoc(),
3197                      diag::err_omp_local_var_in_threadprivate_init)
3198             << E->getSourceRange();
3199         SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
3200             << VD << VD->getSourceRange();
3201         return true;
3202       }
3203     }
3204     return false;
3205   }
3206   bool VisitStmt(const Stmt *S) {
3207     for (const Stmt *Child : S->children()) {
3208       if (Child && Visit(Child))
3209         return true;
3210     }
3211     return false;
3212   }
3213   explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
3214 };
3215 } // namespace
3216 
3217 OMPThreadPrivateDecl *
3218 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
3219   SmallVector<Expr *, 8> Vars;
3220   for (Expr *RefExpr : VarList) {
3221     auto *DE = cast<DeclRefExpr>(RefExpr);
3222     auto *VD = cast<VarDecl>(DE->getDecl());
3223     SourceLocation ILoc = DE->getExprLoc();
3224 
3225     // Mark variable as used.
3226     VD->setReferenced();
3227     VD->markUsed(Context);
3228 
3229     QualType QType = VD->getType();
3230     if (QType->isDependentType() || QType->isInstantiationDependentType()) {
3231       // It will be analyzed later.
3232       Vars.push_back(DE);
3233       continue;
3234     }
3235 
3236     // OpenMP [2.9.2, Restrictions, C/C++, p.10]
3237     //   A threadprivate variable must not have an incomplete type.
3238     if (RequireCompleteType(ILoc, VD->getType(),
3239                             diag::err_omp_threadprivate_incomplete_type)) {
3240       continue;
3241     }
3242 
3243     // OpenMP [2.9.2, Restrictions, C/C++, p.10]
3244     //   A threadprivate variable must not have a reference type.
3245     if (VD->getType()->isReferenceType()) {
3246       Diag(ILoc, diag::err_omp_ref_type_arg)
3247           << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
3248       bool IsDecl =
3249           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3250       Diag(VD->getLocation(),
3251            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3252           << VD;
3253       continue;
3254     }
3255 
3256     // Check if this is a TLS variable. If TLS is not being supported, produce
3257     // the corresponding diagnostic.
3258     if ((VD->getTLSKind() != VarDecl::TLS_None &&
3259          !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
3260            getLangOpts().OpenMPUseTLS &&
3261            getASTContext().getTargetInfo().isTLSSupported())) ||
3262         (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3263          !VD->isLocalVarDecl())) {
3264       Diag(ILoc, diag::err_omp_var_thread_local)
3265           << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
3266       bool IsDecl =
3267           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3268       Diag(VD->getLocation(),
3269            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3270           << VD;
3271       continue;
3272     }
3273 
3274     // Check if initial value of threadprivate variable reference variable with
3275     // local storage (it is not supported by runtime).
3276     if (const Expr *Init = VD->getAnyInitializer()) {
3277       LocalVarRefChecker Checker(*this);
3278       if (Checker.Visit(Init))
3279         continue;
3280     }
3281 
3282     Vars.push_back(RefExpr);
3283     DSAStack->addDSA(VD, DE, OMPC_threadprivate);
3284     VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3285         Context, SourceRange(Loc, Loc)));
3286     if (ASTMutationListener *ML = Context.getASTMutationListener())
3287       ML->DeclarationMarkedOpenMPThreadPrivate(VD);
3288   }
3289   OMPThreadPrivateDecl *D = nullptr;
3290   if (!Vars.empty()) {
3291     D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
3292                                      Vars);
3293     D->setAccess(AS_public);
3294   }
3295   return D;
3296 }
3297 
3298 static OMPAllocateDeclAttr::AllocatorTypeTy
3299 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
3300   if (!Allocator)
3301     return OMPAllocateDeclAttr::OMPNullMemAlloc;
3302   if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3303       Allocator->isInstantiationDependent() ||
3304       Allocator->containsUnexpandedParameterPack())
3305     return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3306   auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3307   llvm::FoldingSetNodeID AEId;
3308   const Expr *AE = Allocator->IgnoreParenImpCasts();
3309   AE->IgnoreImpCasts()->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
3310   for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
3311     auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
3312     const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
3313     llvm::FoldingSetNodeID DAEId;
3314     DefAllocator->IgnoreImpCasts()->Profile(DAEId, S.getASTContext(),
3315                                             /*Canonical=*/true);
3316     if (AEId == DAEId) {
3317       AllocatorKindRes = AllocatorKind;
3318       break;
3319     }
3320   }
3321   return AllocatorKindRes;
3322 }
3323 
3324 static bool checkPreviousOMPAllocateAttribute(
3325     Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
3326     OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
3327   if (!VD->hasAttr<OMPAllocateDeclAttr>())
3328     return false;
3329   const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
3330   Expr *PrevAllocator = A->getAllocator();
3331   OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3332       getAllocatorKind(S, Stack, PrevAllocator);
3333   bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3334   if (AllocatorsMatch &&
3335       AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3336       Allocator && PrevAllocator) {
3337     const Expr *AE = Allocator->IgnoreParenImpCasts();
3338     const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
3339     llvm::FoldingSetNodeID AEId, PAEId;
3340     AE->Profile(AEId, S.Context, /*Canonical=*/true);
3341     PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
3342     AllocatorsMatch = AEId == PAEId;
3343   }
3344   if (!AllocatorsMatch) {
3345     SmallString<256> AllocatorBuffer;
3346     llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3347     if (Allocator)
3348       Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
3349     SmallString<256> PrevAllocatorBuffer;
3350     llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3351     if (PrevAllocator)
3352       PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
3353                                  S.getPrintingPolicy());
3354 
3355     SourceLocation AllocatorLoc =
3356         Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
3357     SourceRange AllocatorRange =
3358         Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
3359     SourceLocation PrevAllocatorLoc =
3360         PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3361     SourceRange PrevAllocatorRange =
3362         PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3363     S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3364         << (Allocator ? 1 : 0) << AllocatorStream.str()
3365         << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3366         << AllocatorRange;
3367     S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3368         << PrevAllocatorRange;
3369     return true;
3370   }
3371   return false;
3372 }
3373 
3374 static void
3375 applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
3376                           OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3377                           Expr *Allocator, Expr *Alignment, SourceRange SR) {
3378   if (VD->hasAttr<OMPAllocateDeclAttr>())
3379     return;
3380   if (Alignment &&
3381       (Alignment->isTypeDependent() || Alignment->isValueDependent() ||
3382        Alignment->isInstantiationDependent() ||
3383        Alignment->containsUnexpandedParameterPack()))
3384     // Apply later when we have a usable value.
3385     return;
3386   if (Allocator &&
3387       (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3388        Allocator->isInstantiationDependent() ||
3389        Allocator->containsUnexpandedParameterPack()))
3390     return;
3391   auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
3392                                                 Allocator, Alignment, SR);
3393   VD->addAttr(A);
3394   if (ASTMutationListener *ML = S.Context.getASTMutationListener())
3395     ML->DeclarationMarkedOpenMPAllocate(VD, A);
3396 }
3397 
3398 Sema::DeclGroupPtrTy
3399 Sema::ActOnOpenMPAllocateDirective(SourceLocation Loc, ArrayRef<Expr *> VarList,
3400                                    ArrayRef<OMPClause *> Clauses,
3401                                    DeclContext *Owner) {
3402   assert(Clauses.size() <= 2 && "Expected at most two clauses.");
3403   Expr *Alignment = nullptr;
3404   Expr *Allocator = nullptr;
3405   if (Clauses.empty()) {
3406     // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
3407     // allocate directives that appear in a target region must specify an
3408     // allocator clause unless a requires directive with the dynamic_allocators
3409     // clause is present in the same compilation unit.
3410     if (LangOpts.OpenMPIsTargetDevice &&
3411         !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
3412       targetDiag(Loc, diag::err_expected_allocator_clause);
3413   } else {
3414     for (const OMPClause *C : Clauses)
3415       if (const auto *AC = dyn_cast<OMPAllocatorClause>(C))
3416         Allocator = AC->getAllocator();
3417       else if (const auto *AC = dyn_cast<OMPAlignClause>(C))
3418         Alignment = AC->getAlignment();
3419       else
3420         llvm_unreachable("Unexpected clause on allocate directive");
3421   }
3422   OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3423       getAllocatorKind(*this, DSAStack, Allocator);
3424   SmallVector<Expr *, 8> Vars;
3425   for (Expr *RefExpr : VarList) {
3426     auto *DE = cast<DeclRefExpr>(RefExpr);
3427     auto *VD = cast<VarDecl>(DE->getDecl());
3428 
3429     // Check if this is a TLS variable or global register.
3430     if (VD->getTLSKind() != VarDecl::TLS_None ||
3431         VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
3432         (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3433          !VD->isLocalVarDecl()))
3434       continue;
3435 
3436     // If the used several times in the allocate directive, the same allocator
3437     // must be used.
3438     if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD,
3439                                           AllocatorKind, Allocator))
3440       continue;
3441 
3442     // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
3443     // If a list item has a static storage type, the allocator expression in the
3444     // allocator clause must be a constant expression that evaluates to one of
3445     // the predefined memory allocator values.
3446     if (Allocator && VD->hasGlobalStorage()) {
3447       if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3448         Diag(Allocator->getExprLoc(),
3449              diag::err_omp_expected_predefined_allocator)
3450             << Allocator->getSourceRange();
3451         bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
3452                       VarDecl::DeclarationOnly;
3453         Diag(VD->getLocation(),
3454              IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3455             << VD;
3456         continue;
3457       }
3458     }
3459 
3460     Vars.push_back(RefExpr);
3461     applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, Alignment,
3462                               DE->getSourceRange());
3463   }
3464   if (Vars.empty())
3465     return nullptr;
3466   if (!Owner)
3467     Owner = getCurLexicalContext();
3468   auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
3469   D->setAccess(AS_public);
3470   Owner->addDecl(D);
3471   return DeclGroupPtrTy::make(DeclGroupRef(D));
3472 }
3473 
3474 Sema::DeclGroupPtrTy
3475 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
3476                                    ArrayRef<OMPClause *> ClauseList) {
3477   OMPRequiresDecl *D = nullptr;
3478   if (!CurContext->isFileContext()) {
3479     Diag(Loc, diag::err_omp_invalid_scope) << "requires";
3480   } else {
3481     D = CheckOMPRequiresDecl(Loc, ClauseList);
3482     if (D) {
3483       CurContext->addDecl(D);
3484       DSAStack->addRequiresDecl(D);
3485     }
3486   }
3487   return DeclGroupPtrTy::make(DeclGroupRef(D));
3488 }
3489 
3490 void Sema::ActOnOpenMPAssumesDirective(SourceLocation Loc,
3491                                        OpenMPDirectiveKind DKind,
3492                                        ArrayRef<std::string> Assumptions,
3493                                        bool SkippedClauses) {
3494   if (!SkippedClauses && Assumptions.empty())
3495     Diag(Loc, diag::err_omp_no_clause_for_directive)
3496         << llvm::omp::getAllAssumeClauseOptions()
3497         << llvm::omp::getOpenMPDirectiveName(DKind);
3498 
3499   auto *AA = AssumptionAttr::Create(Context, llvm::join(Assumptions, ","), Loc);
3500   if (DKind == llvm::omp::Directive::OMPD_begin_assumes) {
3501     OMPAssumeScoped.push_back(AA);
3502     return;
3503   }
3504 
3505   // Global assumes without assumption clauses are ignored.
3506   if (Assumptions.empty())
3507     return;
3508 
3509   assert(DKind == llvm::omp::Directive::OMPD_assumes &&
3510          "Unexpected omp assumption directive!");
3511   OMPAssumeGlobal.push_back(AA);
3512 
3513   // The OMPAssumeGlobal scope above will take care of new declarations but
3514   // we also want to apply the assumption to existing ones, e.g., to
3515   // declarations in included headers. To this end, we traverse all existing
3516   // declaration contexts and annotate function declarations here.
3517   SmallVector<DeclContext *, 8> DeclContexts;
3518   auto *Ctx = CurContext;
3519   while (Ctx->getLexicalParent())
3520     Ctx = Ctx->getLexicalParent();
3521   DeclContexts.push_back(Ctx);
3522   while (!DeclContexts.empty()) {
3523     DeclContext *DC = DeclContexts.pop_back_val();
3524     for (auto *SubDC : DC->decls()) {
3525       if (SubDC->isInvalidDecl())
3526         continue;
3527       if (auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) {
3528         DeclContexts.push_back(CTD->getTemplatedDecl());
3529         llvm::append_range(DeclContexts, CTD->specializations());
3530         continue;
3531       }
3532       if (auto *DC = dyn_cast<DeclContext>(SubDC))
3533         DeclContexts.push_back(DC);
3534       if (auto *F = dyn_cast<FunctionDecl>(SubDC)) {
3535         F->addAttr(AA);
3536         continue;
3537       }
3538     }
3539   }
3540 }
3541 
3542 void Sema::ActOnOpenMPEndAssumesDirective() {
3543   assert(isInOpenMPAssumeScope() && "Not in OpenMP assumes scope!");
3544   OMPAssumeScoped.pop_back();
3545 }
3546 
3547 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
3548                                             ArrayRef<OMPClause *> ClauseList) {
3549   /// For target specific clauses, the requires directive cannot be
3550   /// specified after the handling of any of the target regions in the
3551   /// current compilation unit.
3552   ArrayRef<SourceLocation> TargetLocations =
3553       DSAStack->getEncounteredTargetLocs();
3554   SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc();
3555   if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) {
3556     for (const OMPClause *CNew : ClauseList) {
3557       // Check if any of the requires clauses affect target regions.
3558       if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3559           isa<OMPUnifiedAddressClause>(CNew) ||
3560           isa<OMPReverseOffloadClause>(CNew) ||
3561           isa<OMPDynamicAllocatorsClause>(CNew)) {
3562         Diag(Loc, diag::err_omp_directive_before_requires)
3563             << "target" << getOpenMPClauseName(CNew->getClauseKind());
3564         for (SourceLocation TargetLoc : TargetLocations) {
3565           Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3566               << "target";
3567         }
3568       } else if (!AtomicLoc.isInvalid() &&
3569                  isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3570         Diag(Loc, diag::err_omp_directive_before_requires)
3571             << "atomic" << getOpenMPClauseName(CNew->getClauseKind());
3572         Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3573             << "atomic";
3574       }
3575     }
3576   }
3577 
3578   if (!DSAStack->hasDuplicateRequiresClause(ClauseList))
3579     return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
3580                                    ClauseList);
3581   return nullptr;
3582 }
3583 
3584 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
3585                               const ValueDecl *D,
3586                               const DSAStackTy::DSAVarData &DVar,
3587                               bool IsLoopIterVar) {
3588   if (DVar.RefExpr) {
3589     SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3590         << getOpenMPClauseName(DVar.CKind);
3591     return;
3592   }
3593   enum {
3594     PDSA_StaticMemberShared,
3595     PDSA_StaticLocalVarShared,
3596     PDSA_LoopIterVarPrivate,
3597     PDSA_LoopIterVarLinear,
3598     PDSA_LoopIterVarLastprivate,
3599     PDSA_ConstVarShared,
3600     PDSA_GlobalVarShared,
3601     PDSA_TaskVarFirstprivate,
3602     PDSA_LocalVarPrivate,
3603     PDSA_Implicit
3604   } Reason = PDSA_Implicit;
3605   bool ReportHint = false;
3606   auto ReportLoc = D->getLocation();
3607   auto *VD = dyn_cast<VarDecl>(D);
3608   if (IsLoopIterVar) {
3609     if (DVar.CKind == OMPC_private)
3610       Reason = PDSA_LoopIterVarPrivate;
3611     else if (DVar.CKind == OMPC_lastprivate)
3612       Reason = PDSA_LoopIterVarLastprivate;
3613     else
3614       Reason = PDSA_LoopIterVarLinear;
3615   } else if (isOpenMPTaskingDirective(DVar.DKind) &&
3616              DVar.CKind == OMPC_firstprivate) {
3617     Reason = PDSA_TaskVarFirstprivate;
3618     ReportLoc = DVar.ImplicitDSALoc;
3619   } else if (VD && VD->isStaticLocal())
3620     Reason = PDSA_StaticLocalVarShared;
3621   else if (VD && VD->isStaticDataMember())
3622     Reason = PDSA_StaticMemberShared;
3623   else if (VD && VD->isFileVarDecl())
3624     Reason = PDSA_GlobalVarShared;
3625   else if (D->getType().isConstant(SemaRef.getASTContext()))
3626     Reason = PDSA_ConstVarShared;
3627   else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
3628     ReportHint = true;
3629     Reason = PDSA_LocalVarPrivate;
3630   }
3631   if (Reason != PDSA_Implicit) {
3632     SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3633         << Reason << ReportHint
3634         << getOpenMPDirectiveName(Stack->getCurrentDirective());
3635   } else if (DVar.ImplicitDSALoc.isValid()) {
3636     SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3637         << getOpenMPClauseName(DVar.CKind);
3638   }
3639 }
3640 
3641 static OpenMPMapClauseKind
3642 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,
3643                              bool IsAggregateOrDeclareTarget) {
3644   OpenMPMapClauseKind Kind = OMPC_MAP_unknown;
3645   switch (M) {
3646   case OMPC_DEFAULTMAP_MODIFIER_alloc:
3647     Kind = OMPC_MAP_alloc;
3648     break;
3649   case OMPC_DEFAULTMAP_MODIFIER_to:
3650     Kind = OMPC_MAP_to;
3651     break;
3652   case OMPC_DEFAULTMAP_MODIFIER_from:
3653     Kind = OMPC_MAP_from;
3654     break;
3655   case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3656     Kind = OMPC_MAP_tofrom;
3657     break;
3658   case OMPC_DEFAULTMAP_MODIFIER_present:
3659     // OpenMP 5.1 [2.21.7.3] defaultmap clause, Description]
3660     // If implicit-behavior is present, each variable referenced in the
3661     // construct in the category specified by variable-category is treated as if
3662     // it had been listed in a map clause with the map-type of alloc and
3663     // map-type-modifier of present.
3664     Kind = OMPC_MAP_alloc;
3665     break;
3666   case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3667   case OMPC_DEFAULTMAP_MODIFIER_last:
3668     llvm_unreachable("Unexpected defaultmap implicit behavior");
3669   case OMPC_DEFAULTMAP_MODIFIER_none:
3670   case OMPC_DEFAULTMAP_MODIFIER_default:
3671   case OMPC_DEFAULTMAP_MODIFIER_unknown:
3672     // IsAggregateOrDeclareTarget could be true if:
3673     // 1. the implicit behavior for aggregate is tofrom
3674     // 2. it's a declare target link
3675     if (IsAggregateOrDeclareTarget) {
3676       Kind = OMPC_MAP_tofrom;
3677       break;
3678     }
3679     llvm_unreachable("Unexpected defaultmap implicit behavior");
3680   }
3681   assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known");
3682   return Kind;
3683 }
3684 
3685 namespace {
3686 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
3687   DSAStackTy *Stack;
3688   Sema &SemaRef;
3689   bool ErrorFound = false;
3690   bool TryCaptureCXXThisMembers = false;
3691   CapturedStmt *CS = nullptr;
3692   const static unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_unknown + 1;
3693   llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
3694   llvm::SmallVector<Expr *, 4> ImplicitPrivate;
3695   llvm::SmallVector<Expr *, 4> ImplicitMap[DefaultmapKindNum][OMPC_MAP_delete];
3696   llvm::SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
3697       ImplicitMapModifier[DefaultmapKindNum];
3698   Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
3699   llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3700 
3701   void VisitSubCaptures(OMPExecutableDirective *S) {
3702     // Check implicitly captured variables.
3703     if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
3704       return;
3705     if (S->getDirectiveKind() == OMPD_atomic ||
3706         S->getDirectiveKind() == OMPD_critical ||
3707         S->getDirectiveKind() == OMPD_section ||
3708         S->getDirectiveKind() == OMPD_master ||
3709         S->getDirectiveKind() == OMPD_masked ||
3710         S->getDirectiveKind() == OMPD_scope ||
3711         isOpenMPLoopTransformationDirective(S->getDirectiveKind())) {
3712       Visit(S->getAssociatedStmt());
3713       return;
3714     }
3715     visitSubCaptures(S->getInnermostCapturedStmt());
3716     // Try to capture inner this->member references to generate correct mappings
3717     // and diagnostics.
3718     if (TryCaptureCXXThisMembers ||
3719         (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3720          llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3721                       [](const CapturedStmt::Capture &C) {
3722                         return C.capturesThis();
3723                       }))) {
3724       bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3725       TryCaptureCXXThisMembers = true;
3726       Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3727       TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3728     }
3729     // In tasks firstprivates are not captured anymore, need to analyze them
3730     // explicitly.
3731     if (isOpenMPTaskingDirective(S->getDirectiveKind()) &&
3732         !isOpenMPTaskLoopDirective(S->getDirectiveKind())) {
3733       for (OMPClause *C : S->clauses())
3734         if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) {
3735           for (Expr *Ref : FC->varlists())
3736             Visit(Ref);
3737         }
3738     }
3739   }
3740 
3741 public:
3742   void VisitDeclRefExpr(DeclRefExpr *E) {
3743     if (TryCaptureCXXThisMembers || E->isTypeDependent() ||
3744         E->isValueDependent() || E->containsUnexpandedParameterPack() ||
3745         E->isInstantiationDependent())
3746       return;
3747     if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3748       // Check the datasharing rules for the expressions in the clauses.
3749       if (!CS || (isa<OMPCapturedExprDecl>(VD) && !CS->capturesVariable(VD) &&
3750                   !Stack->getTopDSA(VD, /*FromParent=*/false).RefExpr &&
3751                   !Stack->isImplicitDefaultFirstprivateFD(VD))) {
3752         if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3753           if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3754             Visit(CED->getInit());
3755             return;
3756           }
3757       } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
3758         // Do not analyze internal variables and do not enclose them into
3759         // implicit clauses.
3760         if (!Stack->isImplicitDefaultFirstprivateFD(VD))
3761           return;
3762       VD = VD->getCanonicalDecl();
3763       // Skip internally declared variables.
3764       if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) &&
3765           !Stack->isImplicitDefaultFirstprivateFD(VD) &&
3766           !Stack->isImplicitTaskFirstprivate(VD))
3767         return;
3768       // Skip allocators in uses_allocators clauses.
3769       if (Stack->isUsesAllocatorsDecl(VD))
3770         return;
3771 
3772       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
3773       // Check if the variable has explicit DSA set and stop analysis if it so.
3774       if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3775         return;
3776 
3777       // Skip internally declared static variables.
3778       std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3779           OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3780       if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
3781           (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
3782            !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3783           !Stack->isImplicitDefaultFirstprivateFD(VD) &&
3784           !Stack->isImplicitTaskFirstprivate(VD))
3785         return;
3786 
3787       SourceLocation ELoc = E->getExprLoc();
3788       OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3789       // The default(none) clause requires that each variable that is referenced
3790       // in the construct, and does not have a predetermined data-sharing
3791       // attribute, must have its data-sharing attribute explicitly determined
3792       // by being listed in a data-sharing attribute clause.
3793       if (DVar.CKind == OMPC_unknown &&
3794           (Stack->getDefaultDSA() == DSA_none ||
3795            Stack->getDefaultDSA() == DSA_private ||
3796            Stack->getDefaultDSA() == DSA_firstprivate) &&
3797           isImplicitOrExplicitTaskingRegion(DKind) &&
3798           VarsWithInheritedDSA.count(VD) == 0) {
3799         bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3800         if (!InheritedDSA && (Stack->getDefaultDSA() == DSA_firstprivate ||
3801                               Stack->getDefaultDSA() == DSA_private)) {
3802           DSAStackTy::DSAVarData DVar =
3803               Stack->getImplicitDSA(VD, /*FromParent=*/false);
3804           InheritedDSA = DVar.CKind == OMPC_unknown;
3805         }
3806         if (InheritedDSA)
3807           VarsWithInheritedDSA[VD] = E;
3808         if (Stack->getDefaultDSA() == DSA_none)
3809           return;
3810       }
3811 
3812       // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description]
3813       // If implicit-behavior is none, each variable referenced in the
3814       // construct that does not have a predetermined data-sharing attribute
3815       // and does not appear in a to or link clause on a declare target
3816       // directive must be listed in a data-mapping attribute clause, a
3817       // data-sharing attribute clause (including a data-sharing attribute
3818       // clause on a combined construct where target. is one of the
3819       // constituent constructs), or an is_device_ptr clause.
3820       OpenMPDefaultmapClauseKind ClauseKind =
3821           getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD);
3822       if (SemaRef.getLangOpts().OpenMP >= 50) {
3823         bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3824                               OMPC_DEFAULTMAP_MODIFIER_none;
3825         if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3826             VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3827           // Only check for data-mapping attribute and is_device_ptr here
3828           // since we have already make sure that the declaration does not
3829           // have a data-sharing attribute above
3830           if (!Stack->checkMappableExprComponentListsForDecl(
3831                   VD, /*CurrentRegionOnly=*/true,
3832                   [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef
3833                            MapExprComponents,
3834                        OpenMPClauseKind) {
3835                     auto MI = MapExprComponents.rbegin();
3836                     auto ME = MapExprComponents.rend();
3837                     return MI != ME && MI->getAssociatedDeclaration() == VD;
3838                   })) {
3839             VarsWithInheritedDSA[VD] = E;
3840             return;
3841           }
3842         }
3843       }
3844       if (SemaRef.getLangOpts().OpenMP > 50) {
3845         bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) ==
3846                                  OMPC_DEFAULTMAP_MODIFIER_present;
3847         if (IsModifierPresent) {
3848           if (!llvm::is_contained(ImplicitMapModifier[ClauseKind],
3849                                   OMPC_MAP_MODIFIER_present)) {
3850             ImplicitMapModifier[ClauseKind].push_back(
3851                 OMPC_MAP_MODIFIER_present);
3852           }
3853         }
3854       }
3855 
3856       if (isOpenMPTargetExecutionDirective(DKind) &&
3857           !Stack->isLoopControlVariable(VD).first) {
3858         if (!Stack->checkMappableExprComponentListsForDecl(
3859                 VD, /*CurrentRegionOnly=*/true,
3860                 [this](OMPClauseMappableExprCommon::MappableExprComponentListRef
3861                            StackComponents,
3862                        OpenMPClauseKind) {
3863                   if (SemaRef.LangOpts.OpenMP >= 50)
3864                     return !StackComponents.empty();
3865                   // Variable is used if it has been marked as an array, array
3866                   // section, array shaping or the variable iself.
3867                   return StackComponents.size() == 1 ||
3868                          llvm::all_of(
3869                              llvm::drop_begin(llvm::reverse(StackComponents)),
3870                              [](const OMPClauseMappableExprCommon::
3871                                     MappableComponent &MC) {
3872                                return MC.getAssociatedDeclaration() ==
3873                                           nullptr &&
3874                                       (isa<OMPArraySectionExpr>(
3875                                            MC.getAssociatedExpression()) ||
3876                                        isa<OMPArrayShapingExpr>(
3877                                            MC.getAssociatedExpression()) ||
3878                                        isa<ArraySubscriptExpr>(
3879                                            MC.getAssociatedExpression()));
3880                              });
3881                 })) {
3882           bool IsFirstprivate = false;
3883           // By default lambdas are captured as firstprivates.
3884           if (const auto *RD =
3885                   VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
3886             IsFirstprivate = RD->isLambda();
3887           IsFirstprivate =
3888               IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3889           if (IsFirstprivate) {
3890             ImplicitFirstprivate.emplace_back(E);
3891           } else {
3892             OpenMPDefaultmapClauseModifier M =
3893                 Stack->getDefaultmapModifier(ClauseKind);
3894             OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3895                 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3896             ImplicitMap[ClauseKind][Kind].emplace_back(E);
3897           }
3898           return;
3899         }
3900       }
3901 
3902       // OpenMP [2.9.3.6, Restrictions, p.2]
3903       //  A list item that appears in a reduction clause of the innermost
3904       //  enclosing worksharing or parallel construct may not be accessed in an
3905       //  explicit task.
3906       DVar = Stack->hasInnermostDSA(
3907           VD,
3908           [](OpenMPClauseKind C, bool AppliedToPointee) {
3909             return C == OMPC_reduction && !AppliedToPointee;
3910           },
3911           [](OpenMPDirectiveKind K) {
3912             return isOpenMPParallelDirective(K) ||
3913                    isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3914           },
3915           /*FromParent=*/true);
3916       if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3917         ErrorFound = true;
3918         SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3919         reportOriginalDsa(SemaRef, Stack, VD, DVar);
3920         return;
3921       }
3922 
3923       // Define implicit data-sharing attributes for task.
3924       DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
3925       if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) ||
3926            (((Stack->getDefaultDSA() == DSA_firstprivate &&
3927               DVar.CKind == OMPC_firstprivate) ||
3928              (Stack->getDefaultDSA() == DSA_private &&
3929               DVar.CKind == OMPC_private)) &&
3930             !DVar.RefExpr)) &&
3931           !Stack->isLoopControlVariable(VD).first) {
3932         if (Stack->getDefaultDSA() == DSA_private)
3933           ImplicitPrivate.push_back(E);
3934         else
3935           ImplicitFirstprivate.push_back(E);
3936         return;
3937       }
3938 
3939       // Store implicitly used globals with declare target link for parent
3940       // target.
3941       if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
3942           *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3943         Stack->addToParentTargetRegionLinkGlobals(E);
3944         return;
3945       }
3946     }
3947   }
3948   void VisitMemberExpr(MemberExpr *E) {
3949     if (E->isTypeDependent() || E->isValueDependent() ||
3950         E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
3951       return;
3952     auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
3953     OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3954     if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) {
3955       if (!FD)
3956         return;
3957       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
3958       // Check if the variable has explicit DSA set and stop analysis if it
3959       // so.
3960       if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3961         return;
3962 
3963       if (isOpenMPTargetExecutionDirective(DKind) &&
3964           !Stack->isLoopControlVariable(FD).first &&
3965           !Stack->checkMappableExprComponentListsForDecl(
3966               FD, /*CurrentRegionOnly=*/true,
3967               [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3968                      StackComponents,
3969                  OpenMPClauseKind) {
3970                 return isa<CXXThisExpr>(
3971                     cast<MemberExpr>(
3972                         StackComponents.back().getAssociatedExpression())
3973                         ->getBase()
3974                         ->IgnoreParens());
3975               })) {
3976         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
3977         //  A bit-field cannot appear in a map clause.
3978         //
3979         if (FD->isBitField())
3980           return;
3981 
3982         // Check to see if the member expression is referencing a class that
3983         // has already been explicitly mapped
3984         if (Stack->isClassPreviouslyMapped(TE->getType()))
3985           return;
3986 
3987         OpenMPDefaultmapClauseModifier Modifier =
3988             Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3989         OpenMPDefaultmapClauseKind ClauseKind =
3990             getVariableCategoryFromDecl(SemaRef.getLangOpts(), FD);
3991         OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3992             Modifier, /*IsAggregateOrDeclareTarget*/ true);
3993         ImplicitMap[ClauseKind][Kind].emplace_back(E);
3994         return;
3995       }
3996 
3997       SourceLocation ELoc = E->getExprLoc();
3998       // OpenMP [2.9.3.6, Restrictions, p.2]
3999       //  A list item that appears in a reduction clause of the innermost
4000       //  enclosing worksharing or parallel construct may not be accessed in
4001       //  an  explicit task.
4002       DVar = Stack->hasInnermostDSA(
4003           FD,
4004           [](OpenMPClauseKind C, bool AppliedToPointee) {
4005             return C == OMPC_reduction && !AppliedToPointee;
4006           },
4007           [](OpenMPDirectiveKind K) {
4008             return isOpenMPParallelDirective(K) ||
4009                    isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
4010           },
4011           /*FromParent=*/true);
4012       if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
4013         ErrorFound = true;
4014         SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
4015         reportOriginalDsa(SemaRef, Stack, FD, DVar);
4016         return;
4017       }
4018 
4019       // Define implicit data-sharing attributes for task.
4020       DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
4021       if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
4022           !Stack->isLoopControlVariable(FD).first) {
4023         // Check if there is a captured expression for the current field in the
4024         // region. Do not mark it as firstprivate unless there is no captured
4025         // expression.
4026         // TODO: try to make it firstprivate.
4027         if (DVar.CKind != OMPC_unknown)
4028           ImplicitFirstprivate.push_back(E);
4029       }
4030       return;
4031     }
4032     if (isOpenMPTargetExecutionDirective(DKind)) {
4033       OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
4034       if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
4035                                         Stack->getCurrentDirective(),
4036                                         /*NoDiagnose=*/true))
4037         return;
4038       const auto *VD = cast<ValueDecl>(
4039           CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
4040       if (!Stack->checkMappableExprComponentListsForDecl(
4041               VD, /*CurrentRegionOnly=*/true,
4042               [&CurComponents](
4043                   OMPClauseMappableExprCommon::MappableExprComponentListRef
4044                       StackComponents,
4045                   OpenMPClauseKind) {
4046                 auto CCI = CurComponents.rbegin();
4047                 auto CCE = CurComponents.rend();
4048                 for (const auto &SC : llvm::reverse(StackComponents)) {
4049                   // Do both expressions have the same kind?
4050                   if (CCI->getAssociatedExpression()->getStmtClass() !=
4051                       SC.getAssociatedExpression()->getStmtClass())
4052                     if (!((isa<OMPArraySectionExpr>(
4053                                SC.getAssociatedExpression()) ||
4054                            isa<OMPArrayShapingExpr>(
4055                                SC.getAssociatedExpression())) &&
4056                           isa<ArraySubscriptExpr>(
4057                               CCI->getAssociatedExpression())))
4058                       return false;
4059 
4060                   const Decl *CCD = CCI->getAssociatedDeclaration();
4061                   const Decl *SCD = SC.getAssociatedDeclaration();
4062                   CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
4063                   SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
4064                   if (SCD != CCD)
4065                     return false;
4066                   std::advance(CCI, 1);
4067                   if (CCI == CCE)
4068                     break;
4069                 }
4070                 return true;
4071               })) {
4072         Visit(E->getBase());
4073       }
4074     } else if (!TryCaptureCXXThisMembers) {
4075       Visit(E->getBase());
4076     }
4077   }
4078   void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
4079     for (OMPClause *C : S->clauses()) {
4080       // Skip analysis of arguments of private clauses for task|target
4081       // directives.
4082       if (isa_and_nonnull<OMPPrivateClause>(C))
4083         continue;
4084       // Skip analysis of arguments of implicitly defined firstprivate clause
4085       // for task|target directives.
4086       // Skip analysis of arguments of implicitly defined map clause for target
4087       // directives.
4088       if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
4089                  C->isImplicit() &&
4090                  !isOpenMPTaskingDirective(Stack->getCurrentDirective()))) {
4091         for (Stmt *CC : C->children()) {
4092           if (CC)
4093             Visit(CC);
4094         }
4095       }
4096     }
4097     // Check implicitly captured variables.
4098     VisitSubCaptures(S);
4099   }
4100 
4101   void VisitOMPLoopTransformationDirective(OMPLoopTransformationDirective *S) {
4102     // Loop transformation directives do not introduce data sharing
4103     VisitStmt(S);
4104   }
4105 
4106   void VisitCallExpr(CallExpr *S) {
4107     for (Stmt *C : S->arguments()) {
4108       if (C) {
4109         // Check implicitly captured variables in the task-based directives to
4110         // check if they must be firstprivatized.
4111         Visit(C);
4112       }
4113     }
4114     if (Expr *Callee = S->getCallee()) {
4115       auto *CI = Callee->IgnoreParenImpCasts();
4116       if (auto *CE = dyn_cast<MemberExpr>(CI))
4117         Visit(CE->getBase());
4118       else if (auto *CE = dyn_cast<DeclRefExpr>(CI))
4119         Visit(CE);
4120     }
4121   }
4122   void VisitStmt(Stmt *S) {
4123     for (Stmt *C : S->children()) {
4124       if (C) {
4125         // Check implicitly captured variables in the task-based directives to
4126         // check if they must be firstprivatized.
4127         Visit(C);
4128       }
4129     }
4130   }
4131 
4132   void visitSubCaptures(CapturedStmt *S) {
4133     for (const CapturedStmt::Capture &Cap : S->captures()) {
4134       if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
4135         continue;
4136       VarDecl *VD = Cap.getCapturedVar();
4137       // Do not try to map the variable if it or its sub-component was mapped
4138       // already.
4139       if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
4140           Stack->checkMappableExprComponentListsForDecl(
4141               VD, /*CurrentRegionOnly=*/true,
4142               [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
4143                  OpenMPClauseKind) { return true; }))
4144         continue;
4145       DeclRefExpr *DRE = buildDeclRefExpr(
4146           SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
4147           Cap.getLocation(), /*RefersToCapture=*/true);
4148       Visit(DRE);
4149     }
4150   }
4151   bool isErrorFound() const { return ErrorFound; }
4152   ArrayRef<Expr *> getImplicitFirstprivate() const {
4153     return ImplicitFirstprivate;
4154   }
4155   ArrayRef<Expr *> getImplicitPrivate() const { return ImplicitPrivate; }
4156   ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind DK,
4157                                   OpenMPMapClauseKind MK) const {
4158     return ImplicitMap[DK][MK];
4159   }
4160   ArrayRef<OpenMPMapModifierKind>
4161   getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const {
4162     return ImplicitMapModifier[Kind];
4163   }
4164   const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
4165     return VarsWithInheritedDSA;
4166   }
4167 
4168   DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
4169       : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
4170     // Process declare target link variables for the target directives.
4171     if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
4172       for (DeclRefExpr *E : Stack->getLinkGlobals())
4173         Visit(E);
4174     }
4175   }
4176 };
4177 } // namespace
4178 
4179 static void handleDeclareVariantConstructTrait(DSAStackTy *Stack,
4180                                                OpenMPDirectiveKind DKind,
4181                                                bool ScopeEntry) {
4182   SmallVector<llvm::omp::TraitProperty, 8> Traits;
4183   if (isOpenMPTargetExecutionDirective(DKind))
4184     Traits.emplace_back(llvm::omp::TraitProperty::construct_target_target);
4185   if (isOpenMPTeamsDirective(DKind))
4186     Traits.emplace_back(llvm::omp::TraitProperty::construct_teams_teams);
4187   if (isOpenMPParallelDirective(DKind))
4188     Traits.emplace_back(llvm::omp::TraitProperty::construct_parallel_parallel);
4189   if (isOpenMPWorksharingDirective(DKind))
4190     Traits.emplace_back(llvm::omp::TraitProperty::construct_for_for);
4191   if (isOpenMPSimdDirective(DKind))
4192     Traits.emplace_back(llvm::omp::TraitProperty::construct_simd_simd);
4193   Stack->handleConstructTrait(Traits, ScopeEntry);
4194 }
4195 
4196 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
4197   switch (DKind) {
4198   case OMPD_parallel:
4199   case OMPD_parallel_for:
4200   case OMPD_parallel_for_simd:
4201   case OMPD_parallel_sections:
4202   case OMPD_parallel_master:
4203   case OMPD_parallel_masked:
4204   case OMPD_parallel_loop:
4205   case OMPD_teams:
4206   case OMPD_teams_distribute:
4207   case OMPD_teams_distribute_simd: {
4208     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4209     QualType KmpInt32PtrTy =
4210         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4211     Sema::CapturedParamNameType Params[] = {
4212         std::make_pair(".global_tid.", KmpInt32PtrTy),
4213         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4214         std::make_pair(StringRef(), QualType()) // __context with shared vars
4215     };
4216     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4217                              Params);
4218     break;
4219   }
4220   case OMPD_target_teams:
4221   case OMPD_target_parallel:
4222   case OMPD_target_parallel_for:
4223   case OMPD_target_parallel_for_simd:
4224   case OMPD_target_parallel_loop:
4225   case OMPD_target_teams_distribute:
4226   case OMPD_target_teams_distribute_simd: {
4227     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4228     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4229     QualType KmpInt32PtrTy =
4230         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4231     QualType Args[] = {VoidPtrTy};
4232     FunctionProtoType::ExtProtoInfo EPI;
4233     EPI.Variadic = true;
4234     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4235     Sema::CapturedParamNameType Params[] = {
4236         std::make_pair(".global_tid.", KmpInt32Ty),
4237         std::make_pair(".part_id.", KmpInt32PtrTy),
4238         std::make_pair(".privates.", VoidPtrTy),
4239         std::make_pair(
4240             ".copy_fn.",
4241             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4242         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4243         std::make_pair(StringRef(), QualType()) // __context with shared vars
4244     };
4245     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4246                              Params, /*OpenMPCaptureLevel=*/0);
4247     // Mark this captured region as inlined, because we don't use outlined
4248     // function directly.
4249     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4250         AlwaysInlineAttr::CreateImplicit(
4251             Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4252     SmallVector<Sema::CapturedParamNameType, 2> ParamsTarget;
4253     if (getLangOpts().OpenMPIsTargetDevice)
4254       ParamsTarget.push_back(std::make_pair(StringRef("dyn_ptr"), VoidPtrTy));
4255     ParamsTarget.push_back(
4256         std::make_pair(StringRef(), QualType())); // __context with shared vars;
4257     // Start a captured region for 'target' with no implicit parameters.
4258     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4259                              ParamsTarget,
4260                              /*OpenMPCaptureLevel=*/1);
4261     Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
4262         std::make_pair(".global_tid.", KmpInt32PtrTy),
4263         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4264         std::make_pair(StringRef(), QualType()) // __context with shared vars
4265     };
4266     // Start a captured region for 'teams' or 'parallel'.  Both regions have
4267     // the same implicit parameters.
4268     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4269                              ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
4270     break;
4271   }
4272   case OMPD_target:
4273   case OMPD_target_simd: {
4274     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4275     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4276     QualType KmpInt32PtrTy =
4277         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4278     QualType Args[] = {VoidPtrTy};
4279     FunctionProtoType::ExtProtoInfo EPI;
4280     EPI.Variadic = true;
4281     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4282     Sema::CapturedParamNameType Params[] = {
4283         std::make_pair(".global_tid.", KmpInt32Ty),
4284         std::make_pair(".part_id.", KmpInt32PtrTy),
4285         std::make_pair(".privates.", VoidPtrTy),
4286         std::make_pair(
4287             ".copy_fn.",
4288             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4289         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4290         std::make_pair(StringRef(), QualType()) // __context with shared vars
4291     };
4292     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4293                              Params, /*OpenMPCaptureLevel=*/0);
4294     // Mark this captured region as inlined, because we don't use outlined
4295     // function directly.
4296     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4297         AlwaysInlineAttr::CreateImplicit(
4298             Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4299     SmallVector<Sema::CapturedParamNameType, 2> ParamsTarget;
4300     if (getLangOpts().OpenMPIsTargetDevice)
4301       ParamsTarget.push_back(std::make_pair(StringRef("dyn_ptr"), VoidPtrTy));
4302     ParamsTarget.push_back(
4303         std::make_pair(StringRef(), QualType())); // __context with shared vars;
4304     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4305                              ParamsTarget,
4306                              /*OpenMPCaptureLevel=*/1);
4307     break;
4308   }
4309   case OMPD_atomic:
4310   case OMPD_critical:
4311   case OMPD_section:
4312   case OMPD_master:
4313   case OMPD_masked:
4314   case OMPD_tile:
4315   case OMPD_unroll:
4316     break;
4317   case OMPD_loop:
4318     // TODO: 'loop' may require additional parameters depending on the binding.
4319     // Treat similar to OMPD_simd/OMPD_for for now.
4320   case OMPD_simd:
4321   case OMPD_for:
4322   case OMPD_for_simd:
4323   case OMPD_sections:
4324   case OMPD_single:
4325   case OMPD_taskgroup:
4326   case OMPD_distribute:
4327   case OMPD_distribute_simd:
4328   case OMPD_ordered:
4329   case OMPD_scope:
4330   case OMPD_target_data:
4331   case OMPD_dispatch: {
4332     Sema::CapturedParamNameType Params[] = {
4333         std::make_pair(StringRef(), QualType()) // __context with shared vars
4334     };
4335     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4336                              Params);
4337     break;
4338   }
4339   case OMPD_task: {
4340     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4341     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4342     QualType KmpInt32PtrTy =
4343         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4344     QualType Args[] = {VoidPtrTy};
4345     FunctionProtoType::ExtProtoInfo EPI;
4346     EPI.Variadic = true;
4347     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4348     Sema::CapturedParamNameType Params[] = {
4349         std::make_pair(".global_tid.", KmpInt32Ty),
4350         std::make_pair(".part_id.", KmpInt32PtrTy),
4351         std::make_pair(".privates.", VoidPtrTy),
4352         std::make_pair(
4353             ".copy_fn.",
4354             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4355         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4356         std::make_pair(StringRef(), QualType()) // __context with shared vars
4357     };
4358     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4359                              Params);
4360     // Mark this captured region as inlined, because we don't use outlined
4361     // function directly.
4362     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4363         AlwaysInlineAttr::CreateImplicit(
4364             Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4365     break;
4366   }
4367   case OMPD_taskloop:
4368   case OMPD_taskloop_simd:
4369   case OMPD_master_taskloop:
4370   case OMPD_masked_taskloop:
4371   case OMPD_masked_taskloop_simd:
4372   case OMPD_master_taskloop_simd: {
4373     QualType KmpInt32Ty =
4374         Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4375             .withConst();
4376     QualType KmpUInt64Ty =
4377         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4378             .withConst();
4379     QualType KmpInt64Ty =
4380         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4381             .withConst();
4382     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4383     QualType KmpInt32PtrTy =
4384         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4385     QualType Args[] = {VoidPtrTy};
4386     FunctionProtoType::ExtProtoInfo EPI;
4387     EPI.Variadic = true;
4388     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4389     Sema::CapturedParamNameType Params[] = {
4390         std::make_pair(".global_tid.", KmpInt32Ty),
4391         std::make_pair(".part_id.", KmpInt32PtrTy),
4392         std::make_pair(".privates.", VoidPtrTy),
4393         std::make_pair(
4394             ".copy_fn.",
4395             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4396         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4397         std::make_pair(".lb.", KmpUInt64Ty),
4398         std::make_pair(".ub.", KmpUInt64Ty),
4399         std::make_pair(".st.", KmpInt64Ty),
4400         std::make_pair(".liter.", KmpInt32Ty),
4401         std::make_pair(".reductions.", VoidPtrTy),
4402         std::make_pair(StringRef(), QualType()) // __context with shared vars
4403     };
4404     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4405                              Params);
4406     // Mark this captured region as inlined, because we don't use outlined
4407     // function directly.
4408     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4409         AlwaysInlineAttr::CreateImplicit(
4410             Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4411     break;
4412   }
4413   case OMPD_parallel_masked_taskloop:
4414   case OMPD_parallel_masked_taskloop_simd:
4415   case OMPD_parallel_master_taskloop:
4416   case OMPD_parallel_master_taskloop_simd: {
4417     QualType KmpInt32Ty =
4418         Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4419             .withConst();
4420     QualType KmpUInt64Ty =
4421         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4422             .withConst();
4423     QualType KmpInt64Ty =
4424         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4425             .withConst();
4426     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4427     QualType KmpInt32PtrTy =
4428         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4429     Sema::CapturedParamNameType ParamsParallel[] = {
4430         std::make_pair(".global_tid.", KmpInt32PtrTy),
4431         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4432         std::make_pair(StringRef(), QualType()) // __context with shared vars
4433     };
4434     // Start a captured region for 'parallel'.
4435     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4436                              ParamsParallel, /*OpenMPCaptureLevel=*/0);
4437     QualType Args[] = {VoidPtrTy};
4438     FunctionProtoType::ExtProtoInfo EPI;
4439     EPI.Variadic = true;
4440     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4441     Sema::CapturedParamNameType Params[] = {
4442         std::make_pair(".global_tid.", KmpInt32Ty),
4443         std::make_pair(".part_id.", KmpInt32PtrTy),
4444         std::make_pair(".privates.", VoidPtrTy),
4445         std::make_pair(
4446             ".copy_fn.",
4447             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4448         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4449         std::make_pair(".lb.", KmpUInt64Ty),
4450         std::make_pair(".ub.", KmpUInt64Ty),
4451         std::make_pair(".st.", KmpInt64Ty),
4452         std::make_pair(".liter.", KmpInt32Ty),
4453         std::make_pair(".reductions.", VoidPtrTy),
4454         std::make_pair(StringRef(), QualType()) // __context with shared vars
4455     };
4456     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4457                              Params, /*OpenMPCaptureLevel=*/1);
4458     // Mark this captured region as inlined, because we don't use outlined
4459     // function directly.
4460     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4461         AlwaysInlineAttr::CreateImplicit(
4462             Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4463     break;
4464   }
4465   case OMPD_distribute_parallel_for_simd:
4466   case OMPD_distribute_parallel_for: {
4467     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4468     QualType KmpInt32PtrTy =
4469         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4470     Sema::CapturedParamNameType Params[] = {
4471         std::make_pair(".global_tid.", KmpInt32PtrTy),
4472         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4473         std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4474         std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4475         std::make_pair(StringRef(), QualType()) // __context with shared vars
4476     };
4477     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4478                              Params);
4479     break;
4480   }
4481   case OMPD_target_teams_loop:
4482   case OMPD_target_teams_distribute_parallel_for:
4483   case OMPD_target_teams_distribute_parallel_for_simd: {
4484     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4485     QualType KmpInt32PtrTy =
4486         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4487     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4488 
4489     QualType Args[] = {VoidPtrTy};
4490     FunctionProtoType::ExtProtoInfo EPI;
4491     EPI.Variadic = true;
4492     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4493     Sema::CapturedParamNameType Params[] = {
4494         std::make_pair(".global_tid.", KmpInt32Ty),
4495         std::make_pair(".part_id.", KmpInt32PtrTy),
4496         std::make_pair(".privates.", VoidPtrTy),
4497         std::make_pair(
4498             ".copy_fn.",
4499             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4500         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4501         std::make_pair(StringRef(), QualType()) // __context with shared vars
4502     };
4503     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4504                              Params, /*OpenMPCaptureLevel=*/0);
4505     // Mark this captured region as inlined, because we don't use outlined
4506     // function directly.
4507     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4508         AlwaysInlineAttr::CreateImplicit(
4509             Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4510     SmallVector<Sema::CapturedParamNameType, 2> ParamsTarget;
4511     if (getLangOpts().OpenMPIsTargetDevice)
4512       ParamsTarget.push_back(std::make_pair(StringRef("dyn_ptr"), VoidPtrTy));
4513     ParamsTarget.push_back(
4514         std::make_pair(StringRef(), QualType())); // __context with shared vars;
4515     // Start a captured region for 'target' with no implicit parameters.
4516     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4517                              ParamsTarget, /*OpenMPCaptureLevel=*/1);
4518 
4519     Sema::CapturedParamNameType ParamsTeams[] = {
4520         std::make_pair(".global_tid.", KmpInt32PtrTy),
4521         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4522         std::make_pair(StringRef(), QualType()) // __context with shared vars
4523     };
4524     // Start a captured region for 'target' with no implicit parameters.
4525     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4526                              ParamsTeams, /*OpenMPCaptureLevel=*/2);
4527 
4528     Sema::CapturedParamNameType ParamsParallel[] = {
4529         std::make_pair(".global_tid.", KmpInt32PtrTy),
4530         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4531         std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4532         std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4533         std::make_pair(StringRef(), QualType()) // __context with shared vars
4534     };
4535     // Start a captured region for 'teams' or 'parallel'.  Both regions have
4536     // the same implicit parameters.
4537     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4538                              ParamsParallel, /*OpenMPCaptureLevel=*/3);
4539     break;
4540   }
4541 
4542   case OMPD_teams_loop:
4543   case OMPD_teams_distribute_parallel_for:
4544   case OMPD_teams_distribute_parallel_for_simd: {
4545     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4546     QualType KmpInt32PtrTy =
4547         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4548 
4549     Sema::CapturedParamNameType ParamsTeams[] = {
4550         std::make_pair(".global_tid.", KmpInt32PtrTy),
4551         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4552         std::make_pair(StringRef(), QualType()) // __context with shared vars
4553     };
4554     // Start a captured region for 'target' with no implicit parameters.
4555     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4556                              ParamsTeams, /*OpenMPCaptureLevel=*/0);
4557 
4558     Sema::CapturedParamNameType ParamsParallel[] = {
4559         std::make_pair(".global_tid.", KmpInt32PtrTy),
4560         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4561         std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4562         std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4563         std::make_pair(StringRef(), QualType()) // __context with shared vars
4564     };
4565     // Start a captured region for 'teams' or 'parallel'.  Both regions have
4566     // the same implicit parameters.
4567     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4568                              ParamsParallel, /*OpenMPCaptureLevel=*/1);
4569     break;
4570   }
4571   case OMPD_target_update:
4572   case OMPD_target_enter_data:
4573   case OMPD_target_exit_data: {
4574     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4575     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4576     QualType KmpInt32PtrTy =
4577         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4578     QualType Args[] = {VoidPtrTy};
4579     FunctionProtoType::ExtProtoInfo EPI;
4580     EPI.Variadic = true;
4581     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4582     Sema::CapturedParamNameType Params[] = {
4583         std::make_pair(".global_tid.", KmpInt32Ty),
4584         std::make_pair(".part_id.", KmpInt32PtrTy),
4585         std::make_pair(".privates.", VoidPtrTy),
4586         std::make_pair(
4587             ".copy_fn.",
4588             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4589         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4590         std::make_pair(StringRef(), QualType()) // __context with shared vars
4591     };
4592     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4593                              Params);
4594     // Mark this captured region as inlined, because we don't use outlined
4595     // function directly.
4596     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4597         AlwaysInlineAttr::CreateImplicit(
4598             Context, {}, AlwaysInlineAttr::Keyword_forceinline));
4599     break;
4600   }
4601   case OMPD_threadprivate:
4602   case OMPD_allocate:
4603   case OMPD_taskyield:
4604   case OMPD_error:
4605   case OMPD_barrier:
4606   case OMPD_taskwait:
4607   case OMPD_cancellation_point:
4608   case OMPD_cancel:
4609   case OMPD_flush:
4610   case OMPD_depobj:
4611   case OMPD_scan:
4612   case OMPD_declare_reduction:
4613   case OMPD_declare_mapper:
4614   case OMPD_declare_simd:
4615   case OMPD_declare_target:
4616   case OMPD_end_declare_target:
4617   case OMPD_requires:
4618   case OMPD_declare_variant:
4619   case OMPD_begin_declare_variant:
4620   case OMPD_end_declare_variant:
4621   case OMPD_metadirective:
4622     llvm_unreachable("OpenMP Directive is not allowed");
4623   case OMPD_unknown:
4624   default:
4625     llvm_unreachable("Unknown OpenMP directive");
4626   }
4627   DSAStack->setContext(CurContext);
4628   handleDeclareVariantConstructTrait(DSAStack, DKind, /* ScopeEntry */ true);
4629 }
4630 
4631 int Sema::getNumberOfConstructScopes(unsigned Level) const {
4632   return getOpenMPCaptureLevels(DSAStack->getDirective(Level));
4633 }
4634 
4635 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
4636   SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4637   getOpenMPCaptureRegions(CaptureRegions, DKind);
4638   return CaptureRegions.size();
4639 }
4640 
4641 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
4642                                              Expr *CaptureExpr, bool WithInit,
4643                                              DeclContext *CurContext,
4644                                              bool AsExpression) {
4645   assert(CaptureExpr);
4646   ASTContext &C = S.getASTContext();
4647   Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
4648   QualType Ty = Init->getType();
4649   if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
4650     if (S.getLangOpts().CPlusPlus) {
4651       Ty = C.getLValueReferenceType(Ty);
4652     } else {
4653       Ty = C.getPointerType(Ty);
4654       ExprResult Res =
4655           S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
4656       if (!Res.isUsable())
4657         return nullptr;
4658       Init = Res.get();
4659     }
4660     WithInit = true;
4661   }
4662   auto *CED = OMPCapturedExprDecl::Create(C, CurContext, Id, Ty,
4663                                           CaptureExpr->getBeginLoc());
4664   if (!WithInit)
4665     CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
4666   CurContext->addHiddenDecl(CED);
4667   Sema::TentativeAnalysisScope Trap(S);
4668   S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
4669   return CED;
4670 }
4671 
4672 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
4673                                  bool WithInit) {
4674   OMPCapturedExprDecl *CD;
4675   if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
4676     CD = cast<OMPCapturedExprDecl>(VD);
4677   else
4678     CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
4679                           S.CurContext,
4680                           /*AsExpression=*/false);
4681   return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4682                           CaptureExpr->getExprLoc());
4683 }
4684 
4685 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref,
4686                                StringRef Name) {
4687   CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
4688   if (!Ref) {
4689     OMPCapturedExprDecl *CD = buildCaptureDecl(
4690         S, &S.getASTContext().Idents.get(Name), CaptureExpr,
4691         /*WithInit=*/true, S.CurContext, /*AsExpression=*/true);
4692     Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4693                            CaptureExpr->getExprLoc());
4694   }
4695   ExprResult Res = Ref;
4696   if (!S.getLangOpts().CPlusPlus &&
4697       CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
4698       Ref->getType()->isPointerType()) {
4699     Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
4700     if (!Res.isUsable())
4701       return ExprError();
4702   }
4703   return S.DefaultLvalueConversion(Res.get());
4704 }
4705 
4706 namespace {
4707 // OpenMP directives parsed in this section are represented as a
4708 // CapturedStatement with an associated statement.  If a syntax error
4709 // is detected during the parsing of the associated statement, the
4710 // compiler must abort processing and close the CapturedStatement.
4711 //
4712 // Combined directives such as 'target parallel' have more than one
4713 // nested CapturedStatements.  This RAII ensures that we unwind out
4714 // of all the nested CapturedStatements when an error is found.
4715 class CaptureRegionUnwinderRAII {
4716 private:
4717   Sema &S;
4718   bool &ErrorFound;
4719   OpenMPDirectiveKind DKind = OMPD_unknown;
4720 
4721 public:
4722   CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
4723                             OpenMPDirectiveKind DKind)
4724       : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
4725   ~CaptureRegionUnwinderRAII() {
4726     if (ErrorFound) {
4727       int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
4728       while (--ThisCaptureLevel >= 0)
4729         S.ActOnCapturedRegionError();
4730     }
4731   }
4732 };
4733 } // namespace
4734 
4735 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) {
4736   // Capture variables captured by reference in lambdas for target-based
4737   // directives.
4738   if (!CurContext->isDependentContext() &&
4739       (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) ||
4740        isOpenMPTargetDataManagementDirective(
4741            DSAStack->getCurrentDirective()))) {
4742     QualType Type = V->getType();
4743     if (const auto *RD = Type.getCanonicalType()
4744                              .getNonReferenceType()
4745                              ->getAsCXXRecordDecl()) {
4746       bool SavedForceCaptureByReferenceInTargetExecutable =
4747           DSAStack->isForceCaptureByReferenceInTargetExecutable();
4748       DSAStack->setForceCaptureByReferenceInTargetExecutable(
4749           /*V=*/true);
4750       if (RD->isLambda()) {
4751         llvm::DenseMap<const ValueDecl *, FieldDecl *> Captures;
4752         FieldDecl *ThisCapture;
4753         RD->getCaptureFields(Captures, ThisCapture);
4754         for (const LambdaCapture &LC : RD->captures()) {
4755           if (LC.getCaptureKind() == LCK_ByRef) {
4756             VarDecl *VD = cast<VarDecl>(LC.getCapturedVar());
4757             DeclContext *VDC = VD->getDeclContext();
4758             if (!VDC->Encloses(CurContext))
4759               continue;
4760             MarkVariableReferenced(LC.getLocation(), VD);
4761           } else if (LC.getCaptureKind() == LCK_This) {
4762             QualType ThisTy = getCurrentThisType();
4763             if (!ThisTy.isNull() &&
4764                 Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
4765               CheckCXXThisCapture(LC.getLocation());
4766           }
4767         }
4768       }
4769       DSAStack->setForceCaptureByReferenceInTargetExecutable(
4770           SavedForceCaptureByReferenceInTargetExecutable);
4771     }
4772   }
4773 }
4774 
4775 static bool checkOrderedOrderSpecified(Sema &S,
4776                                        const ArrayRef<OMPClause *> Clauses) {
4777   const OMPOrderedClause *Ordered = nullptr;
4778   const OMPOrderClause *Order = nullptr;
4779 
4780   for (const OMPClause *Clause : Clauses) {
4781     if (Clause->getClauseKind() == OMPC_ordered)
4782       Ordered = cast<OMPOrderedClause>(Clause);
4783     else if (Clause->getClauseKind() == OMPC_order) {
4784       Order = cast<OMPOrderClause>(Clause);
4785       if (Order->getKind() != OMPC_ORDER_concurrent)
4786         Order = nullptr;
4787     }
4788     if (Ordered && Order)
4789       break;
4790   }
4791 
4792   if (Ordered && Order) {
4793     S.Diag(Order->getKindKwLoc(),
4794            diag::err_omp_simple_clause_incompatible_with_ordered)
4795         << getOpenMPClauseName(OMPC_order)
4796         << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent)
4797         << SourceRange(Order->getBeginLoc(), Order->getEndLoc());
4798     S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param)
4799         << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc());
4800     return true;
4801   }
4802   return false;
4803 }
4804 
4805 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
4806                                       ArrayRef<OMPClause *> Clauses) {
4807   handleDeclareVariantConstructTrait(DSAStack, DSAStack->getCurrentDirective(),
4808                                      /* ScopeEntry */ false);
4809   if (DSAStack->getCurrentDirective() == OMPD_atomic ||
4810       DSAStack->getCurrentDirective() == OMPD_critical ||
4811       DSAStack->getCurrentDirective() == OMPD_section ||
4812       DSAStack->getCurrentDirective() == OMPD_master ||
4813       DSAStack->getCurrentDirective() == OMPD_masked)
4814     return S;
4815 
4816   bool ErrorFound = false;
4817   CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4818       *this, ErrorFound, DSAStack->getCurrentDirective());
4819   if (!S.isUsable()) {
4820     ErrorFound = true;
4821     return StmtError();
4822   }
4823 
4824   SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4825   getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective());
4826   OMPOrderedClause *OC = nullptr;
4827   OMPScheduleClause *SC = nullptr;
4828   SmallVector<const OMPLinearClause *, 4> LCs;
4829   SmallVector<const OMPClauseWithPreInit *, 4> PICs;
4830   // This is required for proper codegen.
4831   for (OMPClause *Clause : Clauses) {
4832     if (!LangOpts.OpenMPSimd &&
4833         (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) ||
4834          DSAStack->getCurrentDirective() == OMPD_target) &&
4835         Clause->getClauseKind() == OMPC_in_reduction) {
4836       // Capture taskgroup task_reduction descriptors inside the tasking regions
4837       // with the corresponding in_reduction items.
4838       auto *IRC = cast<OMPInReductionClause>(Clause);
4839       for (Expr *E : IRC->taskgroup_descriptors())
4840         if (E)
4841           MarkDeclarationsReferencedInExpr(E);
4842     }
4843     if (isOpenMPPrivate(Clause->getClauseKind()) ||
4844         Clause->getClauseKind() == OMPC_copyprivate ||
4845         (getLangOpts().OpenMPUseTLS &&
4846          getASTContext().getTargetInfo().isTLSSupported() &&
4847          Clause->getClauseKind() == OMPC_copyin)) {
4848       DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
4849       // Mark all variables in private list clauses as used in inner region.
4850       for (Stmt *VarRef : Clause->children()) {
4851         if (auto *E = cast_or_null<Expr>(VarRef)) {
4852           MarkDeclarationsReferencedInExpr(E);
4853         }
4854       }
4855       DSAStack->setForceVarCapturing(/*V=*/false);
4856     } else if (isOpenMPLoopTransformationDirective(
4857                    DSAStack->getCurrentDirective())) {
4858       assert(CaptureRegions.empty() &&
4859              "No captured regions in loop transformation directives.");
4860     } else if (CaptureRegions.size() > 1 ||
4861                CaptureRegions.back() != OMPD_unknown) {
4862       if (auto *C = OMPClauseWithPreInit::get(Clause))
4863         PICs.push_back(C);
4864       if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
4865         if (Expr *E = C->getPostUpdateExpr())
4866           MarkDeclarationsReferencedInExpr(E);
4867       }
4868     }
4869     if (Clause->getClauseKind() == OMPC_schedule)
4870       SC = cast<OMPScheduleClause>(Clause);
4871     else if (Clause->getClauseKind() == OMPC_ordered)
4872       OC = cast<OMPOrderedClause>(Clause);
4873     else if (Clause->getClauseKind() == OMPC_linear)
4874       LCs.push_back(cast<OMPLinearClause>(Clause));
4875   }
4876   // Capture allocator expressions if used.
4877   for (Expr *E : DSAStack->getInnerAllocators())
4878     MarkDeclarationsReferencedInExpr(E);
4879   // OpenMP, 2.7.1 Loop Construct, Restrictions
4880   // The nonmonotonic modifier cannot be specified if an ordered clause is
4881   // specified.
4882   if (SC &&
4883       (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
4884        SC->getSecondScheduleModifier() ==
4885            OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4886       OC) {
4887     Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
4888              ? SC->getFirstScheduleModifierLoc()
4889              : SC->getSecondScheduleModifierLoc(),
4890          diag::err_omp_simple_clause_incompatible_with_ordered)
4891         << getOpenMPClauseName(OMPC_schedule)
4892         << getOpenMPSimpleClauseTypeName(OMPC_schedule,
4893                                          OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4894         << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4895     ErrorFound = true;
4896   }
4897   // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions.
4898   // If an order(concurrent) clause is present, an ordered clause may not appear
4899   // on the same directive.
4900   if (checkOrderedOrderSpecified(*this, Clauses))
4901     ErrorFound = true;
4902   if (!LCs.empty() && OC && OC->getNumForLoops()) {
4903     for (const OMPLinearClause *C : LCs) {
4904       Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
4905           << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4906     }
4907     ErrorFound = true;
4908   }
4909   if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
4910       isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
4911       OC->getNumForLoops()) {
4912     Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
4913         << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
4914     ErrorFound = true;
4915   }
4916   if (ErrorFound) {
4917     return StmtError();
4918   }
4919   StmtResult SR = S;
4920   unsigned CompletedRegions = 0;
4921   for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
4922     // Mark all variables in private list clauses as used in inner region.
4923     // Required for proper codegen of combined directives.
4924     // TODO: add processing for other clauses.
4925     if (ThisCaptureRegion != OMPD_unknown) {
4926       for (const clang::OMPClauseWithPreInit *C : PICs) {
4927         OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
4928         // Find the particular capture region for the clause if the
4929         // directive is a combined one with multiple capture regions.
4930         // If the directive is not a combined one, the capture region
4931         // associated with the clause is OMPD_unknown and is generated
4932         // only once.
4933         if (CaptureRegion == ThisCaptureRegion ||
4934             CaptureRegion == OMPD_unknown) {
4935           if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
4936             for (Decl *D : DS->decls())
4937               MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
4938           }
4939         }
4940       }
4941     }
4942     if (ThisCaptureRegion == OMPD_target) {
4943       // Capture allocator traits in the target region. They are used implicitly
4944       // and, thus, are not captured by default.
4945       for (OMPClause *C : Clauses) {
4946         if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) {
4947           for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4948                ++I) {
4949             OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I);
4950             if (Expr *E = D.AllocatorTraits)
4951               MarkDeclarationsReferencedInExpr(E);
4952           }
4953           continue;
4954         }
4955       }
4956     }
4957     if (ThisCaptureRegion == OMPD_parallel) {
4958       // Capture temp arrays for inscan reductions and locals in aligned
4959       // clauses.
4960       for (OMPClause *C : Clauses) {
4961         if (auto *RC = dyn_cast<OMPReductionClause>(C)) {
4962           if (RC->getModifier() != OMPC_REDUCTION_inscan)
4963             continue;
4964           for (Expr *E : RC->copy_array_temps())
4965             MarkDeclarationsReferencedInExpr(E);
4966         }
4967         if (auto *AC = dyn_cast<OMPAlignedClause>(C)) {
4968           for (Expr *E : AC->varlists())
4969             MarkDeclarationsReferencedInExpr(E);
4970         }
4971       }
4972     }
4973     if (++CompletedRegions == CaptureRegions.size())
4974       DSAStack->setBodyComplete();
4975     SR = ActOnCapturedRegionEnd(SR.get());
4976   }
4977   return SR;
4978 }
4979 
4980 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
4981                               OpenMPDirectiveKind CancelRegion,
4982                               SourceLocation StartLoc) {
4983   // CancelRegion is only needed for cancel and cancellation_point.
4984   if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4985     return false;
4986 
4987   if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4988       CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4989     return false;
4990 
4991   SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4992       << getOpenMPDirectiveName(CancelRegion);
4993   return true;
4994 }
4995 
4996 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4997                                   OpenMPDirectiveKind CurrentRegion,
4998                                   const DeclarationNameInfo &CurrentName,
4999                                   OpenMPDirectiveKind CancelRegion,
5000                                   OpenMPBindClauseKind BindKind,
5001                                   SourceLocation StartLoc) {
5002   if (Stack->getCurScope()) {
5003     OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
5004     OpenMPDirectiveKind OffendingRegion = ParentRegion;
5005     bool NestingProhibited = false;
5006     bool CloseNesting = true;
5007     bool OrphanSeen = false;
5008     enum {
5009       NoRecommend,
5010       ShouldBeInParallelRegion,
5011       ShouldBeInOrderedRegion,
5012       ShouldBeInTargetRegion,
5013       ShouldBeInTeamsRegion,
5014       ShouldBeInLoopSimdRegion,
5015     } Recommend = NoRecommend;
5016     if (SemaRef.LangOpts.OpenMP >= 51 && Stack->isParentOrderConcurrent() &&
5017         CurrentRegion != OMPD_simd && CurrentRegion != OMPD_loop &&
5018         CurrentRegion != OMPD_parallel &&
5019         !isOpenMPCombinedParallelADirective(CurrentRegion)) {
5020       SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_order)
5021           << getOpenMPDirectiveName(CurrentRegion);
5022       return true;
5023     }
5024     if (isOpenMPSimdDirective(ParentRegion) &&
5025         ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
5026          (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
5027           CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
5028           CurrentRegion != OMPD_scan))) {
5029       // OpenMP [2.16, Nesting of Regions]
5030       // OpenMP constructs may not be nested inside a simd region.
5031       // OpenMP [2.8.1,simd Construct, Restrictions]
5032       // An ordered construct with the simd clause is the only OpenMP
5033       // construct that can appear in the simd region.
5034       // Allowing a SIMD construct nested in another SIMD construct is an
5035       // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
5036       // message.
5037       // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions]
5038       // The only OpenMP constructs that can be encountered during execution of
5039       // a simd region are the atomic construct, the loop construct, the simd
5040       // construct and the ordered construct with the simd clause.
5041       SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
5042                                  ? diag::err_omp_prohibited_region_simd
5043                                  : diag::warn_omp_nesting_simd)
5044           << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0);
5045       return CurrentRegion != OMPD_simd;
5046     }
5047     if (ParentRegion == OMPD_atomic) {
5048       // OpenMP [2.16, Nesting of Regions]
5049       // OpenMP constructs may not be nested inside an atomic region.
5050       SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
5051       return true;
5052     }
5053     if (CurrentRegion == OMPD_section) {
5054       // OpenMP [2.7.2, sections Construct, Restrictions]
5055       // Orphaned section directives are prohibited. That is, the section
5056       // directives must appear within the sections construct and must not be
5057       // encountered elsewhere in the sections region.
5058       if (ParentRegion != OMPD_sections &&
5059           ParentRegion != OMPD_parallel_sections) {
5060         SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
5061             << (ParentRegion != OMPD_unknown)
5062             << getOpenMPDirectiveName(ParentRegion);
5063         return true;
5064       }
5065       return false;
5066     }
5067     // Allow some constructs (except teams and cancellation constructs) to be
5068     // orphaned (they could be used in functions, called from OpenMP regions
5069     // with the required preconditions).
5070     if (ParentRegion == OMPD_unknown &&
5071         !isOpenMPNestingTeamsDirective(CurrentRegion) &&
5072         CurrentRegion != OMPD_cancellation_point &&
5073         CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
5074       return false;
5075     if (CurrentRegion == OMPD_cancellation_point ||
5076         CurrentRegion == OMPD_cancel) {
5077       // OpenMP [2.16, Nesting of Regions]
5078       // A cancellation point construct for which construct-type-clause is
5079       // taskgroup must be nested inside a task construct. A cancellation
5080       // point construct for which construct-type-clause is not taskgroup must
5081       // be closely nested inside an OpenMP construct that matches the type
5082       // specified in construct-type-clause.
5083       // A cancel construct for which construct-type-clause is taskgroup must be
5084       // nested inside a task construct. A cancel construct for which
5085       // construct-type-clause is not taskgroup must be closely nested inside an
5086       // OpenMP construct that matches the type specified in
5087       // construct-type-clause.
5088       NestingProhibited =
5089           !((CancelRegion == OMPD_parallel &&
5090              (ParentRegion == OMPD_parallel ||
5091               ParentRegion == OMPD_target_parallel)) ||
5092             (CancelRegion == OMPD_for &&
5093              (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
5094               ParentRegion == OMPD_target_parallel_for ||
5095               ParentRegion == OMPD_distribute_parallel_for ||
5096               ParentRegion == OMPD_teams_distribute_parallel_for ||
5097               ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
5098             (CancelRegion == OMPD_taskgroup &&
5099              (ParentRegion == OMPD_task ||
5100               (SemaRef.getLangOpts().OpenMP >= 50 &&
5101                (ParentRegion == OMPD_taskloop ||
5102                 ParentRegion == OMPD_master_taskloop ||
5103                 ParentRegion == OMPD_masked_taskloop ||
5104                 ParentRegion == OMPD_parallel_masked_taskloop ||
5105                 ParentRegion == OMPD_parallel_master_taskloop)))) ||
5106             (CancelRegion == OMPD_sections &&
5107              (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
5108               ParentRegion == OMPD_parallel_sections)));
5109       OrphanSeen = ParentRegion == OMPD_unknown;
5110     } else if (CurrentRegion == OMPD_master || CurrentRegion == OMPD_masked) {
5111       // OpenMP 5.1 [2.22, Nesting of Regions]
5112       // A masked region may not be closely nested inside a worksharing, loop,
5113       // atomic, task, or taskloop region.
5114       NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
5115                           isOpenMPGenericLoopDirective(ParentRegion) ||
5116                           isOpenMPTaskingDirective(ParentRegion);
5117     } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
5118       // OpenMP [2.16, Nesting of Regions]
5119       // A critical region may not be nested (closely or otherwise) inside a
5120       // critical region with the same name. Note that this restriction is not
5121       // sufficient to prevent deadlock.
5122       SourceLocation PreviousCriticalLoc;
5123       bool DeadLock = Stack->hasDirective(
5124           [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
5125                                               const DeclarationNameInfo &DNI,
5126                                               SourceLocation Loc) {
5127             if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
5128               PreviousCriticalLoc = Loc;
5129               return true;
5130             }
5131             return false;
5132           },
5133           false /* skip top directive */);
5134       if (DeadLock) {
5135         SemaRef.Diag(StartLoc,
5136                      diag::err_omp_prohibited_region_critical_same_name)
5137             << CurrentName.getName();
5138         if (PreviousCriticalLoc.isValid())
5139           SemaRef.Diag(PreviousCriticalLoc,
5140                        diag::note_omp_previous_critical_region);
5141         return true;
5142       }
5143     } else if (CurrentRegion == OMPD_barrier || CurrentRegion == OMPD_scope) {
5144       // OpenMP 5.1 [2.22, Nesting of Regions]
5145       // A scope region may not be closely nested inside a worksharing, loop,
5146       // task, taskloop, critical, ordered, atomic, or masked region.
5147       // OpenMP 5.1 [2.22, Nesting of Regions]
5148       // A barrier region may not be closely nested inside a worksharing, loop,
5149       // task, taskloop, critical, ordered, atomic, or masked region.
5150       NestingProhibited =
5151           isOpenMPWorksharingDirective(ParentRegion) ||
5152           isOpenMPGenericLoopDirective(ParentRegion) ||
5153           isOpenMPTaskingDirective(ParentRegion) ||
5154           ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
5155           ParentRegion == OMPD_parallel_master ||
5156           ParentRegion == OMPD_parallel_masked ||
5157           ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
5158     } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
5159                !isOpenMPParallelDirective(CurrentRegion) &&
5160                !isOpenMPTeamsDirective(CurrentRegion)) {
5161       // OpenMP 5.1 [2.22, Nesting of Regions]
5162       // A loop region that binds to a parallel region or a worksharing region
5163       // may not be closely nested inside a worksharing, loop, task, taskloop,
5164       // critical, ordered, atomic, or masked region.
5165       NestingProhibited =
5166           isOpenMPWorksharingDirective(ParentRegion) ||
5167           isOpenMPGenericLoopDirective(ParentRegion) ||
5168           isOpenMPTaskingDirective(ParentRegion) ||
5169           ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
5170           ParentRegion == OMPD_parallel_master ||
5171           ParentRegion == OMPD_parallel_masked ||
5172           ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
5173       Recommend = ShouldBeInParallelRegion;
5174     } else if (CurrentRegion == OMPD_ordered) {
5175       // OpenMP [2.16, Nesting of Regions]
5176       // An ordered region may not be closely nested inside a critical,
5177       // atomic, or explicit task region.
5178       // An ordered region must be closely nested inside a loop region (or
5179       // parallel loop region) with an ordered clause.
5180       // OpenMP [2.8.1,simd Construct, Restrictions]
5181       // An ordered construct with the simd clause is the only OpenMP construct
5182       // that can appear in the simd region.
5183       NestingProhibited = ParentRegion == OMPD_critical ||
5184                           isOpenMPTaskingDirective(ParentRegion) ||
5185                           !(isOpenMPSimdDirective(ParentRegion) ||
5186                             Stack->isParentOrderedRegion());
5187       Recommend = ShouldBeInOrderedRegion;
5188     } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
5189       // OpenMP [2.16, Nesting of Regions]
5190       // If specified, a teams construct must be contained within a target
5191       // construct.
5192       NestingProhibited =
5193           (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
5194           (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
5195            ParentRegion != OMPD_target);
5196       OrphanSeen = ParentRegion == OMPD_unknown;
5197       Recommend = ShouldBeInTargetRegion;
5198     } else if (CurrentRegion == OMPD_scan) {
5199       // OpenMP [2.16, Nesting of Regions]
5200       // If specified, a teams construct must be contained within a target
5201       // construct.
5202       NestingProhibited =
5203           SemaRef.LangOpts.OpenMP < 50 ||
5204           (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
5205            ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
5206            ParentRegion != OMPD_parallel_for_simd);
5207       OrphanSeen = ParentRegion == OMPD_unknown;
5208       Recommend = ShouldBeInLoopSimdRegion;
5209     }
5210     if (!NestingProhibited &&
5211         !isOpenMPTargetExecutionDirective(CurrentRegion) &&
5212         !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
5213         (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
5214       // OpenMP [5.1, 2.22, Nesting of Regions]
5215       // distribute, distribute simd, distribute parallel worksharing-loop,
5216       // distribute parallel worksharing-loop SIMD, loop, parallel regions,
5217       // including any parallel regions arising from combined constructs,
5218       // omp_get_num_teams() regions, and omp_get_team_num() regions are the
5219       // only OpenMP regions that may be strictly nested inside the teams
5220       // region.
5221       //
5222       // As an extension, we permit atomic within teams as well.
5223       NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
5224                           !isOpenMPDistributeDirective(CurrentRegion) &&
5225                           CurrentRegion != OMPD_loop &&
5226                           !(SemaRef.getLangOpts().OpenMPExtensions &&
5227                             CurrentRegion == OMPD_atomic);
5228       Recommend = ShouldBeInParallelRegion;
5229     }
5230     if (!NestingProhibited && CurrentRegion == OMPD_loop) {
5231       // OpenMP [5.1, 2.11.7, loop Construct, Restrictions]
5232       // If the bind clause is present on the loop construct and binding is
5233       // teams then the corresponding loop region must be strictly nested inside
5234       // a teams region.
5235       NestingProhibited = BindKind == OMPC_BIND_teams &&
5236                           ParentRegion != OMPD_teams &&
5237                           ParentRegion != OMPD_target_teams;
5238       Recommend = ShouldBeInTeamsRegion;
5239     }
5240     if (!NestingProhibited &&
5241         isOpenMPNestingDistributeDirective(CurrentRegion)) {
5242       // OpenMP 4.5 [2.17 Nesting of Regions]
5243       // The region associated with the distribute construct must be strictly
5244       // nested inside a teams region
5245       NestingProhibited =
5246           (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
5247       Recommend = ShouldBeInTeamsRegion;
5248     }
5249     if (!NestingProhibited &&
5250         (isOpenMPTargetExecutionDirective(CurrentRegion) ||
5251          isOpenMPTargetDataManagementDirective(CurrentRegion))) {
5252       // OpenMP 4.5 [2.17 Nesting of Regions]
5253       // If a target, target update, target data, target enter data, or
5254       // target exit data construct is encountered during execution of a
5255       // target region, the behavior is unspecified.
5256       NestingProhibited = Stack->hasDirective(
5257           [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
5258                              SourceLocation) {
5259             if (isOpenMPTargetExecutionDirective(K)) {
5260               OffendingRegion = K;
5261               return true;
5262             }
5263             return false;
5264           },
5265           false /* don't skip top directive */);
5266       CloseNesting = false;
5267     }
5268     if (NestingProhibited) {
5269       if (OrphanSeen) {
5270         SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
5271             << getOpenMPDirectiveName(CurrentRegion) << Recommend;
5272       } else {
5273         SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
5274             << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
5275             << Recommend << getOpenMPDirectiveName(CurrentRegion);
5276       }
5277       return true;
5278     }
5279   }
5280   return false;
5281 }
5282 
5283 struct Kind2Unsigned {
5284   using argument_type = OpenMPDirectiveKind;
5285   unsigned operator()(argument_type DK) { return unsigned(DK); }
5286 };
5287 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
5288                            ArrayRef<OMPClause *> Clauses,
5289                            ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
5290   bool ErrorFound = false;
5291   unsigned NamedModifiersNumber = 0;
5292   llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
5293   FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
5294   SmallVector<SourceLocation, 4> NameModifierLoc;
5295   for (const OMPClause *C : Clauses) {
5296     if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
5297       // At most one if clause without a directive-name-modifier can appear on
5298       // the directive.
5299       OpenMPDirectiveKind CurNM = IC->getNameModifier();
5300       if (FoundNameModifiers[CurNM]) {
5301         S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
5302             << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
5303             << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
5304         ErrorFound = true;
5305       } else if (CurNM != OMPD_unknown) {
5306         NameModifierLoc.push_back(IC->getNameModifierLoc());
5307         ++NamedModifiersNumber;
5308       }
5309       FoundNameModifiers[CurNM] = IC;
5310       if (CurNM == OMPD_unknown)
5311         continue;
5312       // Check if the specified name modifier is allowed for the current
5313       // directive.
5314       // At most one if clause with the particular directive-name-modifier can
5315       // appear on the directive.
5316       if (!llvm::is_contained(AllowedNameModifiers, CurNM)) {
5317         S.Diag(IC->getNameModifierLoc(),
5318                diag::err_omp_wrong_if_directive_name_modifier)
5319             << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
5320         ErrorFound = true;
5321       }
5322     }
5323   }
5324   // If any if clause on the directive includes a directive-name-modifier then
5325   // all if clauses on the directive must include a directive-name-modifier.
5326   if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
5327     if (NamedModifiersNumber == AllowedNameModifiers.size()) {
5328       S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
5329              diag::err_omp_no_more_if_clause);
5330     } else {
5331       std::string Values;
5332       std::string Sep(", ");
5333       unsigned AllowedCnt = 0;
5334       unsigned TotalAllowedNum =
5335           AllowedNameModifiers.size() - NamedModifiersNumber;
5336       for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
5337            ++Cnt) {
5338         OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
5339         if (!FoundNameModifiers[NM]) {
5340           Values += "'";
5341           Values += getOpenMPDirectiveName(NM);
5342           Values += "'";
5343           if (AllowedCnt + 2 == TotalAllowedNum)
5344             Values += " or ";
5345           else if (AllowedCnt + 1 != TotalAllowedNum)
5346             Values += Sep;
5347           ++AllowedCnt;
5348         }
5349       }
5350       S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
5351              diag::err_omp_unnamed_if_clause)
5352           << (TotalAllowedNum > 1) << Values;
5353     }
5354     for (SourceLocation Loc : NameModifierLoc) {
5355       S.Diag(Loc, diag::note_omp_previous_named_if_clause);
5356     }
5357     ErrorFound = true;
5358   }
5359   return ErrorFound;
5360 }
5361 
5362 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
5363                                                    SourceLocation &ELoc,
5364                                                    SourceRange &ERange,
5365                                                    bool AllowArraySection,
5366                                                    StringRef DiagType) {
5367   if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
5368       RefExpr->containsUnexpandedParameterPack())
5369     return std::make_pair(nullptr, true);
5370 
5371   // OpenMP [3.1, C/C++]
5372   //  A list item is a variable name.
5373   // OpenMP  [2.9.3.3, Restrictions, p.1]
5374   //  A variable that is part of another variable (as an array or
5375   //  structure element) cannot appear in a private clause.
5376   RefExpr = RefExpr->IgnoreParens();
5377   enum {
5378     NoArrayExpr = -1,
5379     ArraySubscript = 0,
5380     OMPArraySection = 1
5381   } IsArrayExpr = NoArrayExpr;
5382   if (AllowArraySection) {
5383     if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
5384       Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
5385       while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
5386         Base = TempASE->getBase()->IgnoreParenImpCasts();
5387       RefExpr = Base;
5388       IsArrayExpr = ArraySubscript;
5389     } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
5390       Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
5391       while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
5392         Base = TempOASE->getBase()->IgnoreParenImpCasts();
5393       while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
5394         Base = TempASE->getBase()->IgnoreParenImpCasts();
5395       RefExpr = Base;
5396       IsArrayExpr = OMPArraySection;
5397     }
5398   }
5399   ELoc = RefExpr->getExprLoc();
5400   ERange = RefExpr->getSourceRange();
5401   RefExpr = RefExpr->IgnoreParenImpCasts();
5402   auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
5403   auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
5404   if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
5405       (S.getCurrentThisType().isNull() || !ME ||
5406        !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
5407        !isa<FieldDecl>(ME->getMemberDecl()))) {
5408     if (IsArrayExpr != NoArrayExpr) {
5409       S.Diag(ELoc, diag::err_omp_expected_base_var_name)
5410           << IsArrayExpr << ERange;
5411     } else if (!DiagType.empty()) {
5412       unsigned DiagSelect = S.getLangOpts().CPlusPlus
5413                                 ? (S.getCurrentThisType().isNull() ? 1 : 2)
5414                                 : 0;
5415       S.Diag(ELoc, diag::err_omp_expected_var_name_member_expr_with_type)
5416           << DiagSelect << DiagType << ERange;
5417     } else {
5418       S.Diag(ELoc,
5419              AllowArraySection
5420                  ? diag::err_omp_expected_var_name_member_expr_or_array_item
5421                  : diag::err_omp_expected_var_name_member_expr)
5422           << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
5423     }
5424     return std::make_pair(nullptr, false);
5425   }
5426   return std::make_pair(
5427       getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
5428 }
5429 
5430 namespace {
5431 /// Checks if the allocator is used in uses_allocators clause to be allowed in
5432 /// target regions.
5433 class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> {
5434   DSAStackTy *S = nullptr;
5435 
5436 public:
5437   bool VisitDeclRefExpr(const DeclRefExpr *E) {
5438     return S->isUsesAllocatorsDecl(E->getDecl())
5439                .value_or(DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
5440            DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
5441   }
5442   bool VisitStmt(const Stmt *S) {
5443     for (const Stmt *Child : S->children()) {
5444       if (Child && Visit(Child))
5445         return true;
5446     }
5447     return false;
5448   }
5449   explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
5450 };
5451 } // namespace
5452 
5453 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
5454                                  ArrayRef<OMPClause *> Clauses) {
5455   assert(!S.CurContext->isDependentContext() &&
5456          "Expected non-dependent context.");
5457   auto AllocateRange =
5458       llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
5459   llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> DeclToCopy;
5460   auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
5461     return isOpenMPPrivate(C->getClauseKind());
5462   });
5463   for (OMPClause *Cl : PrivateRange) {
5464     MutableArrayRef<Expr *>::iterator I, It, Et;
5465     if (Cl->getClauseKind() == OMPC_private) {
5466       auto *PC = cast<OMPPrivateClause>(Cl);
5467       I = PC->private_copies().begin();
5468       It = PC->varlist_begin();
5469       Et = PC->varlist_end();
5470     } else if (Cl->getClauseKind() == OMPC_firstprivate) {
5471       auto *PC = cast<OMPFirstprivateClause>(Cl);
5472       I = PC->private_copies().begin();
5473       It = PC->varlist_begin();
5474       Et = PC->varlist_end();
5475     } else if (Cl->getClauseKind() == OMPC_lastprivate) {
5476       auto *PC = cast<OMPLastprivateClause>(Cl);
5477       I = PC->private_copies().begin();
5478       It = PC->varlist_begin();
5479       Et = PC->varlist_end();
5480     } else if (Cl->getClauseKind() == OMPC_linear) {
5481       auto *PC = cast<OMPLinearClause>(Cl);
5482       I = PC->privates().begin();
5483       It = PC->varlist_begin();
5484       Et = PC->varlist_end();
5485     } else if (Cl->getClauseKind() == OMPC_reduction) {
5486       auto *PC = cast<OMPReductionClause>(Cl);
5487       I = PC->privates().begin();
5488       It = PC->varlist_begin();
5489       Et = PC->varlist_end();
5490     } else if (Cl->getClauseKind() == OMPC_task_reduction) {
5491       auto *PC = cast<OMPTaskReductionClause>(Cl);
5492       I = PC->privates().begin();
5493       It = PC->varlist_begin();
5494       Et = PC->varlist_end();
5495     } else if (Cl->getClauseKind() == OMPC_in_reduction) {
5496       auto *PC = cast<OMPInReductionClause>(Cl);
5497       I = PC->privates().begin();
5498       It = PC->varlist_begin();
5499       Et = PC->varlist_end();
5500     } else {
5501       llvm_unreachable("Expected private clause.");
5502     }
5503     for (Expr *E : llvm::make_range(It, Et)) {
5504       if (!*I) {
5505         ++I;
5506         continue;
5507       }
5508       SourceLocation ELoc;
5509       SourceRange ERange;
5510       Expr *SimpleRefExpr = E;
5511       auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
5512                                 /*AllowArraySection=*/true);
5513       DeclToCopy.try_emplace(Res.first,
5514                              cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
5515       ++I;
5516     }
5517   }
5518   for (OMPClause *C : AllocateRange) {
5519     auto *AC = cast<OMPAllocateClause>(C);
5520     if (S.getLangOpts().OpenMP >= 50 &&
5521         !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() &&
5522         isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
5523         AC->getAllocator()) {
5524       Expr *Allocator = AC->getAllocator();
5525       // OpenMP, 2.12.5 target Construct
5526       // Memory allocators that do not appear in a uses_allocators clause cannot
5527       // appear as an allocator in an allocate clause or be used in the target
5528       // region unless a requires directive with the dynamic_allocators clause
5529       // is present in the same compilation unit.
5530       AllocatorChecker Checker(Stack);
5531       if (Checker.Visit(Allocator))
5532         S.Diag(Allocator->getExprLoc(),
5533                diag::err_omp_allocator_not_in_uses_allocators)
5534             << Allocator->getSourceRange();
5535     }
5536     OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
5537         getAllocatorKind(S, Stack, AC->getAllocator());
5538     // OpenMP, 2.11.4 allocate Clause, Restrictions.
5539     // For task, taskloop or target directives, allocation requests to memory
5540     // allocators with the trait access set to thread result in unspecified
5541     // behavior.
5542     if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
5543         (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
5544          isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
5545       S.Diag(AC->getAllocator()->getExprLoc(),
5546              diag::warn_omp_allocate_thread_on_task_target_directive)
5547           << getOpenMPDirectiveName(Stack->getCurrentDirective());
5548     }
5549     for (Expr *E : AC->varlists()) {
5550       SourceLocation ELoc;
5551       SourceRange ERange;
5552       Expr *SimpleRefExpr = E;
5553       auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
5554       ValueDecl *VD = Res.first;
5555       DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
5556       if (!isOpenMPPrivate(Data.CKind)) {
5557         S.Diag(E->getExprLoc(),
5558                diag::err_omp_expected_private_copy_for_allocate);
5559         continue;
5560       }
5561       VarDecl *PrivateVD = DeclToCopy[VD];
5562       if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
5563                                             AllocatorKind, AC->getAllocator()))
5564         continue;
5565       // Placeholder until allocate clause supports align modifier.
5566       Expr *Alignment = nullptr;
5567       applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
5568                                 Alignment, E->getSourceRange());
5569     }
5570   }
5571 }
5572 
5573 namespace {
5574 /// Rewrite statements and expressions for Sema \p Actions CurContext.
5575 ///
5576 /// Used to wrap already parsed statements/expressions into a new CapturedStmt
5577 /// context. DeclRefExpr used inside the new context are changed to refer to the
5578 /// captured variable instead.
5579 class CaptureVars : public TreeTransform<CaptureVars> {
5580   using BaseTransform = TreeTransform<CaptureVars>;
5581 
5582 public:
5583   CaptureVars(Sema &Actions) : BaseTransform(Actions) {}
5584 
5585   bool AlwaysRebuild() { return true; }
5586 };
5587 } // namespace
5588 
5589 static VarDecl *precomputeExpr(Sema &Actions,
5590                                SmallVectorImpl<Stmt *> &BodyStmts, Expr *E,
5591                                StringRef Name) {
5592   Expr *NewE = AssertSuccess(CaptureVars(Actions).TransformExpr(E));
5593   VarDecl *NewVar = buildVarDecl(Actions, {}, NewE->getType(), Name, nullptr,
5594                                  dyn_cast<DeclRefExpr>(E->IgnoreImplicit()));
5595   auto *NewDeclStmt = cast<DeclStmt>(AssertSuccess(
5596       Actions.ActOnDeclStmt(Actions.ConvertDeclToDeclGroup(NewVar), {}, {})));
5597   Actions.AddInitializerToDecl(NewDeclStmt->getSingleDecl(), NewE, false);
5598   BodyStmts.push_back(NewDeclStmt);
5599   return NewVar;
5600 }
5601 
5602 /// Create a closure that computes the number of iterations of a loop.
5603 ///
5604 /// \param Actions   The Sema object.
5605 /// \param LogicalTy Type for the logical iteration number.
5606 /// \param Rel       Comparison operator of the loop condition.
5607 /// \param StartExpr Value of the loop counter at the first iteration.
5608 /// \param StopExpr  Expression the loop counter is compared against in the loop
5609 /// condition. \param StepExpr      Amount of increment after each iteration.
5610 ///
5611 /// \return Closure (CapturedStmt) of the distance calculation.
5612 static CapturedStmt *buildDistanceFunc(Sema &Actions, QualType LogicalTy,
5613                                        BinaryOperator::Opcode Rel,
5614                                        Expr *StartExpr, Expr *StopExpr,
5615                                        Expr *StepExpr) {
5616   ASTContext &Ctx = Actions.getASTContext();
5617   TypeSourceInfo *LogicalTSI = Ctx.getTrivialTypeSourceInfo(LogicalTy);
5618 
5619   // Captured regions currently don't support return values, we use an
5620   // out-parameter instead. All inputs are implicit captures.
5621   // TODO: Instead of capturing each DeclRefExpr occurring in
5622   // StartExpr/StopExpr/Step, these could also be passed as a value capture.
5623   QualType ResultTy = Ctx.getLValueReferenceType(LogicalTy);
5624   Sema::CapturedParamNameType Params[] = {{"Distance", ResultTy},
5625                                           {StringRef(), QualType()}};
5626   Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5627 
5628   Stmt *Body;
5629   {
5630     Sema::CompoundScopeRAII CompoundScope(Actions);
5631     CapturedDecl *CS = cast<CapturedDecl>(Actions.CurContext);
5632 
5633     // Get the LValue expression for the result.
5634     ImplicitParamDecl *DistParam = CS->getParam(0);
5635     DeclRefExpr *DistRef = Actions.BuildDeclRefExpr(
5636         DistParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5637 
5638     SmallVector<Stmt *, 4> BodyStmts;
5639 
5640     // Capture all referenced variable references.
5641     // TODO: Instead of computing NewStart/NewStop/NewStep inside the
5642     // CapturedStmt, we could compute them before and capture the result, to be
5643     // used jointly with the LoopVar function.
5644     VarDecl *NewStart = precomputeExpr(Actions, BodyStmts, StartExpr, ".start");
5645     VarDecl *NewStop = precomputeExpr(Actions, BodyStmts, StopExpr, ".stop");
5646     VarDecl *NewStep = precomputeExpr(Actions, BodyStmts, StepExpr, ".step");
5647     auto BuildVarRef = [&](VarDecl *VD) {
5648       return buildDeclRefExpr(Actions, VD, VD->getType(), {});
5649     };
5650 
5651     IntegerLiteral *Zero = IntegerLiteral::Create(
5652         Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 0), LogicalTy, {});
5653     IntegerLiteral *One = IntegerLiteral::Create(
5654         Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {});
5655     Expr *Dist;
5656     if (Rel == BO_NE) {
5657       // When using a != comparison, the increment can be +1 or -1. This can be
5658       // dynamic at runtime, so we need to check for the direction.
5659       Expr *IsNegStep = AssertSuccess(
5660           Actions.BuildBinOp(nullptr, {}, BO_LT, BuildVarRef(NewStep), Zero));
5661 
5662       // Positive increment.
5663       Expr *ForwardRange = AssertSuccess(Actions.BuildBinOp(
5664           nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5665       ForwardRange = AssertSuccess(
5666           Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, ForwardRange));
5667       Expr *ForwardDist = AssertSuccess(Actions.BuildBinOp(
5668           nullptr, {}, BO_Div, ForwardRange, BuildVarRef(NewStep)));
5669 
5670       // Negative increment.
5671       Expr *BackwardRange = AssertSuccess(Actions.BuildBinOp(
5672           nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5673       BackwardRange = AssertSuccess(
5674           Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, BackwardRange));
5675       Expr *NegIncAmount = AssertSuccess(
5676           Actions.BuildUnaryOp(nullptr, {}, UO_Minus, BuildVarRef(NewStep)));
5677       Expr *BackwardDist = AssertSuccess(
5678           Actions.BuildBinOp(nullptr, {}, BO_Div, BackwardRange, NegIncAmount));
5679 
5680       // Use the appropriate case.
5681       Dist = AssertSuccess(Actions.ActOnConditionalOp(
5682           {}, {}, IsNegStep, BackwardDist, ForwardDist));
5683     } else {
5684       assert((Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT) &&
5685              "Expected one of these relational operators");
5686 
5687       // We can derive the direction from any other comparison operator. It is
5688       // non well-formed OpenMP if Step increments/decrements in the other
5689       // directions. Whether at least the first iteration passes the loop
5690       // condition.
5691       Expr *HasAnyIteration = AssertSuccess(Actions.BuildBinOp(
5692           nullptr, {}, Rel, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5693 
5694       // Compute the range between first and last counter value.
5695       Expr *Range;
5696       if (Rel == BO_GE || Rel == BO_GT)
5697         Range = AssertSuccess(Actions.BuildBinOp(
5698             nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5699       else
5700         Range = AssertSuccess(Actions.BuildBinOp(
5701             nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5702 
5703       // Ensure unsigned range space.
5704       Range =
5705           AssertSuccess(Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, Range));
5706 
5707       if (Rel == BO_LE || Rel == BO_GE) {
5708         // Add one to the range if the relational operator is inclusive.
5709         Range =
5710             AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, Range, One));
5711       }
5712 
5713       // Divide by the absolute step amount. If the range is not a multiple of
5714       // the step size, rounding-up the effective upper bound ensures that the
5715       // last iteration is included.
5716       // Note that the rounding-up may cause an overflow in a temporry that
5717       // could be avoided, but would have occurred in a C-style for-loop as
5718       // well.
5719       Expr *Divisor = BuildVarRef(NewStep);
5720       if (Rel == BO_GE || Rel == BO_GT)
5721         Divisor =
5722             AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Minus, Divisor));
5723       Expr *DivisorMinusOne =
5724           AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Sub, Divisor, One));
5725       Expr *RangeRoundUp = AssertSuccess(
5726           Actions.BuildBinOp(nullptr, {}, BO_Add, Range, DivisorMinusOne));
5727       Dist = AssertSuccess(
5728           Actions.BuildBinOp(nullptr, {}, BO_Div, RangeRoundUp, Divisor));
5729 
5730       // If there is not at least one iteration, the range contains garbage. Fix
5731       // to zero in this case.
5732       Dist = AssertSuccess(
5733           Actions.ActOnConditionalOp({}, {}, HasAnyIteration, Dist, Zero));
5734     }
5735 
5736     // Assign the result to the out-parameter.
5737     Stmt *ResultAssign = AssertSuccess(Actions.BuildBinOp(
5738         Actions.getCurScope(), {}, BO_Assign, DistRef, Dist));
5739     BodyStmts.push_back(ResultAssign);
5740 
5741     Body = AssertSuccess(Actions.ActOnCompoundStmt({}, {}, BodyStmts, false));
5742   }
5743 
5744   return cast<CapturedStmt>(
5745       AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5746 }
5747 
5748 /// Create a closure that computes the loop variable from the logical iteration
5749 /// number.
5750 ///
5751 /// \param Actions   The Sema object.
5752 /// \param LoopVarTy Type for the loop variable used for result value.
5753 /// \param LogicalTy Type for the logical iteration number.
5754 /// \param StartExpr Value of the loop counter at the first iteration.
5755 /// \param Step      Amount of increment after each iteration.
5756 /// \param Deref     Whether the loop variable is a dereference of the loop
5757 /// counter variable.
5758 ///
5759 /// \return Closure (CapturedStmt) of the loop value calculation.
5760 static CapturedStmt *buildLoopVarFunc(Sema &Actions, QualType LoopVarTy,
5761                                       QualType LogicalTy,
5762                                       DeclRefExpr *StartExpr, Expr *Step,
5763                                       bool Deref) {
5764   ASTContext &Ctx = Actions.getASTContext();
5765 
5766   // Pass the result as an out-parameter. Passing as return value would require
5767   // the OpenMPIRBuilder to know additional C/C++ semantics, such as how to
5768   // invoke a copy constructor.
5769   QualType TargetParamTy = Ctx.getLValueReferenceType(LoopVarTy);
5770   Sema::CapturedParamNameType Params[] = {{"LoopVar", TargetParamTy},
5771                                           {"Logical", LogicalTy},
5772                                           {StringRef(), QualType()}};
5773   Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5774 
5775   // Capture the initial iterator which represents the LoopVar value at the
5776   // zero's logical iteration. Since the original ForStmt/CXXForRangeStmt update
5777   // it in every iteration, capture it by value before it is modified.
5778   VarDecl *StartVar = cast<VarDecl>(StartExpr->getDecl());
5779   bool Invalid = Actions.tryCaptureVariable(StartVar, {},
5780                                             Sema::TryCapture_ExplicitByVal, {});
5781   (void)Invalid;
5782   assert(!Invalid && "Expecting capture-by-value to work.");
5783 
5784   Expr *Body;
5785   {
5786     Sema::CompoundScopeRAII CompoundScope(Actions);
5787     auto *CS = cast<CapturedDecl>(Actions.CurContext);
5788 
5789     ImplicitParamDecl *TargetParam = CS->getParam(0);
5790     DeclRefExpr *TargetRef = Actions.BuildDeclRefExpr(
5791         TargetParam, LoopVarTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5792     ImplicitParamDecl *IndvarParam = CS->getParam(1);
5793     DeclRefExpr *LogicalRef = Actions.BuildDeclRefExpr(
5794         IndvarParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5795 
5796     // Capture the Start expression.
5797     CaptureVars Recap(Actions);
5798     Expr *NewStart = AssertSuccess(Recap.TransformExpr(StartExpr));
5799     Expr *NewStep = AssertSuccess(Recap.TransformExpr(Step));
5800 
5801     Expr *Skip = AssertSuccess(
5802         Actions.BuildBinOp(nullptr, {}, BO_Mul, NewStep, LogicalRef));
5803     // TODO: Explicitly cast to the iterator's difference_type instead of
5804     // relying on implicit conversion.
5805     Expr *Advanced =
5806         AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, NewStart, Skip));
5807 
5808     if (Deref) {
5809       // For range-based for-loops convert the loop counter value to a concrete
5810       // loop variable value by dereferencing the iterator.
5811       Advanced =
5812           AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Deref, Advanced));
5813     }
5814 
5815     // Assign the result to the output parameter.
5816     Body = AssertSuccess(Actions.BuildBinOp(Actions.getCurScope(), {},
5817                                             BO_Assign, TargetRef, Advanced));
5818   }
5819   return cast<CapturedStmt>(
5820       AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5821 }
5822 
5823 StmtResult Sema::ActOnOpenMPCanonicalLoop(Stmt *AStmt) {
5824   ASTContext &Ctx = getASTContext();
5825 
5826   // Extract the common elements of ForStmt and CXXForRangeStmt:
5827   // Loop variable, repeat condition, increment
5828   Expr *Cond, *Inc;
5829   VarDecl *LIVDecl, *LUVDecl;
5830   if (auto *For = dyn_cast<ForStmt>(AStmt)) {
5831     Stmt *Init = For->getInit();
5832     if (auto *LCVarDeclStmt = dyn_cast<DeclStmt>(Init)) {
5833       // For statement declares loop variable.
5834       LIVDecl = cast<VarDecl>(LCVarDeclStmt->getSingleDecl());
5835     } else if (auto *LCAssign = dyn_cast<BinaryOperator>(Init)) {
5836       // For statement reuses variable.
5837       assert(LCAssign->getOpcode() == BO_Assign &&
5838              "init part must be a loop variable assignment");
5839       auto *CounterRef = cast<DeclRefExpr>(LCAssign->getLHS());
5840       LIVDecl = cast<VarDecl>(CounterRef->getDecl());
5841     } else
5842       llvm_unreachable("Cannot determine loop variable");
5843     LUVDecl = LIVDecl;
5844 
5845     Cond = For->getCond();
5846     Inc = For->getInc();
5847   } else if (auto *RangeFor = dyn_cast<CXXForRangeStmt>(AStmt)) {
5848     DeclStmt *BeginStmt = RangeFor->getBeginStmt();
5849     LIVDecl = cast<VarDecl>(BeginStmt->getSingleDecl());
5850     LUVDecl = RangeFor->getLoopVariable();
5851 
5852     Cond = RangeFor->getCond();
5853     Inc = RangeFor->getInc();
5854   } else
5855     llvm_unreachable("unhandled kind of loop");
5856 
5857   QualType CounterTy = LIVDecl->getType();
5858   QualType LVTy = LUVDecl->getType();
5859 
5860   // Analyze the loop condition.
5861   Expr *LHS, *RHS;
5862   BinaryOperator::Opcode CondRel;
5863   Cond = Cond->IgnoreImplicit();
5864   if (auto *CondBinExpr = dyn_cast<BinaryOperator>(Cond)) {
5865     LHS = CondBinExpr->getLHS();
5866     RHS = CondBinExpr->getRHS();
5867     CondRel = CondBinExpr->getOpcode();
5868   } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Cond)) {
5869     assert(CondCXXOp->getNumArgs() == 2 && "Comparison should have 2 operands");
5870     LHS = CondCXXOp->getArg(0);
5871     RHS = CondCXXOp->getArg(1);
5872     switch (CondCXXOp->getOperator()) {
5873     case OO_ExclaimEqual:
5874       CondRel = BO_NE;
5875       break;
5876     case OO_Less:
5877       CondRel = BO_LT;
5878       break;
5879     case OO_LessEqual:
5880       CondRel = BO_LE;
5881       break;
5882     case OO_Greater:
5883       CondRel = BO_GT;
5884       break;
5885     case OO_GreaterEqual:
5886       CondRel = BO_GE;
5887       break;
5888     default:
5889       llvm_unreachable("unexpected iterator operator");
5890     }
5891   } else
5892     llvm_unreachable("unexpected loop condition");
5893 
5894   // Normalize such that the loop counter is on the LHS.
5895   if (!isa<DeclRefExpr>(LHS->IgnoreImplicit()) ||
5896       cast<DeclRefExpr>(LHS->IgnoreImplicit())->getDecl() != LIVDecl) {
5897     std::swap(LHS, RHS);
5898     CondRel = BinaryOperator::reverseComparisonOp(CondRel);
5899   }
5900   auto *CounterRef = cast<DeclRefExpr>(LHS->IgnoreImplicit());
5901 
5902   // Decide the bit width for the logical iteration counter. By default use the
5903   // unsigned ptrdiff_t integer size (for iterators and pointers).
5904   // TODO: For iterators, use iterator::difference_type,
5905   // std::iterator_traits<>::difference_type or decltype(it - end).
5906   QualType LogicalTy = Ctx.getUnsignedPointerDiffType();
5907   if (CounterTy->isIntegerType()) {
5908     unsigned BitWidth = Ctx.getIntWidth(CounterTy);
5909     LogicalTy = Ctx.getIntTypeForBitwidth(BitWidth, false);
5910   }
5911 
5912   // Analyze the loop increment.
5913   Expr *Step;
5914   if (auto *IncUn = dyn_cast<UnaryOperator>(Inc)) {
5915     int Direction;
5916     switch (IncUn->getOpcode()) {
5917     case UO_PreInc:
5918     case UO_PostInc:
5919       Direction = 1;
5920       break;
5921     case UO_PreDec:
5922     case UO_PostDec:
5923       Direction = -1;
5924       break;
5925     default:
5926       llvm_unreachable("unhandled unary increment operator");
5927     }
5928     Step = IntegerLiteral::Create(
5929         Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), Direction), LogicalTy, {});
5930   } else if (auto *IncBin = dyn_cast<BinaryOperator>(Inc)) {
5931     if (IncBin->getOpcode() == BO_AddAssign) {
5932       Step = IncBin->getRHS();
5933     } else if (IncBin->getOpcode() == BO_SubAssign) {
5934       Step =
5935           AssertSuccess(BuildUnaryOp(nullptr, {}, UO_Minus, IncBin->getRHS()));
5936     } else
5937       llvm_unreachable("unhandled binary increment operator");
5938   } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Inc)) {
5939     switch (CondCXXOp->getOperator()) {
5940     case OO_PlusPlus:
5941       Step = IntegerLiteral::Create(
5942           Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {});
5943       break;
5944     case OO_MinusMinus:
5945       Step = IntegerLiteral::Create(
5946           Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), -1), LogicalTy, {});
5947       break;
5948     case OO_PlusEqual:
5949       Step = CondCXXOp->getArg(1);
5950       break;
5951     case OO_MinusEqual:
5952       Step = AssertSuccess(
5953           BuildUnaryOp(nullptr, {}, UO_Minus, CondCXXOp->getArg(1)));
5954       break;
5955     default:
5956       llvm_unreachable("unhandled overloaded increment operator");
5957     }
5958   } else
5959     llvm_unreachable("unknown increment expression");
5960 
5961   CapturedStmt *DistanceFunc =
5962       buildDistanceFunc(*this, LogicalTy, CondRel, LHS, RHS, Step);
5963   CapturedStmt *LoopVarFunc = buildLoopVarFunc(
5964       *this, LVTy, LogicalTy, CounterRef, Step, isa<CXXForRangeStmt>(AStmt));
5965   DeclRefExpr *LVRef = BuildDeclRefExpr(LUVDecl, LUVDecl->getType(), VK_LValue,
5966                                         {}, nullptr, nullptr, {}, nullptr);
5967   return OMPCanonicalLoop::create(getASTContext(), AStmt, DistanceFunc,
5968                                   LoopVarFunc, LVRef);
5969 }
5970 
5971 StmtResult Sema::ActOnOpenMPLoopnest(Stmt *AStmt) {
5972   // Handle a literal loop.
5973   if (isa<ForStmt>(AStmt) || isa<CXXForRangeStmt>(AStmt))
5974     return ActOnOpenMPCanonicalLoop(AStmt);
5975 
5976   // If not a literal loop, it must be the result of a loop transformation.
5977   OMPExecutableDirective *LoopTransform = cast<OMPExecutableDirective>(AStmt);
5978   assert(
5979       isOpenMPLoopTransformationDirective(LoopTransform->getDirectiveKind()) &&
5980       "Loop transformation directive expected");
5981   return LoopTransform;
5982 }
5983 
5984 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
5985                                             CXXScopeSpec &MapperIdScopeSpec,
5986                                             const DeclarationNameInfo &MapperId,
5987                                             QualType Type,
5988                                             Expr *UnresolvedMapper);
5989 
5990 /// Perform DFS through the structure/class data members trying to find
5991 /// member(s) with user-defined 'default' mapper and generate implicit map
5992 /// clauses for such members with the found 'default' mapper.
5993 static void
5994 processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack,
5995                                       SmallVectorImpl<OMPClause *> &Clauses) {
5996   // Check for the deault mapper for data members.
5997   if (S.getLangOpts().OpenMP < 50)
5998     return;
5999   SmallVector<OMPClause *, 4> ImplicitMaps;
6000   for (int Cnt = 0, EndCnt = Clauses.size(); Cnt < EndCnt; ++Cnt) {
6001     auto *C = dyn_cast<OMPMapClause>(Clauses[Cnt]);
6002     if (!C)
6003       continue;
6004     SmallVector<Expr *, 4> SubExprs;
6005     auto *MI = C->mapperlist_begin();
6006     for (auto I = C->varlist_begin(), End = C->varlist_end(); I != End;
6007          ++I, ++MI) {
6008       // Expression is mapped using mapper - skip it.
6009       if (*MI)
6010         continue;
6011       Expr *E = *I;
6012       // Expression is dependent - skip it, build the mapper when it gets
6013       // instantiated.
6014       if (E->isTypeDependent() || E->isValueDependent() ||
6015           E->containsUnexpandedParameterPack())
6016         continue;
6017       // Array section - need to check for the mapping of the array section
6018       // element.
6019       QualType CanonType = E->getType().getCanonicalType();
6020       if (CanonType->isSpecificBuiltinType(BuiltinType::OMPArraySection)) {
6021         const auto *OASE = cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts());
6022         QualType BaseType =
6023             OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
6024         QualType ElemType;
6025         if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
6026           ElemType = ATy->getElementType();
6027         else
6028           ElemType = BaseType->getPointeeType();
6029         CanonType = ElemType;
6030       }
6031 
6032       // DFS over data members in structures/classes.
6033       SmallVector<std::pair<QualType, FieldDecl *>, 4> Types(
6034           1, {CanonType, nullptr});
6035       llvm::DenseMap<const Type *, Expr *> Visited;
6036       SmallVector<std::pair<FieldDecl *, unsigned>, 4> ParentChain(
6037           1, {nullptr, 1});
6038       while (!Types.empty()) {
6039         QualType BaseType;
6040         FieldDecl *CurFD;
6041         std::tie(BaseType, CurFD) = Types.pop_back_val();
6042         while (ParentChain.back().second == 0)
6043           ParentChain.pop_back();
6044         --ParentChain.back().second;
6045         if (BaseType.isNull())
6046           continue;
6047         // Only structs/classes are allowed to have mappers.
6048         const RecordDecl *RD = BaseType.getCanonicalType()->getAsRecordDecl();
6049         if (!RD)
6050           continue;
6051         auto It = Visited.find(BaseType.getTypePtr());
6052         if (It == Visited.end()) {
6053           // Try to find the associated user-defined mapper.
6054           CXXScopeSpec MapperIdScopeSpec;
6055           DeclarationNameInfo DefaultMapperId;
6056           DefaultMapperId.setName(S.Context.DeclarationNames.getIdentifier(
6057               &S.Context.Idents.get("default")));
6058           DefaultMapperId.setLoc(E->getExprLoc());
6059           ExprResult ER = buildUserDefinedMapperRef(
6060               S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId,
6061               BaseType, /*UnresolvedMapper=*/nullptr);
6062           if (ER.isInvalid())
6063             continue;
6064           It = Visited.try_emplace(BaseType.getTypePtr(), ER.get()).first;
6065         }
6066         // Found default mapper.
6067         if (It->second) {
6068           auto *OE = new (S.Context) OpaqueValueExpr(E->getExprLoc(), CanonType,
6069                                                      VK_LValue, OK_Ordinary, E);
6070           OE->setIsUnique(/*V=*/true);
6071           Expr *BaseExpr = OE;
6072           for (const auto &P : ParentChain) {
6073             if (P.first) {
6074               BaseExpr = S.BuildMemberExpr(
6075                   BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
6076                   NestedNameSpecifierLoc(), SourceLocation(), P.first,
6077                   DeclAccessPair::make(P.first, P.first->getAccess()),
6078                   /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
6079                   P.first->getType(), VK_LValue, OK_Ordinary);
6080               BaseExpr = S.DefaultLvalueConversion(BaseExpr).get();
6081             }
6082           }
6083           if (CurFD)
6084             BaseExpr = S.BuildMemberExpr(
6085                 BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
6086                 NestedNameSpecifierLoc(), SourceLocation(), CurFD,
6087                 DeclAccessPair::make(CurFD, CurFD->getAccess()),
6088                 /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
6089                 CurFD->getType(), VK_LValue, OK_Ordinary);
6090           SubExprs.push_back(BaseExpr);
6091           continue;
6092         }
6093         // Check for the "default" mapper for data members.
6094         bool FirstIter = true;
6095         for (FieldDecl *FD : RD->fields()) {
6096           if (!FD)
6097             continue;
6098           QualType FieldTy = FD->getType();
6099           if (FieldTy.isNull() ||
6100               !(FieldTy->isStructureOrClassType() || FieldTy->isUnionType()))
6101             continue;
6102           if (FirstIter) {
6103             FirstIter = false;
6104             ParentChain.emplace_back(CurFD, 1);
6105           } else {
6106             ++ParentChain.back().second;
6107           }
6108           Types.emplace_back(FieldTy, FD);
6109         }
6110       }
6111     }
6112     if (SubExprs.empty())
6113       continue;
6114     CXXScopeSpec MapperIdScopeSpec;
6115     DeclarationNameInfo MapperId;
6116     if (OMPClause *NewClause = S.ActOnOpenMPMapClause(
6117             nullptr, C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
6118             MapperIdScopeSpec, MapperId, C->getMapType(),
6119             /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
6120             SubExprs, OMPVarListLocTy()))
6121       Clauses.push_back(NewClause);
6122   }
6123 }
6124 
6125 bool Sema::mapLoopConstruct(llvm::SmallVector<OMPClause *> &ClausesWithoutBind,
6126                             ArrayRef<OMPClause *> Clauses,
6127                             OpenMPBindClauseKind BindKind,
6128                             OpenMPDirectiveKind &Kind,
6129                             OpenMPDirectiveKind &PrevMappedDirective) {
6130 
6131   bool UseClausesWithoutBind = false;
6132 
6133   // Restricting to "#pragma omp loop bind"
6134   if (getLangOpts().OpenMP >= 50 && Kind == OMPD_loop) {
6135     if (BindKind == OMPC_BIND_unknown) {
6136       // Setting the enclosing teams or parallel construct for the loop
6137       // directive without bind clause.
6138       BindKind = OMPC_BIND_thread; // Default bind(thread) if binding is unknown
6139 
6140       const OpenMPDirectiveKind ParentDirective =
6141           DSAStack->getParentDirective();
6142       if (ParentDirective == OMPD_unknown) {
6143         Diag(DSAStack->getDefaultDSALocation(),
6144              diag::err_omp_bind_required_on_loop);
6145       } else if (ParentDirective == OMPD_parallel ||
6146                  ParentDirective == OMPD_target_parallel) {
6147         BindKind = OMPC_BIND_parallel;
6148       } else if (ParentDirective == OMPD_teams ||
6149                  ParentDirective == OMPD_target_teams) {
6150         BindKind = OMPC_BIND_teams;
6151       }
6152     } else {
6153       // bind clause is present, so we should set flag indicating to only
6154       // use the clauses that aren't the bind clause for the new directive that
6155       // loop is lowered to.
6156       UseClausesWithoutBind = true;
6157     }
6158 
6159     for (OMPClause *C : Clauses) {
6160       // Spec restriction : bind(teams) and reduction not permitted.
6161       if (BindKind == OMPC_BIND_teams &&
6162           C->getClauseKind() == llvm::omp::Clause::OMPC_reduction)
6163         Diag(DSAStack->getDefaultDSALocation(),
6164              diag::err_omp_loop_reduction_clause);
6165 
6166       // A new Vector ClausesWithoutBind, which does not contain the bind
6167       // clause, for passing to new directive.
6168       if (C->getClauseKind() != llvm::omp::Clause::OMPC_bind)
6169         ClausesWithoutBind.push_back(C);
6170     }
6171 
6172     switch (BindKind) {
6173     case OMPC_BIND_parallel:
6174       Kind = OMPD_for;
6175       DSAStack->setCurrentDirective(OMPD_for);
6176       DSAStack->setMappedDirective(OMPD_loop);
6177       PrevMappedDirective = OMPD_loop;
6178       break;
6179     case OMPC_BIND_teams:
6180       Kind = OMPD_distribute;
6181       DSAStack->setCurrentDirective(OMPD_distribute);
6182       DSAStack->setMappedDirective(OMPD_loop);
6183       PrevMappedDirective = OMPD_loop;
6184       break;
6185     case OMPC_BIND_thread:
6186       Kind = OMPD_simd;
6187       DSAStack->setCurrentDirective(OMPD_simd);
6188       DSAStack->setMappedDirective(OMPD_loop);
6189       PrevMappedDirective = OMPD_loop;
6190       break;
6191     case OMPC_BIND_unknown:
6192       break;
6193     }
6194   } else if (PrevMappedDirective == OMPD_loop) {
6195     /// An initial pass after recognizing all the statements is done in the
6196     /// Parser when the directive OMPD_loop is mapped to OMPD_for,
6197     /// OMPD_distribute or OMPD_simd. A second transform pass with call from
6198     /// clang::TreeTransform::TransformOMPExecutableDirective() is done
6199     /// with the Directive as one of the above mapped directive without
6200     /// the bind clause. Then "PrevMappedDirective" stored in the
6201     /// OMPExecutableDirective is accessed and hence this else statement.
6202 
6203     DSAStack->setMappedDirective(OMPD_loop);
6204   }
6205 
6206   return UseClausesWithoutBind;
6207 }
6208 
6209 StmtResult Sema::ActOnOpenMPExecutableDirective(
6210     OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
6211     OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
6212     Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc,
6213     OpenMPDirectiveKind PrevMappedDirective) {
6214   StmtResult Res = StmtError();
6215   OpenMPBindClauseKind BindKind = OMPC_BIND_unknown;
6216   if (const OMPBindClause *BC =
6217           OMPExecutableDirective::getSingleClause<OMPBindClause>(Clauses))
6218     BindKind = BC->getBindKind();
6219   // First check CancelRegion which is then used in checkNestingOfRegions.
6220   if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
6221       checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
6222                             BindKind, StartLoc))
6223     return StmtError();
6224 
6225   // Report affected OpenMP target offloading behavior when in HIP lang-mode.
6226   if (getLangOpts().HIP && (isOpenMPTargetExecutionDirective(Kind) ||
6227                             isOpenMPTargetDataManagementDirective(Kind)))
6228     Diag(StartLoc, diag::warn_hip_omp_target_directives);
6229 
6230   llvm::SmallVector<OMPClause *> ClausesWithoutBind;
6231   bool UseClausesWithoutBind = false;
6232 
6233   UseClausesWithoutBind = mapLoopConstruct(ClausesWithoutBind, Clauses,
6234                                            BindKind, Kind, PrevMappedDirective);
6235 
6236   llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
6237   VarsWithInheritedDSAType VarsWithInheritedDSA;
6238   bool ErrorFound = false;
6239   if (getLangOpts().OpenMP >= 50 && UseClausesWithoutBind) {
6240     ClausesWithImplicit.append(ClausesWithoutBind.begin(),
6241                                ClausesWithoutBind.end());
6242   } else {
6243     ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
6244   }
6245   if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic &&
6246       Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master &&
6247       Kind != OMPD_masked && !isOpenMPLoopTransformationDirective(Kind)) {
6248     assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
6249 
6250     // Check default data sharing attributes for referenced variables.
6251     DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
6252     int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
6253     Stmt *S = AStmt;
6254     while (--ThisCaptureLevel >= 0)
6255       S = cast<CapturedStmt>(S)->getCapturedStmt();
6256     DSAChecker.Visit(S);
6257     if (!isOpenMPTargetDataManagementDirective(Kind) &&
6258         !isOpenMPTaskingDirective(Kind)) {
6259       // Visit subcaptures to generate implicit clauses for captured vars.
6260       auto *CS = cast<CapturedStmt>(AStmt);
6261       SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
6262       getOpenMPCaptureRegions(CaptureRegions, Kind);
6263       // Ignore outer tasking regions for target directives.
6264       if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
6265         CS = cast<CapturedStmt>(CS->getCapturedStmt());
6266       DSAChecker.visitSubCaptures(CS);
6267     }
6268     if (DSAChecker.isErrorFound())
6269       return StmtError();
6270     // Generate list of implicitly defined firstprivate variables.
6271     VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
6272 
6273     SmallVector<Expr *, 4> ImplicitFirstprivates(
6274         DSAChecker.getImplicitFirstprivate().begin(),
6275         DSAChecker.getImplicitFirstprivate().end());
6276     SmallVector<Expr *, 4> ImplicitPrivates(
6277         DSAChecker.getImplicitPrivate().begin(),
6278         DSAChecker.getImplicitPrivate().end());
6279     const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_unknown + 1;
6280     SmallVector<Expr *, 4> ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete];
6281     SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
6282         ImplicitMapModifiers[DefaultmapKindNum];
6283     SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers>
6284         ImplicitMapModifiersLoc[DefaultmapKindNum];
6285     // Get the original location of present modifier from Defaultmap clause.
6286     SourceLocation PresentModifierLocs[DefaultmapKindNum];
6287     for (OMPClause *C : Clauses) {
6288       if (auto *DMC = dyn_cast<OMPDefaultmapClause>(C))
6289         if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present)
6290           PresentModifierLocs[DMC->getDefaultmapKind()] =
6291               DMC->getDefaultmapModifierLoc();
6292     }
6293     for (unsigned VC = 0; VC < DefaultmapKindNum; ++VC) {
6294       auto Kind = static_cast<OpenMPDefaultmapClauseKind>(VC);
6295       for (unsigned I = 0; I < OMPC_MAP_delete; ++I) {
6296         ArrayRef<Expr *> ImplicitMap = DSAChecker.getImplicitMap(
6297             Kind, static_cast<OpenMPMapClauseKind>(I));
6298         ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end());
6299       }
6300       ArrayRef<OpenMPMapModifierKind> ImplicitModifier =
6301           DSAChecker.getImplicitMapModifier(Kind);
6302       ImplicitMapModifiers[VC].append(ImplicitModifier.begin(),
6303                                       ImplicitModifier.end());
6304       std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]),
6305                   ImplicitModifier.size(), PresentModifierLocs[VC]);
6306     }
6307     // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
6308     for (OMPClause *C : Clauses) {
6309       if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
6310         for (Expr *E : IRC->taskgroup_descriptors())
6311           if (E)
6312             ImplicitFirstprivates.emplace_back(E);
6313       }
6314       // OpenMP 5.0, 2.10.1 task Construct
6315       // [detach clause]... The event-handle will be considered as if it was
6316       // specified on a firstprivate clause.
6317       if (auto *DC = dyn_cast<OMPDetachClause>(C))
6318         ImplicitFirstprivates.push_back(DC->getEventHandler());
6319     }
6320     if (!ImplicitFirstprivates.empty()) {
6321       if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
6322               ImplicitFirstprivates, SourceLocation(), SourceLocation(),
6323               SourceLocation())) {
6324         ClausesWithImplicit.push_back(Implicit);
6325         ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
6326                      ImplicitFirstprivates.size();
6327       } else {
6328         ErrorFound = true;
6329       }
6330     }
6331     if (!ImplicitPrivates.empty()) {
6332       if (OMPClause *Implicit =
6333               ActOnOpenMPPrivateClause(ImplicitPrivates, SourceLocation(),
6334                                        SourceLocation(), SourceLocation())) {
6335         ClausesWithImplicit.push_back(Implicit);
6336         ErrorFound = cast<OMPPrivateClause>(Implicit)->varlist_size() !=
6337                      ImplicitPrivates.size();
6338       } else {
6339         ErrorFound = true;
6340       }
6341     }
6342     // OpenMP 5.0 [2.19.7]
6343     // If a list item appears in a reduction, lastprivate or linear
6344     // clause on a combined target construct then it is treated as
6345     // if it also appears in a map clause with a map-type of tofrom
6346     if (getLangOpts().OpenMP >= 50 && Kind != OMPD_target &&
6347         isOpenMPTargetExecutionDirective(Kind)) {
6348       SmallVector<Expr *, 4> ImplicitExprs;
6349       for (OMPClause *C : Clauses) {
6350         if (auto *RC = dyn_cast<OMPReductionClause>(C))
6351           for (Expr *E : RC->varlists())
6352             if (!isa<DeclRefExpr>(E->IgnoreParenImpCasts()))
6353               ImplicitExprs.emplace_back(E);
6354       }
6355       if (!ImplicitExprs.empty()) {
6356         ArrayRef<Expr *> Exprs = ImplicitExprs;
6357         CXXScopeSpec MapperIdScopeSpec;
6358         DeclarationNameInfo MapperId;
6359         if (OMPClause *Implicit = ActOnOpenMPMapClause(
6360                 nullptr, OMPC_MAP_MODIFIER_unknown, SourceLocation(),
6361                 MapperIdScopeSpec, MapperId, OMPC_MAP_tofrom,
6362                 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
6363                 Exprs, OMPVarListLocTy(), /*NoDiagnose=*/true))
6364           ClausesWithImplicit.emplace_back(Implicit);
6365       }
6366     }
6367     for (unsigned I = 0, E = DefaultmapKindNum; I < E; ++I) {
6368       int ClauseKindCnt = -1;
6369       for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps[I]) {
6370         ++ClauseKindCnt;
6371         if (ImplicitMap.empty())
6372           continue;
6373         CXXScopeSpec MapperIdScopeSpec;
6374         DeclarationNameInfo MapperId;
6375         auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
6376         if (OMPClause *Implicit = ActOnOpenMPMapClause(
6377                 nullptr, ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I],
6378                 MapperIdScopeSpec, MapperId, Kind, /*IsMapTypeImplicit=*/true,
6379                 SourceLocation(), SourceLocation(), ImplicitMap,
6380                 OMPVarListLocTy())) {
6381           ClausesWithImplicit.emplace_back(Implicit);
6382           ErrorFound |= cast<OMPMapClause>(Implicit)->varlist_size() !=
6383                         ImplicitMap.size();
6384         } else {
6385           ErrorFound = true;
6386         }
6387       }
6388     }
6389     // Build expressions for implicit maps of data members with 'default'
6390     // mappers.
6391     if (LangOpts.OpenMP >= 50)
6392       processImplicitMapsWithDefaultMappers(*this, DSAStack,
6393                                             ClausesWithImplicit);
6394   }
6395 
6396   llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
6397   switch (Kind) {
6398   case OMPD_parallel:
6399     Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
6400                                        EndLoc);
6401     AllowedNameModifiers.push_back(OMPD_parallel);
6402     break;
6403   case OMPD_simd:
6404     Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
6405                                    VarsWithInheritedDSA);
6406     if (LangOpts.OpenMP >= 50)
6407       AllowedNameModifiers.push_back(OMPD_simd);
6408     break;
6409   case OMPD_tile:
6410     Res =
6411         ActOnOpenMPTileDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6412     break;
6413   case OMPD_unroll:
6414     Res = ActOnOpenMPUnrollDirective(ClausesWithImplicit, AStmt, StartLoc,
6415                                      EndLoc);
6416     break;
6417   case OMPD_for:
6418     Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
6419                                   VarsWithInheritedDSA);
6420     break;
6421   case OMPD_for_simd:
6422     Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6423                                       EndLoc, VarsWithInheritedDSA);
6424     if (LangOpts.OpenMP >= 50)
6425       AllowedNameModifiers.push_back(OMPD_simd);
6426     break;
6427   case OMPD_sections:
6428     Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
6429                                        EndLoc);
6430     break;
6431   case OMPD_section:
6432     assert(ClausesWithImplicit.empty() &&
6433            "No clauses are allowed for 'omp section' directive");
6434     Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
6435     break;
6436   case OMPD_single:
6437     Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
6438                                      EndLoc);
6439     break;
6440   case OMPD_master:
6441     assert(ClausesWithImplicit.empty() &&
6442            "No clauses are allowed for 'omp master' directive");
6443     Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
6444     break;
6445   case OMPD_masked:
6446     Res = ActOnOpenMPMaskedDirective(ClausesWithImplicit, AStmt, StartLoc,
6447                                      EndLoc);
6448     break;
6449   case OMPD_critical:
6450     Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
6451                                        StartLoc, EndLoc);
6452     break;
6453   case OMPD_parallel_for:
6454     Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
6455                                           EndLoc, VarsWithInheritedDSA);
6456     AllowedNameModifiers.push_back(OMPD_parallel);
6457     break;
6458   case OMPD_parallel_for_simd:
6459     Res = ActOnOpenMPParallelForSimdDirective(
6460         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6461     AllowedNameModifiers.push_back(OMPD_parallel);
6462     if (LangOpts.OpenMP >= 50)
6463       AllowedNameModifiers.push_back(OMPD_simd);
6464     break;
6465   case OMPD_scope:
6466     Res =
6467         ActOnOpenMPScopeDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6468     break;
6469   case OMPD_parallel_master:
6470     Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
6471                                              StartLoc, EndLoc);
6472     AllowedNameModifiers.push_back(OMPD_parallel);
6473     break;
6474   case OMPD_parallel_masked:
6475     Res = ActOnOpenMPParallelMaskedDirective(ClausesWithImplicit, AStmt,
6476                                              StartLoc, EndLoc);
6477     AllowedNameModifiers.push_back(OMPD_parallel);
6478     break;
6479   case OMPD_parallel_sections:
6480     Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
6481                                                StartLoc, EndLoc);
6482     AllowedNameModifiers.push_back(OMPD_parallel);
6483     break;
6484   case OMPD_task:
6485     Res =
6486         ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6487     AllowedNameModifiers.push_back(OMPD_task);
6488     break;
6489   case OMPD_taskyield:
6490     assert(ClausesWithImplicit.empty() &&
6491            "No clauses are allowed for 'omp taskyield' directive");
6492     assert(AStmt == nullptr &&
6493            "No associated statement allowed for 'omp taskyield' directive");
6494     Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
6495     break;
6496   case OMPD_error:
6497     assert(AStmt == nullptr &&
6498            "No associated statement allowed for 'omp error' directive");
6499     Res = ActOnOpenMPErrorDirective(ClausesWithImplicit, StartLoc, EndLoc);
6500     break;
6501   case OMPD_barrier:
6502     assert(ClausesWithImplicit.empty() &&
6503            "No clauses are allowed for 'omp barrier' directive");
6504     assert(AStmt == nullptr &&
6505            "No associated statement allowed for 'omp barrier' directive");
6506     Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
6507     break;
6508   case OMPD_taskwait:
6509     assert(AStmt == nullptr &&
6510            "No associated statement allowed for 'omp taskwait' directive");
6511     Res = ActOnOpenMPTaskwaitDirective(ClausesWithImplicit, StartLoc, EndLoc);
6512     break;
6513   case OMPD_taskgroup:
6514     Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
6515                                         EndLoc);
6516     break;
6517   case OMPD_flush:
6518     assert(AStmt == nullptr &&
6519            "No associated statement allowed for 'omp flush' directive");
6520     Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
6521     break;
6522   case OMPD_depobj:
6523     assert(AStmt == nullptr &&
6524            "No associated statement allowed for 'omp depobj' directive");
6525     Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc);
6526     break;
6527   case OMPD_scan:
6528     assert(AStmt == nullptr &&
6529            "No associated statement allowed for 'omp scan' directive");
6530     Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc);
6531     break;
6532   case OMPD_ordered:
6533     Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
6534                                       EndLoc);
6535     break;
6536   case OMPD_atomic:
6537     Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
6538                                      EndLoc);
6539     break;
6540   case OMPD_teams:
6541     Res =
6542         ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6543     break;
6544   case OMPD_target:
6545     Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
6546                                      EndLoc);
6547     AllowedNameModifiers.push_back(OMPD_target);
6548     break;
6549   case OMPD_target_parallel:
6550     Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
6551                                              StartLoc, EndLoc);
6552     AllowedNameModifiers.push_back(OMPD_target);
6553     AllowedNameModifiers.push_back(OMPD_parallel);
6554     break;
6555   case OMPD_target_parallel_for:
6556     Res = ActOnOpenMPTargetParallelForDirective(
6557         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6558     AllowedNameModifiers.push_back(OMPD_target);
6559     AllowedNameModifiers.push_back(OMPD_parallel);
6560     break;
6561   case OMPD_cancellation_point:
6562     assert(ClausesWithImplicit.empty() &&
6563            "No clauses are allowed for 'omp cancellation point' directive");
6564     assert(AStmt == nullptr && "No associated statement allowed for 'omp "
6565                                "cancellation point' directive");
6566     Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
6567     break;
6568   case OMPD_cancel:
6569     assert(AStmt == nullptr &&
6570            "No associated statement allowed for 'omp cancel' directive");
6571     Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
6572                                      CancelRegion);
6573     AllowedNameModifiers.push_back(OMPD_cancel);
6574     break;
6575   case OMPD_target_data:
6576     Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
6577                                          EndLoc);
6578     AllowedNameModifiers.push_back(OMPD_target_data);
6579     break;
6580   case OMPD_target_enter_data:
6581     Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
6582                                               EndLoc, AStmt);
6583     AllowedNameModifiers.push_back(OMPD_target_enter_data);
6584     break;
6585   case OMPD_target_exit_data:
6586     Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
6587                                              EndLoc, AStmt);
6588     AllowedNameModifiers.push_back(OMPD_target_exit_data);
6589     break;
6590   case OMPD_taskloop:
6591     Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
6592                                        EndLoc, VarsWithInheritedDSA);
6593     AllowedNameModifiers.push_back(OMPD_taskloop);
6594     break;
6595   case OMPD_taskloop_simd:
6596     Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6597                                            EndLoc, VarsWithInheritedDSA);
6598     AllowedNameModifiers.push_back(OMPD_taskloop);
6599     if (LangOpts.OpenMP >= 50)
6600       AllowedNameModifiers.push_back(OMPD_simd);
6601     break;
6602   case OMPD_master_taskloop:
6603     Res = ActOnOpenMPMasterTaskLoopDirective(
6604         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6605     AllowedNameModifiers.push_back(OMPD_taskloop);
6606     break;
6607   case OMPD_masked_taskloop:
6608     Res = ActOnOpenMPMaskedTaskLoopDirective(
6609         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6610     AllowedNameModifiers.push_back(OMPD_taskloop);
6611     break;
6612   case OMPD_master_taskloop_simd:
6613     Res = ActOnOpenMPMasterTaskLoopSimdDirective(
6614         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6615     AllowedNameModifiers.push_back(OMPD_taskloop);
6616     if (LangOpts.OpenMP >= 50)
6617       AllowedNameModifiers.push_back(OMPD_simd);
6618     break;
6619   case OMPD_masked_taskloop_simd:
6620     Res = ActOnOpenMPMaskedTaskLoopSimdDirective(
6621         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6622     if (LangOpts.OpenMP >= 51) {
6623       AllowedNameModifiers.push_back(OMPD_taskloop);
6624       AllowedNameModifiers.push_back(OMPD_simd);
6625     }
6626     break;
6627   case OMPD_parallel_master_taskloop:
6628     Res = ActOnOpenMPParallelMasterTaskLoopDirective(
6629         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6630     AllowedNameModifiers.push_back(OMPD_taskloop);
6631     AllowedNameModifiers.push_back(OMPD_parallel);
6632     break;
6633   case OMPD_parallel_masked_taskloop:
6634     Res = ActOnOpenMPParallelMaskedTaskLoopDirective(
6635         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6636     if (LangOpts.OpenMP >= 51) {
6637       AllowedNameModifiers.push_back(OMPD_taskloop);
6638       AllowedNameModifiers.push_back(OMPD_parallel);
6639     }
6640     break;
6641   case OMPD_parallel_master_taskloop_simd:
6642     Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective(
6643         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6644     AllowedNameModifiers.push_back(OMPD_taskloop);
6645     AllowedNameModifiers.push_back(OMPD_parallel);
6646     if (LangOpts.OpenMP >= 50)
6647       AllowedNameModifiers.push_back(OMPD_simd);
6648     break;
6649   case OMPD_parallel_masked_taskloop_simd:
6650     Res = ActOnOpenMPParallelMaskedTaskLoopSimdDirective(
6651         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6652     if (LangOpts.OpenMP >= 51) {
6653       AllowedNameModifiers.push_back(OMPD_taskloop);
6654       AllowedNameModifiers.push_back(OMPD_parallel);
6655       AllowedNameModifiers.push_back(OMPD_simd);
6656     }
6657     break;
6658   case OMPD_distribute:
6659     Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
6660                                          EndLoc, VarsWithInheritedDSA);
6661     break;
6662   case OMPD_target_update:
6663     Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
6664                                            EndLoc, AStmt);
6665     AllowedNameModifiers.push_back(OMPD_target_update);
6666     break;
6667   case OMPD_distribute_parallel_for:
6668     Res = ActOnOpenMPDistributeParallelForDirective(
6669         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6670     AllowedNameModifiers.push_back(OMPD_parallel);
6671     break;
6672   case OMPD_distribute_parallel_for_simd:
6673     Res = ActOnOpenMPDistributeParallelForSimdDirective(
6674         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6675     AllowedNameModifiers.push_back(OMPD_parallel);
6676     if (LangOpts.OpenMP >= 50)
6677       AllowedNameModifiers.push_back(OMPD_simd);
6678     break;
6679   case OMPD_distribute_simd:
6680     Res = ActOnOpenMPDistributeSimdDirective(
6681         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6682     if (LangOpts.OpenMP >= 50)
6683       AllowedNameModifiers.push_back(OMPD_simd);
6684     break;
6685   case OMPD_target_parallel_for_simd:
6686     Res = ActOnOpenMPTargetParallelForSimdDirective(
6687         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6688     AllowedNameModifiers.push_back(OMPD_target);
6689     AllowedNameModifiers.push_back(OMPD_parallel);
6690     if (LangOpts.OpenMP >= 50)
6691       AllowedNameModifiers.push_back(OMPD_simd);
6692     break;
6693   case OMPD_target_simd:
6694     Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6695                                          EndLoc, VarsWithInheritedDSA);
6696     AllowedNameModifiers.push_back(OMPD_target);
6697     if (LangOpts.OpenMP >= 50)
6698       AllowedNameModifiers.push_back(OMPD_simd);
6699     break;
6700   case OMPD_teams_distribute:
6701     Res = ActOnOpenMPTeamsDistributeDirective(
6702         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6703     break;
6704   case OMPD_teams_distribute_simd:
6705     Res = ActOnOpenMPTeamsDistributeSimdDirective(
6706         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6707     if (LangOpts.OpenMP >= 50)
6708       AllowedNameModifiers.push_back(OMPD_simd);
6709     break;
6710   case OMPD_teams_distribute_parallel_for_simd:
6711     Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
6712         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6713     AllowedNameModifiers.push_back(OMPD_parallel);
6714     if (LangOpts.OpenMP >= 50)
6715       AllowedNameModifiers.push_back(OMPD_simd);
6716     break;
6717   case OMPD_teams_distribute_parallel_for:
6718     Res = ActOnOpenMPTeamsDistributeParallelForDirective(
6719         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6720     AllowedNameModifiers.push_back(OMPD_parallel);
6721     break;
6722   case OMPD_target_teams:
6723     Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
6724                                           EndLoc);
6725     AllowedNameModifiers.push_back(OMPD_target);
6726     break;
6727   case OMPD_target_teams_distribute:
6728     Res = ActOnOpenMPTargetTeamsDistributeDirective(
6729         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6730     AllowedNameModifiers.push_back(OMPD_target);
6731     break;
6732   case OMPD_target_teams_distribute_parallel_for:
6733     Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
6734         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6735     AllowedNameModifiers.push_back(OMPD_target);
6736     AllowedNameModifiers.push_back(OMPD_parallel);
6737     break;
6738   case OMPD_target_teams_distribute_parallel_for_simd:
6739     Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
6740         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6741     AllowedNameModifiers.push_back(OMPD_target);
6742     AllowedNameModifiers.push_back(OMPD_parallel);
6743     if (LangOpts.OpenMP >= 50)
6744       AllowedNameModifiers.push_back(OMPD_simd);
6745     break;
6746   case OMPD_target_teams_distribute_simd:
6747     Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
6748         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6749     AllowedNameModifiers.push_back(OMPD_target);
6750     if (LangOpts.OpenMP >= 50)
6751       AllowedNameModifiers.push_back(OMPD_simd);
6752     break;
6753   case OMPD_interop:
6754     assert(AStmt == nullptr &&
6755            "No associated statement allowed for 'omp interop' directive");
6756     Res = ActOnOpenMPInteropDirective(ClausesWithImplicit, StartLoc, EndLoc);
6757     break;
6758   case OMPD_dispatch:
6759     Res = ActOnOpenMPDispatchDirective(ClausesWithImplicit, AStmt, StartLoc,
6760                                        EndLoc);
6761     break;
6762   case OMPD_loop:
6763     Res = ActOnOpenMPGenericLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
6764                                           EndLoc, VarsWithInheritedDSA);
6765     break;
6766   case OMPD_teams_loop:
6767     Res = ActOnOpenMPTeamsGenericLoopDirective(
6768         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6769     break;
6770   case OMPD_target_teams_loop:
6771     Res = ActOnOpenMPTargetTeamsGenericLoopDirective(
6772         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6773     AllowedNameModifiers.push_back(OMPD_target);
6774     break;
6775   case OMPD_parallel_loop:
6776     Res = ActOnOpenMPParallelGenericLoopDirective(
6777         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6778     break;
6779   case OMPD_target_parallel_loop:
6780     Res = ActOnOpenMPTargetParallelGenericLoopDirective(
6781         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6782     break;
6783   case OMPD_declare_target:
6784   case OMPD_end_declare_target:
6785   case OMPD_threadprivate:
6786   case OMPD_allocate:
6787   case OMPD_declare_reduction:
6788   case OMPD_declare_mapper:
6789   case OMPD_declare_simd:
6790   case OMPD_requires:
6791   case OMPD_declare_variant:
6792   case OMPD_begin_declare_variant:
6793   case OMPD_end_declare_variant:
6794     llvm_unreachable("OpenMP Directive is not allowed");
6795   case OMPD_unknown:
6796   default:
6797     llvm_unreachable("Unknown OpenMP directive");
6798   }
6799 
6800   ErrorFound = Res.isInvalid() || ErrorFound;
6801 
6802   // Check variables in the clauses if default(none) or
6803   // default(firstprivate) was specified.
6804   if (DSAStack->getDefaultDSA() == DSA_none ||
6805       DSAStack->getDefaultDSA() == DSA_private ||
6806       DSAStack->getDefaultDSA() == DSA_firstprivate) {
6807     DSAAttrChecker DSAChecker(DSAStack, *this, nullptr);
6808     for (OMPClause *C : Clauses) {
6809       switch (C->getClauseKind()) {
6810       case OMPC_num_threads:
6811       case OMPC_dist_schedule:
6812         // Do not analyse if no parent teams directive.
6813         if (isOpenMPTeamsDirective(Kind))
6814           break;
6815         continue;
6816       case OMPC_if:
6817         if (isOpenMPTeamsDirective(Kind) &&
6818             cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
6819           break;
6820         if (isOpenMPParallelDirective(Kind) &&
6821             isOpenMPTaskLoopDirective(Kind) &&
6822             cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel)
6823           break;
6824         continue;
6825       case OMPC_schedule:
6826       case OMPC_detach:
6827         break;
6828       case OMPC_grainsize:
6829       case OMPC_num_tasks:
6830       case OMPC_final:
6831       case OMPC_priority:
6832       case OMPC_novariants:
6833       case OMPC_nocontext:
6834         // Do not analyze if no parent parallel directive.
6835         if (isOpenMPParallelDirective(Kind))
6836           break;
6837         continue;
6838       case OMPC_ordered:
6839       case OMPC_device:
6840       case OMPC_num_teams:
6841       case OMPC_thread_limit:
6842       case OMPC_hint:
6843       case OMPC_collapse:
6844       case OMPC_safelen:
6845       case OMPC_simdlen:
6846       case OMPC_sizes:
6847       case OMPC_default:
6848       case OMPC_proc_bind:
6849       case OMPC_private:
6850       case OMPC_firstprivate:
6851       case OMPC_lastprivate:
6852       case OMPC_shared:
6853       case OMPC_reduction:
6854       case OMPC_task_reduction:
6855       case OMPC_in_reduction:
6856       case OMPC_linear:
6857       case OMPC_aligned:
6858       case OMPC_copyin:
6859       case OMPC_copyprivate:
6860       case OMPC_nowait:
6861       case OMPC_untied:
6862       case OMPC_mergeable:
6863       case OMPC_allocate:
6864       case OMPC_read:
6865       case OMPC_write:
6866       case OMPC_update:
6867       case OMPC_capture:
6868       case OMPC_compare:
6869       case OMPC_seq_cst:
6870       case OMPC_acq_rel:
6871       case OMPC_acquire:
6872       case OMPC_release:
6873       case OMPC_relaxed:
6874       case OMPC_depend:
6875       case OMPC_threads:
6876       case OMPC_simd:
6877       case OMPC_map:
6878       case OMPC_nogroup:
6879       case OMPC_defaultmap:
6880       case OMPC_to:
6881       case OMPC_from:
6882       case OMPC_use_device_ptr:
6883       case OMPC_use_device_addr:
6884       case OMPC_is_device_ptr:
6885       case OMPC_has_device_addr:
6886       case OMPC_nontemporal:
6887       case OMPC_order:
6888       case OMPC_destroy:
6889       case OMPC_inclusive:
6890       case OMPC_exclusive:
6891       case OMPC_uses_allocators:
6892       case OMPC_affinity:
6893       case OMPC_bind:
6894       case OMPC_filter:
6895         continue;
6896       case OMPC_allocator:
6897       case OMPC_flush:
6898       case OMPC_depobj:
6899       case OMPC_threadprivate:
6900       case OMPC_uniform:
6901       case OMPC_unknown:
6902       case OMPC_unified_address:
6903       case OMPC_unified_shared_memory:
6904       case OMPC_reverse_offload:
6905       case OMPC_dynamic_allocators:
6906       case OMPC_atomic_default_mem_order:
6907       case OMPC_device_type:
6908       case OMPC_match:
6909       case OMPC_when:
6910       case OMPC_at:
6911       case OMPC_severity:
6912       case OMPC_message:
6913       default:
6914         llvm_unreachable("Unexpected clause");
6915       }
6916       for (Stmt *CC : C->children()) {
6917         if (CC)
6918           DSAChecker.Visit(CC);
6919       }
6920     }
6921     for (const auto &P : DSAChecker.getVarsWithInheritedDSA())
6922       VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
6923   }
6924   for (const auto &P : VarsWithInheritedDSA) {
6925     if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
6926       continue;
6927     ErrorFound = true;
6928     if (DSAStack->getDefaultDSA() == DSA_none ||
6929         DSAStack->getDefaultDSA() == DSA_private ||
6930         DSAStack->getDefaultDSA() == DSA_firstprivate) {
6931       Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
6932           << P.first << P.second->getSourceRange();
6933       Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
6934     } else if (getLangOpts().OpenMP >= 50) {
6935       Diag(P.second->getExprLoc(),
6936            diag::err_omp_defaultmap_no_attr_for_variable)
6937           << P.first << P.second->getSourceRange();
6938       Diag(DSAStack->getDefaultDSALocation(),
6939            diag::note_omp_defaultmap_attr_none);
6940     }
6941   }
6942 
6943   if (!AllowedNameModifiers.empty())
6944     ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
6945                  ErrorFound;
6946 
6947   if (ErrorFound)
6948     return StmtError();
6949 
6950   if (!CurContext->isDependentContext() &&
6951       isOpenMPTargetExecutionDirective(Kind) &&
6952       !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
6953         DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
6954         DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
6955         DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
6956     // Register target to DSA Stack.
6957     DSAStack->addTargetDirLocation(StartLoc);
6958   }
6959 
6960   return Res;
6961 }
6962 
6963 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
6964     DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
6965     ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
6966     ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
6967     ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
6968   assert(Aligneds.size() == Alignments.size());
6969   assert(Linears.size() == LinModifiers.size());
6970   assert(Linears.size() == Steps.size());
6971   if (!DG || DG.get().isNull())
6972     return DeclGroupPtrTy();
6973 
6974   const int SimdId = 0;
6975   if (!DG.get().isSingleDecl()) {
6976     Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
6977         << SimdId;
6978     return DG;
6979   }
6980   Decl *ADecl = DG.get().getSingleDecl();
6981   if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
6982     ADecl = FTD->getTemplatedDecl();
6983 
6984   auto *FD = dyn_cast<FunctionDecl>(ADecl);
6985   if (!FD) {
6986     Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId;
6987     return DeclGroupPtrTy();
6988   }
6989 
6990   // OpenMP [2.8.2, declare simd construct, Description]
6991   // The parameter of the simdlen clause must be a constant positive integer
6992   // expression.
6993   ExprResult SL;
6994   if (Simdlen)
6995     SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
6996   // OpenMP [2.8.2, declare simd construct, Description]
6997   // The special this pointer can be used as if was one of the arguments to the
6998   // function in any of the linear, aligned, or uniform clauses.
6999   // The uniform clause declares one or more arguments to have an invariant
7000   // value for all concurrent invocations of the function in the execution of a
7001   // single SIMD loop.
7002   llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
7003   const Expr *UniformedLinearThis = nullptr;
7004   for (const Expr *E : Uniforms) {
7005     E = E->IgnoreParenImpCasts();
7006     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
7007       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
7008         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
7009             FD->getParamDecl(PVD->getFunctionScopeIndex())
7010                     ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
7011           UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
7012           continue;
7013         }
7014     if (isa<CXXThisExpr>(E)) {
7015       UniformedLinearThis = E;
7016       continue;
7017     }
7018     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
7019         << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
7020   }
7021   // OpenMP [2.8.2, declare simd construct, Description]
7022   // The aligned clause declares that the object to which each list item points
7023   // is aligned to the number of bytes expressed in the optional parameter of
7024   // the aligned clause.
7025   // The special this pointer can be used as if was one of the arguments to the
7026   // function in any of the linear, aligned, or uniform clauses.
7027   // The type of list items appearing in the aligned clause must be array,
7028   // pointer, reference to array, or reference to pointer.
7029   llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
7030   const Expr *AlignedThis = nullptr;
7031   for (const Expr *E : Aligneds) {
7032     E = E->IgnoreParenImpCasts();
7033     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
7034       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7035         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
7036         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
7037             FD->getParamDecl(PVD->getFunctionScopeIndex())
7038                     ->getCanonicalDecl() == CanonPVD) {
7039           // OpenMP  [2.8.1, simd construct, Restrictions]
7040           // A list-item cannot appear in more than one aligned clause.
7041           if (AlignedArgs.count(CanonPVD) > 0) {
7042             Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
7043                 << 1 << getOpenMPClauseName(OMPC_aligned)
7044                 << E->getSourceRange();
7045             Diag(AlignedArgs[CanonPVD]->getExprLoc(),
7046                  diag::note_omp_explicit_dsa)
7047                 << getOpenMPClauseName(OMPC_aligned);
7048             continue;
7049           }
7050           AlignedArgs[CanonPVD] = E;
7051           QualType QTy = PVD->getType()
7052                              .getNonReferenceType()
7053                              .getUnqualifiedType()
7054                              .getCanonicalType();
7055           const Type *Ty = QTy.getTypePtrOrNull();
7056           if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
7057             Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
7058                 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
7059             Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
7060           }
7061           continue;
7062         }
7063       }
7064     if (isa<CXXThisExpr>(E)) {
7065       if (AlignedThis) {
7066         Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
7067             << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange();
7068         Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
7069             << getOpenMPClauseName(OMPC_aligned);
7070       }
7071       AlignedThis = E;
7072       continue;
7073     }
7074     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
7075         << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
7076   }
7077   // The optional parameter of the aligned clause, alignment, must be a constant
7078   // positive integer expression. If no optional parameter is specified,
7079   // implementation-defined default alignments for SIMD instructions on the
7080   // target platforms are assumed.
7081   SmallVector<const Expr *, 4> NewAligns;
7082   for (Expr *E : Alignments) {
7083     ExprResult Align;
7084     if (E)
7085       Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
7086     NewAligns.push_back(Align.get());
7087   }
7088   // OpenMP [2.8.2, declare simd construct, Description]
7089   // The linear clause declares one or more list items to be private to a SIMD
7090   // lane and to have a linear relationship with respect to the iteration space
7091   // of a loop.
7092   // The special this pointer can be used as if was one of the arguments to the
7093   // function in any of the linear, aligned, or uniform clauses.
7094   // When a linear-step expression is specified in a linear clause it must be
7095   // either a constant integer expression or an integer-typed parameter that is
7096   // specified in a uniform clause on the directive.
7097   llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
7098   const bool IsUniformedThis = UniformedLinearThis != nullptr;
7099   auto MI = LinModifiers.begin();
7100   for (const Expr *E : Linears) {
7101     auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
7102     ++MI;
7103     E = E->IgnoreParenImpCasts();
7104     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
7105       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7106         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
7107         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
7108             FD->getParamDecl(PVD->getFunctionScopeIndex())
7109                     ->getCanonicalDecl() == CanonPVD) {
7110           // OpenMP  [2.15.3.7, linear Clause, Restrictions]
7111           // A list-item cannot appear in more than one linear clause.
7112           if (LinearArgs.count(CanonPVD) > 0) {
7113             Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
7114                 << getOpenMPClauseName(OMPC_linear)
7115                 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
7116             Diag(LinearArgs[CanonPVD]->getExprLoc(),
7117                  diag::note_omp_explicit_dsa)
7118                 << getOpenMPClauseName(OMPC_linear);
7119             continue;
7120           }
7121           // Each argument can appear in at most one uniform or linear clause.
7122           if (UniformedArgs.count(CanonPVD) > 0) {
7123             Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
7124                 << getOpenMPClauseName(OMPC_linear)
7125                 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
7126             Diag(UniformedArgs[CanonPVD]->getExprLoc(),
7127                  diag::note_omp_explicit_dsa)
7128                 << getOpenMPClauseName(OMPC_uniform);
7129             continue;
7130           }
7131           LinearArgs[CanonPVD] = E;
7132           if (E->isValueDependent() || E->isTypeDependent() ||
7133               E->isInstantiationDependent() ||
7134               E->containsUnexpandedParameterPack())
7135             continue;
7136           (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
7137                                       PVD->getOriginalType(),
7138                                       /*IsDeclareSimd=*/true);
7139           continue;
7140         }
7141       }
7142     if (isa<CXXThisExpr>(E)) {
7143       if (UniformedLinearThis) {
7144         Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
7145             << getOpenMPClauseName(OMPC_linear)
7146             << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
7147             << E->getSourceRange();
7148         Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
7149             << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
7150                                                    : OMPC_linear);
7151         continue;
7152       }
7153       UniformedLinearThis = E;
7154       if (E->isValueDependent() || E->isTypeDependent() ||
7155           E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
7156         continue;
7157       (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
7158                                   E->getType(), /*IsDeclareSimd=*/true);
7159       continue;
7160     }
7161     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
7162         << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
7163   }
7164   Expr *Step = nullptr;
7165   Expr *NewStep = nullptr;
7166   SmallVector<Expr *, 4> NewSteps;
7167   for (Expr *E : Steps) {
7168     // Skip the same step expression, it was checked already.
7169     if (Step == E || !E) {
7170       NewSteps.push_back(E ? NewStep : nullptr);
7171       continue;
7172     }
7173     Step = E;
7174     if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
7175       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7176         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
7177         if (UniformedArgs.count(CanonPVD) == 0) {
7178           Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
7179               << Step->getSourceRange();
7180         } else if (E->isValueDependent() || E->isTypeDependent() ||
7181                    E->isInstantiationDependent() ||
7182                    E->containsUnexpandedParameterPack() ||
7183                    CanonPVD->getType()->hasIntegerRepresentation()) {
7184           NewSteps.push_back(Step);
7185         } else {
7186           Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
7187               << Step->getSourceRange();
7188         }
7189         continue;
7190       }
7191     NewStep = Step;
7192     if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
7193         !Step->isInstantiationDependent() &&
7194         !Step->containsUnexpandedParameterPack()) {
7195       NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
7196                     .get();
7197       if (NewStep)
7198         NewStep =
7199             VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get();
7200     }
7201     NewSteps.push_back(NewStep);
7202   }
7203   auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
7204       Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
7205       Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
7206       const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
7207       const_cast<Expr **>(Linears.data()), Linears.size(),
7208       const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
7209       NewSteps.data(), NewSteps.size(), SR);
7210   ADecl->addAttr(NewAttr);
7211   return DG;
7212 }
7213 
7214 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
7215                          QualType NewType) {
7216   assert(NewType->isFunctionProtoType() &&
7217          "Expected function type with prototype.");
7218   assert(FD->getType()->isFunctionNoProtoType() &&
7219          "Expected function with type with no prototype.");
7220   assert(FDWithProto->getType()->isFunctionProtoType() &&
7221          "Expected function with prototype.");
7222   // Synthesize parameters with the same types.
7223   FD->setType(NewType);
7224   SmallVector<ParmVarDecl *, 16> Params;
7225   for (const ParmVarDecl *P : FDWithProto->parameters()) {
7226     auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(),
7227                                       SourceLocation(), nullptr, P->getType(),
7228                                       /*TInfo=*/nullptr, SC_None, nullptr);
7229     Param->setScopeInfo(0, Params.size());
7230     Param->setImplicit();
7231     Params.push_back(Param);
7232   }
7233 
7234   FD->setParams(Params);
7235 }
7236 
7237 void Sema::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D) {
7238   if (D->isInvalidDecl())
7239     return;
7240   FunctionDecl *FD = nullptr;
7241   if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
7242     FD = UTemplDecl->getTemplatedDecl();
7243   else
7244     FD = cast<FunctionDecl>(D);
7245   assert(FD && "Expected a function declaration!");
7246 
7247   // If we are instantiating templates we do *not* apply scoped assumptions but
7248   // only global ones. We apply scoped assumption to the template definition
7249   // though.
7250   if (!inTemplateInstantiation()) {
7251     for (AssumptionAttr *AA : OMPAssumeScoped)
7252       FD->addAttr(AA);
7253   }
7254   for (AssumptionAttr *AA : OMPAssumeGlobal)
7255     FD->addAttr(AA);
7256 }
7257 
7258 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI)
7259     : TI(&TI), NameSuffix(TI.getMangledName()) {}
7260 
7261 void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(
7262     Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists,
7263     SmallVectorImpl<FunctionDecl *> &Bases) {
7264   if (!D.getIdentifier())
7265     return;
7266 
7267   OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
7268 
7269   // Template specialization is an extension, check if we do it.
7270   bool IsTemplated = !TemplateParamLists.empty();
7271   if (IsTemplated &
7272       !DVScope.TI->isExtensionActive(
7273           llvm::omp::TraitProperty::implementation_extension_allow_templates))
7274     return;
7275 
7276   IdentifierInfo *BaseII = D.getIdentifier();
7277   LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(),
7278                       LookupOrdinaryName);
7279   LookupParsedName(Lookup, S, &D.getCXXScopeSpec());
7280 
7281   TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
7282   QualType FType = TInfo->getType();
7283 
7284   bool IsConstexpr =
7285       D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr;
7286   bool IsConsteval =
7287       D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Consteval;
7288 
7289   for (auto *Candidate : Lookup) {
7290     auto *CandidateDecl = Candidate->getUnderlyingDecl();
7291     FunctionDecl *UDecl = nullptr;
7292     if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl)) {
7293       auto *FTD = cast<FunctionTemplateDecl>(CandidateDecl);
7294       if (FTD->getTemplateParameters()->size() == TemplateParamLists.size())
7295         UDecl = FTD->getTemplatedDecl();
7296     } else if (!IsTemplated)
7297       UDecl = dyn_cast<FunctionDecl>(CandidateDecl);
7298     if (!UDecl)
7299       continue;
7300 
7301     // Don't specialize constexpr/consteval functions with
7302     // non-constexpr/consteval functions.
7303     if (UDecl->isConstexpr() && !IsConstexpr)
7304       continue;
7305     if (UDecl->isConsteval() && !IsConsteval)
7306       continue;
7307 
7308     QualType UDeclTy = UDecl->getType();
7309     if (!UDeclTy->isDependentType()) {
7310       QualType NewType = Context.mergeFunctionTypes(
7311           FType, UDeclTy, /* OfBlockPointer */ false,
7312           /* Unqualified */ false, /* AllowCXX */ true);
7313       if (NewType.isNull())
7314         continue;
7315     }
7316 
7317     // Found a base!
7318     Bases.push_back(UDecl);
7319   }
7320 
7321   bool UseImplicitBase = !DVScope.TI->isExtensionActive(
7322       llvm::omp::TraitProperty::implementation_extension_disable_implicit_base);
7323   // If no base was found we create a declaration that we use as base.
7324   if (Bases.empty() && UseImplicitBase) {
7325     D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration);
7326     Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists);
7327     BaseD->setImplicit(true);
7328     if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD))
7329       Bases.push_back(BaseTemplD->getTemplatedDecl());
7330     else
7331       Bases.push_back(cast<FunctionDecl>(BaseD));
7332   }
7333 
7334   std::string MangledName;
7335   MangledName += D.getIdentifier()->getName();
7336   MangledName += getOpenMPVariantManglingSeparatorStr();
7337   MangledName += DVScope.NameSuffix;
7338   IdentifierInfo &VariantII = Context.Idents.get(MangledName);
7339 
7340   VariantII.setMangledOpenMPVariantName(true);
7341   D.SetIdentifier(&VariantII, D.getBeginLoc());
7342 }
7343 
7344 void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(
7345     Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) {
7346   // Do not mark function as is used to prevent its emission if this is the
7347   // only place where it is used.
7348   EnterExpressionEvaluationContext Unevaluated(
7349       *this, Sema::ExpressionEvaluationContext::Unevaluated);
7350 
7351   FunctionDecl *FD = nullptr;
7352   if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
7353     FD = UTemplDecl->getTemplatedDecl();
7354   else
7355     FD = cast<FunctionDecl>(D);
7356   auto *VariantFuncRef = DeclRefExpr::Create(
7357       Context, NestedNameSpecifierLoc(), SourceLocation(), FD,
7358       /* RefersToEnclosingVariableOrCapture */ false,
7359       /* NameLoc */ FD->getLocation(), FD->getType(),
7360       ExprValueKind::VK_PRValue);
7361 
7362   OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
7363   auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit(
7364       Context, VariantFuncRef, DVScope.TI,
7365       /*NothingArgs=*/nullptr, /*NothingArgsSize=*/0,
7366       /*NeedDevicePtrArgs=*/nullptr, /*NeedDevicePtrArgsSize=*/0,
7367       /*AppendArgs=*/nullptr, /*AppendArgsSize=*/0);
7368   for (FunctionDecl *BaseFD : Bases)
7369     BaseFD->addAttr(OMPDeclareVariantA);
7370 }
7371 
7372 ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
7373                                  SourceLocation LParenLoc,
7374                                  MultiExprArg ArgExprs,
7375                                  SourceLocation RParenLoc, Expr *ExecConfig) {
7376   // The common case is a regular call we do not want to specialize at all. Try
7377   // to make that case fast by bailing early.
7378   CallExpr *CE = dyn_cast<CallExpr>(Call.get());
7379   if (!CE)
7380     return Call;
7381 
7382   FunctionDecl *CalleeFnDecl = CE->getDirectCallee();
7383   if (!CalleeFnDecl)
7384     return Call;
7385 
7386   if (LangOpts.OpenMP >= 51 && CalleeFnDecl->getIdentifier() &&
7387       CalleeFnDecl->getName().starts_with_insensitive("omp_")) {
7388     // checking for any calls inside an Order region
7389     if (Scope && Scope->isOpenMPOrderClauseScope())
7390       Diag(LParenLoc, diag::err_omp_unexpected_call_to_omp_runtime_api);
7391   }
7392 
7393   if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>())
7394     return Call;
7395 
7396   ASTContext &Context = getASTContext();
7397   std::function<void(StringRef)> DiagUnknownTrait = [this,
7398                                                      CE](StringRef ISATrait) {
7399     // TODO Track the selector locations in a way that is accessible here to
7400     // improve the diagnostic location.
7401     Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait)
7402         << ISATrait;
7403   };
7404   TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait),
7405                           getCurFunctionDecl(), DSAStack->getConstructTraits());
7406 
7407   QualType CalleeFnType = CalleeFnDecl->getType();
7408 
7409   SmallVector<Expr *, 4> Exprs;
7410   SmallVector<VariantMatchInfo, 4> VMIs;
7411   while (CalleeFnDecl) {
7412     for (OMPDeclareVariantAttr *A :
7413          CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) {
7414       Expr *VariantRef = A->getVariantFuncRef();
7415 
7416       VariantMatchInfo VMI;
7417       OMPTraitInfo &TI = A->getTraitInfo();
7418       TI.getAsVariantMatchInfo(Context, VMI);
7419       if (!isVariantApplicableInContext(VMI, OMPCtx,
7420                                         /* DeviceSetOnly */ false))
7421         continue;
7422 
7423       VMIs.push_back(VMI);
7424       Exprs.push_back(VariantRef);
7425     }
7426 
7427     CalleeFnDecl = CalleeFnDecl->getPreviousDecl();
7428   }
7429 
7430   ExprResult NewCall;
7431   do {
7432     int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
7433     if (BestIdx < 0)
7434       return Call;
7435     Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]);
7436     Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl();
7437 
7438     {
7439       // Try to build a (member) call expression for the current best applicable
7440       // variant expression. We allow this to fail in which case we continue
7441       // with the next best variant expression. The fail case is part of the
7442       // implementation defined behavior in the OpenMP standard when it talks
7443       // about what differences in the function prototypes: "Any differences
7444       // that the specific OpenMP context requires in the prototype of the
7445       // variant from the base function prototype are implementation defined."
7446       // This wording is there to allow the specialized variant to have a
7447       // different type than the base function. This is intended and OK but if
7448       // we cannot create a call the difference is not in the "implementation
7449       // defined range" we allow.
7450       Sema::TentativeAnalysisScope Trap(*this);
7451 
7452       if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) {
7453         auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE);
7454         BestExpr = MemberExpr::CreateImplicit(
7455             Context, MemberCall->getImplicitObjectArgument(),
7456             /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy,
7457             MemberCall->getValueKind(), MemberCall->getObjectKind());
7458       }
7459       NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc,
7460                               ExecConfig);
7461       if (NewCall.isUsable()) {
7462         if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) {
7463           FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee();
7464           QualType NewType = Context.mergeFunctionTypes(
7465               CalleeFnType, NewCalleeFnDecl->getType(),
7466               /* OfBlockPointer */ false,
7467               /* Unqualified */ false, /* AllowCXX */ true);
7468           if (!NewType.isNull())
7469             break;
7470           // Don't use the call if the function type was not compatible.
7471           NewCall = nullptr;
7472         }
7473       }
7474     }
7475 
7476     VMIs.erase(VMIs.begin() + BestIdx);
7477     Exprs.erase(Exprs.begin() + BestIdx);
7478   } while (!VMIs.empty());
7479 
7480   if (!NewCall.isUsable())
7481     return Call;
7482   return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0);
7483 }
7484 
7485 std::optional<std::pair<FunctionDecl *, Expr *>>
7486 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
7487                                         Expr *VariantRef, OMPTraitInfo &TI,
7488                                         unsigned NumAppendArgs,
7489                                         SourceRange SR) {
7490   if (!DG || DG.get().isNull())
7491     return std::nullopt;
7492 
7493   const int VariantId = 1;
7494   // Must be applied only to single decl.
7495   if (!DG.get().isSingleDecl()) {
7496     Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
7497         << VariantId << SR;
7498     return std::nullopt;
7499   }
7500   Decl *ADecl = DG.get().getSingleDecl();
7501   if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
7502     ADecl = FTD->getTemplatedDecl();
7503 
7504   // Decl must be a function.
7505   auto *FD = dyn_cast<FunctionDecl>(ADecl);
7506   if (!FD) {
7507     Diag(ADecl->getLocation(), diag::err_omp_function_expected)
7508         << VariantId << SR;
7509     return std::nullopt;
7510   }
7511 
7512   auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
7513     // The 'target' attribute needs to be separately checked because it does
7514     // not always signify a multiversion function declaration.
7515     return FD->isMultiVersion() || FD->hasAttr<TargetAttr>();
7516   };
7517   // OpenMP is not compatible with multiversion function attributes.
7518   if (HasMultiVersionAttributes(FD)) {
7519     Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
7520         << SR;
7521     return std::nullopt;
7522   }
7523 
7524   // Allow #pragma omp declare variant only if the function is not used.
7525   if (FD->isUsed(false))
7526     Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
7527         << FD->getLocation();
7528 
7529   // Check if the function was emitted already.
7530   const FunctionDecl *Definition;
7531   if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) &&
7532       (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition)))
7533     Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
7534         << FD->getLocation();
7535 
7536   // The VariantRef must point to function.
7537   if (!VariantRef) {
7538     Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
7539     return std::nullopt;
7540   }
7541 
7542   auto ShouldDelayChecks = [](Expr *&E, bool) {
7543     return E && (E->isTypeDependent() || E->isValueDependent() ||
7544                  E->containsUnexpandedParameterPack() ||
7545                  E->isInstantiationDependent());
7546   };
7547   // Do not check templates, wait until instantiation.
7548   if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) ||
7549       TI.anyScoreOrCondition(ShouldDelayChecks))
7550     return std::make_pair(FD, VariantRef);
7551 
7552   // Deal with non-constant score and user condition expressions.
7553   auto HandleNonConstantScoresAndConditions = [this](Expr *&E,
7554                                                      bool IsScore) -> bool {
7555     if (!E || E->isIntegerConstantExpr(Context))
7556       return false;
7557 
7558     if (IsScore) {
7559       // We warn on non-constant scores and pretend they were not present.
7560       Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant)
7561           << E;
7562       E = nullptr;
7563     } else {
7564       // We could replace a non-constant user condition with "false" but we
7565       // will soon need to handle these anyway for the dynamic version of
7566       // OpenMP context selectors.
7567       Diag(E->getExprLoc(),
7568            diag::err_omp_declare_variant_user_condition_not_constant)
7569           << E;
7570     }
7571     return true;
7572   };
7573   if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions))
7574     return std::nullopt;
7575 
7576   QualType AdjustedFnType = FD->getType();
7577   if (NumAppendArgs) {
7578     const auto *PTy = AdjustedFnType->getAsAdjusted<FunctionProtoType>();
7579     if (!PTy) {
7580       Diag(FD->getLocation(), diag::err_omp_declare_variant_prototype_required)
7581           << SR;
7582       return std::nullopt;
7583     }
7584     // Adjust the function type to account for an extra omp_interop_t for each
7585     // specified in the append_args clause.
7586     const TypeDecl *TD = nullptr;
7587     LookupResult Result(*this, &Context.Idents.get("omp_interop_t"),
7588                         SR.getBegin(), Sema::LookupOrdinaryName);
7589     if (LookupName(Result, getCurScope())) {
7590       NamedDecl *ND = Result.getFoundDecl();
7591       TD = dyn_cast_or_null<TypeDecl>(ND);
7592     }
7593     if (!TD) {
7594       Diag(SR.getBegin(), diag::err_omp_interop_type_not_found) << SR;
7595       return std::nullopt;
7596     }
7597     QualType InteropType = Context.getTypeDeclType(TD);
7598     if (PTy->isVariadic()) {
7599       Diag(FD->getLocation(), diag::err_omp_append_args_with_varargs) << SR;
7600       return std::nullopt;
7601     }
7602     llvm::SmallVector<QualType, 8> Params;
7603     Params.append(PTy->param_type_begin(), PTy->param_type_end());
7604     Params.insert(Params.end(), NumAppendArgs, InteropType);
7605     AdjustedFnType = Context.getFunctionType(PTy->getReturnType(), Params,
7606                                              PTy->getExtProtoInfo());
7607   }
7608 
7609   // Convert VariantRef expression to the type of the original function to
7610   // resolve possible conflicts.
7611   ExprResult VariantRefCast = VariantRef;
7612   if (LangOpts.CPlusPlus) {
7613     QualType FnPtrType;
7614     auto *Method = dyn_cast<CXXMethodDecl>(FD);
7615     if (Method && !Method->isStatic()) {
7616       const Type *ClassType =
7617           Context.getTypeDeclType(Method->getParent()).getTypePtr();
7618       FnPtrType = Context.getMemberPointerType(AdjustedFnType, ClassType);
7619       ExprResult ER;
7620       {
7621         // Build adrr_of unary op to correctly handle type checks for member
7622         // functions.
7623         Sema::TentativeAnalysisScope Trap(*this);
7624         ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf,
7625                                   VariantRef);
7626       }
7627       if (!ER.isUsable()) {
7628         Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7629             << VariantId << VariantRef->getSourceRange();
7630         return std::nullopt;
7631       }
7632       VariantRef = ER.get();
7633     } else {
7634       FnPtrType = Context.getPointerType(AdjustedFnType);
7635     }
7636     QualType VarianPtrType = Context.getPointerType(VariantRef->getType());
7637     if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) {
7638       ImplicitConversionSequence ICS = TryImplicitConversion(
7639           VariantRef, FnPtrType.getUnqualifiedType(),
7640           /*SuppressUserConversions=*/false, AllowedExplicit::None,
7641           /*InOverloadResolution=*/false,
7642           /*CStyle=*/false,
7643           /*AllowObjCWritebackConversion=*/false);
7644       if (ICS.isFailure()) {
7645         Diag(VariantRef->getExprLoc(),
7646              diag::err_omp_declare_variant_incompat_types)
7647             << VariantRef->getType()
7648             << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
7649             << (NumAppendArgs ? 1 : 0) << VariantRef->getSourceRange();
7650         return std::nullopt;
7651       }
7652       VariantRefCast = PerformImplicitConversion(
7653           VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
7654       if (!VariantRefCast.isUsable())
7655         return std::nullopt;
7656     }
7657     // Drop previously built artificial addr_of unary op for member functions.
7658     if (Method && !Method->isStatic()) {
7659       Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
7660       if (auto *UO = dyn_cast<UnaryOperator>(
7661               PossibleAddrOfVariantRef->IgnoreImplicit()))
7662         VariantRefCast = UO->getSubExpr();
7663     }
7664   }
7665 
7666   ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get());
7667   if (!ER.isUsable() ||
7668       !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
7669     Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7670         << VariantId << VariantRef->getSourceRange();
7671     return std::nullopt;
7672   }
7673 
7674   // The VariantRef must point to function.
7675   auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts());
7676   if (!DRE) {
7677     Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7678         << VariantId << VariantRef->getSourceRange();
7679     return std::nullopt;
7680   }
7681   auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
7682   if (!NewFD) {
7683     Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7684         << VariantId << VariantRef->getSourceRange();
7685     return std::nullopt;
7686   }
7687 
7688   if (FD->getCanonicalDecl() == NewFD->getCanonicalDecl()) {
7689     Diag(VariantRef->getExprLoc(),
7690          diag::err_omp_declare_variant_same_base_function)
7691         << VariantRef->getSourceRange();
7692     return std::nullopt;
7693   }
7694 
7695   // Check if function types are compatible in C.
7696   if (!LangOpts.CPlusPlus) {
7697     QualType NewType =
7698         Context.mergeFunctionTypes(AdjustedFnType, NewFD->getType());
7699     if (NewType.isNull()) {
7700       Diag(VariantRef->getExprLoc(),
7701            diag::err_omp_declare_variant_incompat_types)
7702           << NewFD->getType() << FD->getType() << (NumAppendArgs ? 1 : 0)
7703           << VariantRef->getSourceRange();
7704       return std::nullopt;
7705     }
7706     if (NewType->isFunctionProtoType()) {
7707       if (FD->getType()->isFunctionNoProtoType())
7708         setPrototype(*this, FD, NewFD, NewType);
7709       else if (NewFD->getType()->isFunctionNoProtoType())
7710         setPrototype(*this, NewFD, FD, NewType);
7711     }
7712   }
7713 
7714   // Check if variant function is not marked with declare variant directive.
7715   if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
7716     Diag(VariantRef->getExprLoc(),
7717          diag::warn_omp_declare_variant_marked_as_declare_variant)
7718         << VariantRef->getSourceRange();
7719     SourceRange SR =
7720         NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
7721     Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
7722     return std::nullopt;
7723   }
7724 
7725   enum DoesntSupport {
7726     VirtFuncs = 1,
7727     Constructors = 3,
7728     Destructors = 4,
7729     DeletedFuncs = 5,
7730     DefaultedFuncs = 6,
7731     ConstexprFuncs = 7,
7732     ConstevalFuncs = 8,
7733   };
7734   if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
7735     if (CXXFD->isVirtual()) {
7736       Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7737           << VirtFuncs;
7738       return std::nullopt;
7739     }
7740 
7741     if (isa<CXXConstructorDecl>(FD)) {
7742       Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7743           << Constructors;
7744       return std::nullopt;
7745     }
7746 
7747     if (isa<CXXDestructorDecl>(FD)) {
7748       Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7749           << Destructors;
7750       return std::nullopt;
7751     }
7752   }
7753 
7754   if (FD->isDeleted()) {
7755     Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7756         << DeletedFuncs;
7757     return std::nullopt;
7758   }
7759 
7760   if (FD->isDefaulted()) {
7761     Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7762         << DefaultedFuncs;
7763     return std::nullopt;
7764   }
7765 
7766   if (FD->isConstexpr()) {
7767     Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7768         << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
7769     return std::nullopt;
7770   }
7771 
7772   // Check general compatibility.
7773   if (areMultiversionVariantFunctionsCompatible(
7774           FD, NewFD, PartialDiagnostic::NullDiagnostic(),
7775           PartialDiagnosticAt(SourceLocation(),
7776                               PartialDiagnostic::NullDiagnostic()),
7777           PartialDiagnosticAt(
7778               VariantRef->getExprLoc(),
7779               PDiag(diag::err_omp_declare_variant_doesnt_support)),
7780           PartialDiagnosticAt(VariantRef->getExprLoc(),
7781                               PDiag(diag::err_omp_declare_variant_diff)
7782                                   << FD->getLocation()),
7783           /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
7784           /*CLinkageMayDiffer=*/true))
7785     return std::nullopt;
7786   return std::make_pair(FD, cast<Expr>(DRE));
7787 }
7788 
7789 void Sema::ActOnOpenMPDeclareVariantDirective(
7790     FunctionDecl *FD, Expr *VariantRef, OMPTraitInfo &TI,
7791     ArrayRef<Expr *> AdjustArgsNothing,
7792     ArrayRef<Expr *> AdjustArgsNeedDevicePtr,
7793     ArrayRef<OMPInteropInfo> AppendArgs, SourceLocation AdjustArgsLoc,
7794     SourceLocation AppendArgsLoc, SourceRange SR) {
7795 
7796   // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions]
7797   // An adjust_args clause or append_args clause can only be specified if the
7798   // dispatch selector of the construct selector set appears in the match
7799   // clause.
7800 
7801   SmallVector<Expr *, 8> AllAdjustArgs;
7802   llvm::append_range(AllAdjustArgs, AdjustArgsNothing);
7803   llvm::append_range(AllAdjustArgs, AdjustArgsNeedDevicePtr);
7804 
7805   if (!AllAdjustArgs.empty() || !AppendArgs.empty()) {
7806     VariantMatchInfo VMI;
7807     TI.getAsVariantMatchInfo(Context, VMI);
7808     if (!llvm::is_contained(
7809             VMI.ConstructTraits,
7810             llvm::omp::TraitProperty::construct_dispatch_dispatch)) {
7811       if (!AllAdjustArgs.empty())
7812         Diag(AdjustArgsLoc, diag::err_omp_clause_requires_dispatch_construct)
7813             << getOpenMPClauseName(OMPC_adjust_args);
7814       if (!AppendArgs.empty())
7815         Diag(AppendArgsLoc, diag::err_omp_clause_requires_dispatch_construct)
7816             << getOpenMPClauseName(OMPC_append_args);
7817       return;
7818     }
7819   }
7820 
7821   // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions]
7822   // Each argument can only appear in a single adjust_args clause for each
7823   // declare variant directive.
7824   llvm::SmallPtrSet<const VarDecl *, 4> AdjustVars;
7825 
7826   for (Expr *E : AllAdjustArgs) {
7827     E = E->IgnoreParenImpCasts();
7828     if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
7829       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7830         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
7831         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
7832             FD->getParamDecl(PVD->getFunctionScopeIndex())
7833                     ->getCanonicalDecl() == CanonPVD) {
7834           // It's a parameter of the function, check duplicates.
7835           if (!AdjustVars.insert(CanonPVD).second) {
7836             Diag(DRE->getLocation(), diag::err_omp_adjust_arg_multiple_clauses)
7837                 << PVD;
7838             return;
7839           }
7840           continue;
7841         }
7842       }
7843     }
7844     // Anything that is not a function parameter is an error.
7845     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) << FD << 0;
7846     return;
7847   }
7848 
7849   auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit(
7850       Context, VariantRef, &TI, const_cast<Expr **>(AdjustArgsNothing.data()),
7851       AdjustArgsNothing.size(),
7852       const_cast<Expr **>(AdjustArgsNeedDevicePtr.data()),
7853       AdjustArgsNeedDevicePtr.size(),
7854       const_cast<OMPInteropInfo *>(AppendArgs.data()), AppendArgs.size(), SR);
7855   FD->addAttr(NewAttr);
7856 }
7857 
7858 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
7859                                               Stmt *AStmt,
7860                                               SourceLocation StartLoc,
7861                                               SourceLocation EndLoc) {
7862   if (!AStmt)
7863     return StmtError();
7864 
7865   auto *CS = cast<CapturedStmt>(AStmt);
7866   // 1.2.2 OpenMP Language Terminology
7867   // Structured block - An executable statement with a single entry at the
7868   // top and a single exit at the bottom.
7869   // The point of exit cannot be a branch out of the structured block.
7870   // longjmp() and throw() must not violate the entry/exit criteria.
7871   CS->getCapturedDecl()->setNothrow();
7872 
7873   setFunctionHasBranchProtectedScope();
7874 
7875   return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
7876                                       DSAStack->getTaskgroupReductionRef(),
7877                                       DSAStack->isCancelRegion());
7878 }
7879 
7880 namespace {
7881 /// Iteration space of a single for loop.
7882 struct LoopIterationSpace final {
7883   /// True if the condition operator is the strict compare operator (<, > or
7884   /// !=).
7885   bool IsStrictCompare = false;
7886   /// Condition of the loop.
7887   Expr *PreCond = nullptr;
7888   /// This expression calculates the number of iterations in the loop.
7889   /// It is always possible to calculate it before starting the loop.
7890   Expr *NumIterations = nullptr;
7891   /// The loop counter variable.
7892   Expr *CounterVar = nullptr;
7893   /// Private loop counter variable.
7894   Expr *PrivateCounterVar = nullptr;
7895   /// This is initializer for the initial value of #CounterVar.
7896   Expr *CounterInit = nullptr;
7897   /// This is step for the #CounterVar used to generate its update:
7898   /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
7899   Expr *CounterStep = nullptr;
7900   /// Should step be subtracted?
7901   bool Subtract = false;
7902   /// Source range of the loop init.
7903   SourceRange InitSrcRange;
7904   /// Source range of the loop condition.
7905   SourceRange CondSrcRange;
7906   /// Source range of the loop increment.
7907   SourceRange IncSrcRange;
7908   /// Minimum value that can have the loop control variable. Used to support
7909   /// non-rectangular loops. Applied only for LCV with the non-iterator types,
7910   /// since only such variables can be used in non-loop invariant expressions.
7911   Expr *MinValue = nullptr;
7912   /// Maximum value that can have the loop control variable. Used to support
7913   /// non-rectangular loops. Applied only for LCV with the non-iterator type,
7914   /// since only such variables can be used in non-loop invariant expressions.
7915   Expr *MaxValue = nullptr;
7916   /// true, if the lower bound depends on the outer loop control var.
7917   bool IsNonRectangularLB = false;
7918   /// true, if the upper bound depends on the outer loop control var.
7919   bool IsNonRectangularUB = false;
7920   /// Index of the loop this loop depends on and forms non-rectangular loop
7921   /// nest.
7922   unsigned LoopDependentIdx = 0;
7923   /// Final condition for the non-rectangular loop nest support. It is used to
7924   /// check that the number of iterations for this particular counter must be
7925   /// finished.
7926   Expr *FinalCondition = nullptr;
7927 };
7928 
7929 /// Helper class for checking canonical form of the OpenMP loops and
7930 /// extracting iteration space of each loop in the loop nest, that will be used
7931 /// for IR generation.
7932 class OpenMPIterationSpaceChecker {
7933   /// Reference to Sema.
7934   Sema &SemaRef;
7935   /// Does the loop associated directive support non-rectangular loops?
7936   bool SupportsNonRectangular;
7937   /// Data-sharing stack.
7938   DSAStackTy &Stack;
7939   /// A location for diagnostics (when there is no some better location).
7940   SourceLocation DefaultLoc;
7941   /// A location for diagnostics (when increment is not compatible).
7942   SourceLocation ConditionLoc;
7943   /// A source location for referring to loop init later.
7944   SourceRange InitSrcRange;
7945   /// A source location for referring to condition later.
7946   SourceRange ConditionSrcRange;
7947   /// A source location for referring to increment later.
7948   SourceRange IncrementSrcRange;
7949   /// Loop variable.
7950   ValueDecl *LCDecl = nullptr;
7951   /// Reference to loop variable.
7952   Expr *LCRef = nullptr;
7953   /// Lower bound (initializer for the var).
7954   Expr *LB = nullptr;
7955   /// Upper bound.
7956   Expr *UB = nullptr;
7957   /// Loop step (increment).
7958   Expr *Step = nullptr;
7959   /// This flag is true when condition is one of:
7960   ///   Var <  UB
7961   ///   Var <= UB
7962   ///   UB  >  Var
7963   ///   UB  >= Var
7964   /// This will have no value when the condition is !=
7965   std::optional<bool> TestIsLessOp;
7966   /// This flag is true when condition is strict ( < or > ).
7967   bool TestIsStrictOp = false;
7968   /// This flag is true when step is subtracted on each iteration.
7969   bool SubtractStep = false;
7970   /// The outer loop counter this loop depends on (if any).
7971   const ValueDecl *DepDecl = nullptr;
7972   /// Contains number of loop (starts from 1) on which loop counter init
7973   /// expression of this loop depends on.
7974   std::optional<unsigned> InitDependOnLC;
7975   /// Contains number of loop (starts from 1) on which loop counter condition
7976   /// expression of this loop depends on.
7977   std::optional<unsigned> CondDependOnLC;
7978   /// Checks if the provide statement depends on the loop counter.
7979   std::optional<unsigned> doesDependOnLoopCounter(const Stmt *S,
7980                                                   bool IsInitializer);
7981   /// Original condition required for checking of the exit condition for
7982   /// non-rectangular loop.
7983   Expr *Condition = nullptr;
7984 
7985 public:
7986   OpenMPIterationSpaceChecker(Sema &SemaRef, bool SupportsNonRectangular,
7987                               DSAStackTy &Stack, SourceLocation DefaultLoc)
7988       : SemaRef(SemaRef), SupportsNonRectangular(SupportsNonRectangular),
7989         Stack(Stack), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
7990   /// Check init-expr for canonical loop form and save loop counter
7991   /// variable - #Var and its initialization value - #LB.
7992   bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
7993   /// Check test-expr for canonical form, save upper-bound (#UB), flags
7994   /// for less/greater and for strict/non-strict comparison.
7995   bool checkAndSetCond(Expr *S);
7996   /// Check incr-expr for canonical loop form and return true if it
7997   /// does not conform, otherwise save loop step (#Step).
7998   bool checkAndSetInc(Expr *S);
7999   /// Return the loop counter variable.
8000   ValueDecl *getLoopDecl() const { return LCDecl; }
8001   /// Return the reference expression to loop counter variable.
8002   Expr *getLoopDeclRefExpr() const { return LCRef; }
8003   /// Source range of the loop init.
8004   SourceRange getInitSrcRange() const { return InitSrcRange; }
8005   /// Source range of the loop condition.
8006   SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
8007   /// Source range of the loop increment.
8008   SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
8009   /// True if the step should be subtracted.
8010   bool shouldSubtractStep() const { return SubtractStep; }
8011   /// True, if the compare operator is strict (<, > or !=).
8012   bool isStrictTestOp() const { return TestIsStrictOp; }
8013   /// Build the expression to calculate the number of iterations.
8014   Expr *buildNumIterations(
8015       Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
8016       llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
8017   /// Build the precondition expression for the loops.
8018   Expr *
8019   buildPreCond(Scope *S, Expr *Cond,
8020                llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
8021   /// Build reference expression to the counter be used for codegen.
8022   DeclRefExpr *
8023   buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8024                   DSAStackTy &DSA) const;
8025   /// Build reference expression to the private counter be used for
8026   /// codegen.
8027   Expr *buildPrivateCounterVar() const;
8028   /// Build initialization of the counter be used for codegen.
8029   Expr *buildCounterInit() const;
8030   /// Build step of the counter be used for codegen.
8031   Expr *buildCounterStep() const;
8032   /// Build loop data with counter value for depend clauses in ordered
8033   /// directives.
8034   Expr *
8035   buildOrderedLoopData(Scope *S, Expr *Counter,
8036                        llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8037                        SourceLocation Loc, Expr *Inc = nullptr,
8038                        OverloadedOperatorKind OOK = OO_Amp);
8039   /// Builds the minimum value for the loop counter.
8040   std::pair<Expr *, Expr *> buildMinMaxValues(
8041       Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
8042   /// Builds final condition for the non-rectangular loops.
8043   Expr *buildFinalCondition(Scope *S) const;
8044   /// Return true if any expression is dependent.
8045   bool dependent() const;
8046   /// Returns true if the initializer forms non-rectangular loop.
8047   bool doesInitDependOnLC() const { return InitDependOnLC.has_value(); }
8048   /// Returns true if the condition forms non-rectangular loop.
8049   bool doesCondDependOnLC() const { return CondDependOnLC.has_value(); }
8050   /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
8051   unsigned getLoopDependentIdx() const {
8052     return InitDependOnLC.value_or(CondDependOnLC.value_or(0));
8053   }
8054 
8055 private:
8056   /// Check the right-hand side of an assignment in the increment
8057   /// expression.
8058   bool checkAndSetIncRHS(Expr *RHS);
8059   /// Helper to set loop counter variable and its initializer.
8060   bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
8061                       bool EmitDiags);
8062   /// Helper to set upper bound.
8063   bool setUB(Expr *NewUB, std::optional<bool> LessOp, bool StrictOp,
8064              SourceRange SR, SourceLocation SL);
8065   /// Helper to set loop increment.
8066   bool setStep(Expr *NewStep, bool Subtract);
8067 };
8068 
8069 bool OpenMPIterationSpaceChecker::dependent() const {
8070   if (!LCDecl) {
8071     assert(!LB && !UB && !Step);
8072     return false;
8073   }
8074   return LCDecl->getType()->isDependentType() ||
8075          (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
8076          (Step && Step->isValueDependent());
8077 }
8078 
8079 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
8080                                                  Expr *NewLCRefExpr,
8081                                                  Expr *NewLB, bool EmitDiags) {
8082   // State consistency checking to ensure correct usage.
8083   assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
8084          UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
8085   if (!NewLCDecl || !NewLB || NewLB->containsErrors())
8086     return true;
8087   LCDecl = getCanonicalDecl(NewLCDecl);
8088   LCRef = NewLCRefExpr;
8089   if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
8090     if (const CXXConstructorDecl *Ctor = CE->getConstructor())
8091       if ((Ctor->isCopyOrMoveConstructor() ||
8092            Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
8093           CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
8094         NewLB = CE->getArg(0)->IgnoreParenImpCasts();
8095   LB = NewLB;
8096   if (EmitDiags)
8097     InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
8098   return false;
8099 }
8100 
8101 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, std::optional<bool> LessOp,
8102                                         bool StrictOp, SourceRange SR,
8103                                         SourceLocation SL) {
8104   // State consistency checking to ensure correct usage.
8105   assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&
8106          Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
8107   if (!NewUB || NewUB->containsErrors())
8108     return true;
8109   UB = NewUB;
8110   if (LessOp)
8111     TestIsLessOp = LessOp;
8112   TestIsStrictOp = StrictOp;
8113   ConditionSrcRange = SR;
8114   ConditionLoc = SL;
8115   CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
8116   return false;
8117 }
8118 
8119 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
8120   // State consistency checking to ensure correct usage.
8121   assert(LCDecl != nullptr && LB != nullptr && Step == nullptr);
8122   if (!NewStep || NewStep->containsErrors())
8123     return true;
8124   if (!NewStep->isValueDependent()) {
8125     // Check that the step is integer expression.
8126     SourceLocation StepLoc = NewStep->getBeginLoc();
8127     ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
8128         StepLoc, getExprAsWritten(NewStep));
8129     if (Val.isInvalid())
8130       return true;
8131     NewStep = Val.get();
8132 
8133     // OpenMP [2.6, Canonical Loop Form, Restrictions]
8134     //  If test-expr is of form var relational-op b and relational-op is < or
8135     //  <= then incr-expr must cause var to increase on each iteration of the
8136     //  loop. If test-expr is of form var relational-op b and relational-op is
8137     //  > or >= then incr-expr must cause var to decrease on each iteration of
8138     //  the loop.
8139     //  If test-expr is of form b relational-op var and relational-op is < or
8140     //  <= then incr-expr must cause var to decrease on each iteration of the
8141     //  loop. If test-expr is of form b relational-op var and relational-op is
8142     //  > or >= then incr-expr must cause var to increase on each iteration of
8143     //  the loop.
8144     std::optional<llvm::APSInt> Result =
8145         NewStep->getIntegerConstantExpr(SemaRef.Context);
8146     bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
8147     bool IsConstNeg =
8148         Result && Result->isSigned() && (Subtract != Result->isNegative());
8149     bool IsConstPos =
8150         Result && Result->isSigned() && (Subtract == Result->isNegative());
8151     bool IsConstZero = Result && !Result->getBoolValue();
8152 
8153     // != with increment is treated as <; != with decrement is treated as >
8154     if (!TestIsLessOp)
8155       TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
8156     if (UB && (IsConstZero ||
8157                (*TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract))
8158                               : (IsConstPos || (IsUnsigned && !Subtract))))) {
8159       SemaRef.Diag(NewStep->getExprLoc(),
8160                    diag::err_omp_loop_incr_not_compatible)
8161           << LCDecl << *TestIsLessOp << NewStep->getSourceRange();
8162       SemaRef.Diag(ConditionLoc,
8163                    diag::note_omp_loop_cond_requres_compatible_incr)
8164           << *TestIsLessOp << ConditionSrcRange;
8165       return true;
8166     }
8167     if (*TestIsLessOp == Subtract) {
8168       NewStep =
8169           SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
8170               .get();
8171       Subtract = !Subtract;
8172     }
8173   }
8174 
8175   Step = NewStep;
8176   SubtractStep = Subtract;
8177   return false;
8178 }
8179 
8180 namespace {
8181 /// Checker for the non-rectangular loops. Checks if the initializer or
8182 /// condition expression references loop counter variable.
8183 class LoopCounterRefChecker final
8184     : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
8185   Sema &SemaRef;
8186   DSAStackTy &Stack;
8187   const ValueDecl *CurLCDecl = nullptr;
8188   const ValueDecl *DepDecl = nullptr;
8189   const ValueDecl *PrevDepDecl = nullptr;
8190   bool IsInitializer = true;
8191   bool SupportsNonRectangular;
8192   unsigned BaseLoopId = 0;
8193   bool checkDecl(const Expr *E, const ValueDecl *VD) {
8194     if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
8195       SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
8196           << (IsInitializer ? 0 : 1);
8197       return false;
8198     }
8199     const auto &&Data = Stack.isLoopControlVariable(VD);
8200     // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
8201     // The type of the loop iterator on which we depend may not have a random
8202     // access iterator type.
8203     if (Data.first && VD->getType()->isRecordType()) {
8204       SmallString<128> Name;
8205       llvm::raw_svector_ostream OS(Name);
8206       VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
8207                                /*Qualified=*/true);
8208       SemaRef.Diag(E->getExprLoc(),
8209                    diag::err_omp_wrong_dependency_iterator_type)
8210           << OS.str();
8211       SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
8212       return false;
8213     }
8214     if (Data.first && !SupportsNonRectangular) {
8215       SemaRef.Diag(E->getExprLoc(), diag::err_omp_invariant_dependency);
8216       return false;
8217     }
8218     if (Data.first &&
8219         (DepDecl || (PrevDepDecl &&
8220                      getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
8221       if (!DepDecl && PrevDepDecl)
8222         DepDecl = PrevDepDecl;
8223       SmallString<128> Name;
8224       llvm::raw_svector_ostream OS(Name);
8225       DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
8226                                     /*Qualified=*/true);
8227       SemaRef.Diag(E->getExprLoc(),
8228                    diag::err_omp_invariant_or_linear_dependency)
8229           << OS.str();
8230       return false;
8231     }
8232     if (Data.first) {
8233       DepDecl = VD;
8234       BaseLoopId = Data.first;
8235     }
8236     return Data.first;
8237   }
8238 
8239 public:
8240   bool VisitDeclRefExpr(const DeclRefExpr *E) {
8241     const ValueDecl *VD = E->getDecl();
8242     if (isa<VarDecl>(VD))
8243       return checkDecl(E, VD);
8244     return false;
8245   }
8246   bool VisitMemberExpr(const MemberExpr *E) {
8247     if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
8248       const ValueDecl *VD = E->getMemberDecl();
8249       if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
8250         return checkDecl(E, VD);
8251     }
8252     return false;
8253   }
8254   bool VisitStmt(const Stmt *S) {
8255     bool Res = false;
8256     for (const Stmt *Child : S->children())
8257       Res = (Child && Visit(Child)) || Res;
8258     return Res;
8259   }
8260   explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
8261                                  const ValueDecl *CurLCDecl, bool IsInitializer,
8262                                  const ValueDecl *PrevDepDecl = nullptr,
8263                                  bool SupportsNonRectangular = true)
8264       : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
8265         PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer),
8266         SupportsNonRectangular(SupportsNonRectangular) {}
8267   unsigned getBaseLoopId() const {
8268     assert(CurLCDecl && "Expected loop dependency.");
8269     return BaseLoopId;
8270   }
8271   const ValueDecl *getDepDecl() const {
8272     assert(CurLCDecl && "Expected loop dependency.");
8273     return DepDecl;
8274   }
8275 };
8276 } // namespace
8277 
8278 std::optional<unsigned>
8279 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
8280                                                      bool IsInitializer) {
8281   // Check for the non-rectangular loops.
8282   LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
8283                                         DepDecl, SupportsNonRectangular);
8284   if (LoopStmtChecker.Visit(S)) {
8285     DepDecl = LoopStmtChecker.getDepDecl();
8286     return LoopStmtChecker.getBaseLoopId();
8287   }
8288   return std::nullopt;
8289 }
8290 
8291 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
8292   // Check init-expr for canonical loop form and save loop counter
8293   // variable - #Var and its initialization value - #LB.
8294   // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
8295   //   var = lb
8296   //   integer-type var = lb
8297   //   random-access-iterator-type var = lb
8298   //   pointer-type var = lb
8299   //
8300   if (!S) {
8301     if (EmitDiags) {
8302       SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
8303     }
8304     return true;
8305   }
8306   if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
8307     if (!ExprTemp->cleanupsHaveSideEffects())
8308       S = ExprTemp->getSubExpr();
8309 
8310   InitSrcRange = S->getSourceRange();
8311   if (Expr *E = dyn_cast<Expr>(S))
8312     S = E->IgnoreParens();
8313   if (auto *BO = dyn_cast<BinaryOperator>(S)) {
8314     if (BO->getOpcode() == BO_Assign) {
8315       Expr *LHS = BO->getLHS()->IgnoreParens();
8316       if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
8317         if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
8318           if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
8319             return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8320                                   EmitDiags);
8321         return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
8322       }
8323       if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
8324         if (ME->isArrow() &&
8325             isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8326           return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8327                                 EmitDiags);
8328       }
8329     }
8330   } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
8331     if (DS->isSingleDecl()) {
8332       if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
8333         if (Var->hasInit() && !Var->getType()->isReferenceType()) {
8334           // Accept non-canonical init form here but emit ext. warning.
8335           if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
8336             SemaRef.Diag(S->getBeginLoc(),
8337                          diag::ext_omp_loop_not_canonical_init)
8338                 << S->getSourceRange();
8339           return setLCDeclAndLB(
8340               Var,
8341               buildDeclRefExpr(SemaRef, Var,
8342                                Var->getType().getNonReferenceType(),
8343                                DS->getBeginLoc()),
8344               Var->getInit(), EmitDiags);
8345         }
8346       }
8347     }
8348   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8349     if (CE->getOperator() == OO_Equal) {
8350       Expr *LHS = CE->getArg(0);
8351       if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
8352         if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
8353           if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
8354             return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8355                                   EmitDiags);
8356         return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
8357       }
8358       if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
8359         if (ME->isArrow() &&
8360             isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8361           return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
8362                                 EmitDiags);
8363       }
8364     }
8365   }
8366 
8367   if (dependent() || SemaRef.CurContext->isDependentContext())
8368     return false;
8369   if (EmitDiags) {
8370     SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
8371         << S->getSourceRange();
8372   }
8373   return true;
8374 }
8375 
8376 /// Ignore parenthesizes, implicit casts, copy constructor and return the
8377 /// variable (which may be the loop variable) if possible.
8378 static const ValueDecl *getInitLCDecl(const Expr *E) {
8379   if (!E)
8380     return nullptr;
8381   E = getExprAsWritten(E);
8382   if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
8383     if (const CXXConstructorDecl *Ctor = CE->getConstructor())
8384       if ((Ctor->isCopyOrMoveConstructor() ||
8385            Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
8386           CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
8387         E = CE->getArg(0)->IgnoreParenImpCasts();
8388   if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
8389     if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
8390       return getCanonicalDecl(VD);
8391   }
8392   if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
8393     if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
8394       return getCanonicalDecl(ME->getMemberDecl());
8395   return nullptr;
8396 }
8397 
8398 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
8399   // Check test-expr for canonical form, save upper-bound UB, flags for
8400   // less/greater and for strict/non-strict comparison.
8401   // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following:
8402   //   var relational-op b
8403   //   b relational-op var
8404   //
8405   bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
8406   if (!S) {
8407     SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
8408         << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
8409     return true;
8410   }
8411   Condition = S;
8412   S = getExprAsWritten(S);
8413   SourceLocation CondLoc = S->getBeginLoc();
8414   auto &&CheckAndSetCond =
8415       [this, IneqCondIsCanonical](BinaryOperatorKind Opcode, const Expr *LHS,
8416                                   const Expr *RHS, SourceRange SR,
8417                                   SourceLocation OpLoc) -> std::optional<bool> {
8418     if (BinaryOperator::isRelationalOp(Opcode)) {
8419       if (getInitLCDecl(LHS) == LCDecl)
8420         return setUB(const_cast<Expr *>(RHS),
8421                      (Opcode == BO_LT || Opcode == BO_LE),
8422                      (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
8423       if (getInitLCDecl(RHS) == LCDecl)
8424         return setUB(const_cast<Expr *>(LHS),
8425                      (Opcode == BO_GT || Opcode == BO_GE),
8426                      (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
8427     } else if (IneqCondIsCanonical && Opcode == BO_NE) {
8428       return setUB(const_cast<Expr *>(getInitLCDecl(LHS) == LCDecl ? RHS : LHS),
8429                    /*LessOp=*/std::nullopt,
8430                    /*StrictOp=*/true, SR, OpLoc);
8431     }
8432     return std::nullopt;
8433   };
8434   std::optional<bool> Res;
8435   if (auto *RBO = dyn_cast<CXXRewrittenBinaryOperator>(S)) {
8436     CXXRewrittenBinaryOperator::DecomposedForm DF = RBO->getDecomposedForm();
8437     Res = CheckAndSetCond(DF.Opcode, DF.LHS, DF.RHS, RBO->getSourceRange(),
8438                           RBO->getOperatorLoc());
8439   } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
8440     Res = CheckAndSetCond(BO->getOpcode(), BO->getLHS(), BO->getRHS(),
8441                           BO->getSourceRange(), BO->getOperatorLoc());
8442   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8443     if (CE->getNumArgs() == 2) {
8444       Res = CheckAndSetCond(
8445           BinaryOperator::getOverloadedOpcode(CE->getOperator()), CE->getArg(0),
8446           CE->getArg(1), CE->getSourceRange(), CE->getOperatorLoc());
8447     }
8448   }
8449   if (Res)
8450     return *Res;
8451   if (dependent() || SemaRef.CurContext->isDependentContext())
8452     return false;
8453   SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
8454       << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
8455   return true;
8456 }
8457 
8458 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
8459   // RHS of canonical loop form increment can be:
8460   //   var + incr
8461   //   incr + var
8462   //   var - incr
8463   //
8464   RHS = RHS->IgnoreParenImpCasts();
8465   if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
8466     if (BO->isAdditiveOp()) {
8467       bool IsAdd = BO->getOpcode() == BO_Add;
8468       if (getInitLCDecl(BO->getLHS()) == LCDecl)
8469         return setStep(BO->getRHS(), !IsAdd);
8470       if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
8471         return setStep(BO->getLHS(), /*Subtract=*/false);
8472     }
8473   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
8474     bool IsAdd = CE->getOperator() == OO_Plus;
8475     if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
8476       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8477         return setStep(CE->getArg(1), !IsAdd);
8478       if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
8479         return setStep(CE->getArg(0), /*Subtract=*/false);
8480     }
8481   }
8482   if (dependent() || SemaRef.CurContext->isDependentContext())
8483     return false;
8484   SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
8485       << RHS->getSourceRange() << LCDecl;
8486   return true;
8487 }
8488 
8489 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
8490   // Check incr-expr for canonical loop form and return true if it
8491   // does not conform.
8492   // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
8493   //   ++var
8494   //   var++
8495   //   --var
8496   //   var--
8497   //   var += incr
8498   //   var -= incr
8499   //   var = var + incr
8500   //   var = incr + var
8501   //   var = var - incr
8502   //
8503   if (!S) {
8504     SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
8505     return true;
8506   }
8507   if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
8508     if (!ExprTemp->cleanupsHaveSideEffects())
8509       S = ExprTemp->getSubExpr();
8510 
8511   IncrementSrcRange = S->getSourceRange();
8512   S = S->IgnoreParens();
8513   if (auto *UO = dyn_cast<UnaryOperator>(S)) {
8514     if (UO->isIncrementDecrementOp() &&
8515         getInitLCDecl(UO->getSubExpr()) == LCDecl)
8516       return setStep(SemaRef
8517                          .ActOnIntegerConstant(UO->getBeginLoc(),
8518                                                (UO->isDecrementOp() ? -1 : 1))
8519                          .get(),
8520                      /*Subtract=*/false);
8521   } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
8522     switch (BO->getOpcode()) {
8523     case BO_AddAssign:
8524     case BO_SubAssign:
8525       if (getInitLCDecl(BO->getLHS()) == LCDecl)
8526         return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
8527       break;
8528     case BO_Assign:
8529       if (getInitLCDecl(BO->getLHS()) == LCDecl)
8530         return checkAndSetIncRHS(BO->getRHS());
8531       break;
8532     default:
8533       break;
8534     }
8535   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8536     switch (CE->getOperator()) {
8537     case OO_PlusPlus:
8538     case OO_MinusMinus:
8539       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8540         return setStep(SemaRef
8541                            .ActOnIntegerConstant(
8542                                CE->getBeginLoc(),
8543                                ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
8544                            .get(),
8545                        /*Subtract=*/false);
8546       break;
8547     case OO_PlusEqual:
8548     case OO_MinusEqual:
8549       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8550         return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
8551       break;
8552     case OO_Equal:
8553       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8554         return checkAndSetIncRHS(CE->getArg(1));
8555       break;
8556     default:
8557       break;
8558     }
8559   }
8560   if (dependent() || SemaRef.CurContext->isDependentContext())
8561     return false;
8562   SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
8563       << S->getSourceRange() << LCDecl;
8564   return true;
8565 }
8566 
8567 static ExprResult
8568 tryBuildCapture(Sema &SemaRef, Expr *Capture,
8569                 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8570                 StringRef Name = ".capture_expr.") {
8571   if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors())
8572     return Capture;
8573   if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
8574     return SemaRef.PerformImplicitConversion(
8575         Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
8576         /*AllowExplicit=*/true);
8577   auto I = Captures.find(Capture);
8578   if (I != Captures.end())
8579     return buildCapture(SemaRef, Capture, I->second, Name);
8580   DeclRefExpr *Ref = nullptr;
8581   ExprResult Res = buildCapture(SemaRef, Capture, Ref, Name);
8582   Captures[Capture] = Ref;
8583   return Res;
8584 }
8585 
8586 /// Calculate number of iterations, transforming to unsigned, if number of
8587 /// iterations may be larger than the original type.
8588 static Expr *
8589 calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc,
8590                   Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy,
8591                   bool TestIsStrictOp, bool RoundToStep,
8592                   llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8593   ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures, ".new_step");
8594   if (!NewStep.isUsable())
8595     return nullptr;
8596   llvm::APSInt LRes, SRes;
8597   bool IsLowerConst = false, IsStepConst = false;
8598   if (std::optional<llvm::APSInt> Res =
8599           Lower->getIntegerConstantExpr(SemaRef.Context)) {
8600     LRes = *Res;
8601     IsLowerConst = true;
8602   }
8603   if (std::optional<llvm::APSInt> Res =
8604           Step->getIntegerConstantExpr(SemaRef.Context)) {
8605     SRes = *Res;
8606     IsStepConst = true;
8607   }
8608   bool NoNeedToConvert = IsLowerConst && !RoundToStep &&
8609                          ((!TestIsStrictOp && LRes.isNonNegative()) ||
8610                           (TestIsStrictOp && LRes.isStrictlyPositive()));
8611   bool NeedToReorganize = false;
8612   // Check if any subexpressions in Lower -Step [+ 1] lead to overflow.
8613   if (!NoNeedToConvert && IsLowerConst &&
8614       (TestIsStrictOp || (RoundToStep && IsStepConst))) {
8615     NoNeedToConvert = true;
8616     if (RoundToStep) {
8617       unsigned BW = LRes.getBitWidth() > SRes.getBitWidth()
8618                         ? LRes.getBitWidth()
8619                         : SRes.getBitWidth();
8620       LRes = LRes.extend(BW + 1);
8621       LRes.setIsSigned(true);
8622       SRes = SRes.extend(BW + 1);
8623       SRes.setIsSigned(true);
8624       LRes -= SRes;
8625       NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes;
8626       LRes = LRes.trunc(BW);
8627     }
8628     if (TestIsStrictOp) {
8629       unsigned BW = LRes.getBitWidth();
8630       LRes = LRes.extend(BW + 1);
8631       LRes.setIsSigned(true);
8632       ++LRes;
8633       NoNeedToConvert =
8634           NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes;
8635       // truncate to the original bitwidth.
8636       LRes = LRes.trunc(BW);
8637     }
8638     NeedToReorganize = NoNeedToConvert;
8639   }
8640   llvm::APSInt URes;
8641   bool IsUpperConst = false;
8642   if (std::optional<llvm::APSInt> Res =
8643           Upper->getIntegerConstantExpr(SemaRef.Context)) {
8644     URes = *Res;
8645     IsUpperConst = true;
8646   }
8647   if (NoNeedToConvert && IsLowerConst && IsUpperConst &&
8648       (!RoundToStep || IsStepConst)) {
8649     unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth()
8650                                                           : URes.getBitWidth();
8651     LRes = LRes.extend(BW + 1);
8652     LRes.setIsSigned(true);
8653     URes = URes.extend(BW + 1);
8654     URes.setIsSigned(true);
8655     URes -= LRes;
8656     NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes;
8657     NeedToReorganize = NoNeedToConvert;
8658   }
8659   // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant
8660   // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to
8661   // unsigned.
8662   if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) &&
8663       !LCTy->isDependentType() && LCTy->isIntegerType()) {
8664     QualType LowerTy = Lower->getType();
8665     QualType UpperTy = Upper->getType();
8666     uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy);
8667     uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy);
8668     if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) ||
8669         (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) {
8670       QualType CastType = SemaRef.Context.getIntTypeForBitwidth(
8671           LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0);
8672       Upper =
8673           SemaRef
8674               .PerformImplicitConversion(
8675                   SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
8676                   CastType, Sema::AA_Converting)
8677               .get();
8678       Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get();
8679       NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get());
8680     }
8681   }
8682   if (!Lower || !Upper || NewStep.isInvalid())
8683     return nullptr;
8684 
8685   ExprResult Diff;
8686   // If need to reorganize, then calculate the form as Upper - (Lower - Step [+
8687   // 1]).
8688   if (NeedToReorganize) {
8689     Diff = Lower;
8690 
8691     if (RoundToStep) {
8692       // Lower - Step
8693       Diff =
8694           SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get());
8695       if (!Diff.isUsable())
8696         return nullptr;
8697     }
8698 
8699     // Lower - Step [+ 1]
8700     if (TestIsStrictOp)
8701       Diff = SemaRef.BuildBinOp(
8702           S, DefaultLoc, BO_Add, Diff.get(),
8703           SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8704     if (!Diff.isUsable())
8705       return nullptr;
8706 
8707     Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8708     if (!Diff.isUsable())
8709       return nullptr;
8710 
8711     // Upper - (Lower - Step [+ 1]).
8712     Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get());
8713     if (!Diff.isUsable())
8714       return nullptr;
8715   } else {
8716     Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
8717 
8718     if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) {
8719       // BuildBinOp already emitted error, this one is to point user to upper
8720       // and lower bound, and to tell what is passed to 'operator-'.
8721       SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
8722           << Upper->getSourceRange() << Lower->getSourceRange();
8723       return nullptr;
8724     }
8725 
8726     if (!Diff.isUsable())
8727       return nullptr;
8728 
8729     // Upper - Lower [- 1]
8730     if (TestIsStrictOp)
8731       Diff = SemaRef.BuildBinOp(
8732           S, DefaultLoc, BO_Sub, Diff.get(),
8733           SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8734     if (!Diff.isUsable())
8735       return nullptr;
8736 
8737     if (RoundToStep) {
8738       // Upper - Lower [- 1] + Step
8739       Diff =
8740           SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
8741       if (!Diff.isUsable())
8742         return nullptr;
8743     }
8744   }
8745 
8746   // Parentheses (for dumping/debugging purposes only).
8747   Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8748   if (!Diff.isUsable())
8749     return nullptr;
8750 
8751   // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step
8752   Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
8753   if (!Diff.isUsable())
8754     return nullptr;
8755 
8756   return Diff.get();
8757 }
8758 
8759 /// Build the expression to calculate the number of iterations.
8760 Expr *OpenMPIterationSpaceChecker::buildNumIterations(
8761     Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
8762     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8763   QualType VarType = LCDecl->getType().getNonReferenceType();
8764   if (!VarType->isIntegerType() && !VarType->isPointerType() &&
8765       !SemaRef.getLangOpts().CPlusPlus)
8766     return nullptr;
8767   Expr *LBVal = LB;
8768   Expr *UBVal = UB;
8769   // OuterVar = (LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
8770   // max(LB(MinVal), LB(MaxVal)))
8771   if (InitDependOnLC) {
8772     const LoopIterationSpace &IS = ResultIterSpaces[*InitDependOnLC - 1];
8773     if (!IS.MinValue || !IS.MaxValue)
8774       return nullptr;
8775     // OuterVar = Min
8776     ExprResult MinValue =
8777         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8778     if (!MinValue.isUsable())
8779       return nullptr;
8780 
8781     ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8782                                              IS.CounterVar, MinValue.get());
8783     if (!LBMinVal.isUsable())
8784       return nullptr;
8785     // OuterVar = Min, LBVal
8786     LBMinVal =
8787         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal);
8788     if (!LBMinVal.isUsable())
8789       return nullptr;
8790     // (OuterVar = Min, LBVal)
8791     LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get());
8792     if (!LBMinVal.isUsable())
8793       return nullptr;
8794 
8795     // OuterVar = Max
8796     ExprResult MaxValue =
8797         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8798     if (!MaxValue.isUsable())
8799       return nullptr;
8800 
8801     ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8802                                              IS.CounterVar, MaxValue.get());
8803     if (!LBMaxVal.isUsable())
8804       return nullptr;
8805     // OuterVar = Max, LBVal
8806     LBMaxVal =
8807         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal);
8808     if (!LBMaxVal.isUsable())
8809       return nullptr;
8810     // (OuterVar = Max, LBVal)
8811     LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get());
8812     if (!LBMaxVal.isUsable())
8813       return nullptr;
8814 
8815     Expr *LBMin =
8816         tryBuildCapture(SemaRef, LBMinVal.get(), Captures, ".lb_min").get();
8817     Expr *LBMax =
8818         tryBuildCapture(SemaRef, LBMaxVal.get(), Captures, ".lb_max").get();
8819     if (!LBMin || !LBMax)
8820       return nullptr;
8821     // LB(MinVal) < LB(MaxVal)
8822     ExprResult MinLessMaxRes =
8823         SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
8824     if (!MinLessMaxRes.isUsable())
8825       return nullptr;
8826     Expr *MinLessMax =
8827         tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures, ".min_less_max")
8828             .get();
8829     if (!MinLessMax)
8830       return nullptr;
8831     if (*TestIsLessOp) {
8832       // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
8833       // LB(MaxVal))
8834       ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8835                                                     MinLessMax, LBMin, LBMax);
8836       if (!MinLB.isUsable())
8837         return nullptr;
8838       LBVal = MinLB.get();
8839     } else {
8840       // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
8841       // LB(MaxVal))
8842       ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8843                                                     MinLessMax, LBMax, LBMin);
8844       if (!MaxLB.isUsable())
8845         return nullptr;
8846       LBVal = MaxLB.get();
8847     }
8848     // OuterVar = LB
8849     LBMinVal =
8850         SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, IS.CounterVar, LBVal);
8851     if (!LBMinVal.isUsable())
8852       return nullptr;
8853     LBVal = LBMinVal.get();
8854   }
8855   // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
8856   // min(UB(MinVal), UB(MaxVal))
8857   if (CondDependOnLC) {
8858     const LoopIterationSpace &IS = ResultIterSpaces[*CondDependOnLC - 1];
8859     if (!IS.MinValue || !IS.MaxValue)
8860       return nullptr;
8861     // OuterVar = Min
8862     ExprResult MinValue =
8863         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8864     if (!MinValue.isUsable())
8865       return nullptr;
8866 
8867     ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8868                                              IS.CounterVar, MinValue.get());
8869     if (!UBMinVal.isUsable())
8870       return nullptr;
8871     // OuterVar = Min, UBVal
8872     UBMinVal =
8873         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal);
8874     if (!UBMinVal.isUsable())
8875       return nullptr;
8876     // (OuterVar = Min, UBVal)
8877     UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get());
8878     if (!UBMinVal.isUsable())
8879       return nullptr;
8880 
8881     // OuterVar = Max
8882     ExprResult MaxValue =
8883         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8884     if (!MaxValue.isUsable())
8885       return nullptr;
8886 
8887     ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8888                                              IS.CounterVar, MaxValue.get());
8889     if (!UBMaxVal.isUsable())
8890       return nullptr;
8891     // OuterVar = Max, UBVal
8892     UBMaxVal =
8893         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal);
8894     if (!UBMaxVal.isUsable())
8895       return nullptr;
8896     // (OuterVar = Max, UBVal)
8897     UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get());
8898     if (!UBMaxVal.isUsable())
8899       return nullptr;
8900 
8901     Expr *UBMin =
8902         tryBuildCapture(SemaRef, UBMinVal.get(), Captures, ".ub_min").get();
8903     Expr *UBMax =
8904         tryBuildCapture(SemaRef, UBMaxVal.get(), Captures, ".ub_max").get();
8905     if (!UBMin || !UBMax)
8906       return nullptr;
8907     // UB(MinVal) > UB(MaxVal)
8908     ExprResult MinGreaterMaxRes =
8909         SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
8910     if (!MinGreaterMaxRes.isUsable())
8911       return nullptr;
8912     Expr *MinGreaterMax = tryBuildCapture(SemaRef, MinGreaterMaxRes.get(),
8913                                           Captures, ".min_greater_max")
8914                               .get();
8915     if (!MinGreaterMax)
8916       return nullptr;
8917     if (*TestIsLessOp) {
8918       // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
8919       // UB(MaxVal))
8920       ExprResult MaxUB = SemaRef.ActOnConditionalOp(
8921           DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
8922       if (!MaxUB.isUsable())
8923         return nullptr;
8924       UBVal = MaxUB.get();
8925     } else {
8926       // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
8927       // UB(MaxVal))
8928       ExprResult MinUB = SemaRef.ActOnConditionalOp(
8929           DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
8930       if (!MinUB.isUsable())
8931         return nullptr;
8932       UBVal = MinUB.get();
8933     }
8934   }
8935   Expr *UBExpr = *TestIsLessOp ? UBVal : LBVal;
8936   Expr *LBExpr = *TestIsLessOp ? LBVal : UBVal;
8937   Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures, ".upper").get();
8938   Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures, ".lower").get();
8939   if (!Upper || !Lower)
8940     return nullptr;
8941 
8942   ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8943                                       Step, VarType, TestIsStrictOp,
8944                                       /*RoundToStep=*/true, Captures);
8945   if (!Diff.isUsable())
8946     return nullptr;
8947 
8948   // OpenMP runtime requires 32-bit or 64-bit loop variables.
8949   QualType Type = Diff.get()->getType();
8950   ASTContext &C = SemaRef.Context;
8951   bool UseVarType = VarType->hasIntegerRepresentation() &&
8952                     C.getTypeSize(Type) > C.getTypeSize(VarType);
8953   if (!Type->isIntegerType() || UseVarType) {
8954     unsigned NewSize =
8955         UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
8956     bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
8957                                : Type->hasSignedIntegerRepresentation();
8958     Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
8959     if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
8960       Diff = SemaRef.PerformImplicitConversion(
8961           Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
8962       if (!Diff.isUsable())
8963         return nullptr;
8964     }
8965   }
8966   if (LimitedType) {
8967     unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
8968     if (NewSize != C.getTypeSize(Type)) {
8969       if (NewSize < C.getTypeSize(Type)) {
8970         assert(NewSize == 64 && "incorrect loop var size");
8971         SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
8972             << InitSrcRange << ConditionSrcRange;
8973       }
8974       QualType NewType = C.getIntTypeForBitwidth(
8975           NewSize, Type->hasSignedIntegerRepresentation() ||
8976                        C.getTypeSize(Type) < NewSize);
8977       if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
8978         Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
8979                                                  Sema::AA_Converting, true);
8980         if (!Diff.isUsable())
8981           return nullptr;
8982       }
8983     }
8984   }
8985 
8986   return Diff.get();
8987 }
8988 
8989 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
8990     Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8991   // Do not build for iterators, they cannot be used in non-rectangular loop
8992   // nests.
8993   if (LCDecl->getType()->isRecordType())
8994     return std::make_pair(nullptr, nullptr);
8995   // If we subtract, the min is in the condition, otherwise the min is in the
8996   // init value.
8997   Expr *MinExpr = nullptr;
8998   Expr *MaxExpr = nullptr;
8999   Expr *LBExpr = *TestIsLessOp ? LB : UB;
9000   Expr *UBExpr = *TestIsLessOp ? UB : LB;
9001   bool LBNonRect =
9002       *TestIsLessOp ? InitDependOnLC.has_value() : CondDependOnLC.has_value();
9003   bool UBNonRect =
9004       *TestIsLessOp ? CondDependOnLC.has_value() : InitDependOnLC.has_value();
9005   Expr *Lower =
9006       LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
9007   Expr *Upper =
9008       UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
9009   if (!Upper || !Lower)
9010     return std::make_pair(nullptr, nullptr);
9011 
9012   if (*TestIsLessOp)
9013     MinExpr = Lower;
9014   else
9015     MaxExpr = Upper;
9016 
9017   // Build minimum/maximum value based on number of iterations.
9018   QualType VarType = LCDecl->getType().getNonReferenceType();
9019 
9020   ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
9021                                       Step, VarType, TestIsStrictOp,
9022                                       /*RoundToStep=*/false, Captures);
9023   if (!Diff.isUsable())
9024     return std::make_pair(nullptr, nullptr);
9025 
9026   // ((Upper - Lower [- 1]) / Step) * Step
9027   // Parentheses (for dumping/debugging purposes only).
9028   Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
9029   if (!Diff.isUsable())
9030     return std::make_pair(nullptr, nullptr);
9031 
9032   ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures, ".new_step");
9033   if (!NewStep.isUsable())
9034     return std::make_pair(nullptr, nullptr);
9035   Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get());
9036   if (!Diff.isUsable())
9037     return std::make_pair(nullptr, nullptr);
9038 
9039   // Parentheses (for dumping/debugging purposes only).
9040   Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
9041   if (!Diff.isUsable())
9042     return std::make_pair(nullptr, nullptr);
9043 
9044   // Convert to the ptrdiff_t, if original type is pointer.
9045   if (VarType->isAnyPointerType() &&
9046       !SemaRef.Context.hasSameType(
9047           Diff.get()->getType(),
9048           SemaRef.Context.getUnsignedPointerDiffType())) {
9049     Diff = SemaRef.PerformImplicitConversion(
9050         Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(),
9051         Sema::AA_Converting, /*AllowExplicit=*/true);
9052   }
9053   if (!Diff.isUsable())
9054     return std::make_pair(nullptr, nullptr);
9055 
9056   if (*TestIsLessOp) {
9057     // MinExpr = Lower;
9058     // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
9059     Diff = SemaRef.BuildBinOp(
9060         S, DefaultLoc, BO_Add,
9061         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(),
9062         Diff.get());
9063     if (!Diff.isUsable())
9064       return std::make_pair(nullptr, nullptr);
9065   } else {
9066     // MaxExpr = Upper;
9067     // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
9068     Diff = SemaRef.BuildBinOp(
9069         S, DefaultLoc, BO_Sub,
9070         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
9071         Diff.get());
9072     if (!Diff.isUsable())
9073       return std::make_pair(nullptr, nullptr);
9074   }
9075 
9076   // Convert to the original type.
9077   if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType))
9078     Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType,
9079                                              Sema::AA_Converting,
9080                                              /*AllowExplicit=*/true);
9081   if (!Diff.isUsable())
9082     return std::make_pair(nullptr, nullptr);
9083 
9084   Sema::TentativeAnalysisScope Trap(SemaRef);
9085   Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false);
9086   if (!Diff.isUsable())
9087     return std::make_pair(nullptr, nullptr);
9088 
9089   if (*TestIsLessOp)
9090     MaxExpr = Diff.get();
9091   else
9092     MinExpr = Diff.get();
9093 
9094   return std::make_pair(MinExpr, MaxExpr);
9095 }
9096 
9097 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const {
9098   if (InitDependOnLC || CondDependOnLC)
9099     return Condition;
9100   return nullptr;
9101 }
9102 
9103 Expr *OpenMPIterationSpaceChecker::buildPreCond(
9104     Scope *S, Expr *Cond,
9105     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
9106   // Do not build a precondition when the condition/initialization is dependent
9107   // to prevent pessimistic early loop exit.
9108   // TODO: this can be improved by calculating min/max values but not sure that
9109   // it will be very effective.
9110   if (CondDependOnLC || InitDependOnLC)
9111     return SemaRef
9112         .PerformImplicitConversion(
9113             SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(),
9114             SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
9115             /*AllowExplicit=*/true)
9116         .get();
9117 
9118   // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
9119   Sema::TentativeAnalysisScope Trap(SemaRef);
9120 
9121   ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
9122   ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
9123   if (!NewLB.isUsable() || !NewUB.isUsable())
9124     return nullptr;
9125 
9126   ExprResult CondExpr =
9127       SemaRef.BuildBinOp(S, DefaultLoc,
9128                          *TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE)
9129                                        : (TestIsStrictOp ? BO_GT : BO_GE),
9130                          NewLB.get(), NewUB.get());
9131   if (CondExpr.isUsable()) {
9132     if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
9133                                                 SemaRef.Context.BoolTy))
9134       CondExpr = SemaRef.PerformImplicitConversion(
9135           CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
9136           /*AllowExplicit=*/true);
9137   }
9138 
9139   // Otherwise use original loop condition and evaluate it in runtime.
9140   return CondExpr.isUsable() ? CondExpr.get() : Cond;
9141 }
9142 
9143 /// Build reference expression to the counter be used for codegen.
9144 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
9145     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
9146     DSAStackTy &DSA) const {
9147   auto *VD = dyn_cast<VarDecl>(LCDecl);
9148   if (!VD) {
9149     VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
9150     DeclRefExpr *Ref = buildDeclRefExpr(
9151         SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
9152     const DSAStackTy::DSAVarData Data =
9153         DSA.getTopDSA(LCDecl, /*FromParent=*/false);
9154     // If the loop control decl is explicitly marked as private, do not mark it
9155     // as captured again.
9156     if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
9157       Captures.insert(std::make_pair(LCRef, Ref));
9158     return Ref;
9159   }
9160   return cast<DeclRefExpr>(LCRef);
9161 }
9162 
9163 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
9164   if (LCDecl && !LCDecl->isInvalidDecl()) {
9165     QualType Type = LCDecl->getType().getNonReferenceType();
9166     VarDecl *PrivateVar = buildVarDecl(
9167         SemaRef, DefaultLoc, Type, LCDecl->getName(),
9168         LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
9169         isa<VarDecl>(LCDecl)
9170             ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
9171             : nullptr);
9172     if (PrivateVar->isInvalidDecl())
9173       return nullptr;
9174     return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
9175   }
9176   return nullptr;
9177 }
9178 
9179 /// Build initialization of the counter to be used for codegen.
9180 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
9181 
9182 /// Build step of the counter be used for codegen.
9183 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
9184 
9185 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
9186     Scope *S, Expr *Counter,
9187     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
9188     Expr *Inc, OverloadedOperatorKind OOK) {
9189   Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
9190   if (!Cnt)
9191     return nullptr;
9192   if (Inc) {
9193     assert((OOK == OO_Plus || OOK == OO_Minus) &&
9194            "Expected only + or - operations for depend clauses.");
9195     BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
9196     Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
9197     if (!Cnt)
9198       return nullptr;
9199   }
9200   QualType VarType = LCDecl->getType().getNonReferenceType();
9201   if (!VarType->isIntegerType() && !VarType->isPointerType() &&
9202       !SemaRef.getLangOpts().CPlusPlus)
9203     return nullptr;
9204   // Upper - Lower
9205   Expr *Upper =
9206       *TestIsLessOp ? Cnt : tryBuildCapture(SemaRef, LB, Captures).get();
9207   Expr *Lower =
9208       *TestIsLessOp ? tryBuildCapture(SemaRef, LB, Captures).get() : Cnt;
9209   if (!Upper || !Lower)
9210     return nullptr;
9211 
9212   ExprResult Diff = calculateNumIters(
9213       SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
9214       /*TestIsStrictOp=*/false, /*RoundToStep=*/false, Captures);
9215   if (!Diff.isUsable())
9216     return nullptr;
9217 
9218   return Diff.get();
9219 }
9220 } // namespace
9221 
9222 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
9223   assert(getLangOpts().OpenMP && "OpenMP is not active.");
9224   assert(Init && "Expected loop in canonical form.");
9225   unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
9226   if (AssociatedLoops > 0 &&
9227       isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
9228     DSAStack->loopStart();
9229     OpenMPIterationSpaceChecker ISC(*this, /*SupportsNonRectangular=*/true,
9230                                     *DSAStack, ForLoc);
9231     if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
9232       if (ValueDecl *D = ISC.getLoopDecl()) {
9233         auto *VD = dyn_cast<VarDecl>(D);
9234         DeclRefExpr *PrivateRef = nullptr;
9235         if (!VD) {
9236           if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
9237             VD = Private;
9238           } else {
9239             PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
9240                                       /*WithInit=*/false);
9241             VD = cast<VarDecl>(PrivateRef->getDecl());
9242           }
9243         }
9244         DSAStack->addLoopControlVariable(D, VD);
9245         const Decl *LD = DSAStack->getPossiblyLoopCunter();
9246         if (LD != D->getCanonicalDecl()) {
9247           DSAStack->resetPossibleLoopCounter();
9248           if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
9249             MarkDeclarationsReferencedInExpr(
9250                 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
9251                                  Var->getType().getNonLValueExprType(Context),
9252                                  ForLoc, /*RefersToCapture=*/true));
9253         }
9254         OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
9255         // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
9256         // Referenced in a Construct, C/C++]. The loop iteration variable in the
9257         // associated for-loop of a simd construct with just one associated
9258         // for-loop may be listed in a linear clause with a constant-linear-step
9259         // that is the increment of the associated for-loop. The loop iteration
9260         // variable(s) in the associated for-loop(s) of a for or parallel for
9261         // construct may be listed in a private or lastprivate clause.
9262         DSAStackTy::DSAVarData DVar =
9263             DSAStack->getTopDSA(D, /*FromParent=*/false);
9264         // If LoopVarRefExpr is nullptr it means the corresponding loop variable
9265         // is declared in the loop and it is predetermined as a private.
9266         Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
9267         OpenMPClauseKind PredeterminedCKind =
9268             isOpenMPSimdDirective(DKind)
9269                 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
9270                 : OMPC_private;
9271         if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
9272               DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
9273               (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
9274                                          DVar.CKind != OMPC_private))) ||
9275              ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
9276                DKind == OMPD_master_taskloop || DKind == OMPD_masked_taskloop ||
9277                DKind == OMPD_parallel_master_taskloop ||
9278                DKind == OMPD_parallel_masked_taskloop ||
9279                isOpenMPDistributeDirective(DKind)) &&
9280               !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
9281               DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
9282             (DVar.CKind != OMPC_private || DVar.RefExpr)) {
9283           Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
9284               << getOpenMPClauseName(DVar.CKind)
9285               << getOpenMPDirectiveName(DKind)
9286               << getOpenMPClauseName(PredeterminedCKind);
9287           if (DVar.RefExpr == nullptr)
9288             DVar.CKind = PredeterminedCKind;
9289           reportOriginalDsa(*this, DSAStack, D, DVar,
9290                             /*IsLoopIterVar=*/true);
9291         } else if (LoopDeclRefExpr) {
9292           // Make the loop iteration variable private (for worksharing
9293           // constructs), linear (for simd directives with the only one
9294           // associated loop) or lastprivate (for simd directives with several
9295           // collapsed or ordered loops).
9296           if (DVar.CKind == OMPC_unknown)
9297             DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
9298                              PrivateRef);
9299         }
9300       }
9301     }
9302     DSAStack->setAssociatedLoops(AssociatedLoops - 1);
9303   }
9304 }
9305 
9306 namespace {
9307 // Utility for openmp doacross clause kind
9308 class OMPDoacrossKind {
9309 public:
9310   bool isSource(const OMPDoacrossClause *C) {
9311     return C->getDependenceType() == OMPC_DOACROSS_source ||
9312            C->getDependenceType() == OMPC_DOACROSS_source_omp_cur_iteration;
9313   }
9314   bool isSink(const OMPDoacrossClause *C) {
9315     return C->getDependenceType() == OMPC_DOACROSS_sink;
9316   }
9317   bool isSinkIter(const OMPDoacrossClause *C) {
9318     return C->getDependenceType() == OMPC_DOACROSS_sink_omp_cur_iteration;
9319   }
9320 };
9321 } // namespace
9322 /// Called on a for stmt to check and extract its iteration space
9323 /// for further processing (such as collapsing).
9324 static bool checkOpenMPIterationSpace(
9325     OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
9326     unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
9327     unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
9328     Expr *OrderedLoopCountExpr,
9329     Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
9330     llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,
9331     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9332   bool SupportsNonRectangular = !isOpenMPLoopTransformationDirective(DKind);
9333   // OpenMP [2.9.1, Canonical Loop Form]
9334   //   for (init-expr; test-expr; incr-expr) structured-block
9335   //   for (range-decl: range-expr) structured-block
9336   if (auto *CanonLoop = dyn_cast_or_null<OMPCanonicalLoop>(S))
9337     S = CanonLoop->getLoopStmt();
9338   auto *For = dyn_cast_or_null<ForStmt>(S);
9339   auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
9340   // Ranged for is supported only in OpenMP 5.0.
9341   if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) {
9342     OpenMPDirectiveKind DK = (SemaRef.getLangOpts().OpenMP < 50 ||
9343                               DSA.getMappedDirective() == OMPD_unknown)
9344                                  ? DKind
9345                                  : DSA.getMappedDirective();
9346     SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
9347         << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
9348         << getOpenMPDirectiveName(DK) << TotalNestedLoopCount
9349         << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
9350     if (TotalNestedLoopCount > 1) {
9351       if (CollapseLoopCountExpr && OrderedLoopCountExpr)
9352         SemaRef.Diag(DSA.getConstructLoc(),
9353                      diag::note_omp_collapse_ordered_expr)
9354             << 2 << CollapseLoopCountExpr->getSourceRange()
9355             << OrderedLoopCountExpr->getSourceRange();
9356       else if (CollapseLoopCountExpr)
9357         SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
9358                      diag::note_omp_collapse_ordered_expr)
9359             << 0 << CollapseLoopCountExpr->getSourceRange();
9360       else
9361         SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
9362                      diag::note_omp_collapse_ordered_expr)
9363             << 1 << OrderedLoopCountExpr->getSourceRange();
9364     }
9365     return true;
9366   }
9367   assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&
9368          "No loop body.");
9369   // Postpone analysis in dependent contexts for ranged for loops.
9370   if (CXXFor && SemaRef.CurContext->isDependentContext())
9371     return false;
9372 
9373   OpenMPIterationSpaceChecker ISC(SemaRef, SupportsNonRectangular, DSA,
9374                                   For ? For->getForLoc() : CXXFor->getForLoc());
9375 
9376   // Check init.
9377   Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt();
9378   if (ISC.checkAndSetInit(Init))
9379     return true;
9380 
9381   bool HasErrors = false;
9382 
9383   // Check loop variable's type.
9384   if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
9385     // OpenMP [2.6, Canonical Loop Form]
9386     // Var is one of the following:
9387     //   A variable of signed or unsigned integer type.
9388     //   For C++, a variable of a random access iterator type.
9389     //   For C, a variable of a pointer type.
9390     QualType VarType = LCDecl->getType().getNonReferenceType();
9391     if (!VarType->isDependentType() && !VarType->isIntegerType() &&
9392         !VarType->isPointerType() &&
9393         !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
9394       SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
9395           << SemaRef.getLangOpts().CPlusPlus;
9396       HasErrors = true;
9397     }
9398 
9399     // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
9400     // a Construct
9401     // The loop iteration variable(s) in the associated for-loop(s) of a for or
9402     // parallel for construct is (are) private.
9403     // The loop iteration variable in the associated for-loop of a simd
9404     // construct with just one associated for-loop is linear with a
9405     // constant-linear-step that is the increment of the associated for-loop.
9406     // Exclude loop var from the list of variables with implicitly defined data
9407     // sharing attributes.
9408     VarsWithImplicitDSA.erase(LCDecl);
9409 
9410     assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
9411 
9412     // Check test-expr.
9413     HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
9414 
9415     // Check incr-expr.
9416     HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
9417   }
9418 
9419   if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
9420     return HasErrors;
9421 
9422   // Build the loop's iteration space representation.
9423   ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
9424       DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
9425   ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
9426       ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
9427                              (isOpenMPWorksharingDirective(DKind) ||
9428                               isOpenMPGenericLoopDirective(DKind) ||
9429                               isOpenMPTaskLoopDirective(DKind) ||
9430                               isOpenMPDistributeDirective(DKind) ||
9431                               isOpenMPLoopTransformationDirective(DKind)),
9432                              Captures);
9433   ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
9434       ISC.buildCounterVar(Captures, DSA);
9435   ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
9436       ISC.buildPrivateCounterVar();
9437   ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
9438   ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
9439   ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
9440   ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
9441       ISC.getConditionSrcRange();
9442   ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
9443       ISC.getIncrementSrcRange();
9444   ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
9445   ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
9446       ISC.isStrictTestOp();
9447   std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
9448            ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
9449       ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
9450   ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
9451       ISC.buildFinalCondition(DSA.getCurScope());
9452   ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
9453       ISC.doesInitDependOnLC();
9454   ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
9455       ISC.doesCondDependOnLC();
9456   ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
9457       ISC.getLoopDependentIdx();
9458 
9459   HasErrors |=
9460       (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr ||
9461        ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr ||
9462        ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr ||
9463        ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr ||
9464        ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr ||
9465        ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr);
9466   if (!HasErrors && DSA.isOrderedRegion()) {
9467     if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
9468       if (CurrentNestedLoopCount <
9469           DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
9470         DSA.getOrderedRegionParam().second->setLoopNumIterations(
9471             CurrentNestedLoopCount,
9472             ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
9473         DSA.getOrderedRegionParam().second->setLoopCounter(
9474             CurrentNestedLoopCount,
9475             ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
9476       }
9477     }
9478     for (auto &Pair : DSA.getDoacrossDependClauses()) {
9479       auto *DependC = dyn_cast<OMPDependClause>(Pair.first);
9480       auto *DoacrossC = dyn_cast<OMPDoacrossClause>(Pair.first);
9481       unsigned NumLoops =
9482           DependC ? DependC->getNumLoops() : DoacrossC->getNumLoops();
9483       if (CurrentNestedLoopCount >= NumLoops) {
9484         // Erroneous case - clause has some problems.
9485         continue;
9486       }
9487       if (DependC && DependC->getDependencyKind() == OMPC_DEPEND_sink &&
9488           Pair.second.size() <= CurrentNestedLoopCount) {
9489         // Erroneous case - clause has some problems.
9490         DependC->setLoopData(CurrentNestedLoopCount, nullptr);
9491         continue;
9492       }
9493       OMPDoacrossKind ODK;
9494       if (DoacrossC && ODK.isSink(DoacrossC) &&
9495           Pair.second.size() <= CurrentNestedLoopCount) {
9496         // Erroneous case - clause has some problems.
9497         DoacrossC->setLoopData(CurrentNestedLoopCount, nullptr);
9498         continue;
9499       }
9500       Expr *CntValue;
9501       SourceLocation DepLoc =
9502           DependC ? DependC->getDependencyLoc() : DoacrossC->getDependenceLoc();
9503       if ((DependC && DependC->getDependencyKind() == OMPC_DEPEND_source) ||
9504           (DoacrossC && ODK.isSource(DoacrossC)))
9505         CntValue = ISC.buildOrderedLoopData(
9506             DSA.getCurScope(),
9507             ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9508             DepLoc);
9509       else if (DoacrossC && ODK.isSinkIter(DoacrossC)) {
9510         Expr *Cnt = SemaRef
9511                         .DefaultLvalueConversion(
9512                             ResultIterSpaces[CurrentNestedLoopCount].CounterVar)
9513                         .get();
9514         if (!Cnt)
9515           continue;
9516         // build CounterVar - 1
9517         Expr *Inc =
9518             SemaRef.ActOnIntegerConstant(DoacrossC->getColonLoc(), /*Val=*/1)
9519                 .get();
9520         CntValue = ISC.buildOrderedLoopData(
9521             DSA.getCurScope(),
9522             ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9523             DepLoc, Inc, clang::OO_Minus);
9524       } else
9525         CntValue = ISC.buildOrderedLoopData(
9526             DSA.getCurScope(),
9527             ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
9528             DepLoc, Pair.second[CurrentNestedLoopCount].first,
9529             Pair.second[CurrentNestedLoopCount].second);
9530       if (DependC)
9531         DependC->setLoopData(CurrentNestedLoopCount, CntValue);
9532       else
9533         DoacrossC->setLoopData(CurrentNestedLoopCount, CntValue);
9534     }
9535   }
9536 
9537   return HasErrors;
9538 }
9539 
9540 /// Build 'VarRef = Start.
9541 static ExprResult
9542 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
9543                  ExprResult Start, bool IsNonRectangularLB,
9544                  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9545   // Build 'VarRef = Start.
9546   ExprResult NewStart = IsNonRectangularLB
9547                             ? Start.get()
9548                             : tryBuildCapture(SemaRef, Start.get(), Captures);
9549   if (!NewStart.isUsable())
9550     return ExprError();
9551   if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
9552                                    VarRef.get()->getType())) {
9553     NewStart = SemaRef.PerformImplicitConversion(
9554         NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
9555         /*AllowExplicit=*/true);
9556     if (!NewStart.isUsable())
9557       return ExprError();
9558   }
9559 
9560   ExprResult Init =
9561       SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
9562   return Init;
9563 }
9564 
9565 /// Build 'VarRef = Start + Iter * Step'.
9566 static ExprResult buildCounterUpdate(
9567     Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
9568     ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
9569     bool IsNonRectangularLB,
9570     llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
9571   // Add parentheses (for debugging purposes only).
9572   Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
9573   if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
9574       !Step.isUsable())
9575     return ExprError();
9576 
9577   ExprResult NewStep = Step;
9578   if (Captures)
9579     NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
9580   if (NewStep.isInvalid())
9581     return ExprError();
9582   ExprResult Update =
9583       SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
9584   if (!Update.isUsable())
9585     return ExprError();
9586 
9587   // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
9588   // 'VarRef = Start (+|-) Iter * Step'.
9589   if (!Start.isUsable())
9590     return ExprError();
9591   ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get());
9592   if (!NewStart.isUsable())
9593     return ExprError();
9594   if (Captures && !IsNonRectangularLB)
9595     NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
9596   if (NewStart.isInvalid())
9597     return ExprError();
9598 
9599   // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
9600   ExprResult SavedUpdate = Update;
9601   ExprResult UpdateVal;
9602   if (VarRef.get()->getType()->isOverloadableType() ||
9603       NewStart.get()->getType()->isOverloadableType() ||
9604       Update.get()->getType()->isOverloadableType()) {
9605     Sema::TentativeAnalysisScope Trap(SemaRef);
9606 
9607     Update =
9608         SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
9609     if (Update.isUsable()) {
9610       UpdateVal =
9611           SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
9612                              VarRef.get(), SavedUpdate.get());
9613       if (UpdateVal.isUsable()) {
9614         Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
9615                                             UpdateVal.get());
9616       }
9617     }
9618   }
9619 
9620   // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
9621   if (!Update.isUsable() || !UpdateVal.isUsable()) {
9622     Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
9623                                 NewStart.get(), SavedUpdate.get());
9624     if (!Update.isUsable())
9625       return ExprError();
9626 
9627     if (!SemaRef.Context.hasSameType(Update.get()->getType(),
9628                                      VarRef.get()->getType())) {
9629       Update = SemaRef.PerformImplicitConversion(
9630           Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
9631       if (!Update.isUsable())
9632         return ExprError();
9633     }
9634 
9635     Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
9636   }
9637   return Update;
9638 }
9639 
9640 /// Convert integer expression \a E to make it have at least \a Bits
9641 /// bits.
9642 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
9643   if (E == nullptr)
9644     return ExprError();
9645   ASTContext &C = SemaRef.Context;
9646   QualType OldType = E->getType();
9647   unsigned HasBits = C.getTypeSize(OldType);
9648   if (HasBits >= Bits)
9649     return ExprResult(E);
9650   // OK to convert to signed, because new type has more bits than old.
9651   QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
9652   return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
9653                                            true);
9654 }
9655 
9656 /// Check if the given expression \a E is a constant integer that fits
9657 /// into \a Bits bits.
9658 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
9659   if (E == nullptr)
9660     return false;
9661   if (std::optional<llvm::APSInt> Result =
9662           E->getIntegerConstantExpr(SemaRef.Context))
9663     return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits);
9664   return false;
9665 }
9666 
9667 /// Build preinits statement for the given declarations.
9668 static Stmt *buildPreInits(ASTContext &Context,
9669                            MutableArrayRef<Decl *> PreInits) {
9670   if (!PreInits.empty()) {
9671     return new (Context) DeclStmt(
9672         DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
9673         SourceLocation(), SourceLocation());
9674   }
9675   return nullptr;
9676 }
9677 
9678 /// Build preinits statement for the given declarations.
9679 static Stmt *
9680 buildPreInits(ASTContext &Context,
9681               const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9682   if (!Captures.empty()) {
9683     SmallVector<Decl *, 16> PreInits;
9684     for (const auto &Pair : Captures)
9685       PreInits.push_back(Pair.second->getDecl());
9686     return buildPreInits(Context, PreInits);
9687   }
9688   return nullptr;
9689 }
9690 
9691 /// Build postupdate expression for the given list of postupdates expressions.
9692 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
9693   Expr *PostUpdate = nullptr;
9694   if (!PostUpdates.empty()) {
9695     for (Expr *E : PostUpdates) {
9696       Expr *ConvE = S.BuildCStyleCastExpr(
9697                          E->getExprLoc(),
9698                          S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
9699                          E->getExprLoc(), E)
9700                         .get();
9701       PostUpdate = PostUpdate
9702                        ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
9703                                               PostUpdate, ConvE)
9704                              .get()
9705                        : ConvE;
9706     }
9707   }
9708   return PostUpdate;
9709 }
9710 
9711 /// Called on a for stmt to check itself and nested loops (if any).
9712 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
9713 /// number of collapsed loops otherwise.
9714 static unsigned
9715 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
9716                 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
9717                 DSAStackTy &DSA,
9718                 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
9719                 OMPLoopBasedDirective::HelperExprs &Built) {
9720   unsigned NestedLoopCount = 1;
9721   bool SupportsNonPerfectlyNested = (SemaRef.LangOpts.OpenMP >= 50) &&
9722                                     !isOpenMPLoopTransformationDirective(DKind);
9723 
9724   if (CollapseLoopCountExpr) {
9725     // Found 'collapse' clause - calculate collapse number.
9726     Expr::EvalResult Result;
9727     if (!CollapseLoopCountExpr->isValueDependent() &&
9728         CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
9729       NestedLoopCount = Result.Val.getInt().getLimitedValue();
9730     } else {
9731       Built.clear(/*Size=*/1);
9732       return 1;
9733     }
9734   }
9735   unsigned OrderedLoopCount = 1;
9736   if (OrderedLoopCountExpr) {
9737     // Found 'ordered' clause - calculate collapse number.
9738     Expr::EvalResult EVResult;
9739     if (!OrderedLoopCountExpr->isValueDependent() &&
9740         OrderedLoopCountExpr->EvaluateAsInt(EVResult,
9741                                             SemaRef.getASTContext())) {
9742       llvm::APSInt Result = EVResult.Val.getInt();
9743       if (Result.getLimitedValue() < NestedLoopCount) {
9744         SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
9745                      diag::err_omp_wrong_ordered_loop_count)
9746             << OrderedLoopCountExpr->getSourceRange();
9747         SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
9748                      diag::note_collapse_loop_count)
9749             << CollapseLoopCountExpr->getSourceRange();
9750       }
9751       OrderedLoopCount = Result.getLimitedValue();
9752     } else {
9753       Built.clear(/*Size=*/1);
9754       return 1;
9755     }
9756   }
9757   // This is helper routine for loop directives (e.g., 'for', 'simd',
9758   // 'for simd', etc.).
9759   llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
9760   unsigned NumLoops = std::max(OrderedLoopCount, NestedLoopCount);
9761   SmallVector<LoopIterationSpace, 4> IterSpaces(NumLoops);
9762   if (!OMPLoopBasedDirective::doForAllLoops(
9763           AStmt->IgnoreContainers(!isOpenMPLoopTransformationDirective(DKind)),
9764           SupportsNonPerfectlyNested, NumLoops,
9765           [DKind, &SemaRef, &DSA, NumLoops, NestedLoopCount,
9766            CollapseLoopCountExpr, OrderedLoopCountExpr, &VarsWithImplicitDSA,
9767            &IterSpaces, &Captures](unsigned Cnt, Stmt *CurStmt) {
9768             if (checkOpenMPIterationSpace(
9769                     DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
9770                     NumLoops, CollapseLoopCountExpr, OrderedLoopCountExpr,
9771                     VarsWithImplicitDSA, IterSpaces, Captures))
9772               return true;
9773             if (Cnt > 0 && Cnt >= NestedLoopCount &&
9774                 IterSpaces[Cnt].CounterVar) {
9775               // Handle initialization of captured loop iterator variables.
9776               auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
9777               if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
9778                 Captures[DRE] = DRE;
9779               }
9780             }
9781             return false;
9782           },
9783           [&SemaRef, &Captures](OMPLoopTransformationDirective *Transform) {
9784             Stmt *DependentPreInits = Transform->getPreInits();
9785             if (!DependentPreInits)
9786               return;
9787             for (Decl *C : cast<DeclStmt>(DependentPreInits)->getDeclGroup()) {
9788               auto *D = cast<VarDecl>(C);
9789               DeclRefExpr *Ref = buildDeclRefExpr(SemaRef, D, D->getType(),
9790                                                   Transform->getBeginLoc());
9791               Captures[Ref] = Ref;
9792             }
9793           }))
9794     return 0;
9795 
9796   Built.clear(/* size */ NestedLoopCount);
9797 
9798   if (SemaRef.CurContext->isDependentContext())
9799     return NestedLoopCount;
9800 
9801   // An example of what is generated for the following code:
9802   //
9803   //   #pragma omp simd collapse(2) ordered(2)
9804   //   for (i = 0; i < NI; ++i)
9805   //     for (k = 0; k < NK; ++k)
9806   //       for (j = J0; j < NJ; j+=2) {
9807   //         <loop body>
9808   //       }
9809   //
9810   // We generate the code below.
9811   // Note: the loop body may be outlined in CodeGen.
9812   // Note: some counters may be C++ classes, operator- is used to find number of
9813   // iterations and operator+= to calculate counter value.
9814   // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
9815   // or i64 is currently supported).
9816   //
9817   //   #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
9818   //   for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
9819   //     .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
9820   //     .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
9821   //     // similar updates for vars in clauses (e.g. 'linear')
9822   //     <loop body (using local i and j)>
9823   //   }
9824   //   i = NI; // assign final values of counters
9825   //   j = NJ;
9826   //
9827 
9828   // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
9829   // the iteration counts of the collapsed for loops.
9830   // Precondition tests if there is at least one iteration (all conditions are
9831   // true).
9832   auto PreCond = ExprResult(IterSpaces[0].PreCond);
9833   Expr *N0 = IterSpaces[0].NumIterations;
9834   ExprResult LastIteration32 =
9835       widenIterationCount(/*Bits=*/32,
9836                           SemaRef
9837                               .PerformImplicitConversion(
9838                                   N0->IgnoreImpCasts(), N0->getType(),
9839                                   Sema::AA_Converting, /*AllowExplicit=*/true)
9840                               .get(),
9841                           SemaRef);
9842   ExprResult LastIteration64 = widenIterationCount(
9843       /*Bits=*/64,
9844       SemaRef
9845           .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
9846                                      Sema::AA_Converting,
9847                                      /*AllowExplicit=*/true)
9848           .get(),
9849       SemaRef);
9850 
9851   if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
9852     return NestedLoopCount;
9853 
9854   ASTContext &C = SemaRef.Context;
9855   bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
9856 
9857   Scope *CurScope = DSA.getCurScope();
9858   for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
9859     if (PreCond.isUsable()) {
9860       PreCond =
9861           SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
9862                              PreCond.get(), IterSpaces[Cnt].PreCond);
9863     }
9864     Expr *N = IterSpaces[Cnt].NumIterations;
9865     SourceLocation Loc = N->getExprLoc();
9866     AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
9867     if (LastIteration32.isUsable())
9868       LastIteration32 = SemaRef.BuildBinOp(
9869           CurScope, Loc, BO_Mul, LastIteration32.get(),
9870           SemaRef
9871               .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
9872                                          Sema::AA_Converting,
9873                                          /*AllowExplicit=*/true)
9874               .get());
9875     if (LastIteration64.isUsable())
9876       LastIteration64 = SemaRef.BuildBinOp(
9877           CurScope, Loc, BO_Mul, LastIteration64.get(),
9878           SemaRef
9879               .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
9880                                          Sema::AA_Converting,
9881                                          /*AllowExplicit=*/true)
9882               .get());
9883   }
9884 
9885   // Choose either the 32-bit or 64-bit version.
9886   ExprResult LastIteration = LastIteration64;
9887   if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
9888       (LastIteration32.isUsable() &&
9889        C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
9890        (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
9891         fitsInto(
9892             /*Bits=*/32,
9893             LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
9894             LastIteration64.get(), SemaRef))))
9895     LastIteration = LastIteration32;
9896   QualType VType = LastIteration.get()->getType();
9897   QualType RealVType = VType;
9898   QualType StrideVType = VType;
9899   if (isOpenMPTaskLoopDirective(DKind)) {
9900     VType =
9901         SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
9902     StrideVType =
9903         SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
9904   }
9905 
9906   if (!LastIteration.isUsable())
9907     return 0;
9908 
9909   // Save the number of iterations.
9910   ExprResult NumIterations = LastIteration;
9911   {
9912     LastIteration = SemaRef.BuildBinOp(
9913         CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
9914         LastIteration.get(),
9915         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9916     if (!LastIteration.isUsable())
9917       return 0;
9918   }
9919 
9920   // Calculate the last iteration number beforehand instead of doing this on
9921   // each iteration. Do not do this if the number of iterations may be kfold-ed.
9922   bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context);
9923   ExprResult CalcLastIteration;
9924   if (!IsConstant) {
9925     ExprResult SaveRef =
9926         tryBuildCapture(SemaRef, LastIteration.get(), Captures);
9927     LastIteration = SaveRef;
9928 
9929     // Prepare SaveRef + 1.
9930     NumIterations = SemaRef.BuildBinOp(
9931         CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
9932         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9933     if (!NumIterations.isUsable())
9934       return 0;
9935   }
9936 
9937   SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
9938 
9939   // Build variables passed into runtime, necessary for worksharing directives.
9940   ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
9941   if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
9942       isOpenMPDistributeDirective(DKind) ||
9943       isOpenMPGenericLoopDirective(DKind) ||
9944       isOpenMPLoopTransformationDirective(DKind)) {
9945     // Lower bound variable, initialized with zero.
9946     VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
9947     LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
9948     SemaRef.AddInitializerToDecl(LBDecl,
9949                                  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9950                                  /*DirectInit*/ false);
9951 
9952     // Upper bound variable, initialized with last iteration number.
9953     VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
9954     UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
9955     SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
9956                                  /*DirectInit*/ false);
9957 
9958     // A 32-bit variable-flag where runtime returns 1 for the last iteration.
9959     // This will be used to implement clause 'lastprivate'.
9960     QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
9961     VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
9962     IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
9963     SemaRef.AddInitializerToDecl(ILDecl,
9964                                  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9965                                  /*DirectInit*/ false);
9966 
9967     // Stride variable returned by runtime (we initialize it to 1 by default).
9968     VarDecl *STDecl =
9969         buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
9970     ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
9971     SemaRef.AddInitializerToDecl(STDecl,
9972                                  SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
9973                                  /*DirectInit*/ false);
9974 
9975     // Build expression: UB = min(UB, LastIteration)
9976     // It is necessary for CodeGen of directives with static scheduling.
9977     ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
9978                                                 UB.get(), LastIteration.get());
9979     ExprResult CondOp = SemaRef.ActOnConditionalOp(
9980         LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
9981         LastIteration.get(), UB.get());
9982     EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
9983                              CondOp.get());
9984     EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
9985 
9986     // If we have a combined directive that combines 'distribute', 'for' or
9987     // 'simd' we need to be able to access the bounds of the schedule of the
9988     // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
9989     // by scheduling 'distribute' have to be passed to the schedule of 'for'.
9990     if (isOpenMPLoopBoundSharingDirective(DKind)) {
9991       // Lower bound variable, initialized with zero.
9992       VarDecl *CombLBDecl =
9993           buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
9994       CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
9995       SemaRef.AddInitializerToDecl(
9996           CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9997           /*DirectInit*/ false);
9998 
9999       // Upper bound variable, initialized with last iteration number.
10000       VarDecl *CombUBDecl =
10001           buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
10002       CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
10003       SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
10004                                    /*DirectInit*/ false);
10005 
10006       ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
10007           CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
10008       ExprResult CombCondOp =
10009           SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
10010                                      LastIteration.get(), CombUB.get());
10011       CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
10012                                    CombCondOp.get());
10013       CombEUB =
10014           SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
10015 
10016       const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
10017       // We expect to have at least 2 more parameters than the 'parallel'
10018       // directive does - the lower and upper bounds of the previous schedule.
10019       assert(CD->getNumParams() >= 4 &&
10020              "Unexpected number of parameters in loop combined directive");
10021 
10022       // Set the proper type for the bounds given what we learned from the
10023       // enclosed loops.
10024       ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
10025       ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
10026 
10027       // Previous lower and upper bounds are obtained from the region
10028       // parameters.
10029       PrevLB =
10030           buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
10031       PrevUB =
10032           buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
10033     }
10034   }
10035 
10036   // Build the iteration variable and its initialization before loop.
10037   ExprResult IV;
10038   ExprResult Init, CombInit;
10039   {
10040     VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
10041     IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
10042     Expr *RHS = (isOpenMPWorksharingDirective(DKind) ||
10043                  isOpenMPGenericLoopDirective(DKind) ||
10044                  isOpenMPTaskLoopDirective(DKind) ||
10045                  isOpenMPDistributeDirective(DKind) ||
10046                  isOpenMPLoopTransformationDirective(DKind))
10047                     ? LB.get()
10048                     : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
10049     Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
10050     Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
10051 
10052     if (isOpenMPLoopBoundSharingDirective(DKind)) {
10053       Expr *CombRHS =
10054           (isOpenMPWorksharingDirective(DKind) ||
10055            isOpenMPGenericLoopDirective(DKind) ||
10056            isOpenMPTaskLoopDirective(DKind) ||
10057            isOpenMPDistributeDirective(DKind))
10058               ? CombLB.get()
10059               : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
10060       CombInit =
10061           SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
10062       CombInit =
10063           SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
10064     }
10065   }
10066 
10067   bool UseStrictCompare =
10068       RealVType->hasUnsignedIntegerRepresentation() &&
10069       llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
10070         return LIS.IsStrictCompare;
10071       });
10072   // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
10073   // unsigned IV)) for worksharing loops.
10074   SourceLocation CondLoc = AStmt->getBeginLoc();
10075   Expr *BoundUB = UB.get();
10076   if (UseStrictCompare) {
10077     BoundUB =
10078         SemaRef
10079             .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
10080                         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
10081             .get();
10082     BoundUB =
10083         SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
10084   }
10085   ExprResult Cond =
10086       (isOpenMPWorksharingDirective(DKind) ||
10087        isOpenMPGenericLoopDirective(DKind) ||
10088        isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind) ||
10089        isOpenMPLoopTransformationDirective(DKind))
10090           ? SemaRef.BuildBinOp(CurScope, CondLoc,
10091                                UseStrictCompare ? BO_LT : BO_LE, IV.get(),
10092                                BoundUB)
10093           : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
10094                                NumIterations.get());
10095   ExprResult CombDistCond;
10096   if (isOpenMPLoopBoundSharingDirective(DKind)) {
10097     CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
10098                                       NumIterations.get());
10099   }
10100 
10101   ExprResult CombCond;
10102   if (isOpenMPLoopBoundSharingDirective(DKind)) {
10103     Expr *BoundCombUB = CombUB.get();
10104     if (UseStrictCompare) {
10105       BoundCombUB =
10106           SemaRef
10107               .BuildBinOp(
10108                   CurScope, CondLoc, BO_Add, BoundCombUB,
10109                   SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
10110               .get();
10111       BoundCombUB =
10112           SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
10113               .get();
10114     }
10115     CombCond =
10116         SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
10117                            IV.get(), BoundCombUB);
10118   }
10119   // Loop increment (IV = IV + 1)
10120   SourceLocation IncLoc = AStmt->getBeginLoc();
10121   ExprResult Inc =
10122       SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
10123                          SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
10124   if (!Inc.isUsable())
10125     return 0;
10126   Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
10127   Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
10128   if (!Inc.isUsable())
10129     return 0;
10130 
10131   // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
10132   // Used for directives with static scheduling.
10133   // In combined construct, add combined version that use CombLB and CombUB
10134   // base variables for the update
10135   ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
10136   if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
10137       isOpenMPGenericLoopDirective(DKind) ||
10138       isOpenMPDistributeDirective(DKind) ||
10139       isOpenMPLoopTransformationDirective(DKind)) {
10140     // LB + ST
10141     NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
10142     if (!NextLB.isUsable())
10143       return 0;
10144     // LB = LB + ST
10145     NextLB =
10146         SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
10147     NextLB =
10148         SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
10149     if (!NextLB.isUsable())
10150       return 0;
10151     // UB + ST
10152     NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
10153     if (!NextUB.isUsable())
10154       return 0;
10155     // UB = UB + ST
10156     NextUB =
10157         SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
10158     NextUB =
10159         SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
10160     if (!NextUB.isUsable())
10161       return 0;
10162     if (isOpenMPLoopBoundSharingDirective(DKind)) {
10163       CombNextLB =
10164           SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
10165       if (!NextLB.isUsable())
10166         return 0;
10167       // LB = LB + ST
10168       CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
10169                                       CombNextLB.get());
10170       CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
10171                                                /*DiscardedValue*/ false);
10172       if (!CombNextLB.isUsable())
10173         return 0;
10174       // UB + ST
10175       CombNextUB =
10176           SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
10177       if (!CombNextUB.isUsable())
10178         return 0;
10179       // UB = UB + ST
10180       CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
10181                                       CombNextUB.get());
10182       CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
10183                                                /*DiscardedValue*/ false);
10184       if (!CombNextUB.isUsable())
10185         return 0;
10186     }
10187   }
10188 
10189   // Create increment expression for distribute loop when combined in a same
10190   // directive with for as IV = IV + ST; ensure upper bound expression based
10191   // on PrevUB instead of NumIterations - used to implement 'for' when found
10192   // in combination with 'distribute', like in 'distribute parallel for'
10193   SourceLocation DistIncLoc = AStmt->getBeginLoc();
10194   ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
10195   if (isOpenMPLoopBoundSharingDirective(DKind)) {
10196     DistCond = SemaRef.BuildBinOp(
10197         CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
10198     assert(DistCond.isUsable() && "distribute cond expr was not built");
10199 
10200     DistInc =
10201         SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
10202     assert(DistInc.isUsable() && "distribute inc expr was not built");
10203     DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
10204                                  DistInc.get());
10205     DistInc =
10206         SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
10207     assert(DistInc.isUsable() && "distribute inc expr was not built");
10208 
10209     // Build expression: UB = min(UB, prevUB) for #for in composite or combined
10210     // construct
10211     ExprResult NewPrevUB = PrevUB;
10212     SourceLocation DistEUBLoc = AStmt->getBeginLoc();
10213     if (!SemaRef.Context.hasSameType(UB.get()->getType(),
10214                                      PrevUB.get()->getType())) {
10215       NewPrevUB = SemaRef.BuildCStyleCastExpr(
10216           DistEUBLoc,
10217           SemaRef.Context.getTrivialTypeSourceInfo(UB.get()->getType()),
10218           DistEUBLoc, NewPrevUB.get());
10219       if (!NewPrevUB.isUsable())
10220         return 0;
10221     }
10222     ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT,
10223                                                 UB.get(), NewPrevUB.get());
10224     ExprResult CondOp = SemaRef.ActOnConditionalOp(
10225         DistEUBLoc, DistEUBLoc, IsUBGreater.get(), NewPrevUB.get(), UB.get());
10226     PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
10227                                  CondOp.get());
10228     PrevEUB =
10229         SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
10230 
10231     // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
10232     // parallel for is in combination with a distribute directive with
10233     // schedule(static, 1)
10234     Expr *BoundPrevUB = PrevUB.get();
10235     if (UseStrictCompare) {
10236       BoundPrevUB =
10237           SemaRef
10238               .BuildBinOp(
10239                   CurScope, CondLoc, BO_Add, BoundPrevUB,
10240                   SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
10241               .get();
10242       BoundPrevUB =
10243           SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
10244               .get();
10245     }
10246     ParForInDistCond =
10247         SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
10248                            IV.get(), BoundPrevUB);
10249   }
10250 
10251   // Build updates and final values of the loop counters.
10252   bool HasErrors = false;
10253   Built.Counters.resize(NestedLoopCount);
10254   Built.Inits.resize(NestedLoopCount);
10255   Built.Updates.resize(NestedLoopCount);
10256   Built.Finals.resize(NestedLoopCount);
10257   Built.DependentCounters.resize(NestedLoopCount);
10258   Built.DependentInits.resize(NestedLoopCount);
10259   Built.FinalsConditions.resize(NestedLoopCount);
10260   {
10261     // We implement the following algorithm for obtaining the
10262     // original loop iteration variable values based on the
10263     // value of the collapsed loop iteration variable IV.
10264     //
10265     // Let n+1 be the number of collapsed loops in the nest.
10266     // Iteration variables (I0, I1, .... In)
10267     // Iteration counts (N0, N1, ... Nn)
10268     //
10269     // Acc = IV;
10270     //
10271     // To compute Ik for loop k, 0 <= k <= n, generate:
10272     //    Prod = N(k+1) * N(k+2) * ... * Nn;
10273     //    Ik = Acc / Prod;
10274     //    Acc -= Ik * Prod;
10275     //
10276     ExprResult Acc = IV;
10277     for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
10278       LoopIterationSpace &IS = IterSpaces[Cnt];
10279       SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
10280       ExprResult Iter;
10281 
10282       // Compute prod
10283       ExprResult Prod = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
10284       for (unsigned int K = Cnt + 1; K < NestedLoopCount; ++K)
10285         Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
10286                                   IterSpaces[K].NumIterations);
10287 
10288       // Iter = Acc / Prod
10289       // If there is at least one more inner loop to avoid
10290       // multiplication by 1.
10291       if (Cnt + 1 < NestedLoopCount)
10292         Iter =
10293             SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, Acc.get(), Prod.get());
10294       else
10295         Iter = Acc;
10296       if (!Iter.isUsable()) {
10297         HasErrors = true;
10298         break;
10299       }
10300 
10301       // Update Acc:
10302       // Acc -= Iter * Prod
10303       // Check if there is at least one more inner loop to avoid
10304       // multiplication by 1.
10305       if (Cnt + 1 < NestedLoopCount)
10306         Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Iter.get(),
10307                                   Prod.get());
10308       else
10309         Prod = Iter;
10310       Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, Acc.get(), Prod.get());
10311 
10312       // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
10313       auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
10314       DeclRefExpr *CounterVar = buildDeclRefExpr(
10315           SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
10316           /*RefersToCapture=*/true);
10317       ExprResult Init =
10318           buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
10319                            IS.CounterInit, IS.IsNonRectangularLB, Captures);
10320       if (!Init.isUsable()) {
10321         HasErrors = true;
10322         break;
10323       }
10324       ExprResult Update = buildCounterUpdate(
10325           SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
10326           IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
10327       if (!Update.isUsable()) {
10328         HasErrors = true;
10329         break;
10330       }
10331 
10332       // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
10333       ExprResult Final =
10334           buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
10335                              IS.CounterInit, IS.NumIterations, IS.CounterStep,
10336                              IS.Subtract, IS.IsNonRectangularLB, &Captures);
10337       if (!Final.isUsable()) {
10338         HasErrors = true;
10339         break;
10340       }
10341 
10342       if (!Update.isUsable() || !Final.isUsable()) {
10343         HasErrors = true;
10344         break;
10345       }
10346       // Save results
10347       Built.Counters[Cnt] = IS.CounterVar;
10348       Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
10349       Built.Inits[Cnt] = Init.get();
10350       Built.Updates[Cnt] = Update.get();
10351       Built.Finals[Cnt] = Final.get();
10352       Built.DependentCounters[Cnt] = nullptr;
10353       Built.DependentInits[Cnt] = nullptr;
10354       Built.FinalsConditions[Cnt] = nullptr;
10355       if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
10356         Built.DependentCounters[Cnt] = Built.Counters[IS.LoopDependentIdx - 1];
10357         Built.DependentInits[Cnt] = Built.Inits[IS.LoopDependentIdx - 1];
10358         Built.FinalsConditions[Cnt] = IS.FinalCondition;
10359       }
10360     }
10361   }
10362 
10363   if (HasErrors)
10364     return 0;
10365 
10366   // Save results
10367   Built.IterationVarRef = IV.get();
10368   Built.LastIteration = LastIteration.get();
10369   Built.NumIterations = NumIterations.get();
10370   Built.CalcLastIteration = SemaRef
10371                                 .ActOnFinishFullExpr(CalcLastIteration.get(),
10372                                                      /*DiscardedValue=*/false)
10373                                 .get();
10374   Built.PreCond = PreCond.get();
10375   Built.PreInits = buildPreInits(C, Captures);
10376   Built.Cond = Cond.get();
10377   Built.Init = Init.get();
10378   Built.Inc = Inc.get();
10379   Built.LB = LB.get();
10380   Built.UB = UB.get();
10381   Built.IL = IL.get();
10382   Built.ST = ST.get();
10383   Built.EUB = EUB.get();
10384   Built.NLB = NextLB.get();
10385   Built.NUB = NextUB.get();
10386   Built.PrevLB = PrevLB.get();
10387   Built.PrevUB = PrevUB.get();
10388   Built.DistInc = DistInc.get();
10389   Built.PrevEUB = PrevEUB.get();
10390   Built.DistCombinedFields.LB = CombLB.get();
10391   Built.DistCombinedFields.UB = CombUB.get();
10392   Built.DistCombinedFields.EUB = CombEUB.get();
10393   Built.DistCombinedFields.Init = CombInit.get();
10394   Built.DistCombinedFields.Cond = CombCond.get();
10395   Built.DistCombinedFields.NLB = CombNextLB.get();
10396   Built.DistCombinedFields.NUB = CombNextUB.get();
10397   Built.DistCombinedFields.DistCond = CombDistCond.get();
10398   Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
10399 
10400   return NestedLoopCount;
10401 }
10402 
10403 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
10404   auto CollapseClauses =
10405       OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
10406   if (CollapseClauses.begin() != CollapseClauses.end())
10407     return (*CollapseClauses.begin())->getNumForLoops();
10408   return nullptr;
10409 }
10410 
10411 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
10412   auto OrderedClauses =
10413       OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
10414   if (OrderedClauses.begin() != OrderedClauses.end())
10415     return (*OrderedClauses.begin())->getNumForLoops();
10416   return nullptr;
10417 }
10418 
10419 static bool checkSimdlenSafelenSpecified(Sema &S,
10420                                          const ArrayRef<OMPClause *> Clauses) {
10421   const OMPSafelenClause *Safelen = nullptr;
10422   const OMPSimdlenClause *Simdlen = nullptr;
10423 
10424   for (const OMPClause *Clause : Clauses) {
10425     if (Clause->getClauseKind() == OMPC_safelen)
10426       Safelen = cast<OMPSafelenClause>(Clause);
10427     else if (Clause->getClauseKind() == OMPC_simdlen)
10428       Simdlen = cast<OMPSimdlenClause>(Clause);
10429     if (Safelen && Simdlen)
10430       break;
10431   }
10432 
10433   if (Simdlen && Safelen) {
10434     const Expr *SimdlenLength = Simdlen->getSimdlen();
10435     const Expr *SafelenLength = Safelen->getSafelen();
10436     if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
10437         SimdlenLength->isInstantiationDependent() ||
10438         SimdlenLength->containsUnexpandedParameterPack())
10439       return false;
10440     if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
10441         SafelenLength->isInstantiationDependent() ||
10442         SafelenLength->containsUnexpandedParameterPack())
10443       return false;
10444     Expr::EvalResult SimdlenResult, SafelenResult;
10445     SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
10446     SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
10447     llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
10448     llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
10449     // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
10450     // If both simdlen and safelen clauses are specified, the value of the
10451     // simdlen parameter must be less than or equal to the value of the safelen
10452     // parameter.
10453     if (SimdlenRes > SafelenRes) {
10454       S.Diag(SimdlenLength->getExprLoc(),
10455              diag::err_omp_wrong_simdlen_safelen_values)
10456           << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
10457       return true;
10458     }
10459   }
10460   return false;
10461 }
10462 
10463 static bool checkGenericLoopLastprivate(Sema &S, ArrayRef<OMPClause *> Clauses,
10464                                         OpenMPDirectiveKind K,
10465                                         DSAStackTy *Stack);
10466 
10467 bool Sema::checkLastPrivateForMappedDirectives(ArrayRef<OMPClause *> Clauses) {
10468 
10469   // Check for syntax of lastprivate
10470   // Param of the lastprivate have different meanings in the mapped directives
10471   // e.g. "omp loop" Only loop iteration vars are allowed in lastprivate clause
10472   //      "omp for"  lastprivate vars must be shared
10473   if (getLangOpts().OpenMP >= 50 &&
10474       DSAStack->getMappedDirective() == OMPD_loop &&
10475       checkGenericLoopLastprivate(*this, Clauses, OMPD_loop, DSAStack)) {
10476     return false;
10477   }
10478   return true;
10479 }
10480 
10481 StmtResult
10482 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
10483                                SourceLocation StartLoc, SourceLocation EndLoc,
10484                                VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10485   if (!AStmt)
10486     return StmtError();
10487 
10488   if (!checkLastPrivateForMappedDirectives(Clauses))
10489     return StmtError();
10490 
10491   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10492   OMPLoopBasedDirective::HelperExprs B;
10493   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10494   // define the nested loops number.
10495   unsigned NestedLoopCount = checkOpenMPLoop(
10496       OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
10497       AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
10498   if (NestedLoopCount == 0)
10499     return StmtError();
10500 
10501   assert((CurContext->isDependentContext() || B.builtAll()) &&
10502          "omp simd loop exprs were not built");
10503 
10504   if (!CurContext->isDependentContext()) {
10505     // Finalize the clauses that need pre-built expressions for CodeGen.
10506     for (OMPClause *C : Clauses) {
10507       if (auto *LC = dyn_cast<OMPLinearClause>(C))
10508         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10509                                      B.NumIterations, *this, CurScope,
10510                                      DSAStack))
10511           return StmtError();
10512     }
10513   }
10514 
10515   if (checkSimdlenSafelenSpecified(*this, Clauses))
10516     return StmtError();
10517 
10518   setFunctionHasBranchProtectedScope();
10519   auto *SimdDirective = OMPSimdDirective::Create(
10520       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10521       DSAStack->getMappedDirective());
10522   return SimdDirective;
10523 }
10524 
10525 StmtResult
10526 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
10527                               SourceLocation StartLoc, SourceLocation EndLoc,
10528                               VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10529   if (!AStmt)
10530     return StmtError();
10531 
10532   if (!checkLastPrivateForMappedDirectives(Clauses))
10533     return StmtError();
10534 
10535   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10536   OMPLoopBasedDirective::HelperExprs B;
10537   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10538   // define the nested loops number.
10539   unsigned NestedLoopCount = checkOpenMPLoop(
10540       OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
10541       AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
10542   if (NestedLoopCount == 0)
10543     return StmtError();
10544 
10545   assert((CurContext->isDependentContext() || B.builtAll()) &&
10546          "omp for loop exprs were not built");
10547 
10548   if (!CurContext->isDependentContext()) {
10549     // Finalize the clauses that need pre-built expressions for CodeGen.
10550     for (OMPClause *C : Clauses) {
10551       if (auto *LC = dyn_cast<OMPLinearClause>(C))
10552         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10553                                      B.NumIterations, *this, CurScope,
10554                                      DSAStack))
10555           return StmtError();
10556     }
10557   }
10558 
10559   auto *ForDirective = OMPForDirective::Create(
10560       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10561       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion(),
10562       DSAStack->getMappedDirective());
10563   return ForDirective;
10564 }
10565 
10566 StmtResult Sema::ActOnOpenMPForSimdDirective(
10567     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10568     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10569   if (!AStmt)
10570     return StmtError();
10571 
10572   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10573   OMPLoopBasedDirective::HelperExprs B;
10574   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10575   // define the nested loops number.
10576   unsigned NestedLoopCount =
10577       checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
10578                       getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
10579                       VarsWithImplicitDSA, B);
10580   if (NestedLoopCount == 0)
10581     return StmtError();
10582 
10583   assert((CurContext->isDependentContext() || B.builtAll()) &&
10584          "omp for simd loop exprs were not built");
10585 
10586   if (!CurContext->isDependentContext()) {
10587     // Finalize the clauses that need pre-built expressions for CodeGen.
10588     for (OMPClause *C : Clauses) {
10589       if (auto *LC = dyn_cast<OMPLinearClause>(C))
10590         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10591                                      B.NumIterations, *this, CurScope,
10592                                      DSAStack))
10593           return StmtError();
10594     }
10595   }
10596 
10597   if (checkSimdlenSafelenSpecified(*this, Clauses))
10598     return StmtError();
10599 
10600   setFunctionHasBranchProtectedScope();
10601   return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
10602                                      Clauses, AStmt, B);
10603 }
10604 
10605 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
10606                                               Stmt *AStmt,
10607                                               SourceLocation StartLoc,
10608                                               SourceLocation EndLoc) {
10609   if (!AStmt)
10610     return StmtError();
10611 
10612   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10613   auto BaseStmt = AStmt;
10614   while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
10615     BaseStmt = CS->getCapturedStmt();
10616   if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
10617     auto S = C->children();
10618     if (S.begin() == S.end())
10619       return StmtError();
10620     // All associated statements must be '#pragma omp section' except for
10621     // the first one.
10622     for (Stmt *SectionStmt : llvm::drop_begin(S)) {
10623       if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
10624         if (SectionStmt)
10625           Diag(SectionStmt->getBeginLoc(),
10626                diag::err_omp_sections_substmt_not_section);
10627         return StmtError();
10628       }
10629       cast<OMPSectionDirective>(SectionStmt)
10630           ->setHasCancel(DSAStack->isCancelRegion());
10631     }
10632   } else {
10633     Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
10634     return StmtError();
10635   }
10636 
10637   setFunctionHasBranchProtectedScope();
10638 
10639   return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10640                                       DSAStack->getTaskgroupReductionRef(),
10641                                       DSAStack->isCancelRegion());
10642 }
10643 
10644 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
10645                                              SourceLocation StartLoc,
10646                                              SourceLocation EndLoc) {
10647   if (!AStmt)
10648     return StmtError();
10649 
10650   setFunctionHasBranchProtectedScope();
10651   DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
10652 
10653   return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
10654                                      DSAStack->isCancelRegion());
10655 }
10656 
10657 static Expr *getDirectCallExpr(Expr *E) {
10658   E = E->IgnoreParenCasts()->IgnoreImplicit();
10659   if (auto *CE = dyn_cast<CallExpr>(E))
10660     if (CE->getDirectCallee())
10661       return E;
10662   return nullptr;
10663 }
10664 
10665 StmtResult Sema::ActOnOpenMPDispatchDirective(ArrayRef<OMPClause *> Clauses,
10666                                               Stmt *AStmt,
10667                                               SourceLocation StartLoc,
10668                                               SourceLocation EndLoc) {
10669   if (!AStmt)
10670     return StmtError();
10671 
10672   Stmt *S = cast<CapturedStmt>(AStmt)->getCapturedStmt();
10673 
10674   // 5.1 OpenMP
10675   // expression-stmt : an expression statement with one of the following forms:
10676   //   expression = target-call ( [expression-list] );
10677   //   target-call ( [expression-list] );
10678 
10679   SourceLocation TargetCallLoc;
10680 
10681   if (!CurContext->isDependentContext()) {
10682     Expr *TargetCall = nullptr;
10683 
10684     auto *E = dyn_cast<Expr>(S);
10685     if (!E) {
10686       Diag(S->getBeginLoc(), diag::err_omp_dispatch_statement_call);
10687       return StmtError();
10688     }
10689 
10690     E = E->IgnoreParenCasts()->IgnoreImplicit();
10691 
10692     if (auto *BO = dyn_cast<BinaryOperator>(E)) {
10693       if (BO->getOpcode() == BO_Assign)
10694         TargetCall = getDirectCallExpr(BO->getRHS());
10695     } else {
10696       if (auto *COCE = dyn_cast<CXXOperatorCallExpr>(E))
10697         if (COCE->getOperator() == OO_Equal)
10698           TargetCall = getDirectCallExpr(COCE->getArg(1));
10699       if (!TargetCall)
10700         TargetCall = getDirectCallExpr(E);
10701     }
10702     if (!TargetCall) {
10703       Diag(E->getBeginLoc(), diag::err_omp_dispatch_statement_call);
10704       return StmtError();
10705     }
10706     TargetCallLoc = TargetCall->getExprLoc();
10707   }
10708 
10709   setFunctionHasBranchProtectedScope();
10710 
10711   return OMPDispatchDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10712                                       TargetCallLoc);
10713 }
10714 
10715 static bool checkGenericLoopLastprivate(Sema &S, ArrayRef<OMPClause *> Clauses,
10716                                         OpenMPDirectiveKind K,
10717                                         DSAStackTy *Stack) {
10718   bool ErrorFound = false;
10719   for (OMPClause *C : Clauses) {
10720     if (auto *LPC = dyn_cast<OMPLastprivateClause>(C)) {
10721       for (Expr *RefExpr : LPC->varlists()) {
10722         SourceLocation ELoc;
10723         SourceRange ERange;
10724         Expr *SimpleRefExpr = RefExpr;
10725         auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
10726         if (ValueDecl *D = Res.first) {
10727           auto &&Info = Stack->isLoopControlVariable(D);
10728           if (!Info.first) {
10729             S.Diag(ELoc, diag::err_omp_lastprivate_loop_var_non_loop_iteration)
10730                 << getOpenMPDirectiveName(K);
10731             ErrorFound = true;
10732           }
10733         }
10734       }
10735     }
10736   }
10737   return ErrorFound;
10738 }
10739 
10740 StmtResult Sema::ActOnOpenMPGenericLoopDirective(
10741     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10742     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10743   if (!AStmt)
10744     return StmtError();
10745 
10746   // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10747   // A list item may not appear in a lastprivate clause unless it is the
10748   // loop iteration variable of a loop that is associated with the construct.
10749   if (checkGenericLoopLastprivate(*this, Clauses, OMPD_loop, DSAStack))
10750     return StmtError();
10751 
10752   auto *CS = cast<CapturedStmt>(AStmt);
10753   // 1.2.2 OpenMP Language Terminology
10754   // Structured block - An executable statement with a single entry at the
10755   // top and a single exit at the bottom.
10756   // The point of exit cannot be a branch out of the structured block.
10757   // longjmp() and throw() must not violate the entry/exit criteria.
10758   CS->getCapturedDecl()->setNothrow();
10759 
10760   OMPLoopDirective::HelperExprs B;
10761   // In presence of clause 'collapse', it will define the nested loops number.
10762   unsigned NestedLoopCount = checkOpenMPLoop(
10763       OMPD_loop, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
10764       AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
10765   if (NestedLoopCount == 0)
10766     return StmtError();
10767 
10768   assert((CurContext->isDependentContext() || B.builtAll()) &&
10769          "omp loop exprs were not built");
10770 
10771   setFunctionHasBranchProtectedScope();
10772   return OMPGenericLoopDirective::Create(Context, StartLoc, EndLoc,
10773                                          NestedLoopCount, Clauses, AStmt, B);
10774 }
10775 
10776 StmtResult Sema::ActOnOpenMPTeamsGenericLoopDirective(
10777     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10778     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10779   if (!AStmt)
10780     return StmtError();
10781 
10782   // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10783   // A list item may not appear in a lastprivate clause unless it is the
10784   // loop iteration variable of a loop that is associated with the construct.
10785   if (checkGenericLoopLastprivate(*this, Clauses, OMPD_teams_loop, DSAStack))
10786     return StmtError();
10787 
10788   auto *CS = cast<CapturedStmt>(AStmt);
10789   // 1.2.2 OpenMP Language Terminology
10790   // Structured block - An executable statement with a single entry at the
10791   // top and a single exit at the bottom.
10792   // The point of exit cannot be a branch out of the structured block.
10793   // longjmp() and throw() must not violate the entry/exit criteria.
10794   CS->getCapturedDecl()->setNothrow();
10795   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_loop);
10796        ThisCaptureLevel > 1; --ThisCaptureLevel) {
10797     CS = cast<CapturedStmt>(CS->getCapturedStmt());
10798     // 1.2.2 OpenMP Language Terminology
10799     // Structured block - An executable statement with a single entry at the
10800     // top and a single exit at the bottom.
10801     // The point of exit cannot be a branch out of the structured block.
10802     // longjmp() and throw() must not violate the entry/exit criteria.
10803     CS->getCapturedDecl()->setNothrow();
10804   }
10805 
10806   OMPLoopDirective::HelperExprs B;
10807   // In presence of clause 'collapse', it will define the nested loops number.
10808   unsigned NestedLoopCount =
10809       checkOpenMPLoop(OMPD_teams_loop, getCollapseNumberExpr(Clauses),
10810                       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10811                       VarsWithImplicitDSA, B);
10812   if (NestedLoopCount == 0)
10813     return StmtError();
10814 
10815   assert((CurContext->isDependentContext() || B.builtAll()) &&
10816          "omp loop exprs were not built");
10817 
10818   setFunctionHasBranchProtectedScope();
10819   DSAStack->setParentTeamsRegionLoc(StartLoc);
10820 
10821   return OMPTeamsGenericLoopDirective::Create(
10822       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10823 }
10824 
10825 StmtResult Sema::ActOnOpenMPTargetTeamsGenericLoopDirective(
10826     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10827     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10828   if (!AStmt)
10829     return StmtError();
10830 
10831   // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10832   // A list item may not appear in a lastprivate clause unless it is the
10833   // loop iteration variable of a loop that is associated with the construct.
10834   if (checkGenericLoopLastprivate(*this, Clauses, OMPD_target_teams_loop,
10835                                   DSAStack))
10836     return StmtError();
10837 
10838   auto *CS = cast<CapturedStmt>(AStmt);
10839   // 1.2.2 OpenMP Language Terminology
10840   // Structured block - An executable statement with a single entry at the
10841   // top and a single exit at the bottom.
10842   // The point of exit cannot be a branch out of the structured block.
10843   // longjmp() and throw() must not violate the entry/exit criteria.
10844   CS->getCapturedDecl()->setNothrow();
10845   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams_loop);
10846        ThisCaptureLevel > 1; --ThisCaptureLevel) {
10847     CS = cast<CapturedStmt>(CS->getCapturedStmt());
10848     // 1.2.2 OpenMP Language Terminology
10849     // Structured block - An executable statement with a single entry at the
10850     // top and a single exit at the bottom.
10851     // The point of exit cannot be a branch out of the structured block.
10852     // longjmp() and throw() must not violate the entry/exit criteria.
10853     CS->getCapturedDecl()->setNothrow();
10854   }
10855 
10856   OMPLoopDirective::HelperExprs B;
10857   // In presence of clause 'collapse', it will define the nested loops number.
10858   unsigned NestedLoopCount =
10859       checkOpenMPLoop(OMPD_target_teams_loop, getCollapseNumberExpr(Clauses),
10860                       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10861                       VarsWithImplicitDSA, B);
10862   if (NestedLoopCount == 0)
10863     return StmtError();
10864 
10865   assert((CurContext->isDependentContext() || B.builtAll()) &&
10866          "omp loop exprs were not built");
10867 
10868   setFunctionHasBranchProtectedScope();
10869 
10870   return OMPTargetTeamsGenericLoopDirective::Create(
10871       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10872 }
10873 
10874 StmtResult Sema::ActOnOpenMPParallelGenericLoopDirective(
10875     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10876     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10877   if (!AStmt)
10878     return StmtError();
10879 
10880   // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10881   // A list item may not appear in a lastprivate clause unless it is the
10882   // loop iteration variable of a loop that is associated with the construct.
10883   if (checkGenericLoopLastprivate(*this, Clauses, OMPD_parallel_loop, DSAStack))
10884     return StmtError();
10885 
10886   auto *CS = cast<CapturedStmt>(AStmt);
10887   // 1.2.2 OpenMP Language Terminology
10888   // Structured block - An executable statement with a single entry at the
10889   // top and a single exit at the bottom.
10890   // The point of exit cannot be a branch out of the structured block.
10891   // longjmp() and throw() must not violate the entry/exit criteria.
10892   CS->getCapturedDecl()->setNothrow();
10893   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_parallel_loop);
10894        ThisCaptureLevel > 1; --ThisCaptureLevel) {
10895     CS = cast<CapturedStmt>(CS->getCapturedStmt());
10896     // 1.2.2 OpenMP Language Terminology
10897     // Structured block - An executable statement with a single entry at the
10898     // top and a single exit at the bottom.
10899     // The point of exit cannot be a branch out of the structured block.
10900     // longjmp() and throw() must not violate the entry/exit criteria.
10901     CS->getCapturedDecl()->setNothrow();
10902   }
10903 
10904   OMPLoopDirective::HelperExprs B;
10905   // In presence of clause 'collapse', it will define the nested loops number.
10906   unsigned NestedLoopCount =
10907       checkOpenMPLoop(OMPD_parallel_loop, getCollapseNumberExpr(Clauses),
10908                       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10909                       VarsWithImplicitDSA, B);
10910   if (NestedLoopCount == 0)
10911     return StmtError();
10912 
10913   assert((CurContext->isDependentContext() || B.builtAll()) &&
10914          "omp loop exprs were not built");
10915 
10916   setFunctionHasBranchProtectedScope();
10917 
10918   return OMPParallelGenericLoopDirective::Create(
10919       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10920 }
10921 
10922 StmtResult Sema::ActOnOpenMPTargetParallelGenericLoopDirective(
10923     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10924     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10925   if (!AStmt)
10926     return StmtError();
10927 
10928   // OpenMP 5.1 [2.11.7, loop construct, Restrictions]
10929   // A list item may not appear in a lastprivate clause unless it is the
10930   // loop iteration variable of a loop that is associated with the construct.
10931   if (checkGenericLoopLastprivate(*this, Clauses, OMPD_target_parallel_loop,
10932                                   DSAStack))
10933     return StmtError();
10934 
10935   auto *CS = cast<CapturedStmt>(AStmt);
10936   // 1.2.2 OpenMP Language Terminology
10937   // Structured block - An executable statement with a single entry at the
10938   // top and a single exit at the bottom.
10939   // The point of exit cannot be a branch out of the structured block.
10940   // longjmp() and throw() must not violate the entry/exit criteria.
10941   CS->getCapturedDecl()->setNothrow();
10942   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_loop);
10943        ThisCaptureLevel > 1; --ThisCaptureLevel) {
10944     CS = cast<CapturedStmt>(CS->getCapturedStmt());
10945     // 1.2.2 OpenMP Language Terminology
10946     // Structured block - An executable statement with a single entry at the
10947     // top and a single exit at the bottom.
10948     // The point of exit cannot be a branch out of the structured block.
10949     // longjmp() and throw() must not violate the entry/exit criteria.
10950     CS->getCapturedDecl()->setNothrow();
10951   }
10952 
10953   OMPLoopDirective::HelperExprs B;
10954   // In presence of clause 'collapse', it will define the nested loops number.
10955   unsigned NestedLoopCount =
10956       checkOpenMPLoop(OMPD_target_parallel_loop, getCollapseNumberExpr(Clauses),
10957                       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
10958                       VarsWithImplicitDSA, B);
10959   if (NestedLoopCount == 0)
10960     return StmtError();
10961 
10962   assert((CurContext->isDependentContext() || B.builtAll()) &&
10963          "omp loop exprs were not built");
10964 
10965   setFunctionHasBranchProtectedScope();
10966 
10967   return OMPTargetParallelGenericLoopDirective::Create(
10968       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10969 }
10970 
10971 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
10972                                             Stmt *AStmt,
10973                                             SourceLocation StartLoc,
10974                                             SourceLocation EndLoc) {
10975   if (!AStmt)
10976     return StmtError();
10977 
10978   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10979 
10980   setFunctionHasBranchProtectedScope();
10981 
10982   // OpenMP [2.7.3, single Construct, Restrictions]
10983   // The copyprivate clause must not be used with the nowait clause.
10984   const OMPClause *Nowait = nullptr;
10985   const OMPClause *Copyprivate = nullptr;
10986   for (const OMPClause *Clause : Clauses) {
10987     if (Clause->getClauseKind() == OMPC_nowait)
10988       Nowait = Clause;
10989     else if (Clause->getClauseKind() == OMPC_copyprivate)
10990       Copyprivate = Clause;
10991     if (Copyprivate && Nowait) {
10992       Diag(Copyprivate->getBeginLoc(),
10993            diag::err_omp_single_copyprivate_with_nowait);
10994       Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
10995       return StmtError();
10996     }
10997   }
10998 
10999   return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
11000 }
11001 
11002 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
11003                                             SourceLocation StartLoc,
11004                                             SourceLocation EndLoc) {
11005   if (!AStmt)
11006     return StmtError();
11007 
11008   setFunctionHasBranchProtectedScope();
11009 
11010   return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
11011 }
11012 
11013 StmtResult Sema::ActOnOpenMPMaskedDirective(ArrayRef<OMPClause *> Clauses,
11014                                             Stmt *AStmt,
11015                                             SourceLocation StartLoc,
11016                                             SourceLocation EndLoc) {
11017   if (!AStmt)
11018     return StmtError();
11019 
11020   setFunctionHasBranchProtectedScope();
11021 
11022   return OMPMaskedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
11023 }
11024 
11025 StmtResult Sema::ActOnOpenMPCriticalDirective(
11026     const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
11027     Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
11028   if (!AStmt)
11029     return StmtError();
11030 
11031   bool ErrorFound = false;
11032   llvm::APSInt Hint;
11033   SourceLocation HintLoc;
11034   bool DependentHint = false;
11035   for (const OMPClause *C : Clauses) {
11036     if (C->getClauseKind() == OMPC_hint) {
11037       if (!DirName.getName()) {
11038         Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
11039         ErrorFound = true;
11040       }
11041       Expr *E = cast<OMPHintClause>(C)->getHint();
11042       if (E->isTypeDependent() || E->isValueDependent() ||
11043           E->isInstantiationDependent()) {
11044         DependentHint = true;
11045       } else {
11046         Hint = E->EvaluateKnownConstInt(Context);
11047         HintLoc = C->getBeginLoc();
11048       }
11049     }
11050   }
11051   if (ErrorFound)
11052     return StmtError();
11053   const auto Pair = DSAStack->getCriticalWithHint(DirName);
11054   if (Pair.first && DirName.getName() && !DependentHint) {
11055     if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
11056       Diag(StartLoc, diag::err_omp_critical_with_hint);
11057       if (HintLoc.isValid())
11058         Diag(HintLoc, diag::note_omp_critical_hint_here)
11059             << 0 << toString(Hint, /*Radix=*/10, /*Signed=*/false);
11060       else
11061         Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
11062       if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
11063         Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
11064             << 1
11065             << toString(C->getHint()->EvaluateKnownConstInt(Context),
11066                         /*Radix=*/10, /*Signed=*/false);
11067       } else {
11068         Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
11069       }
11070     }
11071   }
11072 
11073   setFunctionHasBranchProtectedScope();
11074 
11075   auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
11076                                            Clauses, AStmt);
11077   if (!Pair.first && DirName.getName() && !DependentHint)
11078     DSAStack->addCriticalWithHint(Dir, Hint);
11079   return Dir;
11080 }
11081 
11082 StmtResult Sema::ActOnOpenMPParallelForDirective(
11083     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11084     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11085   if (!AStmt)
11086     return StmtError();
11087 
11088   auto *CS = cast<CapturedStmt>(AStmt);
11089   // 1.2.2 OpenMP Language Terminology
11090   // Structured block - An executable statement with a single entry at the
11091   // top and a single exit at the bottom.
11092   // The point of exit cannot be a branch out of the structured block.
11093   // longjmp() and throw() must not violate the entry/exit criteria.
11094   CS->getCapturedDecl()->setNothrow();
11095 
11096   OMPLoopBasedDirective::HelperExprs B;
11097   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11098   // define the nested loops number.
11099   unsigned NestedLoopCount =
11100       checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
11101                       getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
11102                       VarsWithImplicitDSA, B);
11103   if (NestedLoopCount == 0)
11104     return StmtError();
11105 
11106   assert((CurContext->isDependentContext() || B.builtAll()) &&
11107          "omp parallel for loop exprs were not built");
11108 
11109   if (!CurContext->isDependentContext()) {
11110     // Finalize the clauses that need pre-built expressions for CodeGen.
11111     for (OMPClause *C : Clauses) {
11112       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11113         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11114                                      B.NumIterations, *this, CurScope,
11115                                      DSAStack))
11116           return StmtError();
11117     }
11118   }
11119 
11120   setFunctionHasBranchProtectedScope();
11121   return OMPParallelForDirective::Create(
11122       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11123       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11124 }
11125 
11126 StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
11127     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11128     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11129   if (!AStmt)
11130     return StmtError();
11131 
11132   auto *CS = cast<CapturedStmt>(AStmt);
11133   // 1.2.2 OpenMP Language Terminology
11134   // Structured block - An executable statement with a single entry at the
11135   // top and a single exit at the bottom.
11136   // The point of exit cannot be a branch out of the structured block.
11137   // longjmp() and throw() must not violate the entry/exit criteria.
11138   CS->getCapturedDecl()->setNothrow();
11139 
11140   OMPLoopBasedDirective::HelperExprs B;
11141   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11142   // define the nested loops number.
11143   unsigned NestedLoopCount =
11144       checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
11145                       getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
11146                       VarsWithImplicitDSA, B);
11147   if (NestedLoopCount == 0)
11148     return StmtError();
11149 
11150   if (!CurContext->isDependentContext()) {
11151     // Finalize the clauses that need pre-built expressions for CodeGen.
11152     for (OMPClause *C : Clauses) {
11153       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11154         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11155                                      B.NumIterations, *this, CurScope,
11156                                      DSAStack))
11157           return StmtError();
11158     }
11159   }
11160 
11161   if (checkSimdlenSafelenSpecified(*this, Clauses))
11162     return StmtError();
11163 
11164   setFunctionHasBranchProtectedScope();
11165   return OMPParallelForSimdDirective::Create(
11166       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11167 }
11168 
11169 StmtResult
11170 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses,
11171                                          Stmt *AStmt, SourceLocation StartLoc,
11172                                          SourceLocation EndLoc) {
11173   if (!AStmt)
11174     return StmtError();
11175 
11176   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11177   auto *CS = cast<CapturedStmt>(AStmt);
11178   // 1.2.2 OpenMP Language Terminology
11179   // Structured block - An executable statement with a single entry at the
11180   // top and a single exit at the bottom.
11181   // The point of exit cannot be a branch out of the structured block.
11182   // longjmp() and throw() must not violate the entry/exit criteria.
11183   CS->getCapturedDecl()->setNothrow();
11184 
11185   setFunctionHasBranchProtectedScope();
11186 
11187   return OMPParallelMasterDirective::Create(
11188       Context, StartLoc, EndLoc, Clauses, AStmt,
11189       DSAStack->getTaskgroupReductionRef());
11190 }
11191 
11192 StmtResult
11193 Sema::ActOnOpenMPParallelMaskedDirective(ArrayRef<OMPClause *> Clauses,
11194                                          Stmt *AStmt, SourceLocation StartLoc,
11195                                          SourceLocation EndLoc) {
11196   if (!AStmt)
11197     return StmtError();
11198 
11199   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11200   auto *CS = cast<CapturedStmt>(AStmt);
11201   // 1.2.2 OpenMP Language Terminology
11202   // Structured block - An executable statement with a single entry at the
11203   // top and a single exit at the bottom.
11204   // The point of exit cannot be a branch out of the structured block.
11205   // longjmp() and throw() must not violate the entry/exit criteria.
11206   CS->getCapturedDecl()->setNothrow();
11207 
11208   setFunctionHasBranchProtectedScope();
11209 
11210   return OMPParallelMaskedDirective::Create(
11211       Context, StartLoc, EndLoc, Clauses, AStmt,
11212       DSAStack->getTaskgroupReductionRef());
11213 }
11214 
11215 StmtResult
11216 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
11217                                            Stmt *AStmt, SourceLocation StartLoc,
11218                                            SourceLocation EndLoc) {
11219   if (!AStmt)
11220     return StmtError();
11221 
11222   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11223   auto BaseStmt = AStmt;
11224   while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
11225     BaseStmt = CS->getCapturedStmt();
11226   if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
11227     auto S = C->children();
11228     if (S.begin() == S.end())
11229       return StmtError();
11230     // All associated statements must be '#pragma omp section' except for
11231     // the first one.
11232     for (Stmt *SectionStmt : llvm::drop_begin(S)) {
11233       if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
11234         if (SectionStmt)
11235           Diag(SectionStmt->getBeginLoc(),
11236                diag::err_omp_parallel_sections_substmt_not_section);
11237         return StmtError();
11238       }
11239       cast<OMPSectionDirective>(SectionStmt)
11240           ->setHasCancel(DSAStack->isCancelRegion());
11241     }
11242   } else {
11243     Diag(AStmt->getBeginLoc(),
11244          diag::err_omp_parallel_sections_not_compound_stmt);
11245     return StmtError();
11246   }
11247 
11248   setFunctionHasBranchProtectedScope();
11249 
11250   return OMPParallelSectionsDirective::Create(
11251       Context, StartLoc, EndLoc, Clauses, AStmt,
11252       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11253 }
11254 
11255 /// Find and diagnose mutually exclusive clause kinds.
11256 static bool checkMutuallyExclusiveClauses(
11257     Sema &S, ArrayRef<OMPClause *> Clauses,
11258     ArrayRef<OpenMPClauseKind> MutuallyExclusiveClauses) {
11259   const OMPClause *PrevClause = nullptr;
11260   bool ErrorFound = false;
11261   for (const OMPClause *C : Clauses) {
11262     if (llvm::is_contained(MutuallyExclusiveClauses, C->getClauseKind())) {
11263       if (!PrevClause) {
11264         PrevClause = C;
11265       } else if (PrevClause->getClauseKind() != C->getClauseKind()) {
11266         S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
11267             << getOpenMPClauseName(C->getClauseKind())
11268             << getOpenMPClauseName(PrevClause->getClauseKind());
11269         S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
11270             << getOpenMPClauseName(PrevClause->getClauseKind());
11271         ErrorFound = true;
11272       }
11273     }
11274   }
11275   return ErrorFound;
11276 }
11277 
11278 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
11279                                           Stmt *AStmt, SourceLocation StartLoc,
11280                                           SourceLocation EndLoc) {
11281   if (!AStmt)
11282     return StmtError();
11283 
11284   // OpenMP 5.0, 2.10.1 task Construct
11285   // If a detach clause appears on the directive, then a mergeable clause cannot
11286   // appear on the same directive.
11287   if (checkMutuallyExclusiveClauses(*this, Clauses,
11288                                     {OMPC_detach, OMPC_mergeable}))
11289     return StmtError();
11290 
11291   auto *CS = cast<CapturedStmt>(AStmt);
11292   // 1.2.2 OpenMP Language Terminology
11293   // Structured block - An executable statement with a single entry at the
11294   // top and a single exit at the bottom.
11295   // The point of exit cannot be a branch out of the structured block.
11296   // longjmp() and throw() must not violate the entry/exit criteria.
11297   CS->getCapturedDecl()->setNothrow();
11298 
11299   setFunctionHasBranchProtectedScope();
11300 
11301   return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
11302                                   DSAStack->isCancelRegion());
11303 }
11304 
11305 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
11306                                                SourceLocation EndLoc) {
11307   return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
11308 }
11309 
11310 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
11311                                              SourceLocation EndLoc) {
11312   return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
11313 }
11314 
11315 StmtResult Sema::ActOnOpenMPErrorDirective(ArrayRef<OMPClause *> Clauses,
11316                                            SourceLocation StartLoc,
11317                                            SourceLocation EndLoc,
11318                                            bool InExContext) {
11319   const OMPAtClause *AtC =
11320       OMPExecutableDirective::getSingleClause<OMPAtClause>(Clauses);
11321 
11322   if (AtC && !InExContext && AtC->getAtKind() == OMPC_AT_execution) {
11323     Diag(AtC->getAtKindKwLoc(), diag::err_omp_unexpected_execution_modifier);
11324     return StmtError();
11325   }
11326 
11327   const OMPSeverityClause *SeverityC =
11328       OMPExecutableDirective::getSingleClause<OMPSeverityClause>(Clauses);
11329   const OMPMessageClause *MessageC =
11330       OMPExecutableDirective::getSingleClause<OMPMessageClause>(Clauses);
11331   Expr *ME = MessageC ? MessageC->getMessageString() : nullptr;
11332 
11333   if (!AtC || AtC->getAtKind() == OMPC_AT_compilation) {
11334     if (SeverityC && SeverityC->getSeverityKind() == OMPC_SEVERITY_warning)
11335       Diag(SeverityC->getSeverityKindKwLoc(), diag::warn_diagnose_if_succeeded)
11336           << (ME ? cast<StringLiteral>(ME)->getString() : "WARNING");
11337     else
11338       Diag(StartLoc, diag::err_diagnose_if_succeeded)
11339           << (ME ? cast<StringLiteral>(ME)->getString() : "ERROR");
11340     if (!SeverityC || SeverityC->getSeverityKind() != OMPC_SEVERITY_warning)
11341       return StmtError();
11342   }
11343   return OMPErrorDirective::Create(Context, StartLoc, EndLoc, Clauses);
11344 }
11345 
11346 StmtResult Sema::ActOnOpenMPTaskwaitDirective(ArrayRef<OMPClause *> Clauses,
11347                                               SourceLocation StartLoc,
11348                                               SourceLocation EndLoc) {
11349   const OMPNowaitClause *NowaitC =
11350       OMPExecutableDirective::getSingleClause<OMPNowaitClause>(Clauses);
11351   bool HasDependC =
11352       !OMPExecutableDirective::getClausesOfKind<OMPDependClause>(Clauses)
11353            .empty();
11354   if (NowaitC && !HasDependC) {
11355     Diag(StartLoc, diag::err_omp_nowait_clause_without_depend);
11356     return StmtError();
11357   }
11358 
11359   return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc, Clauses);
11360 }
11361 
11362 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
11363                                                Stmt *AStmt,
11364                                                SourceLocation StartLoc,
11365                                                SourceLocation EndLoc) {
11366   if (!AStmt)
11367     return StmtError();
11368 
11369   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11370 
11371   setFunctionHasBranchProtectedScope();
11372 
11373   return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
11374                                        AStmt,
11375                                        DSAStack->getTaskgroupReductionRef());
11376 }
11377 
11378 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
11379                                            SourceLocation StartLoc,
11380                                            SourceLocation EndLoc) {
11381   OMPFlushClause *FC = nullptr;
11382   OMPClause *OrderClause = nullptr;
11383   for (OMPClause *C : Clauses) {
11384     if (C->getClauseKind() == OMPC_flush)
11385       FC = cast<OMPFlushClause>(C);
11386     else
11387       OrderClause = C;
11388   }
11389   OpenMPClauseKind MemOrderKind = OMPC_unknown;
11390   SourceLocation MemOrderLoc;
11391   for (const OMPClause *C : Clauses) {
11392     if (C->getClauseKind() == OMPC_acq_rel ||
11393         C->getClauseKind() == OMPC_acquire ||
11394         C->getClauseKind() == OMPC_release) {
11395       if (MemOrderKind != OMPC_unknown) {
11396         Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
11397             << getOpenMPDirectiveName(OMPD_flush) << 1
11398             << SourceRange(C->getBeginLoc(), C->getEndLoc());
11399         Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
11400             << getOpenMPClauseName(MemOrderKind);
11401       } else {
11402         MemOrderKind = C->getClauseKind();
11403         MemOrderLoc = C->getBeginLoc();
11404       }
11405     }
11406   }
11407   if (FC && OrderClause) {
11408     Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list)
11409         << getOpenMPClauseName(OrderClause->getClauseKind());
11410     Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here)
11411         << getOpenMPClauseName(OrderClause->getClauseKind());
11412     return StmtError();
11413   }
11414   return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
11415 }
11416 
11417 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses,
11418                                             SourceLocation StartLoc,
11419                                             SourceLocation EndLoc) {
11420   if (Clauses.empty()) {
11421     Diag(StartLoc, diag::err_omp_depobj_expected);
11422     return StmtError();
11423   } else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
11424     Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
11425     return StmtError();
11426   }
11427   // Only depobj expression and another single clause is allowed.
11428   if (Clauses.size() > 2) {
11429     Diag(Clauses[2]->getBeginLoc(),
11430          diag::err_omp_depobj_single_clause_expected);
11431     return StmtError();
11432   } else if (Clauses.size() < 1) {
11433     Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
11434     return StmtError();
11435   }
11436   return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses);
11437 }
11438 
11439 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses,
11440                                           SourceLocation StartLoc,
11441                                           SourceLocation EndLoc) {
11442   // Check that exactly one clause is specified.
11443   if (Clauses.size() != 1) {
11444     Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
11445          diag::err_omp_scan_single_clause_expected);
11446     return StmtError();
11447   }
11448   // Check that scan directive is used in the scopeof the OpenMP loop body.
11449   if (Scope *S = DSAStack->getCurScope()) {
11450     Scope *ParentS = S->getParent();
11451     if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() ||
11452         !ParentS->getBreakParent()->isOpenMPLoopScope())
11453       return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive)
11454                        << getOpenMPDirectiveName(OMPD_scan) << 5);
11455   }
11456   // Check that only one instance of scan directives is used in the same outer
11457   // region.
11458   if (DSAStack->doesParentHasScanDirective()) {
11459     Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan";
11460     Diag(DSAStack->getParentScanDirectiveLoc(),
11461          diag::note_omp_previous_directive)
11462         << "scan";
11463     return StmtError();
11464   }
11465   DSAStack->setParentHasScanDirective(StartLoc);
11466   return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses);
11467 }
11468 
11469 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
11470                                              Stmt *AStmt,
11471                                              SourceLocation StartLoc,
11472                                              SourceLocation EndLoc) {
11473   const OMPClause *DependFound = nullptr;
11474   const OMPClause *DependSourceClause = nullptr;
11475   const OMPClause *DependSinkClause = nullptr;
11476   const OMPClause *DoacrossFound = nullptr;
11477   const OMPClause *DoacrossSourceClause = nullptr;
11478   const OMPClause *DoacrossSinkClause = nullptr;
11479   bool ErrorFound = false;
11480   const OMPThreadsClause *TC = nullptr;
11481   const OMPSIMDClause *SC = nullptr;
11482   for (const OMPClause *C : Clauses) {
11483     auto DOC = dyn_cast<OMPDoacrossClause>(C);
11484     auto DC = dyn_cast<OMPDependClause>(C);
11485     if (DC || DOC) {
11486       DependFound = DC ? C : nullptr;
11487       DoacrossFound = DOC ? C : nullptr;
11488       OMPDoacrossKind ODK;
11489       if ((DC && DC->getDependencyKind() == OMPC_DEPEND_source) ||
11490           (DOC && (ODK.isSource(DOC)))) {
11491         if ((DC && DependSourceClause) || (DOC && DoacrossSourceClause)) {
11492           Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
11493               << getOpenMPDirectiveName(OMPD_ordered)
11494               << getOpenMPClauseName(DC ? OMPC_depend : OMPC_doacross) << 2;
11495           ErrorFound = true;
11496         } else {
11497           if (DC)
11498             DependSourceClause = C;
11499           else
11500             DoacrossSourceClause = C;
11501         }
11502         if ((DC && DependSinkClause) || (DOC && DoacrossSinkClause)) {
11503           Diag(C->getBeginLoc(), diag::err_omp_sink_and_source_not_allowed)
11504               << (DC ? "depend" : "doacross") << 0;
11505           ErrorFound = true;
11506         }
11507       } else if ((DC && DC->getDependencyKind() == OMPC_DEPEND_sink) ||
11508                  (DOC && (ODK.isSink(DOC) || ODK.isSinkIter(DOC)))) {
11509         if (DependSourceClause || DoacrossSourceClause) {
11510           Diag(C->getBeginLoc(), diag::err_omp_sink_and_source_not_allowed)
11511               << (DC ? "depend" : "doacross") << 1;
11512           ErrorFound = true;
11513         }
11514         if (DC)
11515           DependSinkClause = C;
11516         else
11517           DoacrossSinkClause = C;
11518       }
11519     } else if (C->getClauseKind() == OMPC_threads) {
11520       TC = cast<OMPThreadsClause>(C);
11521     } else if (C->getClauseKind() == OMPC_simd) {
11522       SC = cast<OMPSIMDClause>(C);
11523     }
11524   }
11525   if (!ErrorFound && !SC &&
11526       isOpenMPSimdDirective(DSAStack->getParentDirective())) {
11527     // OpenMP [2.8.1,simd Construct, Restrictions]
11528     // An ordered construct with the simd clause is the only OpenMP construct
11529     // that can appear in the simd region.
11530     Diag(StartLoc, diag::err_omp_prohibited_region_simd)
11531         << (LangOpts.OpenMP >= 50 ? 1 : 0);
11532     ErrorFound = true;
11533   } else if ((DependFound || DoacrossFound) && (TC || SC)) {
11534     SourceLocation Loc =
11535         DependFound ? DependFound->getBeginLoc() : DoacrossFound->getBeginLoc();
11536     Diag(Loc, diag::err_omp_depend_clause_thread_simd)
11537         << getOpenMPClauseName(DependFound ? OMPC_depend : OMPC_doacross)
11538         << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
11539     ErrorFound = true;
11540   } else if ((DependFound || DoacrossFound) &&
11541              !DSAStack->getParentOrderedRegionParam().first) {
11542     SourceLocation Loc =
11543         DependFound ? DependFound->getBeginLoc() : DoacrossFound->getBeginLoc();
11544     Diag(Loc, diag::err_omp_ordered_directive_without_param)
11545         << getOpenMPClauseName(DependFound ? OMPC_depend : OMPC_doacross);
11546     ErrorFound = true;
11547   } else if (TC || Clauses.empty()) {
11548     if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) {
11549       SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
11550       Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
11551           << (TC != nullptr);
11552       Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1;
11553       ErrorFound = true;
11554     }
11555   }
11556   if ((!AStmt && !DependFound && !DoacrossFound) || ErrorFound)
11557     return StmtError();
11558 
11559   // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions.
11560   // During execution of an iteration of a worksharing-loop or a loop nest
11561   // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread
11562   // must not execute more than one ordered region corresponding to an ordered
11563   // construct without a depend clause.
11564   if (!DependFound && !DoacrossFound) {
11565     if (DSAStack->doesParentHasOrderedDirective()) {
11566       Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered";
11567       Diag(DSAStack->getParentOrderedDirectiveLoc(),
11568            diag::note_omp_previous_directive)
11569           << "ordered";
11570       return StmtError();
11571     }
11572     DSAStack->setParentHasOrderedDirective(StartLoc);
11573   }
11574 
11575   if (AStmt) {
11576     assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11577 
11578     setFunctionHasBranchProtectedScope();
11579   }
11580 
11581   return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
11582 }
11583 
11584 namespace {
11585 /// Helper class for checking expression in 'omp atomic [update]'
11586 /// construct.
11587 class OpenMPAtomicUpdateChecker {
11588   /// Error results for atomic update expressions.
11589   enum ExprAnalysisErrorCode {
11590     /// A statement is not an expression statement.
11591     NotAnExpression,
11592     /// Expression is not builtin binary or unary operation.
11593     NotABinaryOrUnaryExpression,
11594     /// Unary operation is not post-/pre- increment/decrement operation.
11595     NotAnUnaryIncDecExpression,
11596     /// An expression is not of scalar type.
11597     NotAScalarType,
11598     /// A binary operation is not an assignment operation.
11599     NotAnAssignmentOp,
11600     /// RHS part of the binary operation is not a binary expression.
11601     NotABinaryExpression,
11602     /// RHS part is not additive/multiplicative/shift/biwise binary
11603     /// expression.
11604     NotABinaryOperator,
11605     /// RHS binary operation does not have reference to the updated LHS
11606     /// part.
11607     NotAnUpdateExpression,
11608     /// An expression contains semantical error not related to
11609     /// 'omp atomic [update]'
11610     NotAValidExpression,
11611     /// No errors is found.
11612     NoError
11613   };
11614   /// Reference to Sema.
11615   Sema &SemaRef;
11616   /// A location for note diagnostics (when error is found).
11617   SourceLocation NoteLoc;
11618   /// 'x' lvalue part of the source atomic expression.
11619   Expr *X;
11620   /// 'expr' rvalue part of the source atomic expression.
11621   Expr *E;
11622   /// Helper expression of the form
11623   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
11624   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
11625   Expr *UpdateExpr;
11626   /// Is 'x' a LHS in a RHS part of full update expression. It is
11627   /// important for non-associative operations.
11628   bool IsXLHSInRHSPart;
11629   BinaryOperatorKind Op;
11630   SourceLocation OpLoc;
11631   /// true if the source expression is a postfix unary operation, false
11632   /// if it is a prefix unary operation.
11633   bool IsPostfixUpdate;
11634 
11635 public:
11636   OpenMPAtomicUpdateChecker(Sema &SemaRef)
11637       : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
11638         IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
11639   /// Check specified statement that it is suitable for 'atomic update'
11640   /// constructs and extract 'x', 'expr' and Operation from the original
11641   /// expression. If DiagId and NoteId == 0, then only check is performed
11642   /// without error notification.
11643   /// \param DiagId Diagnostic which should be emitted if error is found.
11644   /// \param NoteId Diagnostic note for the main error message.
11645   /// \return true if statement is not an update expression, false otherwise.
11646   bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
11647   /// Return the 'x' lvalue part of the source atomic expression.
11648   Expr *getX() const { return X; }
11649   /// Return the 'expr' rvalue part of the source atomic expression.
11650   Expr *getExpr() const { return E; }
11651   /// Return the update expression used in calculation of the updated
11652   /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
11653   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
11654   Expr *getUpdateExpr() const { return UpdateExpr; }
11655   /// Return true if 'x' is LHS in RHS part of full update expression,
11656   /// false otherwise.
11657   bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
11658 
11659   /// true if the source expression is a postfix unary operation, false
11660   /// if it is a prefix unary operation.
11661   bool isPostfixUpdate() const { return IsPostfixUpdate; }
11662 
11663 private:
11664   bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
11665                             unsigned NoteId = 0);
11666 };
11667 
11668 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
11669     BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
11670   ExprAnalysisErrorCode ErrorFound = NoError;
11671   SourceLocation ErrorLoc, NoteLoc;
11672   SourceRange ErrorRange, NoteRange;
11673   // Allowed constructs are:
11674   //  x = x binop expr;
11675   //  x = expr binop x;
11676   if (AtomicBinOp->getOpcode() == BO_Assign) {
11677     X = AtomicBinOp->getLHS();
11678     if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
11679             AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
11680       if (AtomicInnerBinOp->isMultiplicativeOp() ||
11681           AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
11682           AtomicInnerBinOp->isBitwiseOp()) {
11683         Op = AtomicInnerBinOp->getOpcode();
11684         OpLoc = AtomicInnerBinOp->getOperatorLoc();
11685         Expr *LHS = AtomicInnerBinOp->getLHS();
11686         Expr *RHS = AtomicInnerBinOp->getRHS();
11687         llvm::FoldingSetNodeID XId, LHSId, RHSId;
11688         X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
11689                                           /*Canonical=*/true);
11690         LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
11691                                             /*Canonical=*/true);
11692         RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
11693                                             /*Canonical=*/true);
11694         if (XId == LHSId) {
11695           E = RHS;
11696           IsXLHSInRHSPart = true;
11697         } else if (XId == RHSId) {
11698           E = LHS;
11699           IsXLHSInRHSPart = false;
11700         } else {
11701           ErrorLoc = AtomicInnerBinOp->getExprLoc();
11702           ErrorRange = AtomicInnerBinOp->getSourceRange();
11703           NoteLoc = X->getExprLoc();
11704           NoteRange = X->getSourceRange();
11705           ErrorFound = NotAnUpdateExpression;
11706         }
11707       } else {
11708         ErrorLoc = AtomicInnerBinOp->getExprLoc();
11709         ErrorRange = AtomicInnerBinOp->getSourceRange();
11710         NoteLoc = AtomicInnerBinOp->getOperatorLoc();
11711         NoteRange = SourceRange(NoteLoc, NoteLoc);
11712         ErrorFound = NotABinaryOperator;
11713       }
11714     } else {
11715       NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
11716       NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
11717       ErrorFound = NotABinaryExpression;
11718     }
11719   } else {
11720     ErrorLoc = AtomicBinOp->getExprLoc();
11721     ErrorRange = AtomicBinOp->getSourceRange();
11722     NoteLoc = AtomicBinOp->getOperatorLoc();
11723     NoteRange = SourceRange(NoteLoc, NoteLoc);
11724     ErrorFound = NotAnAssignmentOp;
11725   }
11726   if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
11727     SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
11728     SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
11729     return true;
11730   }
11731   if (SemaRef.CurContext->isDependentContext())
11732     E = X = UpdateExpr = nullptr;
11733   return ErrorFound != NoError;
11734 }
11735 
11736 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
11737                                                unsigned NoteId) {
11738   ExprAnalysisErrorCode ErrorFound = NoError;
11739   SourceLocation ErrorLoc, NoteLoc;
11740   SourceRange ErrorRange, NoteRange;
11741   // Allowed constructs are:
11742   //  x++;
11743   //  x--;
11744   //  ++x;
11745   //  --x;
11746   //  x binop= expr;
11747   //  x = x binop expr;
11748   //  x = expr binop x;
11749   if (auto *AtomicBody = dyn_cast<Expr>(S)) {
11750     AtomicBody = AtomicBody->IgnoreParenImpCasts();
11751     if (AtomicBody->getType()->isScalarType() ||
11752         AtomicBody->isInstantiationDependent()) {
11753       if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
11754               AtomicBody->IgnoreParenImpCasts())) {
11755         // Check for Compound Assignment Operation
11756         Op = BinaryOperator::getOpForCompoundAssignment(
11757             AtomicCompAssignOp->getOpcode());
11758         OpLoc = AtomicCompAssignOp->getOperatorLoc();
11759         E = AtomicCompAssignOp->getRHS();
11760         X = AtomicCompAssignOp->getLHS()->IgnoreParens();
11761         IsXLHSInRHSPart = true;
11762       } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
11763                      AtomicBody->IgnoreParenImpCasts())) {
11764         // Check for Binary Operation
11765         if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
11766           return true;
11767       } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
11768                      AtomicBody->IgnoreParenImpCasts())) {
11769         // Check for Unary Operation
11770         if (AtomicUnaryOp->isIncrementDecrementOp()) {
11771           IsPostfixUpdate = AtomicUnaryOp->isPostfix();
11772           Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
11773           OpLoc = AtomicUnaryOp->getOperatorLoc();
11774           X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
11775           E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
11776           IsXLHSInRHSPart = true;
11777         } else {
11778           ErrorFound = NotAnUnaryIncDecExpression;
11779           ErrorLoc = AtomicUnaryOp->getExprLoc();
11780           ErrorRange = AtomicUnaryOp->getSourceRange();
11781           NoteLoc = AtomicUnaryOp->getOperatorLoc();
11782           NoteRange = SourceRange(NoteLoc, NoteLoc);
11783         }
11784       } else if (!AtomicBody->isInstantiationDependent()) {
11785         ErrorFound = NotABinaryOrUnaryExpression;
11786         NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
11787         NoteRange = ErrorRange = AtomicBody->getSourceRange();
11788       } else if (AtomicBody->containsErrors()) {
11789         ErrorFound = NotAValidExpression;
11790         NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
11791         NoteRange = ErrorRange = AtomicBody->getSourceRange();
11792       }
11793     } else {
11794       ErrorFound = NotAScalarType;
11795       NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
11796       NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
11797     }
11798   } else {
11799     ErrorFound = NotAnExpression;
11800     NoteLoc = ErrorLoc = S->getBeginLoc();
11801     NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
11802   }
11803   if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
11804     SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
11805     SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
11806     return true;
11807   }
11808   if (SemaRef.CurContext->isDependentContext())
11809     E = X = UpdateExpr = nullptr;
11810   if (ErrorFound == NoError && E && X) {
11811     // Build an update expression of form 'OpaqueValueExpr(x) binop
11812     // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
11813     // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
11814     auto *OVEX = new (SemaRef.getASTContext())
11815         OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_PRValue);
11816     auto *OVEExpr = new (SemaRef.getASTContext())
11817         OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_PRValue);
11818     ExprResult Update =
11819         SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
11820                                    IsXLHSInRHSPart ? OVEExpr : OVEX);
11821     if (Update.isInvalid())
11822       return true;
11823     Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
11824                                                Sema::AA_Casting);
11825     if (Update.isInvalid())
11826       return true;
11827     UpdateExpr = Update.get();
11828   }
11829   return ErrorFound != NoError;
11830 }
11831 
11832 /// Get the node id of the fixed point of an expression \a S.
11833 llvm::FoldingSetNodeID getNodeId(ASTContext &Context, const Expr *S) {
11834   llvm::FoldingSetNodeID Id;
11835   S->IgnoreParenImpCasts()->Profile(Id, Context, true);
11836   return Id;
11837 }
11838 
11839 /// Check if two expressions are same.
11840 bool checkIfTwoExprsAreSame(ASTContext &Context, const Expr *LHS,
11841                             const Expr *RHS) {
11842   return getNodeId(Context, LHS) == getNodeId(Context, RHS);
11843 }
11844 
11845 class OpenMPAtomicCompareChecker {
11846 public:
11847   /// All kinds of errors that can occur in `atomic compare`
11848   enum ErrorTy {
11849     /// Empty compound statement.
11850     NoStmt = 0,
11851     /// More than one statement in a compound statement.
11852     MoreThanOneStmt,
11853     /// Not an assignment binary operator.
11854     NotAnAssignment,
11855     /// Not a conditional operator.
11856     NotCondOp,
11857     /// Wrong false expr. According to the spec, 'x' should be at the false
11858     /// expression of a conditional expression.
11859     WrongFalseExpr,
11860     /// The condition of a conditional expression is not a binary operator.
11861     NotABinaryOp,
11862     /// Invalid binary operator (not <, >, or ==).
11863     InvalidBinaryOp,
11864     /// Invalid comparison (not x == e, e == x, x ordop expr, or expr ordop x).
11865     InvalidComparison,
11866     /// X is not a lvalue.
11867     XNotLValue,
11868     /// Not a scalar.
11869     NotScalar,
11870     /// Not an integer.
11871     NotInteger,
11872     /// 'else' statement is not expected.
11873     UnexpectedElse,
11874     /// Not an equality operator.
11875     NotEQ,
11876     /// Invalid assignment (not v == x).
11877     InvalidAssignment,
11878     /// Not if statement
11879     NotIfStmt,
11880     /// More than two statements in a compund statement.
11881     MoreThanTwoStmts,
11882     /// Not a compound statement.
11883     NotCompoundStmt,
11884     /// No else statement.
11885     NoElse,
11886     /// Not 'if (r)'.
11887     InvalidCondition,
11888     /// No error.
11889     NoError,
11890   };
11891 
11892   struct ErrorInfoTy {
11893     ErrorTy Error;
11894     SourceLocation ErrorLoc;
11895     SourceRange ErrorRange;
11896     SourceLocation NoteLoc;
11897     SourceRange NoteRange;
11898   };
11899 
11900   OpenMPAtomicCompareChecker(Sema &S) : ContextRef(S.getASTContext()) {}
11901 
11902   /// Check if statement \a S is valid for <tt>atomic compare</tt>.
11903   bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
11904 
11905   Expr *getX() const { return X; }
11906   Expr *getE() const { return E; }
11907   Expr *getD() const { return D; }
11908   Expr *getCond() const { return C; }
11909   bool isXBinopExpr() const { return IsXBinopExpr; }
11910 
11911 protected:
11912   /// Reference to ASTContext
11913   ASTContext &ContextRef;
11914   /// 'x' lvalue part of the source atomic expression.
11915   Expr *X = nullptr;
11916   /// 'expr' or 'e' rvalue part of the source atomic expression.
11917   Expr *E = nullptr;
11918   /// 'd' rvalue part of the source atomic expression.
11919   Expr *D = nullptr;
11920   /// 'cond' part of the source atomic expression. It is in one of the following
11921   /// forms:
11922   /// expr ordop x
11923   /// x ordop expr
11924   /// x == e
11925   /// e == x
11926   Expr *C = nullptr;
11927   /// True if the cond expr is in the form of 'x ordop expr'.
11928   bool IsXBinopExpr = true;
11929 
11930   /// Check if it is a valid conditional update statement (cond-update-stmt).
11931   bool checkCondUpdateStmt(IfStmt *S, ErrorInfoTy &ErrorInfo);
11932 
11933   /// Check if it is a valid conditional expression statement (cond-expr-stmt).
11934   bool checkCondExprStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
11935 
11936   /// Check if all captured values have right type.
11937   bool checkType(ErrorInfoTy &ErrorInfo) const;
11938 
11939   static bool CheckValue(const Expr *E, ErrorInfoTy &ErrorInfo,
11940                          bool ShouldBeLValue, bool ShouldBeInteger = false) {
11941     if (E->isInstantiationDependent())
11942       return true;
11943 
11944     if (ShouldBeLValue && !E->isLValue()) {
11945       ErrorInfo.Error = ErrorTy::XNotLValue;
11946       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11947       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11948       return false;
11949     }
11950 
11951     QualType QTy = E->getType();
11952     if (!QTy->isScalarType()) {
11953       ErrorInfo.Error = ErrorTy::NotScalar;
11954       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11955       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11956       return false;
11957     }
11958     if (ShouldBeInteger && !QTy->isIntegerType()) {
11959       ErrorInfo.Error = ErrorTy::NotInteger;
11960       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11961       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11962       return false;
11963     }
11964 
11965     return true;
11966   }
11967   };
11968 
11969 bool OpenMPAtomicCompareChecker::checkCondUpdateStmt(IfStmt *S,
11970                                                      ErrorInfoTy &ErrorInfo) {
11971   auto *Then = S->getThen();
11972   if (auto *CS = dyn_cast<CompoundStmt>(Then)) {
11973     if (CS->body_empty()) {
11974       ErrorInfo.Error = ErrorTy::NoStmt;
11975       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11976       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11977       return false;
11978     }
11979     if (CS->size() > 1) {
11980       ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11981       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11982       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
11983       return false;
11984     }
11985     Then = CS->body_front();
11986   }
11987 
11988   auto *BO = dyn_cast<BinaryOperator>(Then);
11989   if (!BO) {
11990     ErrorInfo.Error = ErrorTy::NotAnAssignment;
11991     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc();
11992     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange();
11993     return false;
11994   }
11995   if (BO->getOpcode() != BO_Assign) {
11996     ErrorInfo.Error = ErrorTy::NotAnAssignment;
11997     ErrorInfo.ErrorLoc = BO->getExprLoc();
11998     ErrorInfo.NoteLoc = BO->getOperatorLoc();
11999     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12000     return false;
12001   }
12002 
12003   X = BO->getLHS();
12004 
12005   auto *Cond = dyn_cast<BinaryOperator>(S->getCond());
12006   if (!Cond) {
12007     ErrorInfo.Error = ErrorTy::NotABinaryOp;
12008     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc();
12009     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange();
12010     return false;
12011   }
12012 
12013   switch (Cond->getOpcode()) {
12014   case BO_EQ: {
12015     C = Cond;
12016     D = BO->getRHS();
12017     if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
12018       E = Cond->getRHS();
12019     } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
12020       E = Cond->getLHS();
12021     } else {
12022       ErrorInfo.Error = ErrorTy::InvalidComparison;
12023       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12024       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12025       return false;
12026     }
12027     break;
12028   }
12029   case BO_LT:
12030   case BO_GT: {
12031     E = BO->getRHS();
12032     if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) &&
12033         checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) {
12034       C = Cond;
12035     } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) &&
12036                checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
12037       C = Cond;
12038       IsXBinopExpr = false;
12039     } else {
12040       ErrorInfo.Error = ErrorTy::InvalidComparison;
12041       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12042       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12043       return false;
12044     }
12045     break;
12046   }
12047   default:
12048     ErrorInfo.Error = ErrorTy::InvalidBinaryOp;
12049     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12050     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12051     return false;
12052   }
12053 
12054   if (S->getElse()) {
12055     ErrorInfo.Error = ErrorTy::UnexpectedElse;
12056     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getElse()->getBeginLoc();
12057     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getElse()->getSourceRange();
12058     return false;
12059   }
12060 
12061   return true;
12062 }
12063 
12064 bool OpenMPAtomicCompareChecker::checkCondExprStmt(Stmt *S,
12065                                                    ErrorInfoTy &ErrorInfo) {
12066   auto *BO = dyn_cast<BinaryOperator>(S);
12067   if (!BO) {
12068     ErrorInfo.Error = ErrorTy::NotAnAssignment;
12069     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
12070     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12071     return false;
12072   }
12073   if (BO->getOpcode() != BO_Assign) {
12074     ErrorInfo.Error = ErrorTy::NotAnAssignment;
12075     ErrorInfo.ErrorLoc = BO->getExprLoc();
12076     ErrorInfo.NoteLoc = BO->getOperatorLoc();
12077     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12078     return false;
12079   }
12080 
12081   X = BO->getLHS();
12082 
12083   auto *CO = dyn_cast<ConditionalOperator>(BO->getRHS()->IgnoreParenImpCasts());
12084   if (!CO) {
12085     ErrorInfo.Error = ErrorTy::NotCondOp;
12086     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getRHS()->getExprLoc();
12087     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getRHS()->getSourceRange();
12088     return false;
12089   }
12090 
12091   if (!checkIfTwoExprsAreSame(ContextRef, X, CO->getFalseExpr())) {
12092     ErrorInfo.Error = ErrorTy::WrongFalseExpr;
12093     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getFalseExpr()->getExprLoc();
12094     ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12095         CO->getFalseExpr()->getSourceRange();
12096     return false;
12097   }
12098 
12099   auto *Cond = dyn_cast<BinaryOperator>(CO->getCond());
12100   if (!Cond) {
12101     ErrorInfo.Error = ErrorTy::NotABinaryOp;
12102     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getCond()->getExprLoc();
12103     ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12104         CO->getCond()->getSourceRange();
12105     return false;
12106   }
12107 
12108   switch (Cond->getOpcode()) {
12109   case BO_EQ: {
12110     C = Cond;
12111     D = CO->getTrueExpr();
12112     if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
12113       E = Cond->getRHS();
12114     } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
12115       E = Cond->getLHS();
12116     } else {
12117       ErrorInfo.Error = ErrorTy::InvalidComparison;
12118       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12119       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12120       return false;
12121     }
12122     break;
12123   }
12124   case BO_LT:
12125   case BO_GT: {
12126     E = CO->getTrueExpr();
12127     if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) &&
12128         checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) {
12129       C = Cond;
12130     } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) &&
12131                checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
12132       C = Cond;
12133       IsXBinopExpr = false;
12134     } else {
12135       ErrorInfo.Error = ErrorTy::InvalidComparison;
12136       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12137       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12138       return false;
12139     }
12140     break;
12141   }
12142   default:
12143     ErrorInfo.Error = ErrorTy::InvalidBinaryOp;
12144     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12145     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12146     return false;
12147   }
12148 
12149   return true;
12150 }
12151 
12152 bool OpenMPAtomicCompareChecker::checkType(ErrorInfoTy &ErrorInfo) const {
12153   // 'x' and 'e' cannot be nullptr
12154   assert(X && E && "X and E cannot be nullptr");
12155 
12156   if (!CheckValue(X, ErrorInfo, true))
12157     return false;
12158 
12159   if (!CheckValue(E, ErrorInfo, false))
12160     return false;
12161 
12162   if (D && !CheckValue(D, ErrorInfo, false))
12163     return false;
12164 
12165   return true;
12166 }
12167 
12168 bool OpenMPAtomicCompareChecker::checkStmt(
12169     Stmt *S, OpenMPAtomicCompareChecker::ErrorInfoTy &ErrorInfo) {
12170   auto *CS = dyn_cast<CompoundStmt>(S);
12171   if (CS) {
12172     if (CS->body_empty()) {
12173       ErrorInfo.Error = ErrorTy::NoStmt;
12174       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12175       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12176       return false;
12177     }
12178 
12179     if (CS->size() != 1) {
12180       ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12181       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12182       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12183       return false;
12184     }
12185     S = CS->body_front();
12186   }
12187 
12188   auto Res = false;
12189 
12190   if (auto *IS = dyn_cast<IfStmt>(S)) {
12191     // Check if the statement is in one of the following forms
12192     // (cond-update-stmt):
12193     // if (expr ordop x) { x = expr; }
12194     // if (x ordop expr) { x = expr; }
12195     // if (x == e) { x = d; }
12196     Res = checkCondUpdateStmt(IS, ErrorInfo);
12197   } else {
12198     // Check if the statement is in one of the following forms (cond-expr-stmt):
12199     // x = expr ordop x ? expr : x;
12200     // x = x ordop expr ? expr : x;
12201     // x = x == e ? d : x;
12202     Res = checkCondExprStmt(S, ErrorInfo);
12203   }
12204 
12205   if (!Res)
12206     return false;
12207 
12208   return checkType(ErrorInfo);
12209 }
12210 
12211 class OpenMPAtomicCompareCaptureChecker final
12212     : public OpenMPAtomicCompareChecker {
12213 public:
12214   OpenMPAtomicCompareCaptureChecker(Sema &S) : OpenMPAtomicCompareChecker(S) {}
12215 
12216   Expr *getV() const { return V; }
12217   Expr *getR() const { return R; }
12218   bool isFailOnly() const { return IsFailOnly; }
12219   bool isPostfixUpdate() const { return IsPostfixUpdate; }
12220 
12221   /// Check if statement \a S is valid for <tt>atomic compare capture</tt>.
12222   bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
12223 
12224 private:
12225   bool checkType(ErrorInfoTy &ErrorInfo);
12226 
12227   // NOTE: Form 3, 4, 5 in the following comments mean the 3rd, 4th, and 5th
12228   // form of 'conditional-update-capture-atomic' structured block on the v5.2
12229   // spec p.p. 82:
12230   // (1) { v = x; cond-update-stmt }
12231   // (2) { cond-update-stmt v = x; }
12232   // (3) if(x == e) { x = d; } else { v = x; }
12233   // (4) { r = x == e; if(r) { x = d; } }
12234   // (5) { r = x == e; if(r) { x = d; } else { v = x; } }
12235 
12236   /// Check if it is valid 'if(x == e) { x = d; } else { v = x; }' (form 3)
12237   bool checkForm3(IfStmt *S, ErrorInfoTy &ErrorInfo);
12238 
12239   /// Check if it is valid '{ r = x == e; if(r) { x = d; } }',
12240   /// or '{ r = x == e; if(r) { x = d; } else { v = x; } }' (form 4 and 5)
12241   bool checkForm45(Stmt *S, ErrorInfoTy &ErrorInfo);
12242 
12243   /// 'v' lvalue part of the source atomic expression.
12244   Expr *V = nullptr;
12245   /// 'r' lvalue part of the source atomic expression.
12246   Expr *R = nullptr;
12247   /// If 'v' is only updated when the comparison fails.
12248   bool IsFailOnly = false;
12249   /// If original value of 'x' must be stored in 'v', not an updated one.
12250   bool IsPostfixUpdate = false;
12251 };
12252 
12253 bool OpenMPAtomicCompareCaptureChecker::checkType(ErrorInfoTy &ErrorInfo) {
12254   if (!OpenMPAtomicCompareChecker::checkType(ErrorInfo))
12255     return false;
12256 
12257   if (V && !CheckValue(V, ErrorInfo, true))
12258     return false;
12259 
12260   if (R && !CheckValue(R, ErrorInfo, true, true))
12261     return false;
12262 
12263   return true;
12264 }
12265 
12266 bool OpenMPAtomicCompareCaptureChecker::checkForm3(IfStmt *S,
12267                                                    ErrorInfoTy &ErrorInfo) {
12268   IsFailOnly = true;
12269 
12270   auto *Then = S->getThen();
12271   if (auto *CS = dyn_cast<CompoundStmt>(Then)) {
12272     if (CS->body_empty()) {
12273       ErrorInfo.Error = ErrorTy::NoStmt;
12274       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12275       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12276       return false;
12277     }
12278     if (CS->size() > 1) {
12279       ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12280       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12281       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12282       return false;
12283     }
12284     Then = CS->body_front();
12285   }
12286 
12287   auto *BO = dyn_cast<BinaryOperator>(Then);
12288   if (!BO) {
12289     ErrorInfo.Error = ErrorTy::NotAnAssignment;
12290     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc();
12291     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange();
12292     return false;
12293   }
12294   if (BO->getOpcode() != BO_Assign) {
12295     ErrorInfo.Error = ErrorTy::NotAnAssignment;
12296     ErrorInfo.ErrorLoc = BO->getExprLoc();
12297     ErrorInfo.NoteLoc = BO->getOperatorLoc();
12298     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12299     return false;
12300   }
12301 
12302   X = BO->getLHS();
12303   D = BO->getRHS();
12304 
12305   auto *Cond = dyn_cast<BinaryOperator>(S->getCond());
12306   if (!Cond) {
12307     ErrorInfo.Error = ErrorTy::NotABinaryOp;
12308     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc();
12309     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange();
12310     return false;
12311   }
12312   if (Cond->getOpcode() != BO_EQ) {
12313     ErrorInfo.Error = ErrorTy::NotEQ;
12314     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12315     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12316     return false;
12317   }
12318 
12319   if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
12320     E = Cond->getRHS();
12321   } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
12322     E = Cond->getLHS();
12323   } else {
12324     ErrorInfo.Error = ErrorTy::InvalidComparison;
12325     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
12326     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
12327     return false;
12328   }
12329 
12330   C = Cond;
12331 
12332   if (!S->getElse()) {
12333     ErrorInfo.Error = ErrorTy::NoElse;
12334     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
12335     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12336     return false;
12337   }
12338 
12339   auto *Else = S->getElse();
12340   if (auto *CS = dyn_cast<CompoundStmt>(Else)) {
12341     if (CS->body_empty()) {
12342       ErrorInfo.Error = ErrorTy::NoStmt;
12343       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12344       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12345       return false;
12346     }
12347     if (CS->size() > 1) {
12348       ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12349       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12350       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12351       return false;
12352     }
12353     Else = CS->body_front();
12354   }
12355 
12356   auto *ElseBO = dyn_cast<BinaryOperator>(Else);
12357   if (!ElseBO) {
12358     ErrorInfo.Error = ErrorTy::NotAnAssignment;
12359     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc();
12360     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange();
12361     return false;
12362   }
12363   if (ElseBO->getOpcode() != BO_Assign) {
12364     ErrorInfo.Error = ErrorTy::NotAnAssignment;
12365     ErrorInfo.ErrorLoc = ElseBO->getExprLoc();
12366     ErrorInfo.NoteLoc = ElseBO->getOperatorLoc();
12367     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange();
12368     return false;
12369   }
12370 
12371   if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) {
12372     ErrorInfo.Error = ErrorTy::InvalidAssignment;
12373     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseBO->getRHS()->getExprLoc();
12374     ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12375         ElseBO->getRHS()->getSourceRange();
12376     return false;
12377   }
12378 
12379   V = ElseBO->getLHS();
12380 
12381   return checkType(ErrorInfo);
12382 }
12383 
12384 bool OpenMPAtomicCompareCaptureChecker::checkForm45(Stmt *S,
12385                                                     ErrorInfoTy &ErrorInfo) {
12386   // We don't check here as they should be already done before call this
12387   // function.
12388   auto *CS = cast<CompoundStmt>(S);
12389   assert(CS->size() == 2 && "CompoundStmt size is not expected");
12390   auto *S1 = cast<BinaryOperator>(CS->body_front());
12391   auto *S2 = cast<IfStmt>(CS->body_back());
12392   assert(S1->getOpcode() == BO_Assign && "unexpected binary operator");
12393 
12394   if (!checkIfTwoExprsAreSame(ContextRef, S1->getLHS(), S2->getCond())) {
12395     ErrorInfo.Error = ErrorTy::InvalidCondition;
12396     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getCond()->getExprLoc();
12397     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S1->getLHS()->getSourceRange();
12398     return false;
12399   }
12400 
12401   R = S1->getLHS();
12402 
12403   auto *Then = S2->getThen();
12404   if (auto *ThenCS = dyn_cast<CompoundStmt>(Then)) {
12405     if (ThenCS->body_empty()) {
12406       ErrorInfo.Error = ErrorTy::NoStmt;
12407       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc();
12408       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange();
12409       return false;
12410     }
12411     if (ThenCS->size() > 1) {
12412       ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12413       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc();
12414       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange();
12415       return false;
12416     }
12417     Then = ThenCS->body_front();
12418   }
12419 
12420   auto *ThenBO = dyn_cast<BinaryOperator>(Then);
12421   if (!ThenBO) {
12422     ErrorInfo.Error = ErrorTy::NotAnAssignment;
12423     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getBeginLoc();
12424     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S2->getSourceRange();
12425     return false;
12426   }
12427   if (ThenBO->getOpcode() != BO_Assign) {
12428     ErrorInfo.Error = ErrorTy::NotAnAssignment;
12429     ErrorInfo.ErrorLoc = ThenBO->getExprLoc();
12430     ErrorInfo.NoteLoc = ThenBO->getOperatorLoc();
12431     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenBO->getSourceRange();
12432     return false;
12433   }
12434 
12435   X = ThenBO->getLHS();
12436   D = ThenBO->getRHS();
12437 
12438   auto *BO = cast<BinaryOperator>(S1->getRHS()->IgnoreImpCasts());
12439   if (BO->getOpcode() != BO_EQ) {
12440     ErrorInfo.Error = ErrorTy::NotEQ;
12441     ErrorInfo.ErrorLoc = BO->getExprLoc();
12442     ErrorInfo.NoteLoc = BO->getOperatorLoc();
12443     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12444     return false;
12445   }
12446 
12447   C = BO;
12448 
12449   if (checkIfTwoExprsAreSame(ContextRef, X, BO->getLHS())) {
12450     E = BO->getRHS();
12451   } else if (checkIfTwoExprsAreSame(ContextRef, X, BO->getRHS())) {
12452     E = BO->getLHS();
12453   } else {
12454     ErrorInfo.Error = ErrorTy::InvalidComparison;
12455     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getExprLoc();
12456     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12457     return false;
12458   }
12459 
12460   if (S2->getElse()) {
12461     IsFailOnly = true;
12462 
12463     auto *Else = S2->getElse();
12464     if (auto *ElseCS = dyn_cast<CompoundStmt>(Else)) {
12465       if (ElseCS->body_empty()) {
12466         ErrorInfo.Error = ErrorTy::NoStmt;
12467         ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc();
12468         ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange();
12469         return false;
12470       }
12471       if (ElseCS->size() > 1) {
12472         ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
12473         ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc();
12474         ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange();
12475         return false;
12476       }
12477       Else = ElseCS->body_front();
12478     }
12479 
12480     auto *ElseBO = dyn_cast<BinaryOperator>(Else);
12481     if (!ElseBO) {
12482       ErrorInfo.Error = ErrorTy::NotAnAssignment;
12483       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc();
12484       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange();
12485       return false;
12486     }
12487     if (ElseBO->getOpcode() != BO_Assign) {
12488       ErrorInfo.Error = ErrorTy::NotAnAssignment;
12489       ErrorInfo.ErrorLoc = ElseBO->getExprLoc();
12490       ErrorInfo.NoteLoc = ElseBO->getOperatorLoc();
12491       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange();
12492       return false;
12493     }
12494     if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) {
12495       ErrorInfo.Error = ErrorTy::InvalidAssignment;
12496       ErrorInfo.ErrorLoc = ElseBO->getRHS()->getExprLoc();
12497       ErrorInfo.NoteLoc = X->getExprLoc();
12498       ErrorInfo.ErrorRange = ElseBO->getRHS()->getSourceRange();
12499       ErrorInfo.NoteRange = X->getSourceRange();
12500       return false;
12501     }
12502 
12503     V = ElseBO->getLHS();
12504   }
12505 
12506   return checkType(ErrorInfo);
12507 }
12508 
12509 bool OpenMPAtomicCompareCaptureChecker::checkStmt(Stmt *S,
12510                                                   ErrorInfoTy &ErrorInfo) {
12511   // if(x == e) { x = d; } else { v = x; }
12512   if (auto *IS = dyn_cast<IfStmt>(S))
12513     return checkForm3(IS, ErrorInfo);
12514 
12515   auto *CS = dyn_cast<CompoundStmt>(S);
12516   if (!CS) {
12517     ErrorInfo.Error = ErrorTy::NotCompoundStmt;
12518     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
12519     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
12520     return false;
12521   }
12522   if (CS->body_empty()) {
12523     ErrorInfo.Error = ErrorTy::NoStmt;
12524     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12525     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12526     return false;
12527   }
12528 
12529   // { if(x == e) { x = d; } else { v = x; } }
12530   if (CS->size() == 1) {
12531     auto *IS = dyn_cast<IfStmt>(CS->body_front());
12532     if (!IS) {
12533       ErrorInfo.Error = ErrorTy::NotIfStmt;
12534       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->body_front()->getBeginLoc();
12535       ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
12536           CS->body_front()->getSourceRange();
12537       return false;
12538     }
12539 
12540     return checkForm3(IS, ErrorInfo);
12541   } else if (CS->size() == 2) {
12542     auto *S1 = CS->body_front();
12543     auto *S2 = CS->body_back();
12544 
12545     Stmt *UpdateStmt = nullptr;
12546     Stmt *CondUpdateStmt = nullptr;
12547     Stmt *CondExprStmt = nullptr;
12548 
12549     if (auto *BO = dyn_cast<BinaryOperator>(S1)) {
12550       // It could be one of the following cases:
12551       // { v = x; cond-update-stmt }
12552       // { v = x; cond-expr-stmt }
12553       // { cond-expr-stmt; v = x; }
12554       // form 45
12555       if (isa<BinaryOperator>(BO->getRHS()->IgnoreImpCasts()) ||
12556           isa<ConditionalOperator>(BO->getRHS()->IgnoreImpCasts())) {
12557         // check if form 45
12558         if (isa<IfStmt>(S2))
12559           return checkForm45(CS, ErrorInfo);
12560         // { cond-expr-stmt; v = x; }
12561         CondExprStmt = S1;
12562         UpdateStmt = S2;
12563       } else {
12564         IsPostfixUpdate = true;
12565         UpdateStmt = S1;
12566         if (isa<IfStmt>(S2)) {
12567           // { v = x; cond-update-stmt }
12568           CondUpdateStmt = S2;
12569         } else {
12570           // { v = x; cond-expr-stmt }
12571           CondExprStmt = S2;
12572         }
12573       }
12574     } else {
12575       // { cond-update-stmt v = x; }
12576       UpdateStmt = S2;
12577       CondUpdateStmt = S1;
12578     }
12579 
12580     auto CheckCondUpdateStmt = [this, &ErrorInfo](Stmt *CUS) {
12581       auto *IS = dyn_cast<IfStmt>(CUS);
12582       if (!IS) {
12583         ErrorInfo.Error = ErrorTy::NotIfStmt;
12584         ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CUS->getBeginLoc();
12585         ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CUS->getSourceRange();
12586         return false;
12587       }
12588 
12589       return checkCondUpdateStmt(IS, ErrorInfo);
12590     };
12591 
12592     // CheckUpdateStmt has to be called *after* CheckCondUpdateStmt.
12593     auto CheckUpdateStmt = [this, &ErrorInfo](Stmt *US) {
12594       auto *BO = dyn_cast<BinaryOperator>(US);
12595       if (!BO) {
12596         ErrorInfo.Error = ErrorTy::NotAnAssignment;
12597         ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = US->getBeginLoc();
12598         ErrorInfo.ErrorRange = ErrorInfo.NoteRange = US->getSourceRange();
12599         return false;
12600       }
12601       if (BO->getOpcode() != BO_Assign) {
12602         ErrorInfo.Error = ErrorTy::NotAnAssignment;
12603         ErrorInfo.ErrorLoc = BO->getExprLoc();
12604         ErrorInfo.NoteLoc = BO->getOperatorLoc();
12605         ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
12606         return false;
12607       }
12608       if (!checkIfTwoExprsAreSame(ContextRef, this->X, BO->getRHS())) {
12609         ErrorInfo.Error = ErrorTy::InvalidAssignment;
12610         ErrorInfo.ErrorLoc = BO->getRHS()->getExprLoc();
12611         ErrorInfo.NoteLoc = this->X->getExprLoc();
12612         ErrorInfo.ErrorRange = BO->getRHS()->getSourceRange();
12613         ErrorInfo.NoteRange = this->X->getSourceRange();
12614         return false;
12615       }
12616 
12617       this->V = BO->getLHS();
12618 
12619       return true;
12620     };
12621 
12622     if (CondUpdateStmt && !CheckCondUpdateStmt(CondUpdateStmt))
12623       return false;
12624     if (CondExprStmt && !checkCondExprStmt(CondExprStmt, ErrorInfo))
12625       return false;
12626     if (!CheckUpdateStmt(UpdateStmt))
12627       return false;
12628   } else {
12629     ErrorInfo.Error = ErrorTy::MoreThanTwoStmts;
12630     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
12631     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
12632     return false;
12633   }
12634 
12635   return checkType(ErrorInfo);
12636 }
12637 } // namespace
12638 
12639 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
12640                                             Stmt *AStmt,
12641                                             SourceLocation StartLoc,
12642                                             SourceLocation EndLoc) {
12643   // Register location of the first atomic directive.
12644   DSAStack->addAtomicDirectiveLoc(StartLoc);
12645   if (!AStmt)
12646     return StmtError();
12647 
12648   // 1.2.2 OpenMP Language Terminology
12649   // Structured block - An executable statement with a single entry at the
12650   // top and a single exit at the bottom.
12651   // The point of exit cannot be a branch out of the structured block.
12652   // longjmp() and throw() must not violate the entry/exit criteria.
12653   OpenMPClauseKind AtomicKind = OMPC_unknown;
12654   SourceLocation AtomicKindLoc;
12655   OpenMPClauseKind MemOrderKind = OMPC_unknown;
12656   SourceLocation MemOrderLoc;
12657   bool MutexClauseEncountered = false;
12658   llvm::SmallSet<OpenMPClauseKind, 2> EncounteredAtomicKinds;
12659   for (const OMPClause *C : Clauses) {
12660     switch (C->getClauseKind()) {
12661     case OMPC_read:
12662     case OMPC_write:
12663     case OMPC_update:
12664       MutexClauseEncountered = true;
12665       [[fallthrough]];
12666     case OMPC_capture:
12667     case OMPC_compare: {
12668       if (AtomicKind != OMPC_unknown && MutexClauseEncountered) {
12669         Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
12670             << SourceRange(C->getBeginLoc(), C->getEndLoc());
12671         Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
12672             << getOpenMPClauseName(AtomicKind);
12673       } else {
12674         AtomicKind = C->getClauseKind();
12675         AtomicKindLoc = C->getBeginLoc();
12676         if (!EncounteredAtomicKinds.insert(C->getClauseKind()).second) {
12677           Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
12678               << SourceRange(C->getBeginLoc(), C->getEndLoc());
12679           Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
12680               << getOpenMPClauseName(AtomicKind);
12681         }
12682       }
12683       break;
12684     }
12685     case OMPC_fail: {
12686       if (AtomicKind != OMPC_compare) {
12687         Diag(C->getBeginLoc(), diag::err_omp_atomic_fail_no_compare)
12688             << SourceRange(C->getBeginLoc(), C->getEndLoc());
12689         return StmtError();
12690       }
12691       break;
12692     }
12693     case OMPC_seq_cst:
12694     case OMPC_acq_rel:
12695     case OMPC_acquire:
12696     case OMPC_release:
12697     case OMPC_relaxed: {
12698       if (MemOrderKind != OMPC_unknown) {
12699         Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
12700             << getOpenMPDirectiveName(OMPD_atomic) << 0
12701             << SourceRange(C->getBeginLoc(), C->getEndLoc());
12702         Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
12703             << getOpenMPClauseName(MemOrderKind);
12704       } else {
12705         MemOrderKind = C->getClauseKind();
12706         MemOrderLoc = C->getBeginLoc();
12707       }
12708       break;
12709     }
12710     // The following clauses are allowed, but we don't need to do anything here.
12711     case OMPC_hint:
12712       break;
12713     default:
12714       llvm_unreachable("unknown clause is encountered");
12715     }
12716   }
12717   bool IsCompareCapture = false;
12718   if (EncounteredAtomicKinds.contains(OMPC_compare) &&
12719       EncounteredAtomicKinds.contains(OMPC_capture)) {
12720     IsCompareCapture = true;
12721     AtomicKind = OMPC_compare;
12722   }
12723   // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions
12724   // If atomic-clause is read then memory-order-clause must not be acq_rel or
12725   // release.
12726   // If atomic-clause is write then memory-order-clause must not be acq_rel or
12727   // acquire.
12728   // If atomic-clause is update or not present then memory-order-clause must not
12729   // be acq_rel or acquire.
12730   if ((AtomicKind == OMPC_read &&
12731        (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) ||
12732       ((AtomicKind == OMPC_write || AtomicKind == OMPC_update ||
12733         AtomicKind == OMPC_unknown) &&
12734        (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) {
12735     SourceLocation Loc = AtomicKindLoc;
12736     if (AtomicKind == OMPC_unknown)
12737       Loc = StartLoc;
12738     Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
12739         << getOpenMPClauseName(AtomicKind)
12740         << (AtomicKind == OMPC_unknown ? 1 : 0)
12741         << getOpenMPClauseName(MemOrderKind);
12742     Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
12743         << getOpenMPClauseName(MemOrderKind);
12744   }
12745 
12746   Stmt *Body = AStmt;
12747   if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
12748     Body = EWC->getSubExpr();
12749 
12750   Expr *X = nullptr;
12751   Expr *V = nullptr;
12752   Expr *E = nullptr;
12753   Expr *UE = nullptr;
12754   Expr *D = nullptr;
12755   Expr *CE = nullptr;
12756   Expr *R = nullptr;
12757   bool IsXLHSInRHSPart = false;
12758   bool IsPostfixUpdate = false;
12759   bool IsFailOnly = false;
12760   // OpenMP [2.12.6, atomic Construct]
12761   // In the next expressions:
12762   // * x and v (as applicable) are both l-value expressions with scalar type.
12763   // * During the execution of an atomic region, multiple syntactic
12764   // occurrences of x must designate the same storage location.
12765   // * Neither of v and expr (as applicable) may access the storage location
12766   // designated by x.
12767   // * Neither of x and expr (as applicable) may access the storage location
12768   // designated by v.
12769   // * expr is an expression with scalar type.
12770   // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
12771   // * binop, binop=, ++, and -- are not overloaded operators.
12772   // * The expression x binop expr must be numerically equivalent to x binop
12773   // (expr). This requirement is satisfied if the operators in expr have
12774   // precedence greater than binop, or by using parentheses around expr or
12775   // subexpressions of expr.
12776   // * The expression expr binop x must be numerically equivalent to (expr)
12777   // binop x. This requirement is satisfied if the operators in expr have
12778   // precedence equal to or greater than binop, or by using parentheses around
12779   // expr or subexpressions of expr.
12780   // * For forms that allow multiple occurrences of x, the number of times
12781   // that x is evaluated is unspecified.
12782   if (AtomicKind == OMPC_read) {
12783     enum {
12784       NotAnExpression,
12785       NotAnAssignmentOp,
12786       NotAScalarType,
12787       NotAnLValue,
12788       NoError
12789     } ErrorFound = NoError;
12790     SourceLocation ErrorLoc, NoteLoc;
12791     SourceRange ErrorRange, NoteRange;
12792     // If clause is read:
12793     //  v = x;
12794     if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12795       const auto *AtomicBinOp =
12796           dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12797       if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
12798         X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
12799         V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
12800         if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
12801             (V->isInstantiationDependent() || V->getType()->isScalarType())) {
12802           if (!X->isLValue() || !V->isLValue()) {
12803             const Expr *NotLValueExpr = X->isLValue() ? V : X;
12804             ErrorFound = NotAnLValue;
12805             ErrorLoc = AtomicBinOp->getExprLoc();
12806             ErrorRange = AtomicBinOp->getSourceRange();
12807             NoteLoc = NotLValueExpr->getExprLoc();
12808             NoteRange = NotLValueExpr->getSourceRange();
12809           }
12810         } else if (!X->isInstantiationDependent() ||
12811                    !V->isInstantiationDependent()) {
12812           const Expr *NotScalarExpr =
12813               (X->isInstantiationDependent() || X->getType()->isScalarType())
12814                   ? V
12815                   : X;
12816           ErrorFound = NotAScalarType;
12817           ErrorLoc = AtomicBinOp->getExprLoc();
12818           ErrorRange = AtomicBinOp->getSourceRange();
12819           NoteLoc = NotScalarExpr->getExprLoc();
12820           NoteRange = NotScalarExpr->getSourceRange();
12821         }
12822       } else if (!AtomicBody->isInstantiationDependent()) {
12823         ErrorFound = NotAnAssignmentOp;
12824         ErrorLoc = AtomicBody->getExprLoc();
12825         ErrorRange = AtomicBody->getSourceRange();
12826         NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
12827                               : AtomicBody->getExprLoc();
12828         NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
12829                                 : AtomicBody->getSourceRange();
12830       }
12831     } else {
12832       ErrorFound = NotAnExpression;
12833       NoteLoc = ErrorLoc = Body->getBeginLoc();
12834       NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
12835     }
12836     if (ErrorFound != NoError) {
12837       Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
12838           << ErrorRange;
12839       Diag(NoteLoc, diag::note_omp_atomic_read_write)
12840           << ErrorFound << NoteRange;
12841       return StmtError();
12842     }
12843     if (CurContext->isDependentContext())
12844       V = X = nullptr;
12845   } else if (AtomicKind == OMPC_write) {
12846     enum {
12847       NotAnExpression,
12848       NotAnAssignmentOp,
12849       NotAScalarType,
12850       NotAnLValue,
12851       NoError
12852     } ErrorFound = NoError;
12853     SourceLocation ErrorLoc, NoteLoc;
12854     SourceRange ErrorRange, NoteRange;
12855     // If clause is write:
12856     //  x = expr;
12857     if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12858       const auto *AtomicBinOp =
12859           dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12860       if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
12861         X = AtomicBinOp->getLHS();
12862         E = AtomicBinOp->getRHS();
12863         if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
12864             (E->isInstantiationDependent() || E->getType()->isScalarType())) {
12865           if (!X->isLValue()) {
12866             ErrorFound = NotAnLValue;
12867             ErrorLoc = AtomicBinOp->getExprLoc();
12868             ErrorRange = AtomicBinOp->getSourceRange();
12869             NoteLoc = X->getExprLoc();
12870             NoteRange = X->getSourceRange();
12871           }
12872         } else if (!X->isInstantiationDependent() ||
12873                    !E->isInstantiationDependent()) {
12874           const Expr *NotScalarExpr =
12875               (X->isInstantiationDependent() || X->getType()->isScalarType())
12876                   ? E
12877                   : X;
12878           ErrorFound = NotAScalarType;
12879           ErrorLoc = AtomicBinOp->getExprLoc();
12880           ErrorRange = AtomicBinOp->getSourceRange();
12881           NoteLoc = NotScalarExpr->getExprLoc();
12882           NoteRange = NotScalarExpr->getSourceRange();
12883         }
12884       } else if (!AtomicBody->isInstantiationDependent()) {
12885         ErrorFound = NotAnAssignmentOp;
12886         ErrorLoc = AtomicBody->getExprLoc();
12887         ErrorRange = AtomicBody->getSourceRange();
12888         NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
12889                               : AtomicBody->getExprLoc();
12890         NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
12891                                 : AtomicBody->getSourceRange();
12892       }
12893     } else {
12894       ErrorFound = NotAnExpression;
12895       NoteLoc = ErrorLoc = Body->getBeginLoc();
12896       NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
12897     }
12898     if (ErrorFound != NoError) {
12899       Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
12900           << ErrorRange;
12901       Diag(NoteLoc, diag::note_omp_atomic_read_write)
12902           << ErrorFound << NoteRange;
12903       return StmtError();
12904     }
12905     if (CurContext->isDependentContext())
12906       E = X = nullptr;
12907   } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
12908     // If clause is update:
12909     //  x++;
12910     //  x--;
12911     //  ++x;
12912     //  --x;
12913     //  x binop= expr;
12914     //  x = x binop expr;
12915     //  x = expr binop x;
12916     OpenMPAtomicUpdateChecker Checker(*this);
12917     if (Checker.checkStatement(
12918             Body,
12919             (AtomicKind == OMPC_update)
12920                 ? diag::err_omp_atomic_update_not_expression_statement
12921                 : diag::err_omp_atomic_not_expression_statement,
12922             diag::note_omp_atomic_update))
12923       return StmtError();
12924     if (!CurContext->isDependentContext()) {
12925       E = Checker.getExpr();
12926       X = Checker.getX();
12927       UE = Checker.getUpdateExpr();
12928       IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12929     }
12930   } else if (AtomicKind == OMPC_capture) {
12931     enum {
12932       NotAnAssignmentOp,
12933       NotACompoundStatement,
12934       NotTwoSubstatements,
12935       NotASpecificExpression,
12936       NoError
12937     } ErrorFound = NoError;
12938     SourceLocation ErrorLoc, NoteLoc;
12939     SourceRange ErrorRange, NoteRange;
12940     if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12941       // If clause is a capture:
12942       //  v = x++;
12943       //  v = x--;
12944       //  v = ++x;
12945       //  v = --x;
12946       //  v = x binop= expr;
12947       //  v = x = x binop expr;
12948       //  v = x = expr binop x;
12949       const auto *AtomicBinOp =
12950           dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12951       if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
12952         V = AtomicBinOp->getLHS();
12953         Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
12954         OpenMPAtomicUpdateChecker Checker(*this);
12955         if (Checker.checkStatement(
12956                 Body, diag::err_omp_atomic_capture_not_expression_statement,
12957                 diag::note_omp_atomic_update))
12958           return StmtError();
12959         E = Checker.getExpr();
12960         X = Checker.getX();
12961         UE = Checker.getUpdateExpr();
12962         IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12963         IsPostfixUpdate = Checker.isPostfixUpdate();
12964       } else if (!AtomicBody->isInstantiationDependent()) {
12965         ErrorLoc = AtomicBody->getExprLoc();
12966         ErrorRange = AtomicBody->getSourceRange();
12967         NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
12968                               : AtomicBody->getExprLoc();
12969         NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
12970                                 : AtomicBody->getSourceRange();
12971         ErrorFound = NotAnAssignmentOp;
12972       }
12973       if (ErrorFound != NoError) {
12974         Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
12975             << ErrorRange;
12976         Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
12977         return StmtError();
12978       }
12979       if (CurContext->isDependentContext())
12980         UE = V = E = X = nullptr;
12981     } else {
12982       // If clause is a capture:
12983       //  { v = x; x = expr; }
12984       //  { v = x; x++; }
12985       //  { v = x; x--; }
12986       //  { v = x; ++x; }
12987       //  { v = x; --x; }
12988       //  { v = x; x binop= expr; }
12989       //  { v = x; x = x binop expr; }
12990       //  { v = x; x = expr binop x; }
12991       //  { x++; v = x; }
12992       //  { x--; v = x; }
12993       //  { ++x; v = x; }
12994       //  { --x; v = x; }
12995       //  { x binop= expr; v = x; }
12996       //  { x = x binop expr; v = x; }
12997       //  { x = expr binop x; v = x; }
12998       if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
12999         // Check that this is { expr1; expr2; }
13000         if (CS->size() == 2) {
13001           Stmt *First = CS->body_front();
13002           Stmt *Second = CS->body_back();
13003           if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
13004             First = EWC->getSubExpr()->IgnoreParenImpCasts();
13005           if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
13006             Second = EWC->getSubExpr()->IgnoreParenImpCasts();
13007           // Need to find what subexpression is 'v' and what is 'x'.
13008           OpenMPAtomicUpdateChecker Checker(*this);
13009           bool IsUpdateExprFound = !Checker.checkStatement(Second);
13010           BinaryOperator *BinOp = nullptr;
13011           if (IsUpdateExprFound) {
13012             BinOp = dyn_cast<BinaryOperator>(First);
13013             IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
13014           }
13015           if (IsUpdateExprFound && !CurContext->isDependentContext()) {
13016             //  { v = x; x++; }
13017             //  { v = x; x--; }
13018             //  { v = x; ++x; }
13019             //  { v = x; --x; }
13020             //  { v = x; x binop= expr; }
13021             //  { v = x; x = x binop expr; }
13022             //  { v = x; x = expr binop x; }
13023             // Check that the first expression has form v = x.
13024             Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
13025             llvm::FoldingSetNodeID XId, PossibleXId;
13026             Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
13027             PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
13028             IsUpdateExprFound = XId == PossibleXId;
13029             if (IsUpdateExprFound) {
13030               V = BinOp->getLHS();
13031               X = Checker.getX();
13032               E = Checker.getExpr();
13033               UE = Checker.getUpdateExpr();
13034               IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
13035               IsPostfixUpdate = true;
13036             }
13037           }
13038           if (!IsUpdateExprFound) {
13039             IsUpdateExprFound = !Checker.checkStatement(First);
13040             BinOp = nullptr;
13041             if (IsUpdateExprFound) {
13042               BinOp = dyn_cast<BinaryOperator>(Second);
13043               IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
13044             }
13045             if (IsUpdateExprFound && !CurContext->isDependentContext()) {
13046               //  { x++; v = x; }
13047               //  { x--; v = x; }
13048               //  { ++x; v = x; }
13049               //  { --x; v = x; }
13050               //  { x binop= expr; v = x; }
13051               //  { x = x binop expr; v = x; }
13052               //  { x = expr binop x; v = x; }
13053               // Check that the second expression has form v = x.
13054               Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
13055               llvm::FoldingSetNodeID XId, PossibleXId;
13056               Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
13057               PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
13058               IsUpdateExprFound = XId == PossibleXId;
13059               if (IsUpdateExprFound) {
13060                 V = BinOp->getLHS();
13061                 X = Checker.getX();
13062                 E = Checker.getExpr();
13063                 UE = Checker.getUpdateExpr();
13064                 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
13065                 IsPostfixUpdate = false;
13066               }
13067             }
13068           }
13069           if (!IsUpdateExprFound) {
13070             //  { v = x; x = expr; }
13071             auto *FirstExpr = dyn_cast<Expr>(First);
13072             auto *SecondExpr = dyn_cast<Expr>(Second);
13073             if (!FirstExpr || !SecondExpr ||
13074                 !(FirstExpr->isInstantiationDependent() ||
13075                   SecondExpr->isInstantiationDependent())) {
13076               auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
13077               if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
13078                 ErrorFound = NotAnAssignmentOp;
13079                 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
13080                                                 : First->getBeginLoc();
13081                 NoteRange = ErrorRange = FirstBinOp
13082                                              ? FirstBinOp->getSourceRange()
13083                                              : SourceRange(ErrorLoc, ErrorLoc);
13084               } else {
13085                 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
13086                 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
13087                   ErrorFound = NotAnAssignmentOp;
13088                   NoteLoc = ErrorLoc = SecondBinOp
13089                                            ? SecondBinOp->getOperatorLoc()
13090                                            : Second->getBeginLoc();
13091                   NoteRange = ErrorRange =
13092                       SecondBinOp ? SecondBinOp->getSourceRange()
13093                                   : SourceRange(ErrorLoc, ErrorLoc);
13094                 } else {
13095                   Expr *PossibleXRHSInFirst =
13096                       FirstBinOp->getRHS()->IgnoreParenImpCasts();
13097                   Expr *PossibleXLHSInSecond =
13098                       SecondBinOp->getLHS()->IgnoreParenImpCasts();
13099                   llvm::FoldingSetNodeID X1Id, X2Id;
13100                   PossibleXRHSInFirst->Profile(X1Id, Context,
13101                                                /*Canonical=*/true);
13102                   PossibleXLHSInSecond->Profile(X2Id, Context,
13103                                                 /*Canonical=*/true);
13104                   IsUpdateExprFound = X1Id == X2Id;
13105                   if (IsUpdateExprFound) {
13106                     V = FirstBinOp->getLHS();
13107                     X = SecondBinOp->getLHS();
13108                     E = SecondBinOp->getRHS();
13109                     UE = nullptr;
13110                     IsXLHSInRHSPart = false;
13111                     IsPostfixUpdate = true;
13112                   } else {
13113                     ErrorFound = NotASpecificExpression;
13114                     ErrorLoc = FirstBinOp->getExprLoc();
13115                     ErrorRange = FirstBinOp->getSourceRange();
13116                     NoteLoc = SecondBinOp->getLHS()->getExprLoc();
13117                     NoteRange = SecondBinOp->getRHS()->getSourceRange();
13118                   }
13119                 }
13120               }
13121             }
13122           }
13123         } else {
13124           NoteLoc = ErrorLoc = Body->getBeginLoc();
13125           NoteRange = ErrorRange =
13126               SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
13127           ErrorFound = NotTwoSubstatements;
13128         }
13129       } else {
13130         NoteLoc = ErrorLoc = Body->getBeginLoc();
13131         NoteRange = ErrorRange =
13132             SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
13133         ErrorFound = NotACompoundStatement;
13134       }
13135     }
13136     if (ErrorFound != NoError) {
13137       Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
13138           << ErrorRange;
13139       Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
13140       return StmtError();
13141     }
13142     if (CurContext->isDependentContext())
13143       UE = V = E = X = nullptr;
13144   } else if (AtomicKind == OMPC_compare) {
13145     if (IsCompareCapture) {
13146       OpenMPAtomicCompareCaptureChecker::ErrorInfoTy ErrorInfo;
13147       OpenMPAtomicCompareCaptureChecker Checker(*this);
13148       if (!Checker.checkStmt(Body, ErrorInfo)) {
13149         Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare_capture)
13150             << ErrorInfo.ErrorRange;
13151         Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare)
13152             << ErrorInfo.Error << ErrorInfo.NoteRange;
13153         return StmtError();
13154       }
13155       X = Checker.getX();
13156       E = Checker.getE();
13157       D = Checker.getD();
13158       CE = Checker.getCond();
13159       V = Checker.getV();
13160       R = Checker.getR();
13161       // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'.
13162       IsXLHSInRHSPart = Checker.isXBinopExpr();
13163       IsFailOnly = Checker.isFailOnly();
13164       IsPostfixUpdate = Checker.isPostfixUpdate();
13165     } else {
13166       OpenMPAtomicCompareChecker::ErrorInfoTy ErrorInfo;
13167       OpenMPAtomicCompareChecker Checker(*this);
13168       if (!Checker.checkStmt(Body, ErrorInfo)) {
13169         Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare)
13170             << ErrorInfo.ErrorRange;
13171         Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare)
13172           << ErrorInfo.Error << ErrorInfo.NoteRange;
13173         return StmtError();
13174       }
13175       X = Checker.getX();
13176       E = Checker.getE();
13177       D = Checker.getD();
13178       CE = Checker.getCond();
13179       // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'.
13180       IsXLHSInRHSPart = Checker.isXBinopExpr();
13181     }
13182   }
13183 
13184   setFunctionHasBranchProtectedScope();
13185 
13186   return OMPAtomicDirective::Create(
13187       Context, StartLoc, EndLoc, Clauses, AStmt,
13188       {X, V, R, E, UE, D, CE, IsXLHSInRHSPart, IsPostfixUpdate, IsFailOnly});
13189 }
13190 
13191 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
13192                                             Stmt *AStmt,
13193                                             SourceLocation StartLoc,
13194                                             SourceLocation EndLoc) {
13195   if (!AStmt)
13196     return StmtError();
13197 
13198   auto *CS = cast<CapturedStmt>(AStmt);
13199   // 1.2.2 OpenMP Language Terminology
13200   // Structured block - An executable statement with a single entry at the
13201   // top and a single exit at the bottom.
13202   // The point of exit cannot be a branch out of the structured block.
13203   // longjmp() and throw() must not violate the entry/exit criteria.
13204   CS->getCapturedDecl()->setNothrow();
13205   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
13206        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13207     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13208     // 1.2.2 OpenMP Language Terminology
13209     // Structured block - An executable statement with a single entry at the
13210     // top and a single exit at the bottom.
13211     // The point of exit cannot be a branch out of the structured block.
13212     // longjmp() and throw() must not violate the entry/exit criteria.
13213     CS->getCapturedDecl()->setNothrow();
13214   }
13215 
13216   // OpenMP [2.16, Nesting of Regions]
13217   // If specified, a teams construct must be contained within a target
13218   // construct. That target construct must contain no statements or directives
13219   // outside of the teams construct.
13220   if (DSAStack->hasInnerTeamsRegion()) {
13221     const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
13222     bool OMPTeamsFound = true;
13223     if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
13224       auto I = CS->body_begin();
13225       while (I != CS->body_end()) {
13226         const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
13227         if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) ||
13228             OMPTeamsFound) {
13229 
13230           OMPTeamsFound = false;
13231           break;
13232         }
13233         ++I;
13234       }
13235       assert(I != CS->body_end() && "Not found statement");
13236       S = *I;
13237     } else {
13238       const auto *OED = dyn_cast<OMPExecutableDirective>(S);
13239       OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
13240     }
13241     if (!OMPTeamsFound) {
13242       Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
13243       Diag(DSAStack->getInnerTeamsRegionLoc(),
13244            diag::note_omp_nested_teams_construct_here);
13245       Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
13246           << isa<OMPExecutableDirective>(S);
13247       return StmtError();
13248     }
13249   }
13250 
13251   setFunctionHasBranchProtectedScope();
13252 
13253   return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
13254 }
13255 
13256 StmtResult
13257 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
13258                                          Stmt *AStmt, SourceLocation StartLoc,
13259                                          SourceLocation EndLoc) {
13260   if (!AStmt)
13261     return StmtError();
13262 
13263   auto *CS = cast<CapturedStmt>(AStmt);
13264   // 1.2.2 OpenMP Language Terminology
13265   // Structured block - An executable statement with a single entry at the
13266   // top and a single exit at the bottom.
13267   // The point of exit cannot be a branch out of the structured block.
13268   // longjmp() and throw() must not violate the entry/exit criteria.
13269   CS->getCapturedDecl()->setNothrow();
13270   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
13271        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13272     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13273     // 1.2.2 OpenMP Language Terminology
13274     // Structured block - An executable statement with a single entry at the
13275     // top and a single exit at the bottom.
13276     // The point of exit cannot be a branch out of the structured block.
13277     // longjmp() and throw() must not violate the entry/exit criteria.
13278     CS->getCapturedDecl()->setNothrow();
13279   }
13280 
13281   setFunctionHasBranchProtectedScope();
13282 
13283   return OMPTargetParallelDirective::Create(
13284       Context, StartLoc, EndLoc, Clauses, AStmt,
13285       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
13286 }
13287 
13288 StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
13289     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13290     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13291   if (!AStmt)
13292     return StmtError();
13293 
13294   auto *CS = cast<CapturedStmt>(AStmt);
13295   // 1.2.2 OpenMP Language Terminology
13296   // Structured block - An executable statement with a single entry at the
13297   // top and a single exit at the bottom.
13298   // The point of exit cannot be a branch out of the structured block.
13299   // longjmp() and throw() must not violate the entry/exit criteria.
13300   CS->getCapturedDecl()->setNothrow();
13301   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
13302        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13303     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13304     // 1.2.2 OpenMP Language Terminology
13305     // Structured block - An executable statement with a single entry at the
13306     // top and a single exit at the bottom.
13307     // The point of exit cannot be a branch out of the structured block.
13308     // longjmp() and throw() must not violate the entry/exit criteria.
13309     CS->getCapturedDecl()->setNothrow();
13310   }
13311 
13312   OMPLoopBasedDirective::HelperExprs B;
13313   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13314   // define the nested loops number.
13315   unsigned NestedLoopCount =
13316       checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
13317                       getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
13318                       VarsWithImplicitDSA, B);
13319   if (NestedLoopCount == 0)
13320     return StmtError();
13321 
13322   assert((CurContext->isDependentContext() || B.builtAll()) &&
13323          "omp target parallel for loop exprs were not built");
13324 
13325   if (!CurContext->isDependentContext()) {
13326     // Finalize the clauses that need pre-built expressions for CodeGen.
13327     for (OMPClause *C : Clauses) {
13328       if (auto *LC = dyn_cast<OMPLinearClause>(C))
13329         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13330                                      B.NumIterations, *this, CurScope,
13331                                      DSAStack))
13332           return StmtError();
13333     }
13334   }
13335 
13336   setFunctionHasBranchProtectedScope();
13337   return OMPTargetParallelForDirective::Create(
13338       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13339       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
13340 }
13341 
13342 /// Check for existence of a map clause in the list of clauses.
13343 static bool hasClauses(ArrayRef<OMPClause *> Clauses,
13344                        const OpenMPClauseKind K) {
13345   return llvm::any_of(
13346       Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
13347 }
13348 
13349 template <typename... Params>
13350 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
13351                        const Params... ClauseTypes) {
13352   return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
13353 }
13354 
13355 /// Check if the variables in the mapping clause are externally visible.
13356 static bool isClauseMappable(ArrayRef<OMPClause *> Clauses) {
13357   for (const OMPClause *C : Clauses) {
13358     if (auto *TC = dyn_cast<OMPToClause>(C))
13359       return llvm::all_of(TC->all_decls(), [](ValueDecl *VD) {
13360         return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
13361                (VD->isExternallyVisible() &&
13362                 VD->getVisibility() != HiddenVisibility);
13363       });
13364     else if (auto *FC = dyn_cast<OMPFromClause>(C))
13365       return llvm::all_of(FC->all_decls(), [](ValueDecl *VD) {
13366         return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() ||
13367                (VD->isExternallyVisible() &&
13368                 VD->getVisibility() != HiddenVisibility);
13369       });
13370   }
13371 
13372   return true;
13373 }
13374 
13375 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
13376                                                 Stmt *AStmt,
13377                                                 SourceLocation StartLoc,
13378                                                 SourceLocation EndLoc) {
13379   if (!AStmt)
13380     return StmtError();
13381 
13382   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13383 
13384   // OpenMP [2.12.2, target data Construct, Restrictions]
13385   // At least one map, use_device_addr or use_device_ptr clause must appear on
13386   // the directive.
13387   if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) &&
13388       (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) {
13389     StringRef Expected;
13390     if (LangOpts.OpenMP < 50)
13391       Expected = "'map' or 'use_device_ptr'";
13392     else
13393       Expected = "'map', 'use_device_ptr', or 'use_device_addr'";
13394     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13395         << Expected << getOpenMPDirectiveName(OMPD_target_data);
13396     return StmtError();
13397   }
13398 
13399   setFunctionHasBranchProtectedScope();
13400 
13401   return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
13402                                         AStmt);
13403 }
13404 
13405 StmtResult
13406 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
13407                                           SourceLocation StartLoc,
13408                                           SourceLocation EndLoc, Stmt *AStmt) {
13409   if (!AStmt)
13410     return StmtError();
13411 
13412   auto *CS = cast<CapturedStmt>(AStmt);
13413   // 1.2.2 OpenMP Language Terminology
13414   // Structured block - An executable statement with a single entry at the
13415   // top and a single exit at the bottom.
13416   // The point of exit cannot be a branch out of the structured block.
13417   // longjmp() and throw() must not violate the entry/exit criteria.
13418   CS->getCapturedDecl()->setNothrow();
13419   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
13420        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13421     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13422     // 1.2.2 OpenMP Language Terminology
13423     // Structured block - An executable statement with a single entry at the
13424     // top and a single exit at the bottom.
13425     // The point of exit cannot be a branch out of the structured block.
13426     // longjmp() and throw() must not violate the entry/exit criteria.
13427     CS->getCapturedDecl()->setNothrow();
13428   }
13429 
13430   // OpenMP [2.10.2, Restrictions, p. 99]
13431   // At least one map clause must appear on the directive.
13432   if (!hasClauses(Clauses, OMPC_map)) {
13433     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13434         << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
13435     return StmtError();
13436   }
13437 
13438   return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
13439                                              AStmt);
13440 }
13441 
13442 StmtResult
13443 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
13444                                          SourceLocation StartLoc,
13445                                          SourceLocation EndLoc, Stmt *AStmt) {
13446   if (!AStmt)
13447     return StmtError();
13448 
13449   auto *CS = cast<CapturedStmt>(AStmt);
13450   // 1.2.2 OpenMP Language Terminology
13451   // Structured block - An executable statement with a single entry at the
13452   // top and a single exit at the bottom.
13453   // The point of exit cannot be a branch out of the structured block.
13454   // longjmp() and throw() must not violate the entry/exit criteria.
13455   CS->getCapturedDecl()->setNothrow();
13456   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
13457        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13458     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13459     // 1.2.2 OpenMP Language Terminology
13460     // Structured block - An executable statement with a single entry at the
13461     // top and a single exit at the bottom.
13462     // The point of exit cannot be a branch out of the structured block.
13463     // longjmp() and throw() must not violate the entry/exit criteria.
13464     CS->getCapturedDecl()->setNothrow();
13465   }
13466 
13467   // OpenMP [2.10.3, Restrictions, p. 102]
13468   // At least one map clause must appear on the directive.
13469   if (!hasClauses(Clauses, OMPC_map)) {
13470     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
13471         << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
13472     return StmtError();
13473   }
13474 
13475   return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
13476                                             AStmt);
13477 }
13478 
13479 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
13480                                                   SourceLocation StartLoc,
13481                                                   SourceLocation EndLoc,
13482                                                   Stmt *AStmt) {
13483   if (!AStmt)
13484     return StmtError();
13485 
13486   auto *CS = cast<CapturedStmt>(AStmt);
13487   // 1.2.2 OpenMP Language Terminology
13488   // Structured block - An executable statement with a single entry at the
13489   // top and a single exit at the bottom.
13490   // The point of exit cannot be a branch out of the structured block.
13491   // longjmp() and throw() must not violate the entry/exit criteria.
13492   CS->getCapturedDecl()->setNothrow();
13493   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
13494        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13495     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13496     // 1.2.2 OpenMP Language Terminology
13497     // Structured block - An executable statement with a single entry at the
13498     // top and a single exit at the bottom.
13499     // The point of exit cannot be a branch out of the structured block.
13500     // longjmp() and throw() must not violate the entry/exit criteria.
13501     CS->getCapturedDecl()->setNothrow();
13502   }
13503 
13504   if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
13505     Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
13506     return StmtError();
13507   }
13508 
13509   if (!isClauseMappable(Clauses)) {
13510     Diag(StartLoc, diag::err_omp_cannot_update_with_internal_linkage);
13511     return StmtError();
13512   }
13513 
13514   return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
13515                                           AStmt);
13516 }
13517 
13518 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
13519                                            Stmt *AStmt, SourceLocation StartLoc,
13520                                            SourceLocation EndLoc) {
13521   if (!AStmt)
13522     return StmtError();
13523 
13524   // Report affected OpenMP target offloading behavior when in HIP lang-mode.
13525   if (getLangOpts().HIP && (DSAStack->getParentDirective() == OMPD_target))
13526     Diag(StartLoc, diag::warn_hip_omp_target_directives);
13527 
13528   auto *CS = cast<CapturedStmt>(AStmt);
13529   // 1.2.2 OpenMP Language Terminology
13530   // Structured block - An executable statement with a single entry at the
13531   // top and a single exit at the bottom.
13532   // The point of exit cannot be a branch out of the structured block.
13533   // longjmp() and throw() must not violate the entry/exit criteria.
13534   CS->getCapturedDecl()->setNothrow();
13535 
13536   setFunctionHasBranchProtectedScope();
13537 
13538   DSAStack->setParentTeamsRegionLoc(StartLoc);
13539 
13540   return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
13541 }
13542 
13543 StmtResult
13544 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
13545                                             SourceLocation EndLoc,
13546                                             OpenMPDirectiveKind CancelRegion) {
13547   if (DSAStack->isParentNowaitRegion()) {
13548     Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
13549     return StmtError();
13550   }
13551   if (DSAStack->isParentOrderedRegion()) {
13552     Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
13553     return StmtError();
13554   }
13555   return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
13556                                                CancelRegion);
13557 }
13558 
13559 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
13560                                             SourceLocation StartLoc,
13561                                             SourceLocation EndLoc,
13562                                             OpenMPDirectiveKind CancelRegion) {
13563   if (DSAStack->isParentNowaitRegion()) {
13564     Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
13565     return StmtError();
13566   }
13567   if (DSAStack->isParentOrderedRegion()) {
13568     Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
13569     return StmtError();
13570   }
13571   DSAStack->setParentCancelRegion(/*Cancel=*/true);
13572   return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
13573                                     CancelRegion);
13574 }
13575 
13576 static bool checkReductionClauseWithNogroup(Sema &S,
13577                                             ArrayRef<OMPClause *> Clauses) {
13578   const OMPClause *ReductionClause = nullptr;
13579   const OMPClause *NogroupClause = nullptr;
13580   for (const OMPClause *C : Clauses) {
13581     if (C->getClauseKind() == OMPC_reduction) {
13582       ReductionClause = C;
13583       if (NogroupClause)
13584         break;
13585       continue;
13586     }
13587     if (C->getClauseKind() == OMPC_nogroup) {
13588       NogroupClause = C;
13589       if (ReductionClause)
13590         break;
13591       continue;
13592     }
13593   }
13594   if (ReductionClause && NogroupClause) {
13595     S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
13596         << SourceRange(NogroupClause->getBeginLoc(),
13597                        NogroupClause->getEndLoc());
13598     return true;
13599   }
13600   return false;
13601 }
13602 
13603 StmtResult Sema::ActOnOpenMPTaskLoopDirective(
13604     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13605     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13606   if (!AStmt)
13607     return StmtError();
13608 
13609   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13610   OMPLoopBasedDirective::HelperExprs B;
13611   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13612   // define the nested loops number.
13613   unsigned NestedLoopCount =
13614       checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
13615                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13616                       VarsWithImplicitDSA, B);
13617   if (NestedLoopCount == 0)
13618     return StmtError();
13619 
13620   assert((CurContext->isDependentContext() || B.builtAll()) &&
13621          "omp for loop exprs were not built");
13622 
13623   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13624   // The grainsize clause and num_tasks clause are mutually exclusive and may
13625   // not appear on the same taskloop directive.
13626   if (checkMutuallyExclusiveClauses(*this, Clauses,
13627                                     {OMPC_grainsize, OMPC_num_tasks}))
13628     return StmtError();
13629   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13630   // If a reduction clause is present on the taskloop directive, the nogroup
13631   // clause must not be specified.
13632   if (checkReductionClauseWithNogroup(*this, Clauses))
13633     return StmtError();
13634 
13635   setFunctionHasBranchProtectedScope();
13636   return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
13637                                       NestedLoopCount, Clauses, AStmt, B,
13638                                       DSAStack->isCancelRegion());
13639 }
13640 
13641 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
13642     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13643     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13644   if (!AStmt)
13645     return StmtError();
13646 
13647   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13648   OMPLoopBasedDirective::HelperExprs B;
13649   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13650   // define the nested loops number.
13651   unsigned NestedLoopCount =
13652       checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
13653                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13654                       VarsWithImplicitDSA, B);
13655   if (NestedLoopCount == 0)
13656     return StmtError();
13657 
13658   assert((CurContext->isDependentContext() || B.builtAll()) &&
13659          "omp for loop exprs were not built");
13660 
13661   if (!CurContext->isDependentContext()) {
13662     // Finalize the clauses that need pre-built expressions for CodeGen.
13663     for (OMPClause *C : Clauses) {
13664       if (auto *LC = dyn_cast<OMPLinearClause>(C))
13665         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13666                                      B.NumIterations, *this, CurScope,
13667                                      DSAStack))
13668           return StmtError();
13669     }
13670   }
13671 
13672   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13673   // The grainsize clause and num_tasks clause are mutually exclusive and may
13674   // not appear on the same taskloop directive.
13675   if (checkMutuallyExclusiveClauses(*this, Clauses,
13676                                     {OMPC_grainsize, OMPC_num_tasks}))
13677     return StmtError();
13678   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13679   // If a reduction clause is present on the taskloop directive, the nogroup
13680   // clause must not be specified.
13681   if (checkReductionClauseWithNogroup(*this, Clauses))
13682     return StmtError();
13683   if (checkSimdlenSafelenSpecified(*this, Clauses))
13684     return StmtError();
13685 
13686   setFunctionHasBranchProtectedScope();
13687   return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
13688                                           NestedLoopCount, Clauses, AStmt, B);
13689 }
13690 
13691 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective(
13692     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13693     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13694   if (!AStmt)
13695     return StmtError();
13696 
13697   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13698   OMPLoopBasedDirective::HelperExprs B;
13699   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13700   // define the nested loops number.
13701   unsigned NestedLoopCount =
13702       checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses),
13703                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13704                       VarsWithImplicitDSA, B);
13705   if (NestedLoopCount == 0)
13706     return StmtError();
13707 
13708   assert((CurContext->isDependentContext() || B.builtAll()) &&
13709          "omp for loop exprs were not built");
13710 
13711   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13712   // The grainsize clause and num_tasks clause are mutually exclusive and may
13713   // not appear on the same taskloop directive.
13714   if (checkMutuallyExclusiveClauses(*this, Clauses,
13715                                     {OMPC_grainsize, OMPC_num_tasks}))
13716     return StmtError();
13717   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13718   // If a reduction clause is present on the taskloop directive, the nogroup
13719   // clause must not be specified.
13720   if (checkReductionClauseWithNogroup(*this, Clauses))
13721     return StmtError();
13722 
13723   setFunctionHasBranchProtectedScope();
13724   return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc,
13725                                             NestedLoopCount, Clauses, AStmt, B,
13726                                             DSAStack->isCancelRegion());
13727 }
13728 
13729 StmtResult Sema::ActOnOpenMPMaskedTaskLoopDirective(
13730     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13731     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13732   if (!AStmt)
13733     return StmtError();
13734 
13735   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13736   OMPLoopBasedDirective::HelperExprs B;
13737   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13738   // define the nested loops number.
13739   unsigned NestedLoopCount =
13740       checkOpenMPLoop(OMPD_masked_taskloop, getCollapseNumberExpr(Clauses),
13741                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13742                       VarsWithImplicitDSA, B);
13743   if (NestedLoopCount == 0)
13744     return StmtError();
13745 
13746   assert((CurContext->isDependentContext() || B.builtAll()) &&
13747          "omp for loop exprs were not built");
13748 
13749   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13750   // The grainsize clause and num_tasks clause are mutually exclusive and may
13751   // not appear on the same taskloop directive.
13752   if (checkMutuallyExclusiveClauses(*this, Clauses,
13753                                     {OMPC_grainsize, OMPC_num_tasks}))
13754     return StmtError();
13755   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13756   // If a reduction clause is present on the taskloop directive, the nogroup
13757   // clause must not be specified.
13758   if (checkReductionClauseWithNogroup(*this, Clauses))
13759     return StmtError();
13760 
13761   setFunctionHasBranchProtectedScope();
13762   return OMPMaskedTaskLoopDirective::Create(Context, StartLoc, EndLoc,
13763                                             NestedLoopCount, Clauses, AStmt, B,
13764                                             DSAStack->isCancelRegion());
13765 }
13766 
13767 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective(
13768     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13769     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13770   if (!AStmt)
13771     return StmtError();
13772 
13773   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13774   OMPLoopBasedDirective::HelperExprs B;
13775   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13776   // define the nested loops number.
13777   unsigned NestedLoopCount =
13778       checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses),
13779                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13780                       VarsWithImplicitDSA, B);
13781   if (NestedLoopCount == 0)
13782     return StmtError();
13783 
13784   assert((CurContext->isDependentContext() || B.builtAll()) &&
13785          "omp for loop exprs were not built");
13786 
13787   if (!CurContext->isDependentContext()) {
13788     // Finalize the clauses that need pre-built expressions for CodeGen.
13789     for (OMPClause *C : Clauses) {
13790       if (auto *LC = dyn_cast<OMPLinearClause>(C))
13791         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13792                                      B.NumIterations, *this, CurScope,
13793                                      DSAStack))
13794           return StmtError();
13795     }
13796   }
13797 
13798   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13799   // The grainsize clause and num_tasks clause are mutually exclusive and may
13800   // not appear on the same taskloop directive.
13801   if (checkMutuallyExclusiveClauses(*this, Clauses,
13802                                     {OMPC_grainsize, OMPC_num_tasks}))
13803     return StmtError();
13804   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13805   // If a reduction clause is present on the taskloop directive, the nogroup
13806   // clause must not be specified.
13807   if (checkReductionClauseWithNogroup(*this, Clauses))
13808     return StmtError();
13809   if (checkSimdlenSafelenSpecified(*this, Clauses))
13810     return StmtError();
13811 
13812   setFunctionHasBranchProtectedScope();
13813   return OMPMasterTaskLoopSimdDirective::Create(
13814       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13815 }
13816 
13817 StmtResult Sema::ActOnOpenMPMaskedTaskLoopSimdDirective(
13818     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13819     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13820   if (!AStmt)
13821     return StmtError();
13822 
13823   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13824   OMPLoopBasedDirective::HelperExprs B;
13825   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13826   // define the nested loops number.
13827   unsigned NestedLoopCount =
13828       checkOpenMPLoop(OMPD_masked_taskloop_simd, getCollapseNumberExpr(Clauses),
13829                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
13830                       VarsWithImplicitDSA, B);
13831   if (NestedLoopCount == 0)
13832     return StmtError();
13833 
13834   assert((CurContext->isDependentContext() || B.builtAll()) &&
13835          "omp for loop exprs were not built");
13836 
13837   if (!CurContext->isDependentContext()) {
13838     // Finalize the clauses that need pre-built expressions for CodeGen.
13839     for (OMPClause *C : Clauses) {
13840       if (auto *LC = dyn_cast<OMPLinearClause>(C))
13841         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13842                                      B.NumIterations, *this, CurScope,
13843                                      DSAStack))
13844           return StmtError();
13845     }
13846   }
13847 
13848   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13849   // The grainsize clause and num_tasks clause are mutually exclusive and may
13850   // not appear on the same taskloop directive.
13851   if (checkMutuallyExclusiveClauses(*this, Clauses,
13852                                     {OMPC_grainsize, OMPC_num_tasks}))
13853     return StmtError();
13854   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13855   // If a reduction clause is present on the taskloop directive, the nogroup
13856   // clause must not be specified.
13857   if (checkReductionClauseWithNogroup(*this, Clauses))
13858     return StmtError();
13859   if (checkSimdlenSafelenSpecified(*this, Clauses))
13860     return StmtError();
13861 
13862   setFunctionHasBranchProtectedScope();
13863   return OMPMaskedTaskLoopSimdDirective::Create(
13864       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13865 }
13866 
13867 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective(
13868     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13869     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13870   if (!AStmt)
13871     return StmtError();
13872 
13873   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13874   auto *CS = cast<CapturedStmt>(AStmt);
13875   // 1.2.2 OpenMP Language Terminology
13876   // Structured block - An executable statement with a single entry at the
13877   // top and a single exit at the bottom.
13878   // The point of exit cannot be a branch out of the structured block.
13879   // longjmp() and throw() must not violate the entry/exit criteria.
13880   CS->getCapturedDecl()->setNothrow();
13881   for (int ThisCaptureLevel =
13882            getOpenMPCaptureLevels(OMPD_parallel_master_taskloop);
13883        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13884     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13885     // 1.2.2 OpenMP Language Terminology
13886     // Structured block - An executable statement with a single entry at the
13887     // top and a single exit at the bottom.
13888     // The point of exit cannot be a branch out of the structured block.
13889     // longjmp() and throw() must not violate the entry/exit criteria.
13890     CS->getCapturedDecl()->setNothrow();
13891   }
13892 
13893   OMPLoopBasedDirective::HelperExprs B;
13894   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13895   // define the nested loops number.
13896   unsigned NestedLoopCount = checkOpenMPLoop(
13897       OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses),
13898       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
13899       VarsWithImplicitDSA, B);
13900   if (NestedLoopCount == 0)
13901     return StmtError();
13902 
13903   assert((CurContext->isDependentContext() || B.builtAll()) &&
13904          "omp for loop exprs were not built");
13905 
13906   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13907   // The grainsize clause and num_tasks clause are mutually exclusive and may
13908   // not appear on the same taskloop directive.
13909   if (checkMutuallyExclusiveClauses(*this, Clauses,
13910                                     {OMPC_grainsize, OMPC_num_tasks}))
13911     return StmtError();
13912   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13913   // If a reduction clause is present on the taskloop directive, the nogroup
13914   // clause must not be specified.
13915   if (checkReductionClauseWithNogroup(*this, Clauses))
13916     return StmtError();
13917 
13918   setFunctionHasBranchProtectedScope();
13919   return OMPParallelMasterTaskLoopDirective::Create(
13920       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13921       DSAStack->isCancelRegion());
13922 }
13923 
13924 StmtResult Sema::ActOnOpenMPParallelMaskedTaskLoopDirective(
13925     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13926     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13927   if (!AStmt)
13928     return StmtError();
13929 
13930   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13931   auto *CS = cast<CapturedStmt>(AStmt);
13932   // 1.2.2 OpenMP Language Terminology
13933   // Structured block - An executable statement with a single entry at the
13934   // top and a single exit at the bottom.
13935   // The point of exit cannot be a branch out of the structured block.
13936   // longjmp() and throw() must not violate the entry/exit criteria.
13937   CS->getCapturedDecl()->setNothrow();
13938   for (int ThisCaptureLevel =
13939            getOpenMPCaptureLevels(OMPD_parallel_masked_taskloop);
13940        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13941     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13942     // 1.2.2 OpenMP Language Terminology
13943     // Structured block - An executable statement with a single entry at the
13944     // top and a single exit at the bottom.
13945     // The point of exit cannot be a branch out of the structured block.
13946     // longjmp() and throw() must not violate the entry/exit criteria.
13947     CS->getCapturedDecl()->setNothrow();
13948   }
13949 
13950   OMPLoopBasedDirective::HelperExprs B;
13951   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13952   // define the nested loops number.
13953   unsigned NestedLoopCount = checkOpenMPLoop(
13954       OMPD_parallel_masked_taskloop, getCollapseNumberExpr(Clauses),
13955       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
13956       VarsWithImplicitDSA, B);
13957   if (NestedLoopCount == 0)
13958     return StmtError();
13959 
13960   assert((CurContext->isDependentContext() || B.builtAll()) &&
13961          "omp for loop exprs were not built");
13962 
13963   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13964   // The grainsize clause and num_tasks clause are mutually exclusive and may
13965   // not appear on the same taskloop directive.
13966   if (checkMutuallyExclusiveClauses(*this, Clauses,
13967                                     {OMPC_grainsize, OMPC_num_tasks}))
13968     return StmtError();
13969   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
13970   // If a reduction clause is present on the taskloop directive, the nogroup
13971   // clause must not be specified.
13972   if (checkReductionClauseWithNogroup(*this, Clauses))
13973     return StmtError();
13974 
13975   setFunctionHasBranchProtectedScope();
13976   return OMPParallelMaskedTaskLoopDirective::Create(
13977       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13978       DSAStack->isCancelRegion());
13979 }
13980 
13981 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective(
13982     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13983     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13984   if (!AStmt)
13985     return StmtError();
13986 
13987   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
13988   auto *CS = cast<CapturedStmt>(AStmt);
13989   // 1.2.2 OpenMP Language Terminology
13990   // Structured block - An executable statement with a single entry at the
13991   // top and a single exit at the bottom.
13992   // The point of exit cannot be a branch out of the structured block.
13993   // longjmp() and throw() must not violate the entry/exit criteria.
13994   CS->getCapturedDecl()->setNothrow();
13995   for (int ThisCaptureLevel =
13996            getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd);
13997        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13998     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13999     // 1.2.2 OpenMP Language Terminology
14000     // Structured block - An executable statement with a single entry at the
14001     // top and a single exit at the bottom.
14002     // The point of exit cannot be a branch out of the structured block.
14003     // longjmp() and throw() must not violate the entry/exit criteria.
14004     CS->getCapturedDecl()->setNothrow();
14005   }
14006 
14007   OMPLoopBasedDirective::HelperExprs B;
14008   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
14009   // define the nested loops number.
14010   unsigned NestedLoopCount = checkOpenMPLoop(
14011       OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses),
14012       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
14013       VarsWithImplicitDSA, B);
14014   if (NestedLoopCount == 0)
14015     return StmtError();
14016 
14017   assert((CurContext->isDependentContext() || B.builtAll()) &&
14018          "omp for loop exprs were not built");
14019 
14020   if (!CurContext->isDependentContext()) {
14021     // Finalize the clauses that need pre-built expressions for CodeGen.
14022     for (OMPClause *C : Clauses) {
14023       if (auto *LC = dyn_cast<OMPLinearClause>(C))
14024         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14025                                      B.NumIterations, *this, CurScope,
14026                                      DSAStack))
14027           return StmtError();
14028     }
14029   }
14030 
14031   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
14032   // The grainsize clause and num_tasks clause are mutually exclusive and may
14033   // not appear on the same taskloop directive.
14034   if (checkMutuallyExclusiveClauses(*this, Clauses,
14035                                     {OMPC_grainsize, OMPC_num_tasks}))
14036     return StmtError();
14037   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
14038   // If a reduction clause is present on the taskloop directive, the nogroup
14039   // clause must not be specified.
14040   if (checkReductionClauseWithNogroup(*this, Clauses))
14041     return StmtError();
14042   if (checkSimdlenSafelenSpecified(*this, Clauses))
14043     return StmtError();
14044 
14045   setFunctionHasBranchProtectedScope();
14046   return OMPParallelMasterTaskLoopSimdDirective::Create(
14047       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14048 }
14049 
14050 StmtResult Sema::ActOnOpenMPParallelMaskedTaskLoopSimdDirective(
14051     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14052     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14053   if (!AStmt)
14054     return StmtError();
14055 
14056   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
14057   auto *CS = cast<CapturedStmt>(AStmt);
14058   // 1.2.2 OpenMP Language Terminology
14059   // Structured block - An executable statement with a single entry at the
14060   // top and a single exit at the bottom.
14061   // The point of exit cannot be a branch out of the structured block.
14062   // longjmp() and throw() must not violate the entry/exit criteria.
14063   CS->getCapturedDecl()->setNothrow();
14064   for (int ThisCaptureLevel =
14065            getOpenMPCaptureLevels(OMPD_parallel_masked_taskloop_simd);
14066        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14067     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14068     // 1.2.2 OpenMP Language Terminology
14069     // Structured block - An executable statement with a single entry at the
14070     // top and a single exit at the bottom.
14071     // The point of exit cannot be a branch out of the structured block.
14072     // longjmp() and throw() must not violate the entry/exit criteria.
14073     CS->getCapturedDecl()->setNothrow();
14074   }
14075 
14076   OMPLoopBasedDirective::HelperExprs B;
14077   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
14078   // define the nested loops number.
14079   unsigned NestedLoopCount = checkOpenMPLoop(
14080       OMPD_parallel_masked_taskloop_simd, getCollapseNumberExpr(Clauses),
14081       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
14082       VarsWithImplicitDSA, B);
14083   if (NestedLoopCount == 0)
14084     return StmtError();
14085 
14086   assert((CurContext->isDependentContext() || B.builtAll()) &&
14087          "omp for loop exprs were not built");
14088 
14089   if (!CurContext->isDependentContext()) {
14090     // Finalize the clauses that need pre-built expressions for CodeGen.
14091     for (OMPClause *C : Clauses) {
14092       if (auto *LC = dyn_cast<OMPLinearClause>(C))
14093         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14094                                      B.NumIterations, *this, CurScope,
14095                                      DSAStack))
14096           return StmtError();
14097     }
14098   }
14099 
14100   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
14101   // The grainsize clause and num_tasks clause are mutually exclusive and may
14102   // not appear on the same taskloop directive.
14103   if (checkMutuallyExclusiveClauses(*this, Clauses,
14104                                     {OMPC_grainsize, OMPC_num_tasks}))
14105     return StmtError();
14106   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
14107   // If a reduction clause is present on the taskloop directive, the nogroup
14108   // clause must not be specified.
14109   if (checkReductionClauseWithNogroup(*this, Clauses))
14110     return StmtError();
14111   if (checkSimdlenSafelenSpecified(*this, Clauses))
14112     return StmtError();
14113 
14114   setFunctionHasBranchProtectedScope();
14115   return OMPParallelMaskedTaskLoopSimdDirective::Create(
14116       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14117 }
14118 
14119 StmtResult Sema::ActOnOpenMPDistributeDirective(
14120     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14121     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14122   if (!AStmt)
14123     return StmtError();
14124 
14125   if (!checkLastPrivateForMappedDirectives(Clauses))
14126     return StmtError();
14127 
14128   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
14129   OMPLoopBasedDirective::HelperExprs B;
14130   // In presence of clause 'collapse' with number of loops, it will
14131   // define the nested loops number.
14132   unsigned NestedLoopCount =
14133       checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
14134                       nullptr /*ordered not a clause on distribute*/, AStmt,
14135                       *this, *DSAStack, VarsWithImplicitDSA, B);
14136   if (NestedLoopCount == 0)
14137     return StmtError();
14138 
14139   assert((CurContext->isDependentContext() || B.builtAll()) &&
14140          "omp for loop exprs were not built");
14141 
14142   setFunctionHasBranchProtectedScope();
14143   auto *DistributeDirective = OMPDistributeDirective::Create(
14144       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14145       DSAStack->getMappedDirective());
14146   return DistributeDirective;
14147 }
14148 
14149 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
14150     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14151     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14152   if (!AStmt)
14153     return StmtError();
14154 
14155   auto *CS = cast<CapturedStmt>(AStmt);
14156   // 1.2.2 OpenMP Language Terminology
14157   // Structured block - An executable statement with a single entry at the
14158   // top and a single exit at the bottom.
14159   // The point of exit cannot be a branch out of the structured block.
14160   // longjmp() and throw() must not violate the entry/exit criteria.
14161   CS->getCapturedDecl()->setNothrow();
14162   for (int ThisCaptureLevel =
14163            getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
14164        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14165     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14166     // 1.2.2 OpenMP Language Terminology
14167     // Structured block - An executable statement with a single entry at the
14168     // top and a single exit at the bottom.
14169     // The point of exit cannot be a branch out of the structured block.
14170     // longjmp() and throw() must not violate the entry/exit criteria.
14171     CS->getCapturedDecl()->setNothrow();
14172   }
14173 
14174   OMPLoopBasedDirective::HelperExprs B;
14175   // In presence of clause 'collapse' with number of loops, it will
14176   // define the nested loops number.
14177   unsigned NestedLoopCount = checkOpenMPLoop(
14178       OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
14179       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14180       VarsWithImplicitDSA, B);
14181   if (NestedLoopCount == 0)
14182     return StmtError();
14183 
14184   assert((CurContext->isDependentContext() || B.builtAll()) &&
14185          "omp for loop exprs were not built");
14186 
14187   setFunctionHasBranchProtectedScope();
14188   return OMPDistributeParallelForDirective::Create(
14189       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14190       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
14191 }
14192 
14193 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
14194     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14195     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14196   if (!AStmt)
14197     return StmtError();
14198 
14199   auto *CS = cast<CapturedStmt>(AStmt);
14200   // 1.2.2 OpenMP Language Terminology
14201   // Structured block - An executable statement with a single entry at the
14202   // top and a single exit at the bottom.
14203   // The point of exit cannot be a branch out of the structured block.
14204   // longjmp() and throw() must not violate the entry/exit criteria.
14205   CS->getCapturedDecl()->setNothrow();
14206   for (int ThisCaptureLevel =
14207            getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
14208        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14209     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14210     // 1.2.2 OpenMP Language Terminology
14211     // Structured block - An executable statement with a single entry at the
14212     // top and a single exit at the bottom.
14213     // The point of exit cannot be a branch out of the structured block.
14214     // longjmp() and throw() must not violate the entry/exit criteria.
14215     CS->getCapturedDecl()->setNothrow();
14216   }
14217 
14218   OMPLoopBasedDirective::HelperExprs B;
14219   // In presence of clause 'collapse' with number of loops, it will
14220   // define the nested loops number.
14221   unsigned NestedLoopCount = checkOpenMPLoop(
14222       OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
14223       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14224       VarsWithImplicitDSA, B);
14225   if (NestedLoopCount == 0)
14226     return StmtError();
14227 
14228   assert((CurContext->isDependentContext() || B.builtAll()) &&
14229          "omp for loop exprs were not built");
14230 
14231   if (!CurContext->isDependentContext()) {
14232     // Finalize the clauses that need pre-built expressions for CodeGen.
14233     for (OMPClause *C : Clauses) {
14234       if (auto *LC = dyn_cast<OMPLinearClause>(C))
14235         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14236                                      B.NumIterations, *this, CurScope,
14237                                      DSAStack))
14238           return StmtError();
14239     }
14240   }
14241 
14242   if (checkSimdlenSafelenSpecified(*this, Clauses))
14243     return StmtError();
14244 
14245   setFunctionHasBranchProtectedScope();
14246   return OMPDistributeParallelForSimdDirective::Create(
14247       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14248 }
14249 
14250 StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
14251     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14252     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14253   if (!AStmt)
14254     return StmtError();
14255 
14256   auto *CS = cast<CapturedStmt>(AStmt);
14257   // 1.2.2 OpenMP Language Terminology
14258   // Structured block - An executable statement with a single entry at the
14259   // top and a single exit at the bottom.
14260   // The point of exit cannot be a branch out of the structured block.
14261   // longjmp() and throw() must not violate the entry/exit criteria.
14262   CS->getCapturedDecl()->setNothrow();
14263   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
14264        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14265     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14266     // 1.2.2 OpenMP Language Terminology
14267     // Structured block - An executable statement with a single entry at the
14268     // top and a single exit at the bottom.
14269     // The point of exit cannot be a branch out of the structured block.
14270     // longjmp() and throw() must not violate the entry/exit criteria.
14271     CS->getCapturedDecl()->setNothrow();
14272   }
14273 
14274   OMPLoopBasedDirective::HelperExprs B;
14275   // In presence of clause 'collapse' with number of loops, it will
14276   // define the nested loops number.
14277   unsigned NestedLoopCount =
14278       checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
14279                       nullptr /*ordered not a clause on distribute*/, CS, *this,
14280                       *DSAStack, VarsWithImplicitDSA, B);
14281   if (NestedLoopCount == 0)
14282     return StmtError();
14283 
14284   assert((CurContext->isDependentContext() || B.builtAll()) &&
14285          "omp for loop exprs were not built");
14286 
14287   if (!CurContext->isDependentContext()) {
14288     // Finalize the clauses that need pre-built expressions for CodeGen.
14289     for (OMPClause *C : Clauses) {
14290       if (auto *LC = dyn_cast<OMPLinearClause>(C))
14291         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14292                                      B.NumIterations, *this, CurScope,
14293                                      DSAStack))
14294           return StmtError();
14295     }
14296   }
14297 
14298   if (checkSimdlenSafelenSpecified(*this, Clauses))
14299     return StmtError();
14300 
14301   setFunctionHasBranchProtectedScope();
14302   return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
14303                                             NestedLoopCount, Clauses, AStmt, B);
14304 }
14305 
14306 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
14307     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14308     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14309   if (!AStmt)
14310     return StmtError();
14311 
14312   auto *CS = cast<CapturedStmt>(AStmt);
14313   // 1.2.2 OpenMP Language Terminology
14314   // Structured block - An executable statement with a single entry at the
14315   // top and a single exit at the bottom.
14316   // The point of exit cannot be a branch out of the structured block.
14317   // longjmp() and throw() must not violate the entry/exit criteria.
14318   CS->getCapturedDecl()->setNothrow();
14319   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
14320        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14321     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14322     // 1.2.2 OpenMP Language Terminology
14323     // Structured block - An executable statement with a single entry at the
14324     // top and a single exit at the bottom.
14325     // The point of exit cannot be a branch out of the structured block.
14326     // longjmp() and throw() must not violate the entry/exit criteria.
14327     CS->getCapturedDecl()->setNothrow();
14328   }
14329 
14330   OMPLoopBasedDirective::HelperExprs B;
14331   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
14332   // define the nested loops number.
14333   unsigned NestedLoopCount = checkOpenMPLoop(
14334       OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
14335       getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, VarsWithImplicitDSA,
14336       B);
14337   if (NestedLoopCount == 0)
14338     return StmtError();
14339 
14340   assert((CurContext->isDependentContext() || B.builtAll()) &&
14341          "omp target parallel for simd loop exprs were not built");
14342 
14343   if (!CurContext->isDependentContext()) {
14344     // Finalize the clauses that need pre-built expressions for CodeGen.
14345     for (OMPClause *C : Clauses) {
14346       if (auto *LC = dyn_cast<OMPLinearClause>(C))
14347         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14348                                      B.NumIterations, *this, CurScope,
14349                                      DSAStack))
14350           return StmtError();
14351     }
14352   }
14353   if (checkSimdlenSafelenSpecified(*this, Clauses))
14354     return StmtError();
14355 
14356   setFunctionHasBranchProtectedScope();
14357   return OMPTargetParallelForSimdDirective::Create(
14358       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14359 }
14360 
14361 StmtResult Sema::ActOnOpenMPTargetSimdDirective(
14362     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14363     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14364   if (!AStmt)
14365     return StmtError();
14366 
14367   auto *CS = cast<CapturedStmt>(AStmt);
14368   // 1.2.2 OpenMP Language Terminology
14369   // Structured block - An executable statement with a single entry at the
14370   // top and a single exit at the bottom.
14371   // The point of exit cannot be a branch out of the structured block.
14372   // longjmp() and throw() must not violate the entry/exit criteria.
14373   CS->getCapturedDecl()->setNothrow();
14374   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
14375        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14376     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14377     // 1.2.2 OpenMP Language Terminology
14378     // Structured block - An executable statement with a single entry at the
14379     // top and a single exit at the bottom.
14380     // The point of exit cannot be a branch out of the structured block.
14381     // longjmp() and throw() must not violate the entry/exit criteria.
14382     CS->getCapturedDecl()->setNothrow();
14383   }
14384 
14385   OMPLoopBasedDirective::HelperExprs B;
14386   // In presence of clause 'collapse' with number of loops, it will define the
14387   // nested loops number.
14388   unsigned NestedLoopCount =
14389       checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
14390                       getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
14391                       VarsWithImplicitDSA, B);
14392   if (NestedLoopCount == 0)
14393     return StmtError();
14394 
14395   assert((CurContext->isDependentContext() || B.builtAll()) &&
14396          "omp target simd loop exprs were not built");
14397 
14398   if (!CurContext->isDependentContext()) {
14399     // Finalize the clauses that need pre-built expressions for CodeGen.
14400     for (OMPClause *C : Clauses) {
14401       if (auto *LC = dyn_cast<OMPLinearClause>(C))
14402         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14403                                      B.NumIterations, *this, CurScope,
14404                                      DSAStack))
14405           return StmtError();
14406     }
14407   }
14408 
14409   if (checkSimdlenSafelenSpecified(*this, Clauses))
14410     return StmtError();
14411 
14412   setFunctionHasBranchProtectedScope();
14413   return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
14414                                         NestedLoopCount, Clauses, AStmt, B);
14415 }
14416 
14417 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
14418     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14419     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14420   if (!AStmt)
14421     return StmtError();
14422 
14423   auto *CS = cast<CapturedStmt>(AStmt);
14424   // 1.2.2 OpenMP Language Terminology
14425   // Structured block - An executable statement with a single entry at the
14426   // top and a single exit at the bottom.
14427   // The point of exit cannot be a branch out of the structured block.
14428   // longjmp() and throw() must not violate the entry/exit criteria.
14429   CS->getCapturedDecl()->setNothrow();
14430   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
14431        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14432     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14433     // 1.2.2 OpenMP Language Terminology
14434     // Structured block - An executable statement with a single entry at the
14435     // top and a single exit at the bottom.
14436     // The point of exit cannot be a branch out of the structured block.
14437     // longjmp() and throw() must not violate the entry/exit criteria.
14438     CS->getCapturedDecl()->setNothrow();
14439   }
14440 
14441   OMPLoopBasedDirective::HelperExprs B;
14442   // In presence of clause 'collapse' with number of loops, it will
14443   // define the nested loops number.
14444   unsigned NestedLoopCount =
14445       checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
14446                       nullptr /*ordered not a clause on distribute*/, CS, *this,
14447                       *DSAStack, VarsWithImplicitDSA, B);
14448   if (NestedLoopCount == 0)
14449     return StmtError();
14450 
14451   assert((CurContext->isDependentContext() || B.builtAll()) &&
14452          "omp teams distribute loop exprs were not built");
14453 
14454   setFunctionHasBranchProtectedScope();
14455 
14456   DSAStack->setParentTeamsRegionLoc(StartLoc);
14457 
14458   return OMPTeamsDistributeDirective::Create(
14459       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14460 }
14461 
14462 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
14463     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14464     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14465   if (!AStmt)
14466     return StmtError();
14467 
14468   auto *CS = cast<CapturedStmt>(AStmt);
14469   // 1.2.2 OpenMP Language Terminology
14470   // Structured block - An executable statement with a single entry at the
14471   // top and a single exit at the bottom.
14472   // The point of exit cannot be a branch out of the structured block.
14473   // longjmp() and throw() must not violate the entry/exit criteria.
14474   CS->getCapturedDecl()->setNothrow();
14475   for (int ThisCaptureLevel =
14476            getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
14477        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14478     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14479     // 1.2.2 OpenMP Language Terminology
14480     // Structured block - An executable statement with a single entry at the
14481     // top and a single exit at the bottom.
14482     // The point of exit cannot be a branch out of the structured block.
14483     // longjmp() and throw() must not violate the entry/exit criteria.
14484     CS->getCapturedDecl()->setNothrow();
14485   }
14486 
14487   OMPLoopBasedDirective::HelperExprs B;
14488   // In presence of clause 'collapse' with number of loops, it will
14489   // define the nested loops number.
14490   unsigned NestedLoopCount = checkOpenMPLoop(
14491       OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
14492       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14493       VarsWithImplicitDSA, B);
14494 
14495   if (NestedLoopCount == 0)
14496     return StmtError();
14497 
14498   assert((CurContext->isDependentContext() || B.builtAll()) &&
14499          "omp teams distribute simd loop exprs were not built");
14500 
14501   if (!CurContext->isDependentContext()) {
14502     // Finalize the clauses that need pre-built expressions for CodeGen.
14503     for (OMPClause *C : Clauses) {
14504       if (auto *LC = dyn_cast<OMPLinearClause>(C))
14505         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14506                                      B.NumIterations, *this, CurScope,
14507                                      DSAStack))
14508           return StmtError();
14509     }
14510   }
14511 
14512   if (checkSimdlenSafelenSpecified(*this, Clauses))
14513     return StmtError();
14514 
14515   setFunctionHasBranchProtectedScope();
14516 
14517   DSAStack->setParentTeamsRegionLoc(StartLoc);
14518 
14519   return OMPTeamsDistributeSimdDirective::Create(
14520       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14521 }
14522 
14523 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
14524     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14525     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14526   if (!AStmt)
14527     return StmtError();
14528 
14529   auto *CS = cast<CapturedStmt>(AStmt);
14530   // 1.2.2 OpenMP Language Terminology
14531   // Structured block - An executable statement with a single entry at the
14532   // top and a single exit at the bottom.
14533   // The point of exit cannot be a branch out of the structured block.
14534   // longjmp() and throw() must not violate the entry/exit criteria.
14535   CS->getCapturedDecl()->setNothrow();
14536 
14537   for (int ThisCaptureLevel =
14538            getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
14539        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14540     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14541     // 1.2.2 OpenMP Language Terminology
14542     // Structured block - An executable statement with a single entry at the
14543     // top and a single exit at the bottom.
14544     // The point of exit cannot be a branch out of the structured block.
14545     // longjmp() and throw() must not violate the entry/exit criteria.
14546     CS->getCapturedDecl()->setNothrow();
14547   }
14548 
14549   OMPLoopBasedDirective::HelperExprs B;
14550   // In presence of clause 'collapse' with number of loops, it will
14551   // define the nested loops number.
14552   unsigned NestedLoopCount = checkOpenMPLoop(
14553       OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
14554       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14555       VarsWithImplicitDSA, B);
14556 
14557   if (NestedLoopCount == 0)
14558     return StmtError();
14559 
14560   assert((CurContext->isDependentContext() || B.builtAll()) &&
14561          "omp for loop exprs were not built");
14562 
14563   if (!CurContext->isDependentContext()) {
14564     // Finalize the clauses that need pre-built expressions for CodeGen.
14565     for (OMPClause *C : Clauses) {
14566       if (auto *LC = dyn_cast<OMPLinearClause>(C))
14567         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14568                                      B.NumIterations, *this, CurScope,
14569                                      DSAStack))
14570           return StmtError();
14571     }
14572   }
14573 
14574   if (checkSimdlenSafelenSpecified(*this, Clauses))
14575     return StmtError();
14576 
14577   setFunctionHasBranchProtectedScope();
14578 
14579   DSAStack->setParentTeamsRegionLoc(StartLoc);
14580 
14581   return OMPTeamsDistributeParallelForSimdDirective::Create(
14582       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14583 }
14584 
14585 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
14586     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14587     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14588   if (!AStmt)
14589     return StmtError();
14590 
14591   auto *CS = cast<CapturedStmt>(AStmt);
14592   // 1.2.2 OpenMP Language Terminology
14593   // Structured block - An executable statement with a single entry at the
14594   // top and a single exit at the bottom.
14595   // The point of exit cannot be a branch out of the structured block.
14596   // longjmp() and throw() must not violate the entry/exit criteria.
14597   CS->getCapturedDecl()->setNothrow();
14598 
14599   for (int ThisCaptureLevel =
14600            getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
14601        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14602     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14603     // 1.2.2 OpenMP Language Terminology
14604     // Structured block - An executable statement with a single entry at the
14605     // top and a single exit at the bottom.
14606     // The point of exit cannot be a branch out of the structured block.
14607     // longjmp() and throw() must not violate the entry/exit criteria.
14608     CS->getCapturedDecl()->setNothrow();
14609   }
14610 
14611   OMPLoopBasedDirective::HelperExprs B;
14612   // In presence of clause 'collapse' with number of loops, it will
14613   // define the nested loops number.
14614   unsigned NestedLoopCount = checkOpenMPLoop(
14615       OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
14616       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14617       VarsWithImplicitDSA, B);
14618 
14619   if (NestedLoopCount == 0)
14620     return StmtError();
14621 
14622   assert((CurContext->isDependentContext() || B.builtAll()) &&
14623          "omp for loop exprs were not built");
14624 
14625   setFunctionHasBranchProtectedScope();
14626 
14627   DSAStack->setParentTeamsRegionLoc(StartLoc);
14628 
14629   return OMPTeamsDistributeParallelForDirective::Create(
14630       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14631       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
14632 }
14633 
14634 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
14635                                                  Stmt *AStmt,
14636                                                  SourceLocation StartLoc,
14637                                                  SourceLocation EndLoc) {
14638   if (!AStmt)
14639     return StmtError();
14640 
14641   auto *CS = cast<CapturedStmt>(AStmt);
14642   // 1.2.2 OpenMP Language Terminology
14643   // Structured block - An executable statement with a single entry at the
14644   // top and a single exit at the bottom.
14645   // The point of exit cannot be a branch out of the structured block.
14646   // longjmp() and throw() must not violate the entry/exit criteria.
14647   CS->getCapturedDecl()->setNothrow();
14648 
14649   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
14650        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14651     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14652     // 1.2.2 OpenMP Language Terminology
14653     // Structured block - An executable statement with a single entry at the
14654     // top and a single exit at the bottom.
14655     // The point of exit cannot be a branch out of the structured block.
14656     // longjmp() and throw() must not violate the entry/exit criteria.
14657     CS->getCapturedDecl()->setNothrow();
14658   }
14659   setFunctionHasBranchProtectedScope();
14660 
14661   const OMPClause *BareClause = nullptr;
14662   bool HasThreadLimitAndNumTeamsClause = hasClauses(Clauses, OMPC_num_teams) &&
14663                                          hasClauses(Clauses, OMPC_thread_limit);
14664   bool HasBareClause = llvm::any_of(Clauses, [&](const OMPClause *C) {
14665     BareClause = C;
14666     return C->getClauseKind() == OMPC_ompx_bare;
14667   });
14668 
14669   if (HasBareClause && !HasThreadLimitAndNumTeamsClause) {
14670     Diag(BareClause->getBeginLoc(), diag::err_ompx_bare_no_grid);
14671     return StmtError();
14672   }
14673 
14674   return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
14675                                          AStmt);
14676 }
14677 
14678 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
14679     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14680     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14681   if (!AStmt)
14682     return StmtError();
14683 
14684   auto *CS = cast<CapturedStmt>(AStmt);
14685   // 1.2.2 OpenMP Language Terminology
14686   // Structured block - An executable statement with a single entry at the
14687   // top and a single exit at the bottom.
14688   // The point of exit cannot be a branch out of the structured block.
14689   // longjmp() and throw() must not violate the entry/exit criteria.
14690   CS->getCapturedDecl()->setNothrow();
14691   for (int ThisCaptureLevel =
14692            getOpenMPCaptureLevels(OMPD_target_teams_distribute);
14693        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14694     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14695     // 1.2.2 OpenMP Language Terminology
14696     // Structured block - An executable statement with a single entry at the
14697     // top and a single exit at the bottom.
14698     // The point of exit cannot be a branch out of the structured block.
14699     // longjmp() and throw() must not violate the entry/exit criteria.
14700     CS->getCapturedDecl()->setNothrow();
14701   }
14702 
14703   OMPLoopBasedDirective::HelperExprs B;
14704   // In presence of clause 'collapse' with number of loops, it will
14705   // define the nested loops number.
14706   unsigned NestedLoopCount = checkOpenMPLoop(
14707       OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
14708       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14709       VarsWithImplicitDSA, B);
14710   if (NestedLoopCount == 0)
14711     return StmtError();
14712 
14713   assert((CurContext->isDependentContext() || B.builtAll()) &&
14714          "omp target teams distribute loop exprs were not built");
14715 
14716   setFunctionHasBranchProtectedScope();
14717   return OMPTargetTeamsDistributeDirective::Create(
14718       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14719 }
14720 
14721 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
14722     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14723     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14724   if (!AStmt)
14725     return StmtError();
14726 
14727   auto *CS = cast<CapturedStmt>(AStmt);
14728   // 1.2.2 OpenMP Language Terminology
14729   // Structured block - An executable statement with a single entry at the
14730   // top and a single exit at the bottom.
14731   // The point of exit cannot be a branch out of the structured block.
14732   // longjmp() and throw() must not violate the entry/exit criteria.
14733   CS->getCapturedDecl()->setNothrow();
14734   for (int ThisCaptureLevel =
14735            getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
14736        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14737     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14738     // 1.2.2 OpenMP Language Terminology
14739     // Structured block - An executable statement with a single entry at the
14740     // top and a single exit at the bottom.
14741     // The point of exit cannot be a branch out of the structured block.
14742     // longjmp() and throw() must not violate the entry/exit criteria.
14743     CS->getCapturedDecl()->setNothrow();
14744   }
14745 
14746   OMPLoopBasedDirective::HelperExprs B;
14747   // In presence of clause 'collapse' with number of loops, it will
14748   // define the nested loops number.
14749   unsigned NestedLoopCount = checkOpenMPLoop(
14750       OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
14751       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14752       VarsWithImplicitDSA, B);
14753   if (NestedLoopCount == 0)
14754     return StmtError();
14755 
14756   assert((CurContext->isDependentContext() || B.builtAll()) &&
14757          "omp target teams distribute parallel for loop exprs were not built");
14758 
14759   if (!CurContext->isDependentContext()) {
14760     // Finalize the clauses that need pre-built expressions for CodeGen.
14761     for (OMPClause *C : Clauses) {
14762       if (auto *LC = dyn_cast<OMPLinearClause>(C))
14763         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14764                                      B.NumIterations, *this, CurScope,
14765                                      DSAStack))
14766           return StmtError();
14767     }
14768   }
14769 
14770   setFunctionHasBranchProtectedScope();
14771   return OMPTargetTeamsDistributeParallelForDirective::Create(
14772       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
14773       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
14774 }
14775 
14776 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
14777     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14778     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14779   if (!AStmt)
14780     return StmtError();
14781 
14782   auto *CS = cast<CapturedStmt>(AStmt);
14783   // 1.2.2 OpenMP Language Terminology
14784   // Structured block - An executable statement with a single entry at the
14785   // top and a single exit at the bottom.
14786   // The point of exit cannot be a branch out of the structured block.
14787   // longjmp() and throw() must not violate the entry/exit criteria.
14788   CS->getCapturedDecl()->setNothrow();
14789   for (int ThisCaptureLevel = getOpenMPCaptureLevels(
14790            OMPD_target_teams_distribute_parallel_for_simd);
14791        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14792     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14793     // 1.2.2 OpenMP Language Terminology
14794     // Structured block - An executable statement with a single entry at the
14795     // top and a single exit at the bottom.
14796     // The point of exit cannot be a branch out of the structured block.
14797     // longjmp() and throw() must not violate the entry/exit criteria.
14798     CS->getCapturedDecl()->setNothrow();
14799   }
14800 
14801   OMPLoopBasedDirective::HelperExprs B;
14802   // In presence of clause 'collapse' with number of loops, it will
14803   // define the nested loops number.
14804   unsigned NestedLoopCount =
14805       checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
14806                       getCollapseNumberExpr(Clauses),
14807                       nullptr /*ordered not a clause on distribute*/, CS, *this,
14808                       *DSAStack, VarsWithImplicitDSA, B);
14809   if (NestedLoopCount == 0)
14810     return StmtError();
14811 
14812   assert((CurContext->isDependentContext() || B.builtAll()) &&
14813          "omp target teams distribute parallel for simd loop exprs were not "
14814          "built");
14815 
14816   if (!CurContext->isDependentContext()) {
14817     // Finalize the clauses that need pre-built expressions for CodeGen.
14818     for (OMPClause *C : Clauses) {
14819       if (auto *LC = dyn_cast<OMPLinearClause>(C))
14820         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14821                                      B.NumIterations, *this, CurScope,
14822                                      DSAStack))
14823           return StmtError();
14824     }
14825   }
14826 
14827   if (checkSimdlenSafelenSpecified(*this, Clauses))
14828     return StmtError();
14829 
14830   setFunctionHasBranchProtectedScope();
14831   return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
14832       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14833 }
14834 
14835 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
14836     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
14837     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
14838   if (!AStmt)
14839     return StmtError();
14840 
14841   auto *CS = cast<CapturedStmt>(AStmt);
14842   // 1.2.2 OpenMP Language Terminology
14843   // Structured block - An executable statement with a single entry at the
14844   // top and a single exit at the bottom.
14845   // The point of exit cannot be a branch out of the structured block.
14846   // longjmp() and throw() must not violate the entry/exit criteria.
14847   CS->getCapturedDecl()->setNothrow();
14848   for (int ThisCaptureLevel =
14849            getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
14850        ThisCaptureLevel > 1; --ThisCaptureLevel) {
14851     CS = cast<CapturedStmt>(CS->getCapturedStmt());
14852     // 1.2.2 OpenMP Language Terminology
14853     // Structured block - An executable statement with a single entry at the
14854     // top and a single exit at the bottom.
14855     // The point of exit cannot be a branch out of the structured block.
14856     // longjmp() and throw() must not violate the entry/exit criteria.
14857     CS->getCapturedDecl()->setNothrow();
14858   }
14859 
14860   OMPLoopBasedDirective::HelperExprs B;
14861   // In presence of clause 'collapse' with number of loops, it will
14862   // define the nested loops number.
14863   unsigned NestedLoopCount = checkOpenMPLoop(
14864       OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
14865       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
14866       VarsWithImplicitDSA, B);
14867   if (NestedLoopCount == 0)
14868     return StmtError();
14869 
14870   assert((CurContext->isDependentContext() || B.builtAll()) &&
14871          "omp target teams distribute simd loop exprs were not built");
14872 
14873   if (!CurContext->isDependentContext()) {
14874     // Finalize the clauses that need pre-built expressions for CodeGen.
14875     for (OMPClause *C : Clauses) {
14876       if (auto *LC = dyn_cast<OMPLinearClause>(C))
14877         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
14878                                      B.NumIterations, *this, CurScope,
14879                                      DSAStack))
14880           return StmtError();
14881     }
14882   }
14883 
14884   if (checkSimdlenSafelenSpecified(*this, Clauses))
14885     return StmtError();
14886 
14887   setFunctionHasBranchProtectedScope();
14888   return OMPTargetTeamsDistributeSimdDirective::Create(
14889       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
14890 }
14891 
14892 bool Sema::checkTransformableLoopNest(
14893     OpenMPDirectiveKind Kind, Stmt *AStmt, int NumLoops,
14894     SmallVectorImpl<OMPLoopBasedDirective::HelperExprs> &LoopHelpers,
14895     Stmt *&Body,
14896     SmallVectorImpl<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>>
14897         &OriginalInits) {
14898   OriginalInits.emplace_back();
14899   bool Result = OMPLoopBasedDirective::doForAllLoops(
14900       AStmt->IgnoreContainers(), /*TryImperfectlyNestedLoops=*/false, NumLoops,
14901       [this, &LoopHelpers, &Body, &OriginalInits, Kind](unsigned Cnt,
14902                                                         Stmt *CurStmt) {
14903         VarsWithInheritedDSAType TmpDSA;
14904         unsigned SingleNumLoops =
14905             checkOpenMPLoop(Kind, nullptr, nullptr, CurStmt, *this, *DSAStack,
14906                             TmpDSA, LoopHelpers[Cnt]);
14907         if (SingleNumLoops == 0)
14908           return true;
14909         assert(SingleNumLoops == 1 && "Expect single loop iteration space");
14910         if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
14911           OriginalInits.back().push_back(For->getInit());
14912           Body = For->getBody();
14913         } else {
14914           assert(isa<CXXForRangeStmt>(CurStmt) &&
14915                  "Expected canonical for or range-based for loops.");
14916           auto *CXXFor = cast<CXXForRangeStmt>(CurStmt);
14917           OriginalInits.back().push_back(CXXFor->getBeginStmt());
14918           Body = CXXFor->getBody();
14919         }
14920         OriginalInits.emplace_back();
14921         return false;
14922       },
14923       [&OriginalInits](OMPLoopBasedDirective *Transform) {
14924         Stmt *DependentPreInits;
14925         if (auto *Dir = dyn_cast<OMPTileDirective>(Transform))
14926           DependentPreInits = Dir->getPreInits();
14927         else if (auto *Dir = dyn_cast<OMPUnrollDirective>(Transform))
14928           DependentPreInits = Dir->getPreInits();
14929         else
14930           llvm_unreachable("Unhandled loop transformation");
14931         if (!DependentPreInits)
14932           return;
14933         llvm::append_range(OriginalInits.back(),
14934                            cast<DeclStmt>(DependentPreInits)->getDeclGroup());
14935       });
14936   assert(OriginalInits.back().empty() && "No preinit after innermost loop");
14937   OriginalInits.pop_back();
14938   return Result;
14939 }
14940 
14941 StmtResult Sema::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses,
14942                                           Stmt *AStmt, SourceLocation StartLoc,
14943                                           SourceLocation EndLoc) {
14944   auto SizesClauses =
14945       OMPExecutableDirective::getClausesOfKind<OMPSizesClause>(Clauses);
14946   if (SizesClauses.empty()) {
14947     // A missing 'sizes' clause is already reported by the parser.
14948     return StmtError();
14949   }
14950   const OMPSizesClause *SizesClause = *SizesClauses.begin();
14951   unsigned NumLoops = SizesClause->getNumSizes();
14952 
14953   // Empty statement should only be possible if there already was an error.
14954   if (!AStmt)
14955     return StmtError();
14956 
14957   // Verify and diagnose loop nest.
14958   SmallVector<OMPLoopBasedDirective::HelperExprs, 4> LoopHelpers(NumLoops);
14959   Stmt *Body = nullptr;
14960   SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, 4>
14961       OriginalInits;
14962   if (!checkTransformableLoopNest(OMPD_tile, AStmt, NumLoops, LoopHelpers, Body,
14963                                   OriginalInits))
14964     return StmtError();
14965 
14966   // Delay tiling to when template is completely instantiated.
14967   if (CurContext->isDependentContext())
14968     return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses,
14969                                     NumLoops, AStmt, nullptr, nullptr);
14970 
14971   SmallVector<Decl *, 4> PreInits;
14972 
14973   // Create iteration variables for the generated loops.
14974   SmallVector<VarDecl *, 4> FloorIndVars;
14975   SmallVector<VarDecl *, 4> TileIndVars;
14976   FloorIndVars.resize(NumLoops);
14977   TileIndVars.resize(NumLoops);
14978   for (unsigned I = 0; I < NumLoops; ++I) {
14979     OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
14980 
14981     assert(LoopHelper.Counters.size() == 1 &&
14982            "Expect single-dimensional loop iteration space");
14983     auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
14984     std::string OrigVarName = OrigCntVar->getNameInfo().getAsString();
14985     DeclRefExpr *IterVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
14986     QualType CntTy = IterVarRef->getType();
14987 
14988     // Iteration variable for the floor (i.e. outer) loop.
14989     {
14990       std::string FloorCntName =
14991           (Twine(".floor_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
14992       VarDecl *FloorCntDecl =
14993           buildVarDecl(*this, {}, CntTy, FloorCntName, nullptr, OrigCntVar);
14994       FloorIndVars[I] = FloorCntDecl;
14995     }
14996 
14997     // Iteration variable for the tile (i.e. inner) loop.
14998     {
14999       std::string TileCntName =
15000           (Twine(".tile_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
15001 
15002       // Reuse the iteration variable created by checkOpenMPLoop. It is also
15003       // used by the expressions to derive the original iteration variable's
15004       // value from the logical iteration number.
15005       auto *TileCntDecl = cast<VarDecl>(IterVarRef->getDecl());
15006       TileCntDecl->setDeclName(&PP.getIdentifierTable().get(TileCntName));
15007       TileIndVars[I] = TileCntDecl;
15008     }
15009     for (auto &P : OriginalInits[I]) {
15010       if (auto *D = P.dyn_cast<Decl *>())
15011         PreInits.push_back(D);
15012       else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>()))
15013         PreInits.append(PI->decl_begin(), PI->decl_end());
15014     }
15015     if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
15016       PreInits.append(PI->decl_begin(), PI->decl_end());
15017     // Gather declarations for the data members used as counters.
15018     for (Expr *CounterRef : LoopHelper.Counters) {
15019       auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
15020       if (isa<OMPCapturedExprDecl>(CounterDecl))
15021         PreInits.push_back(CounterDecl);
15022     }
15023   }
15024 
15025   // Once the original iteration values are set, append the innermost body.
15026   Stmt *Inner = Body;
15027 
15028   // Create tile loops from the inside to the outside.
15029   for (int I = NumLoops - 1; I >= 0; --I) {
15030     OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
15031     Expr *NumIterations = LoopHelper.NumIterations;
15032     auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
15033     QualType CntTy = OrigCntVar->getType();
15034     Expr *DimTileSize = SizesClause->getSizesRefs()[I];
15035     Scope *CurScope = getCurScope();
15036 
15037     // Commonly used variables.
15038     DeclRefExpr *TileIV = buildDeclRefExpr(*this, TileIndVars[I], CntTy,
15039                                            OrigCntVar->getExprLoc());
15040     DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
15041                                             OrigCntVar->getExprLoc());
15042 
15043     // For init-statement: auto .tile.iv = .floor.iv
15044     AddInitializerToDecl(TileIndVars[I], DefaultLvalueConversion(FloorIV).get(),
15045                          /*DirectInit=*/false);
15046     Decl *CounterDecl = TileIndVars[I];
15047     StmtResult InitStmt = new (Context)
15048         DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
15049                  OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
15050     if (!InitStmt.isUsable())
15051       return StmtError();
15052 
15053     // For cond-expression: .tile.iv < min(.floor.iv + DimTileSize,
15054     // NumIterations)
15055     ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
15056                                       BO_Add, FloorIV, DimTileSize);
15057     if (!EndOfTile.isUsable())
15058       return StmtError();
15059     ExprResult IsPartialTile =
15060         BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT,
15061                    NumIterations, EndOfTile.get());
15062     if (!IsPartialTile.isUsable())
15063       return StmtError();
15064     ExprResult MinTileAndIterSpace = ActOnConditionalOp(
15065         LoopHelper.Cond->getBeginLoc(), LoopHelper.Cond->getEndLoc(),
15066         IsPartialTile.get(), NumIterations, EndOfTile.get());
15067     if (!MinTileAndIterSpace.isUsable())
15068       return StmtError();
15069     ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
15070                                      BO_LT, TileIV, MinTileAndIterSpace.get());
15071     if (!CondExpr.isUsable())
15072       return StmtError();
15073 
15074     // For incr-statement: ++.tile.iv
15075     ExprResult IncrStmt =
15076         BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), UO_PreInc, TileIV);
15077     if (!IncrStmt.isUsable())
15078       return StmtError();
15079 
15080     // Statements to set the original iteration variable's value from the
15081     // logical iteration number.
15082     // Generated for loop is:
15083     // Original_for_init;
15084     // for (auto .tile.iv = .floor.iv; .tile.iv < min(.floor.iv + DimTileSize,
15085     // NumIterations); ++.tile.iv) {
15086     //   Original_Body;
15087     //   Original_counter_update;
15088     // }
15089     // FIXME: If the innermost body is an loop itself, inserting these
15090     // statements stops it being recognized  as a perfectly nested loop (e.g.
15091     // for applying tiling again). If this is the case, sink the expressions
15092     // further into the inner loop.
15093     SmallVector<Stmt *, 4> BodyParts;
15094     BodyParts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
15095     BodyParts.push_back(Inner);
15096     Inner = CompoundStmt::Create(Context, BodyParts, FPOptionsOverride(),
15097                                  Inner->getBeginLoc(), Inner->getEndLoc());
15098     Inner = new (Context)
15099         ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
15100                 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
15101                 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
15102   }
15103 
15104   // Create floor loops from the inside to the outside.
15105   for (int I = NumLoops - 1; I >= 0; --I) {
15106     auto &LoopHelper = LoopHelpers[I];
15107     Expr *NumIterations = LoopHelper.NumIterations;
15108     DeclRefExpr *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
15109     QualType CntTy = OrigCntVar->getType();
15110     Expr *DimTileSize = SizesClause->getSizesRefs()[I];
15111     Scope *CurScope = getCurScope();
15112 
15113     // Commonly used variables.
15114     DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
15115                                             OrigCntVar->getExprLoc());
15116 
15117     // For init-statement: auto .floor.iv = 0
15118     AddInitializerToDecl(
15119         FloorIndVars[I],
15120         ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
15121         /*DirectInit=*/false);
15122     Decl *CounterDecl = FloorIndVars[I];
15123     StmtResult InitStmt = new (Context)
15124         DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
15125                  OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
15126     if (!InitStmt.isUsable())
15127       return StmtError();
15128 
15129     // For cond-expression: .floor.iv < NumIterations
15130     ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
15131                                      BO_LT, FloorIV, NumIterations);
15132     if (!CondExpr.isUsable())
15133       return StmtError();
15134 
15135     // For incr-statement: .floor.iv += DimTileSize
15136     ExprResult IncrStmt = BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(),
15137                                      BO_AddAssign, FloorIV, DimTileSize);
15138     if (!IncrStmt.isUsable())
15139       return StmtError();
15140 
15141     Inner = new (Context)
15142         ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
15143                 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
15144                 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
15145   }
15146 
15147   return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, NumLoops,
15148                                   AStmt, Inner,
15149                                   buildPreInits(Context, PreInits));
15150 }
15151 
15152 StmtResult Sema::ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses,
15153                                             Stmt *AStmt,
15154                                             SourceLocation StartLoc,
15155                                             SourceLocation EndLoc) {
15156   // Empty statement should only be possible if there already was an error.
15157   if (!AStmt)
15158     return StmtError();
15159 
15160   if (checkMutuallyExclusiveClauses(*this, Clauses, {OMPC_partial, OMPC_full}))
15161     return StmtError();
15162 
15163   const OMPFullClause *FullClause =
15164       OMPExecutableDirective::getSingleClause<OMPFullClause>(Clauses);
15165   const OMPPartialClause *PartialClause =
15166       OMPExecutableDirective::getSingleClause<OMPPartialClause>(Clauses);
15167   assert(!(FullClause && PartialClause) &&
15168          "mutual exclusivity must have been checked before");
15169 
15170   constexpr unsigned NumLoops = 1;
15171   Stmt *Body = nullptr;
15172   SmallVector<OMPLoopBasedDirective::HelperExprs, NumLoops> LoopHelpers(
15173       NumLoops);
15174   SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, NumLoops + 1>
15175       OriginalInits;
15176   if (!checkTransformableLoopNest(OMPD_unroll, AStmt, NumLoops, LoopHelpers,
15177                                   Body, OriginalInits))
15178     return StmtError();
15179 
15180   unsigned NumGeneratedLoops = PartialClause ? 1 : 0;
15181 
15182   // Delay unrolling to when template is completely instantiated.
15183   if (CurContext->isDependentContext())
15184     return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
15185                                       NumGeneratedLoops, nullptr, nullptr);
15186 
15187   OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front();
15188 
15189   if (FullClause) {
15190     if (!VerifyPositiveIntegerConstantInClause(
15191              LoopHelper.NumIterations, OMPC_full, /*StrictlyPositive=*/false,
15192              /*SuppressExprDiags=*/true)
15193              .isUsable()) {
15194       Diag(AStmt->getBeginLoc(), diag::err_omp_unroll_full_variable_trip_count);
15195       Diag(FullClause->getBeginLoc(), diag::note_omp_directive_here)
15196           << "#pragma omp unroll full";
15197       return StmtError();
15198     }
15199   }
15200 
15201   // The generated loop may only be passed to other loop-associated directive
15202   // when a partial clause is specified. Without the requirement it is
15203   // sufficient to generate loop unroll metadata at code-generation.
15204   if (NumGeneratedLoops == 0)
15205     return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
15206                                       NumGeneratedLoops, nullptr, nullptr);
15207 
15208   // Otherwise, we need to provide a de-sugared/transformed AST that can be
15209   // associated with another loop directive.
15210   //
15211   // The canonical loop analysis return by checkTransformableLoopNest assumes
15212   // the following structure to be the same loop without transformations or
15213   // directives applied: \code OriginalInits; LoopHelper.PreInits;
15214   // LoopHelper.Counters;
15215   // for (; IV < LoopHelper.NumIterations; ++IV) {
15216   //   LoopHelper.Updates;
15217   //   Body;
15218   // }
15219   // \endcode
15220   // where IV is a variable declared and initialized to 0 in LoopHelper.PreInits
15221   // and referenced by LoopHelper.IterationVarRef.
15222   //
15223   // The unrolling directive transforms this into the following loop:
15224   // \code
15225   // OriginalInits;         \
15226   // LoopHelper.PreInits;    > NewPreInits
15227   // LoopHelper.Counters;   /
15228   // for (auto UIV = 0; UIV < LoopHelper.NumIterations; UIV+=Factor) {
15229   //   #pragma clang loop unroll_count(Factor)
15230   //   for (IV = UIV; IV < UIV + Factor && UIV < LoopHelper.NumIterations; ++IV)
15231   //   {
15232   //     LoopHelper.Updates;
15233   //     Body;
15234   //   }
15235   // }
15236   // \endcode
15237   // where UIV is a new logical iteration counter. IV must be the same VarDecl
15238   // as the original LoopHelper.IterationVarRef because LoopHelper.Updates
15239   // references it. If the partially unrolled loop is associated with another
15240   // loop directive (like an OMPForDirective), it will use checkOpenMPLoop to
15241   // analyze this loop, i.e. the outer loop must fulfill the constraints of an
15242   // OpenMP canonical loop. The inner loop is not an associable canonical loop
15243   // and only exists to defer its unrolling to LLVM's LoopUnroll instead of
15244   // doing it in the frontend (by adding loop metadata). NewPreInits becomes a
15245   // property of the OMPLoopBasedDirective instead of statements in
15246   // CompoundStatement. This is to allow the loop to become a non-outermost loop
15247   // of a canonical loop nest where these PreInits are emitted before the
15248   // outermost directive.
15249 
15250   // Determine the PreInit declarations.
15251   SmallVector<Decl *, 4> PreInits;
15252   assert(OriginalInits.size() == 1 &&
15253          "Expecting a single-dimensional loop iteration space");
15254   for (auto &P : OriginalInits[0]) {
15255     if (auto *D = P.dyn_cast<Decl *>())
15256       PreInits.push_back(D);
15257     else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>()))
15258       PreInits.append(PI->decl_begin(), PI->decl_end());
15259   }
15260   if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
15261     PreInits.append(PI->decl_begin(), PI->decl_end());
15262   // Gather declarations for the data members used as counters.
15263   for (Expr *CounterRef : LoopHelper.Counters) {
15264     auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
15265     if (isa<OMPCapturedExprDecl>(CounterDecl))
15266       PreInits.push_back(CounterDecl);
15267   }
15268 
15269   auto *IterationVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
15270   QualType IVTy = IterationVarRef->getType();
15271   assert(LoopHelper.Counters.size() == 1 &&
15272          "Expecting a single-dimensional loop iteration space");
15273   auto *OrigVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
15274 
15275   // Determine the unroll factor.
15276   uint64_t Factor;
15277   SourceLocation FactorLoc;
15278   if (Expr *FactorVal = PartialClause->getFactor()) {
15279     Factor = FactorVal->getIntegerConstantExpr(Context)->getZExtValue();
15280     FactorLoc = FactorVal->getExprLoc();
15281   } else {
15282     // TODO: Use a better profitability model.
15283     Factor = 2;
15284   }
15285   assert(Factor > 0 && "Expected positive unroll factor");
15286   auto MakeFactorExpr = [this, Factor, IVTy, FactorLoc]() {
15287     return IntegerLiteral::Create(
15288         Context, llvm::APInt(Context.getIntWidth(IVTy), Factor), IVTy,
15289         FactorLoc);
15290   };
15291 
15292   // Iteration variable SourceLocations.
15293   SourceLocation OrigVarLoc = OrigVar->getExprLoc();
15294   SourceLocation OrigVarLocBegin = OrigVar->getBeginLoc();
15295   SourceLocation OrigVarLocEnd = OrigVar->getEndLoc();
15296 
15297   // Internal variable names.
15298   std::string OrigVarName = OrigVar->getNameInfo().getAsString();
15299   std::string OuterIVName = (Twine(".unrolled.iv.") + OrigVarName).str();
15300   std::string InnerIVName = (Twine(".unroll_inner.iv.") + OrigVarName).str();
15301   std::string InnerTripCountName =
15302       (Twine(".unroll_inner.tripcount.") + OrigVarName).str();
15303 
15304   // Create the iteration variable for the unrolled loop.
15305   VarDecl *OuterIVDecl =
15306       buildVarDecl(*this, {}, IVTy, OuterIVName, nullptr, OrigVar);
15307   auto MakeOuterRef = [this, OuterIVDecl, IVTy, OrigVarLoc]() {
15308     return buildDeclRefExpr(*this, OuterIVDecl, IVTy, OrigVarLoc);
15309   };
15310 
15311   // Iteration variable for the inner loop: Reuse the iteration variable created
15312   // by checkOpenMPLoop.
15313   auto *InnerIVDecl = cast<VarDecl>(IterationVarRef->getDecl());
15314   InnerIVDecl->setDeclName(&PP.getIdentifierTable().get(InnerIVName));
15315   auto MakeInnerRef = [this, InnerIVDecl, IVTy, OrigVarLoc]() {
15316     return buildDeclRefExpr(*this, InnerIVDecl, IVTy, OrigVarLoc);
15317   };
15318 
15319   // Make a copy of the NumIterations expression for each use: By the AST
15320   // constraints, every expression object in a DeclContext must be unique.
15321   CaptureVars CopyTransformer(*this);
15322   auto MakeNumIterations = [&CopyTransformer, &LoopHelper]() -> Expr * {
15323     return AssertSuccess(
15324         CopyTransformer.TransformExpr(LoopHelper.NumIterations));
15325   };
15326 
15327   // Inner For init-statement: auto .unroll_inner.iv = .unrolled.iv
15328   ExprResult LValueConv = DefaultLvalueConversion(MakeOuterRef());
15329   AddInitializerToDecl(InnerIVDecl, LValueConv.get(), /*DirectInit=*/false);
15330   StmtResult InnerInit = new (Context)
15331       DeclStmt(DeclGroupRef(InnerIVDecl), OrigVarLocBegin, OrigVarLocEnd);
15332   if (!InnerInit.isUsable())
15333     return StmtError();
15334 
15335   // Inner For cond-expression:
15336   // \code
15337   //   .unroll_inner.iv < .unrolled.iv + Factor &&
15338   //   .unroll_inner.iv < NumIterations
15339   // \endcode
15340   // This conjunction of two conditions allows ScalarEvolution to derive the
15341   // maximum trip count of the inner loop.
15342   ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
15343                                     BO_Add, MakeOuterRef(), MakeFactorExpr());
15344   if (!EndOfTile.isUsable())
15345     return StmtError();
15346   ExprResult InnerCond1 = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
15347                                      BO_LT, MakeInnerRef(), EndOfTile.get());
15348   if (!InnerCond1.isUsable())
15349     return StmtError();
15350   ExprResult InnerCond2 =
15351       BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeInnerRef(),
15352                  MakeNumIterations());
15353   if (!InnerCond2.isUsable())
15354     return StmtError();
15355   ExprResult InnerCond =
15356       BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LAnd,
15357                  InnerCond1.get(), InnerCond2.get());
15358   if (!InnerCond.isUsable())
15359     return StmtError();
15360 
15361   // Inner For incr-statement: ++.unroll_inner.iv
15362   ExprResult InnerIncr = BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(),
15363                                       UO_PreInc, MakeInnerRef());
15364   if (!InnerIncr.isUsable())
15365     return StmtError();
15366 
15367   // Inner For statement.
15368   SmallVector<Stmt *> InnerBodyStmts;
15369   InnerBodyStmts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
15370   InnerBodyStmts.push_back(Body);
15371   CompoundStmt *InnerBody =
15372       CompoundStmt::Create(Context, InnerBodyStmts, FPOptionsOverride(),
15373                            Body->getBeginLoc(), Body->getEndLoc());
15374   ForStmt *InnerFor = new (Context)
15375       ForStmt(Context, InnerInit.get(), InnerCond.get(), nullptr,
15376               InnerIncr.get(), InnerBody, LoopHelper.Init->getBeginLoc(),
15377               LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
15378 
15379   // Unroll metadata for the inner loop.
15380   // This needs to take into account the remainder portion of the unrolled loop,
15381   // hence `unroll(full)` does not apply here, even though the LoopUnroll pass
15382   // supports multiple loop exits. Instead, unroll using a factor equivalent to
15383   // the maximum trip count, which will also generate a remainder loop. Just
15384   // `unroll(enable)` (which could have been useful if the user has not
15385   // specified a concrete factor; even though the outer loop cannot be
15386   // influenced anymore, would avoid more code bloat than necessary) will refuse
15387   // the loop because "Won't unroll; remainder loop could not be generated when
15388   // assuming runtime trip count". Even if it did work, it must not choose a
15389   // larger unroll factor than the maximum loop length, or it would always just
15390   // execute the remainder loop.
15391   LoopHintAttr *UnrollHintAttr =
15392       LoopHintAttr::CreateImplicit(Context, LoopHintAttr::UnrollCount,
15393                                    LoopHintAttr::Numeric, MakeFactorExpr());
15394   AttributedStmt *InnerUnrolled =
15395       AttributedStmt::Create(Context, StartLoc, {UnrollHintAttr}, InnerFor);
15396 
15397   // Outer For init-statement: auto .unrolled.iv = 0
15398   AddInitializerToDecl(
15399       OuterIVDecl, ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
15400       /*DirectInit=*/false);
15401   StmtResult OuterInit = new (Context)
15402       DeclStmt(DeclGroupRef(OuterIVDecl), OrigVarLocBegin, OrigVarLocEnd);
15403   if (!OuterInit.isUsable())
15404     return StmtError();
15405 
15406   // Outer For cond-expression: .unrolled.iv < NumIterations
15407   ExprResult OuterConde =
15408       BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeOuterRef(),
15409                  MakeNumIterations());
15410   if (!OuterConde.isUsable())
15411     return StmtError();
15412 
15413   // Outer For incr-statement: .unrolled.iv += Factor
15414   ExprResult OuterIncr =
15415       BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(), BO_AddAssign,
15416                  MakeOuterRef(), MakeFactorExpr());
15417   if (!OuterIncr.isUsable())
15418     return StmtError();
15419 
15420   // Outer For statement.
15421   ForStmt *OuterFor = new (Context)
15422       ForStmt(Context, OuterInit.get(), OuterConde.get(), nullptr,
15423               OuterIncr.get(), InnerUnrolled, LoopHelper.Init->getBeginLoc(),
15424               LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
15425 
15426   return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
15427                                     NumGeneratedLoops, OuterFor,
15428                                     buildPreInits(Context, PreInits));
15429 }
15430 
15431 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
15432                                              SourceLocation StartLoc,
15433                                              SourceLocation LParenLoc,
15434                                              SourceLocation EndLoc) {
15435   OMPClause *Res = nullptr;
15436   switch (Kind) {
15437   case OMPC_final:
15438     Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
15439     break;
15440   case OMPC_num_threads:
15441     Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
15442     break;
15443   case OMPC_safelen:
15444     Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
15445     break;
15446   case OMPC_simdlen:
15447     Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
15448     break;
15449   case OMPC_allocator:
15450     Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
15451     break;
15452   case OMPC_collapse:
15453     Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
15454     break;
15455   case OMPC_ordered:
15456     Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
15457     break;
15458   case OMPC_num_teams:
15459     Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
15460     break;
15461   case OMPC_thread_limit:
15462     Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
15463     break;
15464   case OMPC_priority:
15465     Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
15466     break;
15467   case OMPC_hint:
15468     Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
15469     break;
15470   case OMPC_depobj:
15471     Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc);
15472     break;
15473   case OMPC_detach:
15474     Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc);
15475     break;
15476   case OMPC_novariants:
15477     Res = ActOnOpenMPNovariantsClause(Expr, StartLoc, LParenLoc, EndLoc);
15478     break;
15479   case OMPC_nocontext:
15480     Res = ActOnOpenMPNocontextClause(Expr, StartLoc, LParenLoc, EndLoc);
15481     break;
15482   case OMPC_filter:
15483     Res = ActOnOpenMPFilterClause(Expr, StartLoc, LParenLoc, EndLoc);
15484     break;
15485   case OMPC_partial:
15486     Res = ActOnOpenMPPartialClause(Expr, StartLoc, LParenLoc, EndLoc);
15487     break;
15488   case OMPC_message:
15489     Res = ActOnOpenMPMessageClause(Expr, StartLoc, LParenLoc, EndLoc);
15490     break;
15491   case OMPC_align:
15492     Res = ActOnOpenMPAlignClause(Expr, StartLoc, LParenLoc, EndLoc);
15493     break;
15494   case OMPC_ompx_dyn_cgroup_mem:
15495     Res = ActOnOpenMPXDynCGroupMemClause(Expr, StartLoc, LParenLoc, EndLoc);
15496     break;
15497   case OMPC_grainsize:
15498   case OMPC_num_tasks:
15499   case OMPC_device:
15500   case OMPC_if:
15501   case OMPC_default:
15502   case OMPC_proc_bind:
15503   case OMPC_schedule:
15504   case OMPC_private:
15505   case OMPC_firstprivate:
15506   case OMPC_lastprivate:
15507   case OMPC_shared:
15508   case OMPC_reduction:
15509   case OMPC_task_reduction:
15510   case OMPC_in_reduction:
15511   case OMPC_linear:
15512   case OMPC_aligned:
15513   case OMPC_copyin:
15514   case OMPC_copyprivate:
15515   case OMPC_nowait:
15516   case OMPC_untied:
15517   case OMPC_mergeable:
15518   case OMPC_threadprivate:
15519   case OMPC_sizes:
15520   case OMPC_allocate:
15521   case OMPC_flush:
15522   case OMPC_read:
15523   case OMPC_write:
15524   case OMPC_update:
15525   case OMPC_capture:
15526   case OMPC_compare:
15527   case OMPC_seq_cst:
15528   case OMPC_acq_rel:
15529   case OMPC_acquire:
15530   case OMPC_release:
15531   case OMPC_relaxed:
15532   case OMPC_depend:
15533   case OMPC_threads:
15534   case OMPC_simd:
15535   case OMPC_map:
15536   case OMPC_nogroup:
15537   case OMPC_dist_schedule:
15538   case OMPC_defaultmap:
15539   case OMPC_unknown:
15540   case OMPC_uniform:
15541   case OMPC_to:
15542   case OMPC_from:
15543   case OMPC_use_device_ptr:
15544   case OMPC_use_device_addr:
15545   case OMPC_is_device_ptr:
15546   case OMPC_unified_address:
15547   case OMPC_unified_shared_memory:
15548   case OMPC_reverse_offload:
15549   case OMPC_dynamic_allocators:
15550   case OMPC_atomic_default_mem_order:
15551   case OMPC_device_type:
15552   case OMPC_match:
15553   case OMPC_nontemporal:
15554   case OMPC_order:
15555   case OMPC_at:
15556   case OMPC_severity:
15557   case OMPC_destroy:
15558   case OMPC_inclusive:
15559   case OMPC_exclusive:
15560   case OMPC_uses_allocators:
15561   case OMPC_affinity:
15562   case OMPC_when:
15563   case OMPC_bind:
15564   default:
15565     llvm_unreachable("Clause is not allowed.");
15566   }
15567   return Res;
15568 }
15569 
15570 // An OpenMP directive such as 'target parallel' has two captured regions:
15571 // for the 'target' and 'parallel' respectively.  This function returns
15572 // the region in which to capture expressions associated with a clause.
15573 // A return value of OMPD_unknown signifies that the expression should not
15574 // be captured.
15575 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
15576     OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion,
15577     OpenMPDirectiveKind NameModifier = OMPD_unknown) {
15578   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
15579   switch (CKind) {
15580   case OMPC_if:
15581     switch (DKind) {
15582     case OMPD_target_parallel_for_simd:
15583       if (OpenMPVersion >= 50 &&
15584           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
15585         CaptureRegion = OMPD_parallel;
15586         break;
15587       }
15588       [[fallthrough]];
15589     case OMPD_target_parallel:
15590     case OMPD_target_parallel_for:
15591     case OMPD_target_parallel_loop:
15592       // If this clause applies to the nested 'parallel' region, capture within
15593       // the 'target' region, otherwise do not capture.
15594       if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
15595         CaptureRegion = OMPD_target;
15596       break;
15597     case OMPD_target_teams_distribute_parallel_for_simd:
15598       if (OpenMPVersion >= 50 &&
15599           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
15600         CaptureRegion = OMPD_parallel;
15601         break;
15602       }
15603       [[fallthrough]];
15604     case OMPD_target_teams_loop:
15605     case OMPD_target_teams_distribute_parallel_for:
15606       // If this clause applies to the nested 'parallel' region, capture within
15607       // the 'teams' region, otherwise do not capture.
15608       if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
15609         CaptureRegion = OMPD_teams;
15610       break;
15611     case OMPD_teams_distribute_parallel_for_simd:
15612       if (OpenMPVersion >= 50 &&
15613           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
15614         CaptureRegion = OMPD_parallel;
15615         break;
15616       }
15617       [[fallthrough]];
15618     case OMPD_teams_distribute_parallel_for:
15619       CaptureRegion = OMPD_teams;
15620       break;
15621     case OMPD_target_update:
15622     case OMPD_target_enter_data:
15623     case OMPD_target_exit_data:
15624       CaptureRegion = OMPD_task;
15625       break;
15626     case OMPD_parallel_masked_taskloop:
15627       if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
15628         CaptureRegion = OMPD_parallel;
15629       break;
15630     case OMPD_parallel_master_taskloop:
15631       if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
15632         CaptureRegion = OMPD_parallel;
15633       break;
15634     case OMPD_parallel_masked_taskloop_simd:
15635       if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
15636           NameModifier == OMPD_taskloop) {
15637         CaptureRegion = OMPD_parallel;
15638         break;
15639       }
15640       if (OpenMPVersion <= 45)
15641         break;
15642       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15643         CaptureRegion = OMPD_taskloop;
15644       break;
15645     case OMPD_parallel_master_taskloop_simd:
15646       if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
15647           NameModifier == OMPD_taskloop) {
15648         CaptureRegion = OMPD_parallel;
15649         break;
15650       }
15651       if (OpenMPVersion <= 45)
15652         break;
15653       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15654         CaptureRegion = OMPD_taskloop;
15655       break;
15656     case OMPD_parallel_for_simd:
15657       if (OpenMPVersion <= 45)
15658         break;
15659       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15660         CaptureRegion = OMPD_parallel;
15661       break;
15662     case OMPD_taskloop_simd:
15663     case OMPD_master_taskloop_simd:
15664     case OMPD_masked_taskloop_simd:
15665       if (OpenMPVersion <= 45)
15666         break;
15667       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15668         CaptureRegion = OMPD_taskloop;
15669       break;
15670     case OMPD_distribute_parallel_for_simd:
15671       if (OpenMPVersion <= 45)
15672         break;
15673       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
15674         CaptureRegion = OMPD_parallel;
15675       break;
15676     case OMPD_target_simd:
15677       if (OpenMPVersion >= 50 &&
15678           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
15679         CaptureRegion = OMPD_target;
15680       break;
15681     case OMPD_teams_distribute_simd:
15682     case OMPD_target_teams_distribute_simd:
15683       if (OpenMPVersion >= 50 &&
15684           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
15685         CaptureRegion = OMPD_teams;
15686       break;
15687     case OMPD_cancel:
15688     case OMPD_parallel:
15689     case OMPD_parallel_master:
15690     case OMPD_parallel_masked:
15691     case OMPD_parallel_sections:
15692     case OMPD_parallel_for:
15693     case OMPD_parallel_loop:
15694     case OMPD_target:
15695     case OMPD_target_teams:
15696     case OMPD_target_teams_distribute:
15697     case OMPD_distribute_parallel_for:
15698     case OMPD_task:
15699     case OMPD_taskloop:
15700     case OMPD_master_taskloop:
15701     case OMPD_masked_taskloop:
15702     case OMPD_target_data:
15703     case OMPD_simd:
15704     case OMPD_for_simd:
15705     case OMPD_distribute_simd:
15706       // Do not capture if-clause expressions.
15707       break;
15708     case OMPD_threadprivate:
15709     case OMPD_allocate:
15710     case OMPD_taskyield:
15711     case OMPD_error:
15712     case OMPD_barrier:
15713     case OMPD_taskwait:
15714     case OMPD_cancellation_point:
15715     case OMPD_flush:
15716     case OMPD_depobj:
15717     case OMPD_scan:
15718     case OMPD_declare_reduction:
15719     case OMPD_declare_mapper:
15720     case OMPD_declare_simd:
15721     case OMPD_declare_variant:
15722     case OMPD_begin_declare_variant:
15723     case OMPD_end_declare_variant:
15724     case OMPD_declare_target:
15725     case OMPD_end_declare_target:
15726     case OMPD_loop:
15727     case OMPD_teams_loop:
15728     case OMPD_teams:
15729     case OMPD_tile:
15730     case OMPD_unroll:
15731     case OMPD_for:
15732     case OMPD_sections:
15733     case OMPD_section:
15734     case OMPD_single:
15735     case OMPD_master:
15736     case OMPD_masked:
15737     case OMPD_critical:
15738     case OMPD_taskgroup:
15739     case OMPD_distribute:
15740     case OMPD_ordered:
15741     case OMPD_atomic:
15742     case OMPD_teams_distribute:
15743     case OMPD_requires:
15744     case OMPD_metadirective:
15745       llvm_unreachable("Unexpected OpenMP directive with if-clause");
15746     case OMPD_unknown:
15747     default:
15748       llvm_unreachable("Unknown OpenMP directive");
15749     }
15750     break;
15751   case OMPC_num_threads:
15752     switch (DKind) {
15753     case OMPD_target_parallel:
15754     case OMPD_target_parallel_for:
15755     case OMPD_target_parallel_for_simd:
15756     case OMPD_target_parallel_loop:
15757       CaptureRegion = OMPD_target;
15758       break;
15759     case OMPD_teams_distribute_parallel_for:
15760     case OMPD_teams_distribute_parallel_for_simd:
15761     case OMPD_target_teams_distribute_parallel_for:
15762     case OMPD_target_teams_distribute_parallel_for_simd:
15763       CaptureRegion = OMPD_teams;
15764       break;
15765     case OMPD_parallel:
15766     case OMPD_parallel_master:
15767     case OMPD_parallel_masked:
15768     case OMPD_parallel_sections:
15769     case OMPD_parallel_for:
15770     case OMPD_parallel_for_simd:
15771     case OMPD_parallel_loop:
15772     case OMPD_distribute_parallel_for:
15773     case OMPD_distribute_parallel_for_simd:
15774     case OMPD_parallel_master_taskloop:
15775     case OMPD_parallel_masked_taskloop:
15776     case OMPD_parallel_master_taskloop_simd:
15777     case OMPD_parallel_masked_taskloop_simd:
15778       // Do not capture num_threads-clause expressions.
15779       break;
15780     case OMPD_target_data:
15781     case OMPD_target_enter_data:
15782     case OMPD_target_exit_data:
15783     case OMPD_target_update:
15784     case OMPD_target:
15785     case OMPD_target_simd:
15786     case OMPD_target_teams:
15787     case OMPD_target_teams_distribute:
15788     case OMPD_target_teams_distribute_simd:
15789     case OMPD_cancel:
15790     case OMPD_task:
15791     case OMPD_taskloop:
15792     case OMPD_taskloop_simd:
15793     case OMPD_master_taskloop:
15794     case OMPD_masked_taskloop:
15795     case OMPD_master_taskloop_simd:
15796     case OMPD_masked_taskloop_simd:
15797     case OMPD_threadprivate:
15798     case OMPD_allocate:
15799     case OMPD_taskyield:
15800     case OMPD_error:
15801     case OMPD_barrier:
15802     case OMPD_taskwait:
15803     case OMPD_cancellation_point:
15804     case OMPD_flush:
15805     case OMPD_depobj:
15806     case OMPD_scan:
15807     case OMPD_declare_reduction:
15808     case OMPD_declare_mapper:
15809     case OMPD_declare_simd:
15810     case OMPD_declare_variant:
15811     case OMPD_begin_declare_variant:
15812     case OMPD_end_declare_variant:
15813     case OMPD_declare_target:
15814     case OMPD_end_declare_target:
15815     case OMPD_loop:
15816     case OMPD_teams_loop:
15817     case OMPD_target_teams_loop:
15818     case OMPD_teams:
15819     case OMPD_simd:
15820     case OMPD_tile:
15821     case OMPD_unroll:
15822     case OMPD_for:
15823     case OMPD_for_simd:
15824     case OMPD_sections:
15825     case OMPD_section:
15826     case OMPD_single:
15827     case OMPD_master:
15828     case OMPD_masked:
15829     case OMPD_critical:
15830     case OMPD_taskgroup:
15831     case OMPD_distribute:
15832     case OMPD_ordered:
15833     case OMPD_atomic:
15834     case OMPD_distribute_simd:
15835     case OMPD_teams_distribute:
15836     case OMPD_teams_distribute_simd:
15837     case OMPD_requires:
15838     case OMPD_metadirective:
15839       llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
15840     case OMPD_unknown:
15841     default:
15842       llvm_unreachable("Unknown OpenMP directive");
15843     }
15844     break;
15845   case OMPC_num_teams:
15846     switch (DKind) {
15847     case OMPD_target_teams:
15848     case OMPD_target_teams_distribute:
15849     case OMPD_target_teams_distribute_simd:
15850     case OMPD_target_teams_distribute_parallel_for:
15851     case OMPD_target_teams_distribute_parallel_for_simd:
15852     case OMPD_target_teams_loop:
15853       CaptureRegion = OMPD_target;
15854       break;
15855     case OMPD_teams_distribute_parallel_for:
15856     case OMPD_teams_distribute_parallel_for_simd:
15857     case OMPD_teams:
15858     case OMPD_teams_distribute:
15859     case OMPD_teams_distribute_simd:
15860     case OMPD_teams_loop:
15861       // Do not capture num_teams-clause expressions.
15862       break;
15863     case OMPD_distribute_parallel_for:
15864     case OMPD_distribute_parallel_for_simd:
15865     case OMPD_task:
15866     case OMPD_taskloop:
15867     case OMPD_taskloop_simd:
15868     case OMPD_master_taskloop:
15869     case OMPD_masked_taskloop:
15870     case OMPD_master_taskloop_simd:
15871     case OMPD_masked_taskloop_simd:
15872     case OMPD_parallel_master_taskloop:
15873     case OMPD_parallel_masked_taskloop:
15874     case OMPD_parallel_master_taskloop_simd:
15875     case OMPD_parallel_masked_taskloop_simd:
15876     case OMPD_target_data:
15877     case OMPD_target_enter_data:
15878     case OMPD_target_exit_data:
15879     case OMPD_target_update:
15880     case OMPD_cancel:
15881     case OMPD_parallel:
15882     case OMPD_parallel_master:
15883     case OMPD_parallel_masked:
15884     case OMPD_parallel_sections:
15885     case OMPD_parallel_for:
15886     case OMPD_parallel_for_simd:
15887     case OMPD_parallel_loop:
15888     case OMPD_target:
15889     case OMPD_target_simd:
15890     case OMPD_target_parallel:
15891     case OMPD_target_parallel_for:
15892     case OMPD_target_parallel_for_simd:
15893     case OMPD_target_parallel_loop:
15894     case OMPD_threadprivate:
15895     case OMPD_allocate:
15896     case OMPD_taskyield:
15897     case OMPD_error:
15898     case OMPD_barrier:
15899     case OMPD_taskwait:
15900     case OMPD_cancellation_point:
15901     case OMPD_flush:
15902     case OMPD_depobj:
15903     case OMPD_scan:
15904     case OMPD_declare_reduction:
15905     case OMPD_declare_mapper:
15906     case OMPD_declare_simd:
15907     case OMPD_declare_variant:
15908     case OMPD_begin_declare_variant:
15909     case OMPD_end_declare_variant:
15910     case OMPD_declare_target:
15911     case OMPD_end_declare_target:
15912     case OMPD_loop:
15913     case OMPD_simd:
15914     case OMPD_tile:
15915     case OMPD_unroll:
15916     case OMPD_for:
15917     case OMPD_for_simd:
15918     case OMPD_sections:
15919     case OMPD_section:
15920     case OMPD_single:
15921     case OMPD_master:
15922     case OMPD_masked:
15923     case OMPD_critical:
15924     case OMPD_taskgroup:
15925     case OMPD_distribute:
15926     case OMPD_ordered:
15927     case OMPD_atomic:
15928     case OMPD_distribute_simd:
15929     case OMPD_requires:
15930     case OMPD_metadirective:
15931       llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
15932     case OMPD_unknown:
15933     default:
15934       llvm_unreachable("Unknown OpenMP directive");
15935     }
15936     break;
15937   case OMPC_thread_limit:
15938     switch (DKind) {
15939     case OMPD_target:
15940     case OMPD_target_teams:
15941     case OMPD_target_teams_distribute:
15942     case OMPD_target_teams_distribute_simd:
15943     case OMPD_target_teams_distribute_parallel_for:
15944     case OMPD_target_teams_distribute_parallel_for_simd:
15945     case OMPD_target_teams_loop:
15946     case OMPD_target_simd:
15947     case OMPD_target_parallel:
15948     case OMPD_target_parallel_for:
15949     case OMPD_target_parallel_for_simd:
15950     case OMPD_target_parallel_loop:
15951       CaptureRegion = OMPD_target;
15952       break;
15953     case OMPD_teams_distribute_parallel_for:
15954     case OMPD_teams_distribute_parallel_for_simd:
15955     case OMPD_teams:
15956     case OMPD_teams_distribute:
15957     case OMPD_teams_distribute_simd:
15958     case OMPD_teams_loop:
15959       // Do not capture thread_limit-clause expressions.
15960       break;
15961     case OMPD_distribute_parallel_for:
15962     case OMPD_distribute_parallel_for_simd:
15963     case OMPD_task:
15964     case OMPD_taskloop:
15965     case OMPD_taskloop_simd:
15966     case OMPD_master_taskloop:
15967     case OMPD_masked_taskloop:
15968     case OMPD_master_taskloop_simd:
15969     case OMPD_masked_taskloop_simd:
15970     case OMPD_parallel_master_taskloop:
15971     case OMPD_parallel_masked_taskloop:
15972     case OMPD_parallel_master_taskloop_simd:
15973     case OMPD_parallel_masked_taskloop_simd:
15974     case OMPD_target_data:
15975     case OMPD_target_enter_data:
15976     case OMPD_target_exit_data:
15977     case OMPD_target_update:
15978     case OMPD_cancel:
15979     case OMPD_parallel:
15980     case OMPD_parallel_master:
15981     case OMPD_parallel_masked:
15982     case OMPD_parallel_sections:
15983     case OMPD_parallel_for:
15984     case OMPD_parallel_for_simd:
15985     case OMPD_parallel_loop:
15986     case OMPD_threadprivate:
15987     case OMPD_allocate:
15988     case OMPD_taskyield:
15989     case OMPD_error:
15990     case OMPD_barrier:
15991     case OMPD_taskwait:
15992     case OMPD_cancellation_point:
15993     case OMPD_flush:
15994     case OMPD_depobj:
15995     case OMPD_scan:
15996     case OMPD_declare_reduction:
15997     case OMPD_declare_mapper:
15998     case OMPD_declare_simd:
15999     case OMPD_declare_variant:
16000     case OMPD_begin_declare_variant:
16001     case OMPD_end_declare_variant:
16002     case OMPD_declare_target:
16003     case OMPD_end_declare_target:
16004     case OMPD_loop:
16005     case OMPD_simd:
16006     case OMPD_tile:
16007     case OMPD_unroll:
16008     case OMPD_for:
16009     case OMPD_for_simd:
16010     case OMPD_sections:
16011     case OMPD_section:
16012     case OMPD_single:
16013     case OMPD_master:
16014     case OMPD_masked:
16015     case OMPD_critical:
16016     case OMPD_taskgroup:
16017     case OMPD_distribute:
16018     case OMPD_ordered:
16019     case OMPD_atomic:
16020     case OMPD_distribute_simd:
16021     case OMPD_requires:
16022     case OMPD_metadirective:
16023       llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
16024     case OMPD_unknown:
16025     default:
16026       llvm_unreachable("Unknown OpenMP directive");
16027     }
16028     break;
16029   case OMPC_schedule:
16030     switch (DKind) {
16031     case OMPD_parallel_for:
16032     case OMPD_parallel_for_simd:
16033     case OMPD_distribute_parallel_for:
16034     case OMPD_distribute_parallel_for_simd:
16035     case OMPD_teams_distribute_parallel_for:
16036     case OMPD_teams_distribute_parallel_for_simd:
16037     case OMPD_target_parallel_for:
16038     case OMPD_target_parallel_for_simd:
16039     case OMPD_target_teams_distribute_parallel_for:
16040     case OMPD_target_teams_distribute_parallel_for_simd:
16041       CaptureRegion = OMPD_parallel;
16042       break;
16043     case OMPD_for:
16044     case OMPD_for_simd:
16045       // Do not capture schedule-clause expressions.
16046       break;
16047     case OMPD_task:
16048     case OMPD_taskloop:
16049     case OMPD_taskloop_simd:
16050     case OMPD_master_taskloop:
16051     case OMPD_masked_taskloop:
16052     case OMPD_master_taskloop_simd:
16053     case OMPD_masked_taskloop_simd:
16054     case OMPD_parallel_master_taskloop:
16055     case OMPD_parallel_masked_taskloop:
16056     case OMPD_parallel_master_taskloop_simd:
16057     case OMPD_parallel_masked_taskloop_simd:
16058     case OMPD_target_data:
16059     case OMPD_target_enter_data:
16060     case OMPD_target_exit_data:
16061     case OMPD_target_update:
16062     case OMPD_teams:
16063     case OMPD_teams_distribute:
16064     case OMPD_teams_distribute_simd:
16065     case OMPD_target_teams_distribute:
16066     case OMPD_target_teams_distribute_simd:
16067     case OMPD_target:
16068     case OMPD_target_simd:
16069     case OMPD_target_parallel:
16070     case OMPD_cancel:
16071     case OMPD_parallel:
16072     case OMPD_parallel_master:
16073     case OMPD_parallel_masked:
16074     case OMPD_parallel_sections:
16075     case OMPD_threadprivate:
16076     case OMPD_allocate:
16077     case OMPD_taskyield:
16078     case OMPD_error:
16079     case OMPD_barrier:
16080     case OMPD_taskwait:
16081     case OMPD_cancellation_point:
16082     case OMPD_flush:
16083     case OMPD_depobj:
16084     case OMPD_scan:
16085     case OMPD_declare_reduction:
16086     case OMPD_declare_mapper:
16087     case OMPD_declare_simd:
16088     case OMPD_declare_variant:
16089     case OMPD_begin_declare_variant:
16090     case OMPD_end_declare_variant:
16091     case OMPD_declare_target:
16092     case OMPD_end_declare_target:
16093     case OMPD_loop:
16094     case OMPD_teams_loop:
16095     case OMPD_target_teams_loop:
16096     case OMPD_parallel_loop:
16097     case OMPD_target_parallel_loop:
16098     case OMPD_simd:
16099     case OMPD_tile:
16100     case OMPD_unroll:
16101     case OMPD_sections:
16102     case OMPD_section:
16103     case OMPD_single:
16104     case OMPD_master:
16105     case OMPD_masked:
16106     case OMPD_critical:
16107     case OMPD_taskgroup:
16108     case OMPD_distribute:
16109     case OMPD_ordered:
16110     case OMPD_atomic:
16111     case OMPD_distribute_simd:
16112     case OMPD_target_teams:
16113     case OMPD_requires:
16114     case OMPD_metadirective:
16115       llvm_unreachable("Unexpected OpenMP directive with schedule clause");
16116     case OMPD_unknown:
16117     default:
16118       llvm_unreachable("Unknown OpenMP directive");
16119     }
16120     break;
16121   case OMPC_dist_schedule:
16122     switch (DKind) {
16123     case OMPD_teams_distribute_parallel_for:
16124     case OMPD_teams_distribute_parallel_for_simd:
16125     case OMPD_teams_distribute:
16126     case OMPD_teams_distribute_simd:
16127     case OMPD_target_teams_distribute_parallel_for:
16128     case OMPD_target_teams_distribute_parallel_for_simd:
16129     case OMPD_target_teams_distribute:
16130     case OMPD_target_teams_distribute_simd:
16131       CaptureRegion = OMPD_teams;
16132       break;
16133     case OMPD_distribute_parallel_for:
16134     case OMPD_distribute_parallel_for_simd:
16135     case OMPD_distribute:
16136     case OMPD_distribute_simd:
16137       // Do not capture dist_schedule-clause expressions.
16138       break;
16139     case OMPD_parallel_for:
16140     case OMPD_parallel_for_simd:
16141     case OMPD_target_parallel_for_simd:
16142     case OMPD_target_parallel_for:
16143     case OMPD_task:
16144     case OMPD_taskloop:
16145     case OMPD_taskloop_simd:
16146     case OMPD_master_taskloop:
16147     case OMPD_masked_taskloop:
16148     case OMPD_master_taskloop_simd:
16149     case OMPD_masked_taskloop_simd:
16150     case OMPD_parallel_master_taskloop:
16151     case OMPD_parallel_masked_taskloop:
16152     case OMPD_parallel_master_taskloop_simd:
16153     case OMPD_parallel_masked_taskloop_simd:
16154     case OMPD_target_data:
16155     case OMPD_target_enter_data:
16156     case OMPD_target_exit_data:
16157     case OMPD_target_update:
16158     case OMPD_teams:
16159     case OMPD_target:
16160     case OMPD_target_simd:
16161     case OMPD_target_parallel:
16162     case OMPD_cancel:
16163     case OMPD_parallel:
16164     case OMPD_parallel_master:
16165     case OMPD_parallel_masked:
16166     case OMPD_parallel_sections:
16167     case OMPD_threadprivate:
16168     case OMPD_allocate:
16169     case OMPD_taskyield:
16170     case OMPD_error:
16171     case OMPD_barrier:
16172     case OMPD_taskwait:
16173     case OMPD_cancellation_point:
16174     case OMPD_flush:
16175     case OMPD_depobj:
16176     case OMPD_scan:
16177     case OMPD_declare_reduction:
16178     case OMPD_declare_mapper:
16179     case OMPD_declare_simd:
16180     case OMPD_declare_variant:
16181     case OMPD_begin_declare_variant:
16182     case OMPD_end_declare_variant:
16183     case OMPD_declare_target:
16184     case OMPD_end_declare_target:
16185     case OMPD_loop:
16186     case OMPD_teams_loop:
16187     case OMPD_target_teams_loop:
16188     case OMPD_parallel_loop:
16189     case OMPD_target_parallel_loop:
16190     case OMPD_simd:
16191     case OMPD_tile:
16192     case OMPD_unroll:
16193     case OMPD_for:
16194     case OMPD_for_simd:
16195     case OMPD_sections:
16196     case OMPD_section:
16197     case OMPD_single:
16198     case OMPD_master:
16199     case OMPD_masked:
16200     case OMPD_critical:
16201     case OMPD_taskgroup:
16202     case OMPD_ordered:
16203     case OMPD_atomic:
16204     case OMPD_target_teams:
16205     case OMPD_requires:
16206     case OMPD_metadirective:
16207       llvm_unreachable("Unexpected OpenMP directive with dist_schedule clause");
16208     case OMPD_unknown:
16209     default:
16210       llvm_unreachable("Unknown OpenMP directive");
16211     }
16212     break;
16213   case OMPC_ompx_dyn_cgroup_mem:
16214     switch (DKind) {
16215     case OMPD_target:
16216     case OMPD_target_simd:
16217     case OMPD_target_teams:
16218     case OMPD_target_parallel:
16219     case OMPD_target_teams_distribute:
16220     case OMPD_target_teams_distribute_simd:
16221     case OMPD_target_parallel_for:
16222     case OMPD_target_parallel_for_simd:
16223     case OMPD_target_parallel_loop:
16224     case OMPD_target_teams_distribute_parallel_for:
16225     case OMPD_target_teams_distribute_parallel_for_simd:
16226     case OMPD_target_teams_loop:
16227       CaptureRegion = OMPD_target;
16228       break;
16229     default:
16230       llvm_unreachable("Unknown OpenMP directive");
16231     }
16232     break;
16233   case OMPC_device:
16234     switch (DKind) {
16235     case OMPD_target_update:
16236     case OMPD_target_enter_data:
16237     case OMPD_target_exit_data:
16238     case OMPD_target:
16239     case OMPD_target_simd:
16240     case OMPD_target_teams:
16241     case OMPD_target_parallel:
16242     case OMPD_target_teams_distribute:
16243     case OMPD_target_teams_distribute_simd:
16244     case OMPD_target_parallel_for:
16245     case OMPD_target_parallel_for_simd:
16246     case OMPD_target_parallel_loop:
16247     case OMPD_target_teams_distribute_parallel_for:
16248     case OMPD_target_teams_distribute_parallel_for_simd:
16249     case OMPD_target_teams_loop:
16250     case OMPD_dispatch:
16251       CaptureRegion = OMPD_task;
16252       break;
16253     case OMPD_target_data:
16254     case OMPD_interop:
16255       // Do not capture device-clause expressions.
16256       break;
16257     case OMPD_teams_distribute_parallel_for:
16258     case OMPD_teams_distribute_parallel_for_simd:
16259     case OMPD_teams:
16260     case OMPD_teams_distribute:
16261     case OMPD_teams_distribute_simd:
16262     case OMPD_distribute_parallel_for:
16263     case OMPD_distribute_parallel_for_simd:
16264     case OMPD_task:
16265     case OMPD_taskloop:
16266     case OMPD_taskloop_simd:
16267     case OMPD_master_taskloop:
16268     case OMPD_masked_taskloop:
16269     case OMPD_master_taskloop_simd:
16270     case OMPD_masked_taskloop_simd:
16271     case OMPD_parallel_master_taskloop:
16272     case OMPD_parallel_masked_taskloop:
16273     case OMPD_parallel_master_taskloop_simd:
16274     case OMPD_parallel_masked_taskloop_simd:
16275     case OMPD_cancel:
16276     case OMPD_parallel:
16277     case OMPD_parallel_master:
16278     case OMPD_parallel_masked:
16279     case OMPD_parallel_sections:
16280     case OMPD_parallel_for:
16281     case OMPD_parallel_for_simd:
16282     case OMPD_threadprivate:
16283     case OMPD_allocate:
16284     case OMPD_taskyield:
16285     case OMPD_error:
16286     case OMPD_barrier:
16287     case OMPD_taskwait:
16288     case OMPD_cancellation_point:
16289     case OMPD_flush:
16290     case OMPD_depobj:
16291     case OMPD_scan:
16292     case OMPD_declare_reduction:
16293     case OMPD_declare_mapper:
16294     case OMPD_declare_simd:
16295     case OMPD_declare_variant:
16296     case OMPD_begin_declare_variant:
16297     case OMPD_end_declare_variant:
16298     case OMPD_declare_target:
16299     case OMPD_end_declare_target:
16300     case OMPD_loop:
16301     case OMPD_teams_loop:
16302     case OMPD_parallel_loop:
16303     case OMPD_simd:
16304     case OMPD_tile:
16305     case OMPD_unroll:
16306     case OMPD_for:
16307     case OMPD_for_simd:
16308     case OMPD_sections:
16309     case OMPD_section:
16310     case OMPD_single:
16311     case OMPD_master:
16312     case OMPD_masked:
16313     case OMPD_critical:
16314     case OMPD_taskgroup:
16315     case OMPD_distribute:
16316     case OMPD_ordered:
16317     case OMPD_atomic:
16318     case OMPD_distribute_simd:
16319     case OMPD_requires:
16320     case OMPD_metadirective:
16321       llvm_unreachable("Unexpected OpenMP directive with device-clause");
16322     case OMPD_unknown:
16323     default:
16324       llvm_unreachable("Unknown OpenMP directive");
16325     }
16326     break;
16327   case OMPC_grainsize:
16328   case OMPC_num_tasks:
16329   case OMPC_final:
16330   case OMPC_priority:
16331     switch (DKind) {
16332     case OMPD_task:
16333     case OMPD_taskloop:
16334     case OMPD_taskloop_simd:
16335     case OMPD_master_taskloop:
16336     case OMPD_masked_taskloop:
16337     case OMPD_master_taskloop_simd:
16338     case OMPD_masked_taskloop_simd:
16339       break;
16340     case OMPD_parallel_masked_taskloop:
16341     case OMPD_parallel_masked_taskloop_simd:
16342     case OMPD_parallel_master_taskloop:
16343     case OMPD_parallel_master_taskloop_simd:
16344       CaptureRegion = OMPD_parallel;
16345       break;
16346     case OMPD_target_update:
16347     case OMPD_target_enter_data:
16348     case OMPD_target_exit_data:
16349     case OMPD_target:
16350     case OMPD_target_simd:
16351     case OMPD_target_teams:
16352     case OMPD_target_parallel:
16353     case OMPD_target_teams_distribute:
16354     case OMPD_target_teams_distribute_simd:
16355     case OMPD_target_parallel_for:
16356     case OMPD_target_parallel_for_simd:
16357     case OMPD_target_teams_distribute_parallel_for:
16358     case OMPD_target_teams_distribute_parallel_for_simd:
16359     case OMPD_target_data:
16360     case OMPD_teams_distribute_parallel_for:
16361     case OMPD_teams_distribute_parallel_for_simd:
16362     case OMPD_teams:
16363     case OMPD_teams_distribute:
16364     case OMPD_teams_distribute_simd:
16365     case OMPD_distribute_parallel_for:
16366     case OMPD_distribute_parallel_for_simd:
16367     case OMPD_cancel:
16368     case OMPD_parallel:
16369     case OMPD_parallel_master:
16370     case OMPD_parallel_masked:
16371     case OMPD_parallel_sections:
16372     case OMPD_parallel_for:
16373     case OMPD_parallel_for_simd:
16374     case OMPD_threadprivate:
16375     case OMPD_allocate:
16376     case OMPD_taskyield:
16377     case OMPD_error:
16378     case OMPD_barrier:
16379     case OMPD_taskwait:
16380     case OMPD_cancellation_point:
16381     case OMPD_flush:
16382     case OMPD_depobj:
16383     case OMPD_scan:
16384     case OMPD_declare_reduction:
16385     case OMPD_declare_mapper:
16386     case OMPD_declare_simd:
16387     case OMPD_declare_variant:
16388     case OMPD_begin_declare_variant:
16389     case OMPD_end_declare_variant:
16390     case OMPD_declare_target:
16391     case OMPD_end_declare_target:
16392     case OMPD_loop:
16393     case OMPD_teams_loop:
16394     case OMPD_target_teams_loop:
16395     case OMPD_parallel_loop:
16396     case OMPD_target_parallel_loop:
16397     case OMPD_simd:
16398     case OMPD_tile:
16399     case OMPD_unroll:
16400     case OMPD_for:
16401     case OMPD_for_simd:
16402     case OMPD_sections:
16403     case OMPD_section:
16404     case OMPD_single:
16405     case OMPD_master:
16406     case OMPD_masked:
16407     case OMPD_critical:
16408     case OMPD_taskgroup:
16409     case OMPD_distribute:
16410     case OMPD_ordered:
16411     case OMPD_atomic:
16412     case OMPD_distribute_simd:
16413     case OMPD_requires:
16414     case OMPD_metadirective:
16415       llvm_unreachable("Unexpected OpenMP directive with grainsize-clause");
16416     case OMPD_unknown:
16417     default:
16418       llvm_unreachable("Unknown OpenMP directive");
16419     }
16420     break;
16421   case OMPC_novariants:
16422   case OMPC_nocontext:
16423     switch (DKind) {
16424     case OMPD_dispatch:
16425       CaptureRegion = OMPD_task;
16426       break;
16427     default:
16428       llvm_unreachable("Unexpected OpenMP directive");
16429     }
16430     break;
16431   case OMPC_filter:
16432     // Do not capture filter-clause expressions.
16433     break;
16434   case OMPC_when:
16435     if (DKind == OMPD_metadirective) {
16436       CaptureRegion = OMPD_metadirective;
16437     } else if (DKind == OMPD_unknown) {
16438       llvm_unreachable("Unknown OpenMP directive");
16439     } else {
16440       llvm_unreachable("Unexpected OpenMP directive with when clause");
16441     }
16442     break;
16443   case OMPC_firstprivate:
16444   case OMPC_lastprivate:
16445   case OMPC_reduction:
16446   case OMPC_task_reduction:
16447   case OMPC_in_reduction:
16448   case OMPC_linear:
16449   case OMPC_default:
16450   case OMPC_proc_bind:
16451   case OMPC_safelen:
16452   case OMPC_simdlen:
16453   case OMPC_sizes:
16454   case OMPC_allocator:
16455   case OMPC_collapse:
16456   case OMPC_private:
16457   case OMPC_shared:
16458   case OMPC_aligned:
16459   case OMPC_copyin:
16460   case OMPC_copyprivate:
16461   case OMPC_ordered:
16462   case OMPC_nowait:
16463   case OMPC_untied:
16464   case OMPC_mergeable:
16465   case OMPC_threadprivate:
16466   case OMPC_allocate:
16467   case OMPC_flush:
16468   case OMPC_depobj:
16469   case OMPC_read:
16470   case OMPC_write:
16471   case OMPC_update:
16472   case OMPC_capture:
16473   case OMPC_compare:
16474   case OMPC_seq_cst:
16475   case OMPC_acq_rel:
16476   case OMPC_acquire:
16477   case OMPC_release:
16478   case OMPC_relaxed:
16479   case OMPC_depend:
16480   case OMPC_threads:
16481   case OMPC_simd:
16482   case OMPC_map:
16483   case OMPC_nogroup:
16484   case OMPC_hint:
16485   case OMPC_defaultmap:
16486   case OMPC_unknown:
16487   case OMPC_uniform:
16488   case OMPC_to:
16489   case OMPC_from:
16490   case OMPC_use_device_ptr:
16491   case OMPC_use_device_addr:
16492   case OMPC_is_device_ptr:
16493   case OMPC_unified_address:
16494   case OMPC_unified_shared_memory:
16495   case OMPC_reverse_offload:
16496   case OMPC_dynamic_allocators:
16497   case OMPC_atomic_default_mem_order:
16498   case OMPC_device_type:
16499   case OMPC_match:
16500   case OMPC_nontemporal:
16501   case OMPC_order:
16502   case OMPC_at:
16503   case OMPC_severity:
16504   case OMPC_message:
16505   case OMPC_destroy:
16506   case OMPC_detach:
16507   case OMPC_inclusive:
16508   case OMPC_exclusive:
16509   case OMPC_uses_allocators:
16510   case OMPC_affinity:
16511   case OMPC_bind:
16512   default:
16513     llvm_unreachable("Unexpected OpenMP clause.");
16514   }
16515   return CaptureRegion;
16516 }
16517 
16518 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
16519                                      Expr *Condition, SourceLocation StartLoc,
16520                                      SourceLocation LParenLoc,
16521                                      SourceLocation NameModifierLoc,
16522                                      SourceLocation ColonLoc,
16523                                      SourceLocation EndLoc) {
16524   Expr *ValExpr = Condition;
16525   Stmt *HelperValStmt = nullptr;
16526   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
16527   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
16528       !Condition->isInstantiationDependent() &&
16529       !Condition->containsUnexpandedParameterPack()) {
16530     ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
16531     if (Val.isInvalid())
16532       return nullptr;
16533 
16534     ValExpr = Val.get();
16535 
16536     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16537     CaptureRegion = getOpenMPCaptureRegionForClause(
16538         DKind, OMPC_if, LangOpts.OpenMP, NameModifier);
16539     if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16540       ValExpr = MakeFullExpr(ValExpr).get();
16541       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16542       ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16543       HelperValStmt = buildPreInits(Context, Captures);
16544     }
16545   }
16546 
16547   return new (Context)
16548       OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
16549                   LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
16550 }
16551 
16552 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
16553                                         SourceLocation StartLoc,
16554                                         SourceLocation LParenLoc,
16555                                         SourceLocation EndLoc) {
16556   Expr *ValExpr = Condition;
16557   Stmt *HelperValStmt = nullptr;
16558   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
16559   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
16560       !Condition->isInstantiationDependent() &&
16561       !Condition->containsUnexpandedParameterPack()) {
16562     ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
16563     if (Val.isInvalid())
16564       return nullptr;
16565 
16566     ValExpr = MakeFullExpr(Val.get()).get();
16567 
16568     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16569     CaptureRegion =
16570         getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP);
16571     if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16572       ValExpr = MakeFullExpr(ValExpr).get();
16573       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16574       ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16575       HelperValStmt = buildPreInits(Context, Captures);
16576     }
16577   }
16578 
16579   return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion,
16580                                       StartLoc, LParenLoc, EndLoc);
16581 }
16582 
16583 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
16584                                                         Expr *Op) {
16585   if (!Op)
16586     return ExprError();
16587 
16588   class IntConvertDiagnoser : public ICEConvertDiagnoser {
16589   public:
16590     IntConvertDiagnoser()
16591         : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
16592     SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
16593                                          QualType T) override {
16594       return S.Diag(Loc, diag::err_omp_not_integral) << T;
16595     }
16596     SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
16597                                              QualType T) override {
16598       return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
16599     }
16600     SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
16601                                                QualType T,
16602                                                QualType ConvTy) override {
16603       return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
16604     }
16605     SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
16606                                            QualType ConvTy) override {
16607       return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
16608              << ConvTy->isEnumeralType() << ConvTy;
16609     }
16610     SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
16611                                             QualType T) override {
16612       return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
16613     }
16614     SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
16615                                         QualType ConvTy) override {
16616       return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
16617              << ConvTy->isEnumeralType() << ConvTy;
16618     }
16619     SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
16620                                              QualType) override {
16621       llvm_unreachable("conversion functions are permitted");
16622     }
16623   } ConvertDiagnoser;
16624   return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
16625 }
16626 
16627 static bool
16628 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind,
16629                           bool StrictlyPositive, bool BuildCapture = false,
16630                           OpenMPDirectiveKind DKind = OMPD_unknown,
16631                           OpenMPDirectiveKind *CaptureRegion = nullptr,
16632                           Stmt **HelperValStmt = nullptr) {
16633   if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
16634       !ValExpr->isInstantiationDependent()) {
16635     SourceLocation Loc = ValExpr->getExprLoc();
16636     ExprResult Value =
16637         SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
16638     if (Value.isInvalid())
16639       return false;
16640 
16641     ValExpr = Value.get();
16642     // The expression must evaluate to a non-negative integer value.
16643     if (std::optional<llvm::APSInt> Result =
16644             ValExpr->getIntegerConstantExpr(SemaRef.Context)) {
16645       if (Result->isSigned() &&
16646           !((!StrictlyPositive && Result->isNonNegative()) ||
16647             (StrictlyPositive && Result->isStrictlyPositive()))) {
16648         SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
16649             << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
16650             << ValExpr->getSourceRange();
16651         return false;
16652       }
16653     }
16654     if (!BuildCapture)
16655       return true;
16656     *CaptureRegion =
16657         getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP);
16658     if (*CaptureRegion != OMPD_unknown &&
16659         !SemaRef.CurContext->isDependentContext()) {
16660       ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
16661       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16662       ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
16663       *HelperValStmt = buildPreInits(SemaRef.Context, Captures);
16664     }
16665   }
16666   return true;
16667 }
16668 
16669 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
16670                                              SourceLocation StartLoc,
16671                                              SourceLocation LParenLoc,
16672                                              SourceLocation EndLoc) {
16673   Expr *ValExpr = NumThreads;
16674   Stmt *HelperValStmt = nullptr;
16675 
16676   // OpenMP [2.5, Restrictions]
16677   //  The num_threads expression must evaluate to a positive integer value.
16678   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
16679                                  /*StrictlyPositive=*/true))
16680     return nullptr;
16681 
16682   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16683   OpenMPDirectiveKind CaptureRegion =
16684       getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP);
16685   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16686     ValExpr = MakeFullExpr(ValExpr).get();
16687     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16688     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16689     HelperValStmt = buildPreInits(Context, Captures);
16690   }
16691 
16692   return new (Context) OMPNumThreadsClause(
16693       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
16694 }
16695 
16696 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
16697                                                        OpenMPClauseKind CKind,
16698                                                        bool StrictlyPositive,
16699                                                        bool SuppressExprDiags) {
16700   if (!E)
16701     return ExprError();
16702   if (E->isValueDependent() || E->isTypeDependent() ||
16703       E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
16704     return E;
16705 
16706   llvm::APSInt Result;
16707   ExprResult ICE;
16708   if (SuppressExprDiags) {
16709     // Use a custom diagnoser that suppresses 'note' diagnostics about the
16710     // expression.
16711     struct SuppressedDiagnoser : public Sema::VerifyICEDiagnoser {
16712       SuppressedDiagnoser() : VerifyICEDiagnoser(/*Suppress=*/true) {}
16713       Sema::SemaDiagnosticBuilder diagnoseNotICE(Sema &S,
16714                                                  SourceLocation Loc) override {
16715         llvm_unreachable("Diagnostic suppressed");
16716       }
16717     } Diagnoser;
16718     ICE = VerifyIntegerConstantExpression(E, &Result, Diagnoser, AllowFold);
16719   } else {
16720     ICE = VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold);
16721   }
16722   if (ICE.isInvalid())
16723     return ExprError();
16724 
16725   if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
16726       (!StrictlyPositive && !Result.isNonNegative())) {
16727     Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
16728         << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
16729         << E->getSourceRange();
16730     return ExprError();
16731   }
16732   if ((CKind == OMPC_aligned || CKind == OMPC_align) && !Result.isPowerOf2()) {
16733     Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
16734         << E->getSourceRange();
16735     return ExprError();
16736   }
16737   if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
16738     DSAStack->setAssociatedLoops(Result.getExtValue());
16739   else if (CKind == OMPC_ordered)
16740     DSAStack->setAssociatedLoops(Result.getExtValue());
16741   return ICE;
16742 }
16743 
16744 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
16745                                           SourceLocation LParenLoc,
16746                                           SourceLocation EndLoc) {
16747   // OpenMP [2.8.1, simd construct, Description]
16748   // The parameter of the safelen clause must be a constant
16749   // positive integer expression.
16750   ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
16751   if (Safelen.isInvalid())
16752     return nullptr;
16753   return new (Context)
16754       OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
16755 }
16756 
16757 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
16758                                           SourceLocation LParenLoc,
16759                                           SourceLocation EndLoc) {
16760   // OpenMP [2.8.1, simd construct, Description]
16761   // The parameter of the simdlen clause must be a constant
16762   // positive integer expression.
16763   ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
16764   if (Simdlen.isInvalid())
16765     return nullptr;
16766   return new (Context)
16767       OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
16768 }
16769 
16770 /// Tries to find omp_allocator_handle_t type.
16771 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
16772                                     DSAStackTy *Stack) {
16773   if (!Stack->getOMPAllocatorHandleT().isNull())
16774     return true;
16775 
16776   // Set the allocator handle type.
16777   IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_allocator_handle_t");
16778   ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
16779   if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
16780     S.Diag(Loc, diag::err_omp_implied_type_not_found)
16781         << "omp_allocator_handle_t";
16782     return false;
16783   }
16784   QualType AllocatorHandleEnumTy = PT.get();
16785   AllocatorHandleEnumTy.addConst();
16786   Stack->setOMPAllocatorHandleT(AllocatorHandleEnumTy);
16787 
16788   // Fill the predefined allocator map.
16789   bool ErrorFound = false;
16790   for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
16791     auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
16792     StringRef Allocator =
16793         OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
16794     DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
16795     auto *VD = dyn_cast_or_null<ValueDecl>(
16796         S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
16797     if (!VD) {
16798       ErrorFound = true;
16799       break;
16800     }
16801     QualType AllocatorType =
16802         VD->getType().getNonLValueExprType(S.getASTContext());
16803     ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
16804     if (!Res.isUsable()) {
16805       ErrorFound = true;
16806       break;
16807     }
16808     Res = S.PerformImplicitConversion(Res.get(), AllocatorHandleEnumTy,
16809                                       Sema::AA_Initializing,
16810                                       /* AllowExplicit */ true);
16811     if (!Res.isUsable()) {
16812       ErrorFound = true;
16813       break;
16814     }
16815     Stack->setAllocator(AllocatorKind, Res.get());
16816   }
16817   if (ErrorFound) {
16818     S.Diag(Loc, diag::err_omp_implied_type_not_found)
16819         << "omp_allocator_handle_t";
16820     return false;
16821   }
16822 
16823   return true;
16824 }
16825 
16826 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc,
16827                                             SourceLocation LParenLoc,
16828                                             SourceLocation EndLoc) {
16829   // OpenMP [2.11.3, allocate Directive, Description]
16830   // allocator is an expression of omp_allocator_handle_t type.
16831   if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack))
16832     return nullptr;
16833 
16834   ExprResult Allocator = DefaultLvalueConversion(A);
16835   if (Allocator.isInvalid())
16836     return nullptr;
16837   Allocator = PerformImplicitConversion(Allocator.get(),
16838                                         DSAStack->getOMPAllocatorHandleT(),
16839                                         Sema::AA_Initializing,
16840                                         /*AllowExplicit=*/true);
16841   if (Allocator.isInvalid())
16842     return nullptr;
16843   return new (Context)
16844       OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
16845 }
16846 
16847 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
16848                                            SourceLocation StartLoc,
16849                                            SourceLocation LParenLoc,
16850                                            SourceLocation EndLoc) {
16851   // OpenMP [2.7.1, loop construct, Description]
16852   // OpenMP [2.8.1, simd construct, Description]
16853   // OpenMP [2.9.6, distribute construct, Description]
16854   // The parameter of the collapse clause must be a constant
16855   // positive integer expression.
16856   ExprResult NumForLoopsResult =
16857       VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
16858   if (NumForLoopsResult.isInvalid())
16859     return nullptr;
16860   return new (Context)
16861       OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
16862 }
16863 
16864 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
16865                                           SourceLocation EndLoc,
16866                                           SourceLocation LParenLoc,
16867                                           Expr *NumForLoops) {
16868   // OpenMP [2.7.1, loop construct, Description]
16869   // OpenMP [2.8.1, simd construct, Description]
16870   // OpenMP [2.9.6, distribute construct, Description]
16871   // The parameter of the ordered clause must be a constant
16872   // positive integer expression if any.
16873   if (NumForLoops && LParenLoc.isValid()) {
16874     ExprResult NumForLoopsResult =
16875         VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
16876     if (NumForLoopsResult.isInvalid())
16877       return nullptr;
16878     NumForLoops = NumForLoopsResult.get();
16879   } else {
16880     NumForLoops = nullptr;
16881   }
16882   auto *Clause = OMPOrderedClause::Create(
16883       Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0,
16884       StartLoc, LParenLoc, EndLoc);
16885   DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
16886   return Clause;
16887 }
16888 
16889 OMPClause *Sema::ActOnOpenMPSimpleClause(
16890     OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
16891     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
16892   OMPClause *Res = nullptr;
16893   switch (Kind) {
16894   case OMPC_default:
16895     Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument),
16896                                    ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16897     break;
16898   case OMPC_proc_bind:
16899     Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument),
16900                                     ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16901     break;
16902   case OMPC_atomic_default_mem_order:
16903     Res = ActOnOpenMPAtomicDefaultMemOrderClause(
16904         static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
16905         ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16906     break;
16907   case OMPC_fail:
16908     Res = ActOnOpenMPFailClause(
16909         static_cast<OpenMPClauseKind>(Argument),
16910         ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16911     break;
16912   case OMPC_update:
16913     Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
16914                                   ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16915     break;
16916   case OMPC_bind:
16917     Res = ActOnOpenMPBindClause(static_cast<OpenMPBindClauseKind>(Argument),
16918                                 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16919     break;
16920   case OMPC_at:
16921     Res = ActOnOpenMPAtClause(static_cast<OpenMPAtClauseKind>(Argument),
16922                               ArgumentLoc, StartLoc, LParenLoc, EndLoc);
16923     break;
16924   case OMPC_severity:
16925     Res = ActOnOpenMPSeverityClause(
16926         static_cast<OpenMPSeverityClauseKind>(Argument), ArgumentLoc, StartLoc,
16927         LParenLoc, EndLoc);
16928     break;
16929   case OMPC_if:
16930   case OMPC_final:
16931   case OMPC_num_threads:
16932   case OMPC_safelen:
16933   case OMPC_simdlen:
16934   case OMPC_sizes:
16935   case OMPC_allocator:
16936   case OMPC_collapse:
16937   case OMPC_schedule:
16938   case OMPC_private:
16939   case OMPC_firstprivate:
16940   case OMPC_lastprivate:
16941   case OMPC_shared:
16942   case OMPC_reduction:
16943   case OMPC_task_reduction:
16944   case OMPC_in_reduction:
16945   case OMPC_linear:
16946   case OMPC_aligned:
16947   case OMPC_copyin:
16948   case OMPC_copyprivate:
16949   case OMPC_ordered:
16950   case OMPC_nowait:
16951   case OMPC_untied:
16952   case OMPC_mergeable:
16953   case OMPC_threadprivate:
16954   case OMPC_allocate:
16955   case OMPC_flush:
16956   case OMPC_depobj:
16957   case OMPC_read:
16958   case OMPC_write:
16959   case OMPC_capture:
16960   case OMPC_compare:
16961   case OMPC_seq_cst:
16962   case OMPC_acq_rel:
16963   case OMPC_acquire:
16964   case OMPC_release:
16965   case OMPC_relaxed:
16966   case OMPC_depend:
16967   case OMPC_device:
16968   case OMPC_threads:
16969   case OMPC_simd:
16970   case OMPC_map:
16971   case OMPC_num_teams:
16972   case OMPC_thread_limit:
16973   case OMPC_priority:
16974   case OMPC_grainsize:
16975   case OMPC_nogroup:
16976   case OMPC_num_tasks:
16977   case OMPC_hint:
16978   case OMPC_dist_schedule:
16979   case OMPC_defaultmap:
16980   case OMPC_unknown:
16981   case OMPC_uniform:
16982   case OMPC_to:
16983   case OMPC_from:
16984   case OMPC_use_device_ptr:
16985   case OMPC_use_device_addr:
16986   case OMPC_is_device_ptr:
16987   case OMPC_has_device_addr:
16988   case OMPC_unified_address:
16989   case OMPC_unified_shared_memory:
16990   case OMPC_reverse_offload:
16991   case OMPC_dynamic_allocators:
16992   case OMPC_device_type:
16993   case OMPC_match:
16994   case OMPC_nontemporal:
16995   case OMPC_destroy:
16996   case OMPC_novariants:
16997   case OMPC_nocontext:
16998   case OMPC_detach:
16999   case OMPC_inclusive:
17000   case OMPC_exclusive:
17001   case OMPC_uses_allocators:
17002   case OMPC_affinity:
17003   case OMPC_when:
17004   case OMPC_message:
17005   default:
17006     llvm_unreachable("Clause is not allowed.");
17007   }
17008   return Res;
17009 }
17010 
17011 static std::string
17012 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
17013                         ArrayRef<unsigned> Exclude = std::nullopt) {
17014   SmallString<256> Buffer;
17015   llvm::raw_svector_ostream Out(Buffer);
17016   unsigned Skipped = Exclude.size();
17017   for (unsigned I = First; I < Last; ++I) {
17018     if (llvm::is_contained(Exclude, I)) {
17019       --Skipped;
17020       continue;
17021     }
17022     Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
17023     if (I + Skipped + 2 == Last)
17024       Out << " or ";
17025     else if (I + Skipped + 1 != Last)
17026       Out << ", ";
17027   }
17028   return std::string(Out.str());
17029 }
17030 
17031 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind,
17032                                           SourceLocation KindKwLoc,
17033                                           SourceLocation StartLoc,
17034                                           SourceLocation LParenLoc,
17035                                           SourceLocation EndLoc) {
17036   if (Kind == OMP_DEFAULT_unknown) {
17037     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17038         << getListOfPossibleValues(OMPC_default, /*First=*/0,
17039                                    /*Last=*/unsigned(OMP_DEFAULT_unknown))
17040         << getOpenMPClauseName(OMPC_default);
17041     return nullptr;
17042   }
17043 
17044   switch (Kind) {
17045   case OMP_DEFAULT_none:
17046     DSAStack->setDefaultDSANone(KindKwLoc);
17047     break;
17048   case OMP_DEFAULT_shared:
17049     DSAStack->setDefaultDSAShared(KindKwLoc);
17050     break;
17051   case OMP_DEFAULT_firstprivate:
17052     DSAStack->setDefaultDSAFirstPrivate(KindKwLoc);
17053     break;
17054   case OMP_DEFAULT_private:
17055     DSAStack->setDefaultDSAPrivate(KindKwLoc);
17056     break;
17057   default:
17058     llvm_unreachable("DSA unexpected in OpenMP default clause");
17059   }
17060 
17061   return new (Context)
17062       OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
17063 }
17064 
17065 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind,
17066                                            SourceLocation KindKwLoc,
17067                                            SourceLocation StartLoc,
17068                                            SourceLocation LParenLoc,
17069                                            SourceLocation EndLoc) {
17070   if (Kind == OMP_PROC_BIND_unknown) {
17071     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17072         << getListOfPossibleValues(OMPC_proc_bind,
17073                                    /*First=*/unsigned(OMP_PROC_BIND_master),
17074                                    /*Last=*/
17075                                    unsigned(LangOpts.OpenMP > 50
17076                                                 ? OMP_PROC_BIND_primary
17077                                                 : OMP_PROC_BIND_spread) +
17078                                        1)
17079         << getOpenMPClauseName(OMPC_proc_bind);
17080     return nullptr;
17081   }
17082   if (Kind == OMP_PROC_BIND_primary && LangOpts.OpenMP < 51)
17083     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17084         << getListOfPossibleValues(OMPC_proc_bind,
17085                                    /*First=*/unsigned(OMP_PROC_BIND_master),
17086                                    /*Last=*/
17087                                    unsigned(OMP_PROC_BIND_spread) + 1)
17088         << getOpenMPClauseName(OMPC_proc_bind);
17089   return new (Context)
17090       OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
17091 }
17092 
17093 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause(
17094     OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc,
17095     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
17096   if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) {
17097     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17098         << getListOfPossibleValues(
17099                OMPC_atomic_default_mem_order, /*First=*/0,
17100                /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown)
17101         << getOpenMPClauseName(OMPC_atomic_default_mem_order);
17102     return nullptr;
17103   }
17104   return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
17105                                                       LParenLoc, EndLoc);
17106 }
17107 
17108 OMPClause *Sema::ActOnOpenMPAtClause(OpenMPAtClauseKind Kind,
17109                                      SourceLocation KindKwLoc,
17110                                      SourceLocation StartLoc,
17111                                      SourceLocation LParenLoc,
17112                                      SourceLocation EndLoc) {
17113   if (Kind == OMPC_AT_unknown) {
17114     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17115         << getListOfPossibleValues(OMPC_at, /*First=*/0,
17116                                    /*Last=*/OMPC_AT_unknown)
17117         << getOpenMPClauseName(OMPC_at);
17118     return nullptr;
17119   }
17120   return new (Context)
17121       OMPAtClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
17122 }
17123 
17124 OMPClause *Sema::ActOnOpenMPSeverityClause(OpenMPSeverityClauseKind Kind,
17125                                            SourceLocation KindKwLoc,
17126                                            SourceLocation StartLoc,
17127                                            SourceLocation LParenLoc,
17128                                            SourceLocation EndLoc) {
17129   if (Kind == OMPC_SEVERITY_unknown) {
17130     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17131         << getListOfPossibleValues(OMPC_severity, /*First=*/0,
17132                                    /*Last=*/OMPC_SEVERITY_unknown)
17133         << getOpenMPClauseName(OMPC_severity);
17134     return nullptr;
17135   }
17136   return new (Context)
17137       OMPSeverityClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
17138 }
17139 
17140 OMPClause *Sema::ActOnOpenMPMessageClause(Expr *ME, SourceLocation StartLoc,
17141                                           SourceLocation LParenLoc,
17142                                           SourceLocation EndLoc) {
17143   assert(ME && "NULL expr in Message clause");
17144   if (!isa<StringLiteral>(ME)) {
17145     Diag(ME->getBeginLoc(), diag::warn_clause_expected_string)
17146         << getOpenMPClauseName(OMPC_message);
17147     return nullptr;
17148   }
17149   return new (Context) OMPMessageClause(ME, StartLoc, LParenLoc, EndLoc);
17150 }
17151 
17152 OMPClause *Sema::ActOnOpenMPOrderClause(
17153     OpenMPOrderClauseModifier Modifier, OpenMPOrderClauseKind Kind,
17154     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
17155     SourceLocation KindLoc, SourceLocation EndLoc) {
17156   if (Kind != OMPC_ORDER_concurrent ||
17157       (LangOpts.OpenMP < 51 && MLoc.isValid())) {
17158     // Kind should be concurrent,
17159     // Modifiers introduced in OpenMP 5.1
17160     static_assert(OMPC_ORDER_unknown > 0,
17161                   "OMPC_ORDER_unknown not greater than 0");
17162 
17163     Diag(KindLoc, diag::err_omp_unexpected_clause_value)
17164         << getListOfPossibleValues(OMPC_order,
17165                                    /*First=*/0,
17166                                    /*Last=*/OMPC_ORDER_unknown)
17167         << getOpenMPClauseName(OMPC_order);
17168     return nullptr;
17169   }
17170   if (LangOpts.OpenMP >= 51) {
17171     if (Modifier == OMPC_ORDER_MODIFIER_unknown && MLoc.isValid()) {
17172       Diag(MLoc, diag::err_omp_unexpected_clause_value)
17173           << getListOfPossibleValues(OMPC_order,
17174                                      /*First=*/OMPC_ORDER_MODIFIER_unknown + 1,
17175                                      /*Last=*/OMPC_ORDER_MODIFIER_last)
17176           << getOpenMPClauseName(OMPC_order);
17177     } else {
17178       DSAStack->setRegionHasOrderConcurrent(/*HasOrderConcurrent=*/true);
17179       if (DSAStack->getCurScope()) {
17180         // mark the current scope with 'order' flag
17181         unsigned existingFlags = DSAStack->getCurScope()->getFlags();
17182         DSAStack->getCurScope()->setFlags(existingFlags |
17183                                           Scope::OpenMPOrderClauseScope);
17184       }
17185     }
17186   }
17187   return new (Context) OMPOrderClause(Kind, KindLoc, StartLoc, LParenLoc,
17188                                       EndLoc, Modifier, MLoc);
17189 }
17190 
17191 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,
17192                                          SourceLocation KindKwLoc,
17193                                          SourceLocation StartLoc,
17194                                          SourceLocation LParenLoc,
17195                                          SourceLocation EndLoc) {
17196   if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source ||
17197       Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) {
17198     SmallVector<unsigned> Except = {
17199         OMPC_DEPEND_source, OMPC_DEPEND_sink, OMPC_DEPEND_depobj,
17200         OMPC_DEPEND_outallmemory, OMPC_DEPEND_inoutallmemory};
17201     if (LangOpts.OpenMP < 51)
17202       Except.push_back(OMPC_DEPEND_inoutset);
17203     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
17204         << getListOfPossibleValues(OMPC_depend, /*First=*/0,
17205                                    /*Last=*/OMPC_DEPEND_unknown, Except)
17206         << getOpenMPClauseName(OMPC_update);
17207     return nullptr;
17208   }
17209   return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind,
17210                                  EndLoc);
17211 }
17212 
17213 OMPClause *Sema::ActOnOpenMPSizesClause(ArrayRef<Expr *> SizeExprs,
17214                                         SourceLocation StartLoc,
17215                                         SourceLocation LParenLoc,
17216                                         SourceLocation EndLoc) {
17217   for (Expr *SizeExpr : SizeExprs) {
17218     ExprResult NumForLoopsResult = VerifyPositiveIntegerConstantInClause(
17219         SizeExpr, OMPC_sizes, /*StrictlyPositive=*/true);
17220     if (!NumForLoopsResult.isUsable())
17221       return nullptr;
17222   }
17223 
17224   DSAStack->setAssociatedLoops(SizeExprs.size());
17225   return OMPSizesClause::Create(Context, StartLoc, LParenLoc, EndLoc,
17226                                 SizeExprs);
17227 }
17228 
17229 OMPClause *Sema::ActOnOpenMPFullClause(SourceLocation StartLoc,
17230                                        SourceLocation EndLoc) {
17231   return OMPFullClause::Create(Context, StartLoc, EndLoc);
17232 }
17233 
17234 OMPClause *Sema::ActOnOpenMPPartialClause(Expr *FactorExpr,
17235                                           SourceLocation StartLoc,
17236                                           SourceLocation LParenLoc,
17237                                           SourceLocation EndLoc) {
17238   if (FactorExpr) {
17239     // If an argument is specified, it must be a constant (or an unevaluated
17240     // template expression).
17241     ExprResult FactorResult = VerifyPositiveIntegerConstantInClause(
17242         FactorExpr, OMPC_partial, /*StrictlyPositive=*/true);
17243     if (FactorResult.isInvalid())
17244       return nullptr;
17245     FactorExpr = FactorResult.get();
17246   }
17247 
17248   return OMPPartialClause::Create(Context, StartLoc, LParenLoc, EndLoc,
17249                                   FactorExpr);
17250 }
17251 
17252 OMPClause *Sema::ActOnOpenMPAlignClause(Expr *A, SourceLocation StartLoc,
17253                                         SourceLocation LParenLoc,
17254                                         SourceLocation EndLoc) {
17255   ExprResult AlignVal;
17256   AlignVal = VerifyPositiveIntegerConstantInClause(A, OMPC_align);
17257   if (AlignVal.isInvalid())
17258     return nullptr;
17259   return OMPAlignClause::Create(Context, AlignVal.get(), StartLoc, LParenLoc,
17260                                 EndLoc);
17261 }
17262 
17263 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
17264     OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
17265     SourceLocation StartLoc, SourceLocation LParenLoc,
17266     ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
17267     SourceLocation EndLoc) {
17268   OMPClause *Res = nullptr;
17269   switch (Kind) {
17270   case OMPC_schedule:
17271     enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
17272     assert(Argument.size() == NumberOfElements &&
17273            ArgumentLoc.size() == NumberOfElements);
17274     Res = ActOnOpenMPScheduleClause(
17275         static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
17276         static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
17277         static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
17278         StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
17279         ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
17280     break;
17281   case OMPC_if:
17282     assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
17283     Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
17284                               Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
17285                               DelimLoc, EndLoc);
17286     break;
17287   case OMPC_dist_schedule:
17288     Res = ActOnOpenMPDistScheduleClause(
17289         static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
17290         StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
17291     break;
17292   case OMPC_defaultmap:
17293     enum { Modifier, DefaultmapKind };
17294     Res = ActOnOpenMPDefaultmapClause(
17295         static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
17296         static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
17297         StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
17298         EndLoc);
17299     break;
17300   case OMPC_order:
17301     enum { OrderModifier, OrderKind };
17302     Res = ActOnOpenMPOrderClause(
17303         static_cast<OpenMPOrderClauseModifier>(Argument[OrderModifier]),
17304         static_cast<OpenMPOrderClauseKind>(Argument[OrderKind]), StartLoc,
17305         LParenLoc, ArgumentLoc[OrderModifier], ArgumentLoc[OrderKind], EndLoc);
17306     break;
17307   case OMPC_device:
17308     assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
17309     Res = ActOnOpenMPDeviceClause(
17310         static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr,
17311         StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
17312     break;
17313   case OMPC_grainsize:
17314     assert(Argument.size() == 1 && ArgumentLoc.size() == 1 &&
17315            "Modifier for grainsize clause and its location are expected.");
17316     Res = ActOnOpenMPGrainsizeClause(
17317         static_cast<OpenMPGrainsizeClauseModifier>(Argument.back()), Expr,
17318         StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
17319     break;
17320   case OMPC_num_tasks:
17321     assert(Argument.size() == 1 && ArgumentLoc.size() == 1 &&
17322            "Modifier for num_tasks clause and its location are expected.");
17323     Res = ActOnOpenMPNumTasksClause(
17324         static_cast<OpenMPNumTasksClauseModifier>(Argument.back()), Expr,
17325         StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
17326     break;
17327   case OMPC_final:
17328   case OMPC_num_threads:
17329   case OMPC_safelen:
17330   case OMPC_simdlen:
17331   case OMPC_sizes:
17332   case OMPC_allocator:
17333   case OMPC_collapse:
17334   case OMPC_default:
17335   case OMPC_proc_bind:
17336   case OMPC_private:
17337   case OMPC_firstprivate:
17338   case OMPC_lastprivate:
17339   case OMPC_shared:
17340   case OMPC_reduction:
17341   case OMPC_task_reduction:
17342   case OMPC_in_reduction:
17343   case OMPC_linear:
17344   case OMPC_aligned:
17345   case OMPC_copyin:
17346   case OMPC_copyprivate:
17347   case OMPC_ordered:
17348   case OMPC_nowait:
17349   case OMPC_untied:
17350   case OMPC_mergeable:
17351   case OMPC_threadprivate:
17352   case OMPC_allocate:
17353   case OMPC_flush:
17354   case OMPC_depobj:
17355   case OMPC_read:
17356   case OMPC_write:
17357   case OMPC_update:
17358   case OMPC_capture:
17359   case OMPC_compare:
17360   case OMPC_seq_cst:
17361   case OMPC_acq_rel:
17362   case OMPC_acquire:
17363   case OMPC_release:
17364   case OMPC_relaxed:
17365   case OMPC_depend:
17366   case OMPC_threads:
17367   case OMPC_simd:
17368   case OMPC_map:
17369   case OMPC_num_teams:
17370   case OMPC_thread_limit:
17371   case OMPC_priority:
17372   case OMPC_nogroup:
17373   case OMPC_hint:
17374   case OMPC_unknown:
17375   case OMPC_uniform:
17376   case OMPC_to:
17377   case OMPC_from:
17378   case OMPC_use_device_ptr:
17379   case OMPC_use_device_addr:
17380   case OMPC_is_device_ptr:
17381   case OMPC_has_device_addr:
17382   case OMPC_unified_address:
17383   case OMPC_unified_shared_memory:
17384   case OMPC_reverse_offload:
17385   case OMPC_dynamic_allocators:
17386   case OMPC_atomic_default_mem_order:
17387   case OMPC_device_type:
17388   case OMPC_match:
17389   case OMPC_nontemporal:
17390   case OMPC_at:
17391   case OMPC_severity:
17392   case OMPC_message:
17393   case OMPC_destroy:
17394   case OMPC_novariants:
17395   case OMPC_nocontext:
17396   case OMPC_detach:
17397   case OMPC_inclusive:
17398   case OMPC_exclusive:
17399   case OMPC_uses_allocators:
17400   case OMPC_affinity:
17401   case OMPC_when:
17402   case OMPC_bind:
17403   default:
17404     llvm_unreachable("Clause is not allowed.");
17405   }
17406   return Res;
17407 }
17408 
17409 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
17410                                    OpenMPScheduleClauseModifier M2,
17411                                    SourceLocation M1Loc, SourceLocation M2Loc) {
17412   if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
17413     SmallVector<unsigned, 2> Excluded;
17414     if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
17415       Excluded.push_back(M2);
17416     if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
17417       Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
17418     if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
17419       Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
17420     S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
17421         << getListOfPossibleValues(OMPC_schedule,
17422                                    /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
17423                                    /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
17424                                    Excluded)
17425         << getOpenMPClauseName(OMPC_schedule);
17426     return true;
17427   }
17428   return false;
17429 }
17430 
17431 OMPClause *Sema::ActOnOpenMPScheduleClause(
17432     OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
17433     OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
17434     SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
17435     SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
17436   if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
17437       checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
17438     return nullptr;
17439   // OpenMP, 2.7.1, Loop Construct, Restrictions
17440   // Either the monotonic modifier or the nonmonotonic modifier can be specified
17441   // but not both.
17442   if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
17443       (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
17444        M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
17445       (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
17446        M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
17447     Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
17448         << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
17449         << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
17450     return nullptr;
17451   }
17452   if (Kind == OMPC_SCHEDULE_unknown) {
17453     std::string Values;
17454     if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
17455       unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
17456       Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
17457                                        /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
17458                                        Exclude);
17459     } else {
17460       Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
17461                                        /*Last=*/OMPC_SCHEDULE_unknown);
17462     }
17463     Diag(KindLoc, diag::err_omp_unexpected_clause_value)
17464         << Values << getOpenMPClauseName(OMPC_schedule);
17465     return nullptr;
17466   }
17467   // OpenMP, 2.7.1, Loop Construct, Restrictions
17468   // The nonmonotonic modifier can only be specified with schedule(dynamic) or
17469   // schedule(guided).
17470   // OpenMP 5.0 does not have this restriction.
17471   if (LangOpts.OpenMP < 50 &&
17472       (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
17473        M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
17474       Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
17475     Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
17476          diag::err_omp_schedule_nonmonotonic_static);
17477     return nullptr;
17478   }
17479   Expr *ValExpr = ChunkSize;
17480   Stmt *HelperValStmt = nullptr;
17481   if (ChunkSize) {
17482     if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
17483         !ChunkSize->isInstantiationDependent() &&
17484         !ChunkSize->containsUnexpandedParameterPack()) {
17485       SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
17486       ExprResult Val =
17487           PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
17488       if (Val.isInvalid())
17489         return nullptr;
17490 
17491       ValExpr = Val.get();
17492 
17493       // OpenMP [2.7.1, Restrictions]
17494       //  chunk_size must be a loop invariant integer expression with a positive
17495       //  value.
17496       if (std::optional<llvm::APSInt> Result =
17497               ValExpr->getIntegerConstantExpr(Context)) {
17498         if (Result->isSigned() && !Result->isStrictlyPositive()) {
17499           Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
17500               << "schedule" << 1 << ChunkSize->getSourceRange();
17501           return nullptr;
17502         }
17503       } else if (getOpenMPCaptureRegionForClause(
17504                      DSAStack->getCurrentDirective(), OMPC_schedule,
17505                      LangOpts.OpenMP) != OMPD_unknown &&
17506                  !CurContext->isDependentContext()) {
17507         ValExpr = MakeFullExpr(ValExpr).get();
17508         llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
17509         ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
17510         HelperValStmt = buildPreInits(Context, Captures);
17511       }
17512     }
17513   }
17514 
17515   return new (Context)
17516       OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
17517                         ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
17518 }
17519 
17520 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
17521                                    SourceLocation StartLoc,
17522                                    SourceLocation EndLoc) {
17523   OMPClause *Res = nullptr;
17524   switch (Kind) {
17525   case OMPC_ordered:
17526     Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
17527     break;
17528   case OMPC_nowait:
17529     Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
17530     break;
17531   case OMPC_untied:
17532     Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
17533     break;
17534   case OMPC_mergeable:
17535     Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
17536     break;
17537   case OMPC_read:
17538     Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
17539     break;
17540   case OMPC_write:
17541     Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
17542     break;
17543   case OMPC_update:
17544     Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
17545     break;
17546   case OMPC_capture:
17547     Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
17548     break;
17549   case OMPC_compare:
17550     Res = ActOnOpenMPCompareClause(StartLoc, EndLoc);
17551     break;
17552   case OMPC_fail:
17553     Res = ActOnOpenMPFailClause(StartLoc, EndLoc);
17554     break;
17555   case OMPC_seq_cst:
17556     Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
17557     break;
17558   case OMPC_acq_rel:
17559     Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc);
17560     break;
17561   case OMPC_acquire:
17562     Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc);
17563     break;
17564   case OMPC_release:
17565     Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc);
17566     break;
17567   case OMPC_relaxed:
17568     Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc);
17569     break;
17570   case OMPC_threads:
17571     Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
17572     break;
17573   case OMPC_simd:
17574     Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
17575     break;
17576   case OMPC_nogroup:
17577     Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
17578     break;
17579   case OMPC_unified_address:
17580     Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
17581     break;
17582   case OMPC_unified_shared_memory:
17583     Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
17584     break;
17585   case OMPC_reverse_offload:
17586     Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
17587     break;
17588   case OMPC_dynamic_allocators:
17589     Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
17590     break;
17591   case OMPC_destroy:
17592     Res = ActOnOpenMPDestroyClause(/*InteropVar=*/nullptr, StartLoc,
17593                                    /*LParenLoc=*/SourceLocation(),
17594                                    /*VarLoc=*/SourceLocation(), EndLoc);
17595     break;
17596   case OMPC_full:
17597     Res = ActOnOpenMPFullClause(StartLoc, EndLoc);
17598     break;
17599   case OMPC_partial:
17600     Res = ActOnOpenMPPartialClause(nullptr, StartLoc, /*LParenLoc=*/{}, EndLoc);
17601     break;
17602   case OMPC_ompx_bare:
17603     Res = ActOnOpenMPXBareClause(StartLoc, EndLoc);
17604     break;
17605   case OMPC_if:
17606   case OMPC_final:
17607   case OMPC_num_threads:
17608   case OMPC_safelen:
17609   case OMPC_simdlen:
17610   case OMPC_sizes:
17611   case OMPC_allocator:
17612   case OMPC_collapse:
17613   case OMPC_schedule:
17614   case OMPC_private:
17615   case OMPC_firstprivate:
17616   case OMPC_lastprivate:
17617   case OMPC_shared:
17618   case OMPC_reduction:
17619   case OMPC_task_reduction:
17620   case OMPC_in_reduction:
17621   case OMPC_linear:
17622   case OMPC_aligned:
17623   case OMPC_copyin:
17624   case OMPC_copyprivate:
17625   case OMPC_default:
17626   case OMPC_proc_bind:
17627   case OMPC_threadprivate:
17628   case OMPC_allocate:
17629   case OMPC_flush:
17630   case OMPC_depobj:
17631   case OMPC_depend:
17632   case OMPC_device:
17633   case OMPC_map:
17634   case OMPC_num_teams:
17635   case OMPC_thread_limit:
17636   case OMPC_priority:
17637   case OMPC_grainsize:
17638   case OMPC_num_tasks:
17639   case OMPC_hint:
17640   case OMPC_dist_schedule:
17641   case OMPC_defaultmap:
17642   case OMPC_unknown:
17643   case OMPC_uniform:
17644   case OMPC_to:
17645   case OMPC_from:
17646   case OMPC_use_device_ptr:
17647   case OMPC_use_device_addr:
17648   case OMPC_is_device_ptr:
17649   case OMPC_has_device_addr:
17650   case OMPC_atomic_default_mem_order:
17651   case OMPC_device_type:
17652   case OMPC_match:
17653   case OMPC_nontemporal:
17654   case OMPC_order:
17655   case OMPC_at:
17656   case OMPC_severity:
17657   case OMPC_message:
17658   case OMPC_novariants:
17659   case OMPC_nocontext:
17660   case OMPC_detach:
17661   case OMPC_inclusive:
17662   case OMPC_exclusive:
17663   case OMPC_uses_allocators:
17664   case OMPC_affinity:
17665   case OMPC_when:
17666   case OMPC_ompx_dyn_cgroup_mem:
17667   default:
17668     llvm_unreachable("Clause is not allowed.");
17669   }
17670   return Res;
17671 }
17672 
17673 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
17674                                          SourceLocation EndLoc) {
17675   DSAStack->setNowaitRegion();
17676   return new (Context) OMPNowaitClause(StartLoc, EndLoc);
17677 }
17678 
17679 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
17680                                          SourceLocation EndLoc) {
17681   DSAStack->setUntiedRegion();
17682   return new (Context) OMPUntiedClause(StartLoc, EndLoc);
17683 }
17684 
17685 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
17686                                             SourceLocation EndLoc) {
17687   return new (Context) OMPMergeableClause(StartLoc, EndLoc);
17688 }
17689 
17690 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
17691                                        SourceLocation EndLoc) {
17692   return new (Context) OMPReadClause(StartLoc, EndLoc);
17693 }
17694 
17695 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
17696                                         SourceLocation EndLoc) {
17697   return new (Context) OMPWriteClause(StartLoc, EndLoc);
17698 }
17699 
17700 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
17701                                          SourceLocation EndLoc) {
17702   return OMPUpdateClause::Create(Context, StartLoc, EndLoc);
17703 }
17704 
17705 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
17706                                           SourceLocation EndLoc) {
17707   return new (Context) OMPCaptureClause(StartLoc, EndLoc);
17708 }
17709 
17710 OMPClause *Sema::ActOnOpenMPCompareClause(SourceLocation StartLoc,
17711                                           SourceLocation EndLoc) {
17712   return new (Context) OMPCompareClause(StartLoc, EndLoc);
17713 }
17714 
17715 OMPClause *Sema::ActOnOpenMPFailClause(SourceLocation StartLoc,
17716                                        SourceLocation EndLoc) {
17717   return new (Context) OMPFailClause(StartLoc, EndLoc);
17718 }
17719 
17720 OMPClause *Sema::ActOnOpenMPFailClause(
17721       OpenMPClauseKind Parameter, SourceLocation KindLoc,
17722       SourceLocation StartLoc, SourceLocation LParenLoc,
17723       SourceLocation EndLoc) {
17724 
17725   if (!checkFailClauseParameter(Parameter)) {
17726     Diag(KindLoc, diag::err_omp_atomic_fail_wrong_or_no_clauses);
17727     return nullptr;
17728   }
17729   return new (Context)
17730       OMPFailClause(Parameter, KindLoc, StartLoc, LParenLoc, EndLoc);
17731 }
17732 
17733 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
17734                                          SourceLocation EndLoc) {
17735   return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
17736 }
17737 
17738 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc,
17739                                          SourceLocation EndLoc) {
17740   return new (Context) OMPAcqRelClause(StartLoc, EndLoc);
17741 }
17742 
17743 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc,
17744                                           SourceLocation EndLoc) {
17745   return new (Context) OMPAcquireClause(StartLoc, EndLoc);
17746 }
17747 
17748 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc,
17749                                           SourceLocation EndLoc) {
17750   return new (Context) OMPReleaseClause(StartLoc, EndLoc);
17751 }
17752 
17753 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc,
17754                                           SourceLocation EndLoc) {
17755   return new (Context) OMPRelaxedClause(StartLoc, EndLoc);
17756 }
17757 
17758 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
17759                                           SourceLocation EndLoc) {
17760   return new (Context) OMPThreadsClause(StartLoc, EndLoc);
17761 }
17762 
17763 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
17764                                        SourceLocation EndLoc) {
17765   return new (Context) OMPSIMDClause(StartLoc, EndLoc);
17766 }
17767 
17768 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
17769                                           SourceLocation EndLoc) {
17770   return new (Context) OMPNogroupClause(StartLoc, EndLoc);
17771 }
17772 
17773 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
17774                                                  SourceLocation EndLoc) {
17775   return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
17776 }
17777 
17778 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
17779                                                       SourceLocation EndLoc) {
17780   return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
17781 }
17782 
17783 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
17784                                                  SourceLocation EndLoc) {
17785   return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
17786 }
17787 
17788 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
17789                                                     SourceLocation EndLoc) {
17790   return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
17791 }
17792 
17793 StmtResult Sema::ActOnOpenMPInteropDirective(ArrayRef<OMPClause *> Clauses,
17794                                              SourceLocation StartLoc,
17795                                              SourceLocation EndLoc) {
17796 
17797   // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17798   // At least one action-clause must appear on a directive.
17799   if (!hasClauses(Clauses, OMPC_init, OMPC_use, OMPC_destroy, OMPC_nowait)) {
17800     StringRef Expected = "'init', 'use', 'destroy', or 'nowait'";
17801     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
17802         << Expected << getOpenMPDirectiveName(OMPD_interop);
17803     return StmtError();
17804   }
17805 
17806   // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17807   // A depend clause can only appear on the directive if a targetsync
17808   // interop-type is present or the interop-var was initialized with
17809   // the targetsync interop-type.
17810 
17811   // If there is any 'init' clause diagnose if there is no 'init' clause with
17812   // interop-type of 'targetsync'. Cases involving other directives cannot be
17813   // diagnosed.
17814   const OMPDependClause *DependClause = nullptr;
17815   bool HasInitClause = false;
17816   bool IsTargetSync = false;
17817   for (const OMPClause *C : Clauses) {
17818     if (IsTargetSync)
17819       break;
17820     if (const auto *InitClause = dyn_cast<OMPInitClause>(C)) {
17821       HasInitClause = true;
17822       if (InitClause->getIsTargetSync())
17823         IsTargetSync = true;
17824     } else if (const auto *DC = dyn_cast<OMPDependClause>(C)) {
17825       DependClause = DC;
17826     }
17827   }
17828   if (DependClause && HasInitClause && !IsTargetSync) {
17829     Diag(DependClause->getBeginLoc(), diag::err_omp_interop_bad_depend_clause);
17830     return StmtError();
17831   }
17832 
17833   // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17834   // Each interop-var may be specified for at most one action-clause of each
17835   // interop construct.
17836   llvm::SmallPtrSet<const ValueDecl *, 4> InteropVars;
17837   for (OMPClause *C : Clauses) {
17838     OpenMPClauseKind ClauseKind = C->getClauseKind();
17839     std::pair<ValueDecl *, bool> DeclResult;
17840     SourceLocation ELoc;
17841     SourceRange ERange;
17842 
17843     if (ClauseKind == OMPC_init) {
17844       auto *E = cast<OMPInitClause>(C)->getInteropVar();
17845       DeclResult = getPrivateItem(*this, E, ELoc, ERange);
17846     } else if (ClauseKind == OMPC_use) {
17847       auto *E = cast<OMPUseClause>(C)->getInteropVar();
17848       DeclResult = getPrivateItem(*this, E, ELoc, ERange);
17849     } else if (ClauseKind == OMPC_destroy) {
17850       auto *E = cast<OMPDestroyClause>(C)->getInteropVar();
17851       DeclResult = getPrivateItem(*this, E, ELoc, ERange);
17852     }
17853 
17854     if (DeclResult.first) {
17855       if (!InteropVars.insert(DeclResult.first).second) {
17856         Diag(ELoc, diag::err_omp_interop_var_multiple_actions)
17857             << DeclResult.first;
17858         return StmtError();
17859       }
17860     }
17861   }
17862 
17863   return OMPInteropDirective::Create(Context, StartLoc, EndLoc, Clauses);
17864 }
17865 
17866 static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr,
17867                                    SourceLocation VarLoc,
17868                                    OpenMPClauseKind Kind) {
17869   SourceLocation ELoc;
17870   SourceRange ERange;
17871   Expr *RefExpr = InteropVarExpr;
17872   auto Res =
17873       getPrivateItem(SemaRef, RefExpr, ELoc, ERange,
17874                      /*AllowArraySection=*/false, /*DiagType=*/"omp_interop_t");
17875 
17876   if (Res.second) {
17877     // It will be analyzed later.
17878     return true;
17879   }
17880 
17881   if (!Res.first)
17882     return false;
17883 
17884   // Interop variable should be of type omp_interop_t.
17885   bool HasError = false;
17886   QualType InteropType;
17887   LookupResult Result(SemaRef, &SemaRef.Context.Idents.get("omp_interop_t"),
17888                       VarLoc, Sema::LookupOrdinaryName);
17889   if (SemaRef.LookupName(Result, SemaRef.getCurScope())) {
17890     NamedDecl *ND = Result.getFoundDecl();
17891     if (const auto *TD = dyn_cast<TypeDecl>(ND)) {
17892       InteropType = QualType(TD->getTypeForDecl(), 0);
17893     } else {
17894       HasError = true;
17895     }
17896   } else {
17897     HasError = true;
17898   }
17899 
17900   if (HasError) {
17901     SemaRef.Diag(VarLoc, diag::err_omp_implied_type_not_found)
17902         << "omp_interop_t";
17903     return false;
17904   }
17905 
17906   QualType VarType = InteropVarExpr->getType().getUnqualifiedType();
17907   if (!SemaRef.Context.hasSameType(InteropType, VarType)) {
17908     SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_wrong_type);
17909     return false;
17910   }
17911 
17912   // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
17913   // The interop-var passed to init or destroy must be non-const.
17914   if ((Kind == OMPC_init || Kind == OMPC_destroy) &&
17915       isConstNotMutableType(SemaRef, InteropVarExpr->getType())) {
17916     SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected)
17917         << /*non-const*/ 1;
17918     return false;
17919   }
17920   return true;
17921 }
17922 
17923 OMPClause *
17924 Sema::ActOnOpenMPInitClause(Expr *InteropVar, OMPInteropInfo &InteropInfo,
17925                             SourceLocation StartLoc, SourceLocation LParenLoc,
17926                             SourceLocation VarLoc, SourceLocation EndLoc) {
17927 
17928   if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_init))
17929     return nullptr;
17930 
17931   // Check prefer_type values.  These foreign-runtime-id values are either
17932   // string literals or constant integral expressions.
17933   for (const Expr *E : InteropInfo.PreferTypes) {
17934     if (E->isValueDependent() || E->isTypeDependent() ||
17935         E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
17936       continue;
17937     if (E->isIntegerConstantExpr(Context))
17938       continue;
17939     if (isa<StringLiteral>(E))
17940       continue;
17941     Diag(E->getExprLoc(), diag::err_omp_interop_prefer_type);
17942     return nullptr;
17943   }
17944 
17945   return OMPInitClause::Create(Context, InteropVar, InteropInfo, StartLoc,
17946                                LParenLoc, VarLoc, EndLoc);
17947 }
17948 
17949 OMPClause *Sema::ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
17950                                       SourceLocation LParenLoc,
17951                                       SourceLocation VarLoc,
17952                                       SourceLocation EndLoc) {
17953 
17954   if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_use))
17955     return nullptr;
17956 
17957   return new (Context)
17958       OMPUseClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
17959 }
17960 
17961 OMPClause *Sema::ActOnOpenMPDestroyClause(Expr *InteropVar,
17962                                           SourceLocation StartLoc,
17963                                           SourceLocation LParenLoc,
17964                                           SourceLocation VarLoc,
17965                                           SourceLocation EndLoc) {
17966   if (!InteropVar && LangOpts.OpenMP >= 52 &&
17967       DSAStack->getCurrentDirective() == OMPD_depobj) {
17968     Diag(StartLoc, diag::err_omp_expected_clause_argument)
17969         << getOpenMPClauseName(OMPC_destroy)
17970         << getOpenMPDirectiveName(OMPD_depobj);
17971     return nullptr;
17972   }
17973   if (InteropVar &&
17974       !isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_destroy))
17975     return nullptr;
17976 
17977   return new (Context)
17978       OMPDestroyClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
17979 }
17980 
17981 OMPClause *Sema::ActOnOpenMPNovariantsClause(Expr *Condition,
17982                                              SourceLocation StartLoc,
17983                                              SourceLocation LParenLoc,
17984                                              SourceLocation EndLoc) {
17985   Expr *ValExpr = Condition;
17986   Stmt *HelperValStmt = nullptr;
17987   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
17988   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
17989       !Condition->isInstantiationDependent() &&
17990       !Condition->containsUnexpandedParameterPack()) {
17991     ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
17992     if (Val.isInvalid())
17993       return nullptr;
17994 
17995     ValExpr = MakeFullExpr(Val.get()).get();
17996 
17997     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
17998     CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_novariants,
17999                                                     LangOpts.OpenMP);
18000     if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18001       ValExpr = MakeFullExpr(ValExpr).get();
18002       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18003       ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18004       HelperValStmt = buildPreInits(Context, Captures);
18005     }
18006   }
18007 
18008   return new (Context) OMPNovariantsClause(
18009       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
18010 }
18011 
18012 OMPClause *Sema::ActOnOpenMPNocontextClause(Expr *Condition,
18013                                             SourceLocation StartLoc,
18014                                             SourceLocation LParenLoc,
18015                                             SourceLocation EndLoc) {
18016   Expr *ValExpr = Condition;
18017   Stmt *HelperValStmt = nullptr;
18018   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
18019   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
18020       !Condition->isInstantiationDependent() &&
18021       !Condition->containsUnexpandedParameterPack()) {
18022     ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
18023     if (Val.isInvalid())
18024       return nullptr;
18025 
18026     ValExpr = MakeFullExpr(Val.get()).get();
18027 
18028     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
18029     CaptureRegion =
18030         getOpenMPCaptureRegionForClause(DKind, OMPC_nocontext, LangOpts.OpenMP);
18031     if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18032       ValExpr = MakeFullExpr(ValExpr).get();
18033       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18034       ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18035       HelperValStmt = buildPreInits(Context, Captures);
18036     }
18037   }
18038 
18039   return new (Context) OMPNocontextClause(ValExpr, HelperValStmt, CaptureRegion,
18040                                           StartLoc, LParenLoc, EndLoc);
18041 }
18042 
18043 OMPClause *Sema::ActOnOpenMPFilterClause(Expr *ThreadID,
18044                                          SourceLocation StartLoc,
18045                                          SourceLocation LParenLoc,
18046                                          SourceLocation EndLoc) {
18047   Expr *ValExpr = ThreadID;
18048   Stmt *HelperValStmt = nullptr;
18049 
18050   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
18051   OpenMPDirectiveKind CaptureRegion =
18052       getOpenMPCaptureRegionForClause(DKind, OMPC_filter, LangOpts.OpenMP);
18053   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18054     ValExpr = MakeFullExpr(ValExpr).get();
18055     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18056     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18057     HelperValStmt = buildPreInits(Context, Captures);
18058   }
18059 
18060   return new (Context) OMPFilterClause(ValExpr, HelperValStmt, CaptureRegion,
18061                                        StartLoc, LParenLoc, EndLoc);
18062 }
18063 
18064 OMPClause *Sema::ActOnOpenMPVarListClause(OpenMPClauseKind Kind,
18065                                           ArrayRef<Expr *> VarList,
18066                                           const OMPVarListLocTy &Locs,
18067                                           OpenMPVarListDataTy &Data) {
18068   SourceLocation StartLoc = Locs.StartLoc;
18069   SourceLocation LParenLoc = Locs.LParenLoc;
18070   SourceLocation EndLoc = Locs.EndLoc;
18071   OMPClause *Res = nullptr;
18072   int ExtraModifier = Data.ExtraModifier;
18073   SourceLocation ExtraModifierLoc = Data.ExtraModifierLoc;
18074   SourceLocation ColonLoc = Data.ColonLoc;
18075   switch (Kind) {
18076   case OMPC_private:
18077     Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
18078     break;
18079   case OMPC_firstprivate:
18080     Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
18081     break;
18082   case OMPC_lastprivate:
18083     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown &&
18084            "Unexpected lastprivate modifier.");
18085     Res = ActOnOpenMPLastprivateClause(
18086         VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier),
18087         ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
18088     break;
18089   case OMPC_shared:
18090     Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
18091     break;
18092   case OMPC_reduction:
18093     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown &&
18094            "Unexpected lastprivate modifier.");
18095     Res = ActOnOpenMPReductionClause(
18096         VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier),
18097         StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
18098         Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId);
18099     break;
18100   case OMPC_task_reduction:
18101     Res = ActOnOpenMPTaskReductionClause(
18102         VarList, StartLoc, LParenLoc, ColonLoc, EndLoc,
18103         Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId);
18104     break;
18105   case OMPC_in_reduction:
18106     Res = ActOnOpenMPInReductionClause(
18107         VarList, StartLoc, LParenLoc, ColonLoc, EndLoc,
18108         Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId);
18109     break;
18110   case OMPC_linear:
18111     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown &&
18112            "Unexpected linear modifier.");
18113     Res = ActOnOpenMPLinearClause(
18114         VarList, Data.DepModOrTailExpr, StartLoc, LParenLoc,
18115         static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc,
18116         ColonLoc, Data.StepModifierLoc, EndLoc);
18117     break;
18118   case OMPC_aligned:
18119     Res = ActOnOpenMPAlignedClause(VarList, Data.DepModOrTailExpr, StartLoc,
18120                                    LParenLoc, ColonLoc, EndLoc);
18121     break;
18122   case OMPC_copyin:
18123     Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
18124     break;
18125   case OMPC_copyprivate:
18126     Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
18127     break;
18128   case OMPC_flush:
18129     Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
18130     break;
18131   case OMPC_depend:
18132     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown &&
18133            "Unexpected depend modifier.");
18134     Res = ActOnOpenMPDependClause(
18135         {static_cast<OpenMPDependClauseKind>(ExtraModifier), ExtraModifierLoc,
18136          ColonLoc, Data.OmpAllMemoryLoc},
18137         Data.DepModOrTailExpr, VarList, StartLoc, LParenLoc, EndLoc);
18138     break;
18139   case OMPC_map:
18140     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown &&
18141            "Unexpected map modifier.");
18142     Res = ActOnOpenMPMapClause(
18143         Data.IteratorExpr, Data.MapTypeModifiers, Data.MapTypeModifiersLoc,
18144         Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId,
18145         static_cast<OpenMPMapClauseKind>(ExtraModifier), Data.IsMapTypeImplicit,
18146         ExtraModifierLoc, ColonLoc, VarList, Locs);
18147     break;
18148   case OMPC_to:
18149     Res =
18150         ActOnOpenMPToClause(Data.MotionModifiers, Data.MotionModifiersLoc,
18151                             Data.ReductionOrMapperIdScopeSpec,
18152                             Data.ReductionOrMapperId, ColonLoc, VarList, Locs);
18153     break;
18154   case OMPC_from:
18155     Res = ActOnOpenMPFromClause(Data.MotionModifiers, Data.MotionModifiersLoc,
18156                                 Data.ReductionOrMapperIdScopeSpec,
18157                                 Data.ReductionOrMapperId, ColonLoc, VarList,
18158                                 Locs);
18159     break;
18160   case OMPC_use_device_ptr:
18161     Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
18162     break;
18163   case OMPC_use_device_addr:
18164     Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
18165     break;
18166   case OMPC_is_device_ptr:
18167     Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
18168     break;
18169   case OMPC_has_device_addr:
18170     Res = ActOnOpenMPHasDeviceAddrClause(VarList, Locs);
18171     break;
18172   case OMPC_allocate:
18173     Res = ActOnOpenMPAllocateClause(Data.DepModOrTailExpr, VarList, StartLoc,
18174                                     LParenLoc, ColonLoc, EndLoc);
18175     break;
18176   case OMPC_nontemporal:
18177     Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc);
18178     break;
18179   case OMPC_inclusive:
18180     Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
18181     break;
18182   case OMPC_exclusive:
18183     Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
18184     break;
18185   case OMPC_affinity:
18186     Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc,
18187                                     Data.DepModOrTailExpr, VarList);
18188     break;
18189   case OMPC_doacross:
18190     Res = ActOnOpenMPDoacrossClause(
18191         static_cast<OpenMPDoacrossClauseModifier>(ExtraModifier),
18192         ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
18193     break;
18194   case OMPC_if:
18195   case OMPC_depobj:
18196   case OMPC_final:
18197   case OMPC_num_threads:
18198   case OMPC_safelen:
18199   case OMPC_simdlen:
18200   case OMPC_sizes:
18201   case OMPC_allocator:
18202   case OMPC_collapse:
18203   case OMPC_default:
18204   case OMPC_proc_bind:
18205   case OMPC_schedule:
18206   case OMPC_ordered:
18207   case OMPC_nowait:
18208   case OMPC_untied:
18209   case OMPC_mergeable:
18210   case OMPC_threadprivate:
18211   case OMPC_read:
18212   case OMPC_write:
18213   case OMPC_update:
18214   case OMPC_capture:
18215   case OMPC_compare:
18216   case OMPC_seq_cst:
18217   case OMPC_acq_rel:
18218   case OMPC_acquire:
18219   case OMPC_release:
18220   case OMPC_relaxed:
18221   case OMPC_device:
18222   case OMPC_threads:
18223   case OMPC_simd:
18224   case OMPC_num_teams:
18225   case OMPC_thread_limit:
18226   case OMPC_priority:
18227   case OMPC_grainsize:
18228   case OMPC_nogroup:
18229   case OMPC_num_tasks:
18230   case OMPC_hint:
18231   case OMPC_dist_schedule:
18232   case OMPC_defaultmap:
18233   case OMPC_unknown:
18234   case OMPC_uniform:
18235   case OMPC_unified_address:
18236   case OMPC_unified_shared_memory:
18237   case OMPC_reverse_offload:
18238   case OMPC_dynamic_allocators:
18239   case OMPC_atomic_default_mem_order:
18240   case OMPC_device_type:
18241   case OMPC_match:
18242   case OMPC_order:
18243   case OMPC_at:
18244   case OMPC_severity:
18245   case OMPC_message:
18246   case OMPC_destroy:
18247   case OMPC_novariants:
18248   case OMPC_nocontext:
18249   case OMPC_detach:
18250   case OMPC_uses_allocators:
18251   case OMPC_when:
18252   case OMPC_bind:
18253   default:
18254     llvm_unreachable("Clause is not allowed.");
18255   }
18256   return Res;
18257 }
18258 
18259 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
18260                                        ExprObjectKind OK, SourceLocation Loc) {
18261   ExprResult Res = BuildDeclRefExpr(
18262       Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
18263   if (!Res.isUsable())
18264     return ExprError();
18265   if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
18266     Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
18267     if (!Res.isUsable())
18268       return ExprError();
18269   }
18270   if (VK != VK_LValue && Res.get()->isGLValue()) {
18271     Res = DefaultLvalueConversion(Res.get());
18272     if (!Res.isUsable())
18273       return ExprError();
18274   }
18275   return Res;
18276 }
18277 
18278 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
18279                                           SourceLocation StartLoc,
18280                                           SourceLocation LParenLoc,
18281                                           SourceLocation EndLoc) {
18282   SmallVector<Expr *, 8> Vars;
18283   SmallVector<Expr *, 8> PrivateCopies;
18284   bool IsImplicitClause =
18285       StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
18286   for (Expr *RefExpr : VarList) {
18287     assert(RefExpr && "NULL expr in OpenMP private clause.");
18288     SourceLocation ELoc;
18289     SourceRange ERange;
18290     Expr *SimpleRefExpr = RefExpr;
18291     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18292     if (Res.second) {
18293       // It will be analyzed later.
18294       Vars.push_back(RefExpr);
18295       PrivateCopies.push_back(nullptr);
18296     }
18297     ValueDecl *D = Res.first;
18298     if (!D)
18299       continue;
18300 
18301     QualType Type = D->getType();
18302     auto *VD = dyn_cast<VarDecl>(D);
18303 
18304     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
18305     //  A variable that appears in a private clause must not have an incomplete
18306     //  type or a reference type.
18307     if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
18308       continue;
18309     Type = Type.getNonReferenceType();
18310 
18311     // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
18312     // A variable that is privatized must not have a const-qualified type
18313     // unless it is of class type with a mutable member. This restriction does
18314     // not apply to the firstprivate clause.
18315     //
18316     // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
18317     // A variable that appears in a private clause must not have a
18318     // const-qualified type unless it is of class type with a mutable member.
18319     if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
18320       continue;
18321 
18322     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
18323     // in a Construct]
18324     //  Variables with the predetermined data-sharing attributes may not be
18325     //  listed in data-sharing attributes clauses, except for the cases
18326     //  listed below. For these exceptions only, listing a predetermined
18327     //  variable in a data-sharing attribute clause is allowed and overrides
18328     //  the variable's predetermined data-sharing attributes.
18329     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
18330     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
18331       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
18332                                           << getOpenMPClauseName(OMPC_private);
18333       reportOriginalDsa(*this, DSAStack, D, DVar);
18334       continue;
18335     }
18336 
18337     OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
18338     // Variably modified types are not supported for tasks.
18339     if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
18340         isOpenMPTaskingDirective(CurrDir)) {
18341       Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
18342           << getOpenMPClauseName(OMPC_private) << Type
18343           << getOpenMPDirectiveName(CurrDir);
18344       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18345                                VarDecl::DeclarationOnly;
18346       Diag(D->getLocation(),
18347            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18348           << D;
18349       continue;
18350     }
18351 
18352     // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
18353     // A list item cannot appear in both a map clause and a data-sharing
18354     // attribute clause on the same construct
18355     //
18356     // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
18357     // A list item cannot appear in both a map clause and a data-sharing
18358     // attribute clause on the same construct unless the construct is a
18359     // combined construct.
18360     if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) ||
18361         CurrDir == OMPD_target) {
18362       OpenMPClauseKind ConflictKind;
18363       if (DSAStack->checkMappableExprComponentListsForDecl(
18364               VD, /*CurrentRegionOnly=*/true,
18365               [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
18366                   OpenMPClauseKind WhereFoundClauseKind) -> bool {
18367                 ConflictKind = WhereFoundClauseKind;
18368                 return true;
18369               })) {
18370         Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
18371             << getOpenMPClauseName(OMPC_private)
18372             << getOpenMPClauseName(ConflictKind)
18373             << getOpenMPDirectiveName(CurrDir);
18374         reportOriginalDsa(*this, DSAStack, D, DVar);
18375         continue;
18376       }
18377     }
18378 
18379     // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
18380     //  A variable of class type (or array thereof) that appears in a private
18381     //  clause requires an accessible, unambiguous default constructor for the
18382     //  class type.
18383     // Generate helper private variable and initialize it with the default
18384     // value. The address of the original variable is replaced by the address of
18385     // the new private variable in CodeGen. This new variable is not added to
18386     // IdResolver, so the code in the OpenMP region uses original variable for
18387     // proper diagnostics.
18388     Type = Type.getUnqualifiedType();
18389     VarDecl *VDPrivate =
18390         buildVarDecl(*this, ELoc, Type, D->getName(),
18391                      D->hasAttrs() ? &D->getAttrs() : nullptr,
18392                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
18393     ActOnUninitializedDecl(VDPrivate);
18394     if (VDPrivate->isInvalidDecl())
18395       continue;
18396     DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
18397         *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
18398 
18399     DeclRefExpr *Ref = nullptr;
18400     if (!VD && !CurContext->isDependentContext()) {
18401       auto *FD = dyn_cast<FieldDecl>(D);
18402       VarDecl *VD = FD ? DSAStack->getImplicitFDCapExprDecl(FD) : nullptr;
18403       if (VD)
18404         Ref = buildDeclRefExpr(*this, VD, VD->getType().getNonReferenceType(),
18405                                RefExpr->getExprLoc());
18406       else
18407         Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
18408     }
18409     if (!IsImplicitClause)
18410       DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
18411     Vars.push_back((VD || CurContext->isDependentContext())
18412                        ? RefExpr->IgnoreParens()
18413                        : Ref);
18414     PrivateCopies.push_back(VDPrivateRefExpr);
18415   }
18416 
18417   if (Vars.empty())
18418     return nullptr;
18419 
18420   return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
18421                                   PrivateCopies);
18422 }
18423 
18424 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
18425                                                SourceLocation StartLoc,
18426                                                SourceLocation LParenLoc,
18427                                                SourceLocation EndLoc) {
18428   SmallVector<Expr *, 8> Vars;
18429   SmallVector<Expr *, 8> PrivateCopies;
18430   SmallVector<Expr *, 8> Inits;
18431   SmallVector<Decl *, 4> ExprCaptures;
18432   bool IsImplicitClause =
18433       StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
18434   SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc();
18435 
18436   for (Expr *RefExpr : VarList) {
18437     assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
18438     SourceLocation ELoc;
18439     SourceRange ERange;
18440     Expr *SimpleRefExpr = RefExpr;
18441     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18442     if (Res.second) {
18443       // It will be analyzed later.
18444       Vars.push_back(RefExpr);
18445       PrivateCopies.push_back(nullptr);
18446       Inits.push_back(nullptr);
18447     }
18448     ValueDecl *D = Res.first;
18449     if (!D)
18450       continue;
18451 
18452     ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
18453     QualType Type = D->getType();
18454     auto *VD = dyn_cast<VarDecl>(D);
18455 
18456     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
18457     //  A variable that appears in a private clause must not have an incomplete
18458     //  type or a reference type.
18459     if (RequireCompleteType(ELoc, Type,
18460                             diag::err_omp_firstprivate_incomplete_type))
18461       continue;
18462     Type = Type.getNonReferenceType();
18463 
18464     // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
18465     //  A variable of class type (or array thereof) that appears in a private
18466     //  clause requires an accessible, unambiguous copy constructor for the
18467     //  class type.
18468     QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
18469 
18470     // If an implicit firstprivate variable found it was checked already.
18471     DSAStackTy::DSAVarData TopDVar;
18472     if (!IsImplicitClause) {
18473       DSAStackTy::DSAVarData DVar =
18474           DSAStack->getTopDSA(D, /*FromParent=*/false);
18475       TopDVar = DVar;
18476       OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
18477       bool IsConstant = ElemType.isConstant(Context);
18478       // OpenMP [2.4.13, Data-sharing Attribute Clauses]
18479       //  A list item that specifies a given variable may not appear in more
18480       // than one clause on the same directive, except that a variable may be
18481       //  specified in both firstprivate and lastprivate clauses.
18482       // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
18483       // A list item may appear in a firstprivate or lastprivate clause but not
18484       // both.
18485       if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
18486           (isOpenMPDistributeDirective(CurrDir) ||
18487            DVar.CKind != OMPC_lastprivate) &&
18488           DVar.RefExpr) {
18489         Diag(ELoc, diag::err_omp_wrong_dsa)
18490             << getOpenMPClauseName(DVar.CKind)
18491             << getOpenMPClauseName(OMPC_firstprivate);
18492         reportOriginalDsa(*this, DSAStack, D, DVar);
18493         continue;
18494       }
18495 
18496       // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
18497       // in a Construct]
18498       //  Variables with the predetermined data-sharing attributes may not be
18499       //  listed in data-sharing attributes clauses, except for the cases
18500       //  listed below. For these exceptions only, listing a predetermined
18501       //  variable in a data-sharing attribute clause is allowed and overrides
18502       //  the variable's predetermined data-sharing attributes.
18503       // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
18504       // in a Construct, C/C++, p.2]
18505       //  Variables with const-qualified type having no mutable member may be
18506       //  listed in a firstprivate clause, even if they are static data members.
18507       if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
18508           DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
18509         Diag(ELoc, diag::err_omp_wrong_dsa)
18510             << getOpenMPClauseName(DVar.CKind)
18511             << getOpenMPClauseName(OMPC_firstprivate);
18512         reportOriginalDsa(*this, DSAStack, D, DVar);
18513         continue;
18514       }
18515 
18516       // OpenMP [2.9.3.4, Restrictions, p.2]
18517       //  A list item that is private within a parallel region must not appear
18518       //  in a firstprivate clause on a worksharing construct if any of the
18519       //  worksharing regions arising from the worksharing construct ever bind
18520       //  to any of the parallel regions arising from the parallel construct.
18521       // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
18522       // A list item that is private within a teams region must not appear in a
18523       // firstprivate clause on a distribute construct if any of the distribute
18524       // regions arising from the distribute construct ever bind to any of the
18525       // teams regions arising from the teams construct.
18526       // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
18527       // A list item that appears in a reduction clause of a teams construct
18528       // must not appear in a firstprivate clause on a distribute construct if
18529       // any of the distribute regions arising from the distribute construct
18530       // ever bind to any of the teams regions arising from the teams construct.
18531       if ((isOpenMPWorksharingDirective(CurrDir) ||
18532            isOpenMPDistributeDirective(CurrDir)) &&
18533           !isOpenMPParallelDirective(CurrDir) &&
18534           !isOpenMPTeamsDirective(CurrDir)) {
18535         DVar = DSAStack->getImplicitDSA(D, true);
18536         if (DVar.CKind != OMPC_shared &&
18537             (isOpenMPParallelDirective(DVar.DKind) ||
18538              isOpenMPTeamsDirective(DVar.DKind) ||
18539              DVar.DKind == OMPD_unknown)) {
18540           Diag(ELoc, diag::err_omp_required_access)
18541               << getOpenMPClauseName(OMPC_firstprivate)
18542               << getOpenMPClauseName(OMPC_shared);
18543           reportOriginalDsa(*this, DSAStack, D, DVar);
18544           continue;
18545         }
18546       }
18547       // OpenMP [2.9.3.4, Restrictions, p.3]
18548       //  A list item that appears in a reduction clause of a parallel construct
18549       //  must not appear in a firstprivate clause on a worksharing or task
18550       //  construct if any of the worksharing or task regions arising from the
18551       //  worksharing or task construct ever bind to any of the parallel regions
18552       //  arising from the parallel construct.
18553       // OpenMP [2.9.3.4, Restrictions, p.4]
18554       //  A list item that appears in a reduction clause in worksharing
18555       //  construct must not appear in a firstprivate clause in a task construct
18556       //  encountered during execution of any of the worksharing regions arising
18557       //  from the worksharing construct.
18558       if (isOpenMPTaskingDirective(CurrDir)) {
18559         DVar = DSAStack->hasInnermostDSA(
18560             D,
18561             [](OpenMPClauseKind C, bool AppliedToPointee) {
18562               return C == OMPC_reduction && !AppliedToPointee;
18563             },
18564             [](OpenMPDirectiveKind K) {
18565               return isOpenMPParallelDirective(K) ||
18566                      isOpenMPWorksharingDirective(K) ||
18567                      isOpenMPTeamsDirective(K);
18568             },
18569             /*FromParent=*/true);
18570         if (DVar.CKind == OMPC_reduction &&
18571             (isOpenMPParallelDirective(DVar.DKind) ||
18572              isOpenMPWorksharingDirective(DVar.DKind) ||
18573              isOpenMPTeamsDirective(DVar.DKind))) {
18574           Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
18575               << getOpenMPDirectiveName(DVar.DKind);
18576           reportOriginalDsa(*this, DSAStack, D, DVar);
18577           continue;
18578         }
18579       }
18580 
18581       // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
18582       // A list item cannot appear in both a map clause and a data-sharing
18583       // attribute clause on the same construct
18584       //
18585       // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
18586       // A list item cannot appear in both a map clause and a data-sharing
18587       // attribute clause on the same construct unless the construct is a
18588       // combined construct.
18589       if ((LangOpts.OpenMP <= 45 &&
18590            isOpenMPTargetExecutionDirective(CurrDir)) ||
18591           CurrDir == OMPD_target) {
18592         OpenMPClauseKind ConflictKind;
18593         if (DSAStack->checkMappableExprComponentListsForDecl(
18594                 VD, /*CurrentRegionOnly=*/true,
18595                 [&ConflictKind](
18596                     OMPClauseMappableExprCommon::MappableExprComponentListRef,
18597                     OpenMPClauseKind WhereFoundClauseKind) {
18598                   ConflictKind = WhereFoundClauseKind;
18599                   return true;
18600                 })) {
18601           Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
18602               << getOpenMPClauseName(OMPC_firstprivate)
18603               << getOpenMPClauseName(ConflictKind)
18604               << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
18605           reportOriginalDsa(*this, DSAStack, D, DVar);
18606           continue;
18607         }
18608       }
18609     }
18610 
18611     // Variably modified types are not supported for tasks.
18612     if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
18613         isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
18614       Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
18615           << getOpenMPClauseName(OMPC_firstprivate) << Type
18616           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
18617       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18618                                VarDecl::DeclarationOnly;
18619       Diag(D->getLocation(),
18620            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18621           << D;
18622       continue;
18623     }
18624 
18625     Type = Type.getUnqualifiedType();
18626     VarDecl *VDPrivate =
18627         buildVarDecl(*this, ELoc, Type, D->getName(),
18628                      D->hasAttrs() ? &D->getAttrs() : nullptr,
18629                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
18630     // Generate helper private variable and initialize it with the value of the
18631     // original variable. The address of the original variable is replaced by
18632     // the address of the new private variable in the CodeGen. This new variable
18633     // is not added to IdResolver, so the code in the OpenMP region uses
18634     // original variable for proper diagnostics and variable capturing.
18635     Expr *VDInitRefExpr = nullptr;
18636     // For arrays generate initializer for single element and replace it by the
18637     // original array element in CodeGen.
18638     if (Type->isArrayType()) {
18639       VarDecl *VDInit =
18640           buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
18641       VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
18642       Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
18643       ElemType = ElemType.getUnqualifiedType();
18644       VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
18645                                          ".firstprivate.temp");
18646       InitializedEntity Entity =
18647           InitializedEntity::InitializeVariable(VDInitTemp);
18648       InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
18649 
18650       InitializationSequence InitSeq(*this, Entity, Kind, Init);
18651       ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
18652       if (Result.isInvalid())
18653         VDPrivate->setInvalidDecl();
18654       else
18655         VDPrivate->setInit(Result.getAs<Expr>());
18656       // Remove temp variable declaration.
18657       Context.Deallocate(VDInitTemp);
18658     } else {
18659       VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
18660                                      ".firstprivate.temp");
18661       VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
18662                                        RefExpr->getExprLoc());
18663       AddInitializerToDecl(VDPrivate,
18664                            DefaultLvalueConversion(VDInitRefExpr).get(),
18665                            /*DirectInit=*/false);
18666     }
18667     if (VDPrivate->isInvalidDecl()) {
18668       if (IsImplicitClause) {
18669         Diag(RefExpr->getExprLoc(),
18670              diag::note_omp_task_predetermined_firstprivate_here);
18671       }
18672       continue;
18673     }
18674     CurContext->addDecl(VDPrivate);
18675     DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
18676         *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
18677         RefExpr->getExprLoc());
18678     DeclRefExpr *Ref = nullptr;
18679     if (!VD && !CurContext->isDependentContext()) {
18680       if (TopDVar.CKind == OMPC_lastprivate) {
18681         Ref = TopDVar.PrivateCopy;
18682       } else {
18683         auto *FD = dyn_cast<FieldDecl>(D);
18684         VarDecl *VD = FD ? DSAStack->getImplicitFDCapExprDecl(FD) : nullptr;
18685         if (VD)
18686           Ref = buildDeclRefExpr(*this, VD, VD->getType().getNonReferenceType(),
18687                                  RefExpr->getExprLoc());
18688         else
18689           Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
18690         if (VD || !isOpenMPCapturedDecl(D))
18691           ExprCaptures.push_back(Ref->getDecl());
18692       }
18693     }
18694     if (!IsImplicitClause)
18695       DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
18696     Vars.push_back((VD || CurContext->isDependentContext())
18697                        ? RefExpr->IgnoreParens()
18698                        : Ref);
18699     PrivateCopies.push_back(VDPrivateRefExpr);
18700     Inits.push_back(VDInitRefExpr);
18701   }
18702 
18703   if (Vars.empty())
18704     return nullptr;
18705 
18706   return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
18707                                        Vars, PrivateCopies, Inits,
18708                                        buildPreInits(Context, ExprCaptures));
18709 }
18710 
18711 OMPClause *Sema::ActOnOpenMPLastprivateClause(
18712     ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind,
18713     SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc,
18714     SourceLocation LParenLoc, SourceLocation EndLoc) {
18715   if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) {
18716     assert(ColonLoc.isValid() && "Colon location must be valid.");
18717     Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
18718         << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0,
18719                                    /*Last=*/OMPC_LASTPRIVATE_unknown)
18720         << getOpenMPClauseName(OMPC_lastprivate);
18721     return nullptr;
18722   }
18723 
18724   SmallVector<Expr *, 8> Vars;
18725   SmallVector<Expr *, 8> SrcExprs;
18726   SmallVector<Expr *, 8> DstExprs;
18727   SmallVector<Expr *, 8> AssignmentOps;
18728   SmallVector<Decl *, 4> ExprCaptures;
18729   SmallVector<Expr *, 4> ExprPostUpdates;
18730   for (Expr *RefExpr : VarList) {
18731     assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
18732     SourceLocation ELoc;
18733     SourceRange ERange;
18734     Expr *SimpleRefExpr = RefExpr;
18735     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18736     if (Res.second) {
18737       // It will be analyzed later.
18738       Vars.push_back(RefExpr);
18739       SrcExprs.push_back(nullptr);
18740       DstExprs.push_back(nullptr);
18741       AssignmentOps.push_back(nullptr);
18742     }
18743     ValueDecl *D = Res.first;
18744     if (!D)
18745       continue;
18746 
18747     QualType Type = D->getType();
18748     auto *VD = dyn_cast<VarDecl>(D);
18749 
18750     // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
18751     //  A variable that appears in a lastprivate clause must not have an
18752     //  incomplete type or a reference type.
18753     if (RequireCompleteType(ELoc, Type,
18754                             diag::err_omp_lastprivate_incomplete_type))
18755       continue;
18756     Type = Type.getNonReferenceType();
18757 
18758     // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
18759     // A variable that is privatized must not have a const-qualified type
18760     // unless it is of class type with a mutable member. This restriction does
18761     // not apply to the firstprivate clause.
18762     //
18763     // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
18764     // A variable that appears in a lastprivate clause must not have a
18765     // const-qualified type unless it is of class type with a mutable member.
18766     if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
18767       continue;
18768 
18769     // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions]
18770     // A list item that appears in a lastprivate clause with the conditional
18771     // modifier must be a scalar variable.
18772     if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) {
18773       Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
18774       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18775                                VarDecl::DeclarationOnly;
18776       Diag(D->getLocation(),
18777            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18778           << D;
18779       continue;
18780     }
18781 
18782     OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
18783     // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
18784     // in a Construct]
18785     //  Variables with the predetermined data-sharing attributes may not be
18786     //  listed in data-sharing attributes clauses, except for the cases
18787     //  listed below.
18788     // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
18789     // A list item may appear in a firstprivate or lastprivate clause but not
18790     // both.
18791     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
18792     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
18793         (isOpenMPDistributeDirective(CurrDir) ||
18794          DVar.CKind != OMPC_firstprivate) &&
18795         (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
18796       Diag(ELoc, diag::err_omp_wrong_dsa)
18797           << getOpenMPClauseName(DVar.CKind)
18798           << getOpenMPClauseName(OMPC_lastprivate);
18799       reportOriginalDsa(*this, DSAStack, D, DVar);
18800       continue;
18801     }
18802 
18803     // OpenMP [2.14.3.5, Restrictions, p.2]
18804     // A list item that is private within a parallel region, or that appears in
18805     // the reduction clause of a parallel construct, must not appear in a
18806     // lastprivate clause on a worksharing construct if any of the corresponding
18807     // worksharing regions ever binds to any of the corresponding parallel
18808     // regions.
18809     DSAStackTy::DSAVarData TopDVar = DVar;
18810     if (isOpenMPWorksharingDirective(CurrDir) &&
18811         !isOpenMPParallelDirective(CurrDir) &&
18812         !isOpenMPTeamsDirective(CurrDir)) {
18813       DVar = DSAStack->getImplicitDSA(D, true);
18814       if (DVar.CKind != OMPC_shared) {
18815         Diag(ELoc, diag::err_omp_required_access)
18816             << getOpenMPClauseName(OMPC_lastprivate)
18817             << getOpenMPClauseName(OMPC_shared);
18818         reportOriginalDsa(*this, DSAStack, D, DVar);
18819         continue;
18820       }
18821     }
18822 
18823     // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
18824     //  A variable of class type (or array thereof) that appears in a
18825     //  lastprivate clause requires an accessible, unambiguous default
18826     //  constructor for the class type, unless the list item is also specified
18827     //  in a firstprivate clause.
18828     //  A variable of class type (or array thereof) that appears in a
18829     //  lastprivate clause requires an accessible, unambiguous copy assignment
18830     //  operator for the class type.
18831     Type = Context.getBaseElementType(Type).getNonReferenceType();
18832     VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
18833                                   Type.getUnqualifiedType(), ".lastprivate.src",
18834                                   D->hasAttrs() ? &D->getAttrs() : nullptr);
18835     DeclRefExpr *PseudoSrcExpr =
18836         buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
18837     VarDecl *DstVD =
18838         buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
18839                      D->hasAttrs() ? &D->getAttrs() : nullptr);
18840     DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
18841     // For arrays generate assignment operation for single element and replace
18842     // it by the original array element in CodeGen.
18843     ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
18844                                          PseudoDstExpr, PseudoSrcExpr);
18845     if (AssignmentOp.isInvalid())
18846       continue;
18847     AssignmentOp =
18848         ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
18849     if (AssignmentOp.isInvalid())
18850       continue;
18851 
18852     DeclRefExpr *Ref = nullptr;
18853     if (!VD && !CurContext->isDependentContext()) {
18854       if (TopDVar.CKind == OMPC_firstprivate) {
18855         Ref = TopDVar.PrivateCopy;
18856       } else {
18857         Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
18858         if (!isOpenMPCapturedDecl(D))
18859           ExprCaptures.push_back(Ref->getDecl());
18860       }
18861       if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) ||
18862           (!isOpenMPCapturedDecl(D) &&
18863            Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
18864         ExprResult RefRes = DefaultLvalueConversion(Ref);
18865         if (!RefRes.isUsable())
18866           continue;
18867         ExprResult PostUpdateRes =
18868             BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
18869                        RefRes.get());
18870         if (!PostUpdateRes.isUsable())
18871           continue;
18872         ExprPostUpdates.push_back(
18873             IgnoredValueConversions(PostUpdateRes.get()).get());
18874       }
18875     }
18876     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
18877     Vars.push_back((VD || CurContext->isDependentContext())
18878                        ? RefExpr->IgnoreParens()
18879                        : Ref);
18880     SrcExprs.push_back(PseudoSrcExpr);
18881     DstExprs.push_back(PseudoDstExpr);
18882     AssignmentOps.push_back(AssignmentOp.get());
18883   }
18884 
18885   if (Vars.empty())
18886     return nullptr;
18887 
18888   return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
18889                                       Vars, SrcExprs, DstExprs, AssignmentOps,
18890                                       LPKind, LPKindLoc, ColonLoc,
18891                                       buildPreInits(Context, ExprCaptures),
18892                                       buildPostUpdate(*this, ExprPostUpdates));
18893 }
18894 
18895 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
18896                                          SourceLocation StartLoc,
18897                                          SourceLocation LParenLoc,
18898                                          SourceLocation EndLoc) {
18899   SmallVector<Expr *, 8> Vars;
18900   for (Expr *RefExpr : VarList) {
18901     assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
18902     SourceLocation ELoc;
18903     SourceRange ERange;
18904     Expr *SimpleRefExpr = RefExpr;
18905     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18906     if (Res.second) {
18907       // It will be analyzed later.
18908       Vars.push_back(RefExpr);
18909     }
18910     ValueDecl *D = Res.first;
18911     if (!D)
18912       continue;
18913 
18914     auto *VD = dyn_cast<VarDecl>(D);
18915     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
18916     // in a Construct]
18917     //  Variables with the predetermined data-sharing attributes may not be
18918     //  listed in data-sharing attributes clauses, except for the cases
18919     //  listed below. For these exceptions only, listing a predetermined
18920     //  variable in a data-sharing attribute clause is allowed and overrides
18921     //  the variable's predetermined data-sharing attributes.
18922     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
18923     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
18924         DVar.RefExpr) {
18925       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
18926                                           << getOpenMPClauseName(OMPC_shared);
18927       reportOriginalDsa(*this, DSAStack, D, DVar);
18928       continue;
18929     }
18930 
18931     DeclRefExpr *Ref = nullptr;
18932     if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
18933       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
18934     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
18935     Vars.push_back((VD || !Ref || CurContext->isDependentContext())
18936                        ? RefExpr->IgnoreParens()
18937                        : Ref);
18938   }
18939 
18940   if (Vars.empty())
18941     return nullptr;
18942 
18943   return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
18944 }
18945 
18946 namespace {
18947 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
18948   DSAStackTy *Stack;
18949 
18950 public:
18951   bool VisitDeclRefExpr(DeclRefExpr *E) {
18952     if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
18953       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
18954       if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
18955         return false;
18956       if (DVar.CKind != OMPC_unknown)
18957         return true;
18958       DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
18959           VD,
18960           [](OpenMPClauseKind C, bool AppliedToPointee, bool) {
18961             return isOpenMPPrivate(C) && !AppliedToPointee;
18962           },
18963           [](OpenMPDirectiveKind) { return true; },
18964           /*FromParent=*/true);
18965       return DVarPrivate.CKind != OMPC_unknown;
18966     }
18967     return false;
18968   }
18969   bool VisitStmt(Stmt *S) {
18970     for (Stmt *Child : S->children()) {
18971       if (Child && Visit(Child))
18972         return true;
18973     }
18974     return false;
18975   }
18976   explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
18977 };
18978 } // namespace
18979 
18980 namespace {
18981 // Transform MemberExpression for specified FieldDecl of current class to
18982 // DeclRefExpr to specified OMPCapturedExprDecl.
18983 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
18984   typedef TreeTransform<TransformExprToCaptures> BaseTransform;
18985   ValueDecl *Field = nullptr;
18986   DeclRefExpr *CapturedExpr = nullptr;
18987 
18988 public:
18989   TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
18990       : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
18991 
18992   ExprResult TransformMemberExpr(MemberExpr *E) {
18993     if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
18994         E->getMemberDecl() == Field) {
18995       CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
18996       return CapturedExpr;
18997     }
18998     return BaseTransform::TransformMemberExpr(E);
18999   }
19000   DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
19001 };
19002 } // namespace
19003 
19004 template <typename T, typename U>
19005 static T filterLookupForUDReductionAndMapper(
19006     SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
19007   for (U &Set : Lookups) {
19008     for (auto *D : Set) {
19009       if (T Res = Gen(cast<ValueDecl>(D)))
19010         return Res;
19011     }
19012   }
19013   return T();
19014 }
19015 
19016 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
19017   assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case");
19018 
19019   for (auto *RD : D->redecls()) {
19020     // Don't bother with extra checks if we already know this one isn't visible.
19021     if (RD == D)
19022       continue;
19023 
19024     auto ND = cast<NamedDecl>(RD);
19025     if (LookupResult::isVisible(SemaRef, ND))
19026       return ND;
19027   }
19028 
19029   return nullptr;
19030 }
19031 
19032 static void
19033 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id,
19034                         SourceLocation Loc, QualType Ty,
19035                         SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
19036   // Find all of the associated namespaces and classes based on the
19037   // arguments we have.
19038   Sema::AssociatedNamespaceSet AssociatedNamespaces;
19039   Sema::AssociatedClassSet AssociatedClasses;
19040   OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
19041   SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
19042                                              AssociatedClasses);
19043 
19044   // C++ [basic.lookup.argdep]p3:
19045   //   Let X be the lookup set produced by unqualified lookup (3.4.1)
19046   //   and let Y be the lookup set produced by argument dependent
19047   //   lookup (defined as follows). If X contains [...] then Y is
19048   //   empty. Otherwise Y is the set of declarations found in the
19049   //   namespaces associated with the argument types as described
19050   //   below. The set of declarations found by the lookup of the name
19051   //   is the union of X and Y.
19052   //
19053   // Here, we compute Y and add its members to the overloaded
19054   // candidate set.
19055   for (auto *NS : AssociatedNamespaces) {
19056     //   When considering an associated namespace, the lookup is the
19057     //   same as the lookup performed when the associated namespace is
19058     //   used as a qualifier (3.4.3.2) except that:
19059     //
19060     //     -- Any using-directives in the associated namespace are
19061     //        ignored.
19062     //
19063     //     -- Any namespace-scope friend functions declared in
19064     //        associated classes are visible within their respective
19065     //        namespaces even if they are not visible during an ordinary
19066     //        lookup (11.4).
19067     DeclContext::lookup_result R = NS->lookup(Id.getName());
19068     for (auto *D : R) {
19069       auto *Underlying = D;
19070       if (auto *USD = dyn_cast<UsingShadowDecl>(D))
19071         Underlying = USD->getTargetDecl();
19072 
19073       if (!isa<OMPDeclareReductionDecl>(Underlying) &&
19074           !isa<OMPDeclareMapperDecl>(Underlying))
19075         continue;
19076 
19077       if (!SemaRef.isVisible(D)) {
19078         D = findAcceptableDecl(SemaRef, D);
19079         if (!D)
19080           continue;
19081         if (auto *USD = dyn_cast<UsingShadowDecl>(D))
19082           Underlying = USD->getTargetDecl();
19083       }
19084       Lookups.emplace_back();
19085       Lookups.back().addDecl(Underlying);
19086     }
19087   }
19088 }
19089 
19090 static ExprResult
19091 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
19092                          Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
19093                          const DeclarationNameInfo &ReductionId, QualType Ty,
19094                          CXXCastPath &BasePath, Expr *UnresolvedReduction) {
19095   if (ReductionIdScopeSpec.isInvalid())
19096     return ExprError();
19097   SmallVector<UnresolvedSet<8>, 4> Lookups;
19098   if (S) {
19099     LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
19100     Lookup.suppressDiagnostics();
19101     while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
19102       NamedDecl *D = Lookup.getRepresentativeDecl();
19103       do {
19104         S = S->getParent();
19105       } while (S && !S->isDeclScope(D));
19106       if (S)
19107         S = S->getParent();
19108       Lookups.emplace_back();
19109       Lookups.back().append(Lookup.begin(), Lookup.end());
19110       Lookup.clear();
19111     }
19112   } else if (auto *ULE =
19113                  cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
19114     Lookups.push_back(UnresolvedSet<8>());
19115     Decl *PrevD = nullptr;
19116     for (NamedDecl *D : ULE->decls()) {
19117       if (D == PrevD)
19118         Lookups.push_back(UnresolvedSet<8>());
19119       else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
19120         Lookups.back().addDecl(DRD);
19121       PrevD = D;
19122     }
19123   }
19124   if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
19125       Ty->isInstantiationDependentType() ||
19126       Ty->containsUnexpandedParameterPack() ||
19127       filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
19128         return !D->isInvalidDecl() &&
19129                (D->getType()->isDependentType() ||
19130                 D->getType()->isInstantiationDependentType() ||
19131                 D->getType()->containsUnexpandedParameterPack());
19132       })) {
19133     UnresolvedSet<8> ResSet;
19134     for (const UnresolvedSet<8> &Set : Lookups) {
19135       if (Set.empty())
19136         continue;
19137       ResSet.append(Set.begin(), Set.end());
19138       // The last item marks the end of all declarations at the specified scope.
19139       ResSet.addDecl(Set[Set.size() - 1]);
19140     }
19141     return UnresolvedLookupExpr::Create(
19142         SemaRef.Context, /*NamingClass=*/nullptr,
19143         ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
19144         /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
19145   }
19146   // Lookup inside the classes.
19147   // C++ [over.match.oper]p3:
19148   //   For a unary operator @ with an operand of a type whose
19149   //   cv-unqualified version is T1, and for a binary operator @ with
19150   //   a left operand of a type whose cv-unqualified version is T1 and
19151   //   a right operand of a type whose cv-unqualified version is T2,
19152   //   three sets of candidate functions, designated member
19153   //   candidates, non-member candidates and built-in candidates, are
19154   //   constructed as follows:
19155   //     -- If T1 is a complete class type or a class currently being
19156   //        defined, the set of member candidates is the result of the
19157   //        qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
19158   //        the set of member candidates is empty.
19159   LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
19160   Lookup.suppressDiagnostics();
19161   if (const auto *TyRec = Ty->getAs<RecordType>()) {
19162     // Complete the type if it can be completed.
19163     // If the type is neither complete nor being defined, bail out now.
19164     if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
19165         TyRec->getDecl()->getDefinition()) {
19166       Lookup.clear();
19167       SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
19168       if (Lookup.empty()) {
19169         Lookups.emplace_back();
19170         Lookups.back().append(Lookup.begin(), Lookup.end());
19171       }
19172     }
19173   }
19174   // Perform ADL.
19175   if (SemaRef.getLangOpts().CPlusPlus)
19176     argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
19177   if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
19178           Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
19179             if (!D->isInvalidDecl() &&
19180                 SemaRef.Context.hasSameType(D->getType(), Ty))
19181               return D;
19182             return nullptr;
19183           }))
19184     return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
19185                                     VK_LValue, Loc);
19186   if (SemaRef.getLangOpts().CPlusPlus) {
19187     if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
19188             Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
19189               if (!D->isInvalidDecl() &&
19190                   SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
19191                   !Ty.isMoreQualifiedThan(D->getType()))
19192                 return D;
19193               return nullptr;
19194             })) {
19195       CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
19196                          /*DetectVirtual=*/false);
19197       if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
19198         if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
19199                 VD->getType().getUnqualifiedType()))) {
19200           if (SemaRef.CheckBaseClassAccess(
19201                   Loc, VD->getType(), Ty, Paths.front(),
19202                   /*DiagID=*/0) != Sema::AR_inaccessible) {
19203             SemaRef.BuildBasePathArray(Paths, BasePath);
19204             return SemaRef.BuildDeclRefExpr(
19205                 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
19206           }
19207         }
19208       }
19209     }
19210   }
19211   if (ReductionIdScopeSpec.isSet()) {
19212     SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
19213         << Ty << Range;
19214     return ExprError();
19215   }
19216   return ExprEmpty();
19217 }
19218 
19219 namespace {
19220 /// Data for the reduction-based clauses.
19221 struct ReductionData {
19222   /// List of original reduction items.
19223   SmallVector<Expr *, 8> Vars;
19224   /// List of private copies of the reduction items.
19225   SmallVector<Expr *, 8> Privates;
19226   /// LHS expressions for the reduction_op expressions.
19227   SmallVector<Expr *, 8> LHSs;
19228   /// RHS expressions for the reduction_op expressions.
19229   SmallVector<Expr *, 8> RHSs;
19230   /// Reduction operation expression.
19231   SmallVector<Expr *, 8> ReductionOps;
19232   /// inscan copy operation expressions.
19233   SmallVector<Expr *, 8> InscanCopyOps;
19234   /// inscan copy temp array expressions for prefix sums.
19235   SmallVector<Expr *, 8> InscanCopyArrayTemps;
19236   /// inscan copy temp array element expressions for prefix sums.
19237   SmallVector<Expr *, 8> InscanCopyArrayElems;
19238   /// Taskgroup descriptors for the corresponding reduction items in
19239   /// in_reduction clauses.
19240   SmallVector<Expr *, 8> TaskgroupDescriptors;
19241   /// List of captures for clause.
19242   SmallVector<Decl *, 4> ExprCaptures;
19243   /// List of postupdate expressions.
19244   SmallVector<Expr *, 4> ExprPostUpdates;
19245   /// Reduction modifier.
19246   unsigned RedModifier = 0;
19247   ReductionData() = delete;
19248   /// Reserves required memory for the reduction data.
19249   ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) {
19250     Vars.reserve(Size);
19251     Privates.reserve(Size);
19252     LHSs.reserve(Size);
19253     RHSs.reserve(Size);
19254     ReductionOps.reserve(Size);
19255     if (RedModifier == OMPC_REDUCTION_inscan) {
19256       InscanCopyOps.reserve(Size);
19257       InscanCopyArrayTemps.reserve(Size);
19258       InscanCopyArrayElems.reserve(Size);
19259     }
19260     TaskgroupDescriptors.reserve(Size);
19261     ExprCaptures.reserve(Size);
19262     ExprPostUpdates.reserve(Size);
19263   }
19264   /// Stores reduction item and reduction operation only (required for dependent
19265   /// reduction item).
19266   void push(Expr *Item, Expr *ReductionOp) {
19267     Vars.emplace_back(Item);
19268     Privates.emplace_back(nullptr);
19269     LHSs.emplace_back(nullptr);
19270     RHSs.emplace_back(nullptr);
19271     ReductionOps.emplace_back(ReductionOp);
19272     TaskgroupDescriptors.emplace_back(nullptr);
19273     if (RedModifier == OMPC_REDUCTION_inscan) {
19274       InscanCopyOps.push_back(nullptr);
19275       InscanCopyArrayTemps.push_back(nullptr);
19276       InscanCopyArrayElems.push_back(nullptr);
19277     }
19278   }
19279   /// Stores reduction data.
19280   void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
19281             Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp,
19282             Expr *CopyArrayElem) {
19283     Vars.emplace_back(Item);
19284     Privates.emplace_back(Private);
19285     LHSs.emplace_back(LHS);
19286     RHSs.emplace_back(RHS);
19287     ReductionOps.emplace_back(ReductionOp);
19288     TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
19289     if (RedModifier == OMPC_REDUCTION_inscan) {
19290       InscanCopyOps.push_back(CopyOp);
19291       InscanCopyArrayTemps.push_back(CopyArrayTemp);
19292       InscanCopyArrayElems.push_back(CopyArrayElem);
19293     } else {
19294       assert(CopyOp == nullptr && CopyArrayTemp == nullptr &&
19295              CopyArrayElem == nullptr &&
19296              "Copy operation must be used for inscan reductions only.");
19297     }
19298   }
19299 };
19300 } // namespace
19301 
19302 static bool checkOMPArraySectionConstantForReduction(
19303     ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
19304     SmallVectorImpl<llvm::APSInt> &ArraySizes) {
19305   const Expr *Length = OASE->getLength();
19306   if (Length == nullptr) {
19307     // For array sections of the form [1:] or [:], we would need to analyze
19308     // the lower bound...
19309     if (OASE->getColonLocFirst().isValid())
19310       return false;
19311 
19312     // This is an array subscript which has implicit length 1!
19313     SingleElement = true;
19314     ArraySizes.push_back(llvm::APSInt::get(1));
19315   } else {
19316     Expr::EvalResult Result;
19317     if (!Length->EvaluateAsInt(Result, Context))
19318       return false;
19319 
19320     llvm::APSInt ConstantLengthValue = Result.Val.getInt();
19321     SingleElement = (ConstantLengthValue.getSExtValue() == 1);
19322     ArraySizes.push_back(ConstantLengthValue);
19323   }
19324 
19325   // Get the base of this array section and walk up from there.
19326   const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
19327 
19328   // We require length = 1 for all array sections except the right-most to
19329   // guarantee that the memory region is contiguous and has no holes in it.
19330   while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
19331     Length = TempOASE->getLength();
19332     if (Length == nullptr) {
19333       // For array sections of the form [1:] or [:], we would need to analyze
19334       // the lower bound...
19335       if (OASE->getColonLocFirst().isValid())
19336         return false;
19337 
19338       // This is an array subscript which has implicit length 1!
19339       ArraySizes.push_back(llvm::APSInt::get(1));
19340     } else {
19341       Expr::EvalResult Result;
19342       if (!Length->EvaluateAsInt(Result, Context))
19343         return false;
19344 
19345       llvm::APSInt ConstantLengthValue = Result.Val.getInt();
19346       if (ConstantLengthValue.getSExtValue() != 1)
19347         return false;
19348 
19349       ArraySizes.push_back(ConstantLengthValue);
19350     }
19351     Base = TempOASE->getBase()->IgnoreParenImpCasts();
19352   }
19353 
19354   // If we have a single element, we don't need to add the implicit lengths.
19355   if (!SingleElement) {
19356     while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
19357       // Has implicit length 1!
19358       ArraySizes.push_back(llvm::APSInt::get(1));
19359       Base = TempASE->getBase()->IgnoreParenImpCasts();
19360     }
19361   }
19362 
19363   // This array section can be privatized as a single value or as a constant
19364   // sized array.
19365   return true;
19366 }
19367 
19368 static BinaryOperatorKind
19369 getRelatedCompoundReductionOp(BinaryOperatorKind BOK) {
19370   if (BOK == BO_Add)
19371     return BO_AddAssign;
19372   if (BOK == BO_Mul)
19373     return BO_MulAssign;
19374   if (BOK == BO_And)
19375     return BO_AndAssign;
19376   if (BOK == BO_Or)
19377     return BO_OrAssign;
19378   if (BOK == BO_Xor)
19379     return BO_XorAssign;
19380   return BOK;
19381 }
19382 
19383 static bool actOnOMPReductionKindClause(
19384     Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
19385     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
19386     SourceLocation ColonLoc, SourceLocation EndLoc,
19387     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
19388     ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
19389   DeclarationName DN = ReductionId.getName();
19390   OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator();
19391   BinaryOperatorKind BOK = BO_Comma;
19392 
19393   ASTContext &Context = S.Context;
19394   // OpenMP [2.14.3.6, reduction clause]
19395   // C
19396   // reduction-identifier is either an identifier or one of the following
19397   // operators: +, -, *,  &, |, ^, && and ||
19398   // C++
19399   // reduction-identifier is either an id-expression or one of the following
19400   // operators: +, -, *, &, |, ^, && and ||
19401   switch (OOK) {
19402   case OO_Plus:
19403     BOK = BO_Add;
19404     break;
19405   case OO_Minus:
19406     // Minus(-) operator is not supported in TR11 (OpenMP 6.0). Setting BOK to
19407     // BO_Comma will automatically diagnose it for OpenMP > 52 as not allowed
19408     // reduction identifier.
19409     if (S.LangOpts.OpenMP > 52)
19410       BOK = BO_Comma;
19411     else
19412       BOK = BO_Add;
19413     break;
19414   case OO_Star:
19415     BOK = BO_Mul;
19416     break;
19417   case OO_Amp:
19418     BOK = BO_And;
19419     break;
19420   case OO_Pipe:
19421     BOK = BO_Or;
19422     break;
19423   case OO_Caret:
19424     BOK = BO_Xor;
19425     break;
19426   case OO_AmpAmp:
19427     BOK = BO_LAnd;
19428     break;
19429   case OO_PipePipe:
19430     BOK = BO_LOr;
19431     break;
19432   case OO_New:
19433   case OO_Delete:
19434   case OO_Array_New:
19435   case OO_Array_Delete:
19436   case OO_Slash:
19437   case OO_Percent:
19438   case OO_Tilde:
19439   case OO_Exclaim:
19440   case OO_Equal:
19441   case OO_Less:
19442   case OO_Greater:
19443   case OO_LessEqual:
19444   case OO_GreaterEqual:
19445   case OO_PlusEqual:
19446   case OO_MinusEqual:
19447   case OO_StarEqual:
19448   case OO_SlashEqual:
19449   case OO_PercentEqual:
19450   case OO_CaretEqual:
19451   case OO_AmpEqual:
19452   case OO_PipeEqual:
19453   case OO_LessLess:
19454   case OO_GreaterGreater:
19455   case OO_LessLessEqual:
19456   case OO_GreaterGreaterEqual:
19457   case OO_EqualEqual:
19458   case OO_ExclaimEqual:
19459   case OO_Spaceship:
19460   case OO_PlusPlus:
19461   case OO_MinusMinus:
19462   case OO_Comma:
19463   case OO_ArrowStar:
19464   case OO_Arrow:
19465   case OO_Call:
19466   case OO_Subscript:
19467   case OO_Conditional:
19468   case OO_Coawait:
19469   case NUM_OVERLOADED_OPERATORS:
19470     llvm_unreachable("Unexpected reduction identifier");
19471   case OO_None:
19472     if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
19473       if (II->isStr("max"))
19474         BOK = BO_GT;
19475       else if (II->isStr("min"))
19476         BOK = BO_LT;
19477     }
19478     break;
19479   }
19480 
19481   // OpenMP 5.2, 5.5.5 (see page 627, line 18) reduction Clause, Restrictions
19482   // A reduction clause with the minus (-) operator was deprecated
19483   if (OOK == OO_Minus && S.LangOpts.OpenMP == 52)
19484     S.Diag(ReductionId.getLoc(), diag::warn_omp_minus_in_reduction_deprecated);
19485 
19486   SourceRange ReductionIdRange;
19487   if (ReductionIdScopeSpec.isValid())
19488     ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
19489   else
19490     ReductionIdRange.setBegin(ReductionId.getBeginLoc());
19491   ReductionIdRange.setEnd(ReductionId.getEndLoc());
19492 
19493   auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
19494   bool FirstIter = true;
19495   for (Expr *RefExpr : VarList) {
19496     assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
19497     // OpenMP [2.1, C/C++]
19498     //  A list item is a variable or array section, subject to the restrictions
19499     //  specified in Section 2.4 on page 42 and in each of the sections
19500     // describing clauses and directives for which a list appears.
19501     // OpenMP  [2.14.3.3, Restrictions, p.1]
19502     //  A variable that is part of another variable (as an array or
19503     //  structure element) cannot appear in a private clause.
19504     if (!FirstIter && IR != ER)
19505       ++IR;
19506     FirstIter = false;
19507     SourceLocation ELoc;
19508     SourceRange ERange;
19509     Expr *SimpleRefExpr = RefExpr;
19510     auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
19511                               /*AllowArraySection=*/true);
19512     if (Res.second) {
19513       // Try to find 'declare reduction' corresponding construct before using
19514       // builtin/overloaded operators.
19515       QualType Type = Context.DependentTy;
19516       CXXCastPath BasePath;
19517       ExprResult DeclareReductionRef = buildDeclareReductionRef(
19518           S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
19519           ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
19520       Expr *ReductionOp = nullptr;
19521       if (S.CurContext->isDependentContext() &&
19522           (DeclareReductionRef.isUnset() ||
19523            isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
19524         ReductionOp = DeclareReductionRef.get();
19525       // It will be analyzed later.
19526       RD.push(RefExpr, ReductionOp);
19527     }
19528     ValueDecl *D = Res.first;
19529     if (!D)
19530       continue;
19531 
19532     Expr *TaskgroupDescriptor = nullptr;
19533     QualType Type;
19534     auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
19535     auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
19536     if (ASE) {
19537       Type = ASE->getType().getNonReferenceType();
19538     } else if (OASE) {
19539       QualType BaseType =
19540           OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
19541       if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
19542         Type = ATy->getElementType();
19543       else
19544         Type = BaseType->getPointeeType();
19545       Type = Type.getNonReferenceType();
19546     } else {
19547       Type = Context.getBaseElementType(D->getType().getNonReferenceType());
19548     }
19549     auto *VD = dyn_cast<VarDecl>(D);
19550 
19551     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
19552     //  A variable that appears in a private clause must not have an incomplete
19553     //  type or a reference type.
19554     if (S.RequireCompleteType(ELoc, D->getType(),
19555                               diag::err_omp_reduction_incomplete_type))
19556       continue;
19557     // OpenMP [2.14.3.6, reduction clause, Restrictions]
19558     // A list item that appears in a reduction clause must not be
19559     // const-qualified.
19560     if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
19561                                   /*AcceptIfMutable*/ false, ASE || OASE))
19562       continue;
19563 
19564     OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
19565     // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
19566     //  If a list-item is a reference type then it must bind to the same object
19567     //  for all threads of the team.
19568     if (!ASE && !OASE) {
19569       if (VD) {
19570         VarDecl *VDDef = VD->getDefinition();
19571         if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
19572           DSARefChecker Check(Stack);
19573           if (Check.Visit(VDDef->getInit())) {
19574             S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
19575                 << getOpenMPClauseName(ClauseKind) << ERange;
19576             S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
19577             continue;
19578           }
19579         }
19580       }
19581 
19582       // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
19583       // in a Construct]
19584       //  Variables with the predetermined data-sharing attributes may not be
19585       //  listed in data-sharing attributes clauses, except for the cases
19586       //  listed below. For these exceptions only, listing a predetermined
19587       //  variable in a data-sharing attribute clause is allowed and overrides
19588       //  the variable's predetermined data-sharing attributes.
19589       // OpenMP [2.14.3.6, Restrictions, p.3]
19590       //  Any number of reduction clauses can be specified on the directive,
19591       //  but a list item can appear only once in the reduction clauses for that
19592       //  directive.
19593       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
19594       if (DVar.CKind == OMPC_reduction) {
19595         S.Diag(ELoc, diag::err_omp_once_referenced)
19596             << getOpenMPClauseName(ClauseKind);
19597         if (DVar.RefExpr)
19598           S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
19599         continue;
19600       }
19601       if (DVar.CKind != OMPC_unknown) {
19602         S.Diag(ELoc, diag::err_omp_wrong_dsa)
19603             << getOpenMPClauseName(DVar.CKind)
19604             << getOpenMPClauseName(OMPC_reduction);
19605         reportOriginalDsa(S, Stack, D, DVar);
19606         continue;
19607       }
19608 
19609       // OpenMP [2.14.3.6, Restrictions, p.1]
19610       //  A list item that appears in a reduction clause of a worksharing
19611       //  construct must be shared in the parallel regions to which any of the
19612       //  worksharing regions arising from the worksharing construct bind.
19613       if (isOpenMPWorksharingDirective(CurrDir) &&
19614           !isOpenMPParallelDirective(CurrDir) &&
19615           !isOpenMPTeamsDirective(CurrDir)) {
19616         DVar = Stack->getImplicitDSA(D, true);
19617         if (DVar.CKind != OMPC_shared) {
19618           S.Diag(ELoc, diag::err_omp_required_access)
19619               << getOpenMPClauseName(OMPC_reduction)
19620               << getOpenMPClauseName(OMPC_shared);
19621           reportOriginalDsa(S, Stack, D, DVar);
19622           continue;
19623         }
19624       }
19625     } else {
19626       // Threadprivates cannot be shared between threads, so dignose if the base
19627       // is a threadprivate variable.
19628       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
19629       if (DVar.CKind == OMPC_threadprivate) {
19630         S.Diag(ELoc, diag::err_omp_wrong_dsa)
19631             << getOpenMPClauseName(DVar.CKind)
19632             << getOpenMPClauseName(OMPC_reduction);
19633         reportOriginalDsa(S, Stack, D, DVar);
19634         continue;
19635       }
19636     }
19637 
19638     // Try to find 'declare reduction' corresponding construct before using
19639     // builtin/overloaded operators.
19640     CXXCastPath BasePath;
19641     ExprResult DeclareReductionRef = buildDeclareReductionRef(
19642         S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
19643         ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
19644     if (DeclareReductionRef.isInvalid())
19645       continue;
19646     if (S.CurContext->isDependentContext() &&
19647         (DeclareReductionRef.isUnset() ||
19648          isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
19649       RD.push(RefExpr, DeclareReductionRef.get());
19650       continue;
19651     }
19652     if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
19653       // Not allowed reduction identifier is found.
19654       if (S.LangOpts.OpenMP > 52)
19655         S.Diag(ReductionId.getBeginLoc(),
19656                diag::err_omp_unknown_reduction_identifier_since_omp_6_0)
19657             << Type << ReductionIdRange;
19658       else
19659         S.Diag(ReductionId.getBeginLoc(),
19660                diag::err_omp_unknown_reduction_identifier_prior_omp_6_0)
19661             << Type << ReductionIdRange;
19662       continue;
19663     }
19664 
19665     // OpenMP [2.14.3.6, reduction clause, Restrictions]
19666     // The type of a list item that appears in a reduction clause must be valid
19667     // for the reduction-identifier. For a max or min reduction in C, the type
19668     // of the list item must be an allowed arithmetic data type: char, int,
19669     // float, double, or _Bool, possibly modified with long, short, signed, or
19670     // unsigned. For a max or min reduction in C++, the type of the list item
19671     // must be an allowed arithmetic data type: char, wchar_t, int, float,
19672     // double, or bool, possibly modified with long, short, signed, or unsigned.
19673     if (DeclareReductionRef.isUnset()) {
19674       if ((BOK == BO_GT || BOK == BO_LT) &&
19675           !(Type->isScalarType() ||
19676             (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
19677         S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
19678             << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
19679         if (!ASE && !OASE) {
19680           bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19681                                    VarDecl::DeclarationOnly;
19682           S.Diag(D->getLocation(),
19683                  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19684               << D;
19685         }
19686         continue;
19687       }
19688       if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
19689           !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
19690         S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
19691             << getOpenMPClauseName(ClauseKind);
19692         if (!ASE && !OASE) {
19693           bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19694                                    VarDecl::DeclarationOnly;
19695           S.Diag(D->getLocation(),
19696                  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19697               << D;
19698         }
19699         continue;
19700       }
19701     }
19702 
19703     Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
19704     VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
19705                                   D->hasAttrs() ? &D->getAttrs() : nullptr);
19706     VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
19707                                   D->hasAttrs() ? &D->getAttrs() : nullptr);
19708     QualType PrivateTy = Type;
19709 
19710     // Try if we can determine constant lengths for all array sections and avoid
19711     // the VLA.
19712     bool ConstantLengthOASE = false;
19713     if (OASE) {
19714       bool SingleElement;
19715       llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
19716       ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
19717           Context, OASE, SingleElement, ArraySizes);
19718 
19719       // If we don't have a single element, we must emit a constant array type.
19720       if (ConstantLengthOASE && !SingleElement) {
19721         for (llvm::APSInt &Size : ArraySizes)
19722           PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr,
19723                                                    ArraySizeModifier::Normal,
19724                                                    /*IndexTypeQuals=*/0);
19725       }
19726     }
19727 
19728     if ((OASE && !ConstantLengthOASE) ||
19729         (!OASE && !ASE &&
19730          D->getType().getNonReferenceType()->isVariablyModifiedType())) {
19731       if (!Context.getTargetInfo().isVLASupported()) {
19732         if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) {
19733           S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
19734           S.Diag(ELoc, diag::note_vla_unsupported);
19735           continue;
19736         } else {
19737           S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
19738           S.targetDiag(ELoc, diag::note_vla_unsupported);
19739         }
19740       }
19741       // For arrays/array sections only:
19742       // Create pseudo array type for private copy. The size for this array will
19743       // be generated during codegen.
19744       // For array subscripts or single variables Private Ty is the same as Type
19745       // (type of the variable or single array element).
19746       PrivateTy = Context.getVariableArrayType(
19747           Type,
19748           new (Context)
19749               OpaqueValueExpr(ELoc, Context.getSizeType(), VK_PRValue),
19750           ArraySizeModifier::Normal, /*IndexTypeQuals=*/0, SourceRange());
19751     } else if (!ASE && !OASE &&
19752                Context.getAsArrayType(D->getType().getNonReferenceType())) {
19753       PrivateTy = D->getType().getNonReferenceType();
19754     }
19755     // Private copy.
19756     VarDecl *PrivateVD =
19757         buildVarDecl(S, ELoc, PrivateTy, D->getName(),
19758                      D->hasAttrs() ? &D->getAttrs() : nullptr,
19759                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
19760     // Add initializer for private variable.
19761     Expr *Init = nullptr;
19762     DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
19763     DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
19764     if (DeclareReductionRef.isUsable()) {
19765       auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
19766       auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
19767       if (DRD->getInitializer()) {
19768         Init = DRDRef;
19769         RHSVD->setInit(DRDRef);
19770         RHSVD->setInitStyle(VarDecl::CallInit);
19771       }
19772     } else {
19773       switch (BOK) {
19774       case BO_Add:
19775       case BO_Xor:
19776       case BO_Or:
19777       case BO_LOr:
19778         // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
19779         if (Type->isScalarType() || Type->isAnyComplexType())
19780           Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
19781         break;
19782       case BO_Mul:
19783       case BO_LAnd:
19784         if (Type->isScalarType() || Type->isAnyComplexType()) {
19785           // '*' and '&&' reduction ops - initializer is '1'.
19786           Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
19787         }
19788         break;
19789       case BO_And: {
19790         // '&' reduction op - initializer is '~0'.
19791         QualType OrigType = Type;
19792         if (auto *ComplexTy = OrigType->getAs<ComplexType>())
19793           Type = ComplexTy->getElementType();
19794         if (Type->isRealFloatingType()) {
19795           llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue(
19796               Context.getFloatTypeSemantics(Type));
19797           Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
19798                                          Type, ELoc);
19799         } else if (Type->isScalarType()) {
19800           uint64_t Size = Context.getTypeSize(Type);
19801           QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
19802           llvm::APInt InitValue = llvm::APInt::getAllOnes(Size);
19803           Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
19804         }
19805         if (Init && OrigType->isAnyComplexType()) {
19806           // Init = 0xFFFF + 0xFFFFi;
19807           auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
19808           Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
19809         }
19810         Type = OrigType;
19811         break;
19812       }
19813       case BO_LT:
19814       case BO_GT: {
19815         // 'min' reduction op - initializer is 'Largest representable number in
19816         // the reduction list item type'.
19817         // 'max' reduction op - initializer is 'Least representable number in
19818         // the reduction list item type'.
19819         if (Type->isIntegerType() || Type->isPointerType()) {
19820           bool IsSigned = Type->hasSignedIntegerRepresentation();
19821           uint64_t Size = Context.getTypeSize(Type);
19822           QualType IntTy =
19823               Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
19824           llvm::APInt InitValue =
19825               (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
19826                                         : llvm::APInt::getMinValue(Size)
19827               : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
19828                              : llvm::APInt::getMaxValue(Size);
19829           Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
19830           if (Type->isPointerType()) {
19831             // Cast to pointer type.
19832             ExprResult CastExpr = S.BuildCStyleCastExpr(
19833                 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
19834             if (CastExpr.isInvalid())
19835               continue;
19836             Init = CastExpr.get();
19837           }
19838         } else if (Type->isRealFloatingType()) {
19839           llvm::APFloat InitValue = llvm::APFloat::getLargest(
19840               Context.getFloatTypeSemantics(Type), BOK != BO_LT);
19841           Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
19842                                          Type, ELoc);
19843         }
19844         break;
19845       }
19846       case BO_PtrMemD:
19847       case BO_PtrMemI:
19848       case BO_MulAssign:
19849       case BO_Div:
19850       case BO_Rem:
19851       case BO_Sub:
19852       case BO_Shl:
19853       case BO_Shr:
19854       case BO_LE:
19855       case BO_GE:
19856       case BO_EQ:
19857       case BO_NE:
19858       case BO_Cmp:
19859       case BO_AndAssign:
19860       case BO_XorAssign:
19861       case BO_OrAssign:
19862       case BO_Assign:
19863       case BO_AddAssign:
19864       case BO_SubAssign:
19865       case BO_DivAssign:
19866       case BO_RemAssign:
19867       case BO_ShlAssign:
19868       case BO_ShrAssign:
19869       case BO_Comma:
19870         llvm_unreachable("Unexpected reduction operation");
19871       }
19872     }
19873     if (Init && DeclareReductionRef.isUnset()) {
19874       S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
19875       // Store initializer for single element in private copy. Will be used
19876       // during codegen.
19877       PrivateVD->setInit(RHSVD->getInit());
19878       PrivateVD->setInitStyle(RHSVD->getInitStyle());
19879     } else if (!Init) {
19880       S.ActOnUninitializedDecl(RHSVD);
19881       // Store initializer for single element in private copy. Will be used
19882       // during codegen.
19883       PrivateVD->setInit(RHSVD->getInit());
19884       PrivateVD->setInitStyle(RHSVD->getInitStyle());
19885     }
19886     if (RHSVD->isInvalidDecl())
19887       continue;
19888     if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) {
19889       S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
19890           << Type << ReductionIdRange;
19891       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19892                                VarDecl::DeclarationOnly;
19893       S.Diag(D->getLocation(),
19894              IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19895           << D;
19896       continue;
19897     }
19898     DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
19899     ExprResult ReductionOp;
19900     if (DeclareReductionRef.isUsable()) {
19901       QualType RedTy = DeclareReductionRef.get()->getType();
19902       QualType PtrRedTy = Context.getPointerType(RedTy);
19903       ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
19904       ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
19905       if (!BasePath.empty()) {
19906         LHS = S.DefaultLvalueConversion(LHS.get());
19907         RHS = S.DefaultLvalueConversion(RHS.get());
19908         LHS = ImplicitCastExpr::Create(
19909             Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath,
19910             LHS.get()->getValueKind(), FPOptionsOverride());
19911         RHS = ImplicitCastExpr::Create(
19912             Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath,
19913             RHS.get()->getValueKind(), FPOptionsOverride());
19914       }
19915       FunctionProtoType::ExtProtoInfo EPI;
19916       QualType Params[] = {PtrRedTy, PtrRedTy};
19917       QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
19918       auto *OVE = new (Context) OpaqueValueExpr(
19919           ELoc, Context.getPointerType(FnTy), VK_PRValue, OK_Ordinary,
19920           S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
19921       Expr *Args[] = {LHS.get(), RHS.get()};
19922       ReductionOp =
19923           CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_PRValue, ELoc,
19924                            S.CurFPFeatureOverrides());
19925     } else {
19926       BinaryOperatorKind CombBOK = getRelatedCompoundReductionOp(BOK);
19927       if (Type->isRecordType() && CombBOK != BOK) {
19928         Sema::TentativeAnalysisScope Trap(S);
19929         ReductionOp =
19930             S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
19931                          CombBOK, LHSDRE, RHSDRE);
19932       }
19933       if (!ReductionOp.isUsable()) {
19934         ReductionOp =
19935             S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), BOK,
19936                          LHSDRE, RHSDRE);
19937         if (ReductionOp.isUsable()) {
19938           if (BOK != BO_LT && BOK != BO_GT) {
19939             ReductionOp =
19940                 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
19941                              BO_Assign, LHSDRE, ReductionOp.get());
19942           } else {
19943             auto *ConditionalOp = new (Context)
19944                 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc,
19945                                     RHSDRE, Type, VK_LValue, OK_Ordinary);
19946             ReductionOp =
19947                 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
19948                              BO_Assign, LHSDRE, ConditionalOp);
19949           }
19950         }
19951       }
19952       if (ReductionOp.isUsable())
19953         ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
19954                                             /*DiscardedValue*/ false);
19955       if (!ReductionOp.isUsable())
19956         continue;
19957     }
19958 
19959     // Add copy operations for inscan reductions.
19960     // LHS = RHS;
19961     ExprResult CopyOpRes, TempArrayRes, TempArrayElem;
19962     if (ClauseKind == OMPC_reduction &&
19963         RD.RedModifier == OMPC_REDUCTION_inscan) {
19964       ExprResult RHS = S.DefaultLvalueConversion(RHSDRE);
19965       CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE,
19966                                RHS.get());
19967       if (!CopyOpRes.isUsable())
19968         continue;
19969       CopyOpRes =
19970           S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true);
19971       if (!CopyOpRes.isUsable())
19972         continue;
19973       // For simd directive and simd-based directives in simd mode no need to
19974       // construct temp array, need just a single temp element.
19975       if (Stack->getCurrentDirective() == OMPD_simd ||
19976           (S.getLangOpts().OpenMPSimd &&
19977            isOpenMPSimdDirective(Stack->getCurrentDirective()))) {
19978         VarDecl *TempArrayVD =
19979             buildVarDecl(S, ELoc, PrivateTy, D->getName(),
19980                          D->hasAttrs() ? &D->getAttrs() : nullptr);
19981         // Add a constructor to the temp decl.
19982         S.ActOnUninitializedDecl(TempArrayVD);
19983         TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc);
19984       } else {
19985         // Build temp array for prefix sum.
19986         auto *Dim = new (S.Context)
19987             OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue);
19988         QualType ArrayTy = S.Context.getVariableArrayType(
19989             PrivateTy, Dim, ArraySizeModifier::Normal,
19990             /*IndexTypeQuals=*/0, {ELoc, ELoc});
19991         VarDecl *TempArrayVD =
19992             buildVarDecl(S, ELoc, ArrayTy, D->getName(),
19993                          D->hasAttrs() ? &D->getAttrs() : nullptr);
19994         // Add a constructor to the temp decl.
19995         S.ActOnUninitializedDecl(TempArrayVD);
19996         TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc);
19997         TempArrayElem =
19998             S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get());
19999         auto *Idx = new (S.Context)
20000             OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue);
20001         TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(),
20002                                                           ELoc, Idx, ELoc);
20003       }
20004     }
20005 
20006     // OpenMP [2.15.4.6, Restrictions, p.2]
20007     // A list item that appears in an in_reduction clause of a task construct
20008     // must appear in a task_reduction clause of a construct associated with a
20009     // taskgroup region that includes the participating task in its taskgroup
20010     // set. The construct associated with the innermost region that meets this
20011     // condition must specify the same reduction-identifier as the in_reduction
20012     // clause.
20013     if (ClauseKind == OMPC_in_reduction) {
20014       SourceRange ParentSR;
20015       BinaryOperatorKind ParentBOK;
20016       const Expr *ParentReductionOp = nullptr;
20017       Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr;
20018       DSAStackTy::DSAVarData ParentBOKDSA =
20019           Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
20020                                                   ParentBOKTD);
20021       DSAStackTy::DSAVarData ParentReductionOpDSA =
20022           Stack->getTopMostTaskgroupReductionData(
20023               D, ParentSR, ParentReductionOp, ParentReductionOpTD);
20024       bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
20025       bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
20026       if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
20027           (DeclareReductionRef.isUsable() && IsParentBOK) ||
20028           (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) {
20029         bool EmitError = true;
20030         if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
20031           llvm::FoldingSetNodeID RedId, ParentRedId;
20032           ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
20033           DeclareReductionRef.get()->Profile(RedId, Context,
20034                                              /*Canonical=*/true);
20035           EmitError = RedId != ParentRedId;
20036         }
20037         if (EmitError) {
20038           S.Diag(ReductionId.getBeginLoc(),
20039                  diag::err_omp_reduction_identifier_mismatch)
20040               << ReductionIdRange << RefExpr->getSourceRange();
20041           S.Diag(ParentSR.getBegin(),
20042                  diag::note_omp_previous_reduction_identifier)
20043               << ParentSR
20044               << (IsParentBOK ? ParentBOKDSA.RefExpr
20045                               : ParentReductionOpDSA.RefExpr)
20046                      ->getSourceRange();
20047           continue;
20048         }
20049       }
20050       TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
20051     }
20052 
20053     DeclRefExpr *Ref = nullptr;
20054     Expr *VarsExpr = RefExpr->IgnoreParens();
20055     if (!VD && !S.CurContext->isDependentContext()) {
20056       if (ASE || OASE) {
20057         TransformExprToCaptures RebuildToCapture(S, D);
20058         VarsExpr =
20059             RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
20060         Ref = RebuildToCapture.getCapturedExpr();
20061       } else {
20062         VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
20063       }
20064       if (!S.isOpenMPCapturedDecl(D)) {
20065         RD.ExprCaptures.emplace_back(Ref->getDecl());
20066         if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
20067           ExprResult RefRes = S.DefaultLvalueConversion(Ref);
20068           if (!RefRes.isUsable())
20069             continue;
20070           ExprResult PostUpdateRes =
20071               S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
20072                            RefRes.get());
20073           if (!PostUpdateRes.isUsable())
20074             continue;
20075           if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
20076               Stack->getCurrentDirective() == OMPD_taskgroup) {
20077             S.Diag(RefExpr->getExprLoc(),
20078                    diag::err_omp_reduction_non_addressable_expression)
20079                 << RefExpr->getSourceRange();
20080             continue;
20081           }
20082           RD.ExprPostUpdates.emplace_back(
20083               S.IgnoredValueConversions(PostUpdateRes.get()).get());
20084         }
20085       }
20086     }
20087     // All reduction items are still marked as reduction (to do not increase
20088     // code base size).
20089     unsigned Modifier = RD.RedModifier;
20090     // Consider task_reductions as reductions with task modifier. Required for
20091     // correct analysis of in_reduction clauses.
20092     if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction)
20093       Modifier = OMPC_REDUCTION_task;
20094     Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier,
20095                   ASE || OASE);
20096     if (Modifier == OMPC_REDUCTION_task &&
20097         (CurrDir == OMPD_taskgroup ||
20098          ((isOpenMPParallelDirective(CurrDir) ||
20099            isOpenMPWorksharingDirective(CurrDir)) &&
20100           !isOpenMPSimdDirective(CurrDir)))) {
20101       if (DeclareReductionRef.isUsable())
20102         Stack->addTaskgroupReductionData(D, ReductionIdRange,
20103                                          DeclareReductionRef.get());
20104       else
20105         Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
20106     }
20107     RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
20108             TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(),
20109             TempArrayElem.get());
20110   }
20111   return RD.Vars.empty();
20112 }
20113 
20114 OMPClause *Sema::ActOnOpenMPReductionClause(
20115     ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
20116     SourceLocation StartLoc, SourceLocation LParenLoc,
20117     SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
20118     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
20119     ArrayRef<Expr *> UnresolvedReductions) {
20120   if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) {
20121     Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
20122         << getListOfPossibleValues(OMPC_reduction, /*First=*/0,
20123                                    /*Last=*/OMPC_REDUCTION_unknown)
20124         << getOpenMPClauseName(OMPC_reduction);
20125     return nullptr;
20126   }
20127   // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions
20128   // A reduction clause with the inscan reduction-modifier may only appear on a
20129   // worksharing-loop construct, a worksharing-loop SIMD construct, a simd
20130   // construct, a parallel worksharing-loop construct or a parallel
20131   // worksharing-loop SIMD construct.
20132   if (Modifier == OMPC_REDUCTION_inscan &&
20133       (DSAStack->getCurrentDirective() != OMPD_for &&
20134        DSAStack->getCurrentDirective() != OMPD_for_simd &&
20135        DSAStack->getCurrentDirective() != OMPD_simd &&
20136        DSAStack->getCurrentDirective() != OMPD_parallel_for &&
20137        DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) {
20138     Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
20139     return nullptr;
20140   }
20141 
20142   ReductionData RD(VarList.size(), Modifier);
20143   if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList,
20144                                   StartLoc, LParenLoc, ColonLoc, EndLoc,
20145                                   ReductionIdScopeSpec, ReductionId,
20146                                   UnresolvedReductions, RD))
20147     return nullptr;
20148 
20149   return OMPReductionClause::Create(
20150       Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier,
20151       RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
20152       RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps,
20153       RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems,
20154       buildPreInits(Context, RD.ExprCaptures),
20155       buildPostUpdate(*this, RD.ExprPostUpdates));
20156 }
20157 
20158 OMPClause *Sema::ActOnOpenMPTaskReductionClause(
20159     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
20160     SourceLocation ColonLoc, SourceLocation EndLoc,
20161     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
20162     ArrayRef<Expr *> UnresolvedReductions) {
20163   ReductionData RD(VarList.size());
20164   if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList,
20165                                   StartLoc, LParenLoc, ColonLoc, EndLoc,
20166                                   ReductionIdScopeSpec, ReductionId,
20167                                   UnresolvedReductions, RD))
20168     return nullptr;
20169 
20170   return OMPTaskReductionClause::Create(
20171       Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
20172       ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
20173       RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
20174       buildPreInits(Context, RD.ExprCaptures),
20175       buildPostUpdate(*this, RD.ExprPostUpdates));
20176 }
20177 
20178 OMPClause *Sema::ActOnOpenMPInReductionClause(
20179     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
20180     SourceLocation ColonLoc, SourceLocation EndLoc,
20181     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
20182     ArrayRef<Expr *> UnresolvedReductions) {
20183   ReductionData RD(VarList.size());
20184   if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList,
20185                                   StartLoc, LParenLoc, ColonLoc, EndLoc,
20186                                   ReductionIdScopeSpec, ReductionId,
20187                                   UnresolvedReductions, RD))
20188     return nullptr;
20189 
20190   return OMPInReductionClause::Create(
20191       Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
20192       ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
20193       RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
20194       buildPreInits(Context, RD.ExprCaptures),
20195       buildPostUpdate(*this, RD.ExprPostUpdates));
20196 }
20197 
20198 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
20199                                      SourceLocation LinLoc) {
20200   if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
20201       LinKind == OMPC_LINEAR_unknown || LinKind == OMPC_LINEAR_step) {
20202     Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
20203     return true;
20204   }
20205   return false;
20206 }
20207 
20208 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
20209                                  OpenMPLinearClauseKind LinKind, QualType Type,
20210                                  bool IsDeclareSimd) {
20211   const auto *VD = dyn_cast_or_null<VarDecl>(D);
20212   // A variable must not have an incomplete type or a reference type.
20213   if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
20214     return true;
20215   if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
20216       !Type->isReferenceType()) {
20217     Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
20218         << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
20219     return true;
20220   }
20221   Type = Type.getNonReferenceType();
20222 
20223   // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
20224   // A variable that is privatized must not have a const-qualified type
20225   // unless it is of class type with a mutable member. This restriction does
20226   // not apply to the firstprivate clause, nor to the linear clause on
20227   // declarative directives (like declare simd).
20228   if (!IsDeclareSimd &&
20229       rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
20230     return true;
20231 
20232   // A list item must be of integral or pointer type.
20233   Type = Type.getUnqualifiedType().getCanonicalType();
20234   const auto *Ty = Type.getTypePtrOrNull();
20235   if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
20236               !Ty->isIntegralType(Context) && !Ty->isPointerType())) {
20237     Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
20238     if (D) {
20239       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
20240                                VarDecl::DeclarationOnly;
20241       Diag(D->getLocation(),
20242            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
20243           << D;
20244     }
20245     return true;
20246   }
20247   return false;
20248 }
20249 
20250 OMPClause *Sema::ActOnOpenMPLinearClause(
20251     ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
20252     SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
20253     SourceLocation LinLoc, SourceLocation ColonLoc,
20254     SourceLocation StepModifierLoc, SourceLocation EndLoc) {
20255   SmallVector<Expr *, 8> Vars;
20256   SmallVector<Expr *, 8> Privates;
20257   SmallVector<Expr *, 8> Inits;
20258   SmallVector<Decl *, 4> ExprCaptures;
20259   SmallVector<Expr *, 4> ExprPostUpdates;
20260   // OpenMP 5.2 [Section 5.4.6, linear clause]
20261   // step-simple-modifier is exclusive, can't be used with 'val', 'uval', or
20262   // 'ref'
20263   if (LinLoc.isValid() && StepModifierLoc.isInvalid() && Step &&
20264       getLangOpts().OpenMP >= 52)
20265     Diag(Step->getBeginLoc(), diag::err_omp_step_simple_modifier_exclusive);
20266   if (CheckOpenMPLinearModifier(LinKind, LinLoc))
20267     LinKind = OMPC_LINEAR_val;
20268   for (Expr *RefExpr : VarList) {
20269     assert(RefExpr && "NULL expr in OpenMP linear clause.");
20270     SourceLocation ELoc;
20271     SourceRange ERange;
20272     Expr *SimpleRefExpr = RefExpr;
20273     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20274     if (Res.second) {
20275       // It will be analyzed later.
20276       Vars.push_back(RefExpr);
20277       Privates.push_back(nullptr);
20278       Inits.push_back(nullptr);
20279     }
20280     ValueDecl *D = Res.first;
20281     if (!D)
20282       continue;
20283 
20284     QualType Type = D->getType();
20285     auto *VD = dyn_cast<VarDecl>(D);
20286 
20287     // OpenMP [2.14.3.7, linear clause]
20288     //  A list-item cannot appear in more than one linear clause.
20289     //  A list-item that appears in a linear clause cannot appear in any
20290     //  other data-sharing attribute clause.
20291     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
20292     if (DVar.RefExpr) {
20293       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
20294                                           << getOpenMPClauseName(OMPC_linear);
20295       reportOriginalDsa(*this, DSAStack, D, DVar);
20296       continue;
20297     }
20298 
20299     if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
20300       continue;
20301     Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
20302 
20303     // Build private copy of original var.
20304     VarDecl *Private =
20305         buildVarDecl(*this, ELoc, Type, D->getName(),
20306                      D->hasAttrs() ? &D->getAttrs() : nullptr,
20307                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
20308     DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
20309     // Build var to save initial value.
20310     VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
20311     Expr *InitExpr;
20312     DeclRefExpr *Ref = nullptr;
20313     if (!VD && !CurContext->isDependentContext()) {
20314       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
20315       if (!isOpenMPCapturedDecl(D)) {
20316         ExprCaptures.push_back(Ref->getDecl());
20317         if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
20318           ExprResult RefRes = DefaultLvalueConversion(Ref);
20319           if (!RefRes.isUsable())
20320             continue;
20321           ExprResult PostUpdateRes =
20322               BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
20323                          SimpleRefExpr, RefRes.get());
20324           if (!PostUpdateRes.isUsable())
20325             continue;
20326           ExprPostUpdates.push_back(
20327               IgnoredValueConversions(PostUpdateRes.get()).get());
20328         }
20329       }
20330     }
20331     if (LinKind == OMPC_LINEAR_uval)
20332       InitExpr = VD ? VD->getInit() : SimpleRefExpr;
20333     else
20334       InitExpr = VD ? SimpleRefExpr : Ref;
20335     AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
20336                          /*DirectInit=*/false);
20337     DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
20338 
20339     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
20340     Vars.push_back((VD || CurContext->isDependentContext())
20341                        ? RefExpr->IgnoreParens()
20342                        : Ref);
20343     Privates.push_back(PrivateRef);
20344     Inits.push_back(InitRef);
20345   }
20346 
20347   if (Vars.empty())
20348     return nullptr;
20349 
20350   Expr *StepExpr = Step;
20351   Expr *CalcStepExpr = nullptr;
20352   if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
20353       !Step->isInstantiationDependent() &&
20354       !Step->containsUnexpandedParameterPack()) {
20355     SourceLocation StepLoc = Step->getBeginLoc();
20356     ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
20357     if (Val.isInvalid())
20358       return nullptr;
20359     StepExpr = Val.get();
20360 
20361     // Build var to save the step value.
20362     VarDecl *SaveVar =
20363         buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
20364     ExprResult SaveRef =
20365         buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
20366     ExprResult CalcStep =
20367         BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
20368     CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
20369 
20370     // Warn about zero linear step (it would be probably better specified as
20371     // making corresponding variables 'const').
20372     if (std::optional<llvm::APSInt> Result =
20373             StepExpr->getIntegerConstantExpr(Context)) {
20374       if (!Result->isNegative() && !Result->isStrictlyPositive())
20375         Diag(StepLoc, diag::warn_omp_linear_step_zero)
20376             << Vars[0] << (Vars.size() > 1);
20377     } else if (CalcStep.isUsable()) {
20378       // Calculate the step beforehand instead of doing this on each iteration.
20379       // (This is not used if the number of iterations may be kfold-ed).
20380       CalcStepExpr = CalcStep.get();
20381     }
20382   }
20383 
20384   return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
20385                                  ColonLoc, StepModifierLoc, EndLoc, Vars,
20386                                  Privates, Inits, StepExpr, CalcStepExpr,
20387                                  buildPreInits(Context, ExprCaptures),
20388                                  buildPostUpdate(*this, ExprPostUpdates));
20389 }
20390 
20391 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
20392                                      Expr *NumIterations, Sema &SemaRef,
20393                                      Scope *S, DSAStackTy *Stack) {
20394   // Walk the vars and build update/final expressions for the CodeGen.
20395   SmallVector<Expr *, 8> Updates;
20396   SmallVector<Expr *, 8> Finals;
20397   SmallVector<Expr *, 8> UsedExprs;
20398   Expr *Step = Clause.getStep();
20399   Expr *CalcStep = Clause.getCalcStep();
20400   // OpenMP [2.14.3.7, linear clause]
20401   // If linear-step is not specified it is assumed to be 1.
20402   if (!Step)
20403     Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
20404   else if (CalcStep)
20405     Step = cast<BinaryOperator>(CalcStep)->getLHS();
20406   bool HasErrors = false;
20407   auto CurInit = Clause.inits().begin();
20408   auto CurPrivate = Clause.privates().begin();
20409   OpenMPLinearClauseKind LinKind = Clause.getModifier();
20410   for (Expr *RefExpr : Clause.varlists()) {
20411     SourceLocation ELoc;
20412     SourceRange ERange;
20413     Expr *SimpleRefExpr = RefExpr;
20414     auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
20415     ValueDecl *D = Res.first;
20416     if (Res.second || !D) {
20417       Updates.push_back(nullptr);
20418       Finals.push_back(nullptr);
20419       HasErrors = true;
20420       continue;
20421     }
20422     auto &&Info = Stack->isLoopControlVariable(D);
20423     // OpenMP [2.15.11, distribute simd Construct]
20424     // A list item may not appear in a linear clause, unless it is the loop
20425     // iteration variable.
20426     if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
20427         isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
20428       SemaRef.Diag(ELoc,
20429                    diag::err_omp_linear_distribute_var_non_loop_iteration);
20430       Updates.push_back(nullptr);
20431       Finals.push_back(nullptr);
20432       HasErrors = true;
20433       continue;
20434     }
20435     Expr *InitExpr = *CurInit;
20436 
20437     // Build privatized reference to the current linear var.
20438     auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
20439     Expr *CapturedRef;
20440     if (LinKind == OMPC_LINEAR_uval)
20441       CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
20442     else
20443       CapturedRef =
20444           buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
20445                            DE->getType().getUnqualifiedType(), DE->getExprLoc(),
20446                            /*RefersToCapture=*/true);
20447 
20448     // Build update: Var = InitExpr + IV * Step
20449     ExprResult Update;
20450     if (!Info.first)
20451       Update = buildCounterUpdate(
20452           SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
20453           /*Subtract=*/false, /*IsNonRectangularLB=*/false);
20454     else
20455       Update = *CurPrivate;
20456     Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
20457                                          /*DiscardedValue*/ false);
20458 
20459     // Build final: Var = PrivCopy;
20460     ExprResult Final;
20461     if (!Info.first)
20462       Final = SemaRef.BuildBinOp(
20463           S, RefExpr->getExprLoc(), BO_Assign, CapturedRef,
20464           SemaRef.DefaultLvalueConversion(*CurPrivate).get());
20465     else
20466       Final = *CurPrivate;
20467     Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
20468                                         /*DiscardedValue*/ false);
20469 
20470     if (!Update.isUsable() || !Final.isUsable()) {
20471       Updates.push_back(nullptr);
20472       Finals.push_back(nullptr);
20473       UsedExprs.push_back(nullptr);
20474       HasErrors = true;
20475     } else {
20476       Updates.push_back(Update.get());
20477       Finals.push_back(Final.get());
20478       if (!Info.first)
20479         UsedExprs.push_back(SimpleRefExpr);
20480     }
20481     ++CurInit;
20482     ++CurPrivate;
20483   }
20484   if (Expr *S = Clause.getStep())
20485     UsedExprs.push_back(S);
20486   // Fill the remaining part with the nullptr.
20487   UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr);
20488   Clause.setUpdates(Updates);
20489   Clause.setFinals(Finals);
20490   Clause.setUsedExprs(UsedExprs);
20491   return HasErrors;
20492 }
20493 
20494 OMPClause *Sema::ActOnOpenMPAlignedClause(
20495     ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
20496     SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
20497   SmallVector<Expr *, 8> Vars;
20498   for (Expr *RefExpr : VarList) {
20499     assert(RefExpr && "NULL expr in OpenMP linear clause.");
20500     SourceLocation ELoc;
20501     SourceRange ERange;
20502     Expr *SimpleRefExpr = RefExpr;
20503     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20504     if (Res.second) {
20505       // It will be analyzed later.
20506       Vars.push_back(RefExpr);
20507     }
20508     ValueDecl *D = Res.first;
20509     if (!D)
20510       continue;
20511 
20512     QualType QType = D->getType();
20513     auto *VD = dyn_cast<VarDecl>(D);
20514 
20515     // OpenMP  [2.8.1, simd construct, Restrictions]
20516     // The type of list items appearing in the aligned clause must be
20517     // array, pointer, reference to array, or reference to pointer.
20518     QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
20519     const Type *Ty = QType.getTypePtrOrNull();
20520     if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
20521       Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
20522           << QType << getLangOpts().CPlusPlus << ERange;
20523       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
20524                                VarDecl::DeclarationOnly;
20525       Diag(D->getLocation(),
20526            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
20527           << D;
20528       continue;
20529     }
20530 
20531     // OpenMP  [2.8.1, simd construct, Restrictions]
20532     // A list-item cannot appear in more than one aligned clause.
20533     if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
20534       Diag(ELoc, diag::err_omp_used_in_clause_twice)
20535           << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
20536       Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
20537           << getOpenMPClauseName(OMPC_aligned);
20538       continue;
20539     }
20540 
20541     DeclRefExpr *Ref = nullptr;
20542     if (!VD && isOpenMPCapturedDecl(D))
20543       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
20544     Vars.push_back(DefaultFunctionArrayConversion(
20545                        (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
20546                        .get());
20547   }
20548 
20549   // OpenMP [2.8.1, simd construct, Description]
20550   // The parameter of the aligned clause, alignment, must be a constant
20551   // positive integer expression.
20552   // If no optional parameter is specified, implementation-defined default
20553   // alignments for SIMD instructions on the target platforms are assumed.
20554   if (Alignment != nullptr) {
20555     ExprResult AlignResult =
20556         VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
20557     if (AlignResult.isInvalid())
20558       return nullptr;
20559     Alignment = AlignResult.get();
20560   }
20561   if (Vars.empty())
20562     return nullptr;
20563 
20564   return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
20565                                   EndLoc, Vars, Alignment);
20566 }
20567 
20568 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
20569                                          SourceLocation StartLoc,
20570                                          SourceLocation LParenLoc,
20571                                          SourceLocation EndLoc) {
20572   SmallVector<Expr *, 8> Vars;
20573   SmallVector<Expr *, 8> SrcExprs;
20574   SmallVector<Expr *, 8> DstExprs;
20575   SmallVector<Expr *, 8> AssignmentOps;
20576   for (Expr *RefExpr : VarList) {
20577     assert(RefExpr && "NULL expr in OpenMP copyin clause.");
20578     if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
20579       // It will be analyzed later.
20580       Vars.push_back(RefExpr);
20581       SrcExprs.push_back(nullptr);
20582       DstExprs.push_back(nullptr);
20583       AssignmentOps.push_back(nullptr);
20584       continue;
20585     }
20586 
20587     SourceLocation ELoc = RefExpr->getExprLoc();
20588     // OpenMP [2.1, C/C++]
20589     //  A list item is a variable name.
20590     // OpenMP  [2.14.4.1, Restrictions, p.1]
20591     //  A list item that appears in a copyin clause must be threadprivate.
20592     auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
20593     if (!DE || !isa<VarDecl>(DE->getDecl())) {
20594       Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
20595           << 0 << RefExpr->getSourceRange();
20596       continue;
20597     }
20598 
20599     Decl *D = DE->getDecl();
20600     auto *VD = cast<VarDecl>(D);
20601 
20602     QualType Type = VD->getType();
20603     if (Type->isDependentType() || Type->isInstantiationDependentType()) {
20604       // It will be analyzed later.
20605       Vars.push_back(DE);
20606       SrcExprs.push_back(nullptr);
20607       DstExprs.push_back(nullptr);
20608       AssignmentOps.push_back(nullptr);
20609       continue;
20610     }
20611 
20612     // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
20613     //  A list item that appears in a copyin clause must be threadprivate.
20614     if (!DSAStack->isThreadPrivate(VD)) {
20615       Diag(ELoc, diag::err_omp_required_access)
20616           << getOpenMPClauseName(OMPC_copyin)
20617           << getOpenMPDirectiveName(OMPD_threadprivate);
20618       continue;
20619     }
20620 
20621     // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
20622     //  A variable of class type (or array thereof) that appears in a
20623     //  copyin clause requires an accessible, unambiguous copy assignment
20624     //  operator for the class type.
20625     QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
20626     VarDecl *SrcVD =
20627         buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
20628                      ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
20629     DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
20630         *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
20631     VarDecl *DstVD =
20632         buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
20633                      VD->hasAttrs() ? &VD->getAttrs() : nullptr);
20634     DeclRefExpr *PseudoDstExpr =
20635         buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
20636     // For arrays generate assignment operation for single element and replace
20637     // it by the original array element in CodeGen.
20638     ExprResult AssignmentOp =
20639         BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
20640                    PseudoSrcExpr);
20641     if (AssignmentOp.isInvalid())
20642       continue;
20643     AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
20644                                        /*DiscardedValue*/ false);
20645     if (AssignmentOp.isInvalid())
20646       continue;
20647 
20648     DSAStack->addDSA(VD, DE, OMPC_copyin);
20649     Vars.push_back(DE);
20650     SrcExprs.push_back(PseudoSrcExpr);
20651     DstExprs.push_back(PseudoDstExpr);
20652     AssignmentOps.push_back(AssignmentOp.get());
20653   }
20654 
20655   if (Vars.empty())
20656     return nullptr;
20657 
20658   return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
20659                                  SrcExprs, DstExprs, AssignmentOps);
20660 }
20661 
20662 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
20663                                               SourceLocation StartLoc,
20664                                               SourceLocation LParenLoc,
20665                                               SourceLocation EndLoc) {
20666   SmallVector<Expr *, 8> Vars;
20667   SmallVector<Expr *, 8> SrcExprs;
20668   SmallVector<Expr *, 8> DstExprs;
20669   SmallVector<Expr *, 8> AssignmentOps;
20670   for (Expr *RefExpr : VarList) {
20671     assert(RefExpr && "NULL expr in OpenMP linear clause.");
20672     SourceLocation ELoc;
20673     SourceRange ERange;
20674     Expr *SimpleRefExpr = RefExpr;
20675     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20676     if (Res.second) {
20677       // It will be analyzed later.
20678       Vars.push_back(RefExpr);
20679       SrcExprs.push_back(nullptr);
20680       DstExprs.push_back(nullptr);
20681       AssignmentOps.push_back(nullptr);
20682     }
20683     ValueDecl *D = Res.first;
20684     if (!D)
20685       continue;
20686 
20687     QualType Type = D->getType();
20688     auto *VD = dyn_cast<VarDecl>(D);
20689 
20690     // OpenMP [2.14.4.2, Restrictions, p.2]
20691     //  A list item that appears in a copyprivate clause may not appear in a
20692     //  private or firstprivate clause on the single construct.
20693     if (!VD || !DSAStack->isThreadPrivate(VD)) {
20694       DSAStackTy::DSAVarData DVar =
20695           DSAStack->getTopDSA(D, /*FromParent=*/false);
20696       if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
20697           DVar.RefExpr) {
20698         Diag(ELoc, diag::err_omp_wrong_dsa)
20699             << getOpenMPClauseName(DVar.CKind)
20700             << getOpenMPClauseName(OMPC_copyprivate);
20701         reportOriginalDsa(*this, DSAStack, D, DVar);
20702         continue;
20703       }
20704 
20705       // OpenMP [2.11.4.2, Restrictions, p.1]
20706       //  All list items that appear in a copyprivate clause must be either
20707       //  threadprivate or private in the enclosing context.
20708       if (DVar.CKind == OMPC_unknown) {
20709         DVar = DSAStack->getImplicitDSA(D, false);
20710         if (DVar.CKind == OMPC_shared) {
20711           Diag(ELoc, diag::err_omp_required_access)
20712               << getOpenMPClauseName(OMPC_copyprivate)
20713               << "threadprivate or private in the enclosing context";
20714           reportOriginalDsa(*this, DSAStack, D, DVar);
20715           continue;
20716         }
20717       }
20718     }
20719 
20720     // Variably modified types are not supported.
20721     if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
20722       Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
20723           << getOpenMPClauseName(OMPC_copyprivate) << Type
20724           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
20725       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
20726                                VarDecl::DeclarationOnly;
20727       Diag(D->getLocation(),
20728            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
20729           << D;
20730       continue;
20731     }
20732 
20733     // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
20734     //  A variable of class type (or array thereof) that appears in a
20735     //  copyin clause requires an accessible, unambiguous copy assignment
20736     //  operator for the class type.
20737     Type = Context.getBaseElementType(Type.getNonReferenceType())
20738                .getUnqualifiedType();
20739     VarDecl *SrcVD =
20740         buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
20741                      D->hasAttrs() ? &D->getAttrs() : nullptr);
20742     DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
20743     VarDecl *DstVD =
20744         buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
20745                      D->hasAttrs() ? &D->getAttrs() : nullptr);
20746     DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
20747     ExprResult AssignmentOp = BuildBinOp(
20748         DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
20749     if (AssignmentOp.isInvalid())
20750       continue;
20751     AssignmentOp =
20752         ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
20753     if (AssignmentOp.isInvalid())
20754       continue;
20755 
20756     // No need to mark vars as copyprivate, they are already threadprivate or
20757     // implicitly private.
20758     assert(VD || isOpenMPCapturedDecl(D));
20759     Vars.push_back(
20760         VD ? RefExpr->IgnoreParens()
20761            : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
20762     SrcExprs.push_back(PseudoSrcExpr);
20763     DstExprs.push_back(PseudoDstExpr);
20764     AssignmentOps.push_back(AssignmentOp.get());
20765   }
20766 
20767   if (Vars.empty())
20768     return nullptr;
20769 
20770   return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
20771                                       Vars, SrcExprs, DstExprs, AssignmentOps);
20772 }
20773 
20774 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
20775                                         SourceLocation StartLoc,
20776                                         SourceLocation LParenLoc,
20777                                         SourceLocation EndLoc) {
20778   if (VarList.empty())
20779     return nullptr;
20780 
20781   return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
20782 }
20783 
20784 /// Tries to find omp_depend_t. type.
20785 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack,
20786                            bool Diagnose = true) {
20787   QualType OMPDependT = Stack->getOMPDependT();
20788   if (!OMPDependT.isNull())
20789     return true;
20790   IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t");
20791   ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
20792   if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
20793     if (Diagnose)
20794       S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t";
20795     return false;
20796   }
20797   Stack->setOMPDependT(PT.get());
20798   return true;
20799 }
20800 
20801 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
20802                                          SourceLocation LParenLoc,
20803                                          SourceLocation EndLoc) {
20804   if (!Depobj)
20805     return nullptr;
20806 
20807   bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack);
20808 
20809   // OpenMP 5.0, 2.17.10.1 depobj Construct
20810   // depobj is an lvalue expression of type omp_depend_t.
20811   if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() &&
20812       !Depobj->isInstantiationDependent() &&
20813       !Depobj->containsUnexpandedParameterPack() &&
20814       (OMPDependTFound &&
20815        !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(),
20816                                    /*CompareUnqualified=*/true))) {
20817     Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
20818         << 0 << Depobj->getType() << Depobj->getSourceRange();
20819   }
20820 
20821   if (!Depobj->isLValue()) {
20822     Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
20823         << 1 << Depobj->getSourceRange();
20824   }
20825 
20826   return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj);
20827 }
20828 
20829 namespace {
20830 // Utility struct that gathers the related info for doacross clause.
20831 struct DoacrossDataInfoTy {
20832   // The list of expressions.
20833   SmallVector<Expr *, 8> Vars;
20834   // The OperatorOffset for doacross loop.
20835   DSAStackTy::OperatorOffsetTy OpsOffs;
20836   // The depended loop count.
20837   llvm::APSInt TotalDepCount;
20838 };
20839 } // namespace
20840 static DoacrossDataInfoTy
20841 ProcessOpenMPDoacrossClauseCommon(Sema &SemaRef, bool IsSource,
20842                                   ArrayRef<Expr *> VarList, DSAStackTy *Stack,
20843                                   SourceLocation EndLoc) {
20844 
20845   SmallVector<Expr *, 8> Vars;
20846   DSAStackTy::OperatorOffsetTy OpsOffs;
20847   llvm::APSInt DepCounter(/*BitWidth=*/32);
20848   llvm::APSInt TotalDepCount(/*BitWidth=*/32);
20849 
20850   if (const Expr *OrderedCountExpr =
20851           Stack->getParentOrderedRegionParam().first) {
20852     TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(SemaRef.Context);
20853     TotalDepCount.setIsUnsigned(/*Val=*/true);
20854   }
20855 
20856   for (Expr *RefExpr : VarList) {
20857     assert(RefExpr && "NULL expr in OpenMP doacross clause.");
20858     if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
20859       // It will be analyzed later.
20860       Vars.push_back(RefExpr);
20861       continue;
20862     }
20863 
20864     SourceLocation ELoc = RefExpr->getExprLoc();
20865     Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
20866     if (!IsSource) {
20867       if (Stack->getParentOrderedRegionParam().first &&
20868           DepCounter >= TotalDepCount) {
20869         SemaRef.Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
20870         continue;
20871       }
20872       ++DepCounter;
20873       // OpenMP  [2.13.9, Summary]
20874       // depend(dependence-type : vec), where dependence-type is:
20875       // 'sink' and where vec is the iteration vector, which has the form:
20876       //  x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
20877       // where n is the value specified by the ordered clause in the loop
20878       // directive, xi denotes the loop iteration variable of the i-th nested
20879       // loop associated with the loop directive, and di is a constant
20880       // non-negative integer.
20881       if (SemaRef.CurContext->isDependentContext()) {
20882         // It will be analyzed later.
20883         Vars.push_back(RefExpr);
20884         continue;
20885       }
20886       SimpleExpr = SimpleExpr->IgnoreImplicit();
20887       OverloadedOperatorKind OOK = OO_None;
20888       SourceLocation OOLoc;
20889       Expr *LHS = SimpleExpr;
20890       Expr *RHS = nullptr;
20891       if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
20892         OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
20893         OOLoc = BO->getOperatorLoc();
20894         LHS = BO->getLHS()->IgnoreParenImpCasts();
20895         RHS = BO->getRHS()->IgnoreParenImpCasts();
20896       } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
20897         OOK = OCE->getOperator();
20898         OOLoc = OCE->getOperatorLoc();
20899         LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
20900         RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
20901       } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
20902         OOK = MCE->getMethodDecl()
20903                   ->getNameInfo()
20904                   .getName()
20905                   .getCXXOverloadedOperator();
20906         OOLoc = MCE->getCallee()->getExprLoc();
20907         LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
20908         RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
20909       }
20910       SourceLocation ELoc;
20911       SourceRange ERange;
20912       auto Res = getPrivateItem(SemaRef, LHS, ELoc, ERange);
20913       if (Res.second) {
20914         // It will be analyzed later.
20915         Vars.push_back(RefExpr);
20916       }
20917       ValueDecl *D = Res.first;
20918       if (!D)
20919         continue;
20920 
20921       if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
20922         SemaRef.Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
20923         continue;
20924       }
20925       if (RHS) {
20926         ExprResult RHSRes = SemaRef.VerifyPositiveIntegerConstantInClause(
20927             RHS, OMPC_depend, /*StrictlyPositive=*/false);
20928         if (RHSRes.isInvalid())
20929           continue;
20930       }
20931       if (!SemaRef.CurContext->isDependentContext() &&
20932           Stack->getParentOrderedRegionParam().first &&
20933           DepCounter != Stack->isParentLoopControlVariable(D).first) {
20934         const ValueDecl *VD =
20935             Stack->getParentLoopControlVariable(DepCounter.getZExtValue());
20936         if (VD)
20937           SemaRef.Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
20938               << 1 << VD;
20939         else
20940           SemaRef.Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
20941               << 0;
20942         continue;
20943       }
20944       OpsOffs.emplace_back(RHS, OOK);
20945     }
20946     Vars.push_back(RefExpr->IgnoreParenImpCasts());
20947   }
20948   if (!SemaRef.CurContext->isDependentContext() && !IsSource &&
20949       TotalDepCount > VarList.size() &&
20950       Stack->getParentOrderedRegionParam().first &&
20951       Stack->getParentLoopControlVariable(VarList.size() + 1)) {
20952     SemaRef.Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
20953         << 1 << Stack->getParentLoopControlVariable(VarList.size() + 1);
20954   }
20955   return {Vars, OpsOffs, TotalDepCount};
20956 }
20957 
20958 OMPClause *
20959 Sema::ActOnOpenMPDependClause(const OMPDependClause::DependDataTy &Data,
20960                               Expr *DepModifier, ArrayRef<Expr *> VarList,
20961                               SourceLocation StartLoc, SourceLocation LParenLoc,
20962                               SourceLocation EndLoc) {
20963   OpenMPDependClauseKind DepKind = Data.DepKind;
20964   SourceLocation DepLoc = Data.DepLoc;
20965   if (DSAStack->getCurrentDirective() == OMPD_ordered &&
20966       DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
20967     Diag(DepLoc, diag::err_omp_unexpected_clause_value)
20968         << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
20969     return nullptr;
20970   }
20971   if (DSAStack->getCurrentDirective() == OMPD_taskwait &&
20972       DepKind == OMPC_DEPEND_mutexinoutset) {
20973     Diag(DepLoc, diag::err_omp_taskwait_depend_mutexinoutset_not_allowed);
20974     return nullptr;
20975   }
20976   if ((DSAStack->getCurrentDirective() != OMPD_ordered ||
20977        DSAStack->getCurrentDirective() == OMPD_depobj) &&
20978       (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
20979        DepKind == OMPC_DEPEND_sink ||
20980        ((LangOpts.OpenMP < 50 ||
20981          DSAStack->getCurrentDirective() == OMPD_depobj) &&
20982         DepKind == OMPC_DEPEND_depobj))) {
20983     SmallVector<unsigned, 6> Except = {OMPC_DEPEND_source, OMPC_DEPEND_sink,
20984                                        OMPC_DEPEND_outallmemory,
20985                                        OMPC_DEPEND_inoutallmemory};
20986     if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj)
20987       Except.push_back(OMPC_DEPEND_depobj);
20988     if (LangOpts.OpenMP < 51)
20989       Except.push_back(OMPC_DEPEND_inoutset);
20990     std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier)
20991                                ? "depend modifier(iterator) or "
20992                                : "";
20993     Diag(DepLoc, diag::err_omp_unexpected_clause_value)
20994         << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0,
20995                                               /*Last=*/OMPC_DEPEND_unknown,
20996                                               Except)
20997         << getOpenMPClauseName(OMPC_depend);
20998     return nullptr;
20999   }
21000   if (DepModifier &&
21001       (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) {
21002     Diag(DepModifier->getExprLoc(),
21003          diag::err_omp_depend_sink_source_with_modifier);
21004     return nullptr;
21005   }
21006   if (DepModifier &&
21007       !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator))
21008     Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator);
21009 
21010   SmallVector<Expr *, 8> Vars;
21011   DSAStackTy::OperatorOffsetTy OpsOffs;
21012   llvm::APSInt TotalDepCount(/*BitWidth=*/32);
21013 
21014   if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
21015     DoacrossDataInfoTy VarOffset = ProcessOpenMPDoacrossClauseCommon(
21016         *this, DepKind == OMPC_DEPEND_source, VarList, DSAStack, EndLoc);
21017     Vars = VarOffset.Vars;
21018     OpsOffs = VarOffset.OpsOffs;
21019     TotalDepCount = VarOffset.TotalDepCount;
21020   } else {
21021     for (Expr *RefExpr : VarList) {
21022       assert(RefExpr && "NULL expr in OpenMP shared clause.");
21023       if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
21024         // It will be analyzed later.
21025         Vars.push_back(RefExpr);
21026         continue;
21027       }
21028 
21029       SourceLocation ELoc = RefExpr->getExprLoc();
21030       Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
21031       if (DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) {
21032         bool OMPDependTFound = LangOpts.OpenMP >= 50;
21033         if (OMPDependTFound)
21034           OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack,
21035                                            DepKind == OMPC_DEPEND_depobj);
21036         if (DepKind == OMPC_DEPEND_depobj) {
21037           // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
21038           // List items used in depend clauses with the depobj dependence type
21039           // must be expressions of the omp_depend_t type.
21040           if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
21041               !RefExpr->isInstantiationDependent() &&
21042               !RefExpr->containsUnexpandedParameterPack() &&
21043               (OMPDependTFound &&
21044                !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(),
21045                                                RefExpr->getType()))) {
21046             Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
21047                 << 0 << RefExpr->getType() << RefExpr->getSourceRange();
21048             continue;
21049           }
21050           if (!RefExpr->isLValue()) {
21051             Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
21052                 << 1 << RefExpr->getType() << RefExpr->getSourceRange();
21053             continue;
21054           }
21055         } else {
21056           // OpenMP 5.0 [2.17.11, Restrictions]
21057           // List items used in depend clauses cannot be zero-length array
21058           // sections.
21059           QualType ExprTy = RefExpr->getType().getNonReferenceType();
21060           const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
21061           if (OASE) {
21062             QualType BaseType =
21063                 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
21064             if (BaseType.isNull())
21065               return nullptr;
21066             if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
21067               ExprTy = ATy->getElementType();
21068             else
21069               ExprTy = BaseType->getPointeeType();
21070             ExprTy = ExprTy.getNonReferenceType();
21071             const Expr *Length = OASE->getLength();
21072             Expr::EvalResult Result;
21073             if (Length && !Length->isValueDependent() &&
21074                 Length->EvaluateAsInt(Result, Context) &&
21075                 Result.Val.getInt().isZero()) {
21076               Diag(ELoc,
21077                    diag::err_omp_depend_zero_length_array_section_not_allowed)
21078                   << SimpleExpr->getSourceRange();
21079               continue;
21080             }
21081           }
21082 
21083           // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
21084           // List items used in depend clauses with the in, out, inout,
21085           // inoutset, or mutexinoutset dependence types cannot be
21086           // expressions of the omp_depend_t type.
21087           if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
21088               !RefExpr->isInstantiationDependent() &&
21089               !RefExpr->containsUnexpandedParameterPack() &&
21090               (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
21091                (OMPDependTFound && DSAStack->getOMPDependT().getTypePtr() ==
21092                                        ExprTy.getTypePtr()))) {
21093             Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
21094                 << (LangOpts.OpenMP >= 50 ? 1 : 0)
21095                 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
21096             continue;
21097           }
21098 
21099           auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
21100           if (ASE && !ASE->getBase()->isTypeDependent() &&
21101               !ASE->getBase()
21102                    ->getType()
21103                    .getNonReferenceType()
21104                    ->isPointerType() &&
21105               !ASE->getBase()->getType().getNonReferenceType()->isArrayType()) {
21106             Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
21107                 << (LangOpts.OpenMP >= 50 ? 1 : 0)
21108                 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
21109             continue;
21110           }
21111 
21112           ExprResult Res;
21113           {
21114             Sema::TentativeAnalysisScope Trap(*this);
21115             Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
21116                                        RefExpr->IgnoreParenImpCasts());
21117           }
21118           if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
21119               !isa<OMPArrayShapingExpr>(SimpleExpr)) {
21120             Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
21121                 << (LangOpts.OpenMP >= 50 ? 1 : 0)
21122                 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
21123             continue;
21124           }
21125         }
21126       }
21127       Vars.push_back(RefExpr->IgnoreParenImpCasts());
21128     }
21129   }
21130 
21131   if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
21132       DepKind != OMPC_DEPEND_outallmemory &&
21133       DepKind != OMPC_DEPEND_inoutallmemory && Vars.empty())
21134     return nullptr;
21135 
21136   auto *C = OMPDependClause::Create(
21137       Context, StartLoc, LParenLoc, EndLoc,
21138       {DepKind, DepLoc, Data.ColonLoc, Data.OmpAllMemoryLoc}, DepModifier, Vars,
21139       TotalDepCount.getZExtValue());
21140   if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
21141       DSAStack->isParentOrderedRegion())
21142     DSAStack->addDoacrossDependClause(C, OpsOffs);
21143   return C;
21144 }
21145 
21146 OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
21147                                          Expr *Device, SourceLocation StartLoc,
21148                                          SourceLocation LParenLoc,
21149                                          SourceLocation ModifierLoc,
21150                                          SourceLocation EndLoc) {
21151   assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) &&
21152          "Unexpected device modifier in OpenMP < 50.");
21153 
21154   bool ErrorFound = false;
21155   if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) {
21156     std::string Values =
21157         getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown);
21158     Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
21159         << Values << getOpenMPClauseName(OMPC_device);
21160     ErrorFound = true;
21161   }
21162 
21163   Expr *ValExpr = Device;
21164   Stmt *HelperValStmt = nullptr;
21165 
21166   // OpenMP [2.9.1, Restrictions]
21167   // The device expression must evaluate to a non-negative integer value.
21168   ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
21169                                           /*StrictlyPositive=*/false) ||
21170                ErrorFound;
21171   if (ErrorFound)
21172     return nullptr;
21173 
21174   // OpenMP 5.0 [2.12.5, Restrictions]
21175   // In case of ancestor device-modifier, a requires directive with
21176   // the reverse_offload clause must be specified.
21177   if (Modifier == OMPC_DEVICE_ancestor) {
21178     if (!DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>()) {
21179       targetDiag(
21180           StartLoc,
21181           diag::err_omp_device_ancestor_without_requires_reverse_offload);
21182       ErrorFound = true;
21183     }
21184   }
21185 
21186   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
21187   OpenMPDirectiveKind CaptureRegion =
21188       getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP);
21189   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
21190     ValExpr = MakeFullExpr(ValExpr).get();
21191     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
21192     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
21193     HelperValStmt = buildPreInits(Context, Captures);
21194   }
21195 
21196   return new (Context)
21197       OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
21198                       LParenLoc, ModifierLoc, EndLoc);
21199 }
21200 
21201 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
21202                               DSAStackTy *Stack, QualType QTy,
21203                               bool FullCheck = true) {
21204   if (SemaRef.RequireCompleteType(SL, QTy, diag::err_incomplete_type))
21205     return false;
21206   if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
21207       !QTy.isTriviallyCopyableType(SemaRef.Context))
21208     SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
21209   return true;
21210 }
21211 
21212 /// Return true if it can be proven that the provided array expression
21213 /// (array section or array subscript) does NOT specify the whole size of the
21214 /// array whose base type is \a BaseQTy.
21215 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
21216                                                         const Expr *E,
21217                                                         QualType BaseQTy) {
21218   const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
21219 
21220   // If this is an array subscript, it refers to the whole size if the size of
21221   // the dimension is constant and equals 1. Also, an array section assumes the
21222   // format of an array subscript if no colon is used.
21223   if (isa<ArraySubscriptExpr>(E) ||
21224       (OASE && OASE->getColonLocFirst().isInvalid())) {
21225     if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
21226       return ATy->getSize().getSExtValue() != 1;
21227     // Size can't be evaluated statically.
21228     return false;
21229   }
21230 
21231   assert(OASE && "Expecting array section if not an array subscript.");
21232   const Expr *LowerBound = OASE->getLowerBound();
21233   const Expr *Length = OASE->getLength();
21234 
21235   // If there is a lower bound that does not evaluates to zero, we are not
21236   // covering the whole dimension.
21237   if (LowerBound) {
21238     Expr::EvalResult Result;
21239     if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
21240       return false; // Can't get the integer value as a constant.
21241 
21242     llvm::APSInt ConstLowerBound = Result.Val.getInt();
21243     if (ConstLowerBound.getSExtValue())
21244       return true;
21245   }
21246 
21247   // If we don't have a length we covering the whole dimension.
21248   if (!Length)
21249     return false;
21250 
21251   // If the base is a pointer, we don't have a way to get the size of the
21252   // pointee.
21253   if (BaseQTy->isPointerType())
21254     return false;
21255 
21256   // We can only check if the length is the same as the size of the dimension
21257   // if we have a constant array.
21258   const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
21259   if (!CATy)
21260     return false;
21261 
21262   Expr::EvalResult Result;
21263   if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
21264     return false; // Can't get the integer value as a constant.
21265 
21266   llvm::APSInt ConstLength = Result.Val.getInt();
21267   return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
21268 }
21269 
21270 // Return true if it can be proven that the provided array expression (array
21271 // section or array subscript) does NOT specify a single element of the array
21272 // whose base type is \a BaseQTy.
21273 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
21274                                                         const Expr *E,
21275                                                         QualType BaseQTy) {
21276   const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
21277 
21278   // An array subscript always refer to a single element. Also, an array section
21279   // assumes the format of an array subscript if no colon is used.
21280   if (isa<ArraySubscriptExpr>(E) ||
21281       (OASE && OASE->getColonLocFirst().isInvalid()))
21282     return false;
21283 
21284   assert(OASE && "Expecting array section if not an array subscript.");
21285   const Expr *Length = OASE->getLength();
21286 
21287   // If we don't have a length we have to check if the array has unitary size
21288   // for this dimension. Also, we should always expect a length if the base type
21289   // is pointer.
21290   if (!Length) {
21291     if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
21292       return ATy->getSize().getSExtValue() != 1;
21293     // We cannot assume anything.
21294     return false;
21295   }
21296 
21297   // Check if the length evaluates to 1.
21298   Expr::EvalResult Result;
21299   if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
21300     return false; // Can't get the integer value as a constant.
21301 
21302   llvm::APSInt ConstLength = Result.Val.getInt();
21303   return ConstLength.getSExtValue() != 1;
21304 }
21305 
21306 // The base of elements of list in a map clause have to be either:
21307 //  - a reference to variable or field.
21308 //  - a member expression.
21309 //  - an array expression.
21310 //
21311 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
21312 // reference to 'r'.
21313 //
21314 // If we have:
21315 //
21316 // struct SS {
21317 //   Bla S;
21318 //   foo() {
21319 //     #pragma omp target map (S.Arr[:12]);
21320 //   }
21321 // }
21322 //
21323 // We want to retrieve the member expression 'this->S';
21324 
21325 // OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2]
21326 //  If a list item is an array section, it must specify contiguous storage.
21327 //
21328 // For this restriction it is sufficient that we make sure only references
21329 // to variables or fields and array expressions, and that no array sections
21330 // exist except in the rightmost expression (unless they cover the whole
21331 // dimension of the array). E.g. these would be invalid:
21332 //
21333 //   r.ArrS[3:5].Arr[6:7]
21334 //
21335 //   r.ArrS[3:5].x
21336 //
21337 // but these would be valid:
21338 //   r.ArrS[3].Arr[6:7]
21339 //
21340 //   r.ArrS[3].x
21341 namespace {
21342 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> {
21343   Sema &SemaRef;
21344   OpenMPClauseKind CKind = OMPC_unknown;
21345   OpenMPDirectiveKind DKind = OMPD_unknown;
21346   OMPClauseMappableExprCommon::MappableExprComponentList &Components;
21347   bool IsNonContiguous = false;
21348   bool NoDiagnose = false;
21349   const Expr *RelevantExpr = nullptr;
21350   bool AllowUnitySizeArraySection = true;
21351   bool AllowWholeSizeArraySection = true;
21352   bool AllowAnotherPtr = true;
21353   SourceLocation ELoc;
21354   SourceRange ERange;
21355 
21356   void emitErrorMsg() {
21357     // If nothing else worked, this is not a valid map clause expression.
21358     if (SemaRef.getLangOpts().OpenMP < 50) {
21359       SemaRef.Diag(ELoc,
21360                    diag::err_omp_expected_named_var_member_or_array_expression)
21361           << ERange;
21362     } else {
21363       SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
21364           << getOpenMPClauseName(CKind) << ERange;
21365     }
21366   }
21367 
21368 public:
21369   bool VisitDeclRefExpr(DeclRefExpr *DRE) {
21370     if (!isa<VarDecl>(DRE->getDecl())) {
21371       emitErrorMsg();
21372       return false;
21373     }
21374     assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21375     RelevantExpr = DRE;
21376     // Record the component.
21377     Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous);
21378     return true;
21379   }
21380 
21381   bool VisitMemberExpr(MemberExpr *ME) {
21382     Expr *E = ME;
21383     Expr *BaseE = ME->getBase()->IgnoreParenCasts();
21384 
21385     if (isa<CXXThisExpr>(BaseE)) {
21386       assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21387       // We found a base expression: this->Val.
21388       RelevantExpr = ME;
21389     } else {
21390       E = BaseE;
21391     }
21392 
21393     if (!isa<FieldDecl>(ME->getMemberDecl())) {
21394       if (!NoDiagnose) {
21395         SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
21396             << ME->getSourceRange();
21397         return false;
21398       }
21399       if (RelevantExpr)
21400         return false;
21401       return Visit(E);
21402     }
21403 
21404     auto *FD = cast<FieldDecl>(ME->getMemberDecl());
21405 
21406     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
21407     //  A bit-field cannot appear in a map clause.
21408     //
21409     if (FD->isBitField()) {
21410       if (!NoDiagnose) {
21411         SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
21412             << ME->getSourceRange() << getOpenMPClauseName(CKind);
21413         return false;
21414       }
21415       if (RelevantExpr)
21416         return false;
21417       return Visit(E);
21418     }
21419 
21420     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
21421     //  If the type of a list item is a reference to a type T then the type
21422     //  will be considered to be T for all purposes of this clause.
21423     QualType CurType = BaseE->getType().getNonReferenceType();
21424 
21425     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
21426     //  A list item cannot be a variable that is a member of a structure with
21427     //  a union type.
21428     //
21429     if (CurType->isUnionType()) {
21430       if (!NoDiagnose) {
21431         SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
21432             << ME->getSourceRange();
21433         return false;
21434       }
21435       return RelevantExpr || Visit(E);
21436     }
21437 
21438     // If we got a member expression, we should not expect any array section
21439     // before that:
21440     //
21441     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
21442     //  If a list item is an element of a structure, only the rightmost symbol
21443     //  of the variable reference can be an array section.
21444     //
21445     AllowUnitySizeArraySection = false;
21446     AllowWholeSizeArraySection = false;
21447 
21448     // Record the component.
21449     Components.emplace_back(ME, FD, IsNonContiguous);
21450     return RelevantExpr || Visit(E);
21451   }
21452 
21453   bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) {
21454     Expr *E = AE->getBase()->IgnoreParenImpCasts();
21455 
21456     if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
21457       if (!NoDiagnose) {
21458         SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
21459             << 0 << AE->getSourceRange();
21460         return false;
21461       }
21462       return RelevantExpr || Visit(E);
21463     }
21464 
21465     // If we got an array subscript that express the whole dimension we
21466     // can have any array expressions before. If it only expressing part of
21467     // the dimension, we can only have unitary-size array expressions.
21468     if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, E->getType()))
21469       AllowWholeSizeArraySection = false;
21470 
21471     if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) {
21472       Expr::EvalResult Result;
21473       if (!AE->getIdx()->isValueDependent() &&
21474           AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) &&
21475           !Result.Val.getInt().isZero()) {
21476         SemaRef.Diag(AE->getIdx()->getExprLoc(),
21477                      diag::err_omp_invalid_map_this_expr);
21478         SemaRef.Diag(AE->getIdx()->getExprLoc(),
21479                      diag::note_omp_invalid_subscript_on_this_ptr_map);
21480       }
21481       assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21482       RelevantExpr = TE;
21483     }
21484 
21485     // Record the component - we don't have any declaration associated.
21486     Components.emplace_back(AE, nullptr, IsNonContiguous);
21487 
21488     return RelevantExpr || Visit(E);
21489   }
21490 
21491   bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) {
21492     // After OMP 5.0  Array section in reduction clause will be implicitly
21493     // mapped
21494     assert(!(SemaRef.getLangOpts().OpenMP < 50 && NoDiagnose) &&
21495            "Array sections cannot be implicitly mapped.");
21496     Expr *E = OASE->getBase()->IgnoreParenImpCasts();
21497     QualType CurType =
21498         OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
21499 
21500     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
21501     //  If the type of a list item is a reference to a type T then the type
21502     //  will be considered to be T for all purposes of this clause.
21503     if (CurType->isReferenceType())
21504       CurType = CurType->getPointeeType();
21505 
21506     bool IsPointer = CurType->isAnyPointerType();
21507 
21508     if (!IsPointer && !CurType->isArrayType()) {
21509       SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
21510           << 0 << OASE->getSourceRange();
21511       return false;
21512     }
21513 
21514     bool NotWhole =
21515         checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType);
21516     bool NotUnity =
21517         checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType);
21518 
21519     if (AllowWholeSizeArraySection) {
21520       // Any array section is currently allowed. Allowing a whole size array
21521       // section implies allowing a unity array section as well.
21522       //
21523       // If this array section refers to the whole dimension we can still
21524       // accept other array sections before this one, except if the base is a
21525       // pointer. Otherwise, only unitary sections are accepted.
21526       if (NotWhole || IsPointer)
21527         AllowWholeSizeArraySection = false;
21528     } else if (DKind == OMPD_target_update &&
21529                SemaRef.getLangOpts().OpenMP >= 50) {
21530       if (IsPointer && !AllowAnotherPtr)
21531         SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined)
21532             << /*array of unknown bound */ 1;
21533       else
21534         IsNonContiguous = true;
21535     } else if (AllowUnitySizeArraySection && NotUnity) {
21536       // A unity or whole array section is not allowed and that is not
21537       // compatible with the properties of the current array section.
21538       if (NoDiagnose)
21539         return false;
21540       SemaRef.Diag(ELoc,
21541                    diag::err_array_section_does_not_specify_contiguous_storage)
21542           << OASE->getSourceRange();
21543       return false;
21544     }
21545 
21546     if (IsPointer)
21547       AllowAnotherPtr = false;
21548 
21549     if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
21550       Expr::EvalResult ResultR;
21551       Expr::EvalResult ResultL;
21552       if (!OASE->getLength()->isValueDependent() &&
21553           OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) &&
21554           !ResultR.Val.getInt().isOne()) {
21555         SemaRef.Diag(OASE->getLength()->getExprLoc(),
21556                      diag::err_omp_invalid_map_this_expr);
21557         SemaRef.Diag(OASE->getLength()->getExprLoc(),
21558                      diag::note_omp_invalid_length_on_this_ptr_mapping);
21559       }
21560       if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() &&
21561           OASE->getLowerBound()->EvaluateAsInt(ResultL,
21562                                                SemaRef.getASTContext()) &&
21563           !ResultL.Val.getInt().isZero()) {
21564         SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
21565                      diag::err_omp_invalid_map_this_expr);
21566         SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
21567                      diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
21568       }
21569       assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21570       RelevantExpr = TE;
21571     }
21572 
21573     // Record the component - we don't have any declaration associated.
21574     Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false);
21575     return RelevantExpr || Visit(E);
21576   }
21577   bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
21578     Expr *Base = E->getBase();
21579 
21580     // Record the component - we don't have any declaration associated.
21581     Components.emplace_back(E, nullptr, IsNonContiguous);
21582 
21583     return Visit(Base->IgnoreParenImpCasts());
21584   }
21585 
21586   bool VisitUnaryOperator(UnaryOperator *UO) {
21587     if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() ||
21588         UO->getOpcode() != UO_Deref) {
21589       emitErrorMsg();
21590       return false;
21591     }
21592     if (!RelevantExpr) {
21593       // Record the component if haven't found base decl.
21594       Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false);
21595     }
21596     return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts());
21597   }
21598   bool VisitBinaryOperator(BinaryOperator *BO) {
21599     if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) {
21600       emitErrorMsg();
21601       return false;
21602     }
21603 
21604     // Pointer arithmetic is the only thing we expect to happen here so after we
21605     // make sure the binary operator is a pointer type, the only thing we need
21606     // to do is to visit the subtree that has the same type as root (so that we
21607     // know the other subtree is just an offset)
21608     Expr *LE = BO->getLHS()->IgnoreParenImpCasts();
21609     Expr *RE = BO->getRHS()->IgnoreParenImpCasts();
21610     Components.emplace_back(BO, nullptr, false);
21611     assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() ||
21612             RE->getType().getTypePtr() == BO->getType().getTypePtr()) &&
21613            "Either LHS or RHS have base decl inside");
21614     if (BO->getType().getTypePtr() == LE->getType().getTypePtr())
21615       return RelevantExpr || Visit(LE);
21616     return RelevantExpr || Visit(RE);
21617   }
21618   bool VisitCXXThisExpr(CXXThisExpr *CTE) {
21619     assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21620     RelevantExpr = CTE;
21621     Components.emplace_back(CTE, nullptr, IsNonContiguous);
21622     return true;
21623   }
21624   bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) {
21625     assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
21626     Components.emplace_back(COCE, nullptr, IsNonContiguous);
21627     return true;
21628   }
21629   bool VisitOpaqueValueExpr(OpaqueValueExpr *E) {
21630     Expr *Source = E->getSourceExpr();
21631     if (!Source) {
21632       emitErrorMsg();
21633       return false;
21634     }
21635     return Visit(Source);
21636   }
21637   bool VisitStmt(Stmt *) {
21638     emitErrorMsg();
21639     return false;
21640   }
21641   const Expr *getFoundBase() const { return RelevantExpr; }
21642   explicit MapBaseChecker(
21643       Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind,
21644       OMPClauseMappableExprCommon::MappableExprComponentList &Components,
21645       bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange)
21646       : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components),
21647         NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
21648 };
21649 } // namespace
21650 
21651 /// Return the expression of the base of the mappable expression or null if it
21652 /// cannot be determined and do all the necessary checks to see if the
21653 /// expression is valid as a standalone mappable expression. In the process,
21654 /// record all the components of the expression.
21655 static const Expr *checkMapClauseExpressionBase(
21656     Sema &SemaRef, Expr *E,
21657     OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
21658     OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) {
21659   SourceLocation ELoc = E->getExprLoc();
21660   SourceRange ERange = E->getSourceRange();
21661   MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc,
21662                          ERange);
21663   if (Checker.Visit(E->IgnoreParens())) {
21664     // Check if the highest dimension array section has length specified
21665     if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() &&
21666         (CKind == OMPC_to || CKind == OMPC_from)) {
21667       auto CI = CurComponents.rbegin();
21668       auto CE = CurComponents.rend();
21669       for (; CI != CE; ++CI) {
21670         const auto *OASE =
21671             dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression());
21672         if (!OASE)
21673           continue;
21674         if (OASE && OASE->getLength())
21675           break;
21676         SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length)
21677             << ERange;
21678       }
21679     }
21680     return Checker.getFoundBase();
21681   }
21682   return nullptr;
21683 }
21684 
21685 // Return true if expression E associated with value VD has conflicts with other
21686 // map information.
21687 static bool checkMapConflicts(
21688     Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
21689     bool CurrentRegionOnly,
21690     OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
21691     OpenMPClauseKind CKind) {
21692   assert(VD && E);
21693   SourceLocation ELoc = E->getExprLoc();
21694   SourceRange ERange = E->getSourceRange();
21695 
21696   // In order to easily check the conflicts we need to match each component of
21697   // the expression under test with the components of the expressions that are
21698   // already in the stack.
21699 
21700   assert(!CurComponents.empty() && "Map clause expression with no components!");
21701   assert(CurComponents.back().getAssociatedDeclaration() == VD &&
21702          "Map clause expression with unexpected base!");
21703 
21704   // Variables to help detecting enclosing problems in data environment nests.
21705   bool IsEnclosedByDataEnvironmentExpr = false;
21706   const Expr *EnclosingExpr = nullptr;
21707 
21708   bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
21709       VD, CurrentRegionOnly,
21710       [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
21711        ERange, CKind, &EnclosingExpr,
21712        CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef
21713                           StackComponents,
21714                       OpenMPClauseKind Kind) {
21715         if (CKind == Kind && SemaRef.LangOpts.OpenMP >= 50)
21716           return false;
21717         assert(!StackComponents.empty() &&
21718                "Map clause expression with no components!");
21719         assert(StackComponents.back().getAssociatedDeclaration() == VD &&
21720                "Map clause expression with unexpected base!");
21721         (void)VD;
21722 
21723         // The whole expression in the stack.
21724         const Expr *RE = StackComponents.front().getAssociatedExpression();
21725 
21726         // Expressions must start from the same base. Here we detect at which
21727         // point both expressions diverge from each other and see if we can
21728         // detect if the memory referred to both expressions is contiguous and
21729         // do not overlap.
21730         auto CI = CurComponents.rbegin();
21731         auto CE = CurComponents.rend();
21732         auto SI = StackComponents.rbegin();
21733         auto SE = StackComponents.rend();
21734         for (; CI != CE && SI != SE; ++CI, ++SI) {
21735 
21736           // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
21737           //  At most one list item can be an array item derived from a given
21738           //  variable in map clauses of the same construct.
21739           if (CurrentRegionOnly &&
21740               (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
21741                isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) ||
21742                isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) &&
21743               (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
21744                isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) ||
21745                isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) {
21746             SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
21747                          diag::err_omp_multiple_array_items_in_map_clause)
21748                 << CI->getAssociatedExpression()->getSourceRange();
21749             SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
21750                          diag::note_used_here)
21751                 << SI->getAssociatedExpression()->getSourceRange();
21752             return true;
21753           }
21754 
21755           // Do both expressions have the same kind?
21756           if (CI->getAssociatedExpression()->getStmtClass() !=
21757               SI->getAssociatedExpression()->getStmtClass())
21758             break;
21759 
21760           // Are we dealing with different variables/fields?
21761           if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
21762             break;
21763         }
21764         // Check if the extra components of the expressions in the enclosing
21765         // data environment are redundant for the current base declaration.
21766         // If they are, the maps completely overlap, which is legal.
21767         for (; SI != SE; ++SI) {
21768           QualType Type;
21769           if (const auto *ASE =
21770                   dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
21771             Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
21772           } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
21773                          SI->getAssociatedExpression())) {
21774             const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
21775             Type =
21776                 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
21777           } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>(
21778                          SI->getAssociatedExpression())) {
21779             Type = OASE->getBase()->getType()->getPointeeType();
21780           }
21781           if (Type.isNull() || Type->isAnyPointerType() ||
21782               checkArrayExpressionDoesNotReferToWholeSize(
21783                   SemaRef, SI->getAssociatedExpression(), Type))
21784             break;
21785         }
21786 
21787         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
21788         //  List items of map clauses in the same construct must not share
21789         //  original storage.
21790         //
21791         // If the expressions are exactly the same or one is a subset of the
21792         // other, it means they are sharing storage.
21793         if (CI == CE && SI == SE) {
21794           if (CurrentRegionOnly) {
21795             if (CKind == OMPC_map) {
21796               SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
21797             } else {
21798               assert(CKind == OMPC_to || CKind == OMPC_from);
21799               SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
21800                   << ERange;
21801             }
21802             SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
21803                 << RE->getSourceRange();
21804             return true;
21805           }
21806           // If we find the same expression in the enclosing data environment,
21807           // that is legal.
21808           IsEnclosedByDataEnvironmentExpr = true;
21809           return false;
21810         }
21811 
21812         QualType DerivedType =
21813             std::prev(CI)->getAssociatedDeclaration()->getType();
21814         SourceLocation DerivedLoc =
21815             std::prev(CI)->getAssociatedExpression()->getExprLoc();
21816 
21817         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
21818         //  If the type of a list item is a reference to a type T then the type
21819         //  will be considered to be T for all purposes of this clause.
21820         DerivedType = DerivedType.getNonReferenceType();
21821 
21822         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
21823         //  A variable for which the type is pointer and an array section
21824         //  derived from that variable must not appear as list items of map
21825         //  clauses of the same construct.
21826         //
21827         // Also, cover one of the cases in:
21828         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
21829         //  If any part of the original storage of a list item has corresponding
21830         //  storage in the device data environment, all of the original storage
21831         //  must have corresponding storage in the device data environment.
21832         //
21833         if (DerivedType->isAnyPointerType()) {
21834           if (CI == CE || SI == SE) {
21835             SemaRef.Diag(
21836                 DerivedLoc,
21837                 diag::err_omp_pointer_mapped_along_with_derived_section)
21838                 << DerivedLoc;
21839             SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
21840                 << RE->getSourceRange();
21841             return true;
21842           }
21843           if (CI->getAssociatedExpression()->getStmtClass() !=
21844                   SI->getAssociatedExpression()->getStmtClass() ||
21845               CI->getAssociatedDeclaration()->getCanonicalDecl() ==
21846                   SI->getAssociatedDeclaration()->getCanonicalDecl()) {
21847             assert(CI != CE && SI != SE);
21848             SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
21849                 << DerivedLoc;
21850             SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
21851                 << RE->getSourceRange();
21852             return true;
21853           }
21854         }
21855 
21856         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
21857         //  List items of map clauses in the same construct must not share
21858         //  original storage.
21859         //
21860         // An expression is a subset of the other.
21861         if (CurrentRegionOnly && (CI == CE || SI == SE)) {
21862           if (CKind == OMPC_map) {
21863             if (CI != CE || SI != SE) {
21864               // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
21865               // a pointer.
21866               auto Begin =
21867                   CI != CE ? CurComponents.begin() : StackComponents.begin();
21868               auto End = CI != CE ? CurComponents.end() : StackComponents.end();
21869               auto It = Begin;
21870               while (It != End && !It->getAssociatedDeclaration())
21871                 std::advance(It, 1);
21872               assert(It != End &&
21873                      "Expected at least one component with the declaration.");
21874               if (It != Begin && It->getAssociatedDeclaration()
21875                                      ->getType()
21876                                      .getCanonicalType()
21877                                      ->isAnyPointerType()) {
21878                 IsEnclosedByDataEnvironmentExpr = false;
21879                 EnclosingExpr = nullptr;
21880                 return false;
21881               }
21882             }
21883             SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
21884           } else {
21885             assert(CKind == OMPC_to || CKind == OMPC_from);
21886             SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
21887                 << ERange;
21888           }
21889           SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
21890               << RE->getSourceRange();
21891           return true;
21892         }
21893 
21894         // The current expression uses the same base as other expression in the
21895         // data environment but does not contain it completely.
21896         if (!CurrentRegionOnly && SI != SE)
21897           EnclosingExpr = RE;
21898 
21899         // The current expression is a subset of the expression in the data
21900         // environment.
21901         IsEnclosedByDataEnvironmentExpr |=
21902             (!CurrentRegionOnly && CI != CE && SI == SE);
21903 
21904         return false;
21905       });
21906 
21907   if (CurrentRegionOnly)
21908     return FoundError;
21909 
21910   // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
21911   //  If any part of the original storage of a list item has corresponding
21912   //  storage in the device data environment, all of the original storage must
21913   //  have corresponding storage in the device data environment.
21914   // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
21915   //  If a list item is an element of a structure, and a different element of
21916   //  the structure has a corresponding list item in the device data environment
21917   //  prior to a task encountering the construct associated with the map clause,
21918   //  then the list item must also have a corresponding list item in the device
21919   //  data environment prior to the task encountering the construct.
21920   //
21921   if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
21922     SemaRef.Diag(ELoc,
21923                  diag::err_omp_original_storage_is_shared_and_does_not_contain)
21924         << ERange;
21925     SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
21926         << EnclosingExpr->getSourceRange();
21927     return true;
21928   }
21929 
21930   return FoundError;
21931 }
21932 
21933 // Look up the user-defined mapper given the mapper name and mapped type, and
21934 // build a reference to it.
21935 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
21936                                             CXXScopeSpec &MapperIdScopeSpec,
21937                                             const DeclarationNameInfo &MapperId,
21938                                             QualType Type,
21939                                             Expr *UnresolvedMapper) {
21940   if (MapperIdScopeSpec.isInvalid())
21941     return ExprError();
21942   // Get the actual type for the array type.
21943   if (Type->isArrayType()) {
21944     assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type");
21945     Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType();
21946   }
21947   // Find all user-defined mappers with the given MapperId.
21948   SmallVector<UnresolvedSet<8>, 4> Lookups;
21949   LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
21950   Lookup.suppressDiagnostics();
21951   if (S) {
21952     while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) {
21953       NamedDecl *D = Lookup.getRepresentativeDecl();
21954       while (S && !S->isDeclScope(D))
21955         S = S->getParent();
21956       if (S)
21957         S = S->getParent();
21958       Lookups.emplace_back();
21959       Lookups.back().append(Lookup.begin(), Lookup.end());
21960       Lookup.clear();
21961     }
21962   } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
21963     // Extract the user-defined mappers with the given MapperId.
21964     Lookups.push_back(UnresolvedSet<8>());
21965     for (NamedDecl *D : ULE->decls()) {
21966       auto *DMD = cast<OMPDeclareMapperDecl>(D);
21967       assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation.");
21968       Lookups.back().addDecl(DMD);
21969     }
21970   }
21971   // Defer the lookup for dependent types. The results will be passed through
21972   // UnresolvedMapper on instantiation.
21973   if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
21974       Type->isInstantiationDependentType() ||
21975       Type->containsUnexpandedParameterPack() ||
21976       filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
21977         return !D->isInvalidDecl() &&
21978                (D->getType()->isDependentType() ||
21979                 D->getType()->isInstantiationDependentType() ||
21980                 D->getType()->containsUnexpandedParameterPack());
21981       })) {
21982     UnresolvedSet<8> URS;
21983     for (const UnresolvedSet<8> &Set : Lookups) {
21984       if (Set.empty())
21985         continue;
21986       URS.append(Set.begin(), Set.end());
21987     }
21988     return UnresolvedLookupExpr::Create(
21989         SemaRef.Context, /*NamingClass=*/nullptr,
21990         MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
21991         /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end());
21992   }
21993   SourceLocation Loc = MapperId.getLoc();
21994   // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
21995   //  The type must be of struct, union or class type in C and C++
21996   if (!Type->isStructureOrClassType() && !Type->isUnionType() &&
21997       (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) {
21998     SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type);
21999     return ExprError();
22000   }
22001   // Perform argument dependent lookup.
22002   if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
22003     argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
22004   // Return the first user-defined mapper with the desired type.
22005   if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
22006           Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
22007             if (!D->isInvalidDecl() &&
22008                 SemaRef.Context.hasSameType(D->getType(), Type))
22009               return D;
22010             return nullptr;
22011           }))
22012     return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
22013   // Find the first user-defined mapper with a type derived from the desired
22014   // type.
22015   if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
22016           Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
22017             if (!D->isInvalidDecl() &&
22018                 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
22019                 !Type.isMoreQualifiedThan(D->getType()))
22020               return D;
22021             return nullptr;
22022           })) {
22023     CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
22024                        /*DetectVirtual=*/false);
22025     if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
22026       if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
22027               VD->getType().getUnqualifiedType()))) {
22028         if (SemaRef.CheckBaseClassAccess(
22029                 Loc, VD->getType(), Type, Paths.front(),
22030                 /*DiagID=*/0) != Sema::AR_inaccessible) {
22031           return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
22032         }
22033       }
22034     }
22035   }
22036   // Report error if a mapper is specified, but cannot be found.
22037   if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
22038     SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
22039         << Type << MapperId.getName();
22040     return ExprError();
22041   }
22042   return ExprEmpty();
22043 }
22044 
22045 namespace {
22046 // Utility struct that gathers all the related lists associated with a mappable
22047 // expression.
22048 struct MappableVarListInfo {
22049   // The list of expressions.
22050   ArrayRef<Expr *> VarList;
22051   // The list of processed expressions.
22052   SmallVector<Expr *, 16> ProcessedVarList;
22053   // The mappble components for each expression.
22054   OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
22055   // The base declaration of the variable.
22056   SmallVector<ValueDecl *, 16> VarBaseDeclarations;
22057   // The reference to the user-defined mapper associated with every expression.
22058   SmallVector<Expr *, 16> UDMapperList;
22059 
22060   MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
22061     // We have a list of components and base declarations for each entry in the
22062     // variable list.
22063     VarComponents.reserve(VarList.size());
22064     VarBaseDeclarations.reserve(VarList.size());
22065   }
22066 };
22067 } // namespace
22068 
22069 // Check the validity of the provided variable list for the provided clause kind
22070 // \a CKind. In the check process the valid expressions, mappable expression
22071 // components, variables, and user-defined mappers are extracted and used to
22072 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
22073 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
22074 // and \a MapperId are expected to be valid if the clause kind is 'map'.
22075 static void checkMappableExpressionList(
22076     Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
22077     MappableVarListInfo &MVLI, SourceLocation StartLoc,
22078     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
22079     ArrayRef<Expr *> UnresolvedMappers,
22080     OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
22081     ArrayRef<OpenMPMapModifierKind> Modifiers = std::nullopt,
22082     bool IsMapTypeImplicit = false, bool NoDiagnose = false) {
22083   // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
22084   assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
22085          "Unexpected clause kind with mappable expressions!");
22086 
22087   // If the identifier of user-defined mapper is not specified, it is "default".
22088   // We do not change the actual name in this clause to distinguish whether a
22089   // mapper is specified explicitly, i.e., it is not explicitly specified when
22090   // MapperId.getName() is empty.
22091   if (!MapperId.getName() || MapperId.getName().isEmpty()) {
22092     auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
22093     MapperId.setName(DeclNames.getIdentifier(
22094         &SemaRef.getASTContext().Idents.get("default")));
22095     MapperId.setLoc(StartLoc);
22096   }
22097 
22098   // Iterators to find the current unresolved mapper expression.
22099   auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
22100   bool UpdateUMIt = false;
22101   Expr *UnresolvedMapper = nullptr;
22102 
22103   bool HasHoldModifier =
22104       llvm::is_contained(Modifiers, OMPC_MAP_MODIFIER_ompx_hold);
22105 
22106   // Keep track of the mappable components and base declarations in this clause.
22107   // Each entry in the list is going to have a list of components associated. We
22108   // record each set of the components so that we can build the clause later on.
22109   // In the end we should have the same amount of declarations and component
22110   // lists.
22111 
22112   for (Expr *RE : MVLI.VarList) {
22113     assert(RE && "Null expr in omp to/from/map clause");
22114     SourceLocation ELoc = RE->getExprLoc();
22115 
22116     // Find the current unresolved mapper expression.
22117     if (UpdateUMIt && UMIt != UMEnd) {
22118       UMIt++;
22119       assert(
22120           UMIt != UMEnd &&
22121           "Expect the size of UnresolvedMappers to match with that of VarList");
22122     }
22123     UpdateUMIt = true;
22124     if (UMIt != UMEnd)
22125       UnresolvedMapper = *UMIt;
22126 
22127     const Expr *VE = RE->IgnoreParenLValueCasts();
22128 
22129     if (VE->isValueDependent() || VE->isTypeDependent() ||
22130         VE->isInstantiationDependent() ||
22131         VE->containsUnexpandedParameterPack()) {
22132       // Try to find the associated user-defined mapper.
22133       ExprResult ER = buildUserDefinedMapperRef(
22134           SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
22135           VE->getType().getCanonicalType(), UnresolvedMapper);
22136       if (ER.isInvalid())
22137         continue;
22138       MVLI.UDMapperList.push_back(ER.get());
22139       // We can only analyze this information once the missing information is
22140       // resolved.
22141       MVLI.ProcessedVarList.push_back(RE);
22142       continue;
22143     }
22144 
22145     Expr *SimpleExpr = RE->IgnoreParenCasts();
22146 
22147     if (!RE->isLValue()) {
22148       if (SemaRef.getLangOpts().OpenMP < 50) {
22149         SemaRef.Diag(
22150             ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
22151             << RE->getSourceRange();
22152       } else {
22153         SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
22154             << getOpenMPClauseName(CKind) << RE->getSourceRange();
22155       }
22156       continue;
22157     }
22158 
22159     OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
22160     ValueDecl *CurDeclaration = nullptr;
22161 
22162     // Obtain the array or member expression bases if required. Also, fill the
22163     // components array with all the components identified in the process.
22164     const Expr *BE =
22165         checkMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents, CKind,
22166                                      DSAS->getCurrentDirective(), NoDiagnose);
22167     if (!BE)
22168       continue;
22169 
22170     assert(!CurComponents.empty() &&
22171            "Invalid mappable expression information.");
22172 
22173     if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
22174       // Add store "this" pointer to class in DSAStackTy for future checking
22175       DSAS->addMappedClassesQualTypes(TE->getType());
22176       // Try to find the associated user-defined mapper.
22177       ExprResult ER = buildUserDefinedMapperRef(
22178           SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
22179           VE->getType().getCanonicalType(), UnresolvedMapper);
22180       if (ER.isInvalid())
22181         continue;
22182       MVLI.UDMapperList.push_back(ER.get());
22183       // Skip restriction checking for variable or field declarations
22184       MVLI.ProcessedVarList.push_back(RE);
22185       MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
22186       MVLI.VarComponents.back().append(CurComponents.begin(),
22187                                        CurComponents.end());
22188       MVLI.VarBaseDeclarations.push_back(nullptr);
22189       continue;
22190     }
22191 
22192     // For the following checks, we rely on the base declaration which is
22193     // expected to be associated with the last component. The declaration is
22194     // expected to be a variable or a field (if 'this' is being mapped).
22195     CurDeclaration = CurComponents.back().getAssociatedDeclaration();
22196     assert(CurDeclaration && "Null decl on map clause.");
22197     assert(
22198         CurDeclaration->isCanonicalDecl() &&
22199         "Expecting components to have associated only canonical declarations.");
22200 
22201     auto *VD = dyn_cast<VarDecl>(CurDeclaration);
22202     const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
22203 
22204     assert((VD || FD) && "Only variables or fields are expected here!");
22205     (void)FD;
22206 
22207     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
22208     // threadprivate variables cannot appear in a map clause.
22209     // OpenMP 4.5 [2.10.5, target update Construct]
22210     // threadprivate variables cannot appear in a from clause.
22211     if (VD && DSAS->isThreadPrivate(VD)) {
22212       if (NoDiagnose)
22213         continue;
22214       DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
22215       SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
22216           << getOpenMPClauseName(CKind);
22217       reportOriginalDsa(SemaRef, DSAS, VD, DVar);
22218       continue;
22219     }
22220 
22221     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
22222     //  A list item cannot appear in both a map clause and a data-sharing
22223     //  attribute clause on the same construct.
22224 
22225     // Check conflicts with other map clause expressions. We check the conflicts
22226     // with the current construct separately from the enclosing data
22227     // environment, because the restrictions are different. We only have to
22228     // check conflicts across regions for the map clauses.
22229     if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
22230                           /*CurrentRegionOnly=*/true, CurComponents, CKind))
22231       break;
22232     if (CKind == OMPC_map &&
22233         (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) &&
22234         checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
22235                           /*CurrentRegionOnly=*/false, CurComponents, CKind))
22236       break;
22237 
22238     // OpenMP 4.5 [2.10.5, target update Construct]
22239     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
22240     //  If the type of a list item is a reference to a type T then the type will
22241     //  be considered to be T for all purposes of this clause.
22242     auto I = llvm::find_if(
22243         CurComponents,
22244         [](const OMPClauseMappableExprCommon::MappableComponent &MC) {
22245           return MC.getAssociatedDeclaration();
22246         });
22247     assert(I != CurComponents.end() && "Null decl on map clause.");
22248     (void)I;
22249     QualType Type;
22250     auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens());
22251     auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens());
22252     auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens());
22253     if (ASE) {
22254       Type = ASE->getType().getNonReferenceType();
22255     } else if (OASE) {
22256       QualType BaseType =
22257           OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
22258       if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
22259         Type = ATy->getElementType();
22260       else
22261         Type = BaseType->getPointeeType();
22262       Type = Type.getNonReferenceType();
22263     } else if (OAShE) {
22264       Type = OAShE->getBase()->getType()->getPointeeType();
22265     } else {
22266       Type = VE->getType();
22267     }
22268 
22269     // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
22270     // A list item in a to or from clause must have a mappable type.
22271     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
22272     //  A list item must have a mappable type.
22273     if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
22274                            DSAS, Type, /*FullCheck=*/true))
22275       continue;
22276 
22277     if (CKind == OMPC_map) {
22278       // target enter data
22279       // OpenMP [2.10.2, Restrictions, p. 99]
22280       // A map-type must be specified in all map clauses and must be either
22281       // to or alloc. Starting with OpenMP 5.2 the default map type is `to` if
22282       // no map type is present.
22283       OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
22284       if (DKind == OMPD_target_enter_data &&
22285           !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc ||
22286             SemaRef.getLangOpts().OpenMP >= 52)) {
22287         SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
22288             << (IsMapTypeImplicit ? 1 : 0)
22289             << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
22290             << getOpenMPDirectiveName(DKind);
22291         continue;
22292       }
22293 
22294       // target exit_data
22295       // OpenMP [2.10.3, Restrictions, p. 102]
22296       // A map-type must be specified in all map clauses and must be either
22297       // from, release, or delete. Starting with OpenMP 5.2 the default map
22298       // type is `from` if no map type is present.
22299       if (DKind == OMPD_target_exit_data &&
22300           !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
22301             MapType == OMPC_MAP_delete || SemaRef.getLangOpts().OpenMP >= 52)) {
22302         SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
22303             << (IsMapTypeImplicit ? 1 : 0)
22304             << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
22305             << getOpenMPDirectiveName(DKind);
22306         continue;
22307       }
22308 
22309       // The 'ompx_hold' modifier is specifically intended to be used on a
22310       // 'target' or 'target data' directive to prevent data from being unmapped
22311       // during the associated statement.  It is not permitted on a 'target
22312       // enter data' or 'target exit data' directive, which have no associated
22313       // statement.
22314       if ((DKind == OMPD_target_enter_data || DKind == OMPD_target_exit_data) &&
22315           HasHoldModifier) {
22316         SemaRef.Diag(StartLoc,
22317                      diag::err_omp_invalid_map_type_modifier_for_directive)
22318             << getOpenMPSimpleClauseTypeName(OMPC_map,
22319                                              OMPC_MAP_MODIFIER_ompx_hold)
22320             << getOpenMPDirectiveName(DKind);
22321         continue;
22322       }
22323 
22324       // target, target data
22325       // OpenMP 5.0 [2.12.2, Restrictions, p. 163]
22326       // OpenMP 5.0 [2.12.5, Restrictions, p. 174]
22327       // A map-type in a map clause must be to, from, tofrom or alloc
22328       if ((DKind == OMPD_target_data ||
22329            isOpenMPTargetExecutionDirective(DKind)) &&
22330           !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
22331             MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) {
22332         SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
22333             << (IsMapTypeImplicit ? 1 : 0)
22334             << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
22335             << getOpenMPDirectiveName(DKind);
22336         continue;
22337       }
22338 
22339       // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
22340       // A list item cannot appear in both a map clause and a data-sharing
22341       // attribute clause on the same construct
22342       //
22343       // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
22344       // A list item cannot appear in both a map clause and a data-sharing
22345       // attribute clause on the same construct unless the construct is a
22346       // combined construct.
22347       if (VD && ((SemaRef.LangOpts.OpenMP <= 45 &&
22348                   isOpenMPTargetExecutionDirective(DKind)) ||
22349                  DKind == OMPD_target)) {
22350         DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
22351         if (isOpenMPPrivate(DVar.CKind)) {
22352           SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
22353               << getOpenMPClauseName(DVar.CKind)
22354               << getOpenMPClauseName(OMPC_map)
22355               << getOpenMPDirectiveName(DSAS->getCurrentDirective());
22356           reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
22357           continue;
22358         }
22359       }
22360     }
22361 
22362     // Try to find the associated user-defined mapper.
22363     ExprResult ER = buildUserDefinedMapperRef(
22364         SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
22365         Type.getCanonicalType(), UnresolvedMapper);
22366     if (ER.isInvalid())
22367       continue;
22368     MVLI.UDMapperList.push_back(ER.get());
22369 
22370     // Save the current expression.
22371     MVLI.ProcessedVarList.push_back(RE);
22372 
22373     // Store the components in the stack so that they can be used to check
22374     // against other clauses later on.
22375     DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
22376                                           /*WhereFoundClauseKind=*/OMPC_map);
22377 
22378     // Save the components and declaration to create the clause. For purposes of
22379     // the clause creation, any component list that has base 'this' uses
22380     // null as base declaration.
22381     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
22382     MVLI.VarComponents.back().append(CurComponents.begin(),
22383                                      CurComponents.end());
22384     MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
22385                                                            : CurDeclaration);
22386   }
22387 }
22388 
22389 OMPClause *Sema::ActOnOpenMPMapClause(
22390     Expr *IteratorModifier, ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
22391     ArrayRef<SourceLocation> MapTypeModifiersLoc,
22392     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
22393     OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
22394     SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
22395     const OMPVarListLocTy &Locs, bool NoDiagnose,
22396     ArrayRef<Expr *> UnresolvedMappers) {
22397   OpenMPMapModifierKind Modifiers[] = {
22398       OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
22399       OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
22400       OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown};
22401   SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers];
22402 
22403   if (IteratorModifier && !IteratorModifier->getType()->isSpecificBuiltinType(
22404                               BuiltinType::OMPIterator))
22405     Diag(IteratorModifier->getExprLoc(),
22406          diag::err_omp_map_modifier_not_iterator);
22407 
22408   // Process map-type-modifiers, flag errors for duplicate modifiers.
22409   unsigned Count = 0;
22410   for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
22411     if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
22412         llvm::is_contained(Modifiers, MapTypeModifiers[I])) {
22413       Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
22414       continue;
22415     }
22416     assert(Count < NumberOfOMPMapClauseModifiers &&
22417            "Modifiers exceed the allowed number of map type modifiers");
22418     Modifiers[Count] = MapTypeModifiers[I];
22419     ModifiersLoc[Count] = MapTypeModifiersLoc[I];
22420     ++Count;
22421   }
22422 
22423   MappableVarListInfo MVLI(VarList);
22424   checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc,
22425                               MapperIdScopeSpec, MapperId, UnresolvedMappers,
22426                               MapType, Modifiers, IsMapTypeImplicit,
22427                               NoDiagnose);
22428 
22429   // We need to produce a map clause even if we don't have variables so that
22430   // other diagnostics related with non-existing map clauses are accurate.
22431   return OMPMapClause::Create(
22432       Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
22433       MVLI.VarComponents, MVLI.UDMapperList, IteratorModifier, Modifiers,
22434       ModifiersLoc, MapperIdScopeSpec.getWithLocInContext(Context), MapperId,
22435       MapType, IsMapTypeImplicit, MapLoc);
22436 }
22437 
22438 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
22439                                                TypeResult ParsedType) {
22440   assert(ParsedType.isUsable());
22441 
22442   QualType ReductionType = GetTypeFromParser(ParsedType.get());
22443   if (ReductionType.isNull())
22444     return QualType();
22445 
22446   // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
22447   // A type name in a declare reduction directive cannot be a function type, an
22448   // array type, a reference type, or a type qualified with const, volatile or
22449   // restrict.
22450   if (ReductionType.hasQualifiers()) {
22451     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
22452     return QualType();
22453   }
22454 
22455   if (ReductionType->isFunctionType()) {
22456     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
22457     return QualType();
22458   }
22459   if (ReductionType->isReferenceType()) {
22460     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
22461     return QualType();
22462   }
22463   if (ReductionType->isArrayType()) {
22464     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
22465     return QualType();
22466   }
22467   return ReductionType;
22468 }
22469 
22470 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
22471     Scope *S, DeclContext *DC, DeclarationName Name,
22472     ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
22473     AccessSpecifier AS, Decl *PrevDeclInScope) {
22474   SmallVector<Decl *, 8> Decls;
22475   Decls.reserve(ReductionTypes.size());
22476 
22477   LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
22478                       forRedeclarationInCurContext());
22479   // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
22480   // A reduction-identifier may not be re-declared in the current scope for the
22481   // same type or for a type that is compatible according to the base language
22482   // rules.
22483   llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
22484   OMPDeclareReductionDecl *PrevDRD = nullptr;
22485   bool InCompoundScope = true;
22486   if (S != nullptr) {
22487     // Find previous declaration with the same name not referenced in other
22488     // declarations.
22489     FunctionScopeInfo *ParentFn = getEnclosingFunction();
22490     InCompoundScope =
22491         (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
22492     LookupName(Lookup, S);
22493     FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
22494                          /*AllowInlineNamespace=*/false);
22495     llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
22496     LookupResult::Filter Filter = Lookup.makeFilter();
22497     while (Filter.hasNext()) {
22498       auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
22499       if (InCompoundScope) {
22500         auto I = UsedAsPrevious.find(PrevDecl);
22501         if (I == UsedAsPrevious.end())
22502           UsedAsPrevious[PrevDecl] = false;
22503         if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
22504           UsedAsPrevious[D] = true;
22505       }
22506       PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
22507           PrevDecl->getLocation();
22508     }
22509     Filter.done();
22510     if (InCompoundScope) {
22511       for (const auto &PrevData : UsedAsPrevious) {
22512         if (!PrevData.second) {
22513           PrevDRD = PrevData.first;
22514           break;
22515         }
22516       }
22517     }
22518   } else if (PrevDeclInScope != nullptr) {
22519     auto *PrevDRDInScope = PrevDRD =
22520         cast<OMPDeclareReductionDecl>(PrevDeclInScope);
22521     do {
22522       PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
22523           PrevDRDInScope->getLocation();
22524       PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
22525     } while (PrevDRDInScope != nullptr);
22526   }
22527   for (const auto &TyData : ReductionTypes) {
22528     const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
22529     bool Invalid = false;
22530     if (I != PreviousRedeclTypes.end()) {
22531       Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
22532           << TyData.first;
22533       Diag(I->second, diag::note_previous_definition);
22534       Invalid = true;
22535     }
22536     PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
22537     auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
22538                                                 Name, TyData.first, PrevDRD);
22539     DC->addDecl(DRD);
22540     DRD->setAccess(AS);
22541     Decls.push_back(DRD);
22542     if (Invalid)
22543       DRD->setInvalidDecl();
22544     else
22545       PrevDRD = DRD;
22546   }
22547 
22548   return DeclGroupPtrTy::make(
22549       DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
22550 }
22551 
22552 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
22553   auto *DRD = cast<OMPDeclareReductionDecl>(D);
22554 
22555   // Enter new function scope.
22556   PushFunctionScope();
22557   setFunctionHasBranchProtectedScope();
22558   getCurFunction()->setHasOMPDeclareReductionCombiner();
22559 
22560   if (S != nullptr)
22561     PushDeclContext(S, DRD);
22562   else
22563     CurContext = DRD;
22564 
22565   PushExpressionEvaluationContext(
22566       ExpressionEvaluationContext::PotentiallyEvaluated);
22567 
22568   QualType ReductionType = DRD->getType();
22569   // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
22570   // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
22571   // uses semantics of argument handles by value, but it should be passed by
22572   // reference. C lang does not support references, so pass all parameters as
22573   // pointers.
22574   // Create 'T omp_in;' variable.
22575   VarDecl *OmpInParm =
22576       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
22577   // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
22578   // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
22579   // uses semantics of argument handles by value, but it should be passed by
22580   // reference. C lang does not support references, so pass all parameters as
22581   // pointers.
22582   // Create 'T omp_out;' variable.
22583   VarDecl *OmpOutParm =
22584       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
22585   if (S != nullptr) {
22586     PushOnScopeChains(OmpInParm, S);
22587     PushOnScopeChains(OmpOutParm, S);
22588   } else {
22589     DRD->addDecl(OmpInParm);
22590     DRD->addDecl(OmpOutParm);
22591   }
22592   Expr *InE =
22593       ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
22594   Expr *OutE =
22595       ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
22596   DRD->setCombinerData(InE, OutE);
22597 }
22598 
22599 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
22600   auto *DRD = cast<OMPDeclareReductionDecl>(D);
22601   DiscardCleanupsInEvaluationContext();
22602   PopExpressionEvaluationContext();
22603 
22604   PopDeclContext();
22605   PopFunctionScopeInfo();
22606 
22607   if (Combiner != nullptr)
22608     DRD->setCombiner(Combiner);
22609   else
22610     DRD->setInvalidDecl();
22611 }
22612 
22613 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
22614   auto *DRD = cast<OMPDeclareReductionDecl>(D);
22615 
22616   // Enter new function scope.
22617   PushFunctionScope();
22618   setFunctionHasBranchProtectedScope();
22619 
22620   if (S != nullptr)
22621     PushDeclContext(S, DRD);
22622   else
22623     CurContext = DRD;
22624 
22625   PushExpressionEvaluationContext(
22626       ExpressionEvaluationContext::PotentiallyEvaluated);
22627 
22628   QualType ReductionType = DRD->getType();
22629   // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
22630   // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
22631   // uses semantics of argument handles by value, but it should be passed by
22632   // reference. C lang does not support references, so pass all parameters as
22633   // pointers.
22634   // Create 'T omp_priv;' variable.
22635   VarDecl *OmpPrivParm =
22636       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
22637   // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
22638   // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
22639   // uses semantics of argument handles by value, but it should be passed by
22640   // reference. C lang does not support references, so pass all parameters as
22641   // pointers.
22642   // Create 'T omp_orig;' variable.
22643   VarDecl *OmpOrigParm =
22644       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
22645   if (S != nullptr) {
22646     PushOnScopeChains(OmpPrivParm, S);
22647     PushOnScopeChains(OmpOrigParm, S);
22648   } else {
22649     DRD->addDecl(OmpPrivParm);
22650     DRD->addDecl(OmpOrigParm);
22651   }
22652   Expr *OrigE =
22653       ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
22654   Expr *PrivE =
22655       ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
22656   DRD->setInitializerData(OrigE, PrivE);
22657   return OmpPrivParm;
22658 }
22659 
22660 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
22661                                                      VarDecl *OmpPrivParm) {
22662   auto *DRD = cast<OMPDeclareReductionDecl>(D);
22663   DiscardCleanupsInEvaluationContext();
22664   PopExpressionEvaluationContext();
22665 
22666   PopDeclContext();
22667   PopFunctionScopeInfo();
22668 
22669   if (Initializer != nullptr) {
22670     DRD->setInitializer(Initializer, OMPDeclareReductionInitKind::Call);
22671   } else if (OmpPrivParm->hasInit()) {
22672     DRD->setInitializer(OmpPrivParm->getInit(),
22673                         OmpPrivParm->isDirectInit()
22674                             ? OMPDeclareReductionInitKind::Direct
22675                             : OMPDeclareReductionInitKind::Copy);
22676   } else {
22677     DRD->setInvalidDecl();
22678   }
22679 }
22680 
22681 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
22682     Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
22683   for (Decl *D : DeclReductions.get()) {
22684     if (IsValid) {
22685       if (S)
22686         PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
22687                           /*AddToContext=*/false);
22688     } else {
22689       D->setInvalidDecl();
22690     }
22691   }
22692   return DeclReductions;
22693 }
22694 
22695 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) {
22696   TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
22697   QualType T = TInfo->getType();
22698   if (D.isInvalidType())
22699     return true;
22700 
22701   if (getLangOpts().CPlusPlus) {
22702     // Check that there are no default arguments (C++ only).
22703     CheckExtraCXXDefaultArguments(D);
22704   }
22705 
22706   return CreateParsedType(T, TInfo);
22707 }
22708 
22709 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
22710                                             TypeResult ParsedType) {
22711   assert(ParsedType.isUsable() && "Expect usable parsed mapper type");
22712 
22713   QualType MapperType = GetTypeFromParser(ParsedType.get());
22714   assert(!MapperType.isNull() && "Expect valid mapper type");
22715 
22716   // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
22717   //  The type must be of struct, union or class type in C and C++
22718   if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
22719     Diag(TyLoc, diag::err_omp_mapper_wrong_type);
22720     return QualType();
22721   }
22722   return MapperType;
22723 }
22724 
22725 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective(
22726     Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
22727     SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
22728     Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) {
22729   LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
22730                       forRedeclarationInCurContext());
22731   // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
22732   //  A mapper-identifier may not be redeclared in the current scope for the
22733   //  same type or for a type that is compatible according to the base language
22734   //  rules.
22735   llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
22736   OMPDeclareMapperDecl *PrevDMD = nullptr;
22737   bool InCompoundScope = true;
22738   if (S != nullptr) {
22739     // Find previous declaration with the same name not referenced in other
22740     // declarations.
22741     FunctionScopeInfo *ParentFn = getEnclosingFunction();
22742     InCompoundScope =
22743         (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
22744     LookupName(Lookup, S);
22745     FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
22746                          /*AllowInlineNamespace=*/false);
22747     llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
22748     LookupResult::Filter Filter = Lookup.makeFilter();
22749     while (Filter.hasNext()) {
22750       auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
22751       if (InCompoundScope) {
22752         auto I = UsedAsPrevious.find(PrevDecl);
22753         if (I == UsedAsPrevious.end())
22754           UsedAsPrevious[PrevDecl] = false;
22755         if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
22756           UsedAsPrevious[D] = true;
22757       }
22758       PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
22759           PrevDecl->getLocation();
22760     }
22761     Filter.done();
22762     if (InCompoundScope) {
22763       for (const auto &PrevData : UsedAsPrevious) {
22764         if (!PrevData.second) {
22765           PrevDMD = PrevData.first;
22766           break;
22767         }
22768       }
22769     }
22770   } else if (PrevDeclInScope) {
22771     auto *PrevDMDInScope = PrevDMD =
22772         cast<OMPDeclareMapperDecl>(PrevDeclInScope);
22773     do {
22774       PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
22775           PrevDMDInScope->getLocation();
22776       PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
22777     } while (PrevDMDInScope != nullptr);
22778   }
22779   const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
22780   bool Invalid = false;
22781   if (I != PreviousRedeclTypes.end()) {
22782     Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
22783         << MapperType << Name;
22784     Diag(I->second, diag::note_previous_definition);
22785     Invalid = true;
22786   }
22787   // Build expressions for implicit maps of data members with 'default'
22788   // mappers.
22789   SmallVector<OMPClause *, 4> ClausesWithImplicit(Clauses.begin(),
22790                                                   Clauses.end());
22791   if (LangOpts.OpenMP >= 50)
22792     processImplicitMapsWithDefaultMappers(*this, DSAStack, ClausesWithImplicit);
22793   auto *DMD =
22794       OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, MapperType, VN,
22795                                    ClausesWithImplicit, PrevDMD);
22796   if (S)
22797     PushOnScopeChains(DMD, S);
22798   else
22799     DC->addDecl(DMD);
22800   DMD->setAccess(AS);
22801   if (Invalid)
22802     DMD->setInvalidDecl();
22803 
22804   auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl();
22805   VD->setDeclContext(DMD);
22806   VD->setLexicalDeclContext(DMD);
22807   DMD->addDecl(VD);
22808   DMD->setMapperVarRef(MapperVarRef);
22809 
22810   return DeclGroupPtrTy::make(DeclGroupRef(DMD));
22811 }
22812 
22813 ExprResult
22814 Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType,
22815                                                SourceLocation StartLoc,
22816                                                DeclarationName VN) {
22817   TypeSourceInfo *TInfo =
22818       Context.getTrivialTypeSourceInfo(MapperType, StartLoc);
22819   auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(),
22820                              StartLoc, StartLoc, VN.getAsIdentifierInfo(),
22821                              MapperType, TInfo, SC_None);
22822   if (S)
22823     PushOnScopeChains(VD, S, /*AddToContext=*/false);
22824   Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
22825   DSAStack->addDeclareMapperVarRef(E);
22826   return E;
22827 }
22828 
22829 void Sema::ActOnOpenMPIteratorVarDecl(VarDecl *VD) {
22830   if (DSAStack->getDeclareMapperVarRef())
22831     DSAStack->addIteratorVarDecl(VD);
22832 }
22833 
22834 bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const {
22835   assert(LangOpts.OpenMP && "Expected OpenMP mode.");
22836   const Expr *Ref = DSAStack->getDeclareMapperVarRef();
22837   if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref)) {
22838     if (VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl())
22839       return true;
22840     if (VD->isUsableInConstantExpressions(Context))
22841       return true;
22842     if (LangOpts.OpenMP >= 52 && DSAStack->isIteratorVarDecl(VD))
22843       return true;
22844     return false;
22845   }
22846   return true;
22847 }
22848 
22849 const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const {
22850   assert(LangOpts.OpenMP && "Expected OpenMP mode.");
22851   return cast<DeclRefExpr>(DSAStack->getDeclareMapperVarRef())->getDecl();
22852 }
22853 
22854 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
22855                                            SourceLocation StartLoc,
22856                                            SourceLocation LParenLoc,
22857                                            SourceLocation EndLoc) {
22858   Expr *ValExpr = NumTeams;
22859   Stmt *HelperValStmt = nullptr;
22860 
22861   // OpenMP [teams Constrcut, Restrictions]
22862   // The num_teams expression must evaluate to a positive integer value.
22863   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
22864                                  /*StrictlyPositive=*/true))
22865     return nullptr;
22866 
22867   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
22868   OpenMPDirectiveKind CaptureRegion =
22869       getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP);
22870   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
22871     ValExpr = MakeFullExpr(ValExpr).get();
22872     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
22873     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
22874     HelperValStmt = buildPreInits(Context, Captures);
22875   }
22876 
22877   return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
22878                                          StartLoc, LParenLoc, EndLoc);
22879 }
22880 
22881 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
22882                                               SourceLocation StartLoc,
22883                                               SourceLocation LParenLoc,
22884                                               SourceLocation EndLoc) {
22885   Expr *ValExpr = ThreadLimit;
22886   Stmt *HelperValStmt = nullptr;
22887 
22888   // OpenMP [teams Constrcut, Restrictions]
22889   // The thread_limit expression must evaluate to a positive integer value.
22890   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
22891                                  /*StrictlyPositive=*/true))
22892     return nullptr;
22893 
22894   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
22895   OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
22896       DKind, OMPC_thread_limit, LangOpts.OpenMP);
22897   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
22898     ValExpr = MakeFullExpr(ValExpr).get();
22899     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
22900     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
22901     HelperValStmt = buildPreInits(Context, Captures);
22902   }
22903 
22904   return new (Context) OMPThreadLimitClause(
22905       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
22906 }
22907 
22908 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
22909                                            SourceLocation StartLoc,
22910                                            SourceLocation LParenLoc,
22911                                            SourceLocation EndLoc) {
22912   Expr *ValExpr = Priority;
22913   Stmt *HelperValStmt = nullptr;
22914   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
22915 
22916   // OpenMP [2.9.1, task Constrcut]
22917   // The priority-value is a non-negative numerical scalar expression.
22918   if (!isNonNegativeIntegerValue(
22919           ValExpr, *this, OMPC_priority,
22920           /*StrictlyPositive=*/false, /*BuildCapture=*/true,
22921           DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
22922     return nullptr;
22923 
22924   return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion,
22925                                          StartLoc, LParenLoc, EndLoc);
22926 }
22927 
22928 OMPClause *Sema::ActOnOpenMPGrainsizeClause(
22929     OpenMPGrainsizeClauseModifier Modifier, Expr *Grainsize,
22930     SourceLocation StartLoc, SourceLocation LParenLoc,
22931     SourceLocation ModifierLoc, SourceLocation EndLoc) {
22932   assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 51) &&
22933          "Unexpected grainsize modifier in OpenMP < 51.");
22934 
22935   if (ModifierLoc.isValid() && Modifier == OMPC_GRAINSIZE_unknown) {
22936     std::string Values = getListOfPossibleValues(OMPC_grainsize, /*First=*/0,
22937                                                  OMPC_GRAINSIZE_unknown);
22938     Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
22939         << Values << getOpenMPClauseName(OMPC_grainsize);
22940     return nullptr;
22941   }
22942 
22943   Expr *ValExpr = Grainsize;
22944   Stmt *HelperValStmt = nullptr;
22945   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
22946 
22947   // OpenMP [2.9.2, taskloop Constrcut]
22948   // The parameter of the grainsize clause must be a positive integer
22949   // expression.
22950   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize,
22951                                  /*StrictlyPositive=*/true,
22952                                  /*BuildCapture=*/true,
22953                                  DSAStack->getCurrentDirective(),
22954                                  &CaptureRegion, &HelperValStmt))
22955     return nullptr;
22956 
22957   return new (Context)
22958       OMPGrainsizeClause(Modifier, ValExpr, HelperValStmt, CaptureRegion,
22959                          StartLoc, LParenLoc, ModifierLoc, EndLoc);
22960 }
22961 
22962 OMPClause *Sema::ActOnOpenMPNumTasksClause(
22963     OpenMPNumTasksClauseModifier Modifier, Expr *NumTasks,
22964     SourceLocation StartLoc, SourceLocation LParenLoc,
22965     SourceLocation ModifierLoc, SourceLocation EndLoc) {
22966   assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 51) &&
22967          "Unexpected num_tasks modifier in OpenMP < 51.");
22968 
22969   if (ModifierLoc.isValid() && Modifier == OMPC_NUMTASKS_unknown) {
22970     std::string Values = getListOfPossibleValues(OMPC_num_tasks, /*First=*/0,
22971                                                  OMPC_NUMTASKS_unknown);
22972     Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
22973         << Values << getOpenMPClauseName(OMPC_num_tasks);
22974     return nullptr;
22975   }
22976 
22977   Expr *ValExpr = NumTasks;
22978   Stmt *HelperValStmt = nullptr;
22979   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
22980 
22981   // OpenMP [2.9.2, taskloop Constrcut]
22982   // The parameter of the num_tasks clause must be a positive integer
22983   // expression.
22984   if (!isNonNegativeIntegerValue(
22985           ValExpr, *this, OMPC_num_tasks,
22986           /*StrictlyPositive=*/true, /*BuildCapture=*/true,
22987           DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
22988     return nullptr;
22989 
22990   return new (Context)
22991       OMPNumTasksClause(Modifier, ValExpr, HelperValStmt, CaptureRegion,
22992                         StartLoc, LParenLoc, ModifierLoc, EndLoc);
22993 }
22994 
22995 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
22996                                        SourceLocation LParenLoc,
22997                                        SourceLocation EndLoc) {
22998   // OpenMP [2.13.2, critical construct, Description]
22999   // ... where hint-expression is an integer constant expression that evaluates
23000   // to a valid lock hint.
23001   ExprResult HintExpr =
23002       VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint, false);
23003   if (HintExpr.isInvalid())
23004     return nullptr;
23005   return new (Context)
23006       OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
23007 }
23008 
23009 /// Tries to find omp_event_handle_t type.
23010 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc,
23011                                 DSAStackTy *Stack) {
23012   QualType OMPEventHandleT = Stack->getOMPEventHandleT();
23013   if (!OMPEventHandleT.isNull())
23014     return true;
23015   IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t");
23016   ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
23017   if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
23018     S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t";
23019     return false;
23020   }
23021   Stack->setOMPEventHandleT(PT.get());
23022   return true;
23023 }
23024 
23025 OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc,
23026                                          SourceLocation LParenLoc,
23027                                          SourceLocation EndLoc) {
23028   if (!Evt->isValueDependent() && !Evt->isTypeDependent() &&
23029       !Evt->isInstantiationDependent() &&
23030       !Evt->containsUnexpandedParameterPack()) {
23031     if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack))
23032       return nullptr;
23033     // OpenMP 5.0, 2.10.1 task Construct.
23034     // event-handle is a variable of the omp_event_handle_t type.
23035     auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts());
23036     if (!Ref) {
23037       Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
23038           << "omp_event_handle_t" << 0 << Evt->getSourceRange();
23039       return nullptr;
23040     }
23041     auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl());
23042     if (!VD) {
23043       Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
23044           << "omp_event_handle_t" << 0 << Evt->getSourceRange();
23045       return nullptr;
23046     }
23047     if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(),
23048                                         VD->getType()) ||
23049         VD->getType().isConstant(Context)) {
23050       Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
23051           << "omp_event_handle_t" << 1 << VD->getType()
23052           << Evt->getSourceRange();
23053       return nullptr;
23054     }
23055     // OpenMP 5.0, 2.10.1 task Construct
23056     // [detach clause]... The event-handle will be considered as if it was
23057     // specified on a firstprivate clause.
23058     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false);
23059     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
23060         DVar.RefExpr) {
23061       Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa)
23062           << getOpenMPClauseName(DVar.CKind)
23063           << getOpenMPClauseName(OMPC_firstprivate);
23064       reportOriginalDsa(*this, DSAStack, VD, DVar);
23065       return nullptr;
23066     }
23067   }
23068 
23069   return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc);
23070 }
23071 
23072 OMPClause *Sema::ActOnOpenMPDistScheduleClause(
23073     OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
23074     SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
23075     SourceLocation EndLoc) {
23076   if (Kind == OMPC_DIST_SCHEDULE_unknown) {
23077     std::string Values;
23078     Values += "'";
23079     Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
23080     Values += "'";
23081     Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23082         << Values << getOpenMPClauseName(OMPC_dist_schedule);
23083     return nullptr;
23084   }
23085   Expr *ValExpr = ChunkSize;
23086   Stmt *HelperValStmt = nullptr;
23087   if (ChunkSize) {
23088     if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
23089         !ChunkSize->isInstantiationDependent() &&
23090         !ChunkSize->containsUnexpandedParameterPack()) {
23091       SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
23092       ExprResult Val =
23093           PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
23094       if (Val.isInvalid())
23095         return nullptr;
23096 
23097       ValExpr = Val.get();
23098 
23099       // OpenMP [2.7.1, Restrictions]
23100       //  chunk_size must be a loop invariant integer expression with a positive
23101       //  value.
23102       if (std::optional<llvm::APSInt> Result =
23103               ValExpr->getIntegerConstantExpr(Context)) {
23104         if (Result->isSigned() && !Result->isStrictlyPositive()) {
23105           Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
23106               << "dist_schedule" << ChunkSize->getSourceRange();
23107           return nullptr;
23108         }
23109       } else if (getOpenMPCaptureRegionForClause(
23110                      DSAStack->getCurrentDirective(), OMPC_dist_schedule,
23111                      LangOpts.OpenMP) != OMPD_unknown &&
23112                  !CurContext->isDependentContext()) {
23113         ValExpr = MakeFullExpr(ValExpr).get();
23114         llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
23115         ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
23116         HelperValStmt = buildPreInits(Context, Captures);
23117       }
23118     }
23119   }
23120 
23121   return new (Context)
23122       OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
23123                             Kind, ValExpr, HelperValStmt);
23124 }
23125 
23126 OMPClause *Sema::ActOnOpenMPDefaultmapClause(
23127     OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
23128     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
23129     SourceLocation KindLoc, SourceLocation EndLoc) {
23130   if (getLangOpts().OpenMP < 50) {
23131     if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
23132         Kind != OMPC_DEFAULTMAP_scalar) {
23133       std::string Value;
23134       SourceLocation Loc;
23135       Value += "'";
23136       if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
23137         Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
23138                                                OMPC_DEFAULTMAP_MODIFIER_tofrom);
23139         Loc = MLoc;
23140       } else {
23141         Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
23142                                                OMPC_DEFAULTMAP_scalar);
23143         Loc = KindLoc;
23144       }
23145       Value += "'";
23146       Diag(Loc, diag::err_omp_unexpected_clause_value)
23147           << Value << getOpenMPClauseName(OMPC_defaultmap);
23148       return nullptr;
23149     }
23150   } else {
23151     bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown);
23152     bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) ||
23153                             (LangOpts.OpenMP >= 50 && KindLoc.isInvalid());
23154     if (!isDefaultmapKind || !isDefaultmapModifier) {
23155       StringRef KindValue = "'scalar', 'aggregate', 'pointer'";
23156       if (LangOpts.OpenMP == 50) {
23157         StringRef ModifierValue = "'alloc', 'from', 'to', 'tofrom', "
23158                                   "'firstprivate', 'none', 'default'";
23159         if (!isDefaultmapKind && isDefaultmapModifier) {
23160           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23161               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
23162         } else if (isDefaultmapKind && !isDefaultmapModifier) {
23163           Diag(MLoc, diag::err_omp_unexpected_clause_value)
23164               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
23165         } else {
23166           Diag(MLoc, diag::err_omp_unexpected_clause_value)
23167               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
23168           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23169               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
23170         }
23171       } else {
23172         StringRef ModifierValue =
23173             "'alloc', 'from', 'to', 'tofrom', "
23174             "'firstprivate', 'none', 'default', 'present'";
23175         if (!isDefaultmapKind && isDefaultmapModifier) {
23176           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23177               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
23178         } else if (isDefaultmapKind && !isDefaultmapModifier) {
23179           Diag(MLoc, diag::err_omp_unexpected_clause_value)
23180               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
23181         } else {
23182           Diag(MLoc, diag::err_omp_unexpected_clause_value)
23183               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
23184           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
23185               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
23186         }
23187       }
23188       return nullptr;
23189     }
23190 
23191     // OpenMP [5.0, 2.12.5, Restrictions, p. 174]
23192     //  At most one defaultmap clause for each category can appear on the
23193     //  directive.
23194     if (DSAStack->checkDefaultmapCategory(Kind)) {
23195       Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
23196       return nullptr;
23197     }
23198   }
23199   if (Kind == OMPC_DEFAULTMAP_unknown) {
23200     // Variable category is not specified - mark all categories.
23201     DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc);
23202     DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc);
23203     DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc);
23204   } else {
23205     DSAStack->setDefaultDMAAttr(M, Kind, StartLoc);
23206   }
23207 
23208   return new (Context)
23209       OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
23210 }
23211 
23212 bool Sema::ActOnStartOpenMPDeclareTargetContext(
23213     DeclareTargetContextInfo &DTCI) {
23214   DeclContext *CurLexicalContext = getCurLexicalContext();
23215   if (!CurLexicalContext->isFileContext() &&
23216       !CurLexicalContext->isExternCContext() &&
23217       !CurLexicalContext->isExternCXXContext() &&
23218       !isa<CXXRecordDecl>(CurLexicalContext) &&
23219       !isa<ClassTemplateDecl>(CurLexicalContext) &&
23220       !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
23221       !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
23222     Diag(DTCI.Loc, diag::err_omp_region_not_file_context);
23223     return false;
23224   }
23225 
23226   // Report affected OpenMP target offloading behavior when in HIP lang-mode.
23227   if (getLangOpts().HIP)
23228     Diag(DTCI.Loc, diag::warn_hip_omp_target_directives);
23229 
23230   DeclareTargetNesting.push_back(DTCI);
23231   return true;
23232 }
23233 
23234 const Sema::DeclareTargetContextInfo
23235 Sema::ActOnOpenMPEndDeclareTargetDirective() {
23236   assert(!DeclareTargetNesting.empty() &&
23237          "check isInOpenMPDeclareTargetContext() first!");
23238   return DeclareTargetNesting.pop_back_val();
23239 }
23240 
23241 void Sema::ActOnFinishedOpenMPDeclareTargetContext(
23242     DeclareTargetContextInfo &DTCI) {
23243   for (auto &It : DTCI.ExplicitlyMapped)
23244     ActOnOpenMPDeclareTargetName(It.first, It.second.Loc, It.second.MT, DTCI);
23245 }
23246 
23247 void Sema::DiagnoseUnterminatedOpenMPDeclareTarget() {
23248   if (DeclareTargetNesting.empty())
23249     return;
23250   DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back();
23251   Diag(DTCI.Loc, diag::warn_omp_unterminated_declare_target)
23252       << getOpenMPDirectiveName(DTCI.Kind);
23253 }
23254 
23255 NamedDecl *Sema::lookupOpenMPDeclareTargetName(Scope *CurScope,
23256                                                CXXScopeSpec &ScopeSpec,
23257                                                const DeclarationNameInfo &Id) {
23258   LookupResult Lookup(*this, Id, LookupOrdinaryName);
23259   LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
23260 
23261   if (Lookup.isAmbiguous())
23262     return nullptr;
23263   Lookup.suppressDiagnostics();
23264 
23265   if (!Lookup.isSingleResult()) {
23266     VarOrFuncDeclFilterCCC CCC(*this);
23267     if (TypoCorrection Corrected =
23268             CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
23269                         CTK_ErrorRecovery)) {
23270       diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
23271                                   << Id.getName());
23272       checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
23273       return nullptr;
23274     }
23275 
23276     Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
23277     return nullptr;
23278   }
23279 
23280   NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
23281   if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
23282       !isa<FunctionTemplateDecl>(ND)) {
23283     Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
23284     return nullptr;
23285   }
23286   return ND;
23287 }
23288 
23289 void Sema::ActOnOpenMPDeclareTargetName(NamedDecl *ND, SourceLocation Loc,
23290                                         OMPDeclareTargetDeclAttr::MapTypeTy MT,
23291                                         DeclareTargetContextInfo &DTCI) {
23292   assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
23293           isa<FunctionTemplateDecl>(ND)) &&
23294          "Expected variable, function or function template.");
23295 
23296   // Diagnose marking after use as it may lead to incorrect diagnosis and
23297   // codegen.
23298   if (LangOpts.OpenMP >= 50 &&
23299       (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced()))
23300     Diag(Loc, diag::warn_omp_declare_target_after_first_use);
23301 
23302   // Report affected OpenMP target offloading behavior when in HIP lang-mode.
23303   if (getLangOpts().HIP)
23304     Diag(Loc, diag::warn_hip_omp_target_directives);
23305 
23306   // Explicit declare target lists have precedence.
23307   const unsigned Level = -1;
23308 
23309   auto *VD = cast<ValueDecl>(ND);
23310   std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
23311       OMPDeclareTargetDeclAttr::getActiveAttr(VD);
23312   if (ActiveAttr && (*ActiveAttr)->getDevType() != DTCI.DT &&
23313       (*ActiveAttr)->getLevel() == Level) {
23314     Diag(Loc, diag::err_omp_device_type_mismatch)
23315         << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DTCI.DT)
23316         << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(
23317                (*ActiveAttr)->getDevType());
23318     return;
23319   }
23320   if (ActiveAttr && (*ActiveAttr)->getMapType() != MT &&
23321       (*ActiveAttr)->getLevel() == Level) {
23322     Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
23323     return;
23324   }
23325 
23326   if (ActiveAttr && (*ActiveAttr)->getLevel() == Level)
23327     return;
23328 
23329   Expr *IndirectE = nullptr;
23330   bool IsIndirect = false;
23331   if (DTCI.Indirect) {
23332     IndirectE = *DTCI.Indirect;
23333     if (!IndirectE)
23334       IsIndirect = true;
23335   }
23336   auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
23337       Context, MT, DTCI.DT, IndirectE, IsIndirect, Level,
23338       SourceRange(Loc, Loc));
23339   ND->addAttr(A);
23340   if (ASTMutationListener *ML = Context.getASTMutationListener())
23341     ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
23342   checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc);
23343   if (auto *VD = dyn_cast<VarDecl>(ND);
23344       LangOpts.OpenMP && VD && VD->hasAttr<OMPDeclareTargetDeclAttr>() &&
23345       VD->hasGlobalStorage())
23346     ActOnOpenMPDeclareTargetInitializer(ND);
23347 }
23348 
23349 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
23350                                      Sema &SemaRef, Decl *D) {
23351   if (!D || !isa<VarDecl>(D))
23352     return;
23353   auto *VD = cast<VarDecl>(D);
23354   std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
23355       OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
23356   if (SemaRef.LangOpts.OpenMP >= 50 &&
23357       (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) ||
23358        SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) &&
23359       VD->hasGlobalStorage()) {
23360     if (!MapTy || (*MapTy != OMPDeclareTargetDeclAttr::MT_To &&
23361                    *MapTy != OMPDeclareTargetDeclAttr::MT_Enter)) {
23362       // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
23363       // If a lambda declaration and definition appears between a
23364       // declare target directive and the matching end declare target
23365       // directive, all variables that are captured by the lambda
23366       // expression must also appear in a to clause.
23367       SemaRef.Diag(VD->getLocation(),
23368                    diag::err_omp_lambda_capture_in_declare_target_not_to);
23369       SemaRef.Diag(SL, diag::note_var_explicitly_captured_here)
23370           << VD << 0 << SR;
23371       return;
23372     }
23373   }
23374   if (MapTy)
23375     return;
23376   SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
23377   SemaRef.Diag(SL, diag::note_used_here) << SR;
23378 }
23379 
23380 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
23381                                    Sema &SemaRef, DSAStackTy *Stack,
23382                                    ValueDecl *VD) {
23383   return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
23384          checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
23385                            /*FullCheck=*/false);
23386 }
23387 
23388 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
23389                                             SourceLocation IdLoc) {
23390   if (!D || D->isInvalidDecl())
23391     return;
23392   SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
23393   SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
23394   if (auto *VD = dyn_cast<VarDecl>(D)) {
23395     // Only global variables can be marked as declare target.
23396     if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
23397         !VD->isStaticDataMember())
23398       return;
23399     // 2.10.6: threadprivate variable cannot appear in a declare target
23400     // directive.
23401     if (DSAStack->isThreadPrivate(VD)) {
23402       Diag(SL, diag::err_omp_threadprivate_in_target);
23403       reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false));
23404       return;
23405     }
23406   }
23407   if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
23408     D = FTD->getTemplatedDecl();
23409   if (auto *FD = dyn_cast<FunctionDecl>(D)) {
23410     std::optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
23411         OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
23412     if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
23413       Diag(IdLoc, diag::err_omp_function_in_link_clause);
23414       Diag(FD->getLocation(), diag::note_defined_here) << FD;
23415       return;
23416     }
23417   }
23418   if (auto *VD = dyn_cast<ValueDecl>(D)) {
23419     // Problem if any with var declared with incomplete type will be reported
23420     // as normal, so no need to check it here.
23421     if ((E || !VD->getType()->isIncompleteType()) &&
23422         !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD))
23423       return;
23424     if (!E && isInOpenMPDeclareTargetContext()) {
23425       // Checking declaration inside declare target region.
23426       if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
23427           isa<FunctionTemplateDecl>(D)) {
23428         std::optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
23429             OMPDeclareTargetDeclAttr::getActiveAttr(VD);
23430         unsigned Level = DeclareTargetNesting.size();
23431         if (ActiveAttr && (*ActiveAttr)->getLevel() >= Level)
23432           return;
23433         DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back();
23434         Expr *IndirectE = nullptr;
23435         bool IsIndirect = false;
23436         if (DTCI.Indirect) {
23437           IndirectE = *DTCI.Indirect;
23438           if (!IndirectE)
23439             IsIndirect = true;
23440         }
23441         auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
23442             Context,
23443             getLangOpts().OpenMP >= 52 ? OMPDeclareTargetDeclAttr::MT_Enter
23444                                        : OMPDeclareTargetDeclAttr::MT_To,
23445             DTCI.DT, IndirectE, IsIndirect, Level,
23446             SourceRange(DTCI.Loc, DTCI.Loc));
23447         D->addAttr(A);
23448         if (ASTMutationListener *ML = Context.getASTMutationListener())
23449           ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
23450       }
23451       return;
23452     }
23453   }
23454   if (!E)
23455     return;
23456   checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
23457 }
23458 
23459 /// This class visits every VarDecl that the initializer references and adds
23460 /// OMPDeclareTargetDeclAttr to each of them.
23461 class GlobalDeclRefChecker final
23462     : public StmtVisitor<GlobalDeclRefChecker> {
23463   SmallVector<VarDecl *> DeclVector;
23464   Attr *A;
23465 
23466 public:
23467   /// A StmtVisitor class function that visits all DeclRefExpr and adds
23468   /// OMPDeclareTargetDeclAttr to them.
23469   void VisitDeclRefExpr(DeclRefExpr *Node) {
23470     if (auto *VD = dyn_cast<VarDecl>(Node->getDecl())) {
23471       VD->addAttr(A);
23472       DeclVector.push_back(VD);
23473     }
23474   }
23475   /// A function that iterates across each of the Expr's children.
23476   void VisitExpr(Expr *Ex) {
23477     for (auto *Child : Ex->children()) {
23478       Visit(Child);
23479     }
23480   }
23481   /// A function that keeps a record of all the Decls that are variables, has
23482   /// OMPDeclareTargetDeclAttr, and has global storage in the DeclVector. Pop
23483   /// each Decl one at a time and use the inherited 'visit' functions to look
23484   /// for DeclRefExpr.
23485   void declareTargetInitializer(Decl *TD) {
23486     A = TD->getAttr<OMPDeclareTargetDeclAttr>();
23487     DeclVector.push_back(cast<VarDecl>(TD));
23488     while (!DeclVector.empty()) {
23489       VarDecl *TargetVarDecl = DeclVector.pop_back_val();
23490       if (TargetVarDecl->hasAttr<OMPDeclareTargetDeclAttr>() &&
23491           TargetVarDecl->hasInit() && TargetVarDecl->hasGlobalStorage()) {
23492         if (Expr *Ex = TargetVarDecl->getInit())
23493           Visit(Ex);
23494       }
23495     }
23496   }
23497 };
23498 
23499 /// Adding OMPDeclareTargetDeclAttr to variables with static storage
23500 /// duration that are referenced in the initializer expression list of
23501 /// variables with static storage duration in declare target directive.
23502 void Sema::ActOnOpenMPDeclareTargetInitializer(Decl *TargetDecl) {
23503   GlobalDeclRefChecker Checker;
23504   if (isa<VarDecl>(TargetDecl))
23505     Checker.declareTargetInitializer(TargetDecl);
23506 }
23507 
23508 OMPClause *Sema::ActOnOpenMPToClause(
23509     ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
23510     ArrayRef<SourceLocation> MotionModifiersLoc,
23511     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
23512     SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
23513     const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
23514   OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
23515                                           OMPC_MOTION_MODIFIER_unknown};
23516   SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
23517 
23518   // Process motion-modifiers, flag errors for duplicate modifiers.
23519   unsigned Count = 0;
23520   for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
23521     if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
23522         llvm::is_contained(Modifiers, MotionModifiers[I])) {
23523       Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
23524       continue;
23525     }
23526     assert(Count < NumberOfOMPMotionModifiers &&
23527            "Modifiers exceed the allowed number of motion modifiers");
23528     Modifiers[Count] = MotionModifiers[I];
23529     ModifiersLoc[Count] = MotionModifiersLoc[I];
23530     ++Count;
23531   }
23532 
23533   MappableVarListInfo MVLI(VarList);
23534   checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc,
23535                               MapperIdScopeSpec, MapperId, UnresolvedMappers);
23536   if (MVLI.ProcessedVarList.empty())
23537     return nullptr;
23538 
23539   return OMPToClause::Create(
23540       Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
23541       MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
23542       MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
23543 }
23544 
23545 OMPClause *Sema::ActOnOpenMPFromClause(
23546     ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
23547     ArrayRef<SourceLocation> MotionModifiersLoc,
23548     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
23549     SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
23550     const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
23551   OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
23552                                           OMPC_MOTION_MODIFIER_unknown};
23553   SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
23554 
23555   // Process motion-modifiers, flag errors for duplicate modifiers.
23556   unsigned Count = 0;
23557   for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
23558     if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
23559         llvm::is_contained(Modifiers, MotionModifiers[I])) {
23560       Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
23561       continue;
23562     }
23563     assert(Count < NumberOfOMPMotionModifiers &&
23564            "Modifiers exceed the allowed number of motion modifiers");
23565     Modifiers[Count] = MotionModifiers[I];
23566     ModifiersLoc[Count] = MotionModifiersLoc[I];
23567     ++Count;
23568   }
23569 
23570   MappableVarListInfo MVLI(VarList);
23571   checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc,
23572                               MapperIdScopeSpec, MapperId, UnresolvedMappers);
23573   if (MVLI.ProcessedVarList.empty())
23574     return nullptr;
23575 
23576   return OMPFromClause::Create(
23577       Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
23578       MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
23579       MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
23580 }
23581 
23582 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
23583                                                const OMPVarListLocTy &Locs) {
23584   MappableVarListInfo MVLI(VarList);
23585   SmallVector<Expr *, 8> PrivateCopies;
23586   SmallVector<Expr *, 8> Inits;
23587 
23588   for (Expr *RefExpr : VarList) {
23589     assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
23590     SourceLocation ELoc;
23591     SourceRange ERange;
23592     Expr *SimpleRefExpr = RefExpr;
23593     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
23594     if (Res.second) {
23595       // It will be analyzed later.
23596       MVLI.ProcessedVarList.push_back(RefExpr);
23597       PrivateCopies.push_back(nullptr);
23598       Inits.push_back(nullptr);
23599     }
23600     ValueDecl *D = Res.first;
23601     if (!D)
23602       continue;
23603 
23604     QualType Type = D->getType();
23605     Type = Type.getNonReferenceType().getUnqualifiedType();
23606 
23607     auto *VD = dyn_cast<VarDecl>(D);
23608 
23609     // Item should be a pointer or reference to pointer.
23610     if (!Type->isPointerType()) {
23611       Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
23612           << 0 << RefExpr->getSourceRange();
23613       continue;
23614     }
23615 
23616     // Build the private variable and the expression that refers to it.
23617     auto VDPrivate =
23618         buildVarDecl(*this, ELoc, Type, D->getName(),
23619                      D->hasAttrs() ? &D->getAttrs() : nullptr,
23620                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
23621     if (VDPrivate->isInvalidDecl())
23622       continue;
23623 
23624     CurContext->addDecl(VDPrivate);
23625     DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
23626         *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
23627 
23628     // Add temporary variable to initialize the private copy of the pointer.
23629     VarDecl *VDInit =
23630         buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
23631     DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
23632         *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
23633     AddInitializerToDecl(VDPrivate,
23634                          DefaultLvalueConversion(VDInitRefExpr).get(),
23635                          /*DirectInit=*/false);
23636 
23637     // If required, build a capture to implement the privatization initialized
23638     // with the current list item value.
23639     DeclRefExpr *Ref = nullptr;
23640     if (!VD)
23641       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
23642     MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
23643     PrivateCopies.push_back(VDPrivateRefExpr);
23644     Inits.push_back(VDInitRefExpr);
23645 
23646     // We need to add a data sharing attribute for this variable to make sure it
23647     // is correctly captured. A variable that shows up in a use_device_ptr has
23648     // similar properties of a first private variable.
23649     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
23650 
23651     // Create a mappable component for the list item. List items in this clause
23652     // only need a component.
23653     MVLI.VarBaseDeclarations.push_back(D);
23654     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
23655     MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D,
23656                                            /*IsNonContiguous=*/false);
23657   }
23658 
23659   if (MVLI.ProcessedVarList.empty())
23660     return nullptr;
23661 
23662   return OMPUseDevicePtrClause::Create(
23663       Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
23664       MVLI.VarBaseDeclarations, MVLI.VarComponents);
23665 }
23666 
23667 OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
23668                                                 const OMPVarListLocTy &Locs) {
23669   MappableVarListInfo MVLI(VarList);
23670 
23671   for (Expr *RefExpr : VarList) {
23672     assert(RefExpr && "NULL expr in OpenMP use_device_addr clause.");
23673     SourceLocation ELoc;
23674     SourceRange ERange;
23675     Expr *SimpleRefExpr = RefExpr;
23676     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
23677                               /*AllowArraySection=*/true);
23678     if (Res.second) {
23679       // It will be analyzed later.
23680       MVLI.ProcessedVarList.push_back(RefExpr);
23681     }
23682     ValueDecl *D = Res.first;
23683     if (!D)
23684       continue;
23685     auto *VD = dyn_cast<VarDecl>(D);
23686 
23687     // If required, build a capture to implement the privatization initialized
23688     // with the current list item value.
23689     DeclRefExpr *Ref = nullptr;
23690     if (!VD)
23691       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
23692     MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
23693 
23694     // We need to add a data sharing attribute for this variable to make sure it
23695     // is correctly captured. A variable that shows up in a use_device_addr has
23696     // similar properties of a first private variable.
23697     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
23698 
23699     // Create a mappable component for the list item. List items in this clause
23700     // only need a component.
23701     MVLI.VarBaseDeclarations.push_back(D);
23702     MVLI.VarComponents.emplace_back();
23703     Expr *Component = SimpleRefExpr;
23704     if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
23705                isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
23706       Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
23707     MVLI.VarComponents.back().emplace_back(Component, D,
23708                                            /*IsNonContiguous=*/false);
23709   }
23710 
23711   if (MVLI.ProcessedVarList.empty())
23712     return nullptr;
23713 
23714   return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
23715                                         MVLI.VarBaseDeclarations,
23716                                         MVLI.VarComponents);
23717 }
23718 
23719 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
23720                                               const OMPVarListLocTy &Locs) {
23721   MappableVarListInfo MVLI(VarList);
23722   for (Expr *RefExpr : VarList) {
23723     assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
23724     SourceLocation ELoc;
23725     SourceRange ERange;
23726     Expr *SimpleRefExpr = RefExpr;
23727     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
23728     if (Res.second) {
23729       // It will be analyzed later.
23730       MVLI.ProcessedVarList.push_back(RefExpr);
23731     }
23732     ValueDecl *D = Res.first;
23733     if (!D)
23734       continue;
23735 
23736     QualType Type = D->getType();
23737     // item should be a pointer or array or reference to pointer or array
23738     if (!Type.getNonReferenceType()->isPointerType() &&
23739         !Type.getNonReferenceType()->isArrayType()) {
23740       Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
23741           << 0 << RefExpr->getSourceRange();
23742       continue;
23743     }
23744 
23745     // Check if the declaration in the clause does not show up in any data
23746     // sharing attribute.
23747     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
23748     if (isOpenMPPrivate(DVar.CKind)) {
23749       Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
23750           << getOpenMPClauseName(DVar.CKind)
23751           << getOpenMPClauseName(OMPC_is_device_ptr)
23752           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
23753       reportOriginalDsa(*this, DSAStack, D, DVar);
23754       continue;
23755     }
23756 
23757     const Expr *ConflictExpr;
23758     if (DSAStack->checkMappableExprComponentListsForDecl(
23759             D, /*CurrentRegionOnly=*/true,
23760             [&ConflictExpr](
23761                 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
23762                 OpenMPClauseKind) -> bool {
23763               ConflictExpr = R.front().getAssociatedExpression();
23764               return true;
23765             })) {
23766       Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
23767       Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
23768           << ConflictExpr->getSourceRange();
23769       continue;
23770     }
23771 
23772     // Store the components in the stack so that they can be used to check
23773     // against other clauses later on.
23774     OMPClauseMappableExprCommon::MappableComponent MC(
23775         SimpleRefExpr, D, /*IsNonContiguous=*/false);
23776     DSAStack->addMappableExpressionComponents(
23777         D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
23778 
23779     // Record the expression we've just processed.
23780     MVLI.ProcessedVarList.push_back(SimpleRefExpr);
23781 
23782     // Create a mappable component for the list item. List items in this clause
23783     // only need a component. We use a null declaration to signal fields in
23784     // 'this'.
23785     assert((isa<DeclRefExpr>(SimpleRefExpr) ||
23786             isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
23787            "Unexpected device pointer expression!");
23788     MVLI.VarBaseDeclarations.push_back(
23789         isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
23790     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
23791     MVLI.VarComponents.back().push_back(MC);
23792   }
23793 
23794   if (MVLI.ProcessedVarList.empty())
23795     return nullptr;
23796 
23797   return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
23798                                       MVLI.VarBaseDeclarations,
23799                                       MVLI.VarComponents);
23800 }
23801 
23802 OMPClause *Sema::ActOnOpenMPHasDeviceAddrClause(ArrayRef<Expr *> VarList,
23803                                                 const OMPVarListLocTy &Locs) {
23804   MappableVarListInfo MVLI(VarList);
23805   for (Expr *RefExpr : VarList) {
23806     assert(RefExpr && "NULL expr in OpenMP has_device_addr clause.");
23807     SourceLocation ELoc;
23808     SourceRange ERange;
23809     Expr *SimpleRefExpr = RefExpr;
23810     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
23811                               /*AllowArraySection=*/true);
23812     if (Res.second) {
23813       // It will be analyzed later.
23814       MVLI.ProcessedVarList.push_back(RefExpr);
23815     }
23816     ValueDecl *D = Res.first;
23817     if (!D)
23818       continue;
23819 
23820     // Check if the declaration in the clause does not show up in any data
23821     // sharing attribute.
23822     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
23823     if (isOpenMPPrivate(DVar.CKind)) {
23824       Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
23825           << getOpenMPClauseName(DVar.CKind)
23826           << getOpenMPClauseName(OMPC_has_device_addr)
23827           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
23828       reportOriginalDsa(*this, DSAStack, D, DVar);
23829       continue;
23830     }
23831 
23832     const Expr *ConflictExpr;
23833     if (DSAStack->checkMappableExprComponentListsForDecl(
23834             D, /*CurrentRegionOnly=*/true,
23835             [&ConflictExpr](
23836                 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
23837                 OpenMPClauseKind) -> bool {
23838               ConflictExpr = R.front().getAssociatedExpression();
23839               return true;
23840             })) {
23841       Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
23842       Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
23843           << ConflictExpr->getSourceRange();
23844       continue;
23845     }
23846 
23847     // Store the components in the stack so that they can be used to check
23848     // against other clauses later on.
23849     Expr *Component = SimpleRefExpr;
23850     auto *VD = dyn_cast<VarDecl>(D);
23851     if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
23852                isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
23853       Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
23854     OMPClauseMappableExprCommon::MappableComponent MC(
23855         Component, D, /*IsNonContiguous=*/false);
23856     DSAStack->addMappableExpressionComponents(
23857         D, MC, /*WhereFoundClauseKind=*/OMPC_has_device_addr);
23858 
23859     // Record the expression we've just processed.
23860     if (!VD && !CurContext->isDependentContext()) {
23861       DeclRefExpr *Ref =
23862           buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
23863       assert(Ref && "has_device_addr capture failed");
23864       MVLI.ProcessedVarList.push_back(Ref);
23865     } else
23866       MVLI.ProcessedVarList.push_back(RefExpr->IgnoreParens());
23867 
23868     // Create a mappable component for the list item. List items in this clause
23869     // only need a component. We use a null declaration to signal fields in
23870     // 'this'.
23871     assert((isa<DeclRefExpr>(SimpleRefExpr) ||
23872             isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
23873            "Unexpected device pointer expression!");
23874     MVLI.VarBaseDeclarations.push_back(
23875         isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
23876     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
23877     MVLI.VarComponents.back().push_back(MC);
23878   }
23879 
23880   if (MVLI.ProcessedVarList.empty())
23881     return nullptr;
23882 
23883   return OMPHasDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
23884                                         MVLI.VarBaseDeclarations,
23885                                         MVLI.VarComponents);
23886 }
23887 
23888 OMPClause *Sema::ActOnOpenMPAllocateClause(
23889     Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
23890     SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
23891   if (Allocator) {
23892     // OpenMP [2.11.4 allocate Clause, Description]
23893     // allocator is an expression of omp_allocator_handle_t type.
23894     if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack))
23895       return nullptr;
23896 
23897     ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
23898     if (AllocatorRes.isInvalid())
23899       return nullptr;
23900     AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
23901                                              DSAStack->getOMPAllocatorHandleT(),
23902                                              Sema::AA_Initializing,
23903                                              /*AllowExplicit=*/true);
23904     if (AllocatorRes.isInvalid())
23905       return nullptr;
23906     Allocator = AllocatorRes.get();
23907   } else {
23908     // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
23909     // allocate clauses that appear on a target construct or on constructs in a
23910     // target region must specify an allocator expression unless a requires
23911     // directive with the dynamic_allocators clause is present in the same
23912     // compilation unit.
23913     if (LangOpts.OpenMPIsTargetDevice &&
23914         !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
23915       targetDiag(StartLoc, diag::err_expected_allocator_expression);
23916   }
23917   // Analyze and build list of variables.
23918   SmallVector<Expr *, 8> Vars;
23919   for (Expr *RefExpr : VarList) {
23920     assert(RefExpr && "NULL expr in OpenMP private clause.");
23921     SourceLocation ELoc;
23922     SourceRange ERange;
23923     Expr *SimpleRefExpr = RefExpr;
23924     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
23925     if (Res.second) {
23926       // It will be analyzed later.
23927       Vars.push_back(RefExpr);
23928     }
23929     ValueDecl *D = Res.first;
23930     if (!D)
23931       continue;
23932 
23933     auto *VD = dyn_cast<VarDecl>(D);
23934     DeclRefExpr *Ref = nullptr;
23935     if (!VD && !CurContext->isDependentContext())
23936       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
23937     Vars.push_back((VD || CurContext->isDependentContext())
23938                        ? RefExpr->IgnoreParens()
23939                        : Ref);
23940   }
23941 
23942   if (Vars.empty())
23943     return nullptr;
23944 
23945   if (Allocator)
23946     DSAStack->addInnerAllocatorExpr(Allocator);
23947   return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
23948                                    ColonLoc, EndLoc, Vars);
23949 }
23950 
23951 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
23952                                               SourceLocation StartLoc,
23953                                               SourceLocation LParenLoc,
23954                                               SourceLocation EndLoc) {
23955   SmallVector<Expr *, 8> Vars;
23956   for (Expr *RefExpr : VarList) {
23957     assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
23958     SourceLocation ELoc;
23959     SourceRange ERange;
23960     Expr *SimpleRefExpr = RefExpr;
23961     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
23962     if (Res.second)
23963       // It will be analyzed later.
23964       Vars.push_back(RefExpr);
23965     ValueDecl *D = Res.first;
23966     if (!D)
23967       continue;
23968 
23969     // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions.
23970     // A list-item cannot appear in more than one nontemporal clause.
23971     if (const Expr *PrevRef =
23972             DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) {
23973       Diag(ELoc, diag::err_omp_used_in_clause_twice)
23974           << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
23975       Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
23976           << getOpenMPClauseName(OMPC_nontemporal);
23977       continue;
23978     }
23979 
23980     Vars.push_back(RefExpr);
23981   }
23982 
23983   if (Vars.empty())
23984     return nullptr;
23985 
23986   return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc,
23987                                       Vars);
23988 }
23989 
23990 StmtResult Sema::ActOnOpenMPScopeDirective(ArrayRef<OMPClause *> Clauses,
23991                                            Stmt *AStmt, SourceLocation StartLoc,
23992                                            SourceLocation EndLoc) {
23993   if (!AStmt)
23994     return StmtError();
23995 
23996   setFunctionHasBranchProtectedScope();
23997 
23998   return OMPScopeDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
23999 }
24000 
24001 OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList,
24002                                             SourceLocation StartLoc,
24003                                             SourceLocation LParenLoc,
24004                                             SourceLocation EndLoc) {
24005   SmallVector<Expr *, 8> Vars;
24006   for (Expr *RefExpr : VarList) {
24007     assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
24008     SourceLocation ELoc;
24009     SourceRange ERange;
24010     Expr *SimpleRefExpr = RefExpr;
24011     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
24012                               /*AllowArraySection=*/true);
24013     if (Res.second)
24014       // It will be analyzed later.
24015       Vars.push_back(RefExpr);
24016     ValueDecl *D = Res.first;
24017     if (!D)
24018       continue;
24019 
24020     const DSAStackTy::DSAVarData DVar =
24021         DSAStack->getTopDSA(D, /*FromParent=*/true);
24022     // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
24023     // A list item that appears in the inclusive or exclusive clause must appear
24024     // in a reduction clause with the inscan modifier on the enclosing
24025     // worksharing-loop, worksharing-loop SIMD, or simd construct.
24026     if (DVar.CKind != OMPC_reduction || DVar.Modifier != OMPC_REDUCTION_inscan)
24027       Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
24028           << RefExpr->getSourceRange();
24029 
24030     if (DSAStack->getParentDirective() != OMPD_unknown)
24031       DSAStack->markDeclAsUsedInScanDirective(D);
24032     Vars.push_back(RefExpr);
24033   }
24034 
24035   if (Vars.empty())
24036     return nullptr;
24037 
24038   return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
24039 }
24040 
24041 OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList,
24042                                             SourceLocation StartLoc,
24043                                             SourceLocation LParenLoc,
24044                                             SourceLocation EndLoc) {
24045   SmallVector<Expr *, 8> Vars;
24046   for (Expr *RefExpr : VarList) {
24047     assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
24048     SourceLocation ELoc;
24049     SourceRange ERange;
24050     Expr *SimpleRefExpr = RefExpr;
24051     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
24052                               /*AllowArraySection=*/true);
24053     if (Res.second)
24054       // It will be analyzed later.
24055       Vars.push_back(RefExpr);
24056     ValueDecl *D = Res.first;
24057     if (!D)
24058       continue;
24059 
24060     OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective();
24061     DSAStackTy::DSAVarData DVar;
24062     if (ParentDirective != OMPD_unknown)
24063       DVar = DSAStack->getTopDSA(D, /*FromParent=*/true);
24064     // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
24065     // A list item that appears in the inclusive or exclusive clause must appear
24066     // in a reduction clause with the inscan modifier on the enclosing
24067     // worksharing-loop, worksharing-loop SIMD, or simd construct.
24068     if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction ||
24069         DVar.Modifier != OMPC_REDUCTION_inscan) {
24070       Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
24071           << RefExpr->getSourceRange();
24072     } else {
24073       DSAStack->markDeclAsUsedInScanDirective(D);
24074     }
24075     Vars.push_back(RefExpr);
24076   }
24077 
24078   if (Vars.empty())
24079     return nullptr;
24080 
24081   return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
24082 }
24083 
24084 /// Tries to find omp_alloctrait_t type.
24085 static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) {
24086   QualType OMPAlloctraitT = Stack->getOMPAlloctraitT();
24087   if (!OMPAlloctraitT.isNull())
24088     return true;
24089   IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t");
24090   ParsedType PT = S.getTypeName(II, Loc, S.getCurScope());
24091   if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
24092     S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t";
24093     return false;
24094   }
24095   Stack->setOMPAlloctraitT(PT.get());
24096   return true;
24097 }
24098 
24099 OMPClause *Sema::ActOnOpenMPUsesAllocatorClause(
24100     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
24101     ArrayRef<UsesAllocatorsData> Data) {
24102   // OpenMP [2.12.5, target Construct]
24103   // allocator is an identifier of omp_allocator_handle_t type.
24104   if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack))
24105     return nullptr;
24106   // OpenMP [2.12.5, target Construct]
24107   // allocator-traits-array is an identifier of const omp_alloctrait_t * type.
24108   if (llvm::any_of(
24109           Data,
24110           [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) &&
24111       !findOMPAlloctraitT(*this, StartLoc, DSAStack))
24112     return nullptr;
24113   llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators;
24114   for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
24115     auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
24116     StringRef Allocator =
24117         OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
24118     DeclarationName AllocatorName = &Context.Idents.get(Allocator);
24119     PredefinedAllocators.insert(LookupSingleName(
24120         TUScope, AllocatorName, StartLoc, Sema::LookupAnyName));
24121   }
24122 
24123   SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData;
24124   for (const UsesAllocatorsData &D : Data) {
24125     Expr *AllocatorExpr = nullptr;
24126     // Check allocator expression.
24127     if (D.Allocator->isTypeDependent()) {
24128       AllocatorExpr = D.Allocator;
24129     } else {
24130       // Traits were specified - need to assign new allocator to the specified
24131       // allocator, so it must be an lvalue.
24132       AllocatorExpr = D.Allocator->IgnoreParenImpCasts();
24133       auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr);
24134       bool IsPredefinedAllocator = false;
24135       if (DRE) {
24136         OMPAllocateDeclAttr::AllocatorTypeTy AllocatorTy =
24137             getAllocatorKind(*this, DSAStack, AllocatorExpr);
24138         IsPredefinedAllocator =
24139             AllocatorTy !=
24140             OMPAllocateDeclAttr::AllocatorTypeTy::OMPUserDefinedMemAlloc;
24141       }
24142       QualType OMPAllocatorHandleT = DSAStack->getOMPAllocatorHandleT();
24143       QualType AllocatorExprType = AllocatorExpr->getType();
24144       bool IsTypeCompatible = IsPredefinedAllocator;
24145       IsTypeCompatible = IsTypeCompatible ||
24146                          Context.hasSameUnqualifiedType(AllocatorExprType,
24147                                                         OMPAllocatorHandleT);
24148       IsTypeCompatible =
24149           IsTypeCompatible ||
24150           Context.typesAreCompatible(AllocatorExprType, OMPAllocatorHandleT);
24151       bool IsNonConstantLValue =
24152           !AllocatorExprType.isConstant(Context) && AllocatorExpr->isLValue();
24153       if (!DRE || !IsTypeCompatible ||
24154           (!IsPredefinedAllocator && !IsNonConstantLValue)) {
24155         Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected)
24156             << "omp_allocator_handle_t" << (DRE ? 1 : 0)
24157             << AllocatorExpr->getType() << D.Allocator->getSourceRange();
24158         continue;
24159       }
24160       // OpenMP [2.12.5, target Construct]
24161       // Predefined allocators appearing in a uses_allocators clause cannot have
24162       // traits specified.
24163       if (IsPredefinedAllocator && D.AllocatorTraits) {
24164         Diag(D.AllocatorTraits->getExprLoc(),
24165              diag::err_omp_predefined_allocator_with_traits)
24166             << D.AllocatorTraits->getSourceRange();
24167         Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator)
24168             << cast<NamedDecl>(DRE->getDecl())->getName()
24169             << D.Allocator->getSourceRange();
24170         continue;
24171       }
24172       // OpenMP [2.12.5, target Construct]
24173       // Non-predefined allocators appearing in a uses_allocators clause must
24174       // have traits specified.
24175       if (!IsPredefinedAllocator && !D.AllocatorTraits) {
24176         Diag(D.Allocator->getExprLoc(),
24177              diag::err_omp_nonpredefined_allocator_without_traits);
24178         continue;
24179       }
24180       // No allocator traits - just convert it to rvalue.
24181       if (!D.AllocatorTraits)
24182         AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get();
24183       DSAStack->addUsesAllocatorsDecl(
24184           DRE->getDecl(),
24185           IsPredefinedAllocator
24186               ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator
24187               : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator);
24188     }
24189     Expr *AllocatorTraitsExpr = nullptr;
24190     if (D.AllocatorTraits) {
24191       if (D.AllocatorTraits->isTypeDependent()) {
24192         AllocatorTraitsExpr = D.AllocatorTraits;
24193       } else {
24194         // OpenMP [2.12.5, target Construct]
24195         // Arrays that contain allocator traits that appear in a uses_allocators
24196         // clause must be constant arrays, have constant values and be defined
24197         // in the same scope as the construct in which the clause appears.
24198         AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts();
24199         // Check that traits expr is a constant array.
24200         QualType TraitTy;
24201         if (const ArrayType *Ty =
24202                 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe())
24203           if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty))
24204             TraitTy = ConstArrayTy->getElementType();
24205         if (TraitTy.isNull() ||
24206             !(Context.hasSameUnqualifiedType(TraitTy,
24207                                              DSAStack->getOMPAlloctraitT()) ||
24208               Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(),
24209                                          /*CompareUnqualified=*/true))) {
24210           Diag(D.AllocatorTraits->getExprLoc(),
24211                diag::err_omp_expected_array_alloctraits)
24212               << AllocatorTraitsExpr->getType();
24213           continue;
24214         }
24215         // Do not map by default allocator traits if it is a standalone
24216         // variable.
24217         if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr))
24218           DSAStack->addUsesAllocatorsDecl(
24219               DRE->getDecl(),
24220               DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait);
24221       }
24222     }
24223     OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back();
24224     NewD.Allocator = AllocatorExpr;
24225     NewD.AllocatorTraits = AllocatorTraitsExpr;
24226     NewD.LParenLoc = D.LParenLoc;
24227     NewD.RParenLoc = D.RParenLoc;
24228   }
24229   return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc,
24230                                          NewData);
24231 }
24232 
24233 OMPClause *Sema::ActOnOpenMPAffinityClause(
24234     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
24235     SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) {
24236   SmallVector<Expr *, 8> Vars;
24237   for (Expr *RefExpr : Locators) {
24238     assert(RefExpr && "NULL expr in OpenMP shared clause.");
24239     if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) {
24240       // It will be analyzed later.
24241       Vars.push_back(RefExpr);
24242       continue;
24243     }
24244 
24245     SourceLocation ELoc = RefExpr->getExprLoc();
24246     Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts();
24247 
24248     if (!SimpleExpr->isLValue()) {
24249       Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
24250           << 1 << 0 << RefExpr->getSourceRange();
24251       continue;
24252     }
24253 
24254     ExprResult Res;
24255     {
24256       Sema::TentativeAnalysisScope Trap(*this);
24257       Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr);
24258     }
24259     if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
24260         !isa<OMPArrayShapingExpr>(SimpleExpr)) {
24261       Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
24262           << 1 << 0 << RefExpr->getSourceRange();
24263       continue;
24264     }
24265     Vars.push_back(SimpleExpr);
24266   }
24267 
24268   return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
24269                                    EndLoc, Modifier, Vars);
24270 }
24271 
24272 OMPClause *Sema::ActOnOpenMPBindClause(OpenMPBindClauseKind Kind,
24273                                        SourceLocation KindLoc,
24274                                        SourceLocation StartLoc,
24275                                        SourceLocation LParenLoc,
24276                                        SourceLocation EndLoc) {
24277   if (Kind == OMPC_BIND_unknown) {
24278     Diag(KindLoc, diag::err_omp_unexpected_clause_value)
24279         << getListOfPossibleValues(OMPC_bind, /*First=*/0,
24280                                    /*Last=*/unsigned(OMPC_BIND_unknown))
24281         << getOpenMPClauseName(OMPC_bind);
24282     return nullptr;
24283   }
24284 
24285   return OMPBindClause::Create(Context, Kind, KindLoc, StartLoc, LParenLoc,
24286                                EndLoc);
24287 }
24288 
24289 OMPClause *Sema::ActOnOpenMPXDynCGroupMemClause(Expr *Size,
24290                                                 SourceLocation StartLoc,
24291                                                 SourceLocation LParenLoc,
24292                                                 SourceLocation EndLoc) {
24293   Expr *ValExpr = Size;
24294   Stmt *HelperValStmt = nullptr;
24295 
24296   // OpenMP [2.5, Restrictions]
24297   //  The ompx_dyn_cgroup_mem expression must evaluate to a positive integer
24298   //  value.
24299   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_ompx_dyn_cgroup_mem,
24300                                  /*StrictlyPositive=*/false))
24301     return nullptr;
24302 
24303   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
24304   OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
24305       DKind, OMPC_ompx_dyn_cgroup_mem, LangOpts.OpenMP);
24306   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
24307     ValExpr = MakeFullExpr(ValExpr).get();
24308     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
24309     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
24310     HelperValStmt = buildPreInits(Context, Captures);
24311   }
24312 
24313   return new (Context) OMPXDynCGroupMemClause(
24314       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
24315 }
24316 
24317 OMPClause *Sema::ActOnOpenMPDoacrossClause(
24318     OpenMPDoacrossClauseModifier DepType, SourceLocation DepLoc,
24319     SourceLocation ColonLoc, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
24320     SourceLocation LParenLoc, SourceLocation EndLoc) {
24321 
24322   if (DSAStack->getCurrentDirective() == OMPD_ordered &&
24323       DepType != OMPC_DOACROSS_source && DepType != OMPC_DOACROSS_sink &&
24324       DepType != OMPC_DOACROSS_sink_omp_cur_iteration &&
24325       DepType != OMPC_DOACROSS_source_omp_cur_iteration &&
24326       DepType != OMPC_DOACROSS_source) {
24327     Diag(DepLoc, diag::err_omp_unexpected_clause_value)
24328         << "'source' or 'sink'" << getOpenMPClauseName(OMPC_doacross);
24329     return nullptr;
24330   }
24331 
24332   SmallVector<Expr *, 8> Vars;
24333   DSAStackTy::OperatorOffsetTy OpsOffs;
24334   llvm::APSInt TotalDepCount(/*BitWidth=*/32);
24335   DoacrossDataInfoTy VarOffset = ProcessOpenMPDoacrossClauseCommon(
24336       *this,
24337       DepType == OMPC_DOACROSS_source ||
24338           DepType == OMPC_DOACROSS_source_omp_cur_iteration ||
24339           DepType == OMPC_DOACROSS_sink_omp_cur_iteration,
24340       VarList, DSAStack, EndLoc);
24341   Vars = VarOffset.Vars;
24342   OpsOffs = VarOffset.OpsOffs;
24343   TotalDepCount = VarOffset.TotalDepCount;
24344   auto *C = OMPDoacrossClause::Create(Context, StartLoc, LParenLoc, EndLoc,
24345                                       DepType, DepLoc, ColonLoc, Vars,
24346                                       TotalDepCount.getZExtValue());
24347   if (DSAStack->isParentOrderedRegion())
24348     DSAStack->addDoacrossDependClause(C, OpsOffs);
24349   return C;
24350 }
24351 
24352 OMPClause *Sema::ActOnOpenMPXAttributeClause(ArrayRef<const Attr *> Attrs,
24353                                              SourceLocation StartLoc,
24354                                              SourceLocation LParenLoc,
24355                                              SourceLocation EndLoc) {
24356   return new (Context) OMPXAttributeClause(Attrs, StartLoc, LParenLoc, EndLoc);
24357 }
24358 
24359 OMPClause *Sema::ActOnOpenMPXBareClause(SourceLocation StartLoc,
24360                                         SourceLocation EndLoc) {
24361   return new (Context) OMPXBareClause(StartLoc, EndLoc);
24362 }
24363