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/Initialization.h"
31 #include "clang/Sema/Lookup.h"
32 #include "clang/Sema/Scope.h"
33 #include "clang/Sema/ScopeInfo.h"
34 #include "clang/Sema/SemaInternal.h"
35 #include "llvm/ADT/IndexedMap.h"
36 #include "llvm/ADT/PointerEmbeddedInt.h"
37 #include "llvm/ADT/STLExtras.h"
38 #include "llvm/ADT/SmallSet.h"
39 #include "llvm/ADT/StringExtras.h"
40 #include "llvm/Frontend/OpenMP/OMPAssume.h"
41 #include "llvm/Frontend/OpenMP/OMPConstants.h"
42 #include <set>
43 
44 using namespace clang;
45 using namespace llvm::omp;
46 
47 //===----------------------------------------------------------------------===//
48 // Stack of data-sharing attributes for variables
49 //===----------------------------------------------------------------------===//
50 
51 static const Expr *checkMapClauseExpressionBase(
52     Sema &SemaRef, Expr *E,
53     OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
54     OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose);
55 
56 namespace {
57 /// Default data sharing attributes, which can be applied to directive.
58 enum DefaultDataSharingAttributes {
59   DSA_unspecified = 0,       /// Data sharing attribute not specified.
60   DSA_none = 1 << 0,         /// Default data sharing attribute 'none'.
61   DSA_shared = 1 << 1,       /// Default data sharing attribute 'shared'.
62   DSA_firstprivate = 1 << 2, /// Default data sharing attribute 'firstprivate'.
63 };
64 
65 /// Stack for tracking declarations used in OpenMP directives and
66 /// clauses and their data-sharing attributes.
67 class DSAStackTy {
68 public:
69   struct DSAVarData {
70     OpenMPDirectiveKind DKind = OMPD_unknown;
71     OpenMPClauseKind CKind = OMPC_unknown;
72     unsigned Modifier = 0;
73     const Expr *RefExpr = nullptr;
74     DeclRefExpr *PrivateCopy = nullptr;
75     SourceLocation ImplicitDSALoc;
76     bool AppliedToPointee = false;
77     DSAVarData() = default;
78     DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
79                const Expr *RefExpr, DeclRefExpr *PrivateCopy,
80                SourceLocation ImplicitDSALoc, unsigned Modifier,
81                bool AppliedToPointee)
82         : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr),
83           PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc),
84           AppliedToPointee(AppliedToPointee) {}
85   };
86   using OperatorOffsetTy =
87       llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>;
88   using DoacrossDependMapTy =
89       llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
90   /// Kind of the declaration used in the uses_allocators clauses.
91   enum class UsesAllocatorsDeclKind {
92     /// Predefined allocator
93     PredefinedAllocator,
94     /// User-defined allocator
95     UserDefinedAllocator,
96     /// The declaration that represent allocator trait
97     AllocatorTrait,
98   };
99 
100 private:
101   struct DSAInfo {
102     OpenMPClauseKind Attributes = OMPC_unknown;
103     unsigned Modifier = 0;
104     /// Pointer to a reference expression and a flag which shows that the
105     /// variable is marked as lastprivate(true) or not (false).
106     llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
107     DeclRefExpr *PrivateCopy = nullptr;
108     /// true if the attribute is applied to the pointee, not the variable
109     /// itself.
110     bool AppliedToPointee = false;
111   };
112   using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
113   using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
114   using LCDeclInfo = std::pair<unsigned, VarDecl *>;
115   using LoopControlVariablesMapTy =
116       llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
117   /// Struct that associates a component with the clause kind where they are
118   /// found.
119   struct MappedExprComponentTy {
120     OMPClauseMappableExprCommon::MappableExprComponentLists Components;
121     OpenMPClauseKind Kind = OMPC_unknown;
122   };
123   using MappedExprComponentsTy =
124       llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
125   using CriticalsWithHintsTy =
126       llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
127   struct ReductionData {
128     using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
129     SourceRange ReductionRange;
130     llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
131     ReductionData() = default;
132     void set(BinaryOperatorKind BO, SourceRange RR) {
133       ReductionRange = RR;
134       ReductionOp = BO;
135     }
136     void set(const Expr *RefExpr, SourceRange RR) {
137       ReductionRange = RR;
138       ReductionOp = RefExpr;
139     }
140   };
141   using DeclReductionMapTy =
142       llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
143   struct DefaultmapInfo {
144     OpenMPDefaultmapClauseModifier ImplicitBehavior =
145         OMPC_DEFAULTMAP_MODIFIER_unknown;
146     SourceLocation SLoc;
147     DefaultmapInfo() = default;
148     DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc)
149         : ImplicitBehavior(M), SLoc(Loc) {}
150   };
151 
152   struct SharingMapTy {
153     DeclSAMapTy SharingMap;
154     DeclReductionMapTy ReductionMap;
155     UsedRefMapTy AlignedMap;
156     UsedRefMapTy NontemporalMap;
157     MappedExprComponentsTy MappedExprComponents;
158     LoopControlVariablesMapTy LCVMap;
159     DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
160     SourceLocation DefaultAttrLoc;
161     DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown];
162     OpenMPDirectiveKind Directive = OMPD_unknown;
163     DeclarationNameInfo DirectiveName;
164     Scope *CurScope = nullptr;
165     DeclContext *Context = nullptr;
166     SourceLocation ConstructLoc;
167     /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
168     /// get the data (loop counters etc.) about enclosing loop-based construct.
169     /// This data is required during codegen.
170     DoacrossDependMapTy DoacrossDepends;
171     /// First argument (Expr *) contains optional argument of the
172     /// 'ordered' clause, the second one is true if the regions has 'ordered'
173     /// clause, false otherwise.
174     llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
175     unsigned AssociatedLoops = 1;
176     bool HasMutipleLoops = false;
177     const Decl *PossiblyLoopCounter = nullptr;
178     bool NowaitRegion = false;
179     bool UntiedRegion = false;
180     bool CancelRegion = false;
181     bool LoopStart = false;
182     bool BodyComplete = false;
183     SourceLocation PrevScanLocation;
184     SourceLocation PrevOrderedLocation;
185     SourceLocation InnerTeamsRegionLoc;
186     /// Reference to the taskgroup task_reduction reference expression.
187     Expr *TaskgroupReductionRef = nullptr;
188     llvm::DenseSet<QualType> MappedClassesQualTypes;
189     SmallVector<Expr *, 4> InnerUsedAllocators;
190     llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates;
191     /// List of globals marked as declare target link in this target region
192     /// (isOpenMPTargetExecutionDirective(Directive) == true).
193     llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls;
194     /// List of decls used in inclusive/exclusive clauses of the scan directive.
195     llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective;
196     llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind>
197         UsesAllocatorsDecls;
198     Expr *DeclareMapperVar = nullptr;
199     SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
200                  Scope *CurScope, SourceLocation Loc)
201         : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
202           ConstructLoc(Loc) {}
203     SharingMapTy() = default;
204   };
205 
206   using StackTy = SmallVector<SharingMapTy, 4>;
207 
208   /// Stack of used declaration and their data-sharing attributes.
209   DeclSAMapTy Threadprivates;
210   const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
211   SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack;
212   /// true, if check for DSA must be from parent directive, false, if
213   /// from current directive.
214   OpenMPClauseKind ClauseKindMode = OMPC_unknown;
215   Sema &SemaRef;
216   bool ForceCapturing = false;
217   /// true if all the variables in the target executable directives must be
218   /// captured by reference.
219   bool ForceCaptureByReferenceInTargetExecutable = false;
220   CriticalsWithHintsTy Criticals;
221   unsigned IgnoredStackElements = 0;
222 
223   /// Iterators over the stack iterate in order from innermost to outermost
224   /// directive.
225   using const_iterator = StackTy::const_reverse_iterator;
226   const_iterator begin() const {
227     return Stack.empty() ? const_iterator()
228                          : Stack.back().first.rbegin() + IgnoredStackElements;
229   }
230   const_iterator end() const {
231     return Stack.empty() ? const_iterator() : Stack.back().first.rend();
232   }
233   using iterator = StackTy::reverse_iterator;
234   iterator begin() {
235     return Stack.empty() ? iterator()
236                          : Stack.back().first.rbegin() + IgnoredStackElements;
237   }
238   iterator end() {
239     return Stack.empty() ? iterator() : Stack.back().first.rend();
240   }
241 
242   // Convenience operations to get at the elements of the stack.
243 
244   bool isStackEmpty() const {
245     return Stack.empty() ||
246            Stack.back().second != CurrentNonCapturingFunctionScope ||
247            Stack.back().first.size() <= IgnoredStackElements;
248   }
249   size_t getStackSize() const {
250     return isStackEmpty() ? 0
251                           : Stack.back().first.size() - IgnoredStackElements;
252   }
253 
254   SharingMapTy *getTopOfStackOrNull() {
255     size_t Size = getStackSize();
256     if (Size == 0)
257       return nullptr;
258     return &Stack.back().first[Size - 1];
259   }
260   const SharingMapTy *getTopOfStackOrNull() const {
261     return const_cast<DSAStackTy &>(*this).getTopOfStackOrNull();
262   }
263   SharingMapTy &getTopOfStack() {
264     assert(!isStackEmpty() && "no current directive");
265     return *getTopOfStackOrNull();
266   }
267   const SharingMapTy &getTopOfStack() const {
268     return const_cast<DSAStackTy &>(*this).getTopOfStack();
269   }
270 
271   SharingMapTy *getSecondOnStackOrNull() {
272     size_t Size = getStackSize();
273     if (Size <= 1)
274       return nullptr;
275     return &Stack.back().first[Size - 2];
276   }
277   const SharingMapTy *getSecondOnStackOrNull() const {
278     return const_cast<DSAStackTy &>(*this).getSecondOnStackOrNull();
279   }
280 
281   /// Get the stack element at a certain level (previously returned by
282   /// \c getNestingLevel).
283   ///
284   /// Note that nesting levels count from outermost to innermost, and this is
285   /// the reverse of our iteration order where new inner levels are pushed at
286   /// the front of the stack.
287   SharingMapTy &getStackElemAtLevel(unsigned Level) {
288     assert(Level < getStackSize() && "no such stack element");
289     return Stack.back().first[Level];
290   }
291   const SharingMapTy &getStackElemAtLevel(unsigned Level) const {
292     return const_cast<DSAStackTy &>(*this).getStackElemAtLevel(Level);
293   }
294 
295   DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const;
296 
297   /// Checks if the variable is a local for OpenMP region.
298   bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const;
299 
300   /// Vector of previously declared requires directives
301   SmallVector<const OMPRequiresDecl *, 2> RequiresDecls;
302   /// omp_allocator_handle_t type.
303   QualType OMPAllocatorHandleT;
304   /// omp_depend_t type.
305   QualType OMPDependT;
306   /// omp_event_handle_t type.
307   QualType OMPEventHandleT;
308   /// omp_alloctrait_t type.
309   QualType OMPAlloctraitT;
310   /// Expression for the predefined allocators.
311   Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
312       nullptr};
313   /// Vector of previously encountered target directives
314   SmallVector<SourceLocation, 2> TargetLocations;
315   SourceLocation AtomicLocation;
316   /// Vector of declare variant construct traits.
317   SmallVector<llvm::omp::TraitProperty, 8> ConstructTraits;
318 
319 public:
320   explicit DSAStackTy(Sema &S) : SemaRef(S) {}
321 
322   /// Sets omp_allocator_handle_t type.
323   void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; }
324   /// Gets omp_allocator_handle_t type.
325   QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; }
326   /// Sets omp_alloctrait_t type.
327   void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; }
328   /// Gets omp_alloctrait_t type.
329   QualType getOMPAlloctraitT() const { return OMPAlloctraitT; }
330   /// Sets the given default allocator.
331   void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
332                     Expr *Allocator) {
333     OMPPredefinedAllocators[AllocatorKind] = Allocator;
334   }
335   /// Returns the specified default allocator.
336   Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const {
337     return OMPPredefinedAllocators[AllocatorKind];
338   }
339   /// Sets omp_depend_t type.
340   void setOMPDependT(QualType Ty) { OMPDependT = Ty; }
341   /// Gets omp_depend_t type.
342   QualType getOMPDependT() const { return OMPDependT; }
343 
344   /// Sets omp_event_handle_t type.
345   void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; }
346   /// Gets omp_event_handle_t type.
347   QualType getOMPEventHandleT() const { return OMPEventHandleT; }
348 
349   bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
350   OpenMPClauseKind getClauseParsingMode() const {
351     assert(isClauseParsingMode() && "Must be in clause parsing mode.");
352     return ClauseKindMode;
353   }
354   void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
355 
356   bool isBodyComplete() const {
357     const SharingMapTy *Top = getTopOfStackOrNull();
358     return Top && Top->BodyComplete;
359   }
360   void setBodyComplete() { getTopOfStack().BodyComplete = true; }
361 
362   bool isForceVarCapturing() const { return ForceCapturing; }
363   void setForceVarCapturing(bool V) { ForceCapturing = V; }
364 
365   void setForceCaptureByReferenceInTargetExecutable(bool V) {
366     ForceCaptureByReferenceInTargetExecutable = V;
367   }
368   bool isForceCaptureByReferenceInTargetExecutable() const {
369     return ForceCaptureByReferenceInTargetExecutable;
370   }
371 
372   void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
373             Scope *CurScope, SourceLocation Loc) {
374     assert(!IgnoredStackElements &&
375            "cannot change stack while ignoring elements");
376     if (Stack.empty() ||
377         Stack.back().second != CurrentNonCapturingFunctionScope)
378       Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
379     Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
380     Stack.back().first.back().DefaultAttrLoc = Loc;
381   }
382 
383   void pop() {
384     assert(!IgnoredStackElements &&
385            "cannot change stack while ignoring elements");
386     assert(!Stack.back().first.empty() &&
387            "Data-sharing attributes stack is empty!");
388     Stack.back().first.pop_back();
389   }
390 
391   /// RAII object to temporarily leave the scope of a directive when we want to
392   /// logically operate in its parent.
393   class ParentDirectiveScope {
394     DSAStackTy &Self;
395     bool Active;
396 
397   public:
398     ParentDirectiveScope(DSAStackTy &Self, bool Activate)
399         : Self(Self), Active(false) {
400       if (Activate)
401         enable();
402     }
403     ~ParentDirectiveScope() { disable(); }
404     void disable() {
405       if (Active) {
406         --Self.IgnoredStackElements;
407         Active = false;
408       }
409     }
410     void enable() {
411       if (!Active) {
412         ++Self.IgnoredStackElements;
413         Active = true;
414       }
415     }
416   };
417 
418   /// Marks that we're started loop parsing.
419   void loopInit() {
420     assert(isOpenMPLoopDirective(getCurrentDirective()) &&
421            "Expected loop-based directive.");
422     getTopOfStack().LoopStart = true;
423   }
424   /// Start capturing of the variables in the loop context.
425   void loopStart() {
426     assert(isOpenMPLoopDirective(getCurrentDirective()) &&
427            "Expected loop-based directive.");
428     getTopOfStack().LoopStart = false;
429   }
430   /// true, if variables are captured, false otherwise.
431   bool isLoopStarted() const {
432     assert(isOpenMPLoopDirective(getCurrentDirective()) &&
433            "Expected loop-based directive.");
434     return !getTopOfStack().LoopStart;
435   }
436   /// Marks (or clears) declaration as possibly loop counter.
437   void resetPossibleLoopCounter(const Decl *D = nullptr) {
438     getTopOfStack().PossiblyLoopCounter = D ? D->getCanonicalDecl() : D;
439   }
440   /// Gets the possible loop counter decl.
441   const Decl *getPossiblyLoopCunter() const {
442     return getTopOfStack().PossiblyLoopCounter;
443   }
444   /// Start new OpenMP region stack in new non-capturing function.
445   void pushFunction() {
446     assert(!IgnoredStackElements &&
447            "cannot change stack while ignoring elements");
448     const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
449     assert(!isa<CapturingScopeInfo>(CurFnScope));
450     CurrentNonCapturingFunctionScope = CurFnScope;
451   }
452   /// Pop region stack for non-capturing function.
453   void popFunction(const FunctionScopeInfo *OldFSI) {
454     assert(!IgnoredStackElements &&
455            "cannot change stack while ignoring elements");
456     if (!Stack.empty() && Stack.back().second == OldFSI) {
457       assert(Stack.back().first.empty());
458       Stack.pop_back();
459     }
460     CurrentNonCapturingFunctionScope = nullptr;
461     for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
462       if (!isa<CapturingScopeInfo>(FSI)) {
463         CurrentNonCapturingFunctionScope = FSI;
464         break;
465       }
466     }
467   }
468 
469   void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) {
470     Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
471   }
472   const std::pair<const OMPCriticalDirective *, llvm::APSInt>
473   getCriticalWithHint(const DeclarationNameInfo &Name) const {
474     auto I = Criticals.find(Name.getAsString());
475     if (I != Criticals.end())
476       return I->second;
477     return std::make_pair(nullptr, llvm::APSInt());
478   }
479   /// If 'aligned' declaration for given variable \a D was not seen yet,
480   /// add it and return NULL; otherwise return previous occurrence's expression
481   /// for diagnostics.
482   const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE);
483   /// If 'nontemporal' declaration for given variable \a D was not seen yet,
484   /// add it and return NULL; otherwise return previous occurrence's expression
485   /// for diagnostics.
486   const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE);
487 
488   /// Register specified variable as loop control variable.
489   void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture);
490   /// Check if the specified variable is a loop control variable for
491   /// current region.
492   /// \return The index of the loop control variable in the list of associated
493   /// for-loops (from outer to inner).
494   const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const;
495   /// Check if the specified variable is a loop control variable for
496   /// parent region.
497   /// \return The index of the loop control variable in the list of associated
498   /// for-loops (from outer to inner).
499   const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const;
500   /// Check if the specified variable is a loop control variable for
501   /// current region.
502   /// \return The index of the loop control variable in the list of associated
503   /// for-loops (from outer to inner).
504   const LCDeclInfo isLoopControlVariable(const ValueDecl *D,
505                                          unsigned Level) const;
506   /// Get the loop control variable for the I-th loop (or nullptr) in
507   /// parent directive.
508   const ValueDecl *getParentLoopControlVariable(unsigned I) const;
509 
510   /// Marks the specified decl \p D as used in scan directive.
511   void markDeclAsUsedInScanDirective(ValueDecl *D) {
512     if (SharingMapTy *Stack = getSecondOnStackOrNull())
513       Stack->UsedInScanDirective.insert(D);
514   }
515 
516   /// Checks if the specified declaration was used in the inner scan directive.
517   bool isUsedInScanDirective(ValueDecl *D) const {
518     if (const SharingMapTy *Stack = getTopOfStackOrNull())
519       return Stack->UsedInScanDirective.contains(D);
520     return false;
521   }
522 
523   /// Adds explicit data sharing attribute to the specified declaration.
524   void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
525               DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0,
526               bool AppliedToPointee = false);
527 
528   /// Adds additional information for the reduction items with the reduction id
529   /// represented as an operator.
530   void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
531                                  BinaryOperatorKind BOK);
532   /// Adds additional information for the reduction items with the reduction id
533   /// represented as reduction identifier.
534   void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
535                                  const Expr *ReductionRef);
536   /// Returns the location and reduction operation from the innermost parent
537   /// region for the given \p D.
538   const DSAVarData
539   getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
540                                    BinaryOperatorKind &BOK,
541                                    Expr *&TaskgroupDescriptor) const;
542   /// Returns the location and reduction operation from the innermost parent
543   /// region for the given \p D.
544   const DSAVarData
545   getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
546                                    const Expr *&ReductionRef,
547                                    Expr *&TaskgroupDescriptor) const;
548   /// Return reduction reference expression for the current taskgroup or
549   /// parallel/worksharing directives with task reductions.
550   Expr *getTaskgroupReductionRef() const {
551     assert((getTopOfStack().Directive == OMPD_taskgroup ||
552             ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
553               isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
554              !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
555            "taskgroup reference expression requested for non taskgroup or "
556            "parallel/worksharing directive.");
557     return getTopOfStack().TaskgroupReductionRef;
558   }
559   /// Checks if the given \p VD declaration is actually a taskgroup reduction
560   /// descriptor variable at the \p Level of OpenMP regions.
561   bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
562     return getStackElemAtLevel(Level).TaskgroupReductionRef &&
563            cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
564                    ->getDecl() == VD;
565   }
566 
567   /// Returns data sharing attributes from top of the stack for the
568   /// specified declaration.
569   const DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
570   /// Returns data-sharing attributes for the specified declaration.
571   const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const;
572   /// Returns data-sharing attributes for the specified declaration.
573   const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const;
574   /// Checks if the specified variables has data-sharing attributes which
575   /// match specified \a CPred predicate in any directive which matches \a DPred
576   /// predicate.
577   const DSAVarData
578   hasDSA(ValueDecl *D,
579          const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
580          const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
581          bool FromParent) const;
582   /// Checks if the specified variables has data-sharing attributes which
583   /// match specified \a CPred predicate in any innermost directive which
584   /// matches \a DPred predicate.
585   const DSAVarData
586   hasInnermostDSA(ValueDecl *D,
587                   const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
588                   const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
589                   bool FromParent) const;
590   /// Checks if the specified variables has explicit data-sharing
591   /// attributes which match specified \a CPred predicate at the specified
592   /// OpenMP region.
593   bool
594   hasExplicitDSA(const ValueDecl *D,
595                  const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
596                  unsigned Level, bool NotLastprivate = false) const;
597 
598   /// Returns true if the directive at level \Level matches in the
599   /// specified \a DPred predicate.
600   bool hasExplicitDirective(
601       const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
602       unsigned Level) const;
603 
604   /// Finds a directive which matches specified \a DPred predicate.
605   bool hasDirective(
606       const llvm::function_ref<bool(
607           OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)>
608           DPred,
609       bool FromParent) const;
610 
611   /// Returns currently analyzed directive.
612   OpenMPDirectiveKind getCurrentDirective() const {
613     const SharingMapTy *Top = getTopOfStackOrNull();
614     return Top ? Top->Directive : OMPD_unknown;
615   }
616   /// Returns directive kind at specified level.
617   OpenMPDirectiveKind getDirective(unsigned Level) const {
618     assert(!isStackEmpty() && "No directive at specified level.");
619     return getStackElemAtLevel(Level).Directive;
620   }
621   /// Returns the capture region at the specified level.
622   OpenMPDirectiveKind getCaptureRegion(unsigned Level,
623                                        unsigned OpenMPCaptureLevel) const {
624     SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
625     getOpenMPCaptureRegions(CaptureRegions, getDirective(Level));
626     return CaptureRegions[OpenMPCaptureLevel];
627   }
628   /// Returns parent directive.
629   OpenMPDirectiveKind getParentDirective() const {
630     const SharingMapTy *Parent = getSecondOnStackOrNull();
631     return Parent ? Parent->Directive : OMPD_unknown;
632   }
633 
634   /// Add requires decl to internal vector
635   void addRequiresDecl(OMPRequiresDecl *RD) { RequiresDecls.push_back(RD); }
636 
637   /// Checks if the defined 'requires' directive has specified type of clause.
638   template <typename ClauseType> bool hasRequiresDeclWithClause() const {
639     return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) {
640       return llvm::any_of(D->clauselists(), [](const OMPClause *C) {
641         return isa<ClauseType>(C);
642       });
643     });
644   }
645 
646   /// Checks for a duplicate clause amongst previously declared requires
647   /// directives
648   bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const {
649     bool IsDuplicate = false;
650     for (OMPClause *CNew : ClauseList) {
651       for (const OMPRequiresDecl *D : RequiresDecls) {
652         for (const OMPClause *CPrev : D->clauselists()) {
653           if (CNew->getClauseKind() == CPrev->getClauseKind()) {
654             SemaRef.Diag(CNew->getBeginLoc(),
655                          diag::err_omp_requires_clause_redeclaration)
656                 << getOpenMPClauseName(CNew->getClauseKind());
657             SemaRef.Diag(CPrev->getBeginLoc(),
658                          diag::note_omp_requires_previous_clause)
659                 << getOpenMPClauseName(CPrev->getClauseKind());
660             IsDuplicate = true;
661           }
662         }
663       }
664     }
665     return IsDuplicate;
666   }
667 
668   /// Add location of previously encountered target to internal vector
669   void addTargetDirLocation(SourceLocation LocStart) {
670     TargetLocations.push_back(LocStart);
671   }
672 
673   /// Add location for the first encountered atomicc directive.
674   void addAtomicDirectiveLoc(SourceLocation Loc) {
675     if (AtomicLocation.isInvalid())
676       AtomicLocation = Loc;
677   }
678 
679   /// Returns the location of the first encountered atomic directive in the
680   /// module.
681   SourceLocation getAtomicDirectiveLoc() const { return AtomicLocation; }
682 
683   // Return previously encountered target region locations.
684   ArrayRef<SourceLocation> getEncounteredTargetLocs() const {
685     return TargetLocations;
686   }
687 
688   /// Set default data sharing attribute to none.
689   void setDefaultDSANone(SourceLocation Loc) {
690     getTopOfStack().DefaultAttr = DSA_none;
691     getTopOfStack().DefaultAttrLoc = Loc;
692   }
693   /// Set default data sharing attribute to shared.
694   void setDefaultDSAShared(SourceLocation Loc) {
695     getTopOfStack().DefaultAttr = DSA_shared;
696     getTopOfStack().DefaultAttrLoc = Loc;
697   }
698   /// Set default data sharing attribute to firstprivate.
699   void setDefaultDSAFirstPrivate(SourceLocation Loc) {
700     getTopOfStack().DefaultAttr = DSA_firstprivate;
701     getTopOfStack().DefaultAttrLoc = Loc;
702   }
703   /// Set default data mapping attribute to Modifier:Kind
704   void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,
705                          OpenMPDefaultmapClauseKind Kind, SourceLocation Loc) {
706     DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind];
707     DMI.ImplicitBehavior = M;
708     DMI.SLoc = Loc;
709   }
710   /// Check whether the implicit-behavior has been set in defaultmap
711   bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) {
712     if (VariableCategory == OMPC_DEFAULTMAP_unknown)
713       return getTopOfStack()
714                      .DefaultmapMap[OMPC_DEFAULTMAP_aggregate]
715                      .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
716              getTopOfStack()
717                      .DefaultmapMap[OMPC_DEFAULTMAP_scalar]
718                      .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
719              getTopOfStack()
720                      .DefaultmapMap[OMPC_DEFAULTMAP_pointer]
721                      .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown;
722     return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
723            OMPC_DEFAULTMAP_MODIFIER_unknown;
724   }
725 
726   ArrayRef<llvm::omp::TraitProperty> getConstructTraits() {
727     return ConstructTraits;
728   }
729   void handleConstructTrait(ArrayRef<llvm::omp::TraitProperty> Traits,
730                             bool ScopeEntry) {
731     if (ScopeEntry)
732       ConstructTraits.append(Traits.begin(), Traits.end());
733     else
734       for (llvm::omp::TraitProperty Trait : llvm::reverse(Traits)) {
735         llvm::omp::TraitProperty Top = ConstructTraits.pop_back_val();
736         assert(Top == Trait && "Something left a trait on the stack!");
737         (void)Trait;
738         (void)Top;
739       }
740   }
741 
742   DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const {
743     return getStackSize() <= Level ? DSA_unspecified
744                                    : getStackElemAtLevel(Level).DefaultAttr;
745   }
746   DefaultDataSharingAttributes getDefaultDSA() const {
747     return isStackEmpty() ? DSA_unspecified : getTopOfStack().DefaultAttr;
748   }
749   SourceLocation getDefaultDSALocation() const {
750     return isStackEmpty() ? SourceLocation() : getTopOfStack().DefaultAttrLoc;
751   }
752   OpenMPDefaultmapClauseModifier
753   getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const {
754     return isStackEmpty()
755                ? OMPC_DEFAULTMAP_MODIFIER_unknown
756                : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior;
757   }
758   OpenMPDefaultmapClauseModifier
759   getDefaultmapModifierAtLevel(unsigned Level,
760                                OpenMPDefaultmapClauseKind Kind) const {
761     return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior;
762   }
763   bool isDefaultmapCapturedByRef(unsigned Level,
764                                  OpenMPDefaultmapClauseKind Kind) const {
765     OpenMPDefaultmapClauseModifier M =
766         getDefaultmapModifierAtLevel(Level, Kind);
767     if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) {
768       return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
769              (M == OMPC_DEFAULTMAP_MODIFIER_to) ||
770              (M == OMPC_DEFAULTMAP_MODIFIER_from) ||
771              (M == OMPC_DEFAULTMAP_MODIFIER_tofrom);
772     }
773     return true;
774   }
775   static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M,
776                                      OpenMPDefaultmapClauseKind Kind) {
777     switch (Kind) {
778     case OMPC_DEFAULTMAP_scalar:
779     case OMPC_DEFAULTMAP_pointer:
780       return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) ||
781              (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) ||
782              (M == OMPC_DEFAULTMAP_MODIFIER_default);
783     case OMPC_DEFAULTMAP_aggregate:
784       return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
785     default:
786       break;
787     }
788     llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum");
789   }
790   bool mustBeFirstprivateAtLevel(unsigned Level,
791                                  OpenMPDefaultmapClauseKind Kind) const {
792     OpenMPDefaultmapClauseModifier M =
793         getDefaultmapModifierAtLevel(Level, Kind);
794     return mustBeFirstprivateBase(M, Kind);
795   }
796   bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const {
797     OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind);
798     return mustBeFirstprivateBase(M, Kind);
799   }
800 
801   /// Checks if the specified variable is a threadprivate.
802   bool isThreadPrivate(VarDecl *D) {
803     const DSAVarData DVar = getTopDSA(D, false);
804     return isOpenMPThreadPrivate(DVar.CKind);
805   }
806 
807   /// Marks current region as ordered (it has an 'ordered' clause).
808   void setOrderedRegion(bool IsOrdered, const Expr *Param,
809                         OMPOrderedClause *Clause) {
810     if (IsOrdered)
811       getTopOfStack().OrderedRegion.emplace(Param, Clause);
812     else
813       getTopOfStack().OrderedRegion.reset();
814   }
815   /// Returns true, if region is ordered (has associated 'ordered' clause),
816   /// false - otherwise.
817   bool isOrderedRegion() const {
818     if (const SharingMapTy *Top = getTopOfStackOrNull())
819       return Top->OrderedRegion.hasValue();
820     return false;
821   }
822   /// Returns optional parameter for the ordered region.
823   std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
824     if (const SharingMapTy *Top = getTopOfStackOrNull())
825       if (Top->OrderedRegion.hasValue())
826         return Top->OrderedRegion.getValue();
827     return std::make_pair(nullptr, nullptr);
828   }
829   /// Returns true, if parent region is ordered (has associated
830   /// 'ordered' clause), false - otherwise.
831   bool isParentOrderedRegion() const {
832     if (const SharingMapTy *Parent = getSecondOnStackOrNull())
833       return Parent->OrderedRegion.hasValue();
834     return false;
835   }
836   /// Returns optional parameter for the ordered region.
837   std::pair<const Expr *, OMPOrderedClause *>
838   getParentOrderedRegionParam() const {
839     if (const SharingMapTy *Parent = getSecondOnStackOrNull())
840       if (Parent->OrderedRegion.hasValue())
841         return Parent->OrderedRegion.getValue();
842     return std::make_pair(nullptr, nullptr);
843   }
844   /// Marks current region as nowait (it has a 'nowait' clause).
845   void setNowaitRegion(bool IsNowait = true) {
846     getTopOfStack().NowaitRegion = IsNowait;
847   }
848   /// Returns true, if parent region is nowait (has associated
849   /// 'nowait' clause), false - otherwise.
850   bool isParentNowaitRegion() const {
851     if (const SharingMapTy *Parent = getSecondOnStackOrNull())
852       return Parent->NowaitRegion;
853     return false;
854   }
855   /// Marks current region as untied (it has a 'untied' clause).
856   void setUntiedRegion(bool IsUntied = true) {
857     getTopOfStack().UntiedRegion = IsUntied;
858   }
859   /// Return true if current region is untied.
860   bool isUntiedRegion() const {
861     const SharingMapTy *Top = getTopOfStackOrNull();
862     return Top ? Top->UntiedRegion : false;
863   }
864   /// Marks parent region as cancel region.
865   void setParentCancelRegion(bool Cancel = true) {
866     if (SharingMapTy *Parent = getSecondOnStackOrNull())
867       Parent->CancelRegion |= Cancel;
868   }
869   /// Return true if current region has inner cancel construct.
870   bool isCancelRegion() const {
871     const SharingMapTy *Top = getTopOfStackOrNull();
872     return Top ? Top->CancelRegion : false;
873   }
874 
875   /// Mark that parent region already has scan directive.
876   void setParentHasScanDirective(SourceLocation Loc) {
877     if (SharingMapTy *Parent = getSecondOnStackOrNull())
878       Parent->PrevScanLocation = Loc;
879   }
880   /// Return true if current region has inner cancel construct.
881   bool doesParentHasScanDirective() const {
882     const SharingMapTy *Top = getSecondOnStackOrNull();
883     return Top ? Top->PrevScanLocation.isValid() : false;
884   }
885   /// Return true if current region has inner cancel construct.
886   SourceLocation getParentScanDirectiveLoc() const {
887     const SharingMapTy *Top = getSecondOnStackOrNull();
888     return Top ? Top->PrevScanLocation : SourceLocation();
889   }
890   /// Mark that parent region already has ordered directive.
891   void setParentHasOrderedDirective(SourceLocation Loc) {
892     if (SharingMapTy *Parent = getSecondOnStackOrNull())
893       Parent->PrevOrderedLocation = Loc;
894   }
895   /// Return true if current region has inner ordered construct.
896   bool doesParentHasOrderedDirective() const {
897     const SharingMapTy *Top = getSecondOnStackOrNull();
898     return Top ? Top->PrevOrderedLocation.isValid() : false;
899   }
900   /// Returns the location of the previously specified ordered directive.
901   SourceLocation getParentOrderedDirectiveLoc() const {
902     const SharingMapTy *Top = getSecondOnStackOrNull();
903     return Top ? Top->PrevOrderedLocation : SourceLocation();
904   }
905 
906   /// Set collapse value for the region.
907   void setAssociatedLoops(unsigned Val) {
908     getTopOfStack().AssociatedLoops = Val;
909     if (Val > 1)
910       getTopOfStack().HasMutipleLoops = true;
911   }
912   /// Return collapse value for region.
913   unsigned getAssociatedLoops() const {
914     const SharingMapTy *Top = getTopOfStackOrNull();
915     return Top ? Top->AssociatedLoops : 0;
916   }
917   /// Returns true if the construct is associated with multiple loops.
918   bool hasMutipleLoops() const {
919     const SharingMapTy *Top = getTopOfStackOrNull();
920     return Top ? Top->HasMutipleLoops : false;
921   }
922 
923   /// Marks current target region as one with closely nested teams
924   /// region.
925   void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
926     if (SharingMapTy *Parent = getSecondOnStackOrNull())
927       Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
928   }
929   /// Returns true, if current region has closely nested teams region.
930   bool hasInnerTeamsRegion() const {
931     return getInnerTeamsRegionLoc().isValid();
932   }
933   /// Returns location of the nested teams region (if any).
934   SourceLocation getInnerTeamsRegionLoc() const {
935     const SharingMapTy *Top = getTopOfStackOrNull();
936     return Top ? Top->InnerTeamsRegionLoc : SourceLocation();
937   }
938 
939   Scope *getCurScope() const {
940     const SharingMapTy *Top = getTopOfStackOrNull();
941     return Top ? Top->CurScope : nullptr;
942   }
943   void setContext(DeclContext *DC) { getTopOfStack().Context = DC; }
944   SourceLocation getConstructLoc() const {
945     const SharingMapTy *Top = getTopOfStackOrNull();
946     return Top ? Top->ConstructLoc : SourceLocation();
947   }
948 
949   /// Do the check specified in \a Check to all component lists and return true
950   /// if any issue is found.
951   bool checkMappableExprComponentListsForDecl(
952       const ValueDecl *VD, bool CurrentRegionOnly,
953       const llvm::function_ref<
954           bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
955                OpenMPClauseKind)>
956           Check) const {
957     if (isStackEmpty())
958       return false;
959     auto SI = begin();
960     auto SE = end();
961 
962     if (SI == SE)
963       return false;
964 
965     if (CurrentRegionOnly)
966       SE = std::next(SI);
967     else
968       std::advance(SI, 1);
969 
970     for (; SI != SE; ++SI) {
971       auto MI = SI->MappedExprComponents.find(VD);
972       if (MI != SI->MappedExprComponents.end())
973         for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
974              MI->second.Components)
975           if (Check(L, MI->second.Kind))
976             return true;
977     }
978     return false;
979   }
980 
981   /// Do the check specified in \a Check to all component lists at a given level
982   /// and return true if any issue is found.
983   bool checkMappableExprComponentListsForDeclAtLevel(
984       const ValueDecl *VD, unsigned Level,
985       const llvm::function_ref<
986           bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
987                OpenMPClauseKind)>
988           Check) const {
989     if (getStackSize() <= Level)
990       return false;
991 
992     const SharingMapTy &StackElem = getStackElemAtLevel(Level);
993     auto MI = StackElem.MappedExprComponents.find(VD);
994     if (MI != StackElem.MappedExprComponents.end())
995       for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
996            MI->second.Components)
997         if (Check(L, MI->second.Kind))
998           return true;
999     return false;
1000   }
1001 
1002   /// Create a new mappable expression component list associated with a given
1003   /// declaration and initialize it with the provided list of components.
1004   void addMappableExpressionComponents(
1005       const ValueDecl *VD,
1006       OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
1007       OpenMPClauseKind WhereFoundClauseKind) {
1008     MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
1009     // Create new entry and append the new components there.
1010     MEC.Components.resize(MEC.Components.size() + 1);
1011     MEC.Components.back().append(Components.begin(), Components.end());
1012     MEC.Kind = WhereFoundClauseKind;
1013   }
1014 
1015   unsigned getNestingLevel() const {
1016     assert(!isStackEmpty());
1017     return getStackSize() - 1;
1018   }
1019   void addDoacrossDependClause(OMPDependClause *C,
1020                                const OperatorOffsetTy &OpsOffs) {
1021     SharingMapTy *Parent = getSecondOnStackOrNull();
1022     assert(Parent && isOpenMPWorksharingDirective(Parent->Directive));
1023     Parent->DoacrossDepends.try_emplace(C, OpsOffs);
1024   }
1025   llvm::iterator_range<DoacrossDependMapTy::const_iterator>
1026   getDoacrossDependClauses() const {
1027     const SharingMapTy &StackElem = getTopOfStack();
1028     if (isOpenMPWorksharingDirective(StackElem.Directive)) {
1029       const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
1030       return llvm::make_range(Ref.begin(), Ref.end());
1031     }
1032     return llvm::make_range(StackElem.DoacrossDepends.end(),
1033                             StackElem.DoacrossDepends.end());
1034   }
1035 
1036   // Store types of classes which have been explicitly mapped
1037   void addMappedClassesQualTypes(QualType QT) {
1038     SharingMapTy &StackElem = getTopOfStack();
1039     StackElem.MappedClassesQualTypes.insert(QT);
1040   }
1041 
1042   // Return set of mapped classes types
1043   bool isClassPreviouslyMapped(QualType QT) const {
1044     const SharingMapTy &StackElem = getTopOfStack();
1045     return StackElem.MappedClassesQualTypes.contains(QT);
1046   }
1047 
1048   /// Adds global declare target to the parent target region.
1049   void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) {
1050     assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
1051                E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
1052            "Expected declare target link global.");
1053     for (auto &Elem : *this) {
1054       if (isOpenMPTargetExecutionDirective(Elem.Directive)) {
1055         Elem.DeclareTargetLinkVarDecls.push_back(E);
1056         return;
1057       }
1058     }
1059   }
1060 
1061   /// Returns the list of globals with declare target link if current directive
1062   /// is target.
1063   ArrayRef<DeclRefExpr *> getLinkGlobals() const {
1064     assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) &&
1065            "Expected target executable directive.");
1066     return getTopOfStack().DeclareTargetLinkVarDecls;
1067   }
1068 
1069   /// Adds list of allocators expressions.
1070   void addInnerAllocatorExpr(Expr *E) {
1071     getTopOfStack().InnerUsedAllocators.push_back(E);
1072   }
1073   /// Return list of used allocators.
1074   ArrayRef<Expr *> getInnerAllocators() const {
1075     return getTopOfStack().InnerUsedAllocators;
1076   }
1077   /// Marks the declaration as implicitly firstprivate nin the task-based
1078   /// regions.
1079   void addImplicitTaskFirstprivate(unsigned Level, Decl *D) {
1080     getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D);
1081   }
1082   /// Checks if the decl is implicitly firstprivate in the task-based region.
1083   bool isImplicitTaskFirstprivate(Decl *D) const {
1084     return getTopOfStack().ImplicitTaskFirstprivates.contains(D);
1085   }
1086 
1087   /// Marks decl as used in uses_allocators clause as the allocator.
1088   void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) {
1089     getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind);
1090   }
1091   /// Checks if specified decl is used in uses allocator clause as the
1092   /// allocator.
1093   Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(unsigned Level,
1094                                                         const Decl *D) const {
1095     const SharingMapTy &StackElem = getTopOfStack();
1096     auto I = StackElem.UsesAllocatorsDecls.find(D);
1097     if (I == StackElem.UsesAllocatorsDecls.end())
1098       return None;
1099     return I->getSecond();
1100   }
1101   Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(const Decl *D) const {
1102     const SharingMapTy &StackElem = getTopOfStack();
1103     auto I = StackElem.UsesAllocatorsDecls.find(D);
1104     if (I == StackElem.UsesAllocatorsDecls.end())
1105       return None;
1106     return I->getSecond();
1107   }
1108 
1109   void addDeclareMapperVarRef(Expr *Ref) {
1110     SharingMapTy &StackElem = getTopOfStack();
1111     StackElem.DeclareMapperVar = Ref;
1112   }
1113   const Expr *getDeclareMapperVarRef() const {
1114     const SharingMapTy *Top = getTopOfStackOrNull();
1115     return Top ? Top->DeclareMapperVar : nullptr;
1116   }
1117 };
1118 
1119 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1120   return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
1121 }
1122 
1123 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1124   return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) ||
1125          DKind == OMPD_unknown;
1126 }
1127 
1128 } // namespace
1129 
1130 static const Expr *getExprAsWritten(const Expr *E) {
1131   if (const auto *FE = dyn_cast<FullExpr>(E))
1132     E = FE->getSubExpr();
1133 
1134   if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
1135     E = MTE->getSubExpr();
1136 
1137   while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
1138     E = Binder->getSubExpr();
1139 
1140   if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
1141     E = ICE->getSubExprAsWritten();
1142   return E->IgnoreParens();
1143 }
1144 
1145 static Expr *getExprAsWritten(Expr *E) {
1146   return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
1147 }
1148 
1149 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
1150   if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
1151     if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
1152       D = ME->getMemberDecl();
1153   const auto *VD = dyn_cast<VarDecl>(D);
1154   const auto *FD = dyn_cast<FieldDecl>(D);
1155   if (VD != nullptr) {
1156     VD = VD->getCanonicalDecl();
1157     D = VD;
1158   } else {
1159     assert(FD);
1160     FD = FD->getCanonicalDecl();
1161     D = FD;
1162   }
1163   return D;
1164 }
1165 
1166 static ValueDecl *getCanonicalDecl(ValueDecl *D) {
1167   return const_cast<ValueDecl *>(
1168       getCanonicalDecl(const_cast<const ValueDecl *>(D)));
1169 }
1170 
1171 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
1172                                           ValueDecl *D) const {
1173   D = getCanonicalDecl(D);
1174   auto *VD = dyn_cast<VarDecl>(D);
1175   const auto *FD = dyn_cast<FieldDecl>(D);
1176   DSAVarData DVar;
1177   if (Iter == end()) {
1178     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1179     // in a region but not in construct]
1180     //  File-scope or namespace-scope variables referenced in called routines
1181     //  in the region are shared unless they appear in a threadprivate
1182     //  directive.
1183     if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
1184       DVar.CKind = OMPC_shared;
1185 
1186     // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
1187     // in a region but not in construct]
1188     //  Variables with static storage duration that are declared in called
1189     //  routines in the region are shared.
1190     if (VD && VD->hasGlobalStorage())
1191       DVar.CKind = OMPC_shared;
1192 
1193     // Non-static data members are shared by default.
1194     if (FD)
1195       DVar.CKind = OMPC_shared;
1196 
1197     return DVar;
1198   }
1199 
1200   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1201   // in a Construct, C/C++, predetermined, p.1]
1202   // Variables with automatic storage duration that are declared in a scope
1203   // inside the construct are private.
1204   if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
1205       (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
1206     DVar.CKind = OMPC_private;
1207     return DVar;
1208   }
1209 
1210   DVar.DKind = Iter->Directive;
1211   // Explicitly specified attributes and local variables with predetermined
1212   // attributes.
1213   if (Iter->SharingMap.count(D)) {
1214     const DSAInfo &Data = Iter->SharingMap.lookup(D);
1215     DVar.RefExpr = Data.RefExpr.getPointer();
1216     DVar.PrivateCopy = Data.PrivateCopy;
1217     DVar.CKind = Data.Attributes;
1218     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1219     DVar.Modifier = Data.Modifier;
1220     DVar.AppliedToPointee = Data.AppliedToPointee;
1221     return DVar;
1222   }
1223 
1224   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1225   // in a Construct, C/C++, implicitly determined, p.1]
1226   //  In a parallel or task construct, the data-sharing attributes of these
1227   //  variables are determined by the default clause, if present.
1228   switch (Iter->DefaultAttr) {
1229   case DSA_shared:
1230     DVar.CKind = OMPC_shared;
1231     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1232     return DVar;
1233   case DSA_none:
1234     return DVar;
1235   case DSA_firstprivate:
1236     if (VD->getStorageDuration() == SD_Static &&
1237         VD->getDeclContext()->isFileContext()) {
1238       DVar.CKind = OMPC_unknown;
1239     } else {
1240       DVar.CKind = OMPC_firstprivate;
1241     }
1242     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1243     return DVar;
1244   case DSA_unspecified:
1245     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1246     // in a Construct, implicitly determined, p.2]
1247     //  In a parallel construct, if no default clause is present, these
1248     //  variables are shared.
1249     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1250     if ((isOpenMPParallelDirective(DVar.DKind) &&
1251          !isOpenMPTaskLoopDirective(DVar.DKind)) ||
1252         isOpenMPTeamsDirective(DVar.DKind)) {
1253       DVar.CKind = OMPC_shared;
1254       return DVar;
1255     }
1256 
1257     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1258     // in a Construct, implicitly determined, p.4]
1259     //  In a task construct, if no default clause is present, a variable that in
1260     //  the enclosing context is determined to be shared by all implicit tasks
1261     //  bound to the current team is shared.
1262     if (isOpenMPTaskingDirective(DVar.DKind)) {
1263       DSAVarData DVarTemp;
1264       const_iterator I = Iter, E = end();
1265       do {
1266         ++I;
1267         // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
1268         // Referenced in a Construct, implicitly determined, p.6]
1269         //  In a task construct, if no default clause is present, a variable
1270         //  whose data-sharing attribute is not determined by the rules above is
1271         //  firstprivate.
1272         DVarTemp = getDSA(I, D);
1273         if (DVarTemp.CKind != OMPC_shared) {
1274           DVar.RefExpr = nullptr;
1275           DVar.CKind = OMPC_firstprivate;
1276           return DVar;
1277         }
1278       } while (I != E && !isImplicitTaskingRegion(I->Directive));
1279       DVar.CKind =
1280           (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1281       return DVar;
1282     }
1283   }
1284   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1285   // in a Construct, implicitly determined, p.3]
1286   //  For constructs other than task, if no default clause is present, these
1287   //  variables inherit their data-sharing attributes from the enclosing
1288   //  context.
1289   return getDSA(++Iter, D);
1290 }
1291 
1292 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
1293                                          const Expr *NewDE) {
1294   assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1295   D = getCanonicalDecl(D);
1296   SharingMapTy &StackElem = getTopOfStack();
1297   auto It = StackElem.AlignedMap.find(D);
1298   if (It == StackElem.AlignedMap.end()) {
1299     assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1300     StackElem.AlignedMap[D] = NewDE;
1301     return nullptr;
1302   }
1303   assert(It->second && "Unexpected nullptr expr in the aligned map");
1304   return It->second;
1305 }
1306 
1307 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D,
1308                                              const Expr *NewDE) {
1309   assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1310   D = getCanonicalDecl(D);
1311   SharingMapTy &StackElem = getTopOfStack();
1312   auto It = StackElem.NontemporalMap.find(D);
1313   if (It == StackElem.NontemporalMap.end()) {
1314     assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1315     StackElem.NontemporalMap[D] = NewDE;
1316     return nullptr;
1317   }
1318   assert(It->second && "Unexpected nullptr expr in the aligned map");
1319   return It->second;
1320 }
1321 
1322 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
1323   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1324   D = getCanonicalDecl(D);
1325   SharingMapTy &StackElem = getTopOfStack();
1326   StackElem.LCVMap.try_emplace(
1327       D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
1328 }
1329 
1330 const DSAStackTy::LCDeclInfo
1331 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
1332   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1333   D = getCanonicalDecl(D);
1334   const SharingMapTy &StackElem = getTopOfStack();
1335   auto It = StackElem.LCVMap.find(D);
1336   if (It != StackElem.LCVMap.end())
1337     return It->second;
1338   return {0, nullptr};
1339 }
1340 
1341 const DSAStackTy::LCDeclInfo
1342 DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const {
1343   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1344   D = getCanonicalDecl(D);
1345   for (unsigned I = Level + 1; I > 0; --I) {
1346     const SharingMapTy &StackElem = getStackElemAtLevel(I - 1);
1347     auto It = StackElem.LCVMap.find(D);
1348     if (It != StackElem.LCVMap.end())
1349       return It->second;
1350   }
1351   return {0, nullptr};
1352 }
1353 
1354 const DSAStackTy::LCDeclInfo
1355 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
1356   const SharingMapTy *Parent = getSecondOnStackOrNull();
1357   assert(Parent && "Data-sharing attributes stack is empty");
1358   D = getCanonicalDecl(D);
1359   auto It = Parent->LCVMap.find(D);
1360   if (It != Parent->LCVMap.end())
1361     return It->second;
1362   return {0, nullptr};
1363 }
1364 
1365 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
1366   const SharingMapTy *Parent = getSecondOnStackOrNull();
1367   assert(Parent && "Data-sharing attributes stack is empty");
1368   if (Parent->LCVMap.size() < I)
1369     return nullptr;
1370   for (const auto &Pair : Parent->LCVMap)
1371     if (Pair.second.first == I)
1372       return Pair.first;
1373   return nullptr;
1374 }
1375 
1376 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
1377                         DeclRefExpr *PrivateCopy, unsigned Modifier,
1378                         bool AppliedToPointee) {
1379   D = getCanonicalDecl(D);
1380   if (A == OMPC_threadprivate) {
1381     DSAInfo &Data = Threadprivates[D];
1382     Data.Attributes = A;
1383     Data.RefExpr.setPointer(E);
1384     Data.PrivateCopy = nullptr;
1385     Data.Modifier = Modifier;
1386   } else {
1387     DSAInfo &Data = getTopOfStack().SharingMap[D];
1388     assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
1389            (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
1390            (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
1391            (isLoopControlVariable(D).first && A == OMPC_private));
1392     Data.Modifier = Modifier;
1393     if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
1394       Data.RefExpr.setInt(/*IntVal=*/true);
1395       return;
1396     }
1397     const bool IsLastprivate =
1398         A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
1399     Data.Attributes = A;
1400     Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1401     Data.PrivateCopy = PrivateCopy;
1402     Data.AppliedToPointee = AppliedToPointee;
1403     if (PrivateCopy) {
1404       DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()];
1405       Data.Modifier = Modifier;
1406       Data.Attributes = A;
1407       Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1408       Data.PrivateCopy = nullptr;
1409       Data.AppliedToPointee = AppliedToPointee;
1410     }
1411   }
1412 }
1413 
1414 /// Build a variable declaration for OpenMP loop iteration variable.
1415 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
1416                              StringRef Name, const AttrVec *Attrs = nullptr,
1417                              DeclRefExpr *OrigRef = nullptr) {
1418   DeclContext *DC = SemaRef.CurContext;
1419   IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
1420   TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
1421   auto *Decl =
1422       VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
1423   if (Attrs) {
1424     for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
1425          I != E; ++I)
1426       Decl->addAttr(*I);
1427   }
1428   Decl->setImplicit();
1429   if (OrigRef) {
1430     Decl->addAttr(
1431         OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
1432   }
1433   return Decl;
1434 }
1435 
1436 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
1437                                      SourceLocation Loc,
1438                                      bool RefersToCapture = false) {
1439   D->setReferenced();
1440   D->markUsed(S.Context);
1441   return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
1442                              SourceLocation(), D, RefersToCapture, Loc, Ty,
1443                              VK_LValue);
1444 }
1445 
1446 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1447                                            BinaryOperatorKind BOK) {
1448   D = getCanonicalDecl(D);
1449   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1450   assert(
1451       getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1452       "Additional reduction info may be specified only for reduction items.");
1453   ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1454   assert(ReductionData.ReductionRange.isInvalid() &&
1455          (getTopOfStack().Directive == OMPD_taskgroup ||
1456           ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1457             isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1458            !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1459          "Additional reduction info may be specified only once for reduction "
1460          "items.");
1461   ReductionData.set(BOK, SR);
1462   Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1463   if (!TaskgroupReductionRef) {
1464     VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1465                                SemaRef.Context.VoidPtrTy, ".task_red.");
1466     TaskgroupReductionRef =
1467         buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1468   }
1469 }
1470 
1471 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1472                                            const Expr *ReductionRef) {
1473   D = getCanonicalDecl(D);
1474   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1475   assert(
1476       getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1477       "Additional reduction info may be specified only for reduction items.");
1478   ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1479   assert(ReductionData.ReductionRange.isInvalid() &&
1480          (getTopOfStack().Directive == OMPD_taskgroup ||
1481           ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1482             isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1483            !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1484          "Additional reduction info may be specified only once for reduction "
1485          "items.");
1486   ReductionData.set(ReductionRef, SR);
1487   Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef;
1488   if (!TaskgroupReductionRef) {
1489     VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1490                                SemaRef.Context.VoidPtrTy, ".task_red.");
1491     TaskgroupReductionRef =
1492         buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1493   }
1494 }
1495 
1496 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1497     const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
1498     Expr *&TaskgroupDescriptor) const {
1499   D = getCanonicalDecl(D);
1500   assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1501   for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1502     const DSAInfo &Data = I->SharingMap.lookup(D);
1503     if (Data.Attributes != OMPC_reduction ||
1504         Data.Modifier != OMPC_REDUCTION_task)
1505       continue;
1506     const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1507     if (!ReductionData.ReductionOp ||
1508         ReductionData.ReductionOp.is<const Expr *>())
1509       return DSAVarData();
1510     SR = ReductionData.ReductionRange;
1511     BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1512     assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1513                                        "expression for the descriptor is not "
1514                                        "set.");
1515     TaskgroupDescriptor = I->TaskgroupReductionRef;
1516     return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1517                       Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1518                       /*AppliedToPointee=*/false);
1519   }
1520   return DSAVarData();
1521 }
1522 
1523 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1524     const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
1525     Expr *&TaskgroupDescriptor) const {
1526   D = getCanonicalDecl(D);
1527   assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1528   for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1529     const DSAInfo &Data = I->SharingMap.lookup(D);
1530     if (Data.Attributes != OMPC_reduction ||
1531         Data.Modifier != OMPC_REDUCTION_task)
1532       continue;
1533     const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1534     if (!ReductionData.ReductionOp ||
1535         !ReductionData.ReductionOp.is<const Expr *>())
1536       return DSAVarData();
1537     SR = ReductionData.ReductionRange;
1538     ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
1539     assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1540                                        "expression for the descriptor is not "
1541                                        "set.");
1542     TaskgroupDescriptor = I->TaskgroupReductionRef;
1543     return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1544                       Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1545                       /*AppliedToPointee=*/false);
1546   }
1547   return DSAVarData();
1548 }
1549 
1550 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const {
1551   D = D->getCanonicalDecl();
1552   for (const_iterator E = end(); I != E; ++I) {
1553     if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1554         isOpenMPTargetExecutionDirective(I->Directive)) {
1555       if (I->CurScope) {
1556         Scope *TopScope = I->CurScope->getParent();
1557         Scope *CurScope = getCurScope();
1558         while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D))
1559           CurScope = CurScope->getParent();
1560         return CurScope != TopScope;
1561       }
1562       for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent())
1563         if (I->Context == DC)
1564           return true;
1565       return false;
1566     }
1567   }
1568   return false;
1569 }
1570 
1571 static bool isConstNotMutableType(Sema &SemaRef, QualType Type,
1572                                   bool AcceptIfMutable = true,
1573                                   bool *IsClassType = nullptr) {
1574   ASTContext &Context = SemaRef.getASTContext();
1575   Type = Type.getNonReferenceType().getCanonicalType();
1576   bool IsConstant = Type.isConstant(Context);
1577   Type = Context.getBaseElementType(Type);
1578   const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus
1579                                 ? Type->getAsCXXRecordDecl()
1580                                 : nullptr;
1581   if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1582     if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1583       RD = CTD->getTemplatedDecl();
1584   if (IsClassType)
1585     *IsClassType = RD;
1586   return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD &&
1587                          RD->hasDefinition() && RD->hasMutableFields());
1588 }
1589 
1590 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D,
1591                                       QualType Type, OpenMPClauseKind CKind,
1592                                       SourceLocation ELoc,
1593                                       bool AcceptIfMutable = true,
1594                                       bool ListItemNotVar = false) {
1595   ASTContext &Context = SemaRef.getASTContext();
1596   bool IsClassType;
1597   if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) {
1598     unsigned Diag = ListItemNotVar ? diag::err_omp_const_list_item
1599                     : IsClassType  ? diag::err_omp_const_not_mutable_variable
1600                                    : diag::err_omp_const_variable;
1601     SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind);
1602     if (!ListItemNotVar && D) {
1603       const VarDecl *VD = dyn_cast<VarDecl>(D);
1604       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
1605                                VarDecl::DeclarationOnly;
1606       SemaRef.Diag(D->getLocation(),
1607                    IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1608           << D;
1609     }
1610     return true;
1611   }
1612   return false;
1613 }
1614 
1615 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1616                                                    bool FromParent) {
1617   D = getCanonicalDecl(D);
1618   DSAVarData DVar;
1619 
1620   auto *VD = dyn_cast<VarDecl>(D);
1621   auto TI = Threadprivates.find(D);
1622   if (TI != Threadprivates.end()) {
1623     DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1624     DVar.CKind = OMPC_threadprivate;
1625     DVar.Modifier = TI->getSecond().Modifier;
1626     return DVar;
1627   }
1628   if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1629     DVar.RefExpr = buildDeclRefExpr(
1630         SemaRef, VD, D->getType().getNonReferenceType(),
1631         VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1632     DVar.CKind = OMPC_threadprivate;
1633     addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1634     return DVar;
1635   }
1636   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1637   // in a Construct, C/C++, predetermined, p.1]
1638   //  Variables appearing in threadprivate directives are threadprivate.
1639   if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1640        !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1641          SemaRef.getLangOpts().OpenMPUseTLS &&
1642          SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1643       (VD && VD->getStorageClass() == SC_Register &&
1644        VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1645     DVar.RefExpr = buildDeclRefExpr(
1646         SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1647     DVar.CKind = OMPC_threadprivate;
1648     addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1649     return DVar;
1650   }
1651   if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1652       VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1653       !isLoopControlVariable(D).first) {
1654     const_iterator IterTarget =
1655         std::find_if(begin(), end(), [](const SharingMapTy &Data) {
1656           return isOpenMPTargetExecutionDirective(Data.Directive);
1657         });
1658     if (IterTarget != end()) {
1659       const_iterator ParentIterTarget = IterTarget + 1;
1660       for (const_iterator Iter = begin(); Iter != ParentIterTarget; ++Iter) {
1661         if (isOpenMPLocal(VD, Iter)) {
1662           DVar.RefExpr =
1663               buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1664                                D->getLocation());
1665           DVar.CKind = OMPC_threadprivate;
1666           return DVar;
1667         }
1668       }
1669       if (!isClauseParsingMode() || IterTarget != begin()) {
1670         auto DSAIter = IterTarget->SharingMap.find(D);
1671         if (DSAIter != IterTarget->SharingMap.end() &&
1672             isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1673           DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1674           DVar.CKind = OMPC_threadprivate;
1675           return DVar;
1676         }
1677         const_iterator End = end();
1678         if (!SemaRef.isOpenMPCapturedByRef(D,
1679                                            std::distance(ParentIterTarget, End),
1680                                            /*OpenMPCaptureLevel=*/0)) {
1681           DVar.RefExpr =
1682               buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1683                                IterTarget->ConstructLoc);
1684           DVar.CKind = OMPC_threadprivate;
1685           return DVar;
1686         }
1687       }
1688     }
1689   }
1690 
1691   if (isStackEmpty())
1692     // Not in OpenMP execution region and top scope was already checked.
1693     return DVar;
1694 
1695   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1696   // in a Construct, C/C++, predetermined, p.4]
1697   //  Static data members are shared.
1698   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1699   // in a Construct, C/C++, predetermined, p.7]
1700   //  Variables with static storage duration that are declared in a scope
1701   //  inside the construct are shared.
1702   if (VD && VD->isStaticDataMember()) {
1703     // Check for explicitly specified attributes.
1704     const_iterator I = begin();
1705     const_iterator EndI = end();
1706     if (FromParent && I != EndI)
1707       ++I;
1708     if (I != EndI) {
1709       auto It = I->SharingMap.find(D);
1710       if (It != I->SharingMap.end()) {
1711         const DSAInfo &Data = It->getSecond();
1712         DVar.RefExpr = Data.RefExpr.getPointer();
1713         DVar.PrivateCopy = Data.PrivateCopy;
1714         DVar.CKind = Data.Attributes;
1715         DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1716         DVar.DKind = I->Directive;
1717         DVar.Modifier = Data.Modifier;
1718         DVar.AppliedToPointee = Data.AppliedToPointee;
1719         return DVar;
1720       }
1721     }
1722 
1723     DVar.CKind = OMPC_shared;
1724     return DVar;
1725   }
1726 
1727   auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
1728   // The predetermined shared attribute for const-qualified types having no
1729   // mutable members was removed after OpenMP 3.1.
1730   if (SemaRef.LangOpts.OpenMP <= 31) {
1731     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1732     // in a Construct, C/C++, predetermined, p.6]
1733     //  Variables with const qualified type having no mutable member are
1734     //  shared.
1735     if (isConstNotMutableType(SemaRef, D->getType())) {
1736       // Variables with const-qualified type having no mutable member may be
1737       // listed in a firstprivate clause, even if they are static data members.
1738       DSAVarData DVarTemp = hasInnermostDSA(
1739           D,
1740           [](OpenMPClauseKind C, bool) {
1741             return C == OMPC_firstprivate || C == OMPC_shared;
1742           },
1743           MatchesAlways, FromParent);
1744       if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1745         return DVarTemp;
1746 
1747       DVar.CKind = OMPC_shared;
1748       return DVar;
1749     }
1750   }
1751 
1752   // Explicitly specified attributes and local variables with predetermined
1753   // attributes.
1754   const_iterator I = begin();
1755   const_iterator EndI = end();
1756   if (FromParent && I != EndI)
1757     ++I;
1758   if (I == EndI)
1759     return DVar;
1760   auto It = I->SharingMap.find(D);
1761   if (It != I->SharingMap.end()) {
1762     const DSAInfo &Data = It->getSecond();
1763     DVar.RefExpr = Data.RefExpr.getPointer();
1764     DVar.PrivateCopy = Data.PrivateCopy;
1765     DVar.CKind = Data.Attributes;
1766     DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1767     DVar.DKind = I->Directive;
1768     DVar.Modifier = Data.Modifier;
1769     DVar.AppliedToPointee = Data.AppliedToPointee;
1770   }
1771 
1772   return DVar;
1773 }
1774 
1775 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1776                                                         bool FromParent) const {
1777   if (isStackEmpty()) {
1778     const_iterator I;
1779     return getDSA(I, D);
1780   }
1781   D = getCanonicalDecl(D);
1782   const_iterator StartI = begin();
1783   const_iterator EndI = end();
1784   if (FromParent && StartI != EndI)
1785     ++StartI;
1786   return getDSA(StartI, D);
1787 }
1788 
1789 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1790                                                         unsigned Level) const {
1791   if (getStackSize() <= Level)
1792     return DSAVarData();
1793   D = getCanonicalDecl(D);
1794   const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level);
1795   return getDSA(StartI, D);
1796 }
1797 
1798 const DSAStackTy::DSAVarData
1799 DSAStackTy::hasDSA(ValueDecl *D,
1800                    const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1801                    const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1802                    bool FromParent) const {
1803   if (isStackEmpty())
1804     return {};
1805   D = getCanonicalDecl(D);
1806   const_iterator I = begin();
1807   const_iterator EndI = end();
1808   if (FromParent && I != EndI)
1809     ++I;
1810   for (; I != EndI; ++I) {
1811     if (!DPred(I->Directive) &&
1812         !isImplicitOrExplicitTaskingRegion(I->Directive))
1813       continue;
1814     const_iterator NewI = I;
1815     DSAVarData DVar = getDSA(NewI, D);
1816     if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee))
1817       return DVar;
1818   }
1819   return {};
1820 }
1821 
1822 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1823     ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1824     const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1825     bool FromParent) const {
1826   if (isStackEmpty())
1827     return {};
1828   D = getCanonicalDecl(D);
1829   const_iterator StartI = begin();
1830   const_iterator EndI = end();
1831   if (FromParent && StartI != EndI)
1832     ++StartI;
1833   if (StartI == EndI || !DPred(StartI->Directive))
1834     return {};
1835   const_iterator NewI = StartI;
1836   DSAVarData DVar = getDSA(NewI, D);
1837   return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee))
1838              ? DVar
1839              : DSAVarData();
1840 }
1841 
1842 bool DSAStackTy::hasExplicitDSA(
1843     const ValueDecl *D,
1844     const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1845     unsigned Level, bool NotLastprivate) const {
1846   if (getStackSize() <= Level)
1847     return false;
1848   D = getCanonicalDecl(D);
1849   const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1850   auto I = StackElem.SharingMap.find(D);
1851   if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() &&
1852       CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) &&
1853       (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1854     return true;
1855   // Check predetermined rules for the loop control variables.
1856   auto LI = StackElem.LCVMap.find(D);
1857   if (LI != StackElem.LCVMap.end())
1858     return CPred(OMPC_private, /*AppliedToPointee=*/false);
1859   return false;
1860 }
1861 
1862 bool DSAStackTy::hasExplicitDirective(
1863     const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1864     unsigned Level) const {
1865   if (getStackSize() <= Level)
1866     return false;
1867   const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1868   return DPred(StackElem.Directive);
1869 }
1870 
1871 bool DSAStackTy::hasDirective(
1872     const llvm::function_ref<bool(OpenMPDirectiveKind,
1873                                   const DeclarationNameInfo &, SourceLocation)>
1874         DPred,
1875     bool FromParent) const {
1876   // We look only in the enclosing region.
1877   size_t Skip = FromParent ? 2 : 1;
1878   for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
1879        I != E; ++I) {
1880     if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1881       return true;
1882   }
1883   return false;
1884 }
1885 
1886 void Sema::InitDataSharingAttributesStack() {
1887   VarDataSharingAttributesStack = new DSAStackTy(*this);
1888 }
1889 
1890 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1891 
1892 void Sema::pushOpenMPFunctionRegion() { DSAStack->pushFunction(); }
1893 
1894 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
1895   DSAStack->popFunction(OldFSI);
1896 }
1897 
1898 static bool isOpenMPDeviceDelayedContext(Sema &S) {
1899   assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice &&
1900          "Expected OpenMP device compilation.");
1901   return !S.isInOpenMPTargetExecutionDirective();
1902 }
1903 
1904 namespace {
1905 /// Status of the function emission on the host/device.
1906 enum class FunctionEmissionStatus {
1907   Emitted,
1908   Discarded,
1909   Unknown,
1910 };
1911 } // anonymous namespace
1912 
1913 Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc,
1914                                                          unsigned DiagID,
1915                                                          FunctionDecl *FD) {
1916   assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
1917          "Expected OpenMP device compilation.");
1918 
1919   SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
1920   if (FD) {
1921     FunctionEmissionStatus FES = getEmissionStatus(FD);
1922     switch (FES) {
1923     case FunctionEmissionStatus::Emitted:
1924       Kind = SemaDiagnosticBuilder::K_Immediate;
1925       break;
1926     case FunctionEmissionStatus::Unknown:
1927       // TODO: We should always delay diagnostics here in case a target
1928       //       region is in a function we do not emit. However, as the
1929       //       current diagnostics are associated with the function containing
1930       //       the target region and we do not emit that one, we would miss out
1931       //       on diagnostics for the target region itself. We need to anchor
1932       //       the diagnostics with the new generated function *or* ensure we
1933       //       emit diagnostics associated with the surrounding function.
1934       Kind = isOpenMPDeviceDelayedContext(*this)
1935                  ? SemaDiagnosticBuilder::K_Deferred
1936                  : SemaDiagnosticBuilder::K_Immediate;
1937       break;
1938     case FunctionEmissionStatus::TemplateDiscarded:
1939     case FunctionEmissionStatus::OMPDiscarded:
1940       Kind = SemaDiagnosticBuilder::K_Nop;
1941       break;
1942     case FunctionEmissionStatus::CUDADiscarded:
1943       llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation");
1944       break;
1945     }
1946   }
1947 
1948   return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this);
1949 }
1950 
1951 Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc,
1952                                                        unsigned DiagID,
1953                                                        FunctionDecl *FD) {
1954   assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice &&
1955          "Expected OpenMP host compilation.");
1956 
1957   SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
1958   if (FD) {
1959     FunctionEmissionStatus FES = getEmissionStatus(FD);
1960     switch (FES) {
1961     case FunctionEmissionStatus::Emitted:
1962       Kind = SemaDiagnosticBuilder::K_Immediate;
1963       break;
1964     case FunctionEmissionStatus::Unknown:
1965       Kind = SemaDiagnosticBuilder::K_Deferred;
1966       break;
1967     case FunctionEmissionStatus::TemplateDiscarded:
1968     case FunctionEmissionStatus::OMPDiscarded:
1969     case FunctionEmissionStatus::CUDADiscarded:
1970       Kind = SemaDiagnosticBuilder::K_Nop;
1971       break;
1972     }
1973   }
1974 
1975   return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this);
1976 }
1977 
1978 static OpenMPDefaultmapClauseKind
1979 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) {
1980   if (LO.OpenMP <= 45) {
1981     if (VD->getType().getNonReferenceType()->isScalarType())
1982       return OMPC_DEFAULTMAP_scalar;
1983     return OMPC_DEFAULTMAP_aggregate;
1984   }
1985   if (VD->getType().getNonReferenceType()->isAnyPointerType())
1986     return OMPC_DEFAULTMAP_pointer;
1987   if (VD->getType().getNonReferenceType()->isScalarType())
1988     return OMPC_DEFAULTMAP_scalar;
1989   return OMPC_DEFAULTMAP_aggregate;
1990 }
1991 
1992 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
1993                                  unsigned OpenMPCaptureLevel) const {
1994   assert(LangOpts.OpenMP && "OpenMP is not allowed");
1995 
1996   ASTContext &Ctx = getASTContext();
1997   bool IsByRef = true;
1998 
1999   // Find the directive that is associated with the provided scope.
2000   D = cast<ValueDecl>(D->getCanonicalDecl());
2001   QualType Ty = D->getType();
2002 
2003   bool IsVariableUsedInMapClause = false;
2004   if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
2005     // This table summarizes how a given variable should be passed to the device
2006     // given its type and the clauses where it appears. This table is based on
2007     // the description in OpenMP 4.5 [2.10.4, target Construct] and
2008     // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
2009     //
2010     // =========================================================================
2011     // | type |  defaultmap   | pvt | first | is_device_ptr |    map   | res.  |
2012     // |      |(tofrom:scalar)|     |  pvt  |               |          |       |
2013     // =========================================================================
2014     // | scl  |               |     |       |       -       |          | bycopy|
2015     // | scl  |               |  -  |   x   |       -       |     -    | bycopy|
2016     // | scl  |               |  x  |   -   |       -       |     -    | null  |
2017     // | scl  |       x       |     |       |       -       |          | byref |
2018     // | scl  |       x       |  -  |   x   |       -       |     -    | bycopy|
2019     // | scl  |       x       |  x  |   -   |       -       |     -    | null  |
2020     // | scl  |               |  -  |   -   |       -       |     x    | byref |
2021     // | scl  |       x       |  -  |   -   |       -       |     x    | byref |
2022     //
2023     // | agg  |      n.a.     |     |       |       -       |          | byref |
2024     // | agg  |      n.a.     |  -  |   x   |       -       |     -    | byref |
2025     // | agg  |      n.a.     |  x  |   -   |       -       |     -    | null  |
2026     // | agg  |      n.a.     |  -  |   -   |       -       |     x    | byref |
2027     // | agg  |      n.a.     |  -  |   -   |       -       |    x[]   | byref |
2028     //
2029     // | ptr  |      n.a.     |     |       |       -       |          | bycopy|
2030     // | ptr  |      n.a.     |  -  |   x   |       -       |     -    | bycopy|
2031     // | ptr  |      n.a.     |  x  |   -   |       -       |     -    | null  |
2032     // | ptr  |      n.a.     |  -  |   -   |       -       |     x    | byref |
2033     // | ptr  |      n.a.     |  -  |   -   |       -       |    x[]   | bycopy|
2034     // | ptr  |      n.a.     |  -  |   -   |       x       |          | bycopy|
2035     // | ptr  |      n.a.     |  -  |   -   |       x       |     x    | bycopy|
2036     // | ptr  |      n.a.     |  -  |   -   |       x       |    x[]   | bycopy|
2037     // =========================================================================
2038     // Legend:
2039     //  scl - scalar
2040     //  ptr - pointer
2041     //  agg - aggregate
2042     //  x - applies
2043     //  - - invalid in this combination
2044     //  [] - mapped with an array section
2045     //  byref - should be mapped by reference
2046     //  byval - should be mapped by value
2047     //  null - initialize a local variable to null on the device
2048     //
2049     // Observations:
2050     //  - All scalar declarations that show up in a map clause have to be passed
2051     //    by reference, because they may have been mapped in the enclosing data
2052     //    environment.
2053     //  - If the scalar value does not fit the size of uintptr, it has to be
2054     //    passed by reference, regardless the result in the table above.
2055     //  - For pointers mapped by value that have either an implicit map or an
2056     //    array section, the runtime library may pass the NULL value to the
2057     //    device instead of the value passed to it by the compiler.
2058 
2059     if (Ty->isReferenceType())
2060       Ty = Ty->castAs<ReferenceType>()->getPointeeType();
2061 
2062     // Locate map clauses and see if the variable being captured is referred to
2063     // in any of those clauses. Here we only care about variables, not fields,
2064     // because fields are part of aggregates.
2065     bool IsVariableAssociatedWithSection = false;
2066 
2067     DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2068         D, Level,
2069         [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection,
2070          D](OMPClauseMappableExprCommon::MappableExprComponentListRef
2071                 MapExprComponents,
2072             OpenMPClauseKind WhereFoundClauseKind) {
2073           // Only the map clause information influences how a variable is
2074           // captured. E.g. is_device_ptr does not require changing the default
2075           // behavior.
2076           if (WhereFoundClauseKind != OMPC_map)
2077             return false;
2078 
2079           auto EI = MapExprComponents.rbegin();
2080           auto EE = MapExprComponents.rend();
2081 
2082           assert(EI != EE && "Invalid map expression!");
2083 
2084           if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2085             IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
2086 
2087           ++EI;
2088           if (EI == EE)
2089             return false;
2090 
2091           if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
2092               isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
2093               isa<MemberExpr>(EI->getAssociatedExpression()) ||
2094               isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) {
2095             IsVariableAssociatedWithSection = true;
2096             // There is nothing more we need to know about this variable.
2097             return true;
2098           }
2099 
2100           // Keep looking for more map info.
2101           return false;
2102         });
2103 
2104     if (IsVariableUsedInMapClause) {
2105       // If variable is identified in a map clause it is always captured by
2106       // reference except if it is a pointer that is dereferenced somehow.
2107       IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
2108     } else {
2109       // By default, all the data that has a scalar type is mapped by copy
2110       // (except for reduction variables).
2111       // Defaultmap scalar is mutual exclusive to defaultmap pointer
2112       IsByRef = (DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
2113                  !Ty->isAnyPointerType()) ||
2114                 !Ty->isScalarType() ||
2115                 DSAStack->isDefaultmapCapturedByRef(
2116                     Level, getVariableCategoryFromDecl(LangOpts, D)) ||
2117                 DSAStack->hasExplicitDSA(
2118                     D,
2119                     [](OpenMPClauseKind K, bool AppliedToPointee) {
2120                       return K == OMPC_reduction && !AppliedToPointee;
2121                     },
2122                     Level);
2123     }
2124   }
2125 
2126   if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
2127     IsByRef =
2128         ((IsVariableUsedInMapClause &&
2129           DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) ==
2130               OMPD_target) ||
2131          !(DSAStack->hasExplicitDSA(
2132                D,
2133                [](OpenMPClauseKind K, bool AppliedToPointee) -> bool {
2134                  return K == OMPC_firstprivate ||
2135                         (K == OMPC_reduction && AppliedToPointee);
2136                },
2137                Level, /*NotLastprivate=*/true) ||
2138            DSAStack->isUsesAllocatorsDecl(Level, D))) &&
2139         // If the variable is artificial and must be captured by value - try to
2140         // capture by value.
2141         !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
2142           !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) &&
2143         // If the variable is implicitly firstprivate and scalar - capture by
2144         // copy
2145         !(DSAStack->getDefaultDSA() == DSA_firstprivate &&
2146           !DSAStack->hasExplicitDSA(
2147               D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; },
2148               Level) &&
2149           !DSAStack->isLoopControlVariable(D, Level).first);
2150   }
2151 
2152   // When passing data by copy, we need to make sure it fits the uintptr size
2153   // and alignment, because the runtime library only deals with uintptr types.
2154   // If it does not fit the uintptr size, we need to pass the data by reference
2155   // instead.
2156   if (!IsByRef &&
2157       (Ctx.getTypeSizeInChars(Ty) >
2158            Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
2159        Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
2160     IsByRef = true;
2161   }
2162 
2163   return IsByRef;
2164 }
2165 
2166 unsigned Sema::getOpenMPNestingLevel() const {
2167   assert(getLangOpts().OpenMP);
2168   return DSAStack->getNestingLevel();
2169 }
2170 
2171 bool Sema::isInOpenMPTaskUntiedContext() const {
2172   return isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
2173          DSAStack->isUntiedRegion();
2174 }
2175 
2176 bool Sema::isInOpenMPTargetExecutionDirective() const {
2177   return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) &&
2178           !DSAStack->isClauseParsingMode()) ||
2179          DSAStack->hasDirective(
2180              [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2181                 SourceLocation) -> bool {
2182                return isOpenMPTargetExecutionDirective(K);
2183              },
2184              false);
2185 }
2186 
2187 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
2188                                     unsigned StopAt) {
2189   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2190   D = getCanonicalDecl(D);
2191 
2192   auto *VD = dyn_cast<VarDecl>(D);
2193   // Do not capture constexpr variables.
2194   if (VD && VD->isConstexpr())
2195     return nullptr;
2196 
2197   // If we want to determine whether the variable should be captured from the
2198   // perspective of the current capturing scope, and we've already left all the
2199   // capturing scopes of the top directive on the stack, check from the
2200   // perspective of its parent directive (if any) instead.
2201   DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2202       *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete());
2203 
2204   // If we are attempting to capture a global variable in a directive with
2205   // 'target' we return true so that this global is also mapped to the device.
2206   //
2207   if (VD && !VD->hasLocalStorage() &&
2208       (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
2209     if (isInOpenMPTargetExecutionDirective()) {
2210       DSAStackTy::DSAVarData DVarTop =
2211           DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
2212       if (DVarTop.CKind != OMPC_unknown && DVarTop.RefExpr)
2213         return VD;
2214       // If the declaration is enclosed in a 'declare target' directive,
2215       // then it should not be captured.
2216       //
2217       if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2218         return nullptr;
2219       CapturedRegionScopeInfo *CSI = nullptr;
2220       for (FunctionScopeInfo *FSI : llvm::drop_begin(
2221                llvm::reverse(FunctionScopes),
2222                CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) {
2223         if (!isa<CapturingScopeInfo>(FSI))
2224           return nullptr;
2225         if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2226           if (RSI->CapRegionKind == CR_OpenMP) {
2227             CSI = RSI;
2228             break;
2229           }
2230       }
2231       assert(CSI && "Failed to find CapturedRegionScopeInfo");
2232       SmallVector<OpenMPDirectiveKind, 4> Regions;
2233       getOpenMPCaptureRegions(Regions,
2234                               DSAStack->getDirective(CSI->OpenMPLevel));
2235       if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task)
2236         return VD;
2237     }
2238     if (isInOpenMPDeclareTargetContext()) {
2239       // Try to mark variable as declare target if it is used in capturing
2240       // regions.
2241       if (LangOpts.OpenMP <= 45 &&
2242           !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2243         checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
2244       return nullptr;
2245     }
2246   }
2247 
2248   if (CheckScopeInfo) {
2249     bool OpenMPFound = false;
2250     for (unsigned I = StopAt + 1; I > 0; --I) {
2251       FunctionScopeInfo *FSI = FunctionScopes[I - 1];
2252       if (!isa<CapturingScopeInfo>(FSI))
2253         return nullptr;
2254       if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2255         if (RSI->CapRegionKind == CR_OpenMP) {
2256           OpenMPFound = true;
2257           break;
2258         }
2259     }
2260     if (!OpenMPFound)
2261       return nullptr;
2262   }
2263 
2264   if (DSAStack->getCurrentDirective() != OMPD_unknown &&
2265       (!DSAStack->isClauseParsingMode() ||
2266        DSAStack->getParentDirective() != OMPD_unknown)) {
2267     auto &&Info = DSAStack->isLoopControlVariable(D);
2268     if (Info.first ||
2269         (VD && VD->hasLocalStorage() &&
2270          isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) ||
2271         (VD && DSAStack->isForceVarCapturing()))
2272       return VD ? VD : Info.second;
2273     DSAStackTy::DSAVarData DVarTop =
2274         DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
2275     if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) &&
2276         (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee))
2277       return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
2278     // Threadprivate variables must not be captured.
2279     if (isOpenMPThreadPrivate(DVarTop.CKind))
2280       return nullptr;
2281     // The variable is not private or it is the variable in the directive with
2282     // default(none) clause and not used in any clause.
2283     DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2284         D,
2285         [](OpenMPClauseKind C, bool AppliedToPointee) {
2286           return isOpenMPPrivate(C) && !AppliedToPointee;
2287         },
2288         [](OpenMPDirectiveKind) { return true; },
2289         DSAStack->isClauseParsingMode());
2290     // Global shared must not be captured.
2291     if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2292         ((DSAStack->getDefaultDSA() != DSA_none &&
2293           DSAStack->getDefaultDSA() != DSA_firstprivate) ||
2294          DVarTop.CKind == OMPC_shared))
2295       return nullptr;
2296     if (DVarPrivate.CKind != OMPC_unknown ||
2297         (VD && (DSAStack->getDefaultDSA() == DSA_none ||
2298                 DSAStack->getDefaultDSA() == DSA_firstprivate)))
2299       return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2300   }
2301   return nullptr;
2302 }
2303 
2304 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
2305                                         unsigned Level) const {
2306   FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2307 }
2308 
2309 void Sema::startOpenMPLoop() {
2310   assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2311   if (isOpenMPLoopDirective(DSAStack->getCurrentDirective()))
2312     DSAStack->loopInit();
2313 }
2314 
2315 void Sema::startOpenMPCXXRangeFor() {
2316   assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2317   if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2318     DSAStack->resetPossibleLoopCounter();
2319     DSAStack->loopStart();
2320   }
2321 }
2322 
2323 OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level,
2324                                            unsigned CapLevel) const {
2325   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2326   if (DSAStack->hasExplicitDirective(isOpenMPTaskingDirective, Level)) {
2327     bool IsTriviallyCopyable =
2328         D->getType().getNonReferenceType().isTriviallyCopyableType(Context) &&
2329         !D->getType()
2330              .getNonReferenceType()
2331              .getCanonicalType()
2332              ->getAsCXXRecordDecl();
2333     OpenMPDirectiveKind DKind = DSAStack->getDirective(Level);
2334     SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2335     getOpenMPCaptureRegions(CaptureRegions, DKind);
2336     if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) &&
2337         (IsTriviallyCopyable ||
2338          !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) {
2339       if (DSAStack->hasExplicitDSA(
2340               D,
2341               [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; },
2342               Level, /*NotLastprivate=*/true))
2343         return OMPC_firstprivate;
2344       DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2345       if (DVar.CKind != OMPC_shared &&
2346           !DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) {
2347         DSAStack->addImplicitTaskFirstprivate(Level, D);
2348         return OMPC_firstprivate;
2349       }
2350     }
2351   }
2352   if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2353     if (DSAStack->getAssociatedLoops() > 0 && !DSAStack->isLoopStarted()) {
2354       DSAStack->resetPossibleLoopCounter(D);
2355       DSAStack->loopStart();
2356       return OMPC_private;
2357     }
2358     if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
2359          DSAStack->isLoopControlVariable(D).first) &&
2360         !DSAStack->hasExplicitDSA(
2361             D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; },
2362             Level) &&
2363         !isOpenMPSimdDirective(DSAStack->getCurrentDirective()))
2364       return OMPC_private;
2365   }
2366   if (const auto *VD = dyn_cast<VarDecl>(D)) {
2367     if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2368         DSAStack->isForceVarCapturing() &&
2369         !DSAStack->hasExplicitDSA(
2370             D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; },
2371             Level))
2372       return OMPC_private;
2373   }
2374   // User-defined allocators are private since they must be defined in the
2375   // context of target region.
2376   if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) &&
2377       DSAStack->isUsesAllocatorsDecl(Level, D).getValueOr(
2378           DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2379           DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2380     return OMPC_private;
2381   return (DSAStack->hasExplicitDSA(
2382               D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; },
2383               Level) ||
2384           (DSAStack->isClauseParsingMode() &&
2385            DSAStack->getClauseParsingMode() == OMPC_private) ||
2386           // Consider taskgroup reduction descriptor variable a private
2387           // to avoid possible capture in the region.
2388           (DSAStack->hasExplicitDirective(
2389                [](OpenMPDirectiveKind K) {
2390                  return K == OMPD_taskgroup ||
2391                         ((isOpenMPParallelDirective(K) ||
2392                           isOpenMPWorksharingDirective(K)) &&
2393                          !isOpenMPSimdDirective(K));
2394                },
2395                Level) &&
2396            DSAStack->isTaskgroupReductionRef(D, Level)))
2397              ? OMPC_private
2398              : OMPC_unknown;
2399 }
2400 
2401 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
2402                                 unsigned Level) {
2403   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2404   D = getCanonicalDecl(D);
2405   OpenMPClauseKind OMPC = OMPC_unknown;
2406   for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) {
2407     const unsigned NewLevel = I - 1;
2408     if (DSAStack->hasExplicitDSA(
2409             D,
2410             [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) {
2411               if (isOpenMPPrivate(K) && !AppliedToPointee) {
2412                 OMPC = K;
2413                 return true;
2414               }
2415               return false;
2416             },
2417             NewLevel))
2418       break;
2419     if (DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2420             D, NewLevel,
2421             [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
2422                OpenMPClauseKind) { return true; })) {
2423       OMPC = OMPC_map;
2424       break;
2425     }
2426     if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2427                                        NewLevel)) {
2428       OMPC = OMPC_map;
2429       if (DSAStack->mustBeFirstprivateAtLevel(
2430               NewLevel, getVariableCategoryFromDecl(LangOpts, D)))
2431         OMPC = OMPC_firstprivate;
2432       break;
2433     }
2434   }
2435   if (OMPC != OMPC_unknown)
2436     FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC)));
2437 }
2438 
2439 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level,
2440                                       unsigned CaptureLevel) const {
2441   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2442   // Return true if the current level is no longer enclosed in a target region.
2443 
2444   SmallVector<OpenMPDirectiveKind, 4> Regions;
2445   getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level));
2446   const auto *VD = dyn_cast<VarDecl>(D);
2447   return VD && !VD->hasLocalStorage() &&
2448          DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2449                                         Level) &&
2450          Regions[CaptureLevel] != OMPD_task;
2451 }
2452 
2453 bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level,
2454                                       unsigned CaptureLevel) const {
2455   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2456   // Return true if the current level is no longer enclosed in a target region.
2457 
2458   if (const auto *VD = dyn_cast<VarDecl>(D)) {
2459     if (!VD->hasLocalStorage()) {
2460       if (isInOpenMPTargetExecutionDirective())
2461         return true;
2462       DSAStackTy::DSAVarData TopDVar =
2463           DSAStack->getTopDSA(D, /*FromParent=*/false);
2464       unsigned NumLevels =
2465           getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2466       if (Level == 0)
2467         return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared;
2468       do {
2469         --Level;
2470         DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2471         if (DVar.CKind != OMPC_shared)
2472           return true;
2473       } while (Level > 0);
2474     }
2475   }
2476   return true;
2477 }
2478 
2479 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
2480 
2481 void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,
2482                                           OMPTraitInfo &TI) {
2483   OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2484 }
2485 
2486 void Sema::ActOnOpenMPEndDeclareVariant() {
2487   assert(isInOpenMPDeclareVariantScope() &&
2488          "Not in OpenMP declare variant scope!");
2489 
2490   OMPDeclareVariantScopes.pop_back();
2491 }
2492 
2493 void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller,
2494                                          const FunctionDecl *Callee,
2495                                          SourceLocation Loc) {
2496   assert(LangOpts.OpenMP && "Expected OpenMP compilation mode.");
2497   Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2498       OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl());
2499   // Ignore host functions during device analyzis.
2500   if (LangOpts.OpenMPIsDevice &&
2501       (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host))
2502     return;
2503   // Ignore nohost functions during host analyzis.
2504   if (!LangOpts.OpenMPIsDevice && DevTy &&
2505       *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2506     return;
2507   const FunctionDecl *FD = Callee->getMostRecentDecl();
2508   DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2509   if (LangOpts.OpenMPIsDevice && DevTy &&
2510       *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2511     // Diagnose host function called during device codegen.
2512     StringRef HostDevTy =
2513         getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host);
2514     Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2515     Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2516          diag::note_omp_marked_device_type_here)
2517         << HostDevTy;
2518     return;
2519   }
2520   if (!LangOpts.OpenMPIsDevice && !LangOpts.OpenMPOffloadMandatory && DevTy &&
2521       *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2522     // Diagnose nohost function called during host codegen.
2523     StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
2524         OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2525     Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
2526     Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2527          diag::note_omp_marked_device_type_here)
2528         << NoHostDevTy;
2529   }
2530 }
2531 
2532 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
2533                                const DeclarationNameInfo &DirName,
2534                                Scope *CurScope, SourceLocation Loc) {
2535   DSAStack->push(DKind, DirName, CurScope, Loc);
2536   PushExpressionEvaluationContext(
2537       ExpressionEvaluationContext::PotentiallyEvaluated);
2538 }
2539 
2540 void Sema::StartOpenMPClause(OpenMPClauseKind K) {
2541   DSAStack->setClauseParsingMode(K);
2542 }
2543 
2544 void Sema::EndOpenMPClause() {
2545   DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
2546   CleanupVarDeclMarking();
2547 }
2548 
2549 static std::pair<ValueDecl *, bool>
2550 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
2551                SourceRange &ERange, bool AllowArraySection = false);
2552 
2553 /// Check consistency of the reduction clauses.
2554 static void checkReductionClauses(Sema &S, DSAStackTy *Stack,
2555                                   ArrayRef<OMPClause *> Clauses) {
2556   bool InscanFound = false;
2557   SourceLocation InscanLoc;
2558   // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions.
2559   // A reduction clause without the inscan reduction-modifier may not appear on
2560   // a construct on which a reduction clause with the inscan reduction-modifier
2561   // appears.
2562   for (OMPClause *C : Clauses) {
2563     if (C->getClauseKind() != OMPC_reduction)
2564       continue;
2565     auto *RC = cast<OMPReductionClause>(C);
2566     if (RC->getModifier() == OMPC_REDUCTION_inscan) {
2567       InscanFound = true;
2568       InscanLoc = RC->getModifierLoc();
2569       continue;
2570     }
2571     if (RC->getModifier() == OMPC_REDUCTION_task) {
2572       // OpenMP 5.0, 2.19.5.4 reduction Clause.
2573       // A reduction clause with the task reduction-modifier may only appear on
2574       // a parallel construct, a worksharing construct or a combined or
2575       // composite construct for which any of the aforementioned constructs is a
2576       // constituent construct and simd or loop are not constituent constructs.
2577       OpenMPDirectiveKind CurDir = Stack->getCurrentDirective();
2578       if (!(isOpenMPParallelDirective(CurDir) ||
2579             isOpenMPWorksharingDirective(CurDir)) ||
2580           isOpenMPSimdDirective(CurDir))
2581         S.Diag(RC->getModifierLoc(),
2582                diag::err_omp_reduction_task_not_parallel_or_worksharing);
2583       continue;
2584     }
2585   }
2586   if (InscanFound) {
2587     for (OMPClause *C : Clauses) {
2588       if (C->getClauseKind() != OMPC_reduction)
2589         continue;
2590       auto *RC = cast<OMPReductionClause>(C);
2591       if (RC->getModifier() != OMPC_REDUCTION_inscan) {
2592         S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown
2593                    ? RC->getBeginLoc()
2594                    : RC->getModifierLoc(),
2595                diag::err_omp_inscan_reduction_expected);
2596         S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction);
2597         continue;
2598       }
2599       for (Expr *Ref : RC->varlists()) {
2600         assert(Ref && "NULL expr in OpenMP nontemporal clause.");
2601         SourceLocation ELoc;
2602         SourceRange ERange;
2603         Expr *SimpleRefExpr = Ref;
2604         auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
2605                                   /*AllowArraySection=*/true);
2606         ValueDecl *D = Res.first;
2607         if (!D)
2608           continue;
2609         if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) {
2610           S.Diag(Ref->getExprLoc(),
2611                  diag::err_omp_reduction_not_inclusive_exclusive)
2612               << Ref->getSourceRange();
2613         }
2614       }
2615     }
2616   }
2617 }
2618 
2619 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
2620                                  ArrayRef<OMPClause *> Clauses);
2621 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2622                                  bool WithInit);
2623 
2624 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2625                               const ValueDecl *D,
2626                               const DSAStackTy::DSAVarData &DVar,
2627                               bool IsLoopIterVar = false);
2628 
2629 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
2630   // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
2631   //  A variable of class type (or array thereof) that appears in a lastprivate
2632   //  clause requires an accessible, unambiguous default constructor for the
2633   //  class type, unless the list item is also specified in a firstprivate
2634   //  clause.
2635   if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2636     for (OMPClause *C : D->clauses()) {
2637       if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2638         SmallVector<Expr *, 8> PrivateCopies;
2639         for (Expr *DE : Clause->varlists()) {
2640           if (DE->isValueDependent() || DE->isTypeDependent()) {
2641             PrivateCopies.push_back(nullptr);
2642             continue;
2643           }
2644           auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2645           auto *VD = cast<VarDecl>(DRE->getDecl());
2646           QualType Type = VD->getType().getNonReferenceType();
2647           const DSAStackTy::DSAVarData DVar =
2648               DSAStack->getTopDSA(VD, /*FromParent=*/false);
2649           if (DVar.CKind == OMPC_lastprivate) {
2650             // Generate helper private variable and initialize it with the
2651             // default value. The address of the original variable is replaced
2652             // by the address of the new private variable in CodeGen. This new
2653             // variable is not added to IdResolver, so the code in the OpenMP
2654             // region uses original variable for proper diagnostics.
2655             VarDecl *VDPrivate = buildVarDecl(
2656                 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
2657                 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
2658             ActOnUninitializedDecl(VDPrivate);
2659             if (VDPrivate->isInvalidDecl()) {
2660               PrivateCopies.push_back(nullptr);
2661               continue;
2662             }
2663             PrivateCopies.push_back(buildDeclRefExpr(
2664                 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
2665           } else {
2666             // The variable is also a firstprivate, so initialization sequence
2667             // for private copy is generated already.
2668             PrivateCopies.push_back(nullptr);
2669           }
2670         }
2671         Clause->setPrivateCopies(PrivateCopies);
2672         continue;
2673       }
2674       // Finalize nontemporal clause by handling private copies, if any.
2675       if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) {
2676         SmallVector<Expr *, 8> PrivateRefs;
2677         for (Expr *RefExpr : Clause->varlists()) {
2678           assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
2679           SourceLocation ELoc;
2680           SourceRange ERange;
2681           Expr *SimpleRefExpr = RefExpr;
2682           auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
2683           if (Res.second)
2684             // It will be analyzed later.
2685             PrivateRefs.push_back(RefExpr);
2686           ValueDecl *D = Res.first;
2687           if (!D)
2688             continue;
2689 
2690           const DSAStackTy::DSAVarData DVar =
2691               DSAStack->getTopDSA(D, /*FromParent=*/false);
2692           PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2693                                                  : SimpleRefExpr);
2694         }
2695         Clause->setPrivateRefs(PrivateRefs);
2696         continue;
2697       }
2698       if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) {
2699         for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) {
2700           OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I);
2701           auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts());
2702           if (!DRE)
2703             continue;
2704           ValueDecl *VD = DRE->getDecl();
2705           if (!VD || !isa<VarDecl>(VD))
2706             continue;
2707           DSAStackTy::DSAVarData DVar =
2708               DSAStack->getTopDSA(VD, /*FromParent=*/false);
2709           // OpenMP [2.12.5, target Construct]
2710           // Memory allocators that appear in a uses_allocators clause cannot
2711           // appear in other data-sharing attribute clauses or data-mapping
2712           // attribute clauses in the same construct.
2713           Expr *MapExpr = nullptr;
2714           if (DVar.RefExpr ||
2715               DSAStack->checkMappableExprComponentListsForDecl(
2716                   VD, /*CurrentRegionOnly=*/true,
2717                   [VD, &MapExpr](
2718                       OMPClauseMappableExprCommon::MappableExprComponentListRef
2719                           MapExprComponents,
2720                       OpenMPClauseKind C) {
2721                     auto MI = MapExprComponents.rbegin();
2722                     auto ME = MapExprComponents.rend();
2723                     if (MI != ME &&
2724                         MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2725                             VD->getCanonicalDecl()) {
2726                       MapExpr = MI->getAssociatedExpression();
2727                       return true;
2728                     }
2729                     return false;
2730                   })) {
2731             Diag(D.Allocator->getExprLoc(),
2732                  diag::err_omp_allocator_used_in_clauses)
2733                 << D.Allocator->getSourceRange();
2734             if (DVar.RefExpr)
2735               reportOriginalDsa(*this, DSAStack, VD, DVar);
2736             else
2737               Diag(MapExpr->getExprLoc(), diag::note_used_here)
2738                   << MapExpr->getSourceRange();
2739           }
2740         }
2741         continue;
2742       }
2743     }
2744     // Check allocate clauses.
2745     if (!CurContext->isDependentContext())
2746       checkAllocateClauses(*this, DSAStack, D->clauses());
2747     checkReductionClauses(*this, DSAStack, D->clauses());
2748   }
2749 
2750   DSAStack->pop();
2751   DiscardCleanupsInEvaluationContext();
2752   PopExpressionEvaluationContext();
2753 }
2754 
2755 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
2756                                      Expr *NumIterations, Sema &SemaRef,
2757                                      Scope *S, DSAStackTy *Stack);
2758 
2759 namespace {
2760 
2761 class VarDeclFilterCCC final : public CorrectionCandidateCallback {
2762 private:
2763   Sema &SemaRef;
2764 
2765 public:
2766   explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
2767   bool ValidateCandidate(const TypoCorrection &Candidate) override {
2768     NamedDecl *ND = Candidate.getCorrectionDecl();
2769     if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
2770       return VD->hasGlobalStorage() &&
2771              SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2772                                    SemaRef.getCurScope());
2773     }
2774     return false;
2775   }
2776 
2777   std::unique_ptr<CorrectionCandidateCallback> clone() override {
2778     return std::make_unique<VarDeclFilterCCC>(*this);
2779   }
2780 };
2781 
2782 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
2783 private:
2784   Sema &SemaRef;
2785 
2786 public:
2787   explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
2788   bool ValidateCandidate(const TypoCorrection &Candidate) override {
2789     NamedDecl *ND = Candidate.getCorrectionDecl();
2790     if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
2791                isa<FunctionDecl>(ND))) {
2792       return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2793                                    SemaRef.getCurScope());
2794     }
2795     return false;
2796   }
2797 
2798   std::unique_ptr<CorrectionCandidateCallback> clone() override {
2799     return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
2800   }
2801 };
2802 
2803 } // namespace
2804 
2805 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
2806                                          CXXScopeSpec &ScopeSpec,
2807                                          const DeclarationNameInfo &Id,
2808                                          OpenMPDirectiveKind Kind) {
2809   LookupResult Lookup(*this, Id, LookupOrdinaryName);
2810   LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
2811 
2812   if (Lookup.isAmbiguous())
2813     return ExprError();
2814 
2815   VarDecl *VD;
2816   if (!Lookup.isSingleResult()) {
2817     VarDeclFilterCCC CCC(*this);
2818     if (TypoCorrection Corrected =
2819             CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
2820                         CTK_ErrorRecovery)) {
2821       diagnoseTypo(Corrected,
2822                    PDiag(Lookup.empty()
2823                              ? diag::err_undeclared_var_use_suggest
2824                              : diag::err_omp_expected_var_arg_suggest)
2825                        << Id.getName());
2826       VD = Corrected.getCorrectionDeclAs<VarDecl>();
2827     } else {
2828       Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
2829                                        : diag::err_omp_expected_var_arg)
2830           << Id.getName();
2831       return ExprError();
2832     }
2833   } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
2834     Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
2835     Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
2836     return ExprError();
2837   }
2838   Lookup.suppressDiagnostics();
2839 
2840   // OpenMP [2.9.2, Syntax, C/C++]
2841   //   Variables must be file-scope, namespace-scope, or static block-scope.
2842   if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
2843     Diag(Id.getLoc(), diag::err_omp_global_var_arg)
2844         << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
2845     bool IsDecl =
2846         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2847     Diag(VD->getLocation(),
2848          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2849         << VD;
2850     return ExprError();
2851   }
2852 
2853   VarDecl *CanonicalVD = VD->getCanonicalDecl();
2854   NamedDecl *ND = CanonicalVD;
2855   // OpenMP [2.9.2, Restrictions, C/C++, p.2]
2856   //   A threadprivate directive for file-scope variables must appear outside
2857   //   any definition or declaration.
2858   if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
2859       !getCurLexicalContext()->isTranslationUnit()) {
2860     Diag(Id.getLoc(), diag::err_omp_var_scope)
2861         << getOpenMPDirectiveName(Kind) << VD;
2862     bool IsDecl =
2863         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2864     Diag(VD->getLocation(),
2865          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2866         << VD;
2867     return ExprError();
2868   }
2869   // OpenMP [2.9.2, Restrictions, C/C++, p.3]
2870   //   A threadprivate directive for static class member variables must appear
2871   //   in the class definition, in the same scope in which the member
2872   //   variables are declared.
2873   if (CanonicalVD->isStaticDataMember() &&
2874       !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
2875     Diag(Id.getLoc(), diag::err_omp_var_scope)
2876         << getOpenMPDirectiveName(Kind) << VD;
2877     bool IsDecl =
2878         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2879     Diag(VD->getLocation(),
2880          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2881         << VD;
2882     return ExprError();
2883   }
2884   // OpenMP [2.9.2, Restrictions, C/C++, p.4]
2885   //   A threadprivate directive for namespace-scope variables must appear
2886   //   outside any definition or declaration other than the namespace
2887   //   definition itself.
2888   if (CanonicalVD->getDeclContext()->isNamespace() &&
2889       (!getCurLexicalContext()->isFileContext() ||
2890        !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
2891     Diag(Id.getLoc(), diag::err_omp_var_scope)
2892         << getOpenMPDirectiveName(Kind) << VD;
2893     bool IsDecl =
2894         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2895     Diag(VD->getLocation(),
2896          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2897         << VD;
2898     return ExprError();
2899   }
2900   // OpenMP [2.9.2, Restrictions, C/C++, p.6]
2901   //   A threadprivate directive for static block-scope variables must appear
2902   //   in the scope of the variable and not in a nested scope.
2903   if (CanonicalVD->isLocalVarDecl() && CurScope &&
2904       !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
2905     Diag(Id.getLoc(), diag::err_omp_var_scope)
2906         << getOpenMPDirectiveName(Kind) << VD;
2907     bool IsDecl =
2908         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2909     Diag(VD->getLocation(),
2910          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2911         << VD;
2912     return ExprError();
2913   }
2914 
2915   // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
2916   //   A threadprivate directive must lexically precede all references to any
2917   //   of the variables in its list.
2918   if (Kind == OMPD_threadprivate && VD->isUsed() &&
2919       !DSAStack->isThreadPrivate(VD)) {
2920     Diag(Id.getLoc(), diag::err_omp_var_used)
2921         << getOpenMPDirectiveName(Kind) << VD;
2922     return ExprError();
2923   }
2924 
2925   QualType ExprType = VD->getType().getNonReferenceType();
2926   return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
2927                              SourceLocation(), VD,
2928                              /*RefersToEnclosingVariableOrCapture=*/false,
2929                              Id.getLoc(), ExprType, VK_LValue);
2930 }
2931 
2932 Sema::DeclGroupPtrTy
2933 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
2934                                         ArrayRef<Expr *> VarList) {
2935   if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
2936     CurContext->addDecl(D);
2937     return DeclGroupPtrTy::make(DeclGroupRef(D));
2938   }
2939   return nullptr;
2940 }
2941 
2942 namespace {
2943 class LocalVarRefChecker final
2944     : public ConstStmtVisitor<LocalVarRefChecker, bool> {
2945   Sema &SemaRef;
2946 
2947 public:
2948   bool VisitDeclRefExpr(const DeclRefExpr *E) {
2949     if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
2950       if (VD->hasLocalStorage()) {
2951         SemaRef.Diag(E->getBeginLoc(),
2952                      diag::err_omp_local_var_in_threadprivate_init)
2953             << E->getSourceRange();
2954         SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
2955             << VD << VD->getSourceRange();
2956         return true;
2957       }
2958     }
2959     return false;
2960   }
2961   bool VisitStmt(const Stmt *S) {
2962     for (const Stmt *Child : S->children()) {
2963       if (Child && Visit(Child))
2964         return true;
2965     }
2966     return false;
2967   }
2968   explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
2969 };
2970 } // namespace
2971 
2972 OMPThreadPrivateDecl *
2973 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
2974   SmallVector<Expr *, 8> Vars;
2975   for (Expr *RefExpr : VarList) {
2976     auto *DE = cast<DeclRefExpr>(RefExpr);
2977     auto *VD = cast<VarDecl>(DE->getDecl());
2978     SourceLocation ILoc = DE->getExprLoc();
2979 
2980     // Mark variable as used.
2981     VD->setReferenced();
2982     VD->markUsed(Context);
2983 
2984     QualType QType = VD->getType();
2985     if (QType->isDependentType() || QType->isInstantiationDependentType()) {
2986       // It will be analyzed later.
2987       Vars.push_back(DE);
2988       continue;
2989     }
2990 
2991     // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2992     //   A threadprivate variable must not have an incomplete type.
2993     if (RequireCompleteType(ILoc, VD->getType(),
2994                             diag::err_omp_threadprivate_incomplete_type)) {
2995       continue;
2996     }
2997 
2998     // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2999     //   A threadprivate variable must not have a reference type.
3000     if (VD->getType()->isReferenceType()) {
3001       Diag(ILoc, diag::err_omp_ref_type_arg)
3002           << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
3003       bool IsDecl =
3004           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3005       Diag(VD->getLocation(),
3006            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3007           << VD;
3008       continue;
3009     }
3010 
3011     // Check if this is a TLS variable. If TLS is not being supported, produce
3012     // the corresponding diagnostic.
3013     if ((VD->getTLSKind() != VarDecl::TLS_None &&
3014          !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
3015            getLangOpts().OpenMPUseTLS &&
3016            getASTContext().getTargetInfo().isTLSSupported())) ||
3017         (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3018          !VD->isLocalVarDecl())) {
3019       Diag(ILoc, diag::err_omp_var_thread_local)
3020           << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
3021       bool IsDecl =
3022           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3023       Diag(VD->getLocation(),
3024            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3025           << VD;
3026       continue;
3027     }
3028 
3029     // Check if initial value of threadprivate variable reference variable with
3030     // local storage (it is not supported by runtime).
3031     if (const Expr *Init = VD->getAnyInitializer()) {
3032       LocalVarRefChecker Checker(*this);
3033       if (Checker.Visit(Init))
3034         continue;
3035     }
3036 
3037     Vars.push_back(RefExpr);
3038     DSAStack->addDSA(VD, DE, OMPC_threadprivate);
3039     VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3040         Context, SourceRange(Loc, Loc)));
3041     if (ASTMutationListener *ML = Context.getASTMutationListener())
3042       ML->DeclarationMarkedOpenMPThreadPrivate(VD);
3043   }
3044   OMPThreadPrivateDecl *D = nullptr;
3045   if (!Vars.empty()) {
3046     D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
3047                                      Vars);
3048     D->setAccess(AS_public);
3049   }
3050   return D;
3051 }
3052 
3053 static OMPAllocateDeclAttr::AllocatorTypeTy
3054 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
3055   if (!Allocator)
3056     return OMPAllocateDeclAttr::OMPNullMemAlloc;
3057   if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3058       Allocator->isInstantiationDependent() ||
3059       Allocator->containsUnexpandedParameterPack())
3060     return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3061   auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3062   const Expr *AE = Allocator->IgnoreParenImpCasts();
3063   for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
3064     auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
3065     const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
3066     llvm::FoldingSetNodeID AEId, DAEId;
3067     AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
3068     DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true);
3069     if (AEId == DAEId) {
3070       AllocatorKindRes = AllocatorKind;
3071       break;
3072     }
3073   }
3074   return AllocatorKindRes;
3075 }
3076 
3077 static bool checkPreviousOMPAllocateAttribute(
3078     Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
3079     OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
3080   if (!VD->hasAttr<OMPAllocateDeclAttr>())
3081     return false;
3082   const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
3083   Expr *PrevAllocator = A->getAllocator();
3084   OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3085       getAllocatorKind(S, Stack, PrevAllocator);
3086   bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3087   if (AllocatorsMatch &&
3088       AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3089       Allocator && PrevAllocator) {
3090     const Expr *AE = Allocator->IgnoreParenImpCasts();
3091     const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
3092     llvm::FoldingSetNodeID AEId, PAEId;
3093     AE->Profile(AEId, S.Context, /*Canonical=*/true);
3094     PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
3095     AllocatorsMatch = AEId == PAEId;
3096   }
3097   if (!AllocatorsMatch) {
3098     SmallString<256> AllocatorBuffer;
3099     llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3100     if (Allocator)
3101       Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
3102     SmallString<256> PrevAllocatorBuffer;
3103     llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3104     if (PrevAllocator)
3105       PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
3106                                  S.getPrintingPolicy());
3107 
3108     SourceLocation AllocatorLoc =
3109         Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
3110     SourceRange AllocatorRange =
3111         Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
3112     SourceLocation PrevAllocatorLoc =
3113         PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3114     SourceRange PrevAllocatorRange =
3115         PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3116     S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3117         << (Allocator ? 1 : 0) << AllocatorStream.str()
3118         << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3119         << AllocatorRange;
3120     S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3121         << PrevAllocatorRange;
3122     return true;
3123   }
3124   return false;
3125 }
3126 
3127 static void
3128 applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
3129                           OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3130                           Expr *Allocator, Expr *Alignment, SourceRange SR) {
3131   if (VD->hasAttr<OMPAllocateDeclAttr>())
3132     return;
3133   if (Alignment &&
3134       (Alignment->isTypeDependent() || Alignment->isValueDependent() ||
3135        Alignment->isInstantiationDependent() ||
3136        Alignment->containsUnexpandedParameterPack()))
3137     // Apply later when we have a usable value.
3138     return;
3139   if (Allocator &&
3140       (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3141        Allocator->isInstantiationDependent() ||
3142        Allocator->containsUnexpandedParameterPack()))
3143     return;
3144   auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
3145                                                 Allocator, Alignment, SR);
3146   VD->addAttr(A);
3147   if (ASTMutationListener *ML = S.Context.getASTMutationListener())
3148     ML->DeclarationMarkedOpenMPAllocate(VD, A);
3149 }
3150 
3151 Sema::DeclGroupPtrTy
3152 Sema::ActOnOpenMPAllocateDirective(SourceLocation Loc, ArrayRef<Expr *> VarList,
3153                                    ArrayRef<OMPClause *> Clauses,
3154                                    DeclContext *Owner) {
3155   assert(Clauses.size() <= 2 && "Expected at most two clauses.");
3156   Expr *Alignment = nullptr;
3157   Expr *Allocator = nullptr;
3158   if (Clauses.empty()) {
3159     // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
3160     // allocate directives that appear in a target region must specify an
3161     // allocator clause unless a requires directive with the dynamic_allocators
3162     // clause is present in the same compilation unit.
3163     if (LangOpts.OpenMPIsDevice &&
3164         !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
3165       targetDiag(Loc, diag::err_expected_allocator_clause);
3166   } else {
3167     for (const OMPClause *C : Clauses)
3168       if (const auto *AC = dyn_cast<OMPAllocatorClause>(C))
3169         Allocator = AC->getAllocator();
3170       else if (const auto *AC = dyn_cast<OMPAlignClause>(C))
3171         Alignment = AC->getAlignment();
3172       else
3173         llvm_unreachable("Unexpected clause on allocate directive");
3174   }
3175   OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3176       getAllocatorKind(*this, DSAStack, Allocator);
3177   SmallVector<Expr *, 8> Vars;
3178   for (Expr *RefExpr : VarList) {
3179     auto *DE = cast<DeclRefExpr>(RefExpr);
3180     auto *VD = cast<VarDecl>(DE->getDecl());
3181 
3182     // Check if this is a TLS variable or global register.
3183     if (VD->getTLSKind() != VarDecl::TLS_None ||
3184         VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
3185         (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3186          !VD->isLocalVarDecl()))
3187       continue;
3188 
3189     // If the used several times in the allocate directive, the same allocator
3190     // must be used.
3191     if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD,
3192                                           AllocatorKind, Allocator))
3193       continue;
3194 
3195     // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
3196     // If a list item has a static storage type, the allocator expression in the
3197     // allocator clause must be a constant expression that evaluates to one of
3198     // the predefined memory allocator values.
3199     if (Allocator && VD->hasGlobalStorage()) {
3200       if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3201         Diag(Allocator->getExprLoc(),
3202              diag::err_omp_expected_predefined_allocator)
3203             << Allocator->getSourceRange();
3204         bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
3205                       VarDecl::DeclarationOnly;
3206         Diag(VD->getLocation(),
3207              IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3208             << VD;
3209         continue;
3210       }
3211     }
3212 
3213     Vars.push_back(RefExpr);
3214     applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, Alignment,
3215                               DE->getSourceRange());
3216   }
3217   if (Vars.empty())
3218     return nullptr;
3219   if (!Owner)
3220     Owner = getCurLexicalContext();
3221   auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
3222   D->setAccess(AS_public);
3223   Owner->addDecl(D);
3224   return DeclGroupPtrTy::make(DeclGroupRef(D));
3225 }
3226 
3227 Sema::DeclGroupPtrTy
3228 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
3229                                    ArrayRef<OMPClause *> ClauseList) {
3230   OMPRequiresDecl *D = nullptr;
3231   if (!CurContext->isFileContext()) {
3232     Diag(Loc, diag::err_omp_invalid_scope) << "requires";
3233   } else {
3234     D = CheckOMPRequiresDecl(Loc, ClauseList);
3235     if (D) {
3236       CurContext->addDecl(D);
3237       DSAStack->addRequiresDecl(D);
3238     }
3239   }
3240   return DeclGroupPtrTy::make(DeclGroupRef(D));
3241 }
3242 
3243 void Sema::ActOnOpenMPAssumesDirective(SourceLocation Loc,
3244                                        OpenMPDirectiveKind DKind,
3245                                        ArrayRef<std::string> Assumptions,
3246                                        bool SkippedClauses) {
3247   if (!SkippedClauses && Assumptions.empty())
3248     Diag(Loc, diag::err_omp_no_clause_for_directive)
3249         << llvm::omp::getAllAssumeClauseOptions()
3250         << llvm::omp::getOpenMPDirectiveName(DKind);
3251 
3252   auto *AA = AssumptionAttr::Create(Context, llvm::join(Assumptions, ","), Loc);
3253   if (DKind == llvm::omp::Directive::OMPD_begin_assumes) {
3254     OMPAssumeScoped.push_back(AA);
3255     return;
3256   }
3257 
3258   // Global assumes without assumption clauses are ignored.
3259   if (Assumptions.empty())
3260     return;
3261 
3262   assert(DKind == llvm::omp::Directive::OMPD_assumes &&
3263          "Unexpected omp assumption directive!");
3264   OMPAssumeGlobal.push_back(AA);
3265 
3266   // The OMPAssumeGlobal scope above will take care of new declarations but
3267   // we also want to apply the assumption to existing ones, e.g., to
3268   // declarations in included headers. To this end, we traverse all existing
3269   // declaration contexts and annotate function declarations here.
3270   SmallVector<DeclContext *, 8> DeclContexts;
3271   auto *Ctx = CurContext;
3272   while (Ctx->getLexicalParent())
3273     Ctx = Ctx->getLexicalParent();
3274   DeclContexts.push_back(Ctx);
3275   while (!DeclContexts.empty()) {
3276     DeclContext *DC = DeclContexts.pop_back_val();
3277     for (auto *SubDC : DC->decls()) {
3278       if (SubDC->isInvalidDecl())
3279         continue;
3280       if (auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) {
3281         DeclContexts.push_back(CTD->getTemplatedDecl());
3282         for (auto *S : CTD->specializations())
3283           DeclContexts.push_back(S);
3284         continue;
3285       }
3286       if (auto *DC = dyn_cast<DeclContext>(SubDC))
3287         DeclContexts.push_back(DC);
3288       if (auto *F = dyn_cast<FunctionDecl>(SubDC)) {
3289         F->addAttr(AA);
3290         continue;
3291       }
3292     }
3293   }
3294 }
3295 
3296 void Sema::ActOnOpenMPEndAssumesDirective() {
3297   assert(isInOpenMPAssumeScope() && "Not in OpenMP assumes scope!");
3298   OMPAssumeScoped.pop_back();
3299 }
3300 
3301 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
3302                                             ArrayRef<OMPClause *> ClauseList) {
3303   /// For target specific clauses, the requires directive cannot be
3304   /// specified after the handling of any of the target regions in the
3305   /// current compilation unit.
3306   ArrayRef<SourceLocation> TargetLocations =
3307       DSAStack->getEncounteredTargetLocs();
3308   SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc();
3309   if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) {
3310     for (const OMPClause *CNew : ClauseList) {
3311       // Check if any of the requires clauses affect target regions.
3312       if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3313           isa<OMPUnifiedAddressClause>(CNew) ||
3314           isa<OMPReverseOffloadClause>(CNew) ||
3315           isa<OMPDynamicAllocatorsClause>(CNew)) {
3316         Diag(Loc, diag::err_omp_directive_before_requires)
3317             << "target" << getOpenMPClauseName(CNew->getClauseKind());
3318         for (SourceLocation TargetLoc : TargetLocations) {
3319           Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3320               << "target";
3321         }
3322       } else if (!AtomicLoc.isInvalid() &&
3323                  isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3324         Diag(Loc, diag::err_omp_directive_before_requires)
3325             << "atomic" << getOpenMPClauseName(CNew->getClauseKind());
3326         Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3327             << "atomic";
3328       }
3329     }
3330   }
3331 
3332   if (!DSAStack->hasDuplicateRequiresClause(ClauseList))
3333     return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
3334                                    ClauseList);
3335   return nullptr;
3336 }
3337 
3338 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
3339                               const ValueDecl *D,
3340                               const DSAStackTy::DSAVarData &DVar,
3341                               bool IsLoopIterVar) {
3342   if (DVar.RefExpr) {
3343     SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3344         << getOpenMPClauseName(DVar.CKind);
3345     return;
3346   }
3347   enum {
3348     PDSA_StaticMemberShared,
3349     PDSA_StaticLocalVarShared,
3350     PDSA_LoopIterVarPrivate,
3351     PDSA_LoopIterVarLinear,
3352     PDSA_LoopIterVarLastprivate,
3353     PDSA_ConstVarShared,
3354     PDSA_GlobalVarShared,
3355     PDSA_TaskVarFirstprivate,
3356     PDSA_LocalVarPrivate,
3357     PDSA_Implicit
3358   } Reason = PDSA_Implicit;
3359   bool ReportHint = false;
3360   auto ReportLoc = D->getLocation();
3361   auto *VD = dyn_cast<VarDecl>(D);
3362   if (IsLoopIterVar) {
3363     if (DVar.CKind == OMPC_private)
3364       Reason = PDSA_LoopIterVarPrivate;
3365     else if (DVar.CKind == OMPC_lastprivate)
3366       Reason = PDSA_LoopIterVarLastprivate;
3367     else
3368       Reason = PDSA_LoopIterVarLinear;
3369   } else if (isOpenMPTaskingDirective(DVar.DKind) &&
3370              DVar.CKind == OMPC_firstprivate) {
3371     Reason = PDSA_TaskVarFirstprivate;
3372     ReportLoc = DVar.ImplicitDSALoc;
3373   } else if (VD && VD->isStaticLocal())
3374     Reason = PDSA_StaticLocalVarShared;
3375   else if (VD && VD->isStaticDataMember())
3376     Reason = PDSA_StaticMemberShared;
3377   else if (VD && VD->isFileVarDecl())
3378     Reason = PDSA_GlobalVarShared;
3379   else if (D->getType().isConstant(SemaRef.getASTContext()))
3380     Reason = PDSA_ConstVarShared;
3381   else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
3382     ReportHint = true;
3383     Reason = PDSA_LocalVarPrivate;
3384   }
3385   if (Reason != PDSA_Implicit) {
3386     SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3387         << Reason << ReportHint
3388         << getOpenMPDirectiveName(Stack->getCurrentDirective());
3389   } else if (DVar.ImplicitDSALoc.isValid()) {
3390     SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3391         << getOpenMPClauseName(DVar.CKind);
3392   }
3393 }
3394 
3395 static OpenMPMapClauseKind
3396 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,
3397                              bool IsAggregateOrDeclareTarget) {
3398   OpenMPMapClauseKind Kind = OMPC_MAP_unknown;
3399   switch (M) {
3400   case OMPC_DEFAULTMAP_MODIFIER_alloc:
3401     Kind = OMPC_MAP_alloc;
3402     break;
3403   case OMPC_DEFAULTMAP_MODIFIER_to:
3404     Kind = OMPC_MAP_to;
3405     break;
3406   case OMPC_DEFAULTMAP_MODIFIER_from:
3407     Kind = OMPC_MAP_from;
3408     break;
3409   case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3410     Kind = OMPC_MAP_tofrom;
3411     break;
3412   case OMPC_DEFAULTMAP_MODIFIER_present:
3413     // OpenMP 5.1 [2.21.7.3] defaultmap clause, Description]
3414     // If implicit-behavior is present, each variable referenced in the
3415     // construct in the category specified by variable-category is treated as if
3416     // it had been listed in a map clause with the map-type of alloc and
3417     // map-type-modifier of present.
3418     Kind = OMPC_MAP_alloc;
3419     break;
3420   case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3421   case OMPC_DEFAULTMAP_MODIFIER_last:
3422     llvm_unreachable("Unexpected defaultmap implicit behavior");
3423   case OMPC_DEFAULTMAP_MODIFIER_none:
3424   case OMPC_DEFAULTMAP_MODIFIER_default:
3425   case OMPC_DEFAULTMAP_MODIFIER_unknown:
3426     // IsAggregateOrDeclareTarget could be true if:
3427     // 1. the implicit behavior for aggregate is tofrom
3428     // 2. it's a declare target link
3429     if (IsAggregateOrDeclareTarget) {
3430       Kind = OMPC_MAP_tofrom;
3431       break;
3432     }
3433     llvm_unreachable("Unexpected defaultmap implicit behavior");
3434   }
3435   assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known");
3436   return Kind;
3437 }
3438 
3439 namespace {
3440 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
3441   DSAStackTy *Stack;
3442   Sema &SemaRef;
3443   bool ErrorFound = false;
3444   bool TryCaptureCXXThisMembers = false;
3445   CapturedStmt *CS = nullptr;
3446   const static unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
3447   llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
3448   llvm::SmallVector<Expr *, 4> ImplicitMap[DefaultmapKindNum][OMPC_MAP_delete];
3449   llvm::SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
3450       ImplicitMapModifier[DefaultmapKindNum];
3451   Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
3452   llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3453 
3454   void VisitSubCaptures(OMPExecutableDirective *S) {
3455     // Check implicitly captured variables.
3456     if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
3457       return;
3458     if (S->getDirectiveKind() == OMPD_atomic ||
3459         S->getDirectiveKind() == OMPD_critical ||
3460         S->getDirectiveKind() == OMPD_section ||
3461         S->getDirectiveKind() == OMPD_master ||
3462         S->getDirectiveKind() == OMPD_masked ||
3463         isOpenMPLoopTransformationDirective(S->getDirectiveKind())) {
3464       Visit(S->getAssociatedStmt());
3465       return;
3466     }
3467     visitSubCaptures(S->getInnermostCapturedStmt());
3468     // Try to capture inner this->member references to generate correct mappings
3469     // and diagnostics.
3470     if (TryCaptureCXXThisMembers ||
3471         (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3472          llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3473                       [](const CapturedStmt::Capture &C) {
3474                         return C.capturesThis();
3475                       }))) {
3476       bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3477       TryCaptureCXXThisMembers = true;
3478       Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3479       TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3480     }
3481     // In tasks firstprivates are not captured anymore, need to analyze them
3482     // explicitly.
3483     if (isOpenMPTaskingDirective(S->getDirectiveKind()) &&
3484         !isOpenMPTaskLoopDirective(S->getDirectiveKind())) {
3485       for (OMPClause *C : S->clauses())
3486         if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) {
3487           for (Expr *Ref : FC->varlists())
3488             Visit(Ref);
3489         }
3490     }
3491   }
3492 
3493 public:
3494   void VisitDeclRefExpr(DeclRefExpr *E) {
3495     if (TryCaptureCXXThisMembers || E->isTypeDependent() ||
3496         E->isValueDependent() || E->containsUnexpandedParameterPack() ||
3497         E->isInstantiationDependent())
3498       return;
3499     if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3500       // Check the datasharing rules for the expressions in the clauses.
3501       if (!CS || (isa<OMPCapturedExprDecl>(VD) && !CS->capturesVariable(VD) &&
3502                   !Stack->getTopDSA(VD, /*FromParent=*/false).RefExpr)) {
3503         if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3504           if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3505             Visit(CED->getInit());
3506             return;
3507           }
3508       } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
3509         // Do not analyze internal variables and do not enclose them into
3510         // implicit clauses.
3511         return;
3512       VD = VD->getCanonicalDecl();
3513       // Skip internally declared variables.
3514       if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) &&
3515           !Stack->isImplicitTaskFirstprivate(VD))
3516         return;
3517       // Skip allocators in uses_allocators clauses.
3518       if (Stack->isUsesAllocatorsDecl(VD).hasValue())
3519         return;
3520 
3521       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
3522       // Check if the variable has explicit DSA set and stop analysis if it so.
3523       if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3524         return;
3525 
3526       // Skip internally declared static variables.
3527       llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3528           OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3529       if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
3530           (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
3531            !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3532           !Stack->isImplicitTaskFirstprivate(VD))
3533         return;
3534 
3535       SourceLocation ELoc = E->getExprLoc();
3536       OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3537       // The default(none) clause requires that each variable that is referenced
3538       // in the construct, and does not have a predetermined data-sharing
3539       // attribute, must have its data-sharing attribute explicitly determined
3540       // by being listed in a data-sharing attribute clause.
3541       if (DVar.CKind == OMPC_unknown &&
3542           (Stack->getDefaultDSA() == DSA_none ||
3543            Stack->getDefaultDSA() == DSA_firstprivate) &&
3544           isImplicitOrExplicitTaskingRegion(DKind) &&
3545           VarsWithInheritedDSA.count(VD) == 0) {
3546         bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3547         if (!InheritedDSA && Stack->getDefaultDSA() == DSA_firstprivate) {
3548           DSAStackTy::DSAVarData DVar =
3549               Stack->getImplicitDSA(VD, /*FromParent=*/false);
3550           InheritedDSA = DVar.CKind == OMPC_unknown;
3551         }
3552         if (InheritedDSA)
3553           VarsWithInheritedDSA[VD] = E;
3554         return;
3555       }
3556 
3557       // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description]
3558       // If implicit-behavior is none, each variable referenced in the
3559       // construct that does not have a predetermined data-sharing attribute
3560       // and does not appear in a to or link clause on a declare target
3561       // directive must be listed in a data-mapping attribute clause, a
3562       // data-haring attribute clause (including a data-sharing attribute
3563       // clause on a combined construct where target. is one of the
3564       // constituent constructs), or an is_device_ptr clause.
3565       OpenMPDefaultmapClauseKind ClauseKind =
3566           getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD);
3567       if (SemaRef.getLangOpts().OpenMP >= 50) {
3568         bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3569                               OMPC_DEFAULTMAP_MODIFIER_none;
3570         if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3571             VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3572           // Only check for data-mapping attribute and is_device_ptr here
3573           // since we have already make sure that the declaration does not
3574           // have a data-sharing attribute above
3575           if (!Stack->checkMappableExprComponentListsForDecl(
3576                   VD, /*CurrentRegionOnly=*/true,
3577                   [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef
3578                            MapExprComponents,
3579                        OpenMPClauseKind) {
3580                     auto MI = MapExprComponents.rbegin();
3581                     auto ME = MapExprComponents.rend();
3582                     return MI != ME && MI->getAssociatedDeclaration() == VD;
3583                   })) {
3584             VarsWithInheritedDSA[VD] = E;
3585             return;
3586           }
3587         }
3588       }
3589       if (SemaRef.getLangOpts().OpenMP > 50) {
3590         bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) ==
3591                                  OMPC_DEFAULTMAP_MODIFIER_present;
3592         if (IsModifierPresent) {
3593           if (llvm::find(ImplicitMapModifier[ClauseKind],
3594                          OMPC_MAP_MODIFIER_present) ==
3595               std::end(ImplicitMapModifier[ClauseKind])) {
3596             ImplicitMapModifier[ClauseKind].push_back(
3597                 OMPC_MAP_MODIFIER_present);
3598           }
3599         }
3600       }
3601 
3602       if (isOpenMPTargetExecutionDirective(DKind) &&
3603           !Stack->isLoopControlVariable(VD).first) {
3604         if (!Stack->checkMappableExprComponentListsForDecl(
3605                 VD, /*CurrentRegionOnly=*/true,
3606                 [this](OMPClauseMappableExprCommon::MappableExprComponentListRef
3607                            StackComponents,
3608                        OpenMPClauseKind) {
3609                   if (SemaRef.LangOpts.OpenMP >= 50)
3610                     return !StackComponents.empty();
3611                   // Variable is used if it has been marked as an array, array
3612                   // section, array shaping or the variable iself.
3613                   return StackComponents.size() == 1 ||
3614                          std::all_of(
3615                              std::next(StackComponents.rbegin()),
3616                              StackComponents.rend(),
3617                              [](const OMPClauseMappableExprCommon::
3618                                     MappableComponent &MC) {
3619                                return MC.getAssociatedDeclaration() ==
3620                                           nullptr &&
3621                                       (isa<OMPArraySectionExpr>(
3622                                            MC.getAssociatedExpression()) ||
3623                                        isa<OMPArrayShapingExpr>(
3624                                            MC.getAssociatedExpression()) ||
3625                                        isa<ArraySubscriptExpr>(
3626                                            MC.getAssociatedExpression()));
3627                              });
3628                 })) {
3629           bool IsFirstprivate = false;
3630           // By default lambdas are captured as firstprivates.
3631           if (const auto *RD =
3632                   VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
3633             IsFirstprivate = RD->isLambda();
3634           IsFirstprivate =
3635               IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3636           if (IsFirstprivate) {
3637             ImplicitFirstprivate.emplace_back(E);
3638           } else {
3639             OpenMPDefaultmapClauseModifier M =
3640                 Stack->getDefaultmapModifier(ClauseKind);
3641             OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3642                 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3643             ImplicitMap[ClauseKind][Kind].emplace_back(E);
3644           }
3645           return;
3646         }
3647       }
3648 
3649       // OpenMP [2.9.3.6, Restrictions, p.2]
3650       //  A list item that appears in a reduction clause of the innermost
3651       //  enclosing worksharing or parallel construct may not be accessed in an
3652       //  explicit task.
3653       DVar = Stack->hasInnermostDSA(
3654           VD,
3655           [](OpenMPClauseKind C, bool AppliedToPointee) {
3656             return C == OMPC_reduction && !AppliedToPointee;
3657           },
3658           [](OpenMPDirectiveKind K) {
3659             return isOpenMPParallelDirective(K) ||
3660                    isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3661           },
3662           /*FromParent=*/true);
3663       if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3664         ErrorFound = true;
3665         SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3666         reportOriginalDsa(SemaRef, Stack, VD, DVar);
3667         return;
3668       }
3669 
3670       // Define implicit data-sharing attributes for task.
3671       DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
3672       if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) ||
3673            (Stack->getDefaultDSA() == DSA_firstprivate &&
3674             DVar.CKind == OMPC_firstprivate && !DVar.RefExpr)) &&
3675           !Stack->isLoopControlVariable(VD).first) {
3676         ImplicitFirstprivate.push_back(E);
3677         return;
3678       }
3679 
3680       // Store implicitly used globals with declare target link for parent
3681       // target.
3682       if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
3683           *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3684         Stack->addToParentTargetRegionLinkGlobals(E);
3685         return;
3686       }
3687     }
3688   }
3689   void VisitMemberExpr(MemberExpr *E) {
3690     if (E->isTypeDependent() || E->isValueDependent() ||
3691         E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
3692       return;
3693     auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
3694     OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3695     if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) {
3696       if (!FD)
3697         return;
3698       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
3699       // Check if the variable has explicit DSA set and stop analysis if it
3700       // so.
3701       if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3702         return;
3703 
3704       if (isOpenMPTargetExecutionDirective(DKind) &&
3705           !Stack->isLoopControlVariable(FD).first &&
3706           !Stack->checkMappableExprComponentListsForDecl(
3707               FD, /*CurrentRegionOnly=*/true,
3708               [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3709                      StackComponents,
3710                  OpenMPClauseKind) {
3711                 return isa<CXXThisExpr>(
3712                     cast<MemberExpr>(
3713                         StackComponents.back().getAssociatedExpression())
3714                         ->getBase()
3715                         ->IgnoreParens());
3716               })) {
3717         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
3718         //  A bit-field cannot appear in a map clause.
3719         //
3720         if (FD->isBitField())
3721           return;
3722 
3723         // Check to see if the member expression is referencing a class that
3724         // has already been explicitly mapped
3725         if (Stack->isClassPreviouslyMapped(TE->getType()))
3726           return;
3727 
3728         OpenMPDefaultmapClauseModifier Modifier =
3729             Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3730         OpenMPDefaultmapClauseKind ClauseKind =
3731             getVariableCategoryFromDecl(SemaRef.getLangOpts(), FD);
3732         OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3733             Modifier, /*IsAggregateOrDeclareTarget*/ true);
3734         ImplicitMap[ClauseKind][Kind].emplace_back(E);
3735         return;
3736       }
3737 
3738       SourceLocation ELoc = E->getExprLoc();
3739       // OpenMP [2.9.3.6, Restrictions, p.2]
3740       //  A list item that appears in a reduction clause of the innermost
3741       //  enclosing worksharing or parallel construct may not be accessed in
3742       //  an  explicit task.
3743       DVar = Stack->hasInnermostDSA(
3744           FD,
3745           [](OpenMPClauseKind C, bool AppliedToPointee) {
3746             return C == OMPC_reduction && !AppliedToPointee;
3747           },
3748           [](OpenMPDirectiveKind K) {
3749             return isOpenMPParallelDirective(K) ||
3750                    isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3751           },
3752           /*FromParent=*/true);
3753       if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3754         ErrorFound = true;
3755         SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3756         reportOriginalDsa(SemaRef, Stack, FD, DVar);
3757         return;
3758       }
3759 
3760       // Define implicit data-sharing attributes for task.
3761       DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
3762       if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
3763           !Stack->isLoopControlVariable(FD).first) {
3764         // Check if there is a captured expression for the current field in the
3765         // region. Do not mark it as firstprivate unless there is no captured
3766         // expression.
3767         // TODO: try to make it firstprivate.
3768         if (DVar.CKind != OMPC_unknown)
3769           ImplicitFirstprivate.push_back(E);
3770       }
3771       return;
3772     }
3773     if (isOpenMPTargetExecutionDirective(DKind)) {
3774       OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
3775       if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
3776                                         Stack->getCurrentDirective(),
3777                                         /*NoDiagnose=*/true))
3778         return;
3779       const auto *VD = cast<ValueDecl>(
3780           CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
3781       if (!Stack->checkMappableExprComponentListsForDecl(
3782               VD, /*CurrentRegionOnly=*/true,
3783               [&CurComponents](
3784                   OMPClauseMappableExprCommon::MappableExprComponentListRef
3785                       StackComponents,
3786                   OpenMPClauseKind) {
3787                 auto CCI = CurComponents.rbegin();
3788                 auto CCE = CurComponents.rend();
3789                 for (const auto &SC : llvm::reverse(StackComponents)) {
3790                   // Do both expressions have the same kind?
3791                   if (CCI->getAssociatedExpression()->getStmtClass() !=
3792                       SC.getAssociatedExpression()->getStmtClass())
3793                     if (!((isa<OMPArraySectionExpr>(
3794                                SC.getAssociatedExpression()) ||
3795                            isa<OMPArrayShapingExpr>(
3796                                SC.getAssociatedExpression())) &&
3797                           isa<ArraySubscriptExpr>(
3798                               CCI->getAssociatedExpression())))
3799                       return false;
3800 
3801                   const Decl *CCD = CCI->getAssociatedDeclaration();
3802                   const Decl *SCD = SC.getAssociatedDeclaration();
3803                   CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
3804                   SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
3805                   if (SCD != CCD)
3806                     return false;
3807                   std::advance(CCI, 1);
3808                   if (CCI == CCE)
3809                     break;
3810                 }
3811                 return true;
3812               })) {
3813         Visit(E->getBase());
3814       }
3815     } else if (!TryCaptureCXXThisMembers) {
3816       Visit(E->getBase());
3817     }
3818   }
3819   void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
3820     for (OMPClause *C : S->clauses()) {
3821       // Skip analysis of arguments of private clauses for task|target
3822       // directives.
3823       if (isa_and_nonnull<OMPPrivateClause>(C))
3824         continue;
3825       // Skip analysis of arguments of implicitly defined firstprivate clause
3826       // for task|target directives.
3827       // Skip analysis of arguments of implicitly defined map clause for target
3828       // directives.
3829       if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
3830                  C->isImplicit() &&
3831                  !isOpenMPTaskingDirective(Stack->getCurrentDirective()))) {
3832         for (Stmt *CC : C->children()) {
3833           if (CC)
3834             Visit(CC);
3835         }
3836       }
3837     }
3838     // Check implicitly captured variables.
3839     VisitSubCaptures(S);
3840   }
3841 
3842   void VisitOMPLoopTransformationDirective(OMPLoopTransformationDirective *S) {
3843     // Loop transformation directives do not introduce data sharing
3844     VisitStmt(S);
3845   }
3846 
3847   void VisitCallExpr(CallExpr *S) {
3848     for (Stmt *C : S->arguments()) {
3849       if (C) {
3850         // Check implicitly captured variables in the task-based directives to
3851         // check if they must be firstprivatized.
3852         Visit(C);
3853       }
3854     }
3855     if (Expr *Callee = S->getCallee())
3856       if (auto *CE = dyn_cast<MemberExpr>(Callee->IgnoreParenImpCasts()))
3857         Visit(CE->getBase());
3858   }
3859   void VisitStmt(Stmt *S) {
3860     for (Stmt *C : S->children()) {
3861       if (C) {
3862         // Check implicitly captured variables in the task-based directives to
3863         // check if they must be firstprivatized.
3864         Visit(C);
3865       }
3866     }
3867   }
3868 
3869   void visitSubCaptures(CapturedStmt *S) {
3870     for (const CapturedStmt::Capture &Cap : S->captures()) {
3871       if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
3872         continue;
3873       VarDecl *VD = Cap.getCapturedVar();
3874       // Do not try to map the variable if it or its sub-component was mapped
3875       // already.
3876       if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3877           Stack->checkMappableExprComponentListsForDecl(
3878               VD, /*CurrentRegionOnly=*/true,
3879               [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
3880                  OpenMPClauseKind) { return true; }))
3881         continue;
3882       DeclRefExpr *DRE = buildDeclRefExpr(
3883           SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
3884           Cap.getLocation(), /*RefersToCapture=*/true);
3885       Visit(DRE);
3886     }
3887   }
3888   bool isErrorFound() const { return ErrorFound; }
3889   ArrayRef<Expr *> getImplicitFirstprivate() const {
3890     return ImplicitFirstprivate;
3891   }
3892   ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind DK,
3893                                   OpenMPMapClauseKind MK) const {
3894     return ImplicitMap[DK][MK];
3895   }
3896   ArrayRef<OpenMPMapModifierKind>
3897   getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const {
3898     return ImplicitMapModifier[Kind];
3899   }
3900   const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
3901     return VarsWithInheritedDSA;
3902   }
3903 
3904   DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
3905       : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
3906     // Process declare target link variables for the target directives.
3907     if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
3908       for (DeclRefExpr *E : Stack->getLinkGlobals())
3909         Visit(E);
3910     }
3911   }
3912 };
3913 } // namespace
3914 
3915 static void handleDeclareVariantConstructTrait(DSAStackTy *Stack,
3916                                                OpenMPDirectiveKind DKind,
3917                                                bool ScopeEntry) {
3918   SmallVector<llvm::omp::TraitProperty, 8> Traits;
3919   if (isOpenMPTargetExecutionDirective(DKind))
3920     Traits.emplace_back(llvm::omp::TraitProperty::construct_target_target);
3921   if (isOpenMPTeamsDirective(DKind))
3922     Traits.emplace_back(llvm::omp::TraitProperty::construct_teams_teams);
3923   if (isOpenMPParallelDirective(DKind))
3924     Traits.emplace_back(llvm::omp::TraitProperty::construct_parallel_parallel);
3925   if (isOpenMPWorksharingDirective(DKind))
3926     Traits.emplace_back(llvm::omp::TraitProperty::construct_for_for);
3927   if (isOpenMPSimdDirective(DKind))
3928     Traits.emplace_back(llvm::omp::TraitProperty::construct_simd_simd);
3929   Stack->handleConstructTrait(Traits, ScopeEntry);
3930 }
3931 
3932 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
3933   switch (DKind) {
3934   case OMPD_parallel:
3935   case OMPD_parallel_for:
3936   case OMPD_parallel_for_simd:
3937   case OMPD_parallel_sections:
3938   case OMPD_parallel_master:
3939   case OMPD_teams:
3940   case OMPD_teams_distribute:
3941   case OMPD_teams_distribute_simd: {
3942     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3943     QualType KmpInt32PtrTy =
3944         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3945     Sema::CapturedParamNameType Params[] = {
3946         std::make_pair(".global_tid.", KmpInt32PtrTy),
3947         std::make_pair(".bound_tid.", KmpInt32PtrTy),
3948         std::make_pair(StringRef(), QualType()) // __context with shared vars
3949     };
3950     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3951                              Params);
3952     break;
3953   }
3954   case OMPD_target_teams:
3955   case OMPD_target_parallel:
3956   case OMPD_target_parallel_for:
3957   case OMPD_target_parallel_for_simd:
3958   case OMPD_target_teams_distribute:
3959   case OMPD_target_teams_distribute_simd: {
3960     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3961     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3962     QualType KmpInt32PtrTy =
3963         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3964     QualType Args[] = {VoidPtrTy};
3965     FunctionProtoType::ExtProtoInfo EPI;
3966     EPI.Variadic = true;
3967     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3968     Sema::CapturedParamNameType Params[] = {
3969         std::make_pair(".global_tid.", KmpInt32Ty),
3970         std::make_pair(".part_id.", KmpInt32PtrTy),
3971         std::make_pair(".privates.", VoidPtrTy),
3972         std::make_pair(
3973             ".copy_fn.",
3974             Context.getPointerType(CopyFnType).withConst().withRestrict()),
3975         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3976         std::make_pair(StringRef(), QualType()) // __context with shared vars
3977     };
3978     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3979                              Params, /*OpenMPCaptureLevel=*/0);
3980     // Mark this captured region as inlined, because we don't use outlined
3981     // function directly.
3982     getCurCapturedRegion()->TheCapturedDecl->addAttr(
3983         AlwaysInlineAttr::CreateImplicit(
3984             Context, {}, AttributeCommonInfo::AS_Keyword,
3985             AlwaysInlineAttr::Keyword_forceinline));
3986     Sema::CapturedParamNameType ParamsTarget[] = {
3987         std::make_pair(StringRef(), QualType()) // __context with shared vars
3988     };
3989     // Start a captured region for 'target' with no implicit parameters.
3990     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3991                              ParamsTarget, /*OpenMPCaptureLevel=*/1);
3992     Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
3993         std::make_pair(".global_tid.", KmpInt32PtrTy),
3994         std::make_pair(".bound_tid.", KmpInt32PtrTy),
3995         std::make_pair(StringRef(), QualType()) // __context with shared vars
3996     };
3997     // Start a captured region for 'teams' or 'parallel'.  Both regions have
3998     // the same implicit parameters.
3999     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4000                              ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
4001     break;
4002   }
4003   case OMPD_target:
4004   case OMPD_target_simd: {
4005     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4006     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4007     QualType KmpInt32PtrTy =
4008         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4009     QualType Args[] = {VoidPtrTy};
4010     FunctionProtoType::ExtProtoInfo EPI;
4011     EPI.Variadic = true;
4012     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4013     Sema::CapturedParamNameType Params[] = {
4014         std::make_pair(".global_tid.", KmpInt32Ty),
4015         std::make_pair(".part_id.", KmpInt32PtrTy),
4016         std::make_pair(".privates.", VoidPtrTy),
4017         std::make_pair(
4018             ".copy_fn.",
4019             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4020         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4021         std::make_pair(StringRef(), QualType()) // __context with shared vars
4022     };
4023     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4024                              Params, /*OpenMPCaptureLevel=*/0);
4025     // Mark this captured region as inlined, because we don't use outlined
4026     // function directly.
4027     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4028         AlwaysInlineAttr::CreateImplicit(
4029             Context, {}, AttributeCommonInfo::AS_Keyword,
4030             AlwaysInlineAttr::Keyword_forceinline));
4031     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4032                              std::make_pair(StringRef(), QualType()),
4033                              /*OpenMPCaptureLevel=*/1);
4034     break;
4035   }
4036   case OMPD_atomic:
4037   case OMPD_critical:
4038   case OMPD_section:
4039   case OMPD_master:
4040   case OMPD_masked:
4041   case OMPD_tile:
4042   case OMPD_unroll:
4043     break;
4044   case OMPD_loop:
4045     // TODO: 'loop' may require additional parameters depending on the binding.
4046     // Treat similar to OMPD_simd/OMPD_for for now.
4047   case OMPD_simd:
4048   case OMPD_for:
4049   case OMPD_for_simd:
4050   case OMPD_sections:
4051   case OMPD_single:
4052   case OMPD_taskgroup:
4053   case OMPD_distribute:
4054   case OMPD_distribute_simd:
4055   case OMPD_ordered:
4056   case OMPD_target_data:
4057   case OMPD_dispatch: {
4058     Sema::CapturedParamNameType Params[] = {
4059         std::make_pair(StringRef(), QualType()) // __context with shared vars
4060     };
4061     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4062                              Params);
4063     break;
4064   }
4065   case OMPD_task: {
4066     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4067     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4068     QualType KmpInt32PtrTy =
4069         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4070     QualType Args[] = {VoidPtrTy};
4071     FunctionProtoType::ExtProtoInfo EPI;
4072     EPI.Variadic = true;
4073     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4074     Sema::CapturedParamNameType Params[] = {
4075         std::make_pair(".global_tid.", KmpInt32Ty),
4076         std::make_pair(".part_id.", KmpInt32PtrTy),
4077         std::make_pair(".privates.", VoidPtrTy),
4078         std::make_pair(
4079             ".copy_fn.",
4080             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4081         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4082         std::make_pair(StringRef(), QualType()) // __context with shared vars
4083     };
4084     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4085                              Params);
4086     // Mark this captured region as inlined, because we don't use outlined
4087     // function directly.
4088     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4089         AlwaysInlineAttr::CreateImplicit(
4090             Context, {}, AttributeCommonInfo::AS_Keyword,
4091             AlwaysInlineAttr::Keyword_forceinline));
4092     break;
4093   }
4094   case OMPD_taskloop:
4095   case OMPD_taskloop_simd:
4096   case OMPD_master_taskloop:
4097   case OMPD_master_taskloop_simd: {
4098     QualType KmpInt32Ty =
4099         Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4100             .withConst();
4101     QualType KmpUInt64Ty =
4102         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4103             .withConst();
4104     QualType KmpInt64Ty =
4105         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4106             .withConst();
4107     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4108     QualType KmpInt32PtrTy =
4109         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4110     QualType Args[] = {VoidPtrTy};
4111     FunctionProtoType::ExtProtoInfo EPI;
4112     EPI.Variadic = true;
4113     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4114     Sema::CapturedParamNameType Params[] = {
4115         std::make_pair(".global_tid.", KmpInt32Ty),
4116         std::make_pair(".part_id.", KmpInt32PtrTy),
4117         std::make_pair(".privates.", VoidPtrTy),
4118         std::make_pair(
4119             ".copy_fn.",
4120             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4121         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4122         std::make_pair(".lb.", KmpUInt64Ty),
4123         std::make_pair(".ub.", KmpUInt64Ty),
4124         std::make_pair(".st.", KmpInt64Ty),
4125         std::make_pair(".liter.", KmpInt32Ty),
4126         std::make_pair(".reductions.", VoidPtrTy),
4127         std::make_pair(StringRef(), QualType()) // __context with shared vars
4128     };
4129     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4130                              Params);
4131     // Mark this captured region as inlined, because we don't use outlined
4132     // function directly.
4133     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4134         AlwaysInlineAttr::CreateImplicit(
4135             Context, {}, AttributeCommonInfo::AS_Keyword,
4136             AlwaysInlineAttr::Keyword_forceinline));
4137     break;
4138   }
4139   case OMPD_parallel_master_taskloop:
4140   case OMPD_parallel_master_taskloop_simd: {
4141     QualType KmpInt32Ty =
4142         Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4143             .withConst();
4144     QualType KmpUInt64Ty =
4145         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4146             .withConst();
4147     QualType KmpInt64Ty =
4148         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4149             .withConst();
4150     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4151     QualType KmpInt32PtrTy =
4152         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4153     Sema::CapturedParamNameType ParamsParallel[] = {
4154         std::make_pair(".global_tid.", KmpInt32PtrTy),
4155         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4156         std::make_pair(StringRef(), QualType()) // __context with shared vars
4157     };
4158     // Start a captured region for 'parallel'.
4159     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4160                              ParamsParallel, /*OpenMPCaptureLevel=*/0);
4161     QualType Args[] = {VoidPtrTy};
4162     FunctionProtoType::ExtProtoInfo EPI;
4163     EPI.Variadic = true;
4164     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4165     Sema::CapturedParamNameType Params[] = {
4166         std::make_pair(".global_tid.", KmpInt32Ty),
4167         std::make_pair(".part_id.", KmpInt32PtrTy),
4168         std::make_pair(".privates.", VoidPtrTy),
4169         std::make_pair(
4170             ".copy_fn.",
4171             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4172         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4173         std::make_pair(".lb.", KmpUInt64Ty),
4174         std::make_pair(".ub.", KmpUInt64Ty),
4175         std::make_pair(".st.", KmpInt64Ty),
4176         std::make_pair(".liter.", KmpInt32Ty),
4177         std::make_pair(".reductions.", VoidPtrTy),
4178         std::make_pair(StringRef(), QualType()) // __context with shared vars
4179     };
4180     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4181                              Params, /*OpenMPCaptureLevel=*/1);
4182     // Mark this captured region as inlined, because we don't use outlined
4183     // function directly.
4184     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4185         AlwaysInlineAttr::CreateImplicit(
4186             Context, {}, AttributeCommonInfo::AS_Keyword,
4187             AlwaysInlineAttr::Keyword_forceinline));
4188     break;
4189   }
4190   case OMPD_distribute_parallel_for_simd:
4191   case OMPD_distribute_parallel_for: {
4192     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4193     QualType KmpInt32PtrTy =
4194         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4195     Sema::CapturedParamNameType Params[] = {
4196         std::make_pair(".global_tid.", KmpInt32PtrTy),
4197         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4198         std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4199         std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4200         std::make_pair(StringRef(), QualType()) // __context with shared vars
4201     };
4202     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4203                              Params);
4204     break;
4205   }
4206   case OMPD_target_teams_distribute_parallel_for:
4207   case OMPD_target_teams_distribute_parallel_for_simd: {
4208     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4209     QualType KmpInt32PtrTy =
4210         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4211     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4212 
4213     QualType Args[] = {VoidPtrTy};
4214     FunctionProtoType::ExtProtoInfo EPI;
4215     EPI.Variadic = true;
4216     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4217     Sema::CapturedParamNameType Params[] = {
4218         std::make_pair(".global_tid.", KmpInt32Ty),
4219         std::make_pair(".part_id.", KmpInt32PtrTy),
4220         std::make_pair(".privates.", VoidPtrTy),
4221         std::make_pair(
4222             ".copy_fn.",
4223             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4224         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4225         std::make_pair(StringRef(), QualType()) // __context with shared vars
4226     };
4227     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4228                              Params, /*OpenMPCaptureLevel=*/0);
4229     // Mark this captured region as inlined, because we don't use outlined
4230     // function directly.
4231     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4232         AlwaysInlineAttr::CreateImplicit(
4233             Context, {}, AttributeCommonInfo::AS_Keyword,
4234             AlwaysInlineAttr::Keyword_forceinline));
4235     Sema::CapturedParamNameType ParamsTarget[] = {
4236         std::make_pair(StringRef(), QualType()) // __context with shared vars
4237     };
4238     // Start a captured region for 'target' with no implicit parameters.
4239     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4240                              ParamsTarget, /*OpenMPCaptureLevel=*/1);
4241 
4242     Sema::CapturedParamNameType ParamsTeams[] = {
4243         std::make_pair(".global_tid.", KmpInt32PtrTy),
4244         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4245         std::make_pair(StringRef(), QualType()) // __context with shared vars
4246     };
4247     // Start a captured region for 'target' with no implicit parameters.
4248     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4249                              ParamsTeams, /*OpenMPCaptureLevel=*/2);
4250 
4251     Sema::CapturedParamNameType ParamsParallel[] = {
4252         std::make_pair(".global_tid.", KmpInt32PtrTy),
4253         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4254         std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4255         std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4256         std::make_pair(StringRef(), QualType()) // __context with shared vars
4257     };
4258     // Start a captured region for 'teams' or 'parallel'.  Both regions have
4259     // the same implicit parameters.
4260     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4261                              ParamsParallel, /*OpenMPCaptureLevel=*/3);
4262     break;
4263   }
4264 
4265   case OMPD_teams_distribute_parallel_for:
4266   case OMPD_teams_distribute_parallel_for_simd: {
4267     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4268     QualType KmpInt32PtrTy =
4269         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4270 
4271     Sema::CapturedParamNameType ParamsTeams[] = {
4272         std::make_pair(".global_tid.", KmpInt32PtrTy),
4273         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4274         std::make_pair(StringRef(), QualType()) // __context with shared vars
4275     };
4276     // Start a captured region for 'target' with no implicit parameters.
4277     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4278                              ParamsTeams, /*OpenMPCaptureLevel=*/0);
4279 
4280     Sema::CapturedParamNameType ParamsParallel[] = {
4281         std::make_pair(".global_tid.", KmpInt32PtrTy),
4282         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4283         std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4284         std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4285         std::make_pair(StringRef(), QualType()) // __context with shared vars
4286     };
4287     // Start a captured region for 'teams' or 'parallel'.  Both regions have
4288     // the same implicit parameters.
4289     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4290                              ParamsParallel, /*OpenMPCaptureLevel=*/1);
4291     break;
4292   }
4293   case OMPD_target_update:
4294   case OMPD_target_enter_data:
4295   case OMPD_target_exit_data: {
4296     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4297     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4298     QualType KmpInt32PtrTy =
4299         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4300     QualType Args[] = {VoidPtrTy};
4301     FunctionProtoType::ExtProtoInfo EPI;
4302     EPI.Variadic = true;
4303     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4304     Sema::CapturedParamNameType Params[] = {
4305         std::make_pair(".global_tid.", KmpInt32Ty),
4306         std::make_pair(".part_id.", KmpInt32PtrTy),
4307         std::make_pair(".privates.", VoidPtrTy),
4308         std::make_pair(
4309             ".copy_fn.",
4310             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4311         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4312         std::make_pair(StringRef(), QualType()) // __context with shared vars
4313     };
4314     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4315                              Params);
4316     // Mark this captured region as inlined, because we don't use outlined
4317     // function directly.
4318     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4319         AlwaysInlineAttr::CreateImplicit(
4320             Context, {}, AttributeCommonInfo::AS_Keyword,
4321             AlwaysInlineAttr::Keyword_forceinline));
4322     break;
4323   }
4324   case OMPD_threadprivate:
4325   case OMPD_allocate:
4326   case OMPD_taskyield:
4327   case OMPD_barrier:
4328   case OMPD_taskwait:
4329   case OMPD_cancellation_point:
4330   case OMPD_cancel:
4331   case OMPD_flush:
4332   case OMPD_depobj:
4333   case OMPD_scan:
4334   case OMPD_declare_reduction:
4335   case OMPD_declare_mapper:
4336   case OMPD_declare_simd:
4337   case OMPD_declare_target:
4338   case OMPD_end_declare_target:
4339   case OMPD_requires:
4340   case OMPD_declare_variant:
4341   case OMPD_begin_declare_variant:
4342   case OMPD_end_declare_variant:
4343   case OMPD_metadirective:
4344     llvm_unreachable("OpenMP Directive is not allowed");
4345   case OMPD_unknown:
4346   default:
4347     llvm_unreachable("Unknown OpenMP directive");
4348   }
4349   DSAStack->setContext(CurContext);
4350   handleDeclareVariantConstructTrait(DSAStack, DKind, /* ScopeEntry */ true);
4351 }
4352 
4353 int Sema::getNumberOfConstructScopes(unsigned Level) const {
4354   return getOpenMPCaptureLevels(DSAStack->getDirective(Level));
4355 }
4356 
4357 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
4358   SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4359   getOpenMPCaptureRegions(CaptureRegions, DKind);
4360   return CaptureRegions.size();
4361 }
4362 
4363 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
4364                                              Expr *CaptureExpr, bool WithInit,
4365                                              bool AsExpression) {
4366   assert(CaptureExpr);
4367   ASTContext &C = S.getASTContext();
4368   Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
4369   QualType Ty = Init->getType();
4370   if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
4371     if (S.getLangOpts().CPlusPlus) {
4372       Ty = C.getLValueReferenceType(Ty);
4373     } else {
4374       Ty = C.getPointerType(Ty);
4375       ExprResult Res =
4376           S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
4377       if (!Res.isUsable())
4378         return nullptr;
4379       Init = Res.get();
4380     }
4381     WithInit = true;
4382   }
4383   auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
4384                                           CaptureExpr->getBeginLoc());
4385   if (!WithInit)
4386     CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
4387   S.CurContext->addHiddenDecl(CED);
4388   Sema::TentativeAnalysisScope Trap(S);
4389   S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
4390   return CED;
4391 }
4392 
4393 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
4394                                  bool WithInit) {
4395   OMPCapturedExprDecl *CD;
4396   if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
4397     CD = cast<OMPCapturedExprDecl>(VD);
4398   else
4399     CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
4400                           /*AsExpression=*/false);
4401   return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4402                           CaptureExpr->getExprLoc());
4403 }
4404 
4405 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
4406   CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
4407   if (!Ref) {
4408     OMPCapturedExprDecl *CD = buildCaptureDecl(
4409         S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
4410         /*WithInit=*/true, /*AsExpression=*/true);
4411     Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4412                            CaptureExpr->getExprLoc());
4413   }
4414   ExprResult Res = Ref;
4415   if (!S.getLangOpts().CPlusPlus &&
4416       CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
4417       Ref->getType()->isPointerType()) {
4418     Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
4419     if (!Res.isUsable())
4420       return ExprError();
4421   }
4422   return S.DefaultLvalueConversion(Res.get());
4423 }
4424 
4425 namespace {
4426 // OpenMP directives parsed in this section are represented as a
4427 // CapturedStatement with an associated statement.  If a syntax error
4428 // is detected during the parsing of the associated statement, the
4429 // compiler must abort processing and close the CapturedStatement.
4430 //
4431 // Combined directives such as 'target parallel' have more than one
4432 // nested CapturedStatements.  This RAII ensures that we unwind out
4433 // of all the nested CapturedStatements when an error is found.
4434 class CaptureRegionUnwinderRAII {
4435 private:
4436   Sema &S;
4437   bool &ErrorFound;
4438   OpenMPDirectiveKind DKind = OMPD_unknown;
4439 
4440 public:
4441   CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
4442                             OpenMPDirectiveKind DKind)
4443       : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
4444   ~CaptureRegionUnwinderRAII() {
4445     if (ErrorFound) {
4446       int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
4447       while (--ThisCaptureLevel >= 0)
4448         S.ActOnCapturedRegionError();
4449     }
4450   }
4451 };
4452 } // namespace
4453 
4454 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) {
4455   // Capture variables captured by reference in lambdas for target-based
4456   // directives.
4457   if (!CurContext->isDependentContext() &&
4458       (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) ||
4459        isOpenMPTargetDataManagementDirective(
4460            DSAStack->getCurrentDirective()))) {
4461     QualType Type = V->getType();
4462     if (const auto *RD = Type.getCanonicalType()
4463                              .getNonReferenceType()
4464                              ->getAsCXXRecordDecl()) {
4465       bool SavedForceCaptureByReferenceInTargetExecutable =
4466           DSAStack->isForceCaptureByReferenceInTargetExecutable();
4467       DSAStack->setForceCaptureByReferenceInTargetExecutable(
4468           /*V=*/true);
4469       if (RD->isLambda()) {
4470         llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
4471         FieldDecl *ThisCapture;
4472         RD->getCaptureFields(Captures, ThisCapture);
4473         for (const LambdaCapture &LC : RD->captures()) {
4474           if (LC.getCaptureKind() == LCK_ByRef) {
4475             VarDecl *VD = LC.getCapturedVar();
4476             DeclContext *VDC = VD->getDeclContext();
4477             if (!VDC->Encloses(CurContext))
4478               continue;
4479             MarkVariableReferenced(LC.getLocation(), VD);
4480           } else if (LC.getCaptureKind() == LCK_This) {
4481             QualType ThisTy = getCurrentThisType();
4482             if (!ThisTy.isNull() &&
4483                 Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
4484               CheckCXXThisCapture(LC.getLocation());
4485           }
4486         }
4487       }
4488       DSAStack->setForceCaptureByReferenceInTargetExecutable(
4489           SavedForceCaptureByReferenceInTargetExecutable);
4490     }
4491   }
4492 }
4493 
4494 static bool checkOrderedOrderSpecified(Sema &S,
4495                                        const ArrayRef<OMPClause *> Clauses) {
4496   const OMPOrderedClause *Ordered = nullptr;
4497   const OMPOrderClause *Order = nullptr;
4498 
4499   for (const OMPClause *Clause : Clauses) {
4500     if (Clause->getClauseKind() == OMPC_ordered)
4501       Ordered = cast<OMPOrderedClause>(Clause);
4502     else if (Clause->getClauseKind() == OMPC_order) {
4503       Order = cast<OMPOrderClause>(Clause);
4504       if (Order->getKind() != OMPC_ORDER_concurrent)
4505         Order = nullptr;
4506     }
4507     if (Ordered && Order)
4508       break;
4509   }
4510 
4511   if (Ordered && Order) {
4512     S.Diag(Order->getKindKwLoc(),
4513            diag::err_omp_simple_clause_incompatible_with_ordered)
4514         << getOpenMPClauseName(OMPC_order)
4515         << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent)
4516         << SourceRange(Order->getBeginLoc(), Order->getEndLoc());
4517     S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param)
4518         << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc());
4519     return true;
4520   }
4521   return false;
4522 }
4523 
4524 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
4525                                       ArrayRef<OMPClause *> Clauses) {
4526   handleDeclareVariantConstructTrait(DSAStack, DSAStack->getCurrentDirective(),
4527                                      /* ScopeEntry */ false);
4528   if (DSAStack->getCurrentDirective() == OMPD_atomic ||
4529       DSAStack->getCurrentDirective() == OMPD_critical ||
4530       DSAStack->getCurrentDirective() == OMPD_section ||
4531       DSAStack->getCurrentDirective() == OMPD_master ||
4532       DSAStack->getCurrentDirective() == OMPD_masked)
4533     return S;
4534 
4535   bool ErrorFound = false;
4536   CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4537       *this, ErrorFound, DSAStack->getCurrentDirective());
4538   if (!S.isUsable()) {
4539     ErrorFound = true;
4540     return StmtError();
4541   }
4542 
4543   SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4544   getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective());
4545   OMPOrderedClause *OC = nullptr;
4546   OMPScheduleClause *SC = nullptr;
4547   SmallVector<const OMPLinearClause *, 4> LCs;
4548   SmallVector<const OMPClauseWithPreInit *, 4> PICs;
4549   // This is required for proper codegen.
4550   for (OMPClause *Clause : Clauses) {
4551     if (!LangOpts.OpenMPSimd &&
4552         isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
4553         Clause->getClauseKind() == OMPC_in_reduction) {
4554       // Capture taskgroup task_reduction descriptors inside the tasking regions
4555       // with the corresponding in_reduction items.
4556       auto *IRC = cast<OMPInReductionClause>(Clause);
4557       for (Expr *E : IRC->taskgroup_descriptors())
4558         if (E)
4559           MarkDeclarationsReferencedInExpr(E);
4560     }
4561     if (isOpenMPPrivate(Clause->getClauseKind()) ||
4562         Clause->getClauseKind() == OMPC_copyprivate ||
4563         (getLangOpts().OpenMPUseTLS &&
4564          getASTContext().getTargetInfo().isTLSSupported() &&
4565          Clause->getClauseKind() == OMPC_copyin)) {
4566       DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
4567       // Mark all variables in private list clauses as used in inner region.
4568       for (Stmt *VarRef : Clause->children()) {
4569         if (auto *E = cast_or_null<Expr>(VarRef)) {
4570           MarkDeclarationsReferencedInExpr(E);
4571         }
4572       }
4573       DSAStack->setForceVarCapturing(/*V=*/false);
4574     } else if (isOpenMPLoopTransformationDirective(
4575                    DSAStack->getCurrentDirective())) {
4576       assert(CaptureRegions.empty() &&
4577              "No captured regions in loop transformation directives.");
4578     } else if (CaptureRegions.size() > 1 ||
4579                CaptureRegions.back() != OMPD_unknown) {
4580       if (auto *C = OMPClauseWithPreInit::get(Clause))
4581         PICs.push_back(C);
4582       if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
4583         if (Expr *E = C->getPostUpdateExpr())
4584           MarkDeclarationsReferencedInExpr(E);
4585       }
4586     }
4587     if (Clause->getClauseKind() == OMPC_schedule)
4588       SC = cast<OMPScheduleClause>(Clause);
4589     else if (Clause->getClauseKind() == OMPC_ordered)
4590       OC = cast<OMPOrderedClause>(Clause);
4591     else if (Clause->getClauseKind() == OMPC_linear)
4592       LCs.push_back(cast<OMPLinearClause>(Clause));
4593   }
4594   // Capture allocator expressions if used.
4595   for (Expr *E : DSAStack->getInnerAllocators())
4596     MarkDeclarationsReferencedInExpr(E);
4597   // OpenMP, 2.7.1 Loop Construct, Restrictions
4598   // The nonmonotonic modifier cannot be specified if an ordered clause is
4599   // specified.
4600   if (SC &&
4601       (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
4602        SC->getSecondScheduleModifier() ==
4603            OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4604       OC) {
4605     Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
4606              ? SC->getFirstScheduleModifierLoc()
4607              : SC->getSecondScheduleModifierLoc(),
4608          diag::err_omp_simple_clause_incompatible_with_ordered)
4609         << getOpenMPClauseName(OMPC_schedule)
4610         << getOpenMPSimpleClauseTypeName(OMPC_schedule,
4611                                          OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4612         << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4613     ErrorFound = true;
4614   }
4615   // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions.
4616   // If an order(concurrent) clause is present, an ordered clause may not appear
4617   // on the same directive.
4618   if (checkOrderedOrderSpecified(*this, Clauses))
4619     ErrorFound = true;
4620   if (!LCs.empty() && OC && OC->getNumForLoops()) {
4621     for (const OMPLinearClause *C : LCs) {
4622       Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
4623           << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4624     }
4625     ErrorFound = true;
4626   }
4627   if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
4628       isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
4629       OC->getNumForLoops()) {
4630     Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
4631         << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
4632     ErrorFound = true;
4633   }
4634   if (ErrorFound) {
4635     return StmtError();
4636   }
4637   StmtResult SR = S;
4638   unsigned CompletedRegions = 0;
4639   for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
4640     // Mark all variables in private list clauses as used in inner region.
4641     // Required for proper codegen of combined directives.
4642     // TODO: add processing for other clauses.
4643     if (ThisCaptureRegion != OMPD_unknown) {
4644       for (const clang::OMPClauseWithPreInit *C : PICs) {
4645         OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
4646         // Find the particular capture region for the clause if the
4647         // directive is a combined one with multiple capture regions.
4648         // If the directive is not a combined one, the capture region
4649         // associated with the clause is OMPD_unknown and is generated
4650         // only once.
4651         if (CaptureRegion == ThisCaptureRegion ||
4652             CaptureRegion == OMPD_unknown) {
4653           if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
4654             for (Decl *D : DS->decls())
4655               MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
4656           }
4657         }
4658       }
4659     }
4660     if (ThisCaptureRegion == OMPD_target) {
4661       // Capture allocator traits in the target region. They are used implicitly
4662       // and, thus, are not captured by default.
4663       for (OMPClause *C : Clauses) {
4664         if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) {
4665           for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4666                ++I) {
4667             OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I);
4668             if (Expr *E = D.AllocatorTraits)
4669               MarkDeclarationsReferencedInExpr(E);
4670           }
4671           continue;
4672         }
4673       }
4674     }
4675     if (ThisCaptureRegion == OMPD_parallel) {
4676       // Capture temp arrays for inscan reductions and locals in aligned
4677       // clauses.
4678       for (OMPClause *C : Clauses) {
4679         if (auto *RC = dyn_cast<OMPReductionClause>(C)) {
4680           if (RC->getModifier() != OMPC_REDUCTION_inscan)
4681             continue;
4682           for (Expr *E : RC->copy_array_temps())
4683             MarkDeclarationsReferencedInExpr(E);
4684         }
4685         if (auto *AC = dyn_cast<OMPAlignedClause>(C)) {
4686           for (Expr *E : AC->varlists())
4687             MarkDeclarationsReferencedInExpr(E);
4688         }
4689       }
4690     }
4691     if (++CompletedRegions == CaptureRegions.size())
4692       DSAStack->setBodyComplete();
4693     SR = ActOnCapturedRegionEnd(SR.get());
4694   }
4695   return SR;
4696 }
4697 
4698 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
4699                               OpenMPDirectiveKind CancelRegion,
4700                               SourceLocation StartLoc) {
4701   // CancelRegion is only needed for cancel and cancellation_point.
4702   if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4703     return false;
4704 
4705   if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4706       CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4707     return false;
4708 
4709   SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4710       << getOpenMPDirectiveName(CancelRegion);
4711   return true;
4712 }
4713 
4714 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4715                                   OpenMPDirectiveKind CurrentRegion,
4716                                   const DeclarationNameInfo &CurrentName,
4717                                   OpenMPDirectiveKind CancelRegion,
4718                                   OpenMPBindClauseKind BindKind,
4719                                   SourceLocation StartLoc) {
4720   if (Stack->getCurScope()) {
4721     OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
4722     OpenMPDirectiveKind OffendingRegion = ParentRegion;
4723     bool NestingProhibited = false;
4724     bool CloseNesting = true;
4725     bool OrphanSeen = false;
4726     enum {
4727       NoRecommend,
4728       ShouldBeInParallelRegion,
4729       ShouldBeInOrderedRegion,
4730       ShouldBeInTargetRegion,
4731       ShouldBeInTeamsRegion,
4732       ShouldBeInLoopSimdRegion,
4733     } Recommend = NoRecommend;
4734     if (isOpenMPSimdDirective(ParentRegion) &&
4735         ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
4736          (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
4737           CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
4738           CurrentRegion != OMPD_scan))) {
4739       // OpenMP [2.16, Nesting of Regions]
4740       // OpenMP constructs may not be nested inside a simd region.
4741       // OpenMP [2.8.1,simd Construct, Restrictions]
4742       // An ordered construct with the simd clause is the only OpenMP
4743       // construct that can appear in the simd region.
4744       // Allowing a SIMD construct nested in another SIMD construct is an
4745       // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
4746       // message.
4747       // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions]
4748       // The only OpenMP constructs that can be encountered during execution of
4749       // a simd region are the atomic construct, the loop construct, the simd
4750       // construct and the ordered construct with the simd clause.
4751       SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
4752                                  ? diag::err_omp_prohibited_region_simd
4753                                  : diag::warn_omp_nesting_simd)
4754           << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0);
4755       return CurrentRegion != OMPD_simd;
4756     }
4757     if (ParentRegion == OMPD_atomic) {
4758       // OpenMP [2.16, Nesting of Regions]
4759       // OpenMP constructs may not be nested inside an atomic region.
4760       SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
4761       return true;
4762     }
4763     if (CurrentRegion == OMPD_section) {
4764       // OpenMP [2.7.2, sections Construct, Restrictions]
4765       // Orphaned section directives are prohibited. That is, the section
4766       // directives must appear within the sections construct and must not be
4767       // encountered elsewhere in the sections region.
4768       if (ParentRegion != OMPD_sections &&
4769           ParentRegion != OMPD_parallel_sections) {
4770         SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
4771             << (ParentRegion != OMPD_unknown)
4772             << getOpenMPDirectiveName(ParentRegion);
4773         return true;
4774       }
4775       return false;
4776     }
4777     // Allow some constructs (except teams and cancellation constructs) to be
4778     // orphaned (they could be used in functions, called from OpenMP regions
4779     // with the required preconditions).
4780     if (ParentRegion == OMPD_unknown &&
4781         !isOpenMPNestingTeamsDirective(CurrentRegion) &&
4782         CurrentRegion != OMPD_cancellation_point &&
4783         CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
4784       return false;
4785     if (CurrentRegion == OMPD_cancellation_point ||
4786         CurrentRegion == OMPD_cancel) {
4787       // OpenMP [2.16, Nesting of Regions]
4788       // A cancellation point construct for which construct-type-clause is
4789       // taskgroup must be nested inside a task construct. A cancellation
4790       // point construct for which construct-type-clause is not taskgroup must
4791       // be closely nested inside an OpenMP construct that matches the type
4792       // specified in construct-type-clause.
4793       // A cancel construct for which construct-type-clause is taskgroup must be
4794       // nested inside a task construct. A cancel construct for which
4795       // construct-type-clause is not taskgroup must be closely nested inside an
4796       // OpenMP construct that matches the type specified in
4797       // construct-type-clause.
4798       NestingProhibited =
4799           !((CancelRegion == OMPD_parallel &&
4800              (ParentRegion == OMPD_parallel ||
4801               ParentRegion == OMPD_target_parallel)) ||
4802             (CancelRegion == OMPD_for &&
4803              (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
4804               ParentRegion == OMPD_target_parallel_for ||
4805               ParentRegion == OMPD_distribute_parallel_for ||
4806               ParentRegion == OMPD_teams_distribute_parallel_for ||
4807               ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
4808             (CancelRegion == OMPD_taskgroup &&
4809              (ParentRegion == OMPD_task ||
4810               (SemaRef.getLangOpts().OpenMP >= 50 &&
4811                (ParentRegion == OMPD_taskloop ||
4812                 ParentRegion == OMPD_master_taskloop ||
4813                 ParentRegion == OMPD_parallel_master_taskloop)))) ||
4814             (CancelRegion == OMPD_sections &&
4815              (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
4816               ParentRegion == OMPD_parallel_sections)));
4817       OrphanSeen = ParentRegion == OMPD_unknown;
4818     } else if (CurrentRegion == OMPD_master || CurrentRegion == OMPD_masked) {
4819       // OpenMP 5.1 [2.22, Nesting of Regions]
4820       // A masked region may not be closely nested inside a worksharing, loop,
4821       // atomic, task, or taskloop region.
4822       NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4823                           isOpenMPGenericLoopDirective(ParentRegion) ||
4824                           isOpenMPTaskingDirective(ParentRegion);
4825     } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
4826       // OpenMP [2.16, Nesting of Regions]
4827       // A critical region may not be nested (closely or otherwise) inside a
4828       // critical region with the same name. Note that this restriction is not
4829       // sufficient to prevent deadlock.
4830       SourceLocation PreviousCriticalLoc;
4831       bool DeadLock = Stack->hasDirective(
4832           [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
4833                                               const DeclarationNameInfo &DNI,
4834                                               SourceLocation Loc) {
4835             if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
4836               PreviousCriticalLoc = Loc;
4837               return true;
4838             }
4839             return false;
4840           },
4841           false /* skip top directive */);
4842       if (DeadLock) {
4843         SemaRef.Diag(StartLoc,
4844                      diag::err_omp_prohibited_region_critical_same_name)
4845             << CurrentName.getName();
4846         if (PreviousCriticalLoc.isValid())
4847           SemaRef.Diag(PreviousCriticalLoc,
4848                        diag::note_omp_previous_critical_region);
4849         return true;
4850       }
4851     } else if (CurrentRegion == OMPD_barrier) {
4852       // OpenMP 5.1 [2.22, Nesting of Regions]
4853       // A barrier region may not be closely nested inside a worksharing, loop,
4854       // task, taskloop, critical, ordered, atomic, or masked region.
4855       NestingProhibited =
4856           isOpenMPWorksharingDirective(ParentRegion) ||
4857           isOpenMPGenericLoopDirective(ParentRegion) ||
4858           isOpenMPTaskingDirective(ParentRegion) ||
4859           ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
4860           ParentRegion == OMPD_parallel_master ||
4861           ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
4862     } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
4863                !isOpenMPParallelDirective(CurrentRegion) &&
4864                !isOpenMPTeamsDirective(CurrentRegion)) {
4865       // OpenMP 5.1 [2.22, Nesting of Regions]
4866       // A loop region that binds to a parallel region or a worksharing region
4867       // may not be closely nested inside a worksharing, loop, task, taskloop,
4868       // critical, ordered, atomic, or masked region.
4869       NestingProhibited =
4870           isOpenMPWorksharingDirective(ParentRegion) ||
4871           isOpenMPGenericLoopDirective(ParentRegion) ||
4872           isOpenMPTaskingDirective(ParentRegion) ||
4873           ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
4874           ParentRegion == OMPD_parallel_master ||
4875           ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
4876       Recommend = ShouldBeInParallelRegion;
4877     } else if (CurrentRegion == OMPD_ordered) {
4878       // OpenMP [2.16, Nesting of Regions]
4879       // An ordered region may not be closely nested inside a critical,
4880       // atomic, or explicit task region.
4881       // An ordered region must be closely nested inside a loop region (or
4882       // parallel loop region) with an ordered clause.
4883       // OpenMP [2.8.1,simd Construct, Restrictions]
4884       // An ordered construct with the simd clause is the only OpenMP construct
4885       // that can appear in the simd region.
4886       NestingProhibited = ParentRegion == OMPD_critical ||
4887                           isOpenMPTaskingDirective(ParentRegion) ||
4888                           !(isOpenMPSimdDirective(ParentRegion) ||
4889                             Stack->isParentOrderedRegion());
4890       Recommend = ShouldBeInOrderedRegion;
4891     } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
4892       // OpenMP [2.16, Nesting of Regions]
4893       // If specified, a teams construct must be contained within a target
4894       // construct.
4895       NestingProhibited =
4896           (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
4897           (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
4898            ParentRegion != OMPD_target);
4899       OrphanSeen = ParentRegion == OMPD_unknown;
4900       Recommend = ShouldBeInTargetRegion;
4901     } else if (CurrentRegion == OMPD_scan) {
4902       // OpenMP [2.16, Nesting of Regions]
4903       // If specified, a teams construct must be contained within a target
4904       // construct.
4905       NestingProhibited =
4906           SemaRef.LangOpts.OpenMP < 50 ||
4907           (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
4908            ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
4909            ParentRegion != OMPD_parallel_for_simd);
4910       OrphanSeen = ParentRegion == OMPD_unknown;
4911       Recommend = ShouldBeInLoopSimdRegion;
4912     }
4913     if (!NestingProhibited &&
4914         !isOpenMPTargetExecutionDirective(CurrentRegion) &&
4915         !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
4916         (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
4917       // OpenMP [5.1, 2.22, Nesting of Regions]
4918       // distribute, distribute simd, distribute parallel worksharing-loop,
4919       // distribute parallel worksharing-loop SIMD, loop, parallel regions,
4920       // including any parallel regions arising from combined constructs,
4921       // omp_get_num_teams() regions, and omp_get_team_num() regions are the
4922       // only OpenMP regions that may be strictly nested inside the teams
4923       // region.
4924       NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
4925                           !isOpenMPDistributeDirective(CurrentRegion) &&
4926                           CurrentRegion != OMPD_loop;
4927       Recommend = ShouldBeInParallelRegion;
4928     }
4929     if (!NestingProhibited && CurrentRegion == OMPD_loop) {
4930       // OpenMP [5.1, 2.11.7, loop Construct, Restrictions]
4931       // If the bind clause is present on the loop construct and binding is
4932       // teams then the corresponding loop region must be strictly nested inside
4933       // a teams region.
4934       NestingProhibited = BindKind == OMPC_BIND_teams &&
4935                           ParentRegion != OMPD_teams &&
4936                           ParentRegion != OMPD_target_teams;
4937       Recommend = ShouldBeInTeamsRegion;
4938     }
4939     if (!NestingProhibited &&
4940         isOpenMPNestingDistributeDirective(CurrentRegion)) {
4941       // OpenMP 4.5 [2.17 Nesting of Regions]
4942       // The region associated with the distribute construct must be strictly
4943       // nested inside a teams region
4944       NestingProhibited =
4945           (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
4946       Recommend = ShouldBeInTeamsRegion;
4947     }
4948     if (!NestingProhibited &&
4949         (isOpenMPTargetExecutionDirective(CurrentRegion) ||
4950          isOpenMPTargetDataManagementDirective(CurrentRegion))) {
4951       // OpenMP 4.5 [2.17 Nesting of Regions]
4952       // If a target, target update, target data, target enter data, or
4953       // target exit data construct is encountered during execution of a
4954       // target region, the behavior is unspecified.
4955       NestingProhibited = Stack->hasDirective(
4956           [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
4957                              SourceLocation) {
4958             if (isOpenMPTargetExecutionDirective(K)) {
4959               OffendingRegion = K;
4960               return true;
4961             }
4962             return false;
4963           },
4964           false /* don't skip top directive */);
4965       CloseNesting = false;
4966     }
4967     if (NestingProhibited) {
4968       if (OrphanSeen) {
4969         SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
4970             << getOpenMPDirectiveName(CurrentRegion) << Recommend;
4971       } else {
4972         SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
4973             << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
4974             << Recommend << getOpenMPDirectiveName(CurrentRegion);
4975       }
4976       return true;
4977     }
4978   }
4979   return false;
4980 }
4981 
4982 struct Kind2Unsigned {
4983   using argument_type = OpenMPDirectiveKind;
4984   unsigned operator()(argument_type DK) { return unsigned(DK); }
4985 };
4986 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
4987                            ArrayRef<OMPClause *> Clauses,
4988                            ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
4989   bool ErrorFound = false;
4990   unsigned NamedModifiersNumber = 0;
4991   llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
4992   FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
4993   SmallVector<SourceLocation, 4> NameModifierLoc;
4994   for (const OMPClause *C : Clauses) {
4995     if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
4996       // At most one if clause without a directive-name-modifier can appear on
4997       // the directive.
4998       OpenMPDirectiveKind CurNM = IC->getNameModifier();
4999       if (FoundNameModifiers[CurNM]) {
5000         S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
5001             << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
5002             << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
5003         ErrorFound = true;
5004       } else if (CurNM != OMPD_unknown) {
5005         NameModifierLoc.push_back(IC->getNameModifierLoc());
5006         ++NamedModifiersNumber;
5007       }
5008       FoundNameModifiers[CurNM] = IC;
5009       if (CurNM == OMPD_unknown)
5010         continue;
5011       // Check if the specified name modifier is allowed for the current
5012       // directive.
5013       // At most one if clause with the particular directive-name-modifier can
5014       // appear on the directive.
5015       if (!llvm::is_contained(AllowedNameModifiers, CurNM)) {
5016         S.Diag(IC->getNameModifierLoc(),
5017                diag::err_omp_wrong_if_directive_name_modifier)
5018             << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
5019         ErrorFound = true;
5020       }
5021     }
5022   }
5023   // If any if clause on the directive includes a directive-name-modifier then
5024   // all if clauses on the directive must include a directive-name-modifier.
5025   if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
5026     if (NamedModifiersNumber == AllowedNameModifiers.size()) {
5027       S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
5028              diag::err_omp_no_more_if_clause);
5029     } else {
5030       std::string Values;
5031       std::string Sep(", ");
5032       unsigned AllowedCnt = 0;
5033       unsigned TotalAllowedNum =
5034           AllowedNameModifiers.size() - NamedModifiersNumber;
5035       for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
5036            ++Cnt) {
5037         OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
5038         if (!FoundNameModifiers[NM]) {
5039           Values += "'";
5040           Values += getOpenMPDirectiveName(NM);
5041           Values += "'";
5042           if (AllowedCnt + 2 == TotalAllowedNum)
5043             Values += " or ";
5044           else if (AllowedCnt + 1 != TotalAllowedNum)
5045             Values += Sep;
5046           ++AllowedCnt;
5047         }
5048       }
5049       S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
5050              diag::err_omp_unnamed_if_clause)
5051           << (TotalAllowedNum > 1) << Values;
5052     }
5053     for (SourceLocation Loc : NameModifierLoc) {
5054       S.Diag(Loc, diag::note_omp_previous_named_if_clause);
5055     }
5056     ErrorFound = true;
5057   }
5058   return ErrorFound;
5059 }
5060 
5061 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
5062                                                    SourceLocation &ELoc,
5063                                                    SourceRange &ERange,
5064                                                    bool AllowArraySection) {
5065   if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
5066       RefExpr->containsUnexpandedParameterPack())
5067     return std::make_pair(nullptr, true);
5068 
5069   // OpenMP [3.1, C/C++]
5070   //  A list item is a variable name.
5071   // OpenMP  [2.9.3.3, Restrictions, p.1]
5072   //  A variable that is part of another variable (as an array or
5073   //  structure element) cannot appear in a private clause.
5074   RefExpr = RefExpr->IgnoreParens();
5075   enum {
5076     NoArrayExpr = -1,
5077     ArraySubscript = 0,
5078     OMPArraySection = 1
5079   } IsArrayExpr = NoArrayExpr;
5080   if (AllowArraySection) {
5081     if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
5082       Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
5083       while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
5084         Base = TempASE->getBase()->IgnoreParenImpCasts();
5085       RefExpr = Base;
5086       IsArrayExpr = ArraySubscript;
5087     } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
5088       Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
5089       while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
5090         Base = TempOASE->getBase()->IgnoreParenImpCasts();
5091       while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
5092         Base = TempASE->getBase()->IgnoreParenImpCasts();
5093       RefExpr = Base;
5094       IsArrayExpr = OMPArraySection;
5095     }
5096   }
5097   ELoc = RefExpr->getExprLoc();
5098   ERange = RefExpr->getSourceRange();
5099   RefExpr = RefExpr->IgnoreParenImpCasts();
5100   auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
5101   auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
5102   if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
5103       (S.getCurrentThisType().isNull() || !ME ||
5104        !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
5105        !isa<FieldDecl>(ME->getMemberDecl()))) {
5106     if (IsArrayExpr != NoArrayExpr) {
5107       S.Diag(ELoc, diag::err_omp_expected_base_var_name)
5108           << IsArrayExpr << ERange;
5109     } else {
5110       S.Diag(ELoc,
5111              AllowArraySection
5112                  ? diag::err_omp_expected_var_name_member_expr_or_array_item
5113                  : diag::err_omp_expected_var_name_member_expr)
5114           << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
5115     }
5116     return std::make_pair(nullptr, false);
5117   }
5118   return std::make_pair(
5119       getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
5120 }
5121 
5122 namespace {
5123 /// Checks if the allocator is used in uses_allocators clause to be allowed in
5124 /// target regions.
5125 class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> {
5126   DSAStackTy *S = nullptr;
5127 
5128 public:
5129   bool VisitDeclRefExpr(const DeclRefExpr *E) {
5130     return S->isUsesAllocatorsDecl(E->getDecl())
5131                .getValueOr(
5132                    DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
5133            DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
5134   }
5135   bool VisitStmt(const Stmt *S) {
5136     for (const Stmt *Child : S->children()) {
5137       if (Child && Visit(Child))
5138         return true;
5139     }
5140     return false;
5141   }
5142   explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
5143 };
5144 } // namespace
5145 
5146 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
5147                                  ArrayRef<OMPClause *> Clauses) {
5148   assert(!S.CurContext->isDependentContext() &&
5149          "Expected non-dependent context.");
5150   auto AllocateRange =
5151       llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
5152   llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> DeclToCopy;
5153   auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
5154     return isOpenMPPrivate(C->getClauseKind());
5155   });
5156   for (OMPClause *Cl : PrivateRange) {
5157     MutableArrayRef<Expr *>::iterator I, It, Et;
5158     if (Cl->getClauseKind() == OMPC_private) {
5159       auto *PC = cast<OMPPrivateClause>(Cl);
5160       I = PC->private_copies().begin();
5161       It = PC->varlist_begin();
5162       Et = PC->varlist_end();
5163     } else if (Cl->getClauseKind() == OMPC_firstprivate) {
5164       auto *PC = cast<OMPFirstprivateClause>(Cl);
5165       I = PC->private_copies().begin();
5166       It = PC->varlist_begin();
5167       Et = PC->varlist_end();
5168     } else if (Cl->getClauseKind() == OMPC_lastprivate) {
5169       auto *PC = cast<OMPLastprivateClause>(Cl);
5170       I = PC->private_copies().begin();
5171       It = PC->varlist_begin();
5172       Et = PC->varlist_end();
5173     } else if (Cl->getClauseKind() == OMPC_linear) {
5174       auto *PC = cast<OMPLinearClause>(Cl);
5175       I = PC->privates().begin();
5176       It = PC->varlist_begin();
5177       Et = PC->varlist_end();
5178     } else if (Cl->getClauseKind() == OMPC_reduction) {
5179       auto *PC = cast<OMPReductionClause>(Cl);
5180       I = PC->privates().begin();
5181       It = PC->varlist_begin();
5182       Et = PC->varlist_end();
5183     } else if (Cl->getClauseKind() == OMPC_task_reduction) {
5184       auto *PC = cast<OMPTaskReductionClause>(Cl);
5185       I = PC->privates().begin();
5186       It = PC->varlist_begin();
5187       Et = PC->varlist_end();
5188     } else if (Cl->getClauseKind() == OMPC_in_reduction) {
5189       auto *PC = cast<OMPInReductionClause>(Cl);
5190       I = PC->privates().begin();
5191       It = PC->varlist_begin();
5192       Et = PC->varlist_end();
5193     } else {
5194       llvm_unreachable("Expected private clause.");
5195     }
5196     for (Expr *E : llvm::make_range(It, Et)) {
5197       if (!*I) {
5198         ++I;
5199         continue;
5200       }
5201       SourceLocation ELoc;
5202       SourceRange ERange;
5203       Expr *SimpleRefExpr = E;
5204       auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
5205                                 /*AllowArraySection=*/true);
5206       DeclToCopy.try_emplace(Res.first,
5207                              cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
5208       ++I;
5209     }
5210   }
5211   for (OMPClause *C : AllocateRange) {
5212     auto *AC = cast<OMPAllocateClause>(C);
5213     if (S.getLangOpts().OpenMP >= 50 &&
5214         !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() &&
5215         isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
5216         AC->getAllocator()) {
5217       Expr *Allocator = AC->getAllocator();
5218       // OpenMP, 2.12.5 target Construct
5219       // Memory allocators that do not appear in a uses_allocators clause cannot
5220       // appear as an allocator in an allocate clause or be used in the target
5221       // region unless a requires directive with the dynamic_allocators clause
5222       // is present in the same compilation unit.
5223       AllocatorChecker Checker(Stack);
5224       if (Checker.Visit(Allocator))
5225         S.Diag(Allocator->getExprLoc(),
5226                diag::err_omp_allocator_not_in_uses_allocators)
5227             << Allocator->getSourceRange();
5228     }
5229     OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
5230         getAllocatorKind(S, Stack, AC->getAllocator());
5231     // OpenMP, 2.11.4 allocate Clause, Restrictions.
5232     // For task, taskloop or target directives, allocation requests to memory
5233     // allocators with the trait access set to thread result in unspecified
5234     // behavior.
5235     if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
5236         (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
5237          isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
5238       S.Diag(AC->getAllocator()->getExprLoc(),
5239              diag::warn_omp_allocate_thread_on_task_target_directive)
5240           << getOpenMPDirectiveName(Stack->getCurrentDirective());
5241     }
5242     for (Expr *E : AC->varlists()) {
5243       SourceLocation ELoc;
5244       SourceRange ERange;
5245       Expr *SimpleRefExpr = E;
5246       auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
5247       ValueDecl *VD = Res.first;
5248       DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
5249       if (!isOpenMPPrivate(Data.CKind)) {
5250         S.Diag(E->getExprLoc(),
5251                diag::err_omp_expected_private_copy_for_allocate);
5252         continue;
5253       }
5254       VarDecl *PrivateVD = DeclToCopy[VD];
5255       if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
5256                                             AllocatorKind, AC->getAllocator()))
5257         continue;
5258       // Placeholder until allocate clause supports align modifier.
5259       Expr *Alignment = nullptr;
5260       applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
5261                                 Alignment, E->getSourceRange());
5262     }
5263   }
5264 }
5265 
5266 namespace {
5267 /// Rewrite statements and expressions for Sema \p Actions CurContext.
5268 ///
5269 /// Used to wrap already parsed statements/expressions into a new CapturedStmt
5270 /// context. DeclRefExpr used inside the new context are changed to refer to the
5271 /// captured variable instead.
5272 class CaptureVars : public TreeTransform<CaptureVars> {
5273   using BaseTransform = TreeTransform<CaptureVars>;
5274 
5275 public:
5276   CaptureVars(Sema &Actions) : BaseTransform(Actions) {}
5277 
5278   bool AlwaysRebuild() { return true; }
5279 };
5280 } // namespace
5281 
5282 static VarDecl *precomputeExpr(Sema &Actions,
5283                                SmallVectorImpl<Stmt *> &BodyStmts, Expr *E,
5284                                StringRef Name) {
5285   Expr *NewE = AssertSuccess(CaptureVars(Actions).TransformExpr(E));
5286   VarDecl *NewVar = buildVarDecl(Actions, {}, NewE->getType(), Name, nullptr,
5287                                  dyn_cast<DeclRefExpr>(E->IgnoreImplicit()));
5288   auto *NewDeclStmt = cast<DeclStmt>(AssertSuccess(
5289       Actions.ActOnDeclStmt(Actions.ConvertDeclToDeclGroup(NewVar), {}, {})));
5290   Actions.AddInitializerToDecl(NewDeclStmt->getSingleDecl(), NewE, false);
5291   BodyStmts.push_back(NewDeclStmt);
5292   return NewVar;
5293 }
5294 
5295 /// Create a closure that computes the number of iterations of a loop.
5296 ///
5297 /// \param Actions   The Sema object.
5298 /// \param LogicalTy Type for the logical iteration number.
5299 /// \param Rel       Comparison operator of the loop condition.
5300 /// \param StartExpr Value of the loop counter at the first iteration.
5301 /// \param StopExpr  Expression the loop counter is compared against in the loop
5302 /// condition. \param StepExpr      Amount of increment after each iteration.
5303 ///
5304 /// \return Closure (CapturedStmt) of the distance calculation.
5305 static CapturedStmt *buildDistanceFunc(Sema &Actions, QualType LogicalTy,
5306                                        BinaryOperator::Opcode Rel,
5307                                        Expr *StartExpr, Expr *StopExpr,
5308                                        Expr *StepExpr) {
5309   ASTContext &Ctx = Actions.getASTContext();
5310   TypeSourceInfo *LogicalTSI = Ctx.getTrivialTypeSourceInfo(LogicalTy);
5311 
5312   // Captured regions currently don't support return values, we use an
5313   // out-parameter instead. All inputs are implicit captures.
5314   // TODO: Instead of capturing each DeclRefExpr occurring in
5315   // StartExpr/StopExpr/Step, these could also be passed as a value capture.
5316   QualType ResultTy = Ctx.getLValueReferenceType(LogicalTy);
5317   Sema::CapturedParamNameType Params[] = {{"Distance", ResultTy},
5318                                           {StringRef(), QualType()}};
5319   Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5320 
5321   Stmt *Body;
5322   {
5323     Sema::CompoundScopeRAII CompoundScope(Actions);
5324     CapturedDecl *CS = cast<CapturedDecl>(Actions.CurContext);
5325 
5326     // Get the LValue expression for the result.
5327     ImplicitParamDecl *DistParam = CS->getParam(0);
5328     DeclRefExpr *DistRef = Actions.BuildDeclRefExpr(
5329         DistParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5330 
5331     SmallVector<Stmt *, 4> BodyStmts;
5332 
5333     // Capture all referenced variable references.
5334     // TODO: Instead of computing NewStart/NewStop/NewStep inside the
5335     // CapturedStmt, we could compute them before and capture the result, to be
5336     // used jointly with the LoopVar function.
5337     VarDecl *NewStart = precomputeExpr(Actions, BodyStmts, StartExpr, ".start");
5338     VarDecl *NewStop = precomputeExpr(Actions, BodyStmts, StopExpr, ".stop");
5339     VarDecl *NewStep = precomputeExpr(Actions, BodyStmts, StepExpr, ".step");
5340     auto BuildVarRef = [&](VarDecl *VD) {
5341       return buildDeclRefExpr(Actions, VD, VD->getType(), {});
5342     };
5343 
5344     IntegerLiteral *Zero = IntegerLiteral::Create(
5345         Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 0), LogicalTy, {});
5346     IntegerLiteral *One = IntegerLiteral::Create(
5347         Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {});
5348     Expr *Dist;
5349     if (Rel == BO_NE) {
5350       // When using a != comparison, the increment can be +1 or -1. This can be
5351       // dynamic at runtime, so we need to check for the direction.
5352       Expr *IsNegStep = AssertSuccess(
5353           Actions.BuildBinOp(nullptr, {}, BO_LT, BuildVarRef(NewStep), Zero));
5354 
5355       // Positive increment.
5356       Expr *ForwardRange = AssertSuccess(Actions.BuildBinOp(
5357           nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5358       ForwardRange = AssertSuccess(
5359           Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, ForwardRange));
5360       Expr *ForwardDist = AssertSuccess(Actions.BuildBinOp(
5361           nullptr, {}, BO_Div, ForwardRange, BuildVarRef(NewStep)));
5362 
5363       // Negative increment.
5364       Expr *BackwardRange = AssertSuccess(Actions.BuildBinOp(
5365           nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5366       BackwardRange = AssertSuccess(
5367           Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, BackwardRange));
5368       Expr *NegIncAmount = AssertSuccess(
5369           Actions.BuildUnaryOp(nullptr, {}, UO_Minus, BuildVarRef(NewStep)));
5370       Expr *BackwardDist = AssertSuccess(
5371           Actions.BuildBinOp(nullptr, {}, BO_Div, BackwardRange, NegIncAmount));
5372 
5373       // Use the appropriate case.
5374       Dist = AssertSuccess(Actions.ActOnConditionalOp(
5375           {}, {}, IsNegStep, BackwardDist, ForwardDist));
5376     } else {
5377       assert((Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT) &&
5378              "Expected one of these relational operators");
5379 
5380       // We can derive the direction from any other comparison operator. It is
5381       // non well-formed OpenMP if Step increments/decrements in the other
5382       // directions. Whether at least the first iteration passes the loop
5383       // condition.
5384       Expr *HasAnyIteration = AssertSuccess(Actions.BuildBinOp(
5385           nullptr, {}, Rel, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5386 
5387       // Compute the range between first and last counter value.
5388       Expr *Range;
5389       if (Rel == BO_GE || Rel == BO_GT)
5390         Range = AssertSuccess(Actions.BuildBinOp(
5391             nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5392       else
5393         Range = AssertSuccess(Actions.BuildBinOp(
5394             nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5395 
5396       // Ensure unsigned range space.
5397       Range =
5398           AssertSuccess(Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, Range));
5399 
5400       if (Rel == BO_LE || Rel == BO_GE) {
5401         // Add one to the range if the relational operator is inclusive.
5402         Range =
5403             AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, Range, One));
5404       }
5405 
5406       // Divide by the absolute step amount. If the range is not a multiple of
5407       // the step size, rounding-up the effective upper bound ensures that the
5408       // last iteration is included.
5409       // Note that the rounding-up may cause an overflow in a temporry that
5410       // could be avoided, but would have occurred in a C-style for-loop as well.
5411       Expr *Divisor = BuildVarRef(NewStep);
5412       if (Rel == BO_GE || Rel == BO_GT)
5413         Divisor =
5414             AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Minus, Divisor));
5415       Expr *DivisorMinusOne =
5416           AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Sub, Divisor, One));
5417       Expr *RangeRoundUp = AssertSuccess(
5418           Actions.BuildBinOp(nullptr, {}, BO_Add, Range, DivisorMinusOne));
5419       Dist = AssertSuccess(
5420           Actions.BuildBinOp(nullptr, {}, BO_Div, RangeRoundUp, Divisor));
5421 
5422       // If there is not at least one iteration, the range contains garbage. Fix
5423       // to zero in this case.
5424       Dist = AssertSuccess(
5425           Actions.ActOnConditionalOp({}, {}, HasAnyIteration, Dist, Zero));
5426     }
5427 
5428     // Assign the result to the out-parameter.
5429     Stmt *ResultAssign = AssertSuccess(Actions.BuildBinOp(
5430         Actions.getCurScope(), {}, BO_Assign, DistRef, Dist));
5431     BodyStmts.push_back(ResultAssign);
5432 
5433     Body = AssertSuccess(Actions.ActOnCompoundStmt({}, {}, BodyStmts, false));
5434   }
5435 
5436   return cast<CapturedStmt>(
5437       AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5438 }
5439 
5440 /// Create a closure that computes the loop variable from the logical iteration
5441 /// number.
5442 ///
5443 /// \param Actions   The Sema object.
5444 /// \param LoopVarTy Type for the loop variable used for result value.
5445 /// \param LogicalTy Type for the logical iteration number.
5446 /// \param StartExpr Value of the loop counter at the first iteration.
5447 /// \param Step      Amount of increment after each iteration.
5448 /// \param Deref     Whether the loop variable is a dereference of the loop
5449 /// counter variable.
5450 ///
5451 /// \return Closure (CapturedStmt) of the loop value calculation.
5452 static CapturedStmt *buildLoopVarFunc(Sema &Actions, QualType LoopVarTy,
5453                                       QualType LogicalTy,
5454                                       DeclRefExpr *StartExpr, Expr *Step,
5455                                       bool Deref) {
5456   ASTContext &Ctx = Actions.getASTContext();
5457 
5458   // Pass the result as an out-parameter. Passing as return value would require
5459   // the OpenMPIRBuilder to know additional C/C++ semantics, such as how to
5460   // invoke a copy constructor.
5461   QualType TargetParamTy = Ctx.getLValueReferenceType(LoopVarTy);
5462   Sema::CapturedParamNameType Params[] = {{"LoopVar", TargetParamTy},
5463                                           {"Logical", LogicalTy},
5464                                           {StringRef(), QualType()}};
5465   Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5466 
5467   // Capture the initial iterator which represents the LoopVar value at the
5468   // zero's logical iteration. Since the original ForStmt/CXXForRangeStmt update
5469   // it in every iteration, capture it by value before it is modified.
5470   VarDecl *StartVar = cast<VarDecl>(StartExpr->getDecl());
5471   bool Invalid = Actions.tryCaptureVariable(StartVar, {},
5472                                             Sema::TryCapture_ExplicitByVal, {});
5473   (void)Invalid;
5474   assert(!Invalid && "Expecting capture-by-value to work.");
5475 
5476   Expr *Body;
5477   {
5478     Sema::CompoundScopeRAII CompoundScope(Actions);
5479     auto *CS = cast<CapturedDecl>(Actions.CurContext);
5480 
5481     ImplicitParamDecl *TargetParam = CS->getParam(0);
5482     DeclRefExpr *TargetRef = Actions.BuildDeclRefExpr(
5483         TargetParam, LoopVarTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5484     ImplicitParamDecl *IndvarParam = CS->getParam(1);
5485     DeclRefExpr *LogicalRef = Actions.BuildDeclRefExpr(
5486         IndvarParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5487 
5488     // Capture the Start expression.
5489     CaptureVars Recap(Actions);
5490     Expr *NewStart = AssertSuccess(Recap.TransformExpr(StartExpr));
5491     Expr *NewStep = AssertSuccess(Recap.TransformExpr(Step));
5492 
5493     Expr *Skip = AssertSuccess(
5494         Actions.BuildBinOp(nullptr, {}, BO_Mul, NewStep, LogicalRef));
5495     // TODO: Explicitly cast to the iterator's difference_type instead of
5496     // relying on implicit conversion.
5497     Expr *Advanced =
5498         AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, NewStart, Skip));
5499 
5500     if (Deref) {
5501       // For range-based for-loops convert the loop counter value to a concrete
5502       // loop variable value by dereferencing the iterator.
5503       Advanced =
5504           AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Deref, Advanced));
5505     }
5506 
5507     // Assign the result to the output parameter.
5508     Body = AssertSuccess(Actions.BuildBinOp(Actions.getCurScope(), {},
5509                                             BO_Assign, TargetRef, Advanced));
5510   }
5511   return cast<CapturedStmt>(
5512       AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5513 }
5514 
5515 StmtResult Sema::ActOnOpenMPCanonicalLoop(Stmt *AStmt) {
5516   ASTContext &Ctx = getASTContext();
5517 
5518   // Extract the common elements of ForStmt and CXXForRangeStmt:
5519   // Loop variable, repeat condition, increment
5520   Expr *Cond, *Inc;
5521   VarDecl *LIVDecl, *LUVDecl;
5522   if (auto *For = dyn_cast<ForStmt>(AStmt)) {
5523     Stmt *Init = For->getInit();
5524     if (auto *LCVarDeclStmt = dyn_cast<DeclStmt>(Init)) {
5525       // For statement declares loop variable.
5526       LIVDecl = cast<VarDecl>(LCVarDeclStmt->getSingleDecl());
5527     } else if (auto *LCAssign = dyn_cast<BinaryOperator>(Init)) {
5528       // For statement reuses variable.
5529       assert(LCAssign->getOpcode() == BO_Assign &&
5530              "init part must be a loop variable assignment");
5531       auto *CounterRef = cast<DeclRefExpr>(LCAssign->getLHS());
5532       LIVDecl = cast<VarDecl>(CounterRef->getDecl());
5533     } else
5534       llvm_unreachable("Cannot determine loop variable");
5535     LUVDecl = LIVDecl;
5536 
5537     Cond = For->getCond();
5538     Inc = For->getInc();
5539   } else if (auto *RangeFor = dyn_cast<CXXForRangeStmt>(AStmt)) {
5540     DeclStmt *BeginStmt = RangeFor->getBeginStmt();
5541     LIVDecl = cast<VarDecl>(BeginStmt->getSingleDecl());
5542     LUVDecl = RangeFor->getLoopVariable();
5543 
5544     Cond = RangeFor->getCond();
5545     Inc = RangeFor->getInc();
5546   } else
5547     llvm_unreachable("unhandled kind of loop");
5548 
5549   QualType CounterTy = LIVDecl->getType();
5550   QualType LVTy = LUVDecl->getType();
5551 
5552   // Analyze the loop condition.
5553   Expr *LHS, *RHS;
5554   BinaryOperator::Opcode CondRel;
5555   Cond = Cond->IgnoreImplicit();
5556   if (auto *CondBinExpr = dyn_cast<BinaryOperator>(Cond)) {
5557     LHS = CondBinExpr->getLHS();
5558     RHS = CondBinExpr->getRHS();
5559     CondRel = CondBinExpr->getOpcode();
5560   } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Cond)) {
5561     assert(CondCXXOp->getNumArgs() == 2 && "Comparison should have 2 operands");
5562     LHS = CondCXXOp->getArg(0);
5563     RHS = CondCXXOp->getArg(1);
5564     switch (CondCXXOp->getOperator()) {
5565     case OO_ExclaimEqual:
5566       CondRel = BO_NE;
5567       break;
5568     case OO_Less:
5569       CondRel = BO_LT;
5570       break;
5571     case OO_LessEqual:
5572       CondRel = BO_LE;
5573       break;
5574     case OO_Greater:
5575       CondRel = BO_GT;
5576       break;
5577     case OO_GreaterEqual:
5578       CondRel = BO_GE;
5579       break;
5580     default:
5581       llvm_unreachable("unexpected iterator operator");
5582     }
5583   } else
5584     llvm_unreachable("unexpected loop condition");
5585 
5586   // Normalize such that the loop counter is on the LHS.
5587   if (!isa<DeclRefExpr>(LHS->IgnoreImplicit()) ||
5588       cast<DeclRefExpr>(LHS->IgnoreImplicit())->getDecl() != LIVDecl) {
5589     std::swap(LHS, RHS);
5590     CondRel = BinaryOperator::reverseComparisonOp(CondRel);
5591   }
5592   auto *CounterRef = cast<DeclRefExpr>(LHS->IgnoreImplicit());
5593 
5594   // Decide the bit width for the logical iteration counter. By default use the
5595   // unsigned ptrdiff_t integer size (for iterators and pointers).
5596   // TODO: For iterators, use iterator::difference_type,
5597   // std::iterator_traits<>::difference_type or decltype(it - end).
5598   QualType LogicalTy = Ctx.getUnsignedPointerDiffType();
5599   if (CounterTy->isIntegerType()) {
5600     unsigned BitWidth = Ctx.getIntWidth(CounterTy);
5601     LogicalTy = Ctx.getIntTypeForBitwidth(BitWidth, false);
5602   }
5603 
5604   // Analyze the loop increment.
5605   Expr *Step;
5606   if (auto *IncUn = dyn_cast<UnaryOperator>(Inc)) {
5607     int Direction;
5608     switch (IncUn->getOpcode()) {
5609     case UO_PreInc:
5610     case UO_PostInc:
5611       Direction = 1;
5612       break;
5613     case UO_PreDec:
5614     case UO_PostDec:
5615       Direction = -1;
5616       break;
5617     default:
5618       llvm_unreachable("unhandled unary increment operator");
5619     }
5620     Step = IntegerLiteral::Create(
5621         Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), Direction), LogicalTy, {});
5622   } else if (auto *IncBin = dyn_cast<BinaryOperator>(Inc)) {
5623     if (IncBin->getOpcode() == BO_AddAssign) {
5624       Step = IncBin->getRHS();
5625     } else if (IncBin->getOpcode() == BO_SubAssign) {
5626       Step =
5627           AssertSuccess(BuildUnaryOp(nullptr, {}, UO_Minus, IncBin->getRHS()));
5628     } else
5629       llvm_unreachable("unhandled binary increment operator");
5630   } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Inc)) {
5631     switch (CondCXXOp->getOperator()) {
5632     case OO_PlusPlus:
5633       Step = IntegerLiteral::Create(
5634           Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {});
5635       break;
5636     case OO_MinusMinus:
5637       Step = IntegerLiteral::Create(
5638           Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), -1), LogicalTy, {});
5639       break;
5640     case OO_PlusEqual:
5641       Step = CondCXXOp->getArg(1);
5642       break;
5643     case OO_MinusEqual:
5644       Step = AssertSuccess(
5645           BuildUnaryOp(nullptr, {}, UO_Minus, CondCXXOp->getArg(1)));
5646       break;
5647     default:
5648       llvm_unreachable("unhandled overloaded increment operator");
5649     }
5650   } else
5651     llvm_unreachable("unknown increment expression");
5652 
5653   CapturedStmt *DistanceFunc =
5654       buildDistanceFunc(*this, LogicalTy, CondRel, LHS, RHS, Step);
5655   CapturedStmt *LoopVarFunc = buildLoopVarFunc(
5656       *this, LVTy, LogicalTy, CounterRef, Step, isa<CXXForRangeStmt>(AStmt));
5657   DeclRefExpr *LVRef = BuildDeclRefExpr(LUVDecl, LUVDecl->getType(), VK_LValue,
5658                                         {}, nullptr, nullptr, {}, nullptr);
5659   return OMPCanonicalLoop::create(getASTContext(), AStmt, DistanceFunc,
5660                                   LoopVarFunc, LVRef);
5661 }
5662 
5663 StmtResult Sema::ActOnOpenMPLoopnest(Stmt *AStmt) {
5664   // Handle a literal loop.
5665   if (isa<ForStmt>(AStmt) || isa<CXXForRangeStmt>(AStmt))
5666     return ActOnOpenMPCanonicalLoop(AStmt);
5667 
5668   // If not a literal loop, it must be the result of a loop transformation.
5669   OMPExecutableDirective *LoopTransform = cast<OMPExecutableDirective>(AStmt);
5670   assert(
5671       isOpenMPLoopTransformationDirective(LoopTransform->getDirectiveKind()) &&
5672       "Loop transformation directive expected");
5673   return LoopTransform;
5674 }
5675 
5676 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
5677                                             CXXScopeSpec &MapperIdScopeSpec,
5678                                             const DeclarationNameInfo &MapperId,
5679                                             QualType Type,
5680                                             Expr *UnresolvedMapper);
5681 
5682 /// Perform DFS through the structure/class data members trying to find
5683 /// member(s) with user-defined 'default' mapper and generate implicit map
5684 /// clauses for such members with the found 'default' mapper.
5685 static void
5686 processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack,
5687                                       SmallVectorImpl<OMPClause *> &Clauses) {
5688   // Check for the deault mapper for data members.
5689   if (S.getLangOpts().OpenMP < 50)
5690     return;
5691   SmallVector<OMPClause *, 4> ImplicitMaps;
5692   for (int Cnt = 0, EndCnt = Clauses.size(); Cnt < EndCnt; ++Cnt) {
5693     auto *C = dyn_cast<OMPMapClause>(Clauses[Cnt]);
5694     if (!C)
5695       continue;
5696     SmallVector<Expr *, 4> SubExprs;
5697     auto *MI = C->mapperlist_begin();
5698     for (auto I = C->varlist_begin(), End = C->varlist_end(); I != End;
5699          ++I, ++MI) {
5700       // Expression is mapped using mapper - skip it.
5701       if (*MI)
5702         continue;
5703       Expr *E = *I;
5704       // Expression is dependent - skip it, build the mapper when it gets
5705       // instantiated.
5706       if (E->isTypeDependent() || E->isValueDependent() ||
5707           E->containsUnexpandedParameterPack())
5708         continue;
5709       // Array section - need to check for the mapping of the array section
5710       // element.
5711       QualType CanonType = E->getType().getCanonicalType();
5712       if (CanonType->isSpecificBuiltinType(BuiltinType::OMPArraySection)) {
5713         const auto *OASE = cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts());
5714         QualType BaseType =
5715             OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
5716         QualType ElemType;
5717         if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
5718           ElemType = ATy->getElementType();
5719         else
5720           ElemType = BaseType->getPointeeType();
5721         CanonType = ElemType;
5722       }
5723 
5724       // DFS over data members in structures/classes.
5725       SmallVector<std::pair<QualType, FieldDecl *>, 4> Types(
5726           1, {CanonType, nullptr});
5727       llvm::DenseMap<const Type *, Expr *> Visited;
5728       SmallVector<std::pair<FieldDecl *, unsigned>, 4> ParentChain(
5729           1, {nullptr, 1});
5730       while (!Types.empty()) {
5731         QualType BaseType;
5732         FieldDecl *CurFD;
5733         std::tie(BaseType, CurFD) = Types.pop_back_val();
5734         while (ParentChain.back().second == 0)
5735           ParentChain.pop_back();
5736         --ParentChain.back().second;
5737         if (BaseType.isNull())
5738           continue;
5739         // Only structs/classes are allowed to have mappers.
5740         const RecordDecl *RD = BaseType.getCanonicalType()->getAsRecordDecl();
5741         if (!RD)
5742           continue;
5743         auto It = Visited.find(BaseType.getTypePtr());
5744         if (It == Visited.end()) {
5745           // Try to find the associated user-defined mapper.
5746           CXXScopeSpec MapperIdScopeSpec;
5747           DeclarationNameInfo DefaultMapperId;
5748           DefaultMapperId.setName(S.Context.DeclarationNames.getIdentifier(
5749               &S.Context.Idents.get("default")));
5750           DefaultMapperId.setLoc(E->getExprLoc());
5751           ExprResult ER = buildUserDefinedMapperRef(
5752               S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId,
5753               BaseType, /*UnresolvedMapper=*/nullptr);
5754           if (ER.isInvalid())
5755             continue;
5756           It = Visited.try_emplace(BaseType.getTypePtr(), ER.get()).first;
5757         }
5758         // Found default mapper.
5759         if (It->second) {
5760           auto *OE = new (S.Context) OpaqueValueExpr(E->getExprLoc(), CanonType,
5761                                                      VK_LValue, OK_Ordinary, E);
5762           OE->setIsUnique(/*V=*/true);
5763           Expr *BaseExpr = OE;
5764           for (const auto &P : ParentChain) {
5765             if (P.first) {
5766               BaseExpr = S.BuildMemberExpr(
5767                   BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
5768                   NestedNameSpecifierLoc(), SourceLocation(), P.first,
5769                   DeclAccessPair::make(P.first, P.first->getAccess()),
5770                   /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
5771                   P.first->getType(), VK_LValue, OK_Ordinary);
5772               BaseExpr = S.DefaultLvalueConversion(BaseExpr).get();
5773             }
5774           }
5775           if (CurFD)
5776             BaseExpr = S.BuildMemberExpr(
5777                 BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
5778                 NestedNameSpecifierLoc(), SourceLocation(), CurFD,
5779                 DeclAccessPair::make(CurFD, CurFD->getAccess()),
5780                 /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
5781                 CurFD->getType(), VK_LValue, OK_Ordinary);
5782           SubExprs.push_back(BaseExpr);
5783           continue;
5784         }
5785         // Check for the "default" mapper for data members.
5786         bool FirstIter = true;
5787         for (FieldDecl *FD : RD->fields()) {
5788           if (!FD)
5789             continue;
5790           QualType FieldTy = FD->getType();
5791           if (FieldTy.isNull() ||
5792               !(FieldTy->isStructureOrClassType() || FieldTy->isUnionType()))
5793             continue;
5794           if (FirstIter) {
5795             FirstIter = false;
5796             ParentChain.emplace_back(CurFD, 1);
5797           } else {
5798             ++ParentChain.back().second;
5799           }
5800           Types.emplace_back(FieldTy, FD);
5801         }
5802       }
5803     }
5804     if (SubExprs.empty())
5805       continue;
5806     CXXScopeSpec MapperIdScopeSpec;
5807     DeclarationNameInfo MapperId;
5808     if (OMPClause *NewClause = S.ActOnOpenMPMapClause(
5809             C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
5810             MapperIdScopeSpec, MapperId, C->getMapType(),
5811             /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
5812             SubExprs, OMPVarListLocTy()))
5813       Clauses.push_back(NewClause);
5814   }
5815 }
5816 
5817 StmtResult Sema::ActOnOpenMPExecutableDirective(
5818     OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
5819     OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
5820     Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
5821   StmtResult Res = StmtError();
5822   OpenMPBindClauseKind BindKind = OMPC_BIND_unknown;
5823   if (const OMPBindClause *BC =
5824           OMPExecutableDirective::getSingleClause<OMPBindClause>(Clauses))
5825     BindKind = BC->getBindKind();
5826   // First check CancelRegion which is then used in checkNestingOfRegions.
5827   if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
5828       checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
5829                             BindKind, StartLoc))
5830     return StmtError();
5831 
5832   llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
5833   VarsWithInheritedDSAType VarsWithInheritedDSA;
5834   bool ErrorFound = false;
5835   ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
5836   if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic &&
5837       Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master &&
5838       Kind != OMPD_masked && !isOpenMPLoopTransformationDirective(Kind)) {
5839     assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5840 
5841     // Check default data sharing attributes for referenced variables.
5842     DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
5843     int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
5844     Stmt *S = AStmt;
5845     while (--ThisCaptureLevel >= 0)
5846       S = cast<CapturedStmt>(S)->getCapturedStmt();
5847     DSAChecker.Visit(S);
5848     if (!isOpenMPTargetDataManagementDirective(Kind) &&
5849         !isOpenMPTaskingDirective(Kind)) {
5850       // Visit subcaptures to generate implicit clauses for captured vars.
5851       auto *CS = cast<CapturedStmt>(AStmt);
5852       SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
5853       getOpenMPCaptureRegions(CaptureRegions, Kind);
5854       // Ignore outer tasking regions for target directives.
5855       if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
5856         CS = cast<CapturedStmt>(CS->getCapturedStmt());
5857       DSAChecker.visitSubCaptures(CS);
5858     }
5859     if (DSAChecker.isErrorFound())
5860       return StmtError();
5861     // Generate list of implicitly defined firstprivate variables.
5862     VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
5863 
5864     SmallVector<Expr *, 4> ImplicitFirstprivates(
5865         DSAChecker.getImplicitFirstprivate().begin(),
5866         DSAChecker.getImplicitFirstprivate().end());
5867     const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
5868     SmallVector<Expr *, 4> ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete];
5869     SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
5870         ImplicitMapModifiers[DefaultmapKindNum];
5871     SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers>
5872         ImplicitMapModifiersLoc[DefaultmapKindNum];
5873     // Get the original location of present modifier from Defaultmap clause.
5874     SourceLocation PresentModifierLocs[DefaultmapKindNum];
5875     for (OMPClause *C : Clauses) {
5876       if (auto *DMC = dyn_cast<OMPDefaultmapClause>(C))
5877         if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present)
5878           PresentModifierLocs[DMC->getDefaultmapKind()] =
5879               DMC->getDefaultmapModifierLoc();
5880     }
5881     for (unsigned VC = 0; VC < DefaultmapKindNum; ++VC) {
5882       auto Kind = static_cast<OpenMPDefaultmapClauseKind>(VC);
5883       for (unsigned I = 0; I < OMPC_MAP_delete; ++I) {
5884         ArrayRef<Expr *> ImplicitMap = DSAChecker.getImplicitMap(
5885             Kind, static_cast<OpenMPMapClauseKind>(I));
5886         ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end());
5887       }
5888       ArrayRef<OpenMPMapModifierKind> ImplicitModifier =
5889           DSAChecker.getImplicitMapModifier(Kind);
5890       ImplicitMapModifiers[VC].append(ImplicitModifier.begin(),
5891                                       ImplicitModifier.end());
5892       std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]),
5893                   ImplicitModifier.size(), PresentModifierLocs[VC]);
5894     }
5895     // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
5896     for (OMPClause *C : Clauses) {
5897       if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
5898         for (Expr *E : IRC->taskgroup_descriptors())
5899           if (E)
5900             ImplicitFirstprivates.emplace_back(E);
5901       }
5902       // OpenMP 5.0, 2.10.1 task Construct
5903       // [detach clause]... The event-handle will be considered as if it was
5904       // specified on a firstprivate clause.
5905       if (auto *DC = dyn_cast<OMPDetachClause>(C))
5906         ImplicitFirstprivates.push_back(DC->getEventHandler());
5907     }
5908     if (!ImplicitFirstprivates.empty()) {
5909       if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
5910               ImplicitFirstprivates, SourceLocation(), SourceLocation(),
5911               SourceLocation())) {
5912         ClausesWithImplicit.push_back(Implicit);
5913         ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
5914                      ImplicitFirstprivates.size();
5915       } else {
5916         ErrorFound = true;
5917       }
5918     }
5919     // OpenMP 5.0 [2.19.7]
5920     // If a list item appears in a reduction, lastprivate or linear
5921     // clause on a combined target construct then it is treated as
5922     // if it also appears in a map clause with a map-type of tofrom
5923     if (getLangOpts().OpenMP >= 50 && Kind != OMPD_target &&
5924         isOpenMPTargetExecutionDirective(Kind)) {
5925       SmallVector<Expr *, 4> ImplicitExprs;
5926       for (OMPClause *C : Clauses) {
5927         if (auto *RC = dyn_cast<OMPReductionClause>(C))
5928           for (Expr *E : RC->varlists())
5929             if (!isa<DeclRefExpr>(E->IgnoreParenImpCasts()))
5930               ImplicitExprs.emplace_back(E);
5931       }
5932       if (!ImplicitExprs.empty()) {
5933         ArrayRef<Expr *> Exprs = ImplicitExprs;
5934         CXXScopeSpec MapperIdScopeSpec;
5935         DeclarationNameInfo MapperId;
5936         if (OMPClause *Implicit = ActOnOpenMPMapClause(
5937                 OMPC_MAP_MODIFIER_unknown, SourceLocation(), MapperIdScopeSpec,
5938                 MapperId, OMPC_MAP_tofrom,
5939                 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
5940                 Exprs, OMPVarListLocTy(), /*NoDiagnose=*/true))
5941           ClausesWithImplicit.emplace_back(Implicit);
5942       }
5943     }
5944     for (unsigned I = 0, E = DefaultmapKindNum; I < E; ++I) {
5945       int ClauseKindCnt = -1;
5946       for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps[I]) {
5947         ++ClauseKindCnt;
5948         if (ImplicitMap.empty())
5949           continue;
5950         CXXScopeSpec MapperIdScopeSpec;
5951         DeclarationNameInfo MapperId;
5952         auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
5953         if (OMPClause *Implicit = ActOnOpenMPMapClause(
5954                 ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I],
5955                 MapperIdScopeSpec, MapperId, Kind, /*IsMapTypeImplicit=*/true,
5956                 SourceLocation(), SourceLocation(), ImplicitMap,
5957                 OMPVarListLocTy())) {
5958           ClausesWithImplicit.emplace_back(Implicit);
5959           ErrorFound |= cast<OMPMapClause>(Implicit)->varlist_size() !=
5960                         ImplicitMap.size();
5961         } else {
5962           ErrorFound = true;
5963         }
5964       }
5965     }
5966     // Build expressions for implicit maps of data members with 'default'
5967     // mappers.
5968     if (LangOpts.OpenMP >= 50)
5969       processImplicitMapsWithDefaultMappers(*this, DSAStack,
5970                                             ClausesWithImplicit);
5971   }
5972 
5973   llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
5974   switch (Kind) {
5975   case OMPD_parallel:
5976     Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
5977                                        EndLoc);
5978     AllowedNameModifiers.push_back(OMPD_parallel);
5979     break;
5980   case OMPD_simd:
5981     Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5982                                    VarsWithInheritedDSA);
5983     if (LangOpts.OpenMP >= 50)
5984       AllowedNameModifiers.push_back(OMPD_simd);
5985     break;
5986   case OMPD_tile:
5987     Res =
5988         ActOnOpenMPTileDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5989     break;
5990   case OMPD_unroll:
5991     Res = ActOnOpenMPUnrollDirective(ClausesWithImplicit, AStmt, StartLoc,
5992                                      EndLoc);
5993     break;
5994   case OMPD_for:
5995     Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5996                                   VarsWithInheritedDSA);
5997     break;
5998   case OMPD_for_simd:
5999     Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6000                                       EndLoc, VarsWithInheritedDSA);
6001     if (LangOpts.OpenMP >= 50)
6002       AllowedNameModifiers.push_back(OMPD_simd);
6003     break;
6004   case OMPD_sections:
6005     Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
6006                                        EndLoc);
6007     break;
6008   case OMPD_section:
6009     assert(ClausesWithImplicit.empty() &&
6010            "No clauses are allowed for 'omp section' directive");
6011     Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
6012     break;
6013   case OMPD_single:
6014     Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
6015                                      EndLoc);
6016     break;
6017   case OMPD_master:
6018     assert(ClausesWithImplicit.empty() &&
6019            "No clauses are allowed for 'omp master' directive");
6020     Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
6021     break;
6022   case OMPD_masked:
6023     Res = ActOnOpenMPMaskedDirective(ClausesWithImplicit, AStmt, StartLoc,
6024                                      EndLoc);
6025     break;
6026   case OMPD_critical:
6027     Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
6028                                        StartLoc, EndLoc);
6029     break;
6030   case OMPD_parallel_for:
6031     Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
6032                                           EndLoc, VarsWithInheritedDSA);
6033     AllowedNameModifiers.push_back(OMPD_parallel);
6034     break;
6035   case OMPD_parallel_for_simd:
6036     Res = ActOnOpenMPParallelForSimdDirective(
6037         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6038     AllowedNameModifiers.push_back(OMPD_parallel);
6039     if (LangOpts.OpenMP >= 50)
6040       AllowedNameModifiers.push_back(OMPD_simd);
6041     break;
6042   case OMPD_parallel_master:
6043     Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
6044                                              StartLoc, EndLoc);
6045     AllowedNameModifiers.push_back(OMPD_parallel);
6046     break;
6047   case OMPD_parallel_sections:
6048     Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
6049                                                StartLoc, EndLoc);
6050     AllowedNameModifiers.push_back(OMPD_parallel);
6051     break;
6052   case OMPD_task:
6053     Res =
6054         ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6055     AllowedNameModifiers.push_back(OMPD_task);
6056     break;
6057   case OMPD_taskyield:
6058     assert(ClausesWithImplicit.empty() &&
6059            "No clauses are allowed for 'omp taskyield' directive");
6060     assert(AStmt == nullptr &&
6061            "No associated statement allowed for 'omp taskyield' directive");
6062     Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
6063     break;
6064   case OMPD_barrier:
6065     assert(ClausesWithImplicit.empty() &&
6066            "No clauses are allowed for 'omp barrier' directive");
6067     assert(AStmt == nullptr &&
6068            "No associated statement allowed for 'omp barrier' directive");
6069     Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
6070     break;
6071   case OMPD_taskwait:
6072     assert(AStmt == nullptr &&
6073            "No associated statement allowed for 'omp taskwait' directive");
6074     Res = ActOnOpenMPTaskwaitDirective(ClausesWithImplicit, StartLoc, EndLoc);
6075     break;
6076   case OMPD_taskgroup:
6077     Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
6078                                         EndLoc);
6079     break;
6080   case OMPD_flush:
6081     assert(AStmt == nullptr &&
6082            "No associated statement allowed for 'omp flush' directive");
6083     Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
6084     break;
6085   case OMPD_depobj:
6086     assert(AStmt == nullptr &&
6087            "No associated statement allowed for 'omp depobj' directive");
6088     Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc);
6089     break;
6090   case OMPD_scan:
6091     assert(AStmt == nullptr &&
6092            "No associated statement allowed for 'omp scan' directive");
6093     Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc);
6094     break;
6095   case OMPD_ordered:
6096     Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
6097                                       EndLoc);
6098     break;
6099   case OMPD_atomic:
6100     Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
6101                                      EndLoc);
6102     break;
6103   case OMPD_teams:
6104     Res =
6105         ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
6106     break;
6107   case OMPD_target:
6108     Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
6109                                      EndLoc);
6110     AllowedNameModifiers.push_back(OMPD_target);
6111     break;
6112   case OMPD_target_parallel:
6113     Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
6114                                              StartLoc, EndLoc);
6115     AllowedNameModifiers.push_back(OMPD_target);
6116     AllowedNameModifiers.push_back(OMPD_parallel);
6117     break;
6118   case OMPD_target_parallel_for:
6119     Res = ActOnOpenMPTargetParallelForDirective(
6120         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6121     AllowedNameModifiers.push_back(OMPD_target);
6122     AllowedNameModifiers.push_back(OMPD_parallel);
6123     break;
6124   case OMPD_cancellation_point:
6125     assert(ClausesWithImplicit.empty() &&
6126            "No clauses are allowed for 'omp cancellation point' directive");
6127     assert(AStmt == nullptr && "No associated statement allowed for 'omp "
6128                                "cancellation point' directive");
6129     Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
6130     break;
6131   case OMPD_cancel:
6132     assert(AStmt == nullptr &&
6133            "No associated statement allowed for 'omp cancel' directive");
6134     Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
6135                                      CancelRegion);
6136     AllowedNameModifiers.push_back(OMPD_cancel);
6137     break;
6138   case OMPD_target_data:
6139     Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
6140                                          EndLoc);
6141     AllowedNameModifiers.push_back(OMPD_target_data);
6142     break;
6143   case OMPD_target_enter_data:
6144     Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
6145                                               EndLoc, AStmt);
6146     AllowedNameModifiers.push_back(OMPD_target_enter_data);
6147     break;
6148   case OMPD_target_exit_data:
6149     Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
6150                                              EndLoc, AStmt);
6151     AllowedNameModifiers.push_back(OMPD_target_exit_data);
6152     break;
6153   case OMPD_taskloop:
6154     Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
6155                                        EndLoc, VarsWithInheritedDSA);
6156     AllowedNameModifiers.push_back(OMPD_taskloop);
6157     break;
6158   case OMPD_taskloop_simd:
6159     Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6160                                            EndLoc, VarsWithInheritedDSA);
6161     AllowedNameModifiers.push_back(OMPD_taskloop);
6162     if (LangOpts.OpenMP >= 50)
6163       AllowedNameModifiers.push_back(OMPD_simd);
6164     break;
6165   case OMPD_master_taskloop:
6166     Res = ActOnOpenMPMasterTaskLoopDirective(
6167         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6168     AllowedNameModifiers.push_back(OMPD_taskloop);
6169     break;
6170   case OMPD_master_taskloop_simd:
6171     Res = ActOnOpenMPMasterTaskLoopSimdDirective(
6172         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6173     AllowedNameModifiers.push_back(OMPD_taskloop);
6174     if (LangOpts.OpenMP >= 50)
6175       AllowedNameModifiers.push_back(OMPD_simd);
6176     break;
6177   case OMPD_parallel_master_taskloop:
6178     Res = ActOnOpenMPParallelMasterTaskLoopDirective(
6179         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6180     AllowedNameModifiers.push_back(OMPD_taskloop);
6181     AllowedNameModifiers.push_back(OMPD_parallel);
6182     break;
6183   case OMPD_parallel_master_taskloop_simd:
6184     Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective(
6185         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6186     AllowedNameModifiers.push_back(OMPD_taskloop);
6187     AllowedNameModifiers.push_back(OMPD_parallel);
6188     if (LangOpts.OpenMP >= 50)
6189       AllowedNameModifiers.push_back(OMPD_simd);
6190     break;
6191   case OMPD_distribute:
6192     Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
6193                                          EndLoc, VarsWithInheritedDSA);
6194     break;
6195   case OMPD_target_update:
6196     Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
6197                                            EndLoc, AStmt);
6198     AllowedNameModifiers.push_back(OMPD_target_update);
6199     break;
6200   case OMPD_distribute_parallel_for:
6201     Res = ActOnOpenMPDistributeParallelForDirective(
6202         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6203     AllowedNameModifiers.push_back(OMPD_parallel);
6204     break;
6205   case OMPD_distribute_parallel_for_simd:
6206     Res = ActOnOpenMPDistributeParallelForSimdDirective(
6207         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6208     AllowedNameModifiers.push_back(OMPD_parallel);
6209     if (LangOpts.OpenMP >= 50)
6210       AllowedNameModifiers.push_back(OMPD_simd);
6211     break;
6212   case OMPD_distribute_simd:
6213     Res = ActOnOpenMPDistributeSimdDirective(
6214         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6215     if (LangOpts.OpenMP >= 50)
6216       AllowedNameModifiers.push_back(OMPD_simd);
6217     break;
6218   case OMPD_target_parallel_for_simd:
6219     Res = ActOnOpenMPTargetParallelForSimdDirective(
6220         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6221     AllowedNameModifiers.push_back(OMPD_target);
6222     AllowedNameModifiers.push_back(OMPD_parallel);
6223     if (LangOpts.OpenMP >= 50)
6224       AllowedNameModifiers.push_back(OMPD_simd);
6225     break;
6226   case OMPD_target_simd:
6227     Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6228                                          EndLoc, VarsWithInheritedDSA);
6229     AllowedNameModifiers.push_back(OMPD_target);
6230     if (LangOpts.OpenMP >= 50)
6231       AllowedNameModifiers.push_back(OMPD_simd);
6232     break;
6233   case OMPD_teams_distribute:
6234     Res = ActOnOpenMPTeamsDistributeDirective(
6235         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6236     break;
6237   case OMPD_teams_distribute_simd:
6238     Res = ActOnOpenMPTeamsDistributeSimdDirective(
6239         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6240     if (LangOpts.OpenMP >= 50)
6241       AllowedNameModifiers.push_back(OMPD_simd);
6242     break;
6243   case OMPD_teams_distribute_parallel_for_simd:
6244     Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
6245         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6246     AllowedNameModifiers.push_back(OMPD_parallel);
6247     if (LangOpts.OpenMP >= 50)
6248       AllowedNameModifiers.push_back(OMPD_simd);
6249     break;
6250   case OMPD_teams_distribute_parallel_for:
6251     Res = ActOnOpenMPTeamsDistributeParallelForDirective(
6252         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6253     AllowedNameModifiers.push_back(OMPD_parallel);
6254     break;
6255   case OMPD_target_teams:
6256     Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
6257                                           EndLoc);
6258     AllowedNameModifiers.push_back(OMPD_target);
6259     break;
6260   case OMPD_target_teams_distribute:
6261     Res = ActOnOpenMPTargetTeamsDistributeDirective(
6262         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6263     AllowedNameModifiers.push_back(OMPD_target);
6264     break;
6265   case OMPD_target_teams_distribute_parallel_for:
6266     Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
6267         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6268     AllowedNameModifiers.push_back(OMPD_target);
6269     AllowedNameModifiers.push_back(OMPD_parallel);
6270     break;
6271   case OMPD_target_teams_distribute_parallel_for_simd:
6272     Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
6273         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6274     AllowedNameModifiers.push_back(OMPD_target);
6275     AllowedNameModifiers.push_back(OMPD_parallel);
6276     if (LangOpts.OpenMP >= 50)
6277       AllowedNameModifiers.push_back(OMPD_simd);
6278     break;
6279   case OMPD_target_teams_distribute_simd:
6280     Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
6281         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6282     AllowedNameModifiers.push_back(OMPD_target);
6283     if (LangOpts.OpenMP >= 50)
6284       AllowedNameModifiers.push_back(OMPD_simd);
6285     break;
6286   case OMPD_interop:
6287     assert(AStmt == nullptr &&
6288            "No associated statement allowed for 'omp interop' directive");
6289     Res = ActOnOpenMPInteropDirective(ClausesWithImplicit, StartLoc, EndLoc);
6290     break;
6291   case OMPD_dispatch:
6292     Res = ActOnOpenMPDispatchDirective(ClausesWithImplicit, AStmt, StartLoc,
6293                                        EndLoc);
6294     break;
6295   case OMPD_loop:
6296     Res = ActOnOpenMPGenericLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
6297                                           EndLoc, VarsWithInheritedDSA);
6298     break;
6299   case OMPD_declare_target:
6300   case OMPD_end_declare_target:
6301   case OMPD_threadprivate:
6302   case OMPD_allocate:
6303   case OMPD_declare_reduction:
6304   case OMPD_declare_mapper:
6305   case OMPD_declare_simd:
6306   case OMPD_requires:
6307   case OMPD_declare_variant:
6308   case OMPD_begin_declare_variant:
6309   case OMPD_end_declare_variant:
6310     llvm_unreachable("OpenMP Directive is not allowed");
6311   case OMPD_unknown:
6312   default:
6313     llvm_unreachable("Unknown OpenMP directive");
6314   }
6315 
6316   ErrorFound = Res.isInvalid() || ErrorFound;
6317 
6318   // Check variables in the clauses if default(none) or
6319   // default(firstprivate) was specified.
6320   if (DSAStack->getDefaultDSA() == DSA_none ||
6321       DSAStack->getDefaultDSA() == DSA_firstprivate) {
6322     DSAAttrChecker DSAChecker(DSAStack, *this, nullptr);
6323     for (OMPClause *C : Clauses) {
6324       switch (C->getClauseKind()) {
6325       case OMPC_num_threads:
6326       case OMPC_dist_schedule:
6327         // Do not analyse if no parent teams directive.
6328         if (isOpenMPTeamsDirective(Kind))
6329           break;
6330         continue;
6331       case OMPC_if:
6332         if (isOpenMPTeamsDirective(Kind) &&
6333             cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
6334           break;
6335         if (isOpenMPParallelDirective(Kind) &&
6336             isOpenMPTaskLoopDirective(Kind) &&
6337             cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel)
6338           break;
6339         continue;
6340       case OMPC_schedule:
6341       case OMPC_detach:
6342         break;
6343       case OMPC_grainsize:
6344       case OMPC_num_tasks:
6345       case OMPC_final:
6346       case OMPC_priority:
6347       case OMPC_novariants:
6348       case OMPC_nocontext:
6349         // Do not analyze if no parent parallel directive.
6350         if (isOpenMPParallelDirective(Kind))
6351           break;
6352         continue;
6353       case OMPC_ordered:
6354       case OMPC_device:
6355       case OMPC_num_teams:
6356       case OMPC_thread_limit:
6357       case OMPC_hint:
6358       case OMPC_collapse:
6359       case OMPC_safelen:
6360       case OMPC_simdlen:
6361       case OMPC_sizes:
6362       case OMPC_default:
6363       case OMPC_proc_bind:
6364       case OMPC_private:
6365       case OMPC_firstprivate:
6366       case OMPC_lastprivate:
6367       case OMPC_shared:
6368       case OMPC_reduction:
6369       case OMPC_task_reduction:
6370       case OMPC_in_reduction:
6371       case OMPC_linear:
6372       case OMPC_aligned:
6373       case OMPC_copyin:
6374       case OMPC_copyprivate:
6375       case OMPC_nowait:
6376       case OMPC_untied:
6377       case OMPC_mergeable:
6378       case OMPC_allocate:
6379       case OMPC_read:
6380       case OMPC_write:
6381       case OMPC_update:
6382       case OMPC_capture:
6383       case OMPC_compare:
6384       case OMPC_seq_cst:
6385       case OMPC_acq_rel:
6386       case OMPC_acquire:
6387       case OMPC_release:
6388       case OMPC_relaxed:
6389       case OMPC_depend:
6390       case OMPC_threads:
6391       case OMPC_simd:
6392       case OMPC_map:
6393       case OMPC_nogroup:
6394       case OMPC_defaultmap:
6395       case OMPC_to:
6396       case OMPC_from:
6397       case OMPC_use_device_ptr:
6398       case OMPC_use_device_addr:
6399       case OMPC_is_device_ptr:
6400       case OMPC_nontemporal:
6401       case OMPC_order:
6402       case OMPC_destroy:
6403       case OMPC_inclusive:
6404       case OMPC_exclusive:
6405       case OMPC_uses_allocators:
6406       case OMPC_affinity:
6407       case OMPC_bind:
6408         continue;
6409       case OMPC_allocator:
6410       case OMPC_flush:
6411       case OMPC_depobj:
6412       case OMPC_threadprivate:
6413       case OMPC_uniform:
6414       case OMPC_unknown:
6415       case OMPC_unified_address:
6416       case OMPC_unified_shared_memory:
6417       case OMPC_reverse_offload:
6418       case OMPC_dynamic_allocators:
6419       case OMPC_atomic_default_mem_order:
6420       case OMPC_device_type:
6421       case OMPC_match:
6422       case OMPC_when:
6423       default:
6424         llvm_unreachable("Unexpected clause");
6425       }
6426       for (Stmt *CC : C->children()) {
6427         if (CC)
6428           DSAChecker.Visit(CC);
6429       }
6430     }
6431     for (const auto &P : DSAChecker.getVarsWithInheritedDSA())
6432       VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
6433   }
6434   for (const auto &P : VarsWithInheritedDSA) {
6435     if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
6436       continue;
6437     ErrorFound = true;
6438     if (DSAStack->getDefaultDSA() == DSA_none ||
6439         DSAStack->getDefaultDSA() == DSA_firstprivate) {
6440       Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
6441           << P.first << P.second->getSourceRange();
6442       Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
6443     } else if (getLangOpts().OpenMP >= 50) {
6444       Diag(P.second->getExprLoc(),
6445            diag::err_omp_defaultmap_no_attr_for_variable)
6446           << P.first << P.second->getSourceRange();
6447       Diag(DSAStack->getDefaultDSALocation(),
6448            diag::note_omp_defaultmap_attr_none);
6449     }
6450   }
6451 
6452   if (!AllowedNameModifiers.empty())
6453     ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
6454                  ErrorFound;
6455 
6456   if (ErrorFound)
6457     return StmtError();
6458 
6459   if (!CurContext->isDependentContext() &&
6460       isOpenMPTargetExecutionDirective(Kind) &&
6461       !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
6462         DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
6463         DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
6464         DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
6465     // Register target to DSA Stack.
6466     DSAStack->addTargetDirLocation(StartLoc);
6467   }
6468 
6469   return Res;
6470 }
6471 
6472 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
6473     DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
6474     ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
6475     ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
6476     ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
6477   assert(Aligneds.size() == Alignments.size());
6478   assert(Linears.size() == LinModifiers.size());
6479   assert(Linears.size() == Steps.size());
6480   if (!DG || DG.get().isNull())
6481     return DeclGroupPtrTy();
6482 
6483   const int SimdId = 0;
6484   if (!DG.get().isSingleDecl()) {
6485     Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
6486         << SimdId;
6487     return DG;
6488   }
6489   Decl *ADecl = DG.get().getSingleDecl();
6490   if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
6491     ADecl = FTD->getTemplatedDecl();
6492 
6493   auto *FD = dyn_cast<FunctionDecl>(ADecl);
6494   if (!FD) {
6495     Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId;
6496     return DeclGroupPtrTy();
6497   }
6498 
6499   // OpenMP [2.8.2, declare simd construct, Description]
6500   // The parameter of the simdlen clause must be a constant positive integer
6501   // expression.
6502   ExprResult SL;
6503   if (Simdlen)
6504     SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
6505   // OpenMP [2.8.2, declare simd construct, Description]
6506   // The special this pointer can be used as if was one of the arguments to the
6507   // function in any of the linear, aligned, or uniform clauses.
6508   // The uniform clause declares one or more arguments to have an invariant
6509   // value for all concurrent invocations of the function in the execution of a
6510   // single SIMD loop.
6511   llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
6512   const Expr *UniformedLinearThis = nullptr;
6513   for (const Expr *E : Uniforms) {
6514     E = E->IgnoreParenImpCasts();
6515     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6516       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
6517         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6518             FD->getParamDecl(PVD->getFunctionScopeIndex())
6519                     ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
6520           UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
6521           continue;
6522         }
6523     if (isa<CXXThisExpr>(E)) {
6524       UniformedLinearThis = E;
6525       continue;
6526     }
6527     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6528         << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6529   }
6530   // OpenMP [2.8.2, declare simd construct, Description]
6531   // The aligned clause declares that the object to which each list item points
6532   // is aligned to the number of bytes expressed in the optional parameter of
6533   // the aligned clause.
6534   // The special this pointer can be used as if was one of the arguments to the
6535   // function in any of the linear, aligned, or uniform clauses.
6536   // The type of list items appearing in the aligned clause must be array,
6537   // pointer, reference to array, or reference to pointer.
6538   llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
6539   const Expr *AlignedThis = nullptr;
6540   for (const Expr *E : Aligneds) {
6541     E = E->IgnoreParenImpCasts();
6542     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6543       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6544         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6545         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6546             FD->getParamDecl(PVD->getFunctionScopeIndex())
6547                     ->getCanonicalDecl() == CanonPVD) {
6548           // OpenMP  [2.8.1, simd construct, Restrictions]
6549           // A list-item cannot appear in more than one aligned clause.
6550           if (AlignedArgs.count(CanonPVD) > 0) {
6551             Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
6552                 << 1 << getOpenMPClauseName(OMPC_aligned)
6553                 << E->getSourceRange();
6554             Diag(AlignedArgs[CanonPVD]->getExprLoc(),
6555                  diag::note_omp_explicit_dsa)
6556                 << getOpenMPClauseName(OMPC_aligned);
6557             continue;
6558           }
6559           AlignedArgs[CanonPVD] = E;
6560           QualType QTy = PVD->getType()
6561                              .getNonReferenceType()
6562                              .getUnqualifiedType()
6563                              .getCanonicalType();
6564           const Type *Ty = QTy.getTypePtrOrNull();
6565           if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
6566             Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
6567                 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
6568             Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
6569           }
6570           continue;
6571         }
6572       }
6573     if (isa<CXXThisExpr>(E)) {
6574       if (AlignedThis) {
6575         Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
6576             << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange();
6577         Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
6578             << getOpenMPClauseName(OMPC_aligned);
6579       }
6580       AlignedThis = E;
6581       continue;
6582     }
6583     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6584         << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6585   }
6586   // The optional parameter of the aligned clause, alignment, must be a constant
6587   // positive integer expression. If no optional parameter is specified,
6588   // implementation-defined default alignments for SIMD instructions on the
6589   // target platforms are assumed.
6590   SmallVector<const Expr *, 4> NewAligns;
6591   for (Expr *E : Alignments) {
6592     ExprResult Align;
6593     if (E)
6594       Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
6595     NewAligns.push_back(Align.get());
6596   }
6597   // OpenMP [2.8.2, declare simd construct, Description]
6598   // The linear clause declares one or more list items to be private to a SIMD
6599   // lane and to have a linear relationship with respect to the iteration space
6600   // of a loop.
6601   // The special this pointer can be used as if was one of the arguments to the
6602   // function in any of the linear, aligned, or uniform clauses.
6603   // When a linear-step expression is specified in a linear clause it must be
6604   // either a constant integer expression or an integer-typed parameter that is
6605   // specified in a uniform clause on the directive.
6606   llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
6607   const bool IsUniformedThis = UniformedLinearThis != nullptr;
6608   auto MI = LinModifiers.begin();
6609   for (const Expr *E : Linears) {
6610     auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
6611     ++MI;
6612     E = E->IgnoreParenImpCasts();
6613     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6614       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6615         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6616         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6617             FD->getParamDecl(PVD->getFunctionScopeIndex())
6618                     ->getCanonicalDecl() == CanonPVD) {
6619           // OpenMP  [2.15.3.7, linear Clause, Restrictions]
6620           // A list-item cannot appear in more than one linear clause.
6621           if (LinearArgs.count(CanonPVD) > 0) {
6622             Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6623                 << getOpenMPClauseName(OMPC_linear)
6624                 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
6625             Diag(LinearArgs[CanonPVD]->getExprLoc(),
6626                  diag::note_omp_explicit_dsa)
6627                 << getOpenMPClauseName(OMPC_linear);
6628             continue;
6629           }
6630           // Each argument can appear in at most one uniform or linear clause.
6631           if (UniformedArgs.count(CanonPVD) > 0) {
6632             Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6633                 << getOpenMPClauseName(OMPC_linear)
6634                 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
6635             Diag(UniformedArgs[CanonPVD]->getExprLoc(),
6636                  diag::note_omp_explicit_dsa)
6637                 << getOpenMPClauseName(OMPC_uniform);
6638             continue;
6639           }
6640           LinearArgs[CanonPVD] = E;
6641           if (E->isValueDependent() || E->isTypeDependent() ||
6642               E->isInstantiationDependent() ||
6643               E->containsUnexpandedParameterPack())
6644             continue;
6645           (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
6646                                       PVD->getOriginalType(),
6647                                       /*IsDeclareSimd=*/true);
6648           continue;
6649         }
6650       }
6651     if (isa<CXXThisExpr>(E)) {
6652       if (UniformedLinearThis) {
6653         Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6654             << getOpenMPClauseName(OMPC_linear)
6655             << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
6656             << E->getSourceRange();
6657         Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
6658             << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
6659                                                    : OMPC_linear);
6660         continue;
6661       }
6662       UniformedLinearThis = E;
6663       if (E->isValueDependent() || E->isTypeDependent() ||
6664           E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
6665         continue;
6666       (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
6667                                   E->getType(), /*IsDeclareSimd=*/true);
6668       continue;
6669     }
6670     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6671         << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6672   }
6673   Expr *Step = nullptr;
6674   Expr *NewStep = nullptr;
6675   SmallVector<Expr *, 4> NewSteps;
6676   for (Expr *E : Steps) {
6677     // Skip the same step expression, it was checked already.
6678     if (Step == E || !E) {
6679       NewSteps.push_back(E ? NewStep : nullptr);
6680       continue;
6681     }
6682     Step = E;
6683     if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
6684       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6685         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6686         if (UniformedArgs.count(CanonPVD) == 0) {
6687           Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
6688               << Step->getSourceRange();
6689         } else if (E->isValueDependent() || E->isTypeDependent() ||
6690                    E->isInstantiationDependent() ||
6691                    E->containsUnexpandedParameterPack() ||
6692                    CanonPVD->getType()->hasIntegerRepresentation()) {
6693           NewSteps.push_back(Step);
6694         } else {
6695           Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
6696               << Step->getSourceRange();
6697         }
6698         continue;
6699       }
6700     NewStep = Step;
6701     if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
6702         !Step->isInstantiationDependent() &&
6703         !Step->containsUnexpandedParameterPack()) {
6704       NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
6705                     .get();
6706       if (NewStep)
6707         NewStep =
6708             VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get();
6709     }
6710     NewSteps.push_back(NewStep);
6711   }
6712   auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
6713       Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
6714       Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
6715       const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
6716       const_cast<Expr **>(Linears.data()), Linears.size(),
6717       const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
6718       NewSteps.data(), NewSteps.size(), SR);
6719   ADecl->addAttr(NewAttr);
6720   return DG;
6721 }
6722 
6723 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
6724                          QualType NewType) {
6725   assert(NewType->isFunctionProtoType() &&
6726          "Expected function type with prototype.");
6727   assert(FD->getType()->isFunctionNoProtoType() &&
6728          "Expected function with type with no prototype.");
6729   assert(FDWithProto->getType()->isFunctionProtoType() &&
6730          "Expected function with prototype.");
6731   // Synthesize parameters with the same types.
6732   FD->setType(NewType);
6733   SmallVector<ParmVarDecl *, 16> Params;
6734   for (const ParmVarDecl *P : FDWithProto->parameters()) {
6735     auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(),
6736                                       SourceLocation(), nullptr, P->getType(),
6737                                       /*TInfo=*/nullptr, SC_None, nullptr);
6738     Param->setScopeInfo(0, Params.size());
6739     Param->setImplicit();
6740     Params.push_back(Param);
6741   }
6742 
6743   FD->setParams(Params);
6744 }
6745 
6746 void Sema::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D) {
6747   if (D->isInvalidDecl())
6748     return;
6749   FunctionDecl *FD = nullptr;
6750   if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
6751     FD = UTemplDecl->getTemplatedDecl();
6752   else
6753     FD = cast<FunctionDecl>(D);
6754   assert(FD && "Expected a function declaration!");
6755 
6756   // If we are instantiating templates we do *not* apply scoped assumptions but
6757   // only global ones. We apply scoped assumption to the template definition
6758   // though.
6759   if (!inTemplateInstantiation()) {
6760     for (AssumptionAttr *AA : OMPAssumeScoped)
6761       FD->addAttr(AA);
6762   }
6763   for (AssumptionAttr *AA : OMPAssumeGlobal)
6764     FD->addAttr(AA);
6765 }
6766 
6767 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI)
6768     : TI(&TI), NameSuffix(TI.getMangledName()) {}
6769 
6770 void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(
6771     Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists,
6772     SmallVectorImpl<FunctionDecl *> &Bases) {
6773   if (!D.getIdentifier())
6774     return;
6775 
6776   OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
6777 
6778   // Template specialization is an extension, check if we do it.
6779   bool IsTemplated = !TemplateParamLists.empty();
6780   if (IsTemplated &
6781       !DVScope.TI->isExtensionActive(
6782           llvm::omp::TraitProperty::implementation_extension_allow_templates))
6783     return;
6784 
6785   IdentifierInfo *BaseII = D.getIdentifier();
6786   LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(),
6787                       LookupOrdinaryName);
6788   LookupParsedName(Lookup, S, &D.getCXXScopeSpec());
6789 
6790   TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
6791   QualType FType = TInfo->getType();
6792 
6793   bool IsConstexpr =
6794       D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr;
6795   bool IsConsteval =
6796       D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Consteval;
6797 
6798   for (auto *Candidate : Lookup) {
6799     auto *CandidateDecl = Candidate->getUnderlyingDecl();
6800     FunctionDecl *UDecl = nullptr;
6801     if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl)) {
6802       auto *FTD = cast<FunctionTemplateDecl>(CandidateDecl);
6803       if (FTD->getTemplateParameters()->size() == TemplateParamLists.size())
6804         UDecl = FTD->getTemplatedDecl();
6805     } else if (!IsTemplated)
6806       UDecl = dyn_cast<FunctionDecl>(CandidateDecl);
6807     if (!UDecl)
6808       continue;
6809 
6810     // Don't specialize constexpr/consteval functions with
6811     // non-constexpr/consteval functions.
6812     if (UDecl->isConstexpr() && !IsConstexpr)
6813       continue;
6814     if (UDecl->isConsteval() && !IsConsteval)
6815       continue;
6816 
6817     QualType UDeclTy = UDecl->getType();
6818     if (!UDeclTy->isDependentType()) {
6819       QualType NewType = Context.mergeFunctionTypes(
6820           FType, UDeclTy, /* OfBlockPointer */ false,
6821           /* Unqualified */ false, /* AllowCXX */ true);
6822       if (NewType.isNull())
6823         continue;
6824     }
6825 
6826     // Found a base!
6827     Bases.push_back(UDecl);
6828   }
6829 
6830   bool UseImplicitBase = !DVScope.TI->isExtensionActive(
6831       llvm::omp::TraitProperty::implementation_extension_disable_implicit_base);
6832   // If no base was found we create a declaration that we use as base.
6833   if (Bases.empty() && UseImplicitBase) {
6834     D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration);
6835     Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists);
6836     BaseD->setImplicit(true);
6837     if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD))
6838       Bases.push_back(BaseTemplD->getTemplatedDecl());
6839     else
6840       Bases.push_back(cast<FunctionDecl>(BaseD));
6841   }
6842 
6843   std::string MangledName;
6844   MangledName += D.getIdentifier()->getName();
6845   MangledName += getOpenMPVariantManglingSeparatorStr();
6846   MangledName += DVScope.NameSuffix;
6847   IdentifierInfo &VariantII = Context.Idents.get(MangledName);
6848 
6849   VariantII.setMangledOpenMPVariantName(true);
6850   D.SetIdentifier(&VariantII, D.getBeginLoc());
6851 }
6852 
6853 void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(
6854     Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) {
6855   // Do not mark function as is used to prevent its emission if this is the
6856   // only place where it is used.
6857   EnterExpressionEvaluationContext Unevaluated(
6858       *this, Sema::ExpressionEvaluationContext::Unevaluated);
6859 
6860   FunctionDecl *FD = nullptr;
6861   if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
6862     FD = UTemplDecl->getTemplatedDecl();
6863   else
6864     FD = cast<FunctionDecl>(D);
6865   auto *VariantFuncRef = DeclRefExpr::Create(
6866       Context, NestedNameSpecifierLoc(), SourceLocation(), FD,
6867       /* RefersToEnclosingVariableOrCapture */ false,
6868       /* NameLoc */ FD->getLocation(), FD->getType(),
6869       ExprValueKind::VK_PRValue);
6870 
6871   OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
6872   auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit(
6873       Context, VariantFuncRef, DVScope.TI,
6874       /*NothingArgs=*/nullptr, /*NothingArgsSize=*/0,
6875       /*NeedDevicePtrArgs=*/nullptr, /*NeedDevicePtrArgsSize=*/0,
6876       /*AppendArgs=*/nullptr, /*AppendArgsSize=*/0);
6877   for (FunctionDecl *BaseFD : Bases)
6878     BaseFD->addAttr(OMPDeclareVariantA);
6879 }
6880 
6881 ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
6882                                  SourceLocation LParenLoc,
6883                                  MultiExprArg ArgExprs,
6884                                  SourceLocation RParenLoc, Expr *ExecConfig) {
6885   // The common case is a regular call we do not want to specialize at all. Try
6886   // to make that case fast by bailing early.
6887   CallExpr *CE = dyn_cast<CallExpr>(Call.get());
6888   if (!CE)
6889     return Call;
6890 
6891   FunctionDecl *CalleeFnDecl = CE->getDirectCallee();
6892   if (!CalleeFnDecl)
6893     return Call;
6894 
6895   if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>())
6896     return Call;
6897 
6898   ASTContext &Context = getASTContext();
6899   std::function<void(StringRef)> DiagUnknownTrait = [this,
6900                                                      CE](StringRef ISATrait) {
6901     // TODO Track the selector locations in a way that is accessible here to
6902     // improve the diagnostic location.
6903     Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait)
6904         << ISATrait;
6905   };
6906   TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait),
6907                           getCurFunctionDecl(), DSAStack->getConstructTraits());
6908 
6909   QualType CalleeFnType = CalleeFnDecl->getType();
6910 
6911   SmallVector<Expr *, 4> Exprs;
6912   SmallVector<VariantMatchInfo, 4> VMIs;
6913   while (CalleeFnDecl) {
6914     for (OMPDeclareVariantAttr *A :
6915          CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) {
6916       Expr *VariantRef = A->getVariantFuncRef();
6917 
6918       VariantMatchInfo VMI;
6919       OMPTraitInfo &TI = A->getTraitInfo();
6920       TI.getAsVariantMatchInfo(Context, VMI);
6921       if (!isVariantApplicableInContext(VMI, OMPCtx,
6922                                         /* DeviceSetOnly */ false))
6923         continue;
6924 
6925       VMIs.push_back(VMI);
6926       Exprs.push_back(VariantRef);
6927     }
6928 
6929     CalleeFnDecl = CalleeFnDecl->getPreviousDecl();
6930   }
6931 
6932   ExprResult NewCall;
6933   do {
6934     int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
6935     if (BestIdx < 0)
6936       return Call;
6937     Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]);
6938     Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl();
6939 
6940     {
6941       // Try to build a (member) call expression for the current best applicable
6942       // variant expression. We allow this to fail in which case we continue
6943       // with the next best variant expression. The fail case is part of the
6944       // implementation defined behavior in the OpenMP standard when it talks
6945       // about what differences in the function prototypes: "Any differences
6946       // that the specific OpenMP context requires in the prototype of the
6947       // variant from the base function prototype are implementation defined."
6948       // This wording is there to allow the specialized variant to have a
6949       // different type than the base function. This is intended and OK but if
6950       // we cannot create a call the difference is not in the "implementation
6951       // defined range" we allow.
6952       Sema::TentativeAnalysisScope Trap(*this);
6953 
6954       if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) {
6955         auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE);
6956         BestExpr = MemberExpr::CreateImplicit(
6957             Context, MemberCall->getImplicitObjectArgument(),
6958             /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy,
6959             MemberCall->getValueKind(), MemberCall->getObjectKind());
6960       }
6961       NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc,
6962                               ExecConfig);
6963       if (NewCall.isUsable()) {
6964         if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) {
6965           FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee();
6966           QualType NewType = Context.mergeFunctionTypes(
6967               CalleeFnType, NewCalleeFnDecl->getType(),
6968               /* OfBlockPointer */ false,
6969               /* Unqualified */ false, /* AllowCXX */ true);
6970           if (!NewType.isNull())
6971             break;
6972           // Don't use the call if the function type was not compatible.
6973           NewCall = nullptr;
6974         }
6975       }
6976     }
6977 
6978     VMIs.erase(VMIs.begin() + BestIdx);
6979     Exprs.erase(Exprs.begin() + BestIdx);
6980   } while (!VMIs.empty());
6981 
6982   if (!NewCall.isUsable())
6983     return Call;
6984   return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0);
6985 }
6986 
6987 Optional<std::pair<FunctionDecl *, Expr *>>
6988 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
6989                                         Expr *VariantRef, OMPTraitInfo &TI,
6990                                         unsigned NumAppendArgs,
6991                                         SourceRange SR) {
6992   if (!DG || DG.get().isNull())
6993     return None;
6994 
6995   const int VariantId = 1;
6996   // Must be applied only to single decl.
6997   if (!DG.get().isSingleDecl()) {
6998     Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
6999         << VariantId << SR;
7000     return None;
7001   }
7002   Decl *ADecl = DG.get().getSingleDecl();
7003   if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
7004     ADecl = FTD->getTemplatedDecl();
7005 
7006   // Decl must be a function.
7007   auto *FD = dyn_cast<FunctionDecl>(ADecl);
7008   if (!FD) {
7009     Diag(ADecl->getLocation(), diag::err_omp_function_expected)
7010         << VariantId << SR;
7011     return None;
7012   }
7013 
7014   auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
7015     return FD->hasAttrs() &&
7016            (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() ||
7017             FD->hasAttr<TargetAttr>());
7018   };
7019   // OpenMP is not compatible with CPU-specific attributes.
7020   if (HasMultiVersionAttributes(FD)) {
7021     Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
7022         << SR;
7023     return None;
7024   }
7025 
7026   // Allow #pragma omp declare variant only if the function is not used.
7027   if (FD->isUsed(false))
7028     Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
7029         << FD->getLocation();
7030 
7031   // Check if the function was emitted already.
7032   const FunctionDecl *Definition;
7033   if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) &&
7034       (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition)))
7035     Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
7036         << FD->getLocation();
7037 
7038   // The VariantRef must point to function.
7039   if (!VariantRef) {
7040     Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
7041     return None;
7042   }
7043 
7044   auto ShouldDelayChecks = [](Expr *&E, bool) {
7045     return E && (E->isTypeDependent() || E->isValueDependent() ||
7046                  E->containsUnexpandedParameterPack() ||
7047                  E->isInstantiationDependent());
7048   };
7049   // Do not check templates, wait until instantiation.
7050   if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) ||
7051       TI.anyScoreOrCondition(ShouldDelayChecks))
7052     return std::make_pair(FD, VariantRef);
7053 
7054   // Deal with non-constant score and user condition expressions.
7055   auto HandleNonConstantScoresAndConditions = [this](Expr *&E,
7056                                                      bool IsScore) -> bool {
7057     if (!E || E->isIntegerConstantExpr(Context))
7058       return false;
7059 
7060     if (IsScore) {
7061       // We warn on non-constant scores and pretend they were not present.
7062       Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant)
7063           << E;
7064       E = nullptr;
7065     } else {
7066       // We could replace a non-constant user condition with "false" but we
7067       // will soon need to handle these anyway for the dynamic version of
7068       // OpenMP context selectors.
7069       Diag(E->getExprLoc(),
7070            diag::err_omp_declare_variant_user_condition_not_constant)
7071           << E;
7072     }
7073     return true;
7074   };
7075   if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions))
7076     return None;
7077 
7078   QualType AdjustedFnType = FD->getType();
7079   if (NumAppendArgs) {
7080     const auto *PTy = AdjustedFnType->getAsAdjusted<FunctionProtoType>();
7081     if (!PTy) {
7082       Diag(FD->getLocation(), diag::err_omp_declare_variant_prototype_required)
7083           << SR;
7084       return None;
7085     }
7086     // Adjust the function type to account for an extra omp_interop_t for each
7087     // specified in the append_args clause.
7088     const TypeDecl *TD = nullptr;
7089     LookupResult Result(*this, &Context.Idents.get("omp_interop_t"),
7090                         SR.getBegin(), Sema::LookupOrdinaryName);
7091     if (LookupName(Result, getCurScope())) {
7092       NamedDecl *ND = Result.getFoundDecl();
7093       TD = dyn_cast_or_null<TypeDecl>(ND);
7094     }
7095     if (!TD) {
7096       Diag(SR.getBegin(), diag::err_omp_interop_type_not_found) << SR;
7097       return None;
7098     }
7099     QualType InteropType = Context.getTypeDeclType(TD);
7100     if (PTy->isVariadic()) {
7101       Diag(FD->getLocation(), diag::err_omp_append_args_with_varargs) << SR;
7102       return None;
7103     }
7104     llvm::SmallVector<QualType, 8> Params;
7105     Params.append(PTy->param_type_begin(), PTy->param_type_end());
7106     Params.insert(Params.end(), NumAppendArgs, InteropType);
7107     AdjustedFnType = Context.getFunctionType(PTy->getReturnType(), Params,
7108                                              PTy->getExtProtoInfo());
7109   }
7110 
7111   // Convert VariantRef expression to the type of the original function to
7112   // resolve possible conflicts.
7113   ExprResult VariantRefCast = VariantRef;
7114   if (LangOpts.CPlusPlus) {
7115     QualType FnPtrType;
7116     auto *Method = dyn_cast<CXXMethodDecl>(FD);
7117     if (Method && !Method->isStatic()) {
7118       const Type *ClassType =
7119           Context.getTypeDeclType(Method->getParent()).getTypePtr();
7120       FnPtrType = Context.getMemberPointerType(AdjustedFnType, ClassType);
7121       ExprResult ER;
7122       {
7123         // Build adrr_of unary op to correctly handle type checks for member
7124         // functions.
7125         Sema::TentativeAnalysisScope Trap(*this);
7126         ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf,
7127                                   VariantRef);
7128       }
7129       if (!ER.isUsable()) {
7130         Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7131             << VariantId << VariantRef->getSourceRange();
7132         return None;
7133       }
7134       VariantRef = ER.get();
7135     } else {
7136       FnPtrType = Context.getPointerType(AdjustedFnType);
7137     }
7138     QualType VarianPtrType = Context.getPointerType(VariantRef->getType());
7139     if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) {
7140       ImplicitConversionSequence ICS = TryImplicitConversion(
7141           VariantRef, FnPtrType.getUnqualifiedType(),
7142           /*SuppressUserConversions=*/false, AllowedExplicit::None,
7143           /*InOverloadResolution=*/false,
7144           /*CStyle=*/false,
7145           /*AllowObjCWritebackConversion=*/false);
7146       if (ICS.isFailure()) {
7147         Diag(VariantRef->getExprLoc(),
7148              diag::err_omp_declare_variant_incompat_types)
7149             << VariantRef->getType()
7150             << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
7151             << (NumAppendArgs ? 1 : 0) << VariantRef->getSourceRange();
7152         return None;
7153       }
7154       VariantRefCast = PerformImplicitConversion(
7155           VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
7156       if (!VariantRefCast.isUsable())
7157         return None;
7158     }
7159     // Drop previously built artificial addr_of unary op for member functions.
7160     if (Method && !Method->isStatic()) {
7161       Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
7162       if (auto *UO = dyn_cast<UnaryOperator>(
7163               PossibleAddrOfVariantRef->IgnoreImplicit()))
7164         VariantRefCast = UO->getSubExpr();
7165     }
7166   }
7167 
7168   ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get());
7169   if (!ER.isUsable() ||
7170       !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
7171     Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7172         << VariantId << VariantRef->getSourceRange();
7173     return None;
7174   }
7175 
7176   // The VariantRef must point to function.
7177   auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts());
7178   if (!DRE) {
7179     Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7180         << VariantId << VariantRef->getSourceRange();
7181     return None;
7182   }
7183   auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
7184   if (!NewFD) {
7185     Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7186         << VariantId << VariantRef->getSourceRange();
7187     return None;
7188   }
7189 
7190   if (FD->getCanonicalDecl() == NewFD->getCanonicalDecl()) {
7191     Diag(VariantRef->getExprLoc(),
7192          diag::err_omp_declare_variant_same_base_function)
7193         << VariantRef->getSourceRange();
7194     return None;
7195   }
7196 
7197   // Check if function types are compatible in C.
7198   if (!LangOpts.CPlusPlus) {
7199     QualType NewType =
7200         Context.mergeFunctionTypes(AdjustedFnType, NewFD->getType());
7201     if (NewType.isNull()) {
7202       Diag(VariantRef->getExprLoc(),
7203            diag::err_omp_declare_variant_incompat_types)
7204           << NewFD->getType() << FD->getType() << (NumAppendArgs ? 1 : 0)
7205           << VariantRef->getSourceRange();
7206       return None;
7207     }
7208     if (NewType->isFunctionProtoType()) {
7209       if (FD->getType()->isFunctionNoProtoType())
7210         setPrototype(*this, FD, NewFD, NewType);
7211       else if (NewFD->getType()->isFunctionNoProtoType())
7212         setPrototype(*this, NewFD, FD, NewType);
7213     }
7214   }
7215 
7216   // Check if variant function is not marked with declare variant directive.
7217   if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
7218     Diag(VariantRef->getExprLoc(),
7219          diag::warn_omp_declare_variant_marked_as_declare_variant)
7220         << VariantRef->getSourceRange();
7221     SourceRange SR =
7222         NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
7223     Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
7224     return None;
7225   }
7226 
7227   enum DoesntSupport {
7228     VirtFuncs = 1,
7229     Constructors = 3,
7230     Destructors = 4,
7231     DeletedFuncs = 5,
7232     DefaultedFuncs = 6,
7233     ConstexprFuncs = 7,
7234     ConstevalFuncs = 8,
7235   };
7236   if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
7237     if (CXXFD->isVirtual()) {
7238       Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7239           << VirtFuncs;
7240       return None;
7241     }
7242 
7243     if (isa<CXXConstructorDecl>(FD)) {
7244       Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7245           << Constructors;
7246       return None;
7247     }
7248 
7249     if (isa<CXXDestructorDecl>(FD)) {
7250       Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7251           << Destructors;
7252       return None;
7253     }
7254   }
7255 
7256   if (FD->isDeleted()) {
7257     Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7258         << DeletedFuncs;
7259     return None;
7260   }
7261 
7262   if (FD->isDefaulted()) {
7263     Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7264         << DefaultedFuncs;
7265     return None;
7266   }
7267 
7268   if (FD->isConstexpr()) {
7269     Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7270         << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
7271     return None;
7272   }
7273 
7274   // Check general compatibility.
7275   if (areMultiversionVariantFunctionsCompatible(
7276           FD, NewFD, PartialDiagnostic::NullDiagnostic(),
7277           PartialDiagnosticAt(SourceLocation(),
7278                               PartialDiagnostic::NullDiagnostic()),
7279           PartialDiagnosticAt(
7280               VariantRef->getExprLoc(),
7281               PDiag(diag::err_omp_declare_variant_doesnt_support)),
7282           PartialDiagnosticAt(VariantRef->getExprLoc(),
7283                               PDiag(diag::err_omp_declare_variant_diff)
7284                                   << FD->getLocation()),
7285           /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
7286           /*CLinkageMayDiffer=*/true))
7287     return None;
7288   return std::make_pair(FD, cast<Expr>(DRE));
7289 }
7290 
7291 void Sema::ActOnOpenMPDeclareVariantDirective(
7292     FunctionDecl *FD, Expr *VariantRef, OMPTraitInfo &TI,
7293     ArrayRef<Expr *> AdjustArgsNothing,
7294     ArrayRef<Expr *> AdjustArgsNeedDevicePtr,
7295     ArrayRef<OMPDeclareVariantAttr::InteropType> AppendArgs,
7296     SourceLocation AdjustArgsLoc, SourceLocation AppendArgsLoc,
7297     SourceRange SR) {
7298 
7299   // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions]
7300   // An adjust_args clause or append_args clause can only be specified if the
7301   // dispatch selector of the construct selector set appears in the match
7302   // clause.
7303 
7304   SmallVector<Expr *, 8> AllAdjustArgs;
7305   llvm::append_range(AllAdjustArgs, AdjustArgsNothing);
7306   llvm::append_range(AllAdjustArgs, AdjustArgsNeedDevicePtr);
7307 
7308   if (!AllAdjustArgs.empty() || !AppendArgs.empty()) {
7309     VariantMatchInfo VMI;
7310     TI.getAsVariantMatchInfo(Context, VMI);
7311     if (!llvm::is_contained(
7312             VMI.ConstructTraits,
7313             llvm::omp::TraitProperty::construct_dispatch_dispatch)) {
7314       if (!AllAdjustArgs.empty())
7315         Diag(AdjustArgsLoc, diag::err_omp_clause_requires_dispatch_construct)
7316             << getOpenMPClauseName(OMPC_adjust_args);
7317       if (!AppendArgs.empty())
7318         Diag(AppendArgsLoc, diag::err_omp_clause_requires_dispatch_construct)
7319             << getOpenMPClauseName(OMPC_append_args);
7320       return;
7321     }
7322   }
7323 
7324   // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions]
7325   // Each argument can only appear in a single adjust_args clause for each
7326   // declare variant directive.
7327   llvm::SmallPtrSet<const VarDecl *, 4> AdjustVars;
7328 
7329   for (Expr *E : AllAdjustArgs) {
7330     E = E->IgnoreParenImpCasts();
7331     if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) {
7332       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
7333         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
7334         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
7335             FD->getParamDecl(PVD->getFunctionScopeIndex())
7336                     ->getCanonicalDecl() == CanonPVD) {
7337           // It's a parameter of the function, check duplicates.
7338           if (!AdjustVars.insert(CanonPVD).second) {
7339             Diag(DRE->getLocation(), diag::err_omp_adjust_arg_multiple_clauses)
7340                 << PVD;
7341             return;
7342           }
7343           continue;
7344         }
7345       }
7346     }
7347     // Anything that is not a function parameter is an error.
7348     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) << FD << 0;
7349     return;
7350   }
7351 
7352   auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit(
7353       Context, VariantRef, &TI, const_cast<Expr **>(AdjustArgsNothing.data()),
7354       AdjustArgsNothing.size(),
7355       const_cast<Expr **>(AdjustArgsNeedDevicePtr.data()),
7356       AdjustArgsNeedDevicePtr.size(),
7357       const_cast<OMPDeclareVariantAttr::InteropType *>(AppendArgs.data()),
7358       AppendArgs.size(), SR);
7359   FD->addAttr(NewAttr);
7360 }
7361 
7362 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
7363                                               Stmt *AStmt,
7364                                               SourceLocation StartLoc,
7365                                               SourceLocation EndLoc) {
7366   if (!AStmt)
7367     return StmtError();
7368 
7369   auto *CS = cast<CapturedStmt>(AStmt);
7370   // 1.2.2 OpenMP Language Terminology
7371   // Structured block - An executable statement with a single entry at the
7372   // top and a single exit at the bottom.
7373   // The point of exit cannot be a branch out of the structured block.
7374   // longjmp() and throw() must not violate the entry/exit criteria.
7375   CS->getCapturedDecl()->setNothrow();
7376 
7377   setFunctionHasBranchProtectedScope();
7378 
7379   return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
7380                                       DSAStack->getTaskgroupReductionRef(),
7381                                       DSAStack->isCancelRegion());
7382 }
7383 
7384 namespace {
7385 /// Iteration space of a single for loop.
7386 struct LoopIterationSpace final {
7387   /// True if the condition operator is the strict compare operator (<, > or
7388   /// !=).
7389   bool IsStrictCompare = false;
7390   /// Condition of the loop.
7391   Expr *PreCond = nullptr;
7392   /// This expression calculates the number of iterations in the loop.
7393   /// It is always possible to calculate it before starting the loop.
7394   Expr *NumIterations = nullptr;
7395   /// The loop counter variable.
7396   Expr *CounterVar = nullptr;
7397   /// Private loop counter variable.
7398   Expr *PrivateCounterVar = nullptr;
7399   /// This is initializer for the initial value of #CounterVar.
7400   Expr *CounterInit = nullptr;
7401   /// This is step for the #CounterVar used to generate its update:
7402   /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
7403   Expr *CounterStep = nullptr;
7404   /// Should step be subtracted?
7405   bool Subtract = false;
7406   /// Source range of the loop init.
7407   SourceRange InitSrcRange;
7408   /// Source range of the loop condition.
7409   SourceRange CondSrcRange;
7410   /// Source range of the loop increment.
7411   SourceRange IncSrcRange;
7412   /// Minimum value that can have the loop control variable. Used to support
7413   /// non-rectangular loops. Applied only for LCV with the non-iterator types,
7414   /// since only such variables can be used in non-loop invariant expressions.
7415   Expr *MinValue = nullptr;
7416   /// Maximum value that can have the loop control variable. Used to support
7417   /// non-rectangular loops. Applied only for LCV with the non-iterator type,
7418   /// since only such variables can be used in non-loop invariant expressions.
7419   Expr *MaxValue = nullptr;
7420   /// true, if the lower bound depends on the outer loop control var.
7421   bool IsNonRectangularLB = false;
7422   /// true, if the upper bound depends on the outer loop control var.
7423   bool IsNonRectangularUB = false;
7424   /// Index of the loop this loop depends on and forms non-rectangular loop
7425   /// nest.
7426   unsigned LoopDependentIdx = 0;
7427   /// Final condition for the non-rectangular loop nest support. It is used to
7428   /// check that the number of iterations for this particular counter must be
7429   /// finished.
7430   Expr *FinalCondition = nullptr;
7431 };
7432 
7433 /// Helper class for checking canonical form of the OpenMP loops and
7434 /// extracting iteration space of each loop in the loop nest, that will be used
7435 /// for IR generation.
7436 class OpenMPIterationSpaceChecker {
7437   /// Reference to Sema.
7438   Sema &SemaRef;
7439   /// Does the loop associated directive support non-rectangular loops?
7440   bool SupportsNonRectangular;
7441   /// Data-sharing stack.
7442   DSAStackTy &Stack;
7443   /// A location for diagnostics (when there is no some better location).
7444   SourceLocation DefaultLoc;
7445   /// A location for diagnostics (when increment is not compatible).
7446   SourceLocation ConditionLoc;
7447   /// A source location for referring to loop init later.
7448   SourceRange InitSrcRange;
7449   /// A source location for referring to condition later.
7450   SourceRange ConditionSrcRange;
7451   /// A source location for referring to increment later.
7452   SourceRange IncrementSrcRange;
7453   /// Loop variable.
7454   ValueDecl *LCDecl = nullptr;
7455   /// Reference to loop variable.
7456   Expr *LCRef = nullptr;
7457   /// Lower bound (initializer for the var).
7458   Expr *LB = nullptr;
7459   /// Upper bound.
7460   Expr *UB = nullptr;
7461   /// Loop step (increment).
7462   Expr *Step = nullptr;
7463   /// This flag is true when condition is one of:
7464   ///   Var <  UB
7465   ///   Var <= UB
7466   ///   UB  >  Var
7467   ///   UB  >= Var
7468   /// This will have no value when the condition is !=
7469   llvm::Optional<bool> TestIsLessOp;
7470   /// This flag is true when condition is strict ( < or > ).
7471   bool TestIsStrictOp = false;
7472   /// This flag is true when step is subtracted on each iteration.
7473   bool SubtractStep = false;
7474   /// The outer loop counter this loop depends on (if any).
7475   const ValueDecl *DepDecl = nullptr;
7476   /// Contains number of loop (starts from 1) on which loop counter init
7477   /// expression of this loop depends on.
7478   Optional<unsigned> InitDependOnLC;
7479   /// Contains number of loop (starts from 1) on which loop counter condition
7480   /// expression of this loop depends on.
7481   Optional<unsigned> CondDependOnLC;
7482   /// Checks if the provide statement depends on the loop counter.
7483   Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer);
7484   /// Original condition required for checking of the exit condition for
7485   /// non-rectangular loop.
7486   Expr *Condition = nullptr;
7487 
7488 public:
7489   OpenMPIterationSpaceChecker(Sema &SemaRef, bool SupportsNonRectangular,
7490                               DSAStackTy &Stack, SourceLocation DefaultLoc)
7491       : SemaRef(SemaRef), SupportsNonRectangular(SupportsNonRectangular),
7492         Stack(Stack), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
7493   /// Check init-expr for canonical loop form and save loop counter
7494   /// variable - #Var and its initialization value - #LB.
7495   bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
7496   /// Check test-expr for canonical form, save upper-bound (#UB), flags
7497   /// for less/greater and for strict/non-strict comparison.
7498   bool checkAndSetCond(Expr *S);
7499   /// Check incr-expr for canonical loop form and return true if it
7500   /// does not conform, otherwise save loop step (#Step).
7501   bool checkAndSetInc(Expr *S);
7502   /// Return the loop counter variable.
7503   ValueDecl *getLoopDecl() const { return LCDecl; }
7504   /// Return the reference expression to loop counter variable.
7505   Expr *getLoopDeclRefExpr() const { return LCRef; }
7506   /// Source range of the loop init.
7507   SourceRange getInitSrcRange() const { return InitSrcRange; }
7508   /// Source range of the loop condition.
7509   SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
7510   /// Source range of the loop increment.
7511   SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
7512   /// True if the step should be subtracted.
7513   bool shouldSubtractStep() const { return SubtractStep; }
7514   /// True, if the compare operator is strict (<, > or !=).
7515   bool isStrictTestOp() const { return TestIsStrictOp; }
7516   /// Build the expression to calculate the number of iterations.
7517   Expr *buildNumIterations(
7518       Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
7519       llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7520   /// Build the precondition expression for the loops.
7521   Expr *
7522   buildPreCond(Scope *S, Expr *Cond,
7523                llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7524   /// Build reference expression to the counter be used for codegen.
7525   DeclRefExpr *
7526   buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7527                   DSAStackTy &DSA) const;
7528   /// Build reference expression to the private counter be used for
7529   /// codegen.
7530   Expr *buildPrivateCounterVar() const;
7531   /// Build initialization of the counter be used for codegen.
7532   Expr *buildCounterInit() const;
7533   /// Build step of the counter be used for codegen.
7534   Expr *buildCounterStep() const;
7535   /// Build loop data with counter value for depend clauses in ordered
7536   /// directives.
7537   Expr *
7538   buildOrderedLoopData(Scope *S, Expr *Counter,
7539                        llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7540                        SourceLocation Loc, Expr *Inc = nullptr,
7541                        OverloadedOperatorKind OOK = OO_Amp);
7542   /// Builds the minimum value for the loop counter.
7543   std::pair<Expr *, Expr *> buildMinMaxValues(
7544       Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7545   /// Builds final condition for the non-rectangular loops.
7546   Expr *buildFinalCondition(Scope *S) const;
7547   /// Return true if any expression is dependent.
7548   bool dependent() const;
7549   /// Returns true if the initializer forms non-rectangular loop.
7550   bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); }
7551   /// Returns true if the condition forms non-rectangular loop.
7552   bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); }
7553   /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
7554   unsigned getLoopDependentIdx() const {
7555     return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0));
7556   }
7557 
7558 private:
7559   /// Check the right-hand side of an assignment in the increment
7560   /// expression.
7561   bool checkAndSetIncRHS(Expr *RHS);
7562   /// Helper to set loop counter variable and its initializer.
7563   bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
7564                       bool EmitDiags);
7565   /// Helper to set upper bound.
7566   bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp,
7567              SourceRange SR, SourceLocation SL);
7568   /// Helper to set loop increment.
7569   bool setStep(Expr *NewStep, bool Subtract);
7570 };
7571 
7572 bool OpenMPIterationSpaceChecker::dependent() const {
7573   if (!LCDecl) {
7574     assert(!LB && !UB && !Step);
7575     return false;
7576   }
7577   return LCDecl->getType()->isDependentType() ||
7578          (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
7579          (Step && Step->isValueDependent());
7580 }
7581 
7582 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
7583                                                  Expr *NewLCRefExpr,
7584                                                  Expr *NewLB, bool EmitDiags) {
7585   // State consistency checking to ensure correct usage.
7586   assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
7587          UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
7588   if (!NewLCDecl || !NewLB || NewLB->containsErrors())
7589     return true;
7590   LCDecl = getCanonicalDecl(NewLCDecl);
7591   LCRef = NewLCRefExpr;
7592   if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
7593     if (const CXXConstructorDecl *Ctor = CE->getConstructor())
7594       if ((Ctor->isCopyOrMoveConstructor() ||
7595            Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
7596           CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
7597         NewLB = CE->getArg(0)->IgnoreParenImpCasts();
7598   LB = NewLB;
7599   if (EmitDiags)
7600     InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
7601   return false;
7602 }
7603 
7604 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB,
7605                                         llvm::Optional<bool> LessOp,
7606                                         bool StrictOp, SourceRange SR,
7607                                         SourceLocation SL) {
7608   // State consistency checking to ensure correct usage.
7609   assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&
7610          Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
7611   if (!NewUB || NewUB->containsErrors())
7612     return true;
7613   UB = NewUB;
7614   if (LessOp)
7615     TestIsLessOp = LessOp;
7616   TestIsStrictOp = StrictOp;
7617   ConditionSrcRange = SR;
7618   ConditionLoc = SL;
7619   CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
7620   return false;
7621 }
7622 
7623 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
7624   // State consistency checking to ensure correct usage.
7625   assert(LCDecl != nullptr && LB != nullptr && Step == nullptr);
7626   if (!NewStep || NewStep->containsErrors())
7627     return true;
7628   if (!NewStep->isValueDependent()) {
7629     // Check that the step is integer expression.
7630     SourceLocation StepLoc = NewStep->getBeginLoc();
7631     ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
7632         StepLoc, getExprAsWritten(NewStep));
7633     if (Val.isInvalid())
7634       return true;
7635     NewStep = Val.get();
7636 
7637     // OpenMP [2.6, Canonical Loop Form, Restrictions]
7638     //  If test-expr is of form var relational-op b and relational-op is < or
7639     //  <= then incr-expr must cause var to increase on each iteration of the
7640     //  loop. If test-expr is of form var relational-op b and relational-op is
7641     //  > or >= then incr-expr must cause var to decrease on each iteration of
7642     //  the loop.
7643     //  If test-expr is of form b relational-op var and relational-op is < or
7644     //  <= then incr-expr must cause var to decrease on each iteration of the
7645     //  loop. If test-expr is of form b relational-op var and relational-op is
7646     //  > or >= then incr-expr must cause var to increase on each iteration of
7647     //  the loop.
7648     Optional<llvm::APSInt> Result =
7649         NewStep->getIntegerConstantExpr(SemaRef.Context);
7650     bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
7651     bool IsConstNeg =
7652         Result && Result->isSigned() && (Subtract != Result->isNegative());
7653     bool IsConstPos =
7654         Result && Result->isSigned() && (Subtract == Result->isNegative());
7655     bool IsConstZero = Result && !Result->getBoolValue();
7656 
7657     // != with increment is treated as <; != with decrement is treated as >
7658     if (!TestIsLessOp.hasValue())
7659       TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
7660     if (UB &&
7661         (IsConstZero || (TestIsLessOp.getValue()
7662                              ? (IsConstNeg || (IsUnsigned && Subtract))
7663                              : (IsConstPos || (IsUnsigned && !Subtract))))) {
7664       SemaRef.Diag(NewStep->getExprLoc(),
7665                    diag::err_omp_loop_incr_not_compatible)
7666           << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange();
7667       SemaRef.Diag(ConditionLoc,
7668                    diag::note_omp_loop_cond_requres_compatible_incr)
7669           << TestIsLessOp.getValue() << ConditionSrcRange;
7670       return true;
7671     }
7672     if (TestIsLessOp.getValue() == Subtract) {
7673       NewStep =
7674           SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
7675               .get();
7676       Subtract = !Subtract;
7677     }
7678   }
7679 
7680   Step = NewStep;
7681   SubtractStep = Subtract;
7682   return false;
7683 }
7684 
7685 namespace {
7686 /// Checker for the non-rectangular loops. Checks if the initializer or
7687 /// condition expression references loop counter variable.
7688 class LoopCounterRefChecker final
7689     : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
7690   Sema &SemaRef;
7691   DSAStackTy &Stack;
7692   const ValueDecl *CurLCDecl = nullptr;
7693   const ValueDecl *DepDecl = nullptr;
7694   const ValueDecl *PrevDepDecl = nullptr;
7695   bool IsInitializer = true;
7696   bool SupportsNonRectangular;
7697   unsigned BaseLoopId = 0;
7698   bool checkDecl(const Expr *E, const ValueDecl *VD) {
7699     if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
7700       SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
7701           << (IsInitializer ? 0 : 1);
7702       return false;
7703     }
7704     const auto &&Data = Stack.isLoopControlVariable(VD);
7705     // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
7706     // The type of the loop iterator on which we depend may not have a random
7707     // access iterator type.
7708     if (Data.first && VD->getType()->isRecordType()) {
7709       SmallString<128> Name;
7710       llvm::raw_svector_ostream OS(Name);
7711       VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
7712                                /*Qualified=*/true);
7713       SemaRef.Diag(E->getExprLoc(),
7714                    diag::err_omp_wrong_dependency_iterator_type)
7715           << OS.str();
7716       SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
7717       return false;
7718     }
7719     if (Data.first && !SupportsNonRectangular) {
7720       SemaRef.Diag(E->getExprLoc(), diag::err_omp_invariant_dependency);
7721       return false;
7722     }
7723     if (Data.first &&
7724         (DepDecl || (PrevDepDecl &&
7725                      getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
7726       if (!DepDecl && PrevDepDecl)
7727         DepDecl = PrevDepDecl;
7728       SmallString<128> Name;
7729       llvm::raw_svector_ostream OS(Name);
7730       DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
7731                                     /*Qualified=*/true);
7732       SemaRef.Diag(E->getExprLoc(),
7733                    diag::err_omp_invariant_or_linear_dependency)
7734           << OS.str();
7735       return false;
7736     }
7737     if (Data.first) {
7738       DepDecl = VD;
7739       BaseLoopId = Data.first;
7740     }
7741     return Data.first;
7742   }
7743 
7744 public:
7745   bool VisitDeclRefExpr(const DeclRefExpr *E) {
7746     const ValueDecl *VD = E->getDecl();
7747     if (isa<VarDecl>(VD))
7748       return checkDecl(E, VD);
7749     return false;
7750   }
7751   bool VisitMemberExpr(const MemberExpr *E) {
7752     if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
7753       const ValueDecl *VD = E->getMemberDecl();
7754       if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
7755         return checkDecl(E, VD);
7756     }
7757     return false;
7758   }
7759   bool VisitStmt(const Stmt *S) {
7760     bool Res = false;
7761     for (const Stmt *Child : S->children())
7762       Res = (Child && Visit(Child)) || Res;
7763     return Res;
7764   }
7765   explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
7766                                  const ValueDecl *CurLCDecl, bool IsInitializer,
7767                                  const ValueDecl *PrevDepDecl = nullptr,
7768                                  bool SupportsNonRectangular = true)
7769       : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
7770         PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer),
7771         SupportsNonRectangular(SupportsNonRectangular) {}
7772   unsigned getBaseLoopId() const {
7773     assert(CurLCDecl && "Expected loop dependency.");
7774     return BaseLoopId;
7775   }
7776   const ValueDecl *getDepDecl() const {
7777     assert(CurLCDecl && "Expected loop dependency.");
7778     return DepDecl;
7779   }
7780 };
7781 } // namespace
7782 
7783 Optional<unsigned>
7784 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
7785                                                      bool IsInitializer) {
7786   // Check for the non-rectangular loops.
7787   LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
7788                                         DepDecl, SupportsNonRectangular);
7789   if (LoopStmtChecker.Visit(S)) {
7790     DepDecl = LoopStmtChecker.getDepDecl();
7791     return LoopStmtChecker.getBaseLoopId();
7792   }
7793   return llvm::None;
7794 }
7795 
7796 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
7797   // Check init-expr for canonical loop form and save loop counter
7798   // variable - #Var and its initialization value - #LB.
7799   // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
7800   //   var = lb
7801   //   integer-type var = lb
7802   //   random-access-iterator-type var = lb
7803   //   pointer-type var = lb
7804   //
7805   if (!S) {
7806     if (EmitDiags) {
7807       SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
7808     }
7809     return true;
7810   }
7811   if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
7812     if (!ExprTemp->cleanupsHaveSideEffects())
7813       S = ExprTemp->getSubExpr();
7814 
7815   InitSrcRange = S->getSourceRange();
7816   if (Expr *E = dyn_cast<Expr>(S))
7817     S = E->IgnoreParens();
7818   if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7819     if (BO->getOpcode() == BO_Assign) {
7820       Expr *LHS = BO->getLHS()->IgnoreParens();
7821       if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
7822         if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
7823           if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
7824             return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7825                                   EmitDiags);
7826         return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
7827       }
7828       if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
7829         if (ME->isArrow() &&
7830             isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7831           return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7832                                 EmitDiags);
7833       }
7834     }
7835   } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
7836     if (DS->isSingleDecl()) {
7837       if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
7838         if (Var->hasInit() && !Var->getType()->isReferenceType()) {
7839           // Accept non-canonical init form here but emit ext. warning.
7840           if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
7841             SemaRef.Diag(S->getBeginLoc(),
7842                          diag::ext_omp_loop_not_canonical_init)
7843                 << S->getSourceRange();
7844           return setLCDeclAndLB(
7845               Var,
7846               buildDeclRefExpr(SemaRef, Var,
7847                                Var->getType().getNonReferenceType(),
7848                                DS->getBeginLoc()),
7849               Var->getInit(), EmitDiags);
7850         }
7851       }
7852     }
7853   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7854     if (CE->getOperator() == OO_Equal) {
7855       Expr *LHS = CE->getArg(0);
7856       if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
7857         if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
7858           if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
7859             return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7860                                   EmitDiags);
7861         return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
7862       }
7863       if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
7864         if (ME->isArrow() &&
7865             isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7866           return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7867                                 EmitDiags);
7868       }
7869     }
7870   }
7871 
7872   if (dependent() || SemaRef.CurContext->isDependentContext())
7873     return false;
7874   if (EmitDiags) {
7875     SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
7876         << S->getSourceRange();
7877   }
7878   return true;
7879 }
7880 
7881 /// Ignore parenthesizes, implicit casts, copy constructor and return the
7882 /// variable (which may be the loop variable) if possible.
7883 static const ValueDecl *getInitLCDecl(const Expr *E) {
7884   if (!E)
7885     return nullptr;
7886   E = getExprAsWritten(E);
7887   if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
7888     if (const CXXConstructorDecl *Ctor = CE->getConstructor())
7889       if ((Ctor->isCopyOrMoveConstructor() ||
7890            Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
7891           CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
7892         E = CE->getArg(0)->IgnoreParenImpCasts();
7893   if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
7894     if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
7895       return getCanonicalDecl(VD);
7896   }
7897   if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
7898     if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7899       return getCanonicalDecl(ME->getMemberDecl());
7900   return nullptr;
7901 }
7902 
7903 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
7904   // Check test-expr for canonical form, save upper-bound UB, flags for
7905   // less/greater and for strict/non-strict comparison.
7906   // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following:
7907   //   var relational-op b
7908   //   b relational-op var
7909   //
7910   bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
7911   if (!S) {
7912     SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
7913         << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
7914     return true;
7915   }
7916   Condition = S;
7917   S = getExprAsWritten(S);
7918   SourceLocation CondLoc = S->getBeginLoc();
7919   auto &&CheckAndSetCond = [this, IneqCondIsCanonical](
7920                                BinaryOperatorKind Opcode, const Expr *LHS,
7921                                const Expr *RHS, SourceRange SR,
7922                                SourceLocation OpLoc) -> llvm::Optional<bool> {
7923     if (BinaryOperator::isRelationalOp(Opcode)) {
7924       if (getInitLCDecl(LHS) == LCDecl)
7925         return setUB(const_cast<Expr *>(RHS),
7926                      (Opcode == BO_LT || Opcode == BO_LE),
7927                      (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
7928       if (getInitLCDecl(RHS) == LCDecl)
7929         return setUB(const_cast<Expr *>(LHS),
7930                      (Opcode == BO_GT || Opcode == BO_GE),
7931                      (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
7932     } else if (IneqCondIsCanonical && Opcode == BO_NE) {
7933       return setUB(const_cast<Expr *>(getInitLCDecl(LHS) == LCDecl ? RHS : LHS),
7934                    /*LessOp=*/llvm::None,
7935                    /*StrictOp=*/true, SR, OpLoc);
7936     }
7937     return llvm::None;
7938   };
7939   llvm::Optional<bool> Res;
7940   if (auto *RBO = dyn_cast<CXXRewrittenBinaryOperator>(S)) {
7941     CXXRewrittenBinaryOperator::DecomposedForm DF = RBO->getDecomposedForm();
7942     Res = CheckAndSetCond(DF.Opcode, DF.LHS, DF.RHS, RBO->getSourceRange(),
7943                           RBO->getOperatorLoc());
7944   } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7945     Res = CheckAndSetCond(BO->getOpcode(), BO->getLHS(), BO->getRHS(),
7946                           BO->getSourceRange(), BO->getOperatorLoc());
7947   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7948     if (CE->getNumArgs() == 2) {
7949       Res = CheckAndSetCond(
7950           BinaryOperator::getOverloadedOpcode(CE->getOperator()), CE->getArg(0),
7951           CE->getArg(1), CE->getSourceRange(), CE->getOperatorLoc());
7952     }
7953   }
7954   if (Res.hasValue())
7955     return *Res;
7956   if (dependent() || SemaRef.CurContext->isDependentContext())
7957     return false;
7958   SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
7959       << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
7960   return true;
7961 }
7962 
7963 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
7964   // RHS of canonical loop form increment can be:
7965   //   var + incr
7966   //   incr + var
7967   //   var - incr
7968   //
7969   RHS = RHS->IgnoreParenImpCasts();
7970   if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
7971     if (BO->isAdditiveOp()) {
7972       bool IsAdd = BO->getOpcode() == BO_Add;
7973       if (getInitLCDecl(BO->getLHS()) == LCDecl)
7974         return setStep(BO->getRHS(), !IsAdd);
7975       if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
7976         return setStep(BO->getLHS(), /*Subtract=*/false);
7977     }
7978   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
7979     bool IsAdd = CE->getOperator() == OO_Plus;
7980     if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
7981       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7982         return setStep(CE->getArg(1), !IsAdd);
7983       if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
7984         return setStep(CE->getArg(0), /*Subtract=*/false);
7985     }
7986   }
7987   if (dependent() || SemaRef.CurContext->isDependentContext())
7988     return false;
7989   SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
7990       << RHS->getSourceRange() << LCDecl;
7991   return true;
7992 }
7993 
7994 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
7995   // Check incr-expr for canonical loop form and return true if it
7996   // does not conform.
7997   // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
7998   //   ++var
7999   //   var++
8000   //   --var
8001   //   var--
8002   //   var += incr
8003   //   var -= incr
8004   //   var = var + incr
8005   //   var = incr + var
8006   //   var = var - incr
8007   //
8008   if (!S) {
8009     SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
8010     return true;
8011   }
8012   if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
8013     if (!ExprTemp->cleanupsHaveSideEffects())
8014       S = ExprTemp->getSubExpr();
8015 
8016   IncrementSrcRange = S->getSourceRange();
8017   S = S->IgnoreParens();
8018   if (auto *UO = dyn_cast<UnaryOperator>(S)) {
8019     if (UO->isIncrementDecrementOp() &&
8020         getInitLCDecl(UO->getSubExpr()) == LCDecl)
8021       return setStep(SemaRef
8022                          .ActOnIntegerConstant(UO->getBeginLoc(),
8023                                                (UO->isDecrementOp() ? -1 : 1))
8024                          .get(),
8025                      /*Subtract=*/false);
8026   } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
8027     switch (BO->getOpcode()) {
8028     case BO_AddAssign:
8029     case BO_SubAssign:
8030       if (getInitLCDecl(BO->getLHS()) == LCDecl)
8031         return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
8032       break;
8033     case BO_Assign:
8034       if (getInitLCDecl(BO->getLHS()) == LCDecl)
8035         return checkAndSetIncRHS(BO->getRHS());
8036       break;
8037     default:
8038       break;
8039     }
8040   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
8041     switch (CE->getOperator()) {
8042     case OO_PlusPlus:
8043     case OO_MinusMinus:
8044       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8045         return setStep(SemaRef
8046                            .ActOnIntegerConstant(
8047                                CE->getBeginLoc(),
8048                                ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
8049                            .get(),
8050                        /*Subtract=*/false);
8051       break;
8052     case OO_PlusEqual:
8053     case OO_MinusEqual:
8054       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8055         return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
8056       break;
8057     case OO_Equal:
8058       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
8059         return checkAndSetIncRHS(CE->getArg(1));
8060       break;
8061     default:
8062       break;
8063     }
8064   }
8065   if (dependent() || SemaRef.CurContext->isDependentContext())
8066     return false;
8067   SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
8068       << S->getSourceRange() << LCDecl;
8069   return true;
8070 }
8071 
8072 static ExprResult
8073 tryBuildCapture(Sema &SemaRef, Expr *Capture,
8074                 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8075   if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors())
8076     return Capture;
8077   if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
8078     return SemaRef.PerformImplicitConversion(
8079         Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
8080         /*AllowExplicit=*/true);
8081   auto I = Captures.find(Capture);
8082   if (I != Captures.end())
8083     return buildCapture(SemaRef, Capture, I->second);
8084   DeclRefExpr *Ref = nullptr;
8085   ExprResult Res = buildCapture(SemaRef, Capture, Ref);
8086   Captures[Capture] = Ref;
8087   return Res;
8088 }
8089 
8090 /// Calculate number of iterations, transforming to unsigned, if number of
8091 /// iterations may be larger than the original type.
8092 static Expr *
8093 calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc,
8094                   Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy,
8095                   bool TestIsStrictOp, bool RoundToStep,
8096                   llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8097   ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
8098   if (!NewStep.isUsable())
8099     return nullptr;
8100   llvm::APSInt LRes, SRes;
8101   bool IsLowerConst = false, IsStepConst = false;
8102   if (Optional<llvm::APSInt> Res =
8103           Lower->getIntegerConstantExpr(SemaRef.Context)) {
8104     LRes = *Res;
8105     IsLowerConst = true;
8106   }
8107   if (Optional<llvm::APSInt> Res =
8108           Step->getIntegerConstantExpr(SemaRef.Context)) {
8109     SRes = *Res;
8110     IsStepConst = true;
8111   }
8112   bool NoNeedToConvert = IsLowerConst && !RoundToStep &&
8113                          ((!TestIsStrictOp && LRes.isNonNegative()) ||
8114                           (TestIsStrictOp && LRes.isStrictlyPositive()));
8115   bool NeedToReorganize = false;
8116   // Check if any subexpressions in Lower -Step [+ 1] lead to overflow.
8117   if (!NoNeedToConvert && IsLowerConst &&
8118       (TestIsStrictOp || (RoundToStep && IsStepConst))) {
8119     NoNeedToConvert = true;
8120     if (RoundToStep) {
8121       unsigned BW = LRes.getBitWidth() > SRes.getBitWidth()
8122                         ? LRes.getBitWidth()
8123                         : SRes.getBitWidth();
8124       LRes = LRes.extend(BW + 1);
8125       LRes.setIsSigned(true);
8126       SRes = SRes.extend(BW + 1);
8127       SRes.setIsSigned(true);
8128       LRes -= SRes;
8129       NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes;
8130       LRes = LRes.trunc(BW);
8131     }
8132     if (TestIsStrictOp) {
8133       unsigned BW = LRes.getBitWidth();
8134       LRes = LRes.extend(BW + 1);
8135       LRes.setIsSigned(true);
8136       ++LRes;
8137       NoNeedToConvert =
8138           NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes;
8139       // truncate to the original bitwidth.
8140       LRes = LRes.trunc(BW);
8141     }
8142     NeedToReorganize = NoNeedToConvert;
8143   }
8144   llvm::APSInt URes;
8145   bool IsUpperConst = false;
8146   if (Optional<llvm::APSInt> Res =
8147           Upper->getIntegerConstantExpr(SemaRef.Context)) {
8148     URes = *Res;
8149     IsUpperConst = true;
8150   }
8151   if (NoNeedToConvert && IsLowerConst && IsUpperConst &&
8152       (!RoundToStep || IsStepConst)) {
8153     unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth()
8154                                                           : URes.getBitWidth();
8155     LRes = LRes.extend(BW + 1);
8156     LRes.setIsSigned(true);
8157     URes = URes.extend(BW + 1);
8158     URes.setIsSigned(true);
8159     URes -= LRes;
8160     NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes;
8161     NeedToReorganize = NoNeedToConvert;
8162   }
8163   // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant
8164   // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to
8165   // unsigned.
8166   if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) &&
8167       !LCTy->isDependentType() && LCTy->isIntegerType()) {
8168     QualType LowerTy = Lower->getType();
8169     QualType UpperTy = Upper->getType();
8170     uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy);
8171     uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy);
8172     if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) ||
8173         (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) {
8174       QualType CastType = SemaRef.Context.getIntTypeForBitwidth(
8175           LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0);
8176       Upper =
8177           SemaRef
8178               .PerformImplicitConversion(
8179                   SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
8180                   CastType, Sema::AA_Converting)
8181               .get();
8182       Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get();
8183       NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get());
8184     }
8185   }
8186   if (!Lower || !Upper || NewStep.isInvalid())
8187     return nullptr;
8188 
8189   ExprResult Diff;
8190   // If need to reorganize, then calculate the form as Upper - (Lower - Step [+
8191   // 1]).
8192   if (NeedToReorganize) {
8193     Diff = Lower;
8194 
8195     if (RoundToStep) {
8196       // Lower - Step
8197       Diff =
8198           SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get());
8199       if (!Diff.isUsable())
8200         return nullptr;
8201     }
8202 
8203     // Lower - Step [+ 1]
8204     if (TestIsStrictOp)
8205       Diff = SemaRef.BuildBinOp(
8206           S, DefaultLoc, BO_Add, Diff.get(),
8207           SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8208     if (!Diff.isUsable())
8209       return nullptr;
8210 
8211     Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8212     if (!Diff.isUsable())
8213       return nullptr;
8214 
8215     // Upper - (Lower - Step [+ 1]).
8216     Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get());
8217     if (!Diff.isUsable())
8218       return nullptr;
8219   } else {
8220     Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
8221 
8222     if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) {
8223       // BuildBinOp already emitted error, this one is to point user to upper
8224       // and lower bound, and to tell what is passed to 'operator-'.
8225       SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
8226           << Upper->getSourceRange() << Lower->getSourceRange();
8227       return nullptr;
8228     }
8229 
8230     if (!Diff.isUsable())
8231       return nullptr;
8232 
8233     // Upper - Lower [- 1]
8234     if (TestIsStrictOp)
8235       Diff = SemaRef.BuildBinOp(
8236           S, DefaultLoc, BO_Sub, Diff.get(),
8237           SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
8238     if (!Diff.isUsable())
8239       return nullptr;
8240 
8241     if (RoundToStep) {
8242       // Upper - Lower [- 1] + Step
8243       Diff =
8244           SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
8245       if (!Diff.isUsable())
8246         return nullptr;
8247     }
8248   }
8249 
8250   // Parentheses (for dumping/debugging purposes only).
8251   Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8252   if (!Diff.isUsable())
8253     return nullptr;
8254 
8255   // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step
8256   Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
8257   if (!Diff.isUsable())
8258     return nullptr;
8259 
8260   return Diff.get();
8261 }
8262 
8263 /// Build the expression to calculate the number of iterations.
8264 Expr *OpenMPIterationSpaceChecker::buildNumIterations(
8265     Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
8266     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8267   QualType VarType = LCDecl->getType().getNonReferenceType();
8268   if (!VarType->isIntegerType() && !VarType->isPointerType() &&
8269       !SemaRef.getLangOpts().CPlusPlus)
8270     return nullptr;
8271   Expr *LBVal = LB;
8272   Expr *UBVal = UB;
8273   // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
8274   // max(LB(MinVal), LB(MaxVal))
8275   if (InitDependOnLC) {
8276     const LoopIterationSpace &IS = ResultIterSpaces[*InitDependOnLC - 1];
8277     if (!IS.MinValue || !IS.MaxValue)
8278       return nullptr;
8279     // OuterVar = Min
8280     ExprResult MinValue =
8281         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8282     if (!MinValue.isUsable())
8283       return nullptr;
8284 
8285     ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8286                                              IS.CounterVar, MinValue.get());
8287     if (!LBMinVal.isUsable())
8288       return nullptr;
8289     // OuterVar = Min, LBVal
8290     LBMinVal =
8291         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal);
8292     if (!LBMinVal.isUsable())
8293       return nullptr;
8294     // (OuterVar = Min, LBVal)
8295     LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get());
8296     if (!LBMinVal.isUsable())
8297       return nullptr;
8298 
8299     // OuterVar = Max
8300     ExprResult MaxValue =
8301         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8302     if (!MaxValue.isUsable())
8303       return nullptr;
8304 
8305     ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8306                                              IS.CounterVar, MaxValue.get());
8307     if (!LBMaxVal.isUsable())
8308       return nullptr;
8309     // OuterVar = Max, LBVal
8310     LBMaxVal =
8311         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal);
8312     if (!LBMaxVal.isUsable())
8313       return nullptr;
8314     // (OuterVar = Max, LBVal)
8315     LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get());
8316     if (!LBMaxVal.isUsable())
8317       return nullptr;
8318 
8319     Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get();
8320     Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get();
8321     if (!LBMin || !LBMax)
8322       return nullptr;
8323     // LB(MinVal) < LB(MaxVal)
8324     ExprResult MinLessMaxRes =
8325         SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
8326     if (!MinLessMaxRes.isUsable())
8327       return nullptr;
8328     Expr *MinLessMax =
8329         tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get();
8330     if (!MinLessMax)
8331       return nullptr;
8332     if (TestIsLessOp.getValue()) {
8333       // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
8334       // LB(MaxVal))
8335       ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8336                                                     MinLessMax, LBMin, LBMax);
8337       if (!MinLB.isUsable())
8338         return nullptr;
8339       LBVal = MinLB.get();
8340     } else {
8341       // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
8342       // LB(MaxVal))
8343       ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8344                                                     MinLessMax, LBMax, LBMin);
8345       if (!MaxLB.isUsable())
8346         return nullptr;
8347       LBVal = MaxLB.get();
8348     }
8349   }
8350   // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
8351   // min(UB(MinVal), UB(MaxVal))
8352   if (CondDependOnLC) {
8353     const LoopIterationSpace &IS = ResultIterSpaces[*CondDependOnLC - 1];
8354     if (!IS.MinValue || !IS.MaxValue)
8355       return nullptr;
8356     // OuterVar = Min
8357     ExprResult MinValue =
8358         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8359     if (!MinValue.isUsable())
8360       return nullptr;
8361 
8362     ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8363                                              IS.CounterVar, MinValue.get());
8364     if (!UBMinVal.isUsable())
8365       return nullptr;
8366     // OuterVar = Min, UBVal
8367     UBMinVal =
8368         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal);
8369     if (!UBMinVal.isUsable())
8370       return nullptr;
8371     // (OuterVar = Min, UBVal)
8372     UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get());
8373     if (!UBMinVal.isUsable())
8374       return nullptr;
8375 
8376     // OuterVar = Max
8377     ExprResult MaxValue =
8378         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8379     if (!MaxValue.isUsable())
8380       return nullptr;
8381 
8382     ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8383                                              IS.CounterVar, MaxValue.get());
8384     if (!UBMaxVal.isUsable())
8385       return nullptr;
8386     // OuterVar = Max, UBVal
8387     UBMaxVal =
8388         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal);
8389     if (!UBMaxVal.isUsable())
8390       return nullptr;
8391     // (OuterVar = Max, UBVal)
8392     UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get());
8393     if (!UBMaxVal.isUsable())
8394       return nullptr;
8395 
8396     Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get();
8397     Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get();
8398     if (!UBMin || !UBMax)
8399       return nullptr;
8400     // UB(MinVal) > UB(MaxVal)
8401     ExprResult MinGreaterMaxRes =
8402         SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
8403     if (!MinGreaterMaxRes.isUsable())
8404       return nullptr;
8405     Expr *MinGreaterMax =
8406         tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get();
8407     if (!MinGreaterMax)
8408       return nullptr;
8409     if (TestIsLessOp.getValue()) {
8410       // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
8411       // UB(MaxVal))
8412       ExprResult MaxUB = SemaRef.ActOnConditionalOp(
8413           DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
8414       if (!MaxUB.isUsable())
8415         return nullptr;
8416       UBVal = MaxUB.get();
8417     } else {
8418       // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
8419       // UB(MaxVal))
8420       ExprResult MinUB = SemaRef.ActOnConditionalOp(
8421           DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
8422       if (!MinUB.isUsable())
8423         return nullptr;
8424       UBVal = MinUB.get();
8425     }
8426   }
8427   Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal;
8428   Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal;
8429   Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
8430   Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
8431   if (!Upper || !Lower)
8432     return nullptr;
8433 
8434   ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8435                                       Step, VarType, TestIsStrictOp,
8436                                       /*RoundToStep=*/true, Captures);
8437   if (!Diff.isUsable())
8438     return nullptr;
8439 
8440   // OpenMP runtime requires 32-bit or 64-bit loop variables.
8441   QualType Type = Diff.get()->getType();
8442   ASTContext &C = SemaRef.Context;
8443   bool UseVarType = VarType->hasIntegerRepresentation() &&
8444                     C.getTypeSize(Type) > C.getTypeSize(VarType);
8445   if (!Type->isIntegerType() || UseVarType) {
8446     unsigned NewSize =
8447         UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
8448     bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
8449                                : Type->hasSignedIntegerRepresentation();
8450     Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
8451     if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
8452       Diff = SemaRef.PerformImplicitConversion(
8453           Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
8454       if (!Diff.isUsable())
8455         return nullptr;
8456     }
8457   }
8458   if (LimitedType) {
8459     unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
8460     if (NewSize != C.getTypeSize(Type)) {
8461       if (NewSize < C.getTypeSize(Type)) {
8462         assert(NewSize == 64 && "incorrect loop var size");
8463         SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
8464             << InitSrcRange << ConditionSrcRange;
8465       }
8466       QualType NewType = C.getIntTypeForBitwidth(
8467           NewSize, Type->hasSignedIntegerRepresentation() ||
8468                        C.getTypeSize(Type) < NewSize);
8469       if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
8470         Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
8471                                                  Sema::AA_Converting, true);
8472         if (!Diff.isUsable())
8473           return nullptr;
8474       }
8475     }
8476   }
8477 
8478   return Diff.get();
8479 }
8480 
8481 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
8482     Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8483   // Do not build for iterators, they cannot be used in non-rectangular loop
8484   // nests.
8485   if (LCDecl->getType()->isRecordType())
8486     return std::make_pair(nullptr, nullptr);
8487   // If we subtract, the min is in the condition, otherwise the min is in the
8488   // init value.
8489   Expr *MinExpr = nullptr;
8490   Expr *MaxExpr = nullptr;
8491   Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB;
8492   Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB;
8493   bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue()
8494                                            : CondDependOnLC.hasValue();
8495   bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue()
8496                                            : InitDependOnLC.hasValue();
8497   Expr *Lower =
8498       LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
8499   Expr *Upper =
8500       UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
8501   if (!Upper || !Lower)
8502     return std::make_pair(nullptr, nullptr);
8503 
8504   if (TestIsLessOp.getValue())
8505     MinExpr = Lower;
8506   else
8507     MaxExpr = Upper;
8508 
8509   // Build minimum/maximum value based on number of iterations.
8510   QualType VarType = LCDecl->getType().getNonReferenceType();
8511 
8512   ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8513                                       Step, VarType, TestIsStrictOp,
8514                                       /*RoundToStep=*/false, Captures);
8515   if (!Diff.isUsable())
8516     return std::make_pair(nullptr, nullptr);
8517 
8518   // ((Upper - Lower [- 1]) / Step) * Step
8519   // Parentheses (for dumping/debugging purposes only).
8520   Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8521   if (!Diff.isUsable())
8522     return std::make_pair(nullptr, nullptr);
8523 
8524   ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
8525   if (!NewStep.isUsable())
8526     return std::make_pair(nullptr, nullptr);
8527   Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get());
8528   if (!Diff.isUsable())
8529     return std::make_pair(nullptr, nullptr);
8530 
8531   // Parentheses (for dumping/debugging purposes only).
8532   Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8533   if (!Diff.isUsable())
8534     return std::make_pair(nullptr, nullptr);
8535 
8536   // Convert to the ptrdiff_t, if original type is pointer.
8537   if (VarType->isAnyPointerType() &&
8538       !SemaRef.Context.hasSameType(
8539           Diff.get()->getType(),
8540           SemaRef.Context.getUnsignedPointerDiffType())) {
8541     Diff = SemaRef.PerformImplicitConversion(
8542         Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(),
8543         Sema::AA_Converting, /*AllowExplicit=*/true);
8544   }
8545   if (!Diff.isUsable())
8546     return std::make_pair(nullptr, nullptr);
8547 
8548   if (TestIsLessOp.getValue()) {
8549     // MinExpr = Lower;
8550     // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
8551     Diff = SemaRef.BuildBinOp(
8552         S, DefaultLoc, BO_Add,
8553         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(),
8554         Diff.get());
8555     if (!Diff.isUsable())
8556       return std::make_pair(nullptr, nullptr);
8557   } else {
8558     // MaxExpr = Upper;
8559     // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
8560     Diff = SemaRef.BuildBinOp(
8561         S, DefaultLoc, BO_Sub,
8562         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
8563         Diff.get());
8564     if (!Diff.isUsable())
8565       return std::make_pair(nullptr, nullptr);
8566   }
8567 
8568   // Convert to the original type.
8569   if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType))
8570     Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType,
8571                                              Sema::AA_Converting,
8572                                              /*AllowExplicit=*/true);
8573   if (!Diff.isUsable())
8574     return std::make_pair(nullptr, nullptr);
8575 
8576   Sema::TentativeAnalysisScope Trap(SemaRef);
8577   Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false);
8578   if (!Diff.isUsable())
8579     return std::make_pair(nullptr, nullptr);
8580 
8581   if (TestIsLessOp.getValue())
8582     MaxExpr = Diff.get();
8583   else
8584     MinExpr = Diff.get();
8585 
8586   return std::make_pair(MinExpr, MaxExpr);
8587 }
8588 
8589 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const {
8590   if (InitDependOnLC || CondDependOnLC)
8591     return Condition;
8592   return nullptr;
8593 }
8594 
8595 Expr *OpenMPIterationSpaceChecker::buildPreCond(
8596     Scope *S, Expr *Cond,
8597     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8598   // Do not build a precondition when the condition/initialization is dependent
8599   // to prevent pessimistic early loop exit.
8600   // TODO: this can be improved by calculating min/max values but not sure that
8601   // it will be very effective.
8602   if (CondDependOnLC || InitDependOnLC)
8603     return SemaRef
8604         .PerformImplicitConversion(
8605             SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(),
8606             SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
8607             /*AllowExplicit=*/true)
8608         .get();
8609 
8610   // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
8611   Sema::TentativeAnalysisScope Trap(SemaRef);
8612 
8613   ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
8614   ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
8615   if (!NewLB.isUsable() || !NewUB.isUsable())
8616     return nullptr;
8617 
8618   ExprResult CondExpr = SemaRef.BuildBinOp(
8619       S, DefaultLoc,
8620       TestIsLessOp.getValue() ? (TestIsStrictOp ? BO_LT : BO_LE)
8621                               : (TestIsStrictOp ? BO_GT : BO_GE),
8622       NewLB.get(), NewUB.get());
8623   if (CondExpr.isUsable()) {
8624     if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
8625                                                 SemaRef.Context.BoolTy))
8626       CondExpr = SemaRef.PerformImplicitConversion(
8627           CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
8628           /*AllowExplicit=*/true);
8629   }
8630 
8631   // Otherwise use original loop condition and evaluate it in runtime.
8632   return CondExpr.isUsable() ? CondExpr.get() : Cond;
8633 }
8634 
8635 /// Build reference expression to the counter be used for codegen.
8636 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
8637     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8638     DSAStackTy &DSA) const {
8639   auto *VD = dyn_cast<VarDecl>(LCDecl);
8640   if (!VD) {
8641     VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
8642     DeclRefExpr *Ref = buildDeclRefExpr(
8643         SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
8644     const DSAStackTy::DSAVarData Data =
8645         DSA.getTopDSA(LCDecl, /*FromParent=*/false);
8646     // If the loop control decl is explicitly marked as private, do not mark it
8647     // as captured again.
8648     if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
8649       Captures.insert(std::make_pair(LCRef, Ref));
8650     return Ref;
8651   }
8652   return cast<DeclRefExpr>(LCRef);
8653 }
8654 
8655 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
8656   if (LCDecl && !LCDecl->isInvalidDecl()) {
8657     QualType Type = LCDecl->getType().getNonReferenceType();
8658     VarDecl *PrivateVar = buildVarDecl(
8659         SemaRef, DefaultLoc, Type, LCDecl->getName(),
8660         LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
8661         isa<VarDecl>(LCDecl)
8662             ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
8663             : nullptr);
8664     if (PrivateVar->isInvalidDecl())
8665       return nullptr;
8666     return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
8667   }
8668   return nullptr;
8669 }
8670 
8671 /// Build initialization of the counter to be used for codegen.
8672 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
8673 
8674 /// Build step of the counter be used for codegen.
8675 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
8676 
8677 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
8678     Scope *S, Expr *Counter,
8679     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
8680     Expr *Inc, OverloadedOperatorKind OOK) {
8681   Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
8682   if (!Cnt)
8683     return nullptr;
8684   if (Inc) {
8685     assert((OOK == OO_Plus || OOK == OO_Minus) &&
8686            "Expected only + or - operations for depend clauses.");
8687     BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
8688     Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
8689     if (!Cnt)
8690       return nullptr;
8691   }
8692   QualType VarType = LCDecl->getType().getNonReferenceType();
8693   if (!VarType->isIntegerType() && !VarType->isPointerType() &&
8694       !SemaRef.getLangOpts().CPlusPlus)
8695     return nullptr;
8696   // Upper - Lower
8697   Expr *Upper = TestIsLessOp.getValue()
8698                     ? Cnt
8699                     : tryBuildCapture(SemaRef, LB, Captures).get();
8700   Expr *Lower = TestIsLessOp.getValue()
8701                     ? tryBuildCapture(SemaRef, LB, Captures).get()
8702                     : Cnt;
8703   if (!Upper || !Lower)
8704     return nullptr;
8705 
8706   ExprResult Diff = calculateNumIters(
8707       SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
8708       /*TestIsStrictOp=*/false, /*RoundToStep=*/false, Captures);
8709   if (!Diff.isUsable())
8710     return nullptr;
8711 
8712   return Diff.get();
8713 }
8714 } // namespace
8715 
8716 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
8717   assert(getLangOpts().OpenMP && "OpenMP is not active.");
8718   assert(Init && "Expected loop in canonical form.");
8719   unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
8720   if (AssociatedLoops > 0 &&
8721       isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
8722     DSAStack->loopStart();
8723     OpenMPIterationSpaceChecker ISC(*this, /*SupportsNonRectangular=*/true,
8724                                     *DSAStack, ForLoc);
8725     if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
8726       if (ValueDecl *D = ISC.getLoopDecl()) {
8727         auto *VD = dyn_cast<VarDecl>(D);
8728         DeclRefExpr *PrivateRef = nullptr;
8729         if (!VD) {
8730           if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
8731             VD = Private;
8732           } else {
8733             PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
8734                                       /*WithInit=*/false);
8735             VD = cast<VarDecl>(PrivateRef->getDecl());
8736           }
8737         }
8738         DSAStack->addLoopControlVariable(D, VD);
8739         const Decl *LD = DSAStack->getPossiblyLoopCunter();
8740         if (LD != D->getCanonicalDecl()) {
8741           DSAStack->resetPossibleLoopCounter();
8742           if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
8743             MarkDeclarationsReferencedInExpr(
8744                 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
8745                                  Var->getType().getNonLValueExprType(Context),
8746                                  ForLoc, /*RefersToCapture=*/true));
8747         }
8748         OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
8749         // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
8750         // Referenced in a Construct, C/C++]. The loop iteration variable in the
8751         // associated for-loop of a simd construct with just one associated
8752         // for-loop may be listed in a linear clause with a constant-linear-step
8753         // that is the increment of the associated for-loop. The loop iteration
8754         // variable(s) in the associated for-loop(s) of a for or parallel for
8755         // construct may be listed in a private or lastprivate clause.
8756         DSAStackTy::DSAVarData DVar =
8757             DSAStack->getTopDSA(D, /*FromParent=*/false);
8758         // If LoopVarRefExpr is nullptr it means the corresponding loop variable
8759         // is declared in the loop and it is predetermined as a private.
8760         Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
8761         OpenMPClauseKind PredeterminedCKind =
8762             isOpenMPSimdDirective(DKind)
8763                 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
8764                 : OMPC_private;
8765         if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
8766               DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
8767               (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
8768                                          DVar.CKind != OMPC_private))) ||
8769              ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
8770                DKind == OMPD_master_taskloop ||
8771                DKind == OMPD_parallel_master_taskloop ||
8772                isOpenMPDistributeDirective(DKind)) &&
8773               !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
8774               DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
8775             (DVar.CKind != OMPC_private || DVar.RefExpr)) {
8776           Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
8777               << getOpenMPClauseName(DVar.CKind)
8778               << getOpenMPDirectiveName(DKind)
8779               << getOpenMPClauseName(PredeterminedCKind);
8780           if (DVar.RefExpr == nullptr)
8781             DVar.CKind = PredeterminedCKind;
8782           reportOriginalDsa(*this, DSAStack, D, DVar,
8783                             /*IsLoopIterVar=*/true);
8784         } else if (LoopDeclRefExpr) {
8785           // Make the loop iteration variable private (for worksharing
8786           // constructs), linear (for simd directives with the only one
8787           // associated loop) or lastprivate (for simd directives with several
8788           // collapsed or ordered loops).
8789           if (DVar.CKind == OMPC_unknown)
8790             DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
8791                              PrivateRef);
8792         }
8793       }
8794     }
8795     DSAStack->setAssociatedLoops(AssociatedLoops - 1);
8796   }
8797 }
8798 
8799 /// Called on a for stmt to check and extract its iteration space
8800 /// for further processing (such as collapsing).
8801 static bool checkOpenMPIterationSpace(
8802     OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
8803     unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
8804     unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
8805     Expr *OrderedLoopCountExpr,
8806     Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
8807     llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,
8808     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8809   bool SupportsNonRectangular = !isOpenMPLoopTransformationDirective(DKind);
8810   // OpenMP [2.9.1, Canonical Loop Form]
8811   //   for (init-expr; test-expr; incr-expr) structured-block
8812   //   for (range-decl: range-expr) structured-block
8813   if (auto *CanonLoop = dyn_cast_or_null<OMPCanonicalLoop>(S))
8814     S = CanonLoop->getLoopStmt();
8815   auto *For = dyn_cast_or_null<ForStmt>(S);
8816   auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
8817   // Ranged for is supported only in OpenMP 5.0.
8818   if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) {
8819     SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
8820         << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
8821         << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
8822         << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
8823     if (TotalNestedLoopCount > 1) {
8824       if (CollapseLoopCountExpr && OrderedLoopCountExpr)
8825         SemaRef.Diag(DSA.getConstructLoc(),
8826                      diag::note_omp_collapse_ordered_expr)
8827             << 2 << CollapseLoopCountExpr->getSourceRange()
8828             << OrderedLoopCountExpr->getSourceRange();
8829       else if (CollapseLoopCountExpr)
8830         SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
8831                      diag::note_omp_collapse_ordered_expr)
8832             << 0 << CollapseLoopCountExpr->getSourceRange();
8833       else
8834         SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
8835                      diag::note_omp_collapse_ordered_expr)
8836             << 1 << OrderedLoopCountExpr->getSourceRange();
8837     }
8838     return true;
8839   }
8840   assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&
8841          "No loop body.");
8842   // Postpone analysis in dependent contexts for ranged for loops.
8843   if (CXXFor && SemaRef.CurContext->isDependentContext())
8844     return false;
8845 
8846   OpenMPIterationSpaceChecker ISC(SemaRef, SupportsNonRectangular, DSA,
8847                                   For ? For->getForLoc() : CXXFor->getForLoc());
8848 
8849   // Check init.
8850   Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt();
8851   if (ISC.checkAndSetInit(Init))
8852     return true;
8853 
8854   bool HasErrors = false;
8855 
8856   // Check loop variable's type.
8857   if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
8858     // OpenMP [2.6, Canonical Loop Form]
8859     // Var is one of the following:
8860     //   A variable of signed or unsigned integer type.
8861     //   For C++, a variable of a random access iterator type.
8862     //   For C, a variable of a pointer type.
8863     QualType VarType = LCDecl->getType().getNonReferenceType();
8864     if (!VarType->isDependentType() && !VarType->isIntegerType() &&
8865         !VarType->isPointerType() &&
8866         !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
8867       SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
8868           << SemaRef.getLangOpts().CPlusPlus;
8869       HasErrors = true;
8870     }
8871 
8872     // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
8873     // a Construct
8874     // The loop iteration variable(s) in the associated for-loop(s) of a for or
8875     // parallel for construct is (are) private.
8876     // The loop iteration variable in the associated for-loop of a simd
8877     // construct with just one associated for-loop is linear with a
8878     // constant-linear-step that is the increment of the associated for-loop.
8879     // Exclude loop var from the list of variables with implicitly defined data
8880     // sharing attributes.
8881     VarsWithImplicitDSA.erase(LCDecl);
8882 
8883     assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
8884 
8885     // Check test-expr.
8886     HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
8887 
8888     // Check incr-expr.
8889     HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
8890   }
8891 
8892   if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
8893     return HasErrors;
8894 
8895   // Build the loop's iteration space representation.
8896   ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
8897       DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
8898   ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
8899       ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
8900                              (isOpenMPWorksharingDirective(DKind) ||
8901                               isOpenMPGenericLoopDirective(DKind) ||
8902                               isOpenMPTaskLoopDirective(DKind) ||
8903                               isOpenMPDistributeDirective(DKind) ||
8904                               isOpenMPLoopTransformationDirective(DKind)),
8905                              Captures);
8906   ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
8907       ISC.buildCounterVar(Captures, DSA);
8908   ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
8909       ISC.buildPrivateCounterVar();
8910   ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
8911   ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
8912   ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
8913   ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
8914       ISC.getConditionSrcRange();
8915   ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
8916       ISC.getIncrementSrcRange();
8917   ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
8918   ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
8919       ISC.isStrictTestOp();
8920   std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
8921            ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
8922       ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
8923   ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
8924       ISC.buildFinalCondition(DSA.getCurScope());
8925   ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
8926       ISC.doesInitDependOnLC();
8927   ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
8928       ISC.doesCondDependOnLC();
8929   ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
8930       ISC.getLoopDependentIdx();
8931 
8932   HasErrors |=
8933       (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr ||
8934        ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr ||
8935        ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr ||
8936        ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr ||
8937        ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr ||
8938        ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr);
8939   if (!HasErrors && DSA.isOrderedRegion()) {
8940     if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
8941       if (CurrentNestedLoopCount <
8942           DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
8943         DSA.getOrderedRegionParam().second->setLoopNumIterations(
8944             CurrentNestedLoopCount,
8945             ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
8946         DSA.getOrderedRegionParam().second->setLoopCounter(
8947             CurrentNestedLoopCount,
8948             ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
8949       }
8950     }
8951     for (auto &Pair : DSA.getDoacrossDependClauses()) {
8952       if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
8953         // Erroneous case - clause has some problems.
8954         continue;
8955       }
8956       if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
8957           Pair.second.size() <= CurrentNestedLoopCount) {
8958         // Erroneous case - clause has some problems.
8959         Pair.first->setLoopData(CurrentNestedLoopCount, nullptr);
8960         continue;
8961       }
8962       Expr *CntValue;
8963       if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
8964         CntValue = ISC.buildOrderedLoopData(
8965             DSA.getCurScope(),
8966             ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
8967             Pair.first->getDependencyLoc());
8968       else
8969         CntValue = ISC.buildOrderedLoopData(
8970             DSA.getCurScope(),
8971             ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
8972             Pair.first->getDependencyLoc(),
8973             Pair.second[CurrentNestedLoopCount].first,
8974             Pair.second[CurrentNestedLoopCount].second);
8975       Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
8976     }
8977   }
8978 
8979   return HasErrors;
8980 }
8981 
8982 /// Build 'VarRef = Start.
8983 static ExprResult
8984 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
8985                  ExprResult Start, bool IsNonRectangularLB,
8986                  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8987   // Build 'VarRef = Start.
8988   ExprResult NewStart = IsNonRectangularLB
8989                             ? Start.get()
8990                             : tryBuildCapture(SemaRef, Start.get(), Captures);
8991   if (!NewStart.isUsable())
8992     return ExprError();
8993   if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
8994                                    VarRef.get()->getType())) {
8995     NewStart = SemaRef.PerformImplicitConversion(
8996         NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
8997         /*AllowExplicit=*/true);
8998     if (!NewStart.isUsable())
8999       return ExprError();
9000   }
9001 
9002   ExprResult Init =
9003       SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
9004   return Init;
9005 }
9006 
9007 /// Build 'VarRef = Start + Iter * Step'.
9008 static ExprResult buildCounterUpdate(
9009     Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
9010     ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
9011     bool IsNonRectangularLB,
9012     llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
9013   // Add parentheses (for debugging purposes only).
9014   Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
9015   if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
9016       !Step.isUsable())
9017     return ExprError();
9018 
9019   ExprResult NewStep = Step;
9020   if (Captures)
9021     NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
9022   if (NewStep.isInvalid())
9023     return ExprError();
9024   ExprResult Update =
9025       SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
9026   if (!Update.isUsable())
9027     return ExprError();
9028 
9029   // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
9030   // 'VarRef = Start (+|-) Iter * Step'.
9031   if (!Start.isUsable())
9032     return ExprError();
9033   ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get());
9034   if (!NewStart.isUsable())
9035     return ExprError();
9036   if (Captures && !IsNonRectangularLB)
9037     NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
9038   if (NewStart.isInvalid())
9039     return ExprError();
9040 
9041   // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
9042   ExprResult SavedUpdate = Update;
9043   ExprResult UpdateVal;
9044   if (VarRef.get()->getType()->isOverloadableType() ||
9045       NewStart.get()->getType()->isOverloadableType() ||
9046       Update.get()->getType()->isOverloadableType()) {
9047     Sema::TentativeAnalysisScope Trap(SemaRef);
9048 
9049     Update =
9050         SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
9051     if (Update.isUsable()) {
9052       UpdateVal =
9053           SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
9054                              VarRef.get(), SavedUpdate.get());
9055       if (UpdateVal.isUsable()) {
9056         Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
9057                                             UpdateVal.get());
9058       }
9059     }
9060   }
9061 
9062   // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
9063   if (!Update.isUsable() || !UpdateVal.isUsable()) {
9064     Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
9065                                 NewStart.get(), SavedUpdate.get());
9066     if (!Update.isUsable())
9067       return ExprError();
9068 
9069     if (!SemaRef.Context.hasSameType(Update.get()->getType(),
9070                                      VarRef.get()->getType())) {
9071       Update = SemaRef.PerformImplicitConversion(
9072           Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
9073       if (!Update.isUsable())
9074         return ExprError();
9075     }
9076 
9077     Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
9078   }
9079   return Update;
9080 }
9081 
9082 /// Convert integer expression \a E to make it have at least \a Bits
9083 /// bits.
9084 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
9085   if (E == nullptr)
9086     return ExprError();
9087   ASTContext &C = SemaRef.Context;
9088   QualType OldType = E->getType();
9089   unsigned HasBits = C.getTypeSize(OldType);
9090   if (HasBits >= Bits)
9091     return ExprResult(E);
9092   // OK to convert to signed, because new type has more bits than old.
9093   QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
9094   return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
9095                                            true);
9096 }
9097 
9098 /// Check if the given expression \a E is a constant integer that fits
9099 /// into \a Bits bits.
9100 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
9101   if (E == nullptr)
9102     return false;
9103   if (Optional<llvm::APSInt> Result =
9104           E->getIntegerConstantExpr(SemaRef.Context))
9105     return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits);
9106   return false;
9107 }
9108 
9109 /// Build preinits statement for the given declarations.
9110 static Stmt *buildPreInits(ASTContext &Context,
9111                            MutableArrayRef<Decl *> PreInits) {
9112   if (!PreInits.empty()) {
9113     return new (Context) DeclStmt(
9114         DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
9115         SourceLocation(), SourceLocation());
9116   }
9117   return nullptr;
9118 }
9119 
9120 /// Build preinits statement for the given declarations.
9121 static Stmt *
9122 buildPreInits(ASTContext &Context,
9123               const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
9124   if (!Captures.empty()) {
9125     SmallVector<Decl *, 16> PreInits;
9126     for (const auto &Pair : Captures)
9127       PreInits.push_back(Pair.second->getDecl());
9128     return buildPreInits(Context, PreInits);
9129   }
9130   return nullptr;
9131 }
9132 
9133 /// Build postupdate expression for the given list of postupdates expressions.
9134 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
9135   Expr *PostUpdate = nullptr;
9136   if (!PostUpdates.empty()) {
9137     for (Expr *E : PostUpdates) {
9138       Expr *ConvE = S.BuildCStyleCastExpr(
9139                          E->getExprLoc(),
9140                          S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
9141                          E->getExprLoc(), E)
9142                         .get();
9143       PostUpdate = PostUpdate
9144                        ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
9145                                               PostUpdate, ConvE)
9146                              .get()
9147                        : ConvE;
9148     }
9149   }
9150   return PostUpdate;
9151 }
9152 
9153 /// Called on a for stmt to check itself and nested loops (if any).
9154 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
9155 /// number of collapsed loops otherwise.
9156 static unsigned
9157 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
9158                 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
9159                 DSAStackTy &DSA,
9160                 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
9161                 OMPLoopBasedDirective::HelperExprs &Built) {
9162   unsigned NestedLoopCount = 1;
9163   bool SupportsNonPerfectlyNested = (SemaRef.LangOpts.OpenMP >= 50) &&
9164                                     !isOpenMPLoopTransformationDirective(DKind);
9165 
9166   if (CollapseLoopCountExpr) {
9167     // Found 'collapse' clause - calculate collapse number.
9168     Expr::EvalResult Result;
9169     if (!CollapseLoopCountExpr->isValueDependent() &&
9170         CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
9171       NestedLoopCount = Result.Val.getInt().getLimitedValue();
9172     } else {
9173       Built.clear(/*Size=*/1);
9174       return 1;
9175     }
9176   }
9177   unsigned OrderedLoopCount = 1;
9178   if (OrderedLoopCountExpr) {
9179     // Found 'ordered' clause - calculate collapse number.
9180     Expr::EvalResult EVResult;
9181     if (!OrderedLoopCountExpr->isValueDependent() &&
9182         OrderedLoopCountExpr->EvaluateAsInt(EVResult,
9183                                             SemaRef.getASTContext())) {
9184       llvm::APSInt Result = EVResult.Val.getInt();
9185       if (Result.getLimitedValue() < NestedLoopCount) {
9186         SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
9187                      diag::err_omp_wrong_ordered_loop_count)
9188             << OrderedLoopCountExpr->getSourceRange();
9189         SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
9190                      diag::note_collapse_loop_count)
9191             << CollapseLoopCountExpr->getSourceRange();
9192       }
9193       OrderedLoopCount = Result.getLimitedValue();
9194     } else {
9195       Built.clear(/*Size=*/1);
9196       return 1;
9197     }
9198   }
9199   // This is helper routine for loop directives (e.g., 'for', 'simd',
9200   // 'for simd', etc.).
9201   llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
9202   unsigned NumLoops = std::max(OrderedLoopCount, NestedLoopCount);
9203   SmallVector<LoopIterationSpace, 4> IterSpaces(NumLoops);
9204   if (!OMPLoopBasedDirective::doForAllLoops(
9205           AStmt->IgnoreContainers(!isOpenMPLoopTransformationDirective(DKind)),
9206           SupportsNonPerfectlyNested, NumLoops,
9207           [DKind, &SemaRef, &DSA, NumLoops, NestedLoopCount,
9208            CollapseLoopCountExpr, OrderedLoopCountExpr, &VarsWithImplicitDSA,
9209            &IterSpaces, &Captures](unsigned Cnt, Stmt *CurStmt) {
9210             if (checkOpenMPIterationSpace(
9211                     DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
9212                     NumLoops, CollapseLoopCountExpr, OrderedLoopCountExpr,
9213                     VarsWithImplicitDSA, IterSpaces, Captures))
9214               return true;
9215             if (Cnt > 0 && Cnt >= NestedLoopCount &&
9216                 IterSpaces[Cnt].CounterVar) {
9217               // Handle initialization of captured loop iterator variables.
9218               auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
9219               if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
9220                 Captures[DRE] = DRE;
9221               }
9222             }
9223             return false;
9224           },
9225           [&SemaRef, &Captures](OMPLoopTransformationDirective *Transform) {
9226             Stmt *DependentPreInits = Transform->getPreInits();
9227             if (!DependentPreInits)
9228               return;
9229             for (Decl *C : cast<DeclStmt>(DependentPreInits)->getDeclGroup()) {
9230               auto *D = cast<VarDecl>(C);
9231               DeclRefExpr *Ref = buildDeclRefExpr(SemaRef, D, D->getType(),
9232                                                   Transform->getBeginLoc());
9233               Captures[Ref] = Ref;
9234             }
9235           }))
9236     return 0;
9237 
9238   Built.clear(/* size */ NestedLoopCount);
9239 
9240   if (SemaRef.CurContext->isDependentContext())
9241     return NestedLoopCount;
9242 
9243   // An example of what is generated for the following code:
9244   //
9245   //   #pragma omp simd collapse(2) ordered(2)
9246   //   for (i = 0; i < NI; ++i)
9247   //     for (k = 0; k < NK; ++k)
9248   //       for (j = J0; j < NJ; j+=2) {
9249   //         <loop body>
9250   //       }
9251   //
9252   // We generate the code below.
9253   // Note: the loop body may be outlined in CodeGen.
9254   // Note: some counters may be C++ classes, operator- is used to find number of
9255   // iterations and operator+= to calculate counter value.
9256   // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
9257   // or i64 is currently supported).
9258   //
9259   //   #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
9260   //   for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
9261   //     .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
9262   //     .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
9263   //     // similar updates for vars in clauses (e.g. 'linear')
9264   //     <loop body (using local i and j)>
9265   //   }
9266   //   i = NI; // assign final values of counters
9267   //   j = NJ;
9268   //
9269 
9270   // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
9271   // the iteration counts of the collapsed for loops.
9272   // Precondition tests if there is at least one iteration (all conditions are
9273   // true).
9274   auto PreCond = ExprResult(IterSpaces[0].PreCond);
9275   Expr *N0 = IterSpaces[0].NumIterations;
9276   ExprResult LastIteration32 =
9277       widenIterationCount(/*Bits=*/32,
9278                           SemaRef
9279                               .PerformImplicitConversion(
9280                                   N0->IgnoreImpCasts(), N0->getType(),
9281                                   Sema::AA_Converting, /*AllowExplicit=*/true)
9282                               .get(),
9283                           SemaRef);
9284   ExprResult LastIteration64 = widenIterationCount(
9285       /*Bits=*/64,
9286       SemaRef
9287           .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
9288                                      Sema::AA_Converting,
9289                                      /*AllowExplicit=*/true)
9290           .get(),
9291       SemaRef);
9292 
9293   if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
9294     return NestedLoopCount;
9295 
9296   ASTContext &C = SemaRef.Context;
9297   bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
9298 
9299   Scope *CurScope = DSA.getCurScope();
9300   for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
9301     if (PreCond.isUsable()) {
9302       PreCond =
9303           SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
9304                              PreCond.get(), IterSpaces[Cnt].PreCond);
9305     }
9306     Expr *N = IterSpaces[Cnt].NumIterations;
9307     SourceLocation Loc = N->getExprLoc();
9308     AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
9309     if (LastIteration32.isUsable())
9310       LastIteration32 = SemaRef.BuildBinOp(
9311           CurScope, Loc, BO_Mul, LastIteration32.get(),
9312           SemaRef
9313               .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
9314                                          Sema::AA_Converting,
9315                                          /*AllowExplicit=*/true)
9316               .get());
9317     if (LastIteration64.isUsable())
9318       LastIteration64 = SemaRef.BuildBinOp(
9319           CurScope, Loc, BO_Mul, LastIteration64.get(),
9320           SemaRef
9321               .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
9322                                          Sema::AA_Converting,
9323                                          /*AllowExplicit=*/true)
9324               .get());
9325   }
9326 
9327   // Choose either the 32-bit or 64-bit version.
9328   ExprResult LastIteration = LastIteration64;
9329   if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
9330       (LastIteration32.isUsable() &&
9331        C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
9332        (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
9333         fitsInto(
9334             /*Bits=*/32,
9335             LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
9336             LastIteration64.get(), SemaRef))))
9337     LastIteration = LastIteration32;
9338   QualType VType = LastIteration.get()->getType();
9339   QualType RealVType = VType;
9340   QualType StrideVType = VType;
9341   if (isOpenMPTaskLoopDirective(DKind)) {
9342     VType =
9343         SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
9344     StrideVType =
9345         SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
9346   }
9347 
9348   if (!LastIteration.isUsable())
9349     return 0;
9350 
9351   // Save the number of iterations.
9352   ExprResult NumIterations = LastIteration;
9353   {
9354     LastIteration = SemaRef.BuildBinOp(
9355         CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
9356         LastIteration.get(),
9357         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9358     if (!LastIteration.isUsable())
9359       return 0;
9360   }
9361 
9362   // Calculate the last iteration number beforehand instead of doing this on
9363   // each iteration. Do not do this if the number of iterations may be kfold-ed.
9364   bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context);
9365   ExprResult CalcLastIteration;
9366   if (!IsConstant) {
9367     ExprResult SaveRef =
9368         tryBuildCapture(SemaRef, LastIteration.get(), Captures);
9369     LastIteration = SaveRef;
9370 
9371     // Prepare SaveRef + 1.
9372     NumIterations = SemaRef.BuildBinOp(
9373         CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
9374         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9375     if (!NumIterations.isUsable())
9376       return 0;
9377   }
9378 
9379   SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
9380 
9381   // Build variables passed into runtime, necessary for worksharing directives.
9382   ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
9383   if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
9384       isOpenMPDistributeDirective(DKind) ||
9385       isOpenMPGenericLoopDirective(DKind) ||
9386       isOpenMPLoopTransformationDirective(DKind)) {
9387     // Lower bound variable, initialized with zero.
9388     VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
9389     LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
9390     SemaRef.AddInitializerToDecl(LBDecl,
9391                                  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9392                                  /*DirectInit*/ false);
9393 
9394     // Upper bound variable, initialized with last iteration number.
9395     VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
9396     UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
9397     SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
9398                                  /*DirectInit*/ false);
9399 
9400     // A 32-bit variable-flag where runtime returns 1 for the last iteration.
9401     // This will be used to implement clause 'lastprivate'.
9402     QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
9403     VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
9404     IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
9405     SemaRef.AddInitializerToDecl(ILDecl,
9406                                  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9407                                  /*DirectInit*/ false);
9408 
9409     // Stride variable returned by runtime (we initialize it to 1 by default).
9410     VarDecl *STDecl =
9411         buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
9412     ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
9413     SemaRef.AddInitializerToDecl(STDecl,
9414                                  SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
9415                                  /*DirectInit*/ false);
9416 
9417     // Build expression: UB = min(UB, LastIteration)
9418     // It is necessary for CodeGen of directives with static scheduling.
9419     ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
9420                                                 UB.get(), LastIteration.get());
9421     ExprResult CondOp = SemaRef.ActOnConditionalOp(
9422         LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
9423         LastIteration.get(), UB.get());
9424     EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
9425                              CondOp.get());
9426     EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
9427 
9428     // If we have a combined directive that combines 'distribute', 'for' or
9429     // 'simd' we need to be able to access the bounds of the schedule of the
9430     // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
9431     // by scheduling 'distribute' have to be passed to the schedule of 'for'.
9432     if (isOpenMPLoopBoundSharingDirective(DKind)) {
9433       // Lower bound variable, initialized with zero.
9434       VarDecl *CombLBDecl =
9435           buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
9436       CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
9437       SemaRef.AddInitializerToDecl(
9438           CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9439           /*DirectInit*/ false);
9440 
9441       // Upper bound variable, initialized with last iteration number.
9442       VarDecl *CombUBDecl =
9443           buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
9444       CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
9445       SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
9446                                    /*DirectInit*/ false);
9447 
9448       ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
9449           CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
9450       ExprResult CombCondOp =
9451           SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
9452                                      LastIteration.get(), CombUB.get());
9453       CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
9454                                    CombCondOp.get());
9455       CombEUB =
9456           SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
9457 
9458       const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
9459       // We expect to have at least 2 more parameters than the 'parallel'
9460       // directive does - the lower and upper bounds of the previous schedule.
9461       assert(CD->getNumParams() >= 4 &&
9462              "Unexpected number of parameters in loop combined directive");
9463 
9464       // Set the proper type for the bounds given what we learned from the
9465       // enclosed loops.
9466       ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
9467       ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
9468 
9469       // Previous lower and upper bounds are obtained from the region
9470       // parameters.
9471       PrevLB =
9472           buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
9473       PrevUB =
9474           buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
9475     }
9476   }
9477 
9478   // Build the iteration variable and its initialization before loop.
9479   ExprResult IV;
9480   ExprResult Init, CombInit;
9481   {
9482     VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
9483     IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
9484     Expr *RHS = (isOpenMPWorksharingDirective(DKind) ||
9485                  isOpenMPGenericLoopDirective(DKind) ||
9486                  isOpenMPTaskLoopDirective(DKind) ||
9487                  isOpenMPDistributeDirective(DKind) ||
9488                  isOpenMPLoopTransformationDirective(DKind))
9489                     ? LB.get()
9490                     : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
9491     Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
9492     Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
9493 
9494     if (isOpenMPLoopBoundSharingDirective(DKind)) {
9495       Expr *CombRHS =
9496           (isOpenMPWorksharingDirective(DKind) ||
9497            isOpenMPGenericLoopDirective(DKind) ||
9498            isOpenMPTaskLoopDirective(DKind) ||
9499            isOpenMPDistributeDirective(DKind))
9500               ? CombLB.get()
9501               : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
9502       CombInit =
9503           SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
9504       CombInit =
9505           SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
9506     }
9507   }
9508 
9509   bool UseStrictCompare =
9510       RealVType->hasUnsignedIntegerRepresentation() &&
9511       llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
9512         return LIS.IsStrictCompare;
9513       });
9514   // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
9515   // unsigned IV)) for worksharing loops.
9516   SourceLocation CondLoc = AStmt->getBeginLoc();
9517   Expr *BoundUB = UB.get();
9518   if (UseStrictCompare) {
9519     BoundUB =
9520         SemaRef
9521             .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
9522                         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9523             .get();
9524     BoundUB =
9525         SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
9526   }
9527   ExprResult Cond =
9528       (isOpenMPWorksharingDirective(DKind) ||
9529        isOpenMPGenericLoopDirective(DKind) ||
9530        isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind) ||
9531        isOpenMPLoopTransformationDirective(DKind))
9532           ? SemaRef.BuildBinOp(CurScope, CondLoc,
9533                                UseStrictCompare ? BO_LT : BO_LE, IV.get(),
9534                                BoundUB)
9535           : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
9536                                NumIterations.get());
9537   ExprResult CombDistCond;
9538   if (isOpenMPLoopBoundSharingDirective(DKind)) {
9539     CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
9540                                       NumIterations.get());
9541   }
9542 
9543   ExprResult CombCond;
9544   if (isOpenMPLoopBoundSharingDirective(DKind)) {
9545     Expr *BoundCombUB = CombUB.get();
9546     if (UseStrictCompare) {
9547       BoundCombUB =
9548           SemaRef
9549               .BuildBinOp(
9550                   CurScope, CondLoc, BO_Add, BoundCombUB,
9551                   SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9552               .get();
9553       BoundCombUB =
9554           SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
9555               .get();
9556     }
9557     CombCond =
9558         SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
9559                            IV.get(), BoundCombUB);
9560   }
9561   // Loop increment (IV = IV + 1)
9562   SourceLocation IncLoc = AStmt->getBeginLoc();
9563   ExprResult Inc =
9564       SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
9565                          SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
9566   if (!Inc.isUsable())
9567     return 0;
9568   Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
9569   Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
9570   if (!Inc.isUsable())
9571     return 0;
9572 
9573   // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
9574   // Used for directives with static scheduling.
9575   // In combined construct, add combined version that use CombLB and CombUB
9576   // base variables for the update
9577   ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
9578   if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
9579       isOpenMPGenericLoopDirective(DKind) ||
9580       isOpenMPDistributeDirective(DKind) ||
9581       isOpenMPLoopTransformationDirective(DKind)) {
9582     // LB + ST
9583     NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
9584     if (!NextLB.isUsable())
9585       return 0;
9586     // LB = LB + ST
9587     NextLB =
9588         SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
9589     NextLB =
9590         SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
9591     if (!NextLB.isUsable())
9592       return 0;
9593     // UB + ST
9594     NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
9595     if (!NextUB.isUsable())
9596       return 0;
9597     // UB = UB + ST
9598     NextUB =
9599         SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
9600     NextUB =
9601         SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
9602     if (!NextUB.isUsable())
9603       return 0;
9604     if (isOpenMPLoopBoundSharingDirective(DKind)) {
9605       CombNextLB =
9606           SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
9607       if (!NextLB.isUsable())
9608         return 0;
9609       // LB = LB + ST
9610       CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
9611                                       CombNextLB.get());
9612       CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
9613                                                /*DiscardedValue*/ false);
9614       if (!CombNextLB.isUsable())
9615         return 0;
9616       // UB + ST
9617       CombNextUB =
9618           SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
9619       if (!CombNextUB.isUsable())
9620         return 0;
9621       // UB = UB + ST
9622       CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
9623                                       CombNextUB.get());
9624       CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
9625                                                /*DiscardedValue*/ false);
9626       if (!CombNextUB.isUsable())
9627         return 0;
9628     }
9629   }
9630 
9631   // Create increment expression for distribute loop when combined in a same
9632   // directive with for as IV = IV + ST; ensure upper bound expression based
9633   // on PrevUB instead of NumIterations - used to implement 'for' when found
9634   // in combination with 'distribute', like in 'distribute parallel for'
9635   SourceLocation DistIncLoc = AStmt->getBeginLoc();
9636   ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
9637   if (isOpenMPLoopBoundSharingDirective(DKind)) {
9638     DistCond = SemaRef.BuildBinOp(
9639         CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
9640     assert(DistCond.isUsable() && "distribute cond expr was not built");
9641 
9642     DistInc =
9643         SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
9644     assert(DistInc.isUsable() && "distribute inc expr was not built");
9645     DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
9646                                  DistInc.get());
9647     DistInc =
9648         SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
9649     assert(DistInc.isUsable() && "distribute inc expr was not built");
9650 
9651     // Build expression: UB = min(UB, prevUB) for #for in composite or combined
9652     // construct
9653     ExprResult NewPrevUB = PrevUB;
9654     SourceLocation DistEUBLoc = AStmt->getBeginLoc();
9655     if (!SemaRef.Context.hasSameType(UB.get()->getType(),
9656                                      PrevUB.get()->getType())) {
9657       NewPrevUB = SemaRef.BuildCStyleCastExpr(
9658           DistEUBLoc,
9659           SemaRef.Context.getTrivialTypeSourceInfo(UB.get()->getType()),
9660           DistEUBLoc, NewPrevUB.get());
9661       if (!NewPrevUB.isUsable())
9662         return 0;
9663     }
9664     ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT,
9665                                                 UB.get(), NewPrevUB.get());
9666     ExprResult CondOp = SemaRef.ActOnConditionalOp(
9667         DistEUBLoc, DistEUBLoc, IsUBGreater.get(), NewPrevUB.get(), UB.get());
9668     PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
9669                                  CondOp.get());
9670     PrevEUB =
9671         SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
9672 
9673     // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
9674     // parallel for is in combination with a distribute directive with
9675     // schedule(static, 1)
9676     Expr *BoundPrevUB = PrevUB.get();
9677     if (UseStrictCompare) {
9678       BoundPrevUB =
9679           SemaRef
9680               .BuildBinOp(
9681                   CurScope, CondLoc, BO_Add, BoundPrevUB,
9682                   SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9683               .get();
9684       BoundPrevUB =
9685           SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
9686               .get();
9687     }
9688     ParForInDistCond =
9689         SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
9690                            IV.get(), BoundPrevUB);
9691   }
9692 
9693   // Build updates and final values of the loop counters.
9694   bool HasErrors = false;
9695   Built.Counters.resize(NestedLoopCount);
9696   Built.Inits.resize(NestedLoopCount);
9697   Built.Updates.resize(NestedLoopCount);
9698   Built.Finals.resize(NestedLoopCount);
9699   Built.DependentCounters.resize(NestedLoopCount);
9700   Built.DependentInits.resize(NestedLoopCount);
9701   Built.FinalsConditions.resize(NestedLoopCount);
9702   {
9703     // We implement the following algorithm for obtaining the
9704     // original loop iteration variable values based on the
9705     // value of the collapsed loop iteration variable IV.
9706     //
9707     // Let n+1 be the number of collapsed loops in the nest.
9708     // Iteration variables (I0, I1, .... In)
9709     // Iteration counts (N0, N1, ... Nn)
9710     //
9711     // Acc = IV;
9712     //
9713     // To compute Ik for loop k, 0 <= k <= n, generate:
9714     //    Prod = N(k+1) * N(k+2) * ... * Nn;
9715     //    Ik = Acc / Prod;
9716     //    Acc -= Ik * Prod;
9717     //
9718     ExprResult Acc = IV;
9719     for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
9720       LoopIterationSpace &IS = IterSpaces[Cnt];
9721       SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
9722       ExprResult Iter;
9723 
9724       // Compute prod
9725       ExprResult Prod = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
9726       for (unsigned int K = Cnt + 1; K < NestedLoopCount; ++K)
9727         Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
9728                                   IterSpaces[K].NumIterations);
9729 
9730       // Iter = Acc / Prod
9731       // If there is at least one more inner loop to avoid
9732       // multiplication by 1.
9733       if (Cnt + 1 < NestedLoopCount)
9734         Iter =
9735             SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, Acc.get(), Prod.get());
9736       else
9737         Iter = Acc;
9738       if (!Iter.isUsable()) {
9739         HasErrors = true;
9740         break;
9741       }
9742 
9743       // Update Acc:
9744       // Acc -= Iter * Prod
9745       // Check if there is at least one more inner loop to avoid
9746       // multiplication by 1.
9747       if (Cnt + 1 < NestedLoopCount)
9748         Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Iter.get(),
9749                                   Prod.get());
9750       else
9751         Prod = Iter;
9752       Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, Acc.get(), Prod.get());
9753 
9754       // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
9755       auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
9756       DeclRefExpr *CounterVar = buildDeclRefExpr(
9757           SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
9758           /*RefersToCapture=*/true);
9759       ExprResult Init =
9760           buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
9761                            IS.CounterInit, IS.IsNonRectangularLB, Captures);
9762       if (!Init.isUsable()) {
9763         HasErrors = true;
9764         break;
9765       }
9766       ExprResult Update = buildCounterUpdate(
9767           SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
9768           IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
9769       if (!Update.isUsable()) {
9770         HasErrors = true;
9771         break;
9772       }
9773 
9774       // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
9775       ExprResult Final =
9776           buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
9777                              IS.CounterInit, IS.NumIterations, IS.CounterStep,
9778                              IS.Subtract, IS.IsNonRectangularLB, &Captures);
9779       if (!Final.isUsable()) {
9780         HasErrors = true;
9781         break;
9782       }
9783 
9784       if (!Update.isUsable() || !Final.isUsable()) {
9785         HasErrors = true;
9786         break;
9787       }
9788       // Save results
9789       Built.Counters[Cnt] = IS.CounterVar;
9790       Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
9791       Built.Inits[Cnt] = Init.get();
9792       Built.Updates[Cnt] = Update.get();
9793       Built.Finals[Cnt] = Final.get();
9794       Built.DependentCounters[Cnt] = nullptr;
9795       Built.DependentInits[Cnt] = nullptr;
9796       Built.FinalsConditions[Cnt] = nullptr;
9797       if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
9798         Built.DependentCounters[Cnt] =
9799             Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx];
9800         Built.DependentInits[Cnt] =
9801             Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx];
9802         Built.FinalsConditions[Cnt] = IS.FinalCondition;
9803       }
9804     }
9805   }
9806 
9807   if (HasErrors)
9808     return 0;
9809 
9810   // Save results
9811   Built.IterationVarRef = IV.get();
9812   Built.LastIteration = LastIteration.get();
9813   Built.NumIterations = NumIterations.get();
9814   Built.CalcLastIteration = SemaRef
9815                                 .ActOnFinishFullExpr(CalcLastIteration.get(),
9816                                                      /*DiscardedValue=*/false)
9817                                 .get();
9818   Built.PreCond = PreCond.get();
9819   Built.PreInits = buildPreInits(C, Captures);
9820   Built.Cond = Cond.get();
9821   Built.Init = Init.get();
9822   Built.Inc = Inc.get();
9823   Built.LB = LB.get();
9824   Built.UB = UB.get();
9825   Built.IL = IL.get();
9826   Built.ST = ST.get();
9827   Built.EUB = EUB.get();
9828   Built.NLB = NextLB.get();
9829   Built.NUB = NextUB.get();
9830   Built.PrevLB = PrevLB.get();
9831   Built.PrevUB = PrevUB.get();
9832   Built.DistInc = DistInc.get();
9833   Built.PrevEUB = PrevEUB.get();
9834   Built.DistCombinedFields.LB = CombLB.get();
9835   Built.DistCombinedFields.UB = CombUB.get();
9836   Built.DistCombinedFields.EUB = CombEUB.get();
9837   Built.DistCombinedFields.Init = CombInit.get();
9838   Built.DistCombinedFields.Cond = CombCond.get();
9839   Built.DistCombinedFields.NLB = CombNextLB.get();
9840   Built.DistCombinedFields.NUB = CombNextUB.get();
9841   Built.DistCombinedFields.DistCond = CombDistCond.get();
9842   Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
9843 
9844   return NestedLoopCount;
9845 }
9846 
9847 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
9848   auto CollapseClauses =
9849       OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
9850   if (CollapseClauses.begin() != CollapseClauses.end())
9851     return (*CollapseClauses.begin())->getNumForLoops();
9852   return nullptr;
9853 }
9854 
9855 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
9856   auto OrderedClauses =
9857       OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
9858   if (OrderedClauses.begin() != OrderedClauses.end())
9859     return (*OrderedClauses.begin())->getNumForLoops();
9860   return nullptr;
9861 }
9862 
9863 static bool checkSimdlenSafelenSpecified(Sema &S,
9864                                          const ArrayRef<OMPClause *> Clauses) {
9865   const OMPSafelenClause *Safelen = nullptr;
9866   const OMPSimdlenClause *Simdlen = nullptr;
9867 
9868   for (const OMPClause *Clause : Clauses) {
9869     if (Clause->getClauseKind() == OMPC_safelen)
9870       Safelen = cast<OMPSafelenClause>(Clause);
9871     else if (Clause->getClauseKind() == OMPC_simdlen)
9872       Simdlen = cast<OMPSimdlenClause>(Clause);
9873     if (Safelen && Simdlen)
9874       break;
9875   }
9876 
9877   if (Simdlen && Safelen) {
9878     const Expr *SimdlenLength = Simdlen->getSimdlen();
9879     const Expr *SafelenLength = Safelen->getSafelen();
9880     if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
9881         SimdlenLength->isInstantiationDependent() ||
9882         SimdlenLength->containsUnexpandedParameterPack())
9883       return false;
9884     if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
9885         SafelenLength->isInstantiationDependent() ||
9886         SafelenLength->containsUnexpandedParameterPack())
9887       return false;
9888     Expr::EvalResult SimdlenResult, SafelenResult;
9889     SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
9890     SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
9891     llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
9892     llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
9893     // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
9894     // If both simdlen and safelen clauses are specified, the value of the
9895     // simdlen parameter must be less than or equal to the value of the safelen
9896     // parameter.
9897     if (SimdlenRes > SafelenRes) {
9898       S.Diag(SimdlenLength->getExprLoc(),
9899              diag::err_omp_wrong_simdlen_safelen_values)
9900           << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
9901       return true;
9902     }
9903   }
9904   return false;
9905 }
9906 
9907 StmtResult
9908 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
9909                                SourceLocation StartLoc, SourceLocation EndLoc,
9910                                VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9911   if (!AStmt)
9912     return StmtError();
9913 
9914   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9915   OMPLoopBasedDirective::HelperExprs B;
9916   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9917   // define the nested loops number.
9918   unsigned NestedLoopCount = checkOpenMPLoop(
9919       OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
9920       AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
9921   if (NestedLoopCount == 0)
9922     return StmtError();
9923 
9924   assert((CurContext->isDependentContext() || B.builtAll()) &&
9925          "omp simd loop exprs were not built");
9926 
9927   if (!CurContext->isDependentContext()) {
9928     // Finalize the clauses that need pre-built expressions for CodeGen.
9929     for (OMPClause *C : Clauses) {
9930       if (auto *LC = dyn_cast<OMPLinearClause>(C))
9931         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9932                                      B.NumIterations, *this, CurScope,
9933                                      DSAStack))
9934           return StmtError();
9935     }
9936   }
9937 
9938   if (checkSimdlenSafelenSpecified(*this, Clauses))
9939     return StmtError();
9940 
9941   setFunctionHasBranchProtectedScope();
9942   return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
9943                                   Clauses, AStmt, B);
9944 }
9945 
9946 StmtResult
9947 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
9948                               SourceLocation StartLoc, SourceLocation EndLoc,
9949                               VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9950   if (!AStmt)
9951     return StmtError();
9952 
9953   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9954   OMPLoopBasedDirective::HelperExprs B;
9955   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9956   // define the nested loops number.
9957   unsigned NestedLoopCount = checkOpenMPLoop(
9958       OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
9959       AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
9960   if (NestedLoopCount == 0)
9961     return StmtError();
9962 
9963   assert((CurContext->isDependentContext() || B.builtAll()) &&
9964          "omp for loop exprs were not built");
9965 
9966   if (!CurContext->isDependentContext()) {
9967     // Finalize the clauses that need pre-built expressions for CodeGen.
9968     for (OMPClause *C : Clauses) {
9969       if (auto *LC = dyn_cast<OMPLinearClause>(C))
9970         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9971                                      B.NumIterations, *this, CurScope,
9972                                      DSAStack))
9973           return StmtError();
9974     }
9975   }
9976 
9977   setFunctionHasBranchProtectedScope();
9978   return OMPForDirective::Create(
9979       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
9980       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
9981 }
9982 
9983 StmtResult Sema::ActOnOpenMPForSimdDirective(
9984     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9985     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9986   if (!AStmt)
9987     return StmtError();
9988 
9989   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9990   OMPLoopBasedDirective::HelperExprs B;
9991   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9992   // define the nested loops number.
9993   unsigned NestedLoopCount =
9994       checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
9995                       getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
9996                       VarsWithImplicitDSA, B);
9997   if (NestedLoopCount == 0)
9998     return StmtError();
9999 
10000   assert((CurContext->isDependentContext() || B.builtAll()) &&
10001          "omp for simd loop exprs were not built");
10002 
10003   if (!CurContext->isDependentContext()) {
10004     // Finalize the clauses that need pre-built expressions for CodeGen.
10005     for (OMPClause *C : Clauses) {
10006       if (auto *LC = dyn_cast<OMPLinearClause>(C))
10007         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10008                                      B.NumIterations, *this, CurScope,
10009                                      DSAStack))
10010           return StmtError();
10011     }
10012   }
10013 
10014   if (checkSimdlenSafelenSpecified(*this, Clauses))
10015     return StmtError();
10016 
10017   setFunctionHasBranchProtectedScope();
10018   return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
10019                                      Clauses, AStmt, B);
10020 }
10021 
10022 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
10023                                               Stmt *AStmt,
10024                                               SourceLocation StartLoc,
10025                                               SourceLocation EndLoc) {
10026   if (!AStmt)
10027     return StmtError();
10028 
10029   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10030   auto BaseStmt = AStmt;
10031   while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
10032     BaseStmt = CS->getCapturedStmt();
10033   if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
10034     auto S = C->children();
10035     if (S.begin() == S.end())
10036       return StmtError();
10037     // All associated statements must be '#pragma omp section' except for
10038     // the first one.
10039     for (Stmt *SectionStmt : llvm::drop_begin(S)) {
10040       if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
10041         if (SectionStmt)
10042           Diag(SectionStmt->getBeginLoc(),
10043                diag::err_omp_sections_substmt_not_section);
10044         return StmtError();
10045       }
10046       cast<OMPSectionDirective>(SectionStmt)
10047           ->setHasCancel(DSAStack->isCancelRegion());
10048     }
10049   } else {
10050     Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
10051     return StmtError();
10052   }
10053 
10054   setFunctionHasBranchProtectedScope();
10055 
10056   return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10057                                       DSAStack->getTaskgroupReductionRef(),
10058                                       DSAStack->isCancelRegion());
10059 }
10060 
10061 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
10062                                              SourceLocation StartLoc,
10063                                              SourceLocation EndLoc) {
10064   if (!AStmt)
10065     return StmtError();
10066 
10067   setFunctionHasBranchProtectedScope();
10068   DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
10069 
10070   return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
10071                                      DSAStack->isCancelRegion());
10072 }
10073 
10074 static Expr *getDirectCallExpr(Expr *E) {
10075   E = E->IgnoreParenCasts()->IgnoreImplicit();
10076   if (auto *CE = dyn_cast<CallExpr>(E))
10077     if (CE->getDirectCallee())
10078       return E;
10079   return nullptr;
10080 }
10081 
10082 StmtResult Sema::ActOnOpenMPDispatchDirective(ArrayRef<OMPClause *> Clauses,
10083                                               Stmt *AStmt,
10084                                               SourceLocation StartLoc,
10085                                               SourceLocation EndLoc) {
10086   if (!AStmt)
10087     return StmtError();
10088 
10089   Stmt *S = cast<CapturedStmt>(AStmt)->getCapturedStmt();
10090 
10091   // 5.1 OpenMP
10092   // expression-stmt : an expression statement with one of the following forms:
10093   //   expression = target-call ( [expression-list] );
10094   //   target-call ( [expression-list] );
10095 
10096   SourceLocation TargetCallLoc;
10097 
10098   if (!CurContext->isDependentContext()) {
10099     Expr *TargetCall = nullptr;
10100 
10101     auto *E = dyn_cast<Expr>(S);
10102     if (!E) {
10103       Diag(S->getBeginLoc(), diag::err_omp_dispatch_statement_call);
10104       return StmtError();
10105     }
10106 
10107     E = E->IgnoreParenCasts()->IgnoreImplicit();
10108 
10109     if (auto *BO = dyn_cast<BinaryOperator>(E)) {
10110       if (BO->getOpcode() == BO_Assign)
10111         TargetCall = getDirectCallExpr(BO->getRHS());
10112     } else {
10113       if (auto *COCE = dyn_cast<CXXOperatorCallExpr>(E))
10114         if (COCE->getOperator() == OO_Equal)
10115           TargetCall = getDirectCallExpr(COCE->getArg(1));
10116       if (!TargetCall)
10117         TargetCall = getDirectCallExpr(E);
10118     }
10119     if (!TargetCall) {
10120       Diag(E->getBeginLoc(), diag::err_omp_dispatch_statement_call);
10121       return StmtError();
10122     }
10123     TargetCallLoc = TargetCall->getExprLoc();
10124   }
10125 
10126   setFunctionHasBranchProtectedScope();
10127 
10128   return OMPDispatchDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10129                                       TargetCallLoc);
10130 }
10131 
10132 StmtResult Sema::ActOnOpenMPGenericLoopDirective(
10133     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10134     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10135   if (!AStmt)
10136     return StmtError();
10137 
10138   // OpenMP 5.1 [2.11.7, loop construct]
10139   // A list item may not appear in a lastprivate clause unless it is the
10140   // loop iteration variable of a loop that is associated with the construct.
10141   for (OMPClause *C : Clauses) {
10142     if (auto *LPC = dyn_cast<OMPLastprivateClause>(C)) {
10143       for (Expr *RefExpr : LPC->varlists()) {
10144         SourceLocation ELoc;
10145         SourceRange ERange;
10146         Expr *SimpleRefExpr = RefExpr;
10147         auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
10148         if (ValueDecl *D = Res.first) {
10149           auto &&Info = DSAStack->isLoopControlVariable(D);
10150           if (!Info.first) {
10151             Diag(ELoc, diag::err_omp_lastprivate_loop_var_non_loop_iteration);
10152             return StmtError();
10153           }
10154         }
10155       }
10156     }
10157   }
10158 
10159   auto *CS = cast<CapturedStmt>(AStmt);
10160   // 1.2.2 OpenMP Language Terminology
10161   // Structured block - An executable statement with a single entry at the
10162   // top and a single exit at the bottom.
10163   // The point of exit cannot be a branch out of the structured block.
10164   // longjmp() and throw() must not violate the entry/exit criteria.
10165   CS->getCapturedDecl()->setNothrow();
10166 
10167   OMPLoopDirective::HelperExprs B;
10168   // In presence of clause 'collapse', it will define the nested loops number.
10169   unsigned NestedLoopCount = checkOpenMPLoop(
10170       OMPD_loop, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
10171       AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
10172   if (NestedLoopCount == 0)
10173     return StmtError();
10174 
10175   assert((CurContext->isDependentContext() || B.builtAll()) &&
10176          "omp loop exprs were not built");
10177 
10178   setFunctionHasBranchProtectedScope();
10179   return OMPGenericLoopDirective::Create(Context, StartLoc, EndLoc,
10180                                          NestedLoopCount, Clauses, AStmt, B);
10181 }
10182 
10183 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
10184                                             Stmt *AStmt,
10185                                             SourceLocation StartLoc,
10186                                             SourceLocation EndLoc) {
10187   if (!AStmt)
10188     return StmtError();
10189 
10190   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10191 
10192   setFunctionHasBranchProtectedScope();
10193 
10194   // OpenMP [2.7.3, single Construct, Restrictions]
10195   // The copyprivate clause must not be used with the nowait clause.
10196   const OMPClause *Nowait = nullptr;
10197   const OMPClause *Copyprivate = nullptr;
10198   for (const OMPClause *Clause : Clauses) {
10199     if (Clause->getClauseKind() == OMPC_nowait)
10200       Nowait = Clause;
10201     else if (Clause->getClauseKind() == OMPC_copyprivate)
10202       Copyprivate = Clause;
10203     if (Copyprivate && Nowait) {
10204       Diag(Copyprivate->getBeginLoc(),
10205            diag::err_omp_single_copyprivate_with_nowait);
10206       Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
10207       return StmtError();
10208     }
10209   }
10210 
10211   return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10212 }
10213 
10214 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
10215                                             SourceLocation StartLoc,
10216                                             SourceLocation EndLoc) {
10217   if (!AStmt)
10218     return StmtError();
10219 
10220   setFunctionHasBranchProtectedScope();
10221 
10222   return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
10223 }
10224 
10225 StmtResult Sema::ActOnOpenMPMaskedDirective(ArrayRef<OMPClause *> Clauses,
10226                                             Stmt *AStmt,
10227                                             SourceLocation StartLoc,
10228                                             SourceLocation EndLoc) {
10229   if (!AStmt)
10230     return StmtError();
10231 
10232   setFunctionHasBranchProtectedScope();
10233 
10234   return OMPMaskedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10235 }
10236 
10237 StmtResult Sema::ActOnOpenMPCriticalDirective(
10238     const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
10239     Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
10240   if (!AStmt)
10241     return StmtError();
10242 
10243   bool ErrorFound = false;
10244   llvm::APSInt Hint;
10245   SourceLocation HintLoc;
10246   bool DependentHint = false;
10247   for (const OMPClause *C : Clauses) {
10248     if (C->getClauseKind() == OMPC_hint) {
10249       if (!DirName.getName()) {
10250         Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
10251         ErrorFound = true;
10252       }
10253       Expr *E = cast<OMPHintClause>(C)->getHint();
10254       if (E->isTypeDependent() || E->isValueDependent() ||
10255           E->isInstantiationDependent()) {
10256         DependentHint = true;
10257       } else {
10258         Hint = E->EvaluateKnownConstInt(Context);
10259         HintLoc = C->getBeginLoc();
10260       }
10261     }
10262   }
10263   if (ErrorFound)
10264     return StmtError();
10265   const auto Pair = DSAStack->getCriticalWithHint(DirName);
10266   if (Pair.first && DirName.getName() && !DependentHint) {
10267     if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
10268       Diag(StartLoc, diag::err_omp_critical_with_hint);
10269       if (HintLoc.isValid())
10270         Diag(HintLoc, diag::note_omp_critical_hint_here)
10271             << 0 << toString(Hint, /*Radix=*/10, /*Signed=*/false);
10272       else
10273         Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
10274       if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
10275         Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
10276             << 1
10277             << toString(C->getHint()->EvaluateKnownConstInt(Context),
10278                         /*Radix=*/10, /*Signed=*/false);
10279       } else {
10280         Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
10281       }
10282     }
10283   }
10284 
10285   setFunctionHasBranchProtectedScope();
10286 
10287   auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
10288                                            Clauses, AStmt);
10289   if (!Pair.first && DirName.getName() && !DependentHint)
10290     DSAStack->addCriticalWithHint(Dir, Hint);
10291   return Dir;
10292 }
10293 
10294 StmtResult Sema::ActOnOpenMPParallelForDirective(
10295     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10296     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10297   if (!AStmt)
10298     return StmtError();
10299 
10300   auto *CS = cast<CapturedStmt>(AStmt);
10301   // 1.2.2 OpenMP Language Terminology
10302   // Structured block - An executable statement with a single entry at the
10303   // top and a single exit at the bottom.
10304   // The point of exit cannot be a branch out of the structured block.
10305   // longjmp() and throw() must not violate the entry/exit criteria.
10306   CS->getCapturedDecl()->setNothrow();
10307 
10308   OMPLoopBasedDirective::HelperExprs B;
10309   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10310   // define the nested loops number.
10311   unsigned NestedLoopCount =
10312       checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
10313                       getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
10314                       VarsWithImplicitDSA, B);
10315   if (NestedLoopCount == 0)
10316     return StmtError();
10317 
10318   assert((CurContext->isDependentContext() || B.builtAll()) &&
10319          "omp parallel for loop exprs were not built");
10320 
10321   if (!CurContext->isDependentContext()) {
10322     // Finalize the clauses that need pre-built expressions for CodeGen.
10323     for (OMPClause *C : Clauses) {
10324       if (auto *LC = dyn_cast<OMPLinearClause>(C))
10325         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10326                                      B.NumIterations, *this, CurScope,
10327                                      DSAStack))
10328           return StmtError();
10329     }
10330   }
10331 
10332   setFunctionHasBranchProtectedScope();
10333   return OMPParallelForDirective::Create(
10334       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10335       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10336 }
10337 
10338 StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
10339     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10340     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10341   if (!AStmt)
10342     return StmtError();
10343 
10344   auto *CS = cast<CapturedStmt>(AStmt);
10345   // 1.2.2 OpenMP Language Terminology
10346   // Structured block - An executable statement with a single entry at the
10347   // top and a single exit at the bottom.
10348   // The point of exit cannot be a branch out of the structured block.
10349   // longjmp() and throw() must not violate the entry/exit criteria.
10350   CS->getCapturedDecl()->setNothrow();
10351 
10352   OMPLoopBasedDirective::HelperExprs B;
10353   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10354   // define the nested loops number.
10355   unsigned NestedLoopCount =
10356       checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
10357                       getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
10358                       VarsWithImplicitDSA, B);
10359   if (NestedLoopCount == 0)
10360     return StmtError();
10361 
10362   if (!CurContext->isDependentContext()) {
10363     // Finalize the clauses that need pre-built expressions for CodeGen.
10364     for (OMPClause *C : Clauses) {
10365       if (auto *LC = dyn_cast<OMPLinearClause>(C))
10366         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10367                                      B.NumIterations, *this, CurScope,
10368                                      DSAStack))
10369           return StmtError();
10370     }
10371   }
10372 
10373   if (checkSimdlenSafelenSpecified(*this, Clauses))
10374     return StmtError();
10375 
10376   setFunctionHasBranchProtectedScope();
10377   return OMPParallelForSimdDirective::Create(
10378       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10379 }
10380 
10381 StmtResult
10382 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses,
10383                                          Stmt *AStmt, SourceLocation StartLoc,
10384                                          SourceLocation EndLoc) {
10385   if (!AStmt)
10386     return StmtError();
10387 
10388   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10389   auto *CS = cast<CapturedStmt>(AStmt);
10390   // 1.2.2 OpenMP Language Terminology
10391   // Structured block - An executable statement with a single entry at the
10392   // top and a single exit at the bottom.
10393   // The point of exit cannot be a branch out of the structured block.
10394   // longjmp() and throw() must not violate the entry/exit criteria.
10395   CS->getCapturedDecl()->setNothrow();
10396 
10397   setFunctionHasBranchProtectedScope();
10398 
10399   return OMPParallelMasterDirective::Create(
10400       Context, StartLoc, EndLoc, Clauses, AStmt,
10401       DSAStack->getTaskgroupReductionRef());
10402 }
10403 
10404 StmtResult
10405 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
10406                                            Stmt *AStmt, SourceLocation StartLoc,
10407                                            SourceLocation EndLoc) {
10408   if (!AStmt)
10409     return StmtError();
10410 
10411   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10412   auto BaseStmt = AStmt;
10413   while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
10414     BaseStmt = CS->getCapturedStmt();
10415   if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
10416     auto S = C->children();
10417     if (S.begin() == S.end())
10418       return StmtError();
10419     // All associated statements must be '#pragma omp section' except for
10420     // the first one.
10421     for (Stmt *SectionStmt : llvm::drop_begin(S)) {
10422       if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
10423         if (SectionStmt)
10424           Diag(SectionStmt->getBeginLoc(),
10425                diag::err_omp_parallel_sections_substmt_not_section);
10426         return StmtError();
10427       }
10428       cast<OMPSectionDirective>(SectionStmt)
10429           ->setHasCancel(DSAStack->isCancelRegion());
10430     }
10431   } else {
10432     Diag(AStmt->getBeginLoc(),
10433          diag::err_omp_parallel_sections_not_compound_stmt);
10434     return StmtError();
10435   }
10436 
10437   setFunctionHasBranchProtectedScope();
10438 
10439   return OMPParallelSectionsDirective::Create(
10440       Context, StartLoc, EndLoc, Clauses, AStmt,
10441       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10442 }
10443 
10444 /// Find and diagnose mutually exclusive clause kinds.
10445 static bool checkMutuallyExclusiveClauses(
10446     Sema &S, ArrayRef<OMPClause *> Clauses,
10447     ArrayRef<OpenMPClauseKind> MutuallyExclusiveClauses) {
10448   const OMPClause *PrevClause = nullptr;
10449   bool ErrorFound = false;
10450   for (const OMPClause *C : Clauses) {
10451     if (llvm::is_contained(MutuallyExclusiveClauses, C->getClauseKind())) {
10452       if (!PrevClause) {
10453         PrevClause = C;
10454       } else if (PrevClause->getClauseKind() != C->getClauseKind()) {
10455         S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
10456             << getOpenMPClauseName(C->getClauseKind())
10457             << getOpenMPClauseName(PrevClause->getClauseKind());
10458         S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
10459             << getOpenMPClauseName(PrevClause->getClauseKind());
10460         ErrorFound = true;
10461       }
10462     }
10463   }
10464   return ErrorFound;
10465 }
10466 
10467 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
10468                                           Stmt *AStmt, SourceLocation StartLoc,
10469                                           SourceLocation EndLoc) {
10470   if (!AStmt)
10471     return StmtError();
10472 
10473   // OpenMP 5.0, 2.10.1 task Construct
10474   // If a detach clause appears on the directive, then a mergeable clause cannot
10475   // appear on the same directive.
10476   if (checkMutuallyExclusiveClauses(*this, Clauses,
10477                                     {OMPC_detach, OMPC_mergeable}))
10478     return StmtError();
10479 
10480   auto *CS = cast<CapturedStmt>(AStmt);
10481   // 1.2.2 OpenMP Language Terminology
10482   // Structured block - An executable statement with a single entry at the
10483   // top and a single exit at the bottom.
10484   // The point of exit cannot be a branch out of the structured block.
10485   // longjmp() and throw() must not violate the entry/exit criteria.
10486   CS->getCapturedDecl()->setNothrow();
10487 
10488   setFunctionHasBranchProtectedScope();
10489 
10490   return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10491                                   DSAStack->isCancelRegion());
10492 }
10493 
10494 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
10495                                                SourceLocation EndLoc) {
10496   return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
10497 }
10498 
10499 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
10500                                              SourceLocation EndLoc) {
10501   return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
10502 }
10503 
10504 StmtResult Sema::ActOnOpenMPTaskwaitDirective(ArrayRef<OMPClause *> Clauses,
10505                                               SourceLocation StartLoc,
10506                                               SourceLocation EndLoc) {
10507   return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc, Clauses);
10508 }
10509 
10510 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
10511                                                Stmt *AStmt,
10512                                                SourceLocation StartLoc,
10513                                                SourceLocation EndLoc) {
10514   if (!AStmt)
10515     return StmtError();
10516 
10517   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10518 
10519   setFunctionHasBranchProtectedScope();
10520 
10521   return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
10522                                        AStmt,
10523                                        DSAStack->getTaskgroupReductionRef());
10524 }
10525 
10526 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
10527                                            SourceLocation StartLoc,
10528                                            SourceLocation EndLoc) {
10529   OMPFlushClause *FC = nullptr;
10530   OMPClause *OrderClause = nullptr;
10531   for (OMPClause *C : Clauses) {
10532     if (C->getClauseKind() == OMPC_flush)
10533       FC = cast<OMPFlushClause>(C);
10534     else
10535       OrderClause = C;
10536   }
10537   OpenMPClauseKind MemOrderKind = OMPC_unknown;
10538   SourceLocation MemOrderLoc;
10539   for (const OMPClause *C : Clauses) {
10540     if (C->getClauseKind() == OMPC_acq_rel ||
10541         C->getClauseKind() == OMPC_acquire ||
10542         C->getClauseKind() == OMPC_release) {
10543       if (MemOrderKind != OMPC_unknown) {
10544         Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
10545             << getOpenMPDirectiveName(OMPD_flush) << 1
10546             << SourceRange(C->getBeginLoc(), C->getEndLoc());
10547         Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
10548             << getOpenMPClauseName(MemOrderKind);
10549       } else {
10550         MemOrderKind = C->getClauseKind();
10551         MemOrderLoc = C->getBeginLoc();
10552       }
10553     }
10554   }
10555   if (FC && OrderClause) {
10556     Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list)
10557         << getOpenMPClauseName(OrderClause->getClauseKind());
10558     Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here)
10559         << getOpenMPClauseName(OrderClause->getClauseKind());
10560     return StmtError();
10561   }
10562   return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
10563 }
10564 
10565 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses,
10566                                             SourceLocation StartLoc,
10567                                             SourceLocation EndLoc) {
10568   if (Clauses.empty()) {
10569     Diag(StartLoc, diag::err_omp_depobj_expected);
10570     return StmtError();
10571   } else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
10572     Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
10573     return StmtError();
10574   }
10575   // Only depobj expression and another single clause is allowed.
10576   if (Clauses.size() > 2) {
10577     Diag(Clauses[2]->getBeginLoc(),
10578          diag::err_omp_depobj_single_clause_expected);
10579     return StmtError();
10580   } else if (Clauses.size() < 1) {
10581     Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
10582     return StmtError();
10583   }
10584   return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses);
10585 }
10586 
10587 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses,
10588                                           SourceLocation StartLoc,
10589                                           SourceLocation EndLoc) {
10590   // Check that exactly one clause is specified.
10591   if (Clauses.size() != 1) {
10592     Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
10593          diag::err_omp_scan_single_clause_expected);
10594     return StmtError();
10595   }
10596   // Check that scan directive is used in the scopeof the OpenMP loop body.
10597   if (Scope *S = DSAStack->getCurScope()) {
10598     Scope *ParentS = S->getParent();
10599     if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() ||
10600         !ParentS->getBreakParent()->isOpenMPLoopScope())
10601       return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive)
10602                        << getOpenMPDirectiveName(OMPD_scan) << 5);
10603   }
10604   // Check that only one instance of scan directives is used in the same outer
10605   // region.
10606   if (DSAStack->doesParentHasScanDirective()) {
10607     Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan";
10608     Diag(DSAStack->getParentScanDirectiveLoc(),
10609          diag::note_omp_previous_directive)
10610         << "scan";
10611     return StmtError();
10612   }
10613   DSAStack->setParentHasScanDirective(StartLoc);
10614   return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses);
10615 }
10616 
10617 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
10618                                              Stmt *AStmt,
10619                                              SourceLocation StartLoc,
10620                                              SourceLocation EndLoc) {
10621   const OMPClause *DependFound = nullptr;
10622   const OMPClause *DependSourceClause = nullptr;
10623   const OMPClause *DependSinkClause = nullptr;
10624   bool ErrorFound = false;
10625   const OMPThreadsClause *TC = nullptr;
10626   const OMPSIMDClause *SC = nullptr;
10627   for (const OMPClause *C : Clauses) {
10628     if (auto *DC = dyn_cast<OMPDependClause>(C)) {
10629       DependFound = C;
10630       if (DC->getDependencyKind() == OMPC_DEPEND_source) {
10631         if (DependSourceClause) {
10632           Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
10633               << getOpenMPDirectiveName(OMPD_ordered)
10634               << getOpenMPClauseName(OMPC_depend) << 2;
10635           ErrorFound = true;
10636         } else {
10637           DependSourceClause = C;
10638         }
10639         if (DependSinkClause) {
10640           Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
10641               << 0;
10642           ErrorFound = true;
10643         }
10644       } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
10645         if (DependSourceClause) {
10646           Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
10647               << 1;
10648           ErrorFound = true;
10649         }
10650         DependSinkClause = C;
10651       }
10652     } else if (C->getClauseKind() == OMPC_threads) {
10653       TC = cast<OMPThreadsClause>(C);
10654     } else if (C->getClauseKind() == OMPC_simd) {
10655       SC = cast<OMPSIMDClause>(C);
10656     }
10657   }
10658   if (!ErrorFound && !SC &&
10659       isOpenMPSimdDirective(DSAStack->getParentDirective())) {
10660     // OpenMP [2.8.1,simd Construct, Restrictions]
10661     // An ordered construct with the simd clause is the only OpenMP construct
10662     // that can appear in the simd region.
10663     Diag(StartLoc, diag::err_omp_prohibited_region_simd)
10664         << (LangOpts.OpenMP >= 50 ? 1 : 0);
10665     ErrorFound = true;
10666   } else if (DependFound && (TC || SC)) {
10667     Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
10668         << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
10669     ErrorFound = true;
10670   } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) {
10671     Diag(DependFound->getBeginLoc(),
10672          diag::err_omp_ordered_directive_without_param);
10673     ErrorFound = true;
10674   } else if (TC || Clauses.empty()) {
10675     if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) {
10676       SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
10677       Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
10678           << (TC != nullptr);
10679       Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1;
10680       ErrorFound = true;
10681     }
10682   }
10683   if ((!AStmt && !DependFound) || ErrorFound)
10684     return StmtError();
10685 
10686   // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions.
10687   // During execution of an iteration of a worksharing-loop or a loop nest
10688   // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread
10689   // must not execute more than one ordered region corresponding to an ordered
10690   // construct without a depend clause.
10691   if (!DependFound) {
10692     if (DSAStack->doesParentHasOrderedDirective()) {
10693       Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered";
10694       Diag(DSAStack->getParentOrderedDirectiveLoc(),
10695            diag::note_omp_previous_directive)
10696           << "ordered";
10697       return StmtError();
10698     }
10699     DSAStack->setParentHasOrderedDirective(StartLoc);
10700   }
10701 
10702   if (AStmt) {
10703     assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10704 
10705     setFunctionHasBranchProtectedScope();
10706   }
10707 
10708   return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10709 }
10710 
10711 namespace {
10712 /// Helper class for checking expression in 'omp atomic [update]'
10713 /// construct.
10714 class OpenMPAtomicUpdateChecker {
10715   /// Error results for atomic update expressions.
10716   enum ExprAnalysisErrorCode {
10717     /// A statement is not an expression statement.
10718     NotAnExpression,
10719     /// Expression is not builtin binary or unary operation.
10720     NotABinaryOrUnaryExpression,
10721     /// Unary operation is not post-/pre- increment/decrement operation.
10722     NotAnUnaryIncDecExpression,
10723     /// An expression is not of scalar type.
10724     NotAScalarType,
10725     /// A binary operation is not an assignment operation.
10726     NotAnAssignmentOp,
10727     /// RHS part of the binary operation is not a binary expression.
10728     NotABinaryExpression,
10729     /// RHS part is not additive/multiplicative/shift/biwise binary
10730     /// expression.
10731     NotABinaryOperator,
10732     /// RHS binary operation does not have reference to the updated LHS
10733     /// part.
10734     NotAnUpdateExpression,
10735     /// No errors is found.
10736     NoError
10737   };
10738   /// Reference to Sema.
10739   Sema &SemaRef;
10740   /// A location for note diagnostics (when error is found).
10741   SourceLocation NoteLoc;
10742   /// 'x' lvalue part of the source atomic expression.
10743   Expr *X;
10744   /// 'expr' rvalue part of the source atomic expression.
10745   Expr *E;
10746   /// Helper expression of the form
10747   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
10748   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
10749   Expr *UpdateExpr;
10750   /// Is 'x' a LHS in a RHS part of full update expression. It is
10751   /// important for non-associative operations.
10752   bool IsXLHSInRHSPart;
10753   BinaryOperatorKind Op;
10754   SourceLocation OpLoc;
10755   /// true if the source expression is a postfix unary operation, false
10756   /// if it is a prefix unary operation.
10757   bool IsPostfixUpdate;
10758 
10759 public:
10760   OpenMPAtomicUpdateChecker(Sema &SemaRef)
10761       : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
10762         IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
10763   /// Check specified statement that it is suitable for 'atomic update'
10764   /// constructs and extract 'x', 'expr' and Operation from the original
10765   /// expression. If DiagId and NoteId == 0, then only check is performed
10766   /// without error notification.
10767   /// \param DiagId Diagnostic which should be emitted if error is found.
10768   /// \param NoteId Diagnostic note for the main error message.
10769   /// \return true if statement is not an update expression, false otherwise.
10770   bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
10771   /// Return the 'x' lvalue part of the source atomic expression.
10772   Expr *getX() const { return X; }
10773   /// Return the 'expr' rvalue part of the source atomic expression.
10774   Expr *getExpr() const { return E; }
10775   /// Return the update expression used in calculation of the updated
10776   /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
10777   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
10778   Expr *getUpdateExpr() const { return UpdateExpr; }
10779   /// Return true if 'x' is LHS in RHS part of full update expression,
10780   /// false otherwise.
10781   bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
10782 
10783   /// true if the source expression is a postfix unary operation, false
10784   /// if it is a prefix unary operation.
10785   bool isPostfixUpdate() const { return IsPostfixUpdate; }
10786 
10787 private:
10788   bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
10789                             unsigned NoteId = 0);
10790 };
10791 
10792 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
10793     BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
10794   ExprAnalysisErrorCode ErrorFound = NoError;
10795   SourceLocation ErrorLoc, NoteLoc;
10796   SourceRange ErrorRange, NoteRange;
10797   // Allowed constructs are:
10798   //  x = x binop expr;
10799   //  x = expr binop x;
10800   if (AtomicBinOp->getOpcode() == BO_Assign) {
10801     X = AtomicBinOp->getLHS();
10802     if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
10803             AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
10804       if (AtomicInnerBinOp->isMultiplicativeOp() ||
10805           AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
10806           AtomicInnerBinOp->isBitwiseOp()) {
10807         Op = AtomicInnerBinOp->getOpcode();
10808         OpLoc = AtomicInnerBinOp->getOperatorLoc();
10809         Expr *LHS = AtomicInnerBinOp->getLHS();
10810         Expr *RHS = AtomicInnerBinOp->getRHS();
10811         llvm::FoldingSetNodeID XId, LHSId, RHSId;
10812         X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
10813                                           /*Canonical=*/true);
10814         LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
10815                                             /*Canonical=*/true);
10816         RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
10817                                             /*Canonical=*/true);
10818         if (XId == LHSId) {
10819           E = RHS;
10820           IsXLHSInRHSPart = true;
10821         } else if (XId == RHSId) {
10822           E = LHS;
10823           IsXLHSInRHSPart = false;
10824         } else {
10825           ErrorLoc = AtomicInnerBinOp->getExprLoc();
10826           ErrorRange = AtomicInnerBinOp->getSourceRange();
10827           NoteLoc = X->getExprLoc();
10828           NoteRange = X->getSourceRange();
10829           ErrorFound = NotAnUpdateExpression;
10830         }
10831       } else {
10832         ErrorLoc = AtomicInnerBinOp->getExprLoc();
10833         ErrorRange = AtomicInnerBinOp->getSourceRange();
10834         NoteLoc = AtomicInnerBinOp->getOperatorLoc();
10835         NoteRange = SourceRange(NoteLoc, NoteLoc);
10836         ErrorFound = NotABinaryOperator;
10837       }
10838     } else {
10839       NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
10840       NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
10841       ErrorFound = NotABinaryExpression;
10842     }
10843   } else {
10844     ErrorLoc = AtomicBinOp->getExprLoc();
10845     ErrorRange = AtomicBinOp->getSourceRange();
10846     NoteLoc = AtomicBinOp->getOperatorLoc();
10847     NoteRange = SourceRange(NoteLoc, NoteLoc);
10848     ErrorFound = NotAnAssignmentOp;
10849   }
10850   if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
10851     SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
10852     SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
10853     return true;
10854   }
10855   if (SemaRef.CurContext->isDependentContext())
10856     E = X = UpdateExpr = nullptr;
10857   return ErrorFound != NoError;
10858 }
10859 
10860 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
10861                                                unsigned NoteId) {
10862   ExprAnalysisErrorCode ErrorFound = NoError;
10863   SourceLocation ErrorLoc, NoteLoc;
10864   SourceRange ErrorRange, NoteRange;
10865   // Allowed constructs are:
10866   //  x++;
10867   //  x--;
10868   //  ++x;
10869   //  --x;
10870   //  x binop= expr;
10871   //  x = x binop expr;
10872   //  x = expr binop x;
10873   if (auto *AtomicBody = dyn_cast<Expr>(S)) {
10874     AtomicBody = AtomicBody->IgnoreParenImpCasts();
10875     if (AtomicBody->getType()->isScalarType() ||
10876         AtomicBody->isInstantiationDependent()) {
10877       if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
10878               AtomicBody->IgnoreParenImpCasts())) {
10879         // Check for Compound Assignment Operation
10880         Op = BinaryOperator::getOpForCompoundAssignment(
10881             AtomicCompAssignOp->getOpcode());
10882         OpLoc = AtomicCompAssignOp->getOperatorLoc();
10883         E = AtomicCompAssignOp->getRHS();
10884         X = AtomicCompAssignOp->getLHS()->IgnoreParens();
10885         IsXLHSInRHSPart = true;
10886       } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
10887                      AtomicBody->IgnoreParenImpCasts())) {
10888         // Check for Binary Operation
10889         if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
10890           return true;
10891       } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
10892                      AtomicBody->IgnoreParenImpCasts())) {
10893         // Check for Unary Operation
10894         if (AtomicUnaryOp->isIncrementDecrementOp()) {
10895           IsPostfixUpdate = AtomicUnaryOp->isPostfix();
10896           Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
10897           OpLoc = AtomicUnaryOp->getOperatorLoc();
10898           X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
10899           E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
10900           IsXLHSInRHSPart = true;
10901         } else {
10902           ErrorFound = NotAnUnaryIncDecExpression;
10903           ErrorLoc = AtomicUnaryOp->getExprLoc();
10904           ErrorRange = AtomicUnaryOp->getSourceRange();
10905           NoteLoc = AtomicUnaryOp->getOperatorLoc();
10906           NoteRange = SourceRange(NoteLoc, NoteLoc);
10907         }
10908       } else if (!AtomicBody->isInstantiationDependent()) {
10909         ErrorFound = NotABinaryOrUnaryExpression;
10910         NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
10911         NoteRange = ErrorRange = AtomicBody->getSourceRange();
10912       }
10913     } else {
10914       ErrorFound = NotAScalarType;
10915       NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
10916       NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10917     }
10918   } else {
10919     ErrorFound = NotAnExpression;
10920     NoteLoc = ErrorLoc = S->getBeginLoc();
10921     NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10922   }
10923   if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
10924     SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
10925     SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
10926     return true;
10927   }
10928   if (SemaRef.CurContext->isDependentContext())
10929     E = X = UpdateExpr = nullptr;
10930   if (ErrorFound == NoError && E && X) {
10931     // Build an update expression of form 'OpaqueValueExpr(x) binop
10932     // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
10933     // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
10934     auto *OVEX = new (SemaRef.getASTContext())
10935         OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_PRValue);
10936     auto *OVEExpr = new (SemaRef.getASTContext())
10937         OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_PRValue);
10938     ExprResult Update =
10939         SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
10940                                    IsXLHSInRHSPart ? OVEExpr : OVEX);
10941     if (Update.isInvalid())
10942       return true;
10943     Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
10944                                                Sema::AA_Casting);
10945     if (Update.isInvalid())
10946       return true;
10947     UpdateExpr = Update.get();
10948   }
10949   return ErrorFound != NoError;
10950 }
10951 
10952 /// Get the node id of the fixed point of an expression \a S.
10953 llvm::FoldingSetNodeID getNodeId(ASTContext &Context, const Expr *S) {
10954   llvm::FoldingSetNodeID Id;
10955   S->IgnoreParenImpCasts()->Profile(Id, Context, true);
10956   return Id;
10957 }
10958 
10959 /// Check if two expressions are same.
10960 bool checkIfTwoExprsAreSame(ASTContext &Context, const Expr *LHS,
10961                             const Expr *RHS) {
10962   return getNodeId(Context, LHS) == getNodeId(Context, RHS);
10963 }
10964 
10965 class OpenMPAtomicCompareChecker {
10966 public:
10967   /// All kinds of errors that can occur in `atomic compare`
10968   enum ErrorTy {
10969     /// Empty compound statement.
10970     NoStmt = 0,
10971     /// More than one statement in a compound statement.
10972     MoreThanOneStmt,
10973     /// Not an assignment binary operator.
10974     NotAnAssignment,
10975     /// Not a conditional operator.
10976     NotCondOp,
10977     /// Wrong false expr. According to the spec, 'x' should be at the false
10978     /// expression of a conditional expression.
10979     WrongFalseExpr,
10980     /// The condition of a conditional expression is not a binary operator.
10981     NotABinaryOp,
10982     /// Invalid binary operator (not <, >, or ==).
10983     InvalidBinaryOp,
10984     /// Invalid comparison (not x == e, e == x, x ordop expr, or expr ordop x).
10985     InvalidComparison,
10986     /// X is not a lvalue.
10987     XNotLValue,
10988     /// Not a scalar.
10989     NotScalar,
10990     /// Not an integer.
10991     NotInteger,
10992     /// 'else' statement is not expected.
10993     UnexpectedElse,
10994     /// Not an equality operator.
10995     NotEQ,
10996     /// Invalid assignment (not v == x).
10997     InvalidAssignment,
10998     /// Not if statement
10999     NotIfStmt,
11000     /// More than two statements in a compund statement.
11001     MoreThanTwoStmts,
11002     /// Not a compound statement.
11003     NotCompoundStmt,
11004     /// No else statement.
11005     NoElse,
11006     /// Not 'if (r)'.
11007     InvalidCondition,
11008     /// No error.
11009     NoError,
11010   };
11011 
11012   struct ErrorInfoTy {
11013     ErrorTy Error;
11014     SourceLocation ErrorLoc;
11015     SourceRange ErrorRange;
11016     SourceLocation NoteLoc;
11017     SourceRange NoteRange;
11018   };
11019 
11020   OpenMPAtomicCompareChecker(Sema &S) : ContextRef(S.getASTContext()) {}
11021 
11022   /// Check if statement \a S is valid for <tt>atomic compare</tt>.
11023   bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
11024 
11025   Expr *getX() const { return X; }
11026   Expr *getE() const { return E; }
11027   Expr *getD() const { return D; }
11028   Expr *getCond() const { return C; }
11029   bool isXBinopExpr() const { return IsXBinopExpr; }
11030 
11031 protected:
11032   /// Reference to ASTContext
11033   ASTContext &ContextRef;
11034   /// 'x' lvalue part of the source atomic expression.
11035   Expr *X = nullptr;
11036   /// 'expr' or 'e' rvalue part of the source atomic expression.
11037   Expr *E = nullptr;
11038   /// 'd' rvalue part of the source atomic expression.
11039   Expr *D = nullptr;
11040   /// 'cond' part of the source atomic expression. It is in one of the following
11041   /// forms:
11042   /// expr ordop x
11043   /// x ordop expr
11044   /// x == e
11045   /// e == x
11046   Expr *C = nullptr;
11047   /// True if the cond expr is in the form of 'x ordop expr'.
11048   bool IsXBinopExpr = true;
11049 
11050   /// Check if it is a valid conditional update statement (cond-update-stmt).
11051   bool checkCondUpdateStmt(IfStmt *S, ErrorInfoTy &ErrorInfo);
11052 
11053   /// Check if it is a valid conditional expression statement (cond-expr-stmt).
11054   bool checkCondExprStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
11055 
11056   /// Check if all captured values have right type.
11057   bool checkType(ErrorInfoTy &ErrorInfo) const;
11058 
11059   static bool CheckValue(const Expr *E, ErrorInfoTy &ErrorInfo,
11060                          bool ShouldBeLValue) {
11061     if (ShouldBeLValue && !E->isLValue()) {
11062       ErrorInfo.Error = ErrorTy::XNotLValue;
11063       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11064       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11065       return false;
11066     }
11067 
11068     if (!E->isInstantiationDependent()) {
11069       QualType QTy = E->getType();
11070       if (!QTy->isScalarType()) {
11071         ErrorInfo.Error = ErrorTy::NotScalar;
11072         ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11073         ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11074         return false;
11075       }
11076 
11077       if (!QTy->isIntegerType()) {
11078         ErrorInfo.Error = ErrorTy::NotInteger;
11079         ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc();
11080         ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange();
11081         return false;
11082       }
11083     }
11084 
11085     return true;
11086   }
11087 };
11088 
11089 bool OpenMPAtomicCompareChecker::checkCondUpdateStmt(IfStmt *S,
11090                                                      ErrorInfoTy &ErrorInfo) {
11091   auto *Then = S->getThen();
11092   if (auto *CS = dyn_cast<CompoundStmt>(Then)) {
11093     if (CS->body_empty()) {
11094       ErrorInfo.Error = ErrorTy::NoStmt;
11095       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11096       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11097       return false;
11098     }
11099     if (CS->size() > 1) {
11100       ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11101       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11102       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
11103       return false;
11104     }
11105     Then = CS->body_front();
11106   }
11107 
11108   auto *BO = dyn_cast<BinaryOperator>(Then);
11109   if (!BO) {
11110     ErrorInfo.Error = ErrorTy::NotAnAssignment;
11111     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc();
11112     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange();
11113     return false;
11114   }
11115   if (BO->getOpcode() != BO_Assign) {
11116     ErrorInfo.Error = ErrorTy::NotAnAssignment;
11117     ErrorInfo.ErrorLoc = BO->getExprLoc();
11118     ErrorInfo.NoteLoc = BO->getOperatorLoc();
11119     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
11120     return false;
11121   }
11122 
11123   X = BO->getLHS();
11124 
11125   auto *Cond = dyn_cast<BinaryOperator>(S->getCond());
11126   if (!Cond) {
11127     ErrorInfo.Error = ErrorTy::NotABinaryOp;
11128     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc();
11129     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange();
11130     return false;
11131   }
11132 
11133   switch (Cond->getOpcode()) {
11134   case BO_EQ: {
11135     C = Cond;
11136     D = BO->getRHS()->IgnoreImpCasts();
11137     if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
11138       E = Cond->getRHS()->IgnoreImpCasts();
11139     } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11140       E = Cond->getLHS()->IgnoreImpCasts();
11141     } else {
11142       ErrorInfo.Error = ErrorTy::InvalidComparison;
11143       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11144       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11145       return false;
11146     }
11147     break;
11148   }
11149   case BO_LT:
11150   case BO_GT: {
11151     E = BO->getRHS()->IgnoreImpCasts();
11152     if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) &&
11153         checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) {
11154       C = Cond;
11155     } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) &&
11156                checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11157       C = Cond;
11158       IsXBinopExpr = false;
11159     } else {
11160       ErrorInfo.Error = ErrorTy::InvalidComparison;
11161       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11162       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11163       return false;
11164     }
11165     break;
11166   }
11167   default:
11168     ErrorInfo.Error = ErrorTy::InvalidBinaryOp;
11169     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11170     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11171     return false;
11172   }
11173 
11174   if (S->getElse()) {
11175     ErrorInfo.Error = ErrorTy::UnexpectedElse;
11176     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getElse()->getBeginLoc();
11177     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getElse()->getSourceRange();
11178     return false;
11179   }
11180 
11181   return true;
11182 }
11183 
11184 bool OpenMPAtomicCompareChecker::checkCondExprStmt(Stmt *S,
11185                                                    ErrorInfoTy &ErrorInfo) {
11186   auto *BO = dyn_cast<BinaryOperator>(S);
11187   if (!BO) {
11188     ErrorInfo.Error = ErrorTy::NotAnAssignment;
11189     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
11190     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
11191     return false;
11192   }
11193   if (BO->getOpcode() != BO_Assign) {
11194     ErrorInfo.Error = ErrorTy::NotAnAssignment;
11195     ErrorInfo.ErrorLoc = BO->getExprLoc();
11196     ErrorInfo.NoteLoc = BO->getOperatorLoc();
11197     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
11198     return false;
11199   }
11200 
11201   X = BO->getLHS();
11202 
11203   auto *CO = dyn_cast<ConditionalOperator>(BO->getRHS()->IgnoreParenImpCasts());
11204   if (!CO) {
11205     ErrorInfo.Error = ErrorTy::NotCondOp;
11206     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getRHS()->getExprLoc();
11207     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getRHS()->getSourceRange();
11208     return false;
11209   }
11210 
11211   if (!checkIfTwoExprsAreSame(ContextRef, X, CO->getFalseExpr())) {
11212     ErrorInfo.Error = ErrorTy::WrongFalseExpr;
11213     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getFalseExpr()->getExprLoc();
11214     ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
11215         CO->getFalseExpr()->getSourceRange();
11216     return false;
11217   }
11218 
11219   auto *Cond = dyn_cast<BinaryOperator>(CO->getCond());
11220   if (!Cond) {
11221     ErrorInfo.Error = ErrorTy::NotABinaryOp;
11222     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getCond()->getExprLoc();
11223     ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
11224         CO->getCond()->getSourceRange();
11225     return false;
11226   }
11227 
11228   switch (Cond->getOpcode()) {
11229   case BO_EQ: {
11230     C = Cond;
11231     D = CO->getTrueExpr()->IgnoreImpCasts();
11232     if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
11233       E = Cond->getRHS()->IgnoreImpCasts();
11234     } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11235       E = Cond->getLHS()->IgnoreImpCasts();
11236     } else {
11237       ErrorInfo.Error = ErrorTy::InvalidComparison;
11238       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11239       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11240       return false;
11241     }
11242     break;
11243   }
11244   case BO_LT:
11245   case BO_GT: {
11246     E = CO->getTrueExpr()->IgnoreImpCasts();
11247     if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) &&
11248         checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) {
11249       C = Cond;
11250     } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) &&
11251                checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11252       C = Cond;
11253       IsXBinopExpr = false;
11254     } else {
11255       ErrorInfo.Error = ErrorTy::InvalidComparison;
11256       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11257       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11258       return false;
11259     }
11260     break;
11261   }
11262   default:
11263     ErrorInfo.Error = ErrorTy::InvalidBinaryOp;
11264     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11265     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11266     return false;
11267   }
11268 
11269   return true;
11270 }
11271 
11272 bool OpenMPAtomicCompareChecker::checkType(ErrorInfoTy &ErrorInfo) const {
11273   // 'x' and 'e' cannot be nullptr
11274   assert(X && E && "X and E cannot be nullptr");
11275 
11276   if (!CheckValue(X, ErrorInfo, true))
11277     return false;
11278 
11279   if (!CheckValue(E, ErrorInfo, false))
11280     return false;
11281 
11282   if (D && !CheckValue(D, ErrorInfo, false))
11283     return false;
11284 
11285   return true;
11286 }
11287 
11288 bool OpenMPAtomicCompareChecker::checkStmt(
11289     Stmt *S, OpenMPAtomicCompareChecker::ErrorInfoTy &ErrorInfo) {
11290   auto *CS = dyn_cast<CompoundStmt>(S);
11291   if (CS) {
11292     if (CS->body_empty()) {
11293       ErrorInfo.Error = ErrorTy::NoStmt;
11294       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11295       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11296       return false;
11297     }
11298 
11299     if (CS->size() != 1) {
11300       ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11301       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11302       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11303       return false;
11304     }
11305     S = CS->body_front();
11306   }
11307 
11308   auto Res = false;
11309 
11310   if (auto *IS = dyn_cast<IfStmt>(S)) {
11311     // Check if the statement is in one of the following forms
11312     // (cond-update-stmt):
11313     // if (expr ordop x) { x = expr; }
11314     // if (x ordop expr) { x = expr; }
11315     // if (x == e) { x = d; }
11316     Res = checkCondUpdateStmt(IS, ErrorInfo);
11317   } else {
11318     // Check if the statement is in one of the following forms (cond-expr-stmt):
11319     // x = expr ordop x ? expr : x;
11320     // x = x ordop expr ? expr : x;
11321     // x = x == e ? d : x;
11322     Res = checkCondExprStmt(S, ErrorInfo);
11323   }
11324 
11325   if (!Res)
11326     return false;
11327 
11328   return checkType(ErrorInfo);
11329 }
11330 
11331 class OpenMPAtomicCompareCaptureChecker final
11332     : public OpenMPAtomicCompareChecker {
11333 public:
11334   OpenMPAtomicCompareCaptureChecker(Sema &S) : OpenMPAtomicCompareChecker(S) {}
11335 
11336   Expr *getV() const { return V; }
11337   Expr *getR() const { return R; }
11338   bool isFailOnly() const { return IsFailOnly; }
11339 
11340   /// Check if statement \a S is valid for <tt>atomic compare capture</tt>.
11341   bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo);
11342 
11343 private:
11344   bool checkType(ErrorInfoTy &ErrorInfo);
11345 
11346   // NOTE: Form 3, 4, 5 in the following comments mean the 3rd, 4th, and 5th
11347   // form of 'conditional-update-capture-atomic' structured block on the v5.2
11348   // spec p.p. 82:
11349   // (1) { v = x; cond-update-stmt }
11350   // (2) { cond-update-stmt v = x; }
11351   // (3) if(x == e) { x = d; } else { v = x; }
11352   // (4) { r = x == e; if(r) { x = d; } }
11353   // (5) { r = x == e; if(r) { x = d; } else { v = x; } }
11354 
11355   /// Check if it is valid 'if(x == e) { x = d; } else { v = x; }' (form 3)
11356   bool checkForm3(IfStmt *S, ErrorInfoTy &ErrorInfo);
11357 
11358   /// Check if it is valid '{ r = x == e; if(r) { x = d; } }',
11359   /// or '{ r = x == e; if(r) { x = d; } else { v = x; } }' (form 4 and 5)
11360   bool checkForm45(Stmt *S, ErrorInfoTy &ErrorInfo);
11361 
11362   /// 'v' lvalue part of the source atomic expression.
11363   Expr *V = nullptr;
11364   /// 'r' lvalue part of the source atomic expression.
11365   Expr *R = nullptr;
11366   /// If 'v' is only updated when the comparison fails.
11367   bool IsFailOnly = false;
11368 };
11369 
11370 bool OpenMPAtomicCompareCaptureChecker::checkType(ErrorInfoTy &ErrorInfo) {
11371   if (!OpenMPAtomicCompareChecker::checkType(ErrorInfo))
11372     return false;
11373 
11374   if (V && !CheckValue(V, ErrorInfo, true))
11375     return false;
11376 
11377   if (R && !CheckValue(R, ErrorInfo, true))
11378     return false;
11379 
11380   return true;
11381 }
11382 
11383 bool OpenMPAtomicCompareCaptureChecker::checkForm3(IfStmt *S,
11384                                                    ErrorInfoTy &ErrorInfo) {
11385   IsFailOnly = true;
11386 
11387   auto *Then = S->getThen();
11388   if (auto *CS = dyn_cast<CompoundStmt>(Then)) {
11389     if (CS->body_empty()) {
11390       ErrorInfo.Error = ErrorTy::NoStmt;
11391       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11392       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11393       return false;
11394     }
11395     if (CS->size() > 1) {
11396       ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11397       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11398       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11399       return false;
11400     }
11401     Then = CS->body_front();
11402   }
11403 
11404   auto *BO = dyn_cast<BinaryOperator>(Then);
11405   if (!BO) {
11406     ErrorInfo.Error = ErrorTy::NotAnAssignment;
11407     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc();
11408     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange();
11409     return false;
11410   }
11411   if (BO->getOpcode() != BO_Assign) {
11412     ErrorInfo.Error = ErrorTy::NotAnAssignment;
11413     ErrorInfo.ErrorLoc = BO->getExprLoc();
11414     ErrorInfo.NoteLoc = BO->getOperatorLoc();
11415     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
11416     return false;
11417   }
11418 
11419   X = BO->getLHS();
11420   D = BO->getRHS();
11421 
11422   auto *Cond = dyn_cast<BinaryOperator>(S->getCond());
11423   if (!Cond) {
11424     ErrorInfo.Error = ErrorTy::NotABinaryOp;
11425     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc();
11426     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange();
11427     return false;
11428   }
11429   if (Cond->getOpcode() != BO_EQ) {
11430     ErrorInfo.Error = ErrorTy::NotEQ;
11431     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11432     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11433     return false;
11434   }
11435 
11436   if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) {
11437     E = Cond->getRHS();
11438   } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) {
11439     E = Cond->getLHS();
11440   } else {
11441     ErrorInfo.Error = ErrorTy::InvalidComparison;
11442     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc();
11443     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange();
11444     return false;
11445   }
11446 
11447   C = Cond;
11448 
11449   if (!S->getElse()) {
11450     ErrorInfo.Error = ErrorTy::NoElse;
11451     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
11452     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
11453     return false;
11454   }
11455 
11456   auto *Else = S->getElse();
11457   if (auto *CS = dyn_cast<CompoundStmt>(Else)) {
11458     if (CS->body_empty()) {
11459       ErrorInfo.Error = ErrorTy::NoStmt;
11460       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11461       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11462       return false;
11463     }
11464     if (CS->size() > 1) {
11465       ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11466       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11467       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
11468       return false;
11469     }
11470     Else = CS->body_front();
11471   }
11472 
11473   auto *ElseBO = dyn_cast<BinaryOperator>(Else);
11474   if (!ElseBO) {
11475     ErrorInfo.Error = ErrorTy::NotAnAssignment;
11476     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc();
11477     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange();
11478     return false;
11479   }
11480   if (ElseBO->getOpcode() != BO_Assign) {
11481     ErrorInfo.Error = ErrorTy::NotAnAssignment;
11482     ErrorInfo.ErrorLoc = ElseBO->getExprLoc();
11483     ErrorInfo.NoteLoc = ElseBO->getOperatorLoc();
11484     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange();
11485     return false;
11486   }
11487 
11488   if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) {
11489     ErrorInfo.Error = ErrorTy::InvalidAssignment;
11490     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseBO->getRHS()->getExprLoc();
11491     ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
11492         ElseBO->getRHS()->getSourceRange();
11493     return false;
11494   }
11495 
11496   V = ElseBO->getLHS();
11497 
11498   return checkType(ErrorInfo);
11499 }
11500 
11501 bool OpenMPAtomicCompareCaptureChecker::checkForm45(Stmt *S,
11502                                                     ErrorInfoTy &ErrorInfo) {
11503   // We don't check here as they should be already done before call this
11504   // function.
11505   auto *CS = cast<CompoundStmt>(S);
11506   assert(CS->size() == 2 && "CompoundStmt size is not expected");
11507   auto *S1 = cast<BinaryOperator>(CS->body_front());
11508   auto *S2 = cast<IfStmt>(CS->body_back());
11509   assert(S1->getOpcode() == BO_Assign && "unexpected binary operator");
11510 
11511   if (!checkIfTwoExprsAreSame(ContextRef, S1->getLHS(), S2->getCond())) {
11512     ErrorInfo.Error = ErrorTy::InvalidCondition;
11513     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getCond()->getExprLoc();
11514     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S1->getLHS()->getSourceRange();
11515     return false;
11516   }
11517 
11518   R = S1->getLHS();
11519 
11520   auto *Then = S2->getThen();
11521   if (auto *ThenCS = dyn_cast<CompoundStmt>(Then)) {
11522     if (ThenCS->body_empty()) {
11523       ErrorInfo.Error = ErrorTy::NoStmt;
11524       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc();
11525       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange();
11526       return false;
11527     }
11528     if (ThenCS->size() > 1) {
11529       ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11530       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc();
11531       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange();
11532       return false;
11533     }
11534     Then = ThenCS->body_front();
11535   }
11536 
11537   auto *ThenBO = dyn_cast<BinaryOperator>(Then);
11538   if (!ThenBO) {
11539     ErrorInfo.Error = ErrorTy::NotAnAssignment;
11540     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getBeginLoc();
11541     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S2->getSourceRange();
11542     return false;
11543   }
11544   if (ThenBO->getOpcode() != BO_Assign) {
11545     ErrorInfo.Error = ErrorTy::NotAnAssignment;
11546     ErrorInfo.ErrorLoc = ThenBO->getExprLoc();
11547     ErrorInfo.NoteLoc = ThenBO->getOperatorLoc();
11548     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenBO->getSourceRange();
11549     return false;
11550   }
11551 
11552   X = ThenBO->getLHS();
11553   D = ThenBO->getRHS();
11554 
11555   auto *BO = cast<BinaryOperator>(S1->getRHS()->IgnoreImpCasts());
11556   if (BO->getOpcode() != BO_EQ) {
11557     ErrorInfo.Error = ErrorTy::NotEQ;
11558     ErrorInfo.ErrorLoc = BO->getExprLoc();
11559     ErrorInfo.NoteLoc = BO->getOperatorLoc();
11560     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
11561     return false;
11562   }
11563 
11564   C = BO;
11565 
11566   if (checkIfTwoExprsAreSame(ContextRef, X, BO->getLHS())) {
11567     E = BO->getRHS();
11568   } else if (checkIfTwoExprsAreSame(ContextRef, X, BO->getRHS())) {
11569     E = BO->getLHS();
11570   } else {
11571     ErrorInfo.Error = ErrorTy::InvalidComparison;
11572     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getExprLoc();
11573     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
11574     return false;
11575   }
11576 
11577   if (S2->getElse()) {
11578     IsFailOnly = true;
11579 
11580     auto *Else = S2->getElse();
11581     if (auto *ElseCS = dyn_cast<CompoundStmt>(Else)) {
11582       if (ElseCS->body_empty()) {
11583         ErrorInfo.Error = ErrorTy::NoStmt;
11584         ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc();
11585         ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange();
11586         return false;
11587       }
11588       if (ElseCS->size() > 1) {
11589         ErrorInfo.Error = ErrorTy::MoreThanOneStmt;
11590         ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc();
11591         ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange();
11592         return false;
11593       }
11594       Else = ElseCS->body_front();
11595     }
11596 
11597     auto *ElseBO = dyn_cast<BinaryOperator>(Else);
11598     if (!ElseBO) {
11599       ErrorInfo.Error = ErrorTy::NotAnAssignment;
11600       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc();
11601       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange();
11602       return false;
11603     }
11604     if (ElseBO->getOpcode() != BO_Assign) {
11605       ErrorInfo.Error = ErrorTy::NotAnAssignment;
11606       ErrorInfo.ErrorLoc = ElseBO->getExprLoc();
11607       ErrorInfo.NoteLoc = ElseBO->getOperatorLoc();
11608       ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange();
11609       return false;
11610     }
11611     if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) {
11612       ErrorInfo.Error = ErrorTy::InvalidAssignment;
11613       ErrorInfo.ErrorLoc = ElseBO->getRHS()->getExprLoc();
11614       ErrorInfo.NoteLoc = X->getExprLoc();
11615       ErrorInfo.ErrorRange = ElseBO->getRHS()->getSourceRange();
11616       ErrorInfo.NoteRange = X->getSourceRange();
11617       return false;
11618     }
11619 
11620     V = ElseBO->getLHS();
11621   }
11622 
11623   return checkType(ErrorInfo);
11624 }
11625 
11626 bool OpenMPAtomicCompareCaptureChecker::checkStmt(Stmt *S,
11627                                                   ErrorInfoTy &ErrorInfo) {
11628   // if(x == e) { x = d; } else { v = x; }
11629   if (auto *IS = dyn_cast<IfStmt>(S))
11630     return checkForm3(IS, ErrorInfo);
11631 
11632   auto *CS = dyn_cast<CompoundStmt>(S);
11633   if (!CS) {
11634     ErrorInfo.Error = ErrorTy::NotCompoundStmt;
11635     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc();
11636     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange();
11637     return false;
11638   }
11639   if (CS->body_empty()) {
11640     ErrorInfo.Error = ErrorTy::NoStmt;
11641     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11642     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11643     return false;
11644   }
11645 
11646   // { if(x == e) { x = d; } else { v = x; } }
11647   if (CS->size() == 1) {
11648     auto *IS = dyn_cast<IfStmt>(CS->body_front());
11649     if (!IS) {
11650       ErrorInfo.Error = ErrorTy::NotIfStmt;
11651       ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->body_front()->getBeginLoc();
11652       ErrorInfo.ErrorRange = ErrorInfo.NoteRange =
11653           CS->body_front()->getSourceRange();
11654       return false;
11655     }
11656 
11657     return checkForm3(IS, ErrorInfo);
11658   } else if (CS->size() == 2) {
11659     auto *S1 = CS->body_front();
11660     auto *S2 = CS->body_back();
11661 
11662     Stmt *UpdateStmt = nullptr;
11663     Stmt *CondUpdateStmt = nullptr;
11664 
11665     if (auto *BO = dyn_cast<BinaryOperator>(S1)) {
11666       // { v = x; cond-update-stmt } or form 45.
11667       UpdateStmt = S1;
11668       CondUpdateStmt = S2;
11669       // Check if form 45.
11670       if (dyn_cast<BinaryOperator>(BO->getRHS()->IgnoreImpCasts()) &&
11671           dyn_cast<IfStmt>(S2))
11672         return checkForm45(CS, ErrorInfo);
11673     } else {
11674       // { cond-update-stmt v = x; }
11675       UpdateStmt = S2;
11676       CondUpdateStmt = S1;
11677     }
11678 
11679     auto CheckCondUpdateStmt = [this, &ErrorInfo](Stmt *CUS) {
11680       auto *IS = dyn_cast<IfStmt>(CUS);
11681       if (!IS) {
11682         ErrorInfo.Error = ErrorTy::NotIfStmt;
11683         ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CUS->getBeginLoc();
11684         ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CUS->getSourceRange();
11685         return false;
11686       }
11687 
11688       if (!checkCondUpdateStmt(IS, ErrorInfo))
11689         return false;
11690 
11691       return true;
11692     };
11693 
11694     // CheckUpdateStmt has to be called *after* CheckCondUpdateStmt.
11695     auto CheckUpdateStmt = [this, &ErrorInfo](Stmt *US) {
11696       auto *BO = dyn_cast<BinaryOperator>(US);
11697       if (!BO) {
11698         ErrorInfo.Error = ErrorTy::NotAnAssignment;
11699         ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = US->getBeginLoc();
11700         ErrorInfo.ErrorRange = ErrorInfo.NoteRange = US->getSourceRange();
11701         return false;
11702       }
11703       if (BO->getOpcode() != BO_Assign) {
11704         ErrorInfo.Error = ErrorTy::NotAnAssignment;
11705         ErrorInfo.ErrorLoc = BO->getExprLoc();
11706         ErrorInfo.NoteLoc = BO->getOperatorLoc();
11707         ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange();
11708         return false;
11709       }
11710       if (!checkIfTwoExprsAreSame(ContextRef, this->X, BO->getRHS())) {
11711         ErrorInfo.Error = ErrorTy::InvalidAssignment;
11712         ErrorInfo.ErrorLoc = BO->getRHS()->getExprLoc();
11713         ErrorInfo.NoteLoc = this->X->getExprLoc();
11714         ErrorInfo.ErrorRange = BO->getRHS()->getSourceRange();
11715         ErrorInfo.NoteRange = this->X->getSourceRange();
11716         return false;
11717       }
11718 
11719       this->V = BO->getLHS();
11720 
11721       return true;
11722     };
11723 
11724     if (!CheckCondUpdateStmt(CondUpdateStmt))
11725       return false;
11726     if (!CheckUpdateStmt(UpdateStmt))
11727       return false;
11728   } else {
11729     ErrorInfo.Error = ErrorTy::MoreThanTwoStmts;
11730     ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc();
11731     ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange();
11732     return false;
11733   }
11734 
11735   return checkType(ErrorInfo);
11736 }
11737 } // namespace
11738 
11739 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
11740                                             Stmt *AStmt,
11741                                             SourceLocation StartLoc,
11742                                             SourceLocation EndLoc) {
11743   // Register location of the first atomic directive.
11744   DSAStack->addAtomicDirectiveLoc(StartLoc);
11745   if (!AStmt)
11746     return StmtError();
11747 
11748   // 1.2.2 OpenMP Language Terminology
11749   // Structured block - An executable statement with a single entry at the
11750   // top and a single exit at the bottom.
11751   // The point of exit cannot be a branch out of the structured block.
11752   // longjmp() and throw() must not violate the entry/exit criteria.
11753   OpenMPClauseKind AtomicKind = OMPC_unknown;
11754   SourceLocation AtomicKindLoc;
11755   OpenMPClauseKind MemOrderKind = OMPC_unknown;
11756   SourceLocation MemOrderLoc;
11757   bool MutexClauseEncountered = false;
11758   llvm::SmallSet<OpenMPClauseKind, 2> EncounteredAtomicKinds;
11759   for (const OMPClause *C : Clauses) {
11760     switch (C->getClauseKind()) {
11761     case OMPC_read:
11762     case OMPC_write:
11763     case OMPC_update:
11764       MutexClauseEncountered = true;
11765       LLVM_FALLTHROUGH;
11766     case OMPC_capture:
11767     case OMPC_compare: {
11768       if (AtomicKind != OMPC_unknown && MutexClauseEncountered) {
11769         Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
11770             << SourceRange(C->getBeginLoc(), C->getEndLoc());
11771         Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
11772             << getOpenMPClauseName(AtomicKind);
11773       } else {
11774         AtomicKind = C->getClauseKind();
11775         AtomicKindLoc = C->getBeginLoc();
11776         if (!EncounteredAtomicKinds.insert(C->getClauseKind()).second) {
11777           Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
11778               << SourceRange(C->getBeginLoc(), C->getEndLoc());
11779           Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
11780               << getOpenMPClauseName(AtomicKind);
11781         }
11782       }
11783       break;
11784     }
11785     case OMPC_seq_cst:
11786     case OMPC_acq_rel:
11787     case OMPC_acquire:
11788     case OMPC_release:
11789     case OMPC_relaxed: {
11790       if (MemOrderKind != OMPC_unknown) {
11791         Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
11792             << getOpenMPDirectiveName(OMPD_atomic) << 0
11793             << SourceRange(C->getBeginLoc(), C->getEndLoc());
11794         Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
11795             << getOpenMPClauseName(MemOrderKind);
11796       } else {
11797         MemOrderKind = C->getClauseKind();
11798         MemOrderLoc = C->getBeginLoc();
11799       }
11800       break;
11801     }
11802     // The following clauses are allowed, but we don't need to do anything here.
11803     case OMPC_hint:
11804       break;
11805     default:
11806       llvm_unreachable("unknown clause is encountered");
11807     }
11808   }
11809   bool IsCompareCapture = false;
11810   if (EncounteredAtomicKinds.contains(OMPC_compare) &&
11811       EncounteredAtomicKinds.contains(OMPC_capture)) {
11812     IsCompareCapture = true;
11813     AtomicKind = OMPC_compare;
11814   }
11815   // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions
11816   // If atomic-clause is read then memory-order-clause must not be acq_rel or
11817   // release.
11818   // If atomic-clause is write then memory-order-clause must not be acq_rel or
11819   // acquire.
11820   // If atomic-clause is update or not present then memory-order-clause must not
11821   // be acq_rel or acquire.
11822   if ((AtomicKind == OMPC_read &&
11823        (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) ||
11824       ((AtomicKind == OMPC_write || AtomicKind == OMPC_update ||
11825         AtomicKind == OMPC_unknown) &&
11826        (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) {
11827     SourceLocation Loc = AtomicKindLoc;
11828     if (AtomicKind == OMPC_unknown)
11829       Loc = StartLoc;
11830     Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
11831         << getOpenMPClauseName(AtomicKind)
11832         << (AtomicKind == OMPC_unknown ? 1 : 0)
11833         << getOpenMPClauseName(MemOrderKind);
11834     Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
11835         << getOpenMPClauseName(MemOrderKind);
11836   }
11837 
11838   Stmt *Body = AStmt;
11839   if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
11840     Body = EWC->getSubExpr();
11841 
11842   Expr *X = nullptr;
11843   Expr *V = nullptr;
11844   Expr *E = nullptr;
11845   Expr *UE = nullptr;
11846   Expr *D = nullptr;
11847   Expr *CE = nullptr;
11848   bool IsXLHSInRHSPart = false;
11849   bool IsPostfixUpdate = false;
11850   // OpenMP [2.12.6, atomic Construct]
11851   // In the next expressions:
11852   // * x and v (as applicable) are both l-value expressions with scalar type.
11853   // * During the execution of an atomic region, multiple syntactic
11854   // occurrences of x must designate the same storage location.
11855   // * Neither of v and expr (as applicable) may access the storage location
11856   // designated by x.
11857   // * Neither of x and expr (as applicable) may access the storage location
11858   // designated by v.
11859   // * expr is an expression with scalar type.
11860   // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
11861   // * binop, binop=, ++, and -- are not overloaded operators.
11862   // * The expression x binop expr must be numerically equivalent to x binop
11863   // (expr). This requirement is satisfied if the operators in expr have
11864   // precedence greater than binop, or by using parentheses around expr or
11865   // subexpressions of expr.
11866   // * The expression expr binop x must be numerically equivalent to (expr)
11867   // binop x. This requirement is satisfied if the operators in expr have
11868   // precedence equal to or greater than binop, or by using parentheses around
11869   // expr or subexpressions of expr.
11870   // * For forms that allow multiple occurrences of x, the number of times
11871   // that x is evaluated is unspecified.
11872   if (AtomicKind == OMPC_read) {
11873     enum {
11874       NotAnExpression,
11875       NotAnAssignmentOp,
11876       NotAScalarType,
11877       NotAnLValue,
11878       NoError
11879     } ErrorFound = NoError;
11880     SourceLocation ErrorLoc, NoteLoc;
11881     SourceRange ErrorRange, NoteRange;
11882     // If clause is read:
11883     //  v = x;
11884     if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
11885       const auto *AtomicBinOp =
11886           dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
11887       if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
11888         X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
11889         V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
11890         if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
11891             (V->isInstantiationDependent() || V->getType()->isScalarType())) {
11892           if (!X->isLValue() || !V->isLValue()) {
11893             const Expr *NotLValueExpr = X->isLValue() ? V : X;
11894             ErrorFound = NotAnLValue;
11895             ErrorLoc = AtomicBinOp->getExprLoc();
11896             ErrorRange = AtomicBinOp->getSourceRange();
11897             NoteLoc = NotLValueExpr->getExprLoc();
11898             NoteRange = NotLValueExpr->getSourceRange();
11899           }
11900         } else if (!X->isInstantiationDependent() ||
11901                    !V->isInstantiationDependent()) {
11902           const Expr *NotScalarExpr =
11903               (X->isInstantiationDependent() || X->getType()->isScalarType())
11904                   ? V
11905                   : X;
11906           ErrorFound = NotAScalarType;
11907           ErrorLoc = AtomicBinOp->getExprLoc();
11908           ErrorRange = AtomicBinOp->getSourceRange();
11909           NoteLoc = NotScalarExpr->getExprLoc();
11910           NoteRange = NotScalarExpr->getSourceRange();
11911         }
11912       } else if (!AtomicBody->isInstantiationDependent()) {
11913         ErrorFound = NotAnAssignmentOp;
11914         ErrorLoc = AtomicBody->getExprLoc();
11915         ErrorRange = AtomicBody->getSourceRange();
11916         NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
11917                               : AtomicBody->getExprLoc();
11918         NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
11919                                 : AtomicBody->getSourceRange();
11920       }
11921     } else {
11922       ErrorFound = NotAnExpression;
11923       NoteLoc = ErrorLoc = Body->getBeginLoc();
11924       NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
11925     }
11926     if (ErrorFound != NoError) {
11927       Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
11928           << ErrorRange;
11929       Diag(NoteLoc, diag::note_omp_atomic_read_write)
11930           << ErrorFound << NoteRange;
11931       return StmtError();
11932     }
11933     if (CurContext->isDependentContext())
11934       V = X = nullptr;
11935   } else if (AtomicKind == OMPC_write) {
11936     enum {
11937       NotAnExpression,
11938       NotAnAssignmentOp,
11939       NotAScalarType,
11940       NotAnLValue,
11941       NoError
11942     } ErrorFound = NoError;
11943     SourceLocation ErrorLoc, NoteLoc;
11944     SourceRange ErrorRange, NoteRange;
11945     // If clause is write:
11946     //  x = expr;
11947     if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
11948       const auto *AtomicBinOp =
11949           dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
11950       if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
11951         X = AtomicBinOp->getLHS();
11952         E = AtomicBinOp->getRHS();
11953         if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
11954             (E->isInstantiationDependent() || E->getType()->isScalarType())) {
11955           if (!X->isLValue()) {
11956             ErrorFound = NotAnLValue;
11957             ErrorLoc = AtomicBinOp->getExprLoc();
11958             ErrorRange = AtomicBinOp->getSourceRange();
11959             NoteLoc = X->getExprLoc();
11960             NoteRange = X->getSourceRange();
11961           }
11962         } else if (!X->isInstantiationDependent() ||
11963                    !E->isInstantiationDependent()) {
11964           const Expr *NotScalarExpr =
11965               (X->isInstantiationDependent() || X->getType()->isScalarType())
11966                   ? E
11967                   : X;
11968           ErrorFound = NotAScalarType;
11969           ErrorLoc = AtomicBinOp->getExprLoc();
11970           ErrorRange = AtomicBinOp->getSourceRange();
11971           NoteLoc = NotScalarExpr->getExprLoc();
11972           NoteRange = NotScalarExpr->getSourceRange();
11973         }
11974       } else if (!AtomicBody->isInstantiationDependent()) {
11975         ErrorFound = NotAnAssignmentOp;
11976         ErrorLoc = AtomicBody->getExprLoc();
11977         ErrorRange = AtomicBody->getSourceRange();
11978         NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
11979                               : AtomicBody->getExprLoc();
11980         NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
11981                                 : AtomicBody->getSourceRange();
11982       }
11983     } else {
11984       ErrorFound = NotAnExpression;
11985       NoteLoc = ErrorLoc = Body->getBeginLoc();
11986       NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
11987     }
11988     if (ErrorFound != NoError) {
11989       Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
11990           << ErrorRange;
11991       Diag(NoteLoc, diag::note_omp_atomic_read_write)
11992           << ErrorFound << NoteRange;
11993       return StmtError();
11994     }
11995     if (CurContext->isDependentContext())
11996       E = X = nullptr;
11997   } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
11998     // If clause is update:
11999     //  x++;
12000     //  x--;
12001     //  ++x;
12002     //  --x;
12003     //  x binop= expr;
12004     //  x = x binop expr;
12005     //  x = expr binop x;
12006     OpenMPAtomicUpdateChecker Checker(*this);
12007     if (Checker.checkStatement(
12008             Body,
12009             (AtomicKind == OMPC_update)
12010                 ? diag::err_omp_atomic_update_not_expression_statement
12011                 : diag::err_omp_atomic_not_expression_statement,
12012             diag::note_omp_atomic_update))
12013       return StmtError();
12014     if (!CurContext->isDependentContext()) {
12015       E = Checker.getExpr();
12016       X = Checker.getX();
12017       UE = Checker.getUpdateExpr();
12018       IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12019     }
12020   } else if (AtomicKind == OMPC_capture) {
12021     enum {
12022       NotAnAssignmentOp,
12023       NotACompoundStatement,
12024       NotTwoSubstatements,
12025       NotASpecificExpression,
12026       NoError
12027     } ErrorFound = NoError;
12028     SourceLocation ErrorLoc, NoteLoc;
12029     SourceRange ErrorRange, NoteRange;
12030     if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
12031       // If clause is a capture:
12032       //  v = x++;
12033       //  v = x--;
12034       //  v = ++x;
12035       //  v = --x;
12036       //  v = x binop= expr;
12037       //  v = x = x binop expr;
12038       //  v = x = expr binop x;
12039       const auto *AtomicBinOp =
12040           dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
12041       if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
12042         V = AtomicBinOp->getLHS();
12043         Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
12044         OpenMPAtomicUpdateChecker Checker(*this);
12045         if (Checker.checkStatement(
12046                 Body, diag::err_omp_atomic_capture_not_expression_statement,
12047                 diag::note_omp_atomic_update))
12048           return StmtError();
12049         E = Checker.getExpr();
12050         X = Checker.getX();
12051         UE = Checker.getUpdateExpr();
12052         IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12053         IsPostfixUpdate = Checker.isPostfixUpdate();
12054       } else if (!AtomicBody->isInstantiationDependent()) {
12055         ErrorLoc = AtomicBody->getExprLoc();
12056         ErrorRange = AtomicBody->getSourceRange();
12057         NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
12058                               : AtomicBody->getExprLoc();
12059         NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
12060                                 : AtomicBody->getSourceRange();
12061         ErrorFound = NotAnAssignmentOp;
12062       }
12063       if (ErrorFound != NoError) {
12064         Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
12065             << ErrorRange;
12066         Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
12067         return StmtError();
12068       }
12069       if (CurContext->isDependentContext())
12070         UE = V = E = X = nullptr;
12071     } else {
12072       // If clause is a capture:
12073       //  { v = x; x = expr; }
12074       //  { v = x; x++; }
12075       //  { v = x; x--; }
12076       //  { v = x; ++x; }
12077       //  { v = x; --x; }
12078       //  { v = x; x binop= expr; }
12079       //  { v = x; x = x binop expr; }
12080       //  { v = x; x = expr binop x; }
12081       //  { x++; v = x; }
12082       //  { x--; v = x; }
12083       //  { ++x; v = x; }
12084       //  { --x; v = x; }
12085       //  { x binop= expr; v = x; }
12086       //  { x = x binop expr; v = x; }
12087       //  { x = expr binop x; v = x; }
12088       if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
12089         // Check that this is { expr1; expr2; }
12090         if (CS->size() == 2) {
12091           Stmt *First = CS->body_front();
12092           Stmt *Second = CS->body_back();
12093           if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
12094             First = EWC->getSubExpr()->IgnoreParenImpCasts();
12095           if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
12096             Second = EWC->getSubExpr()->IgnoreParenImpCasts();
12097           // Need to find what subexpression is 'v' and what is 'x'.
12098           OpenMPAtomicUpdateChecker Checker(*this);
12099           bool IsUpdateExprFound = !Checker.checkStatement(Second);
12100           BinaryOperator *BinOp = nullptr;
12101           if (IsUpdateExprFound) {
12102             BinOp = dyn_cast<BinaryOperator>(First);
12103             IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
12104           }
12105           if (IsUpdateExprFound && !CurContext->isDependentContext()) {
12106             //  { v = x; x++; }
12107             //  { v = x; x--; }
12108             //  { v = x; ++x; }
12109             //  { v = x; --x; }
12110             //  { v = x; x binop= expr; }
12111             //  { v = x; x = x binop expr; }
12112             //  { v = x; x = expr binop x; }
12113             // Check that the first expression has form v = x.
12114             Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
12115             llvm::FoldingSetNodeID XId, PossibleXId;
12116             Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
12117             PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
12118             IsUpdateExprFound = XId == PossibleXId;
12119             if (IsUpdateExprFound) {
12120               V = BinOp->getLHS();
12121               X = Checker.getX();
12122               E = Checker.getExpr();
12123               UE = Checker.getUpdateExpr();
12124               IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12125               IsPostfixUpdate = true;
12126             }
12127           }
12128           if (!IsUpdateExprFound) {
12129             IsUpdateExprFound = !Checker.checkStatement(First);
12130             BinOp = nullptr;
12131             if (IsUpdateExprFound) {
12132               BinOp = dyn_cast<BinaryOperator>(Second);
12133               IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
12134             }
12135             if (IsUpdateExprFound && !CurContext->isDependentContext()) {
12136               //  { x++; v = x; }
12137               //  { x--; v = x; }
12138               //  { ++x; v = x; }
12139               //  { --x; v = x; }
12140               //  { x binop= expr; v = x; }
12141               //  { x = x binop expr; v = x; }
12142               //  { x = expr binop x; v = x; }
12143               // Check that the second expression has form v = x.
12144               Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
12145               llvm::FoldingSetNodeID XId, PossibleXId;
12146               Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
12147               PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
12148               IsUpdateExprFound = XId == PossibleXId;
12149               if (IsUpdateExprFound) {
12150                 V = BinOp->getLHS();
12151                 X = Checker.getX();
12152                 E = Checker.getExpr();
12153                 UE = Checker.getUpdateExpr();
12154                 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
12155                 IsPostfixUpdate = false;
12156               }
12157             }
12158           }
12159           if (!IsUpdateExprFound) {
12160             //  { v = x; x = expr; }
12161             auto *FirstExpr = dyn_cast<Expr>(First);
12162             auto *SecondExpr = dyn_cast<Expr>(Second);
12163             if (!FirstExpr || !SecondExpr ||
12164                 !(FirstExpr->isInstantiationDependent() ||
12165                   SecondExpr->isInstantiationDependent())) {
12166               auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
12167               if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
12168                 ErrorFound = NotAnAssignmentOp;
12169                 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
12170                                                 : First->getBeginLoc();
12171                 NoteRange = ErrorRange = FirstBinOp
12172                                              ? FirstBinOp->getSourceRange()
12173                                              : SourceRange(ErrorLoc, ErrorLoc);
12174               } else {
12175                 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
12176                 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
12177                   ErrorFound = NotAnAssignmentOp;
12178                   NoteLoc = ErrorLoc = SecondBinOp
12179                                            ? SecondBinOp->getOperatorLoc()
12180                                            : Second->getBeginLoc();
12181                   NoteRange = ErrorRange =
12182                       SecondBinOp ? SecondBinOp->getSourceRange()
12183                                   : SourceRange(ErrorLoc, ErrorLoc);
12184                 } else {
12185                   Expr *PossibleXRHSInFirst =
12186                       FirstBinOp->getRHS()->IgnoreParenImpCasts();
12187                   Expr *PossibleXLHSInSecond =
12188                       SecondBinOp->getLHS()->IgnoreParenImpCasts();
12189                   llvm::FoldingSetNodeID X1Id, X2Id;
12190                   PossibleXRHSInFirst->Profile(X1Id, Context,
12191                                                /*Canonical=*/true);
12192                   PossibleXLHSInSecond->Profile(X2Id, Context,
12193                                                 /*Canonical=*/true);
12194                   IsUpdateExprFound = X1Id == X2Id;
12195                   if (IsUpdateExprFound) {
12196                     V = FirstBinOp->getLHS();
12197                     X = SecondBinOp->getLHS();
12198                     E = SecondBinOp->getRHS();
12199                     UE = nullptr;
12200                     IsXLHSInRHSPart = false;
12201                     IsPostfixUpdate = true;
12202                   } else {
12203                     ErrorFound = NotASpecificExpression;
12204                     ErrorLoc = FirstBinOp->getExprLoc();
12205                     ErrorRange = FirstBinOp->getSourceRange();
12206                     NoteLoc = SecondBinOp->getLHS()->getExprLoc();
12207                     NoteRange = SecondBinOp->getRHS()->getSourceRange();
12208                   }
12209                 }
12210               }
12211             }
12212           }
12213         } else {
12214           NoteLoc = ErrorLoc = Body->getBeginLoc();
12215           NoteRange = ErrorRange =
12216               SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
12217           ErrorFound = NotTwoSubstatements;
12218         }
12219       } else {
12220         NoteLoc = ErrorLoc = Body->getBeginLoc();
12221         NoteRange = ErrorRange =
12222             SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
12223         ErrorFound = NotACompoundStatement;
12224       }
12225     }
12226     if (ErrorFound != NoError) {
12227       Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
12228           << ErrorRange;
12229       Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
12230       return StmtError();
12231     }
12232     if (CurContext->isDependentContext())
12233       UE = V = E = X = nullptr;
12234   } else if (AtomicKind == OMPC_compare) {
12235     if (IsCompareCapture) {
12236       OpenMPAtomicCompareCaptureChecker::ErrorInfoTy ErrorInfo;
12237       OpenMPAtomicCompareCaptureChecker Checker(*this);
12238       if (!Checker.checkStmt(Body, ErrorInfo)) {
12239         Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare_capture)
12240             << ErrorInfo.ErrorRange;
12241         Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare)
12242             << ErrorInfo.Error << ErrorInfo.NoteRange;
12243         return StmtError();
12244       }
12245       // TODO: We don't set X, D, E, etc. here because in code gen we will emit
12246       // error directly.
12247     } else {
12248       OpenMPAtomicCompareChecker::ErrorInfoTy ErrorInfo;
12249       OpenMPAtomicCompareChecker Checker(*this);
12250       if (!Checker.checkStmt(Body, ErrorInfo)) {
12251         Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare)
12252             << ErrorInfo.ErrorRange;
12253         Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare)
12254             << ErrorInfo.Error << ErrorInfo.NoteRange;
12255         return StmtError();
12256       }
12257       X = Checker.getX();
12258       E = Checker.getE();
12259       D = Checker.getD();
12260       CE = Checker.getCond();
12261       // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'.
12262       IsXLHSInRHSPart = Checker.isXBinopExpr();
12263     }
12264   }
12265 
12266   setFunctionHasBranchProtectedScope();
12267 
12268   return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
12269                                     X, V, E, UE, D, CE, IsXLHSInRHSPart,
12270                                     IsPostfixUpdate);
12271 }
12272 
12273 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
12274                                             Stmt *AStmt,
12275                                             SourceLocation StartLoc,
12276                                             SourceLocation EndLoc) {
12277   if (!AStmt)
12278     return StmtError();
12279 
12280   auto *CS = cast<CapturedStmt>(AStmt);
12281   // 1.2.2 OpenMP Language Terminology
12282   // Structured block - An executable statement with a single entry at the
12283   // top and a single exit at the bottom.
12284   // The point of exit cannot be a branch out of the structured block.
12285   // longjmp() and throw() must not violate the entry/exit criteria.
12286   CS->getCapturedDecl()->setNothrow();
12287   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
12288        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12289     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12290     // 1.2.2 OpenMP Language Terminology
12291     // Structured block - An executable statement with a single entry at the
12292     // top and a single exit at the bottom.
12293     // The point of exit cannot be a branch out of the structured block.
12294     // longjmp() and throw() must not violate the entry/exit criteria.
12295     CS->getCapturedDecl()->setNothrow();
12296   }
12297 
12298   // OpenMP [2.16, Nesting of Regions]
12299   // If specified, a teams construct must be contained within a target
12300   // construct. That target construct must contain no statements or directives
12301   // outside of the teams construct.
12302   if (DSAStack->hasInnerTeamsRegion()) {
12303     const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
12304     bool OMPTeamsFound = true;
12305     if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
12306       auto I = CS->body_begin();
12307       while (I != CS->body_end()) {
12308         const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
12309         if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) ||
12310             OMPTeamsFound) {
12311 
12312           OMPTeamsFound = false;
12313           break;
12314         }
12315         ++I;
12316       }
12317       assert(I != CS->body_end() && "Not found statement");
12318       S = *I;
12319     } else {
12320       const auto *OED = dyn_cast<OMPExecutableDirective>(S);
12321       OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
12322     }
12323     if (!OMPTeamsFound) {
12324       Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
12325       Diag(DSAStack->getInnerTeamsRegionLoc(),
12326            diag::note_omp_nested_teams_construct_here);
12327       Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
12328           << isa<OMPExecutableDirective>(S);
12329       return StmtError();
12330     }
12331   }
12332 
12333   setFunctionHasBranchProtectedScope();
12334 
12335   return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
12336 }
12337 
12338 StmtResult
12339 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
12340                                          Stmt *AStmt, SourceLocation StartLoc,
12341                                          SourceLocation EndLoc) {
12342   if (!AStmt)
12343     return StmtError();
12344 
12345   auto *CS = cast<CapturedStmt>(AStmt);
12346   // 1.2.2 OpenMP Language Terminology
12347   // Structured block - An executable statement with a single entry at the
12348   // top and a single exit at the bottom.
12349   // The point of exit cannot be a branch out of the structured block.
12350   // longjmp() and throw() must not violate the entry/exit criteria.
12351   CS->getCapturedDecl()->setNothrow();
12352   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
12353        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12354     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12355     // 1.2.2 OpenMP Language Terminology
12356     // Structured block - An executable statement with a single entry at the
12357     // top and a single exit at the bottom.
12358     // The point of exit cannot be a branch out of the structured block.
12359     // longjmp() and throw() must not violate the entry/exit criteria.
12360     CS->getCapturedDecl()->setNothrow();
12361   }
12362 
12363   setFunctionHasBranchProtectedScope();
12364 
12365   return OMPTargetParallelDirective::Create(
12366       Context, StartLoc, EndLoc, Clauses, AStmt,
12367       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
12368 }
12369 
12370 StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
12371     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12372     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12373   if (!AStmt)
12374     return StmtError();
12375 
12376   auto *CS = cast<CapturedStmt>(AStmt);
12377   // 1.2.2 OpenMP Language Terminology
12378   // Structured block - An executable statement with a single entry at the
12379   // top and a single exit at the bottom.
12380   // The point of exit cannot be a branch out of the structured block.
12381   // longjmp() and throw() must not violate the entry/exit criteria.
12382   CS->getCapturedDecl()->setNothrow();
12383   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
12384        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12385     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12386     // 1.2.2 OpenMP Language Terminology
12387     // Structured block - An executable statement with a single entry at the
12388     // top and a single exit at the bottom.
12389     // The point of exit cannot be a branch out of the structured block.
12390     // longjmp() and throw() must not violate the entry/exit criteria.
12391     CS->getCapturedDecl()->setNothrow();
12392   }
12393 
12394   OMPLoopBasedDirective::HelperExprs B;
12395   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
12396   // define the nested loops number.
12397   unsigned NestedLoopCount =
12398       checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
12399                       getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
12400                       VarsWithImplicitDSA, B);
12401   if (NestedLoopCount == 0)
12402     return StmtError();
12403 
12404   assert((CurContext->isDependentContext() || B.builtAll()) &&
12405          "omp target parallel for loop exprs were not built");
12406 
12407   if (!CurContext->isDependentContext()) {
12408     // Finalize the clauses that need pre-built expressions for CodeGen.
12409     for (OMPClause *C : Clauses) {
12410       if (auto *LC = dyn_cast<OMPLinearClause>(C))
12411         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12412                                      B.NumIterations, *this, CurScope,
12413                                      DSAStack))
12414           return StmtError();
12415     }
12416   }
12417 
12418   setFunctionHasBranchProtectedScope();
12419   return OMPTargetParallelForDirective::Create(
12420       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
12421       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
12422 }
12423 
12424 /// Check for existence of a map clause in the list of clauses.
12425 static bool hasClauses(ArrayRef<OMPClause *> Clauses,
12426                        const OpenMPClauseKind K) {
12427   return llvm::any_of(
12428       Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
12429 }
12430 
12431 template <typename... Params>
12432 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
12433                        const Params... ClauseTypes) {
12434   return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
12435 }
12436 
12437 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
12438                                                 Stmt *AStmt,
12439                                                 SourceLocation StartLoc,
12440                                                 SourceLocation EndLoc) {
12441   if (!AStmt)
12442     return StmtError();
12443 
12444   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
12445 
12446   // OpenMP [2.12.2, target data Construct, Restrictions]
12447   // At least one map, use_device_addr or use_device_ptr clause must appear on
12448   // the directive.
12449   if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) &&
12450       (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) {
12451     StringRef Expected;
12452     if (LangOpts.OpenMP < 50)
12453       Expected = "'map' or 'use_device_ptr'";
12454     else
12455       Expected = "'map', 'use_device_ptr', or 'use_device_addr'";
12456     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
12457         << Expected << getOpenMPDirectiveName(OMPD_target_data);
12458     return StmtError();
12459   }
12460 
12461   setFunctionHasBranchProtectedScope();
12462 
12463   return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
12464                                         AStmt);
12465 }
12466 
12467 StmtResult
12468 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
12469                                           SourceLocation StartLoc,
12470                                           SourceLocation EndLoc, Stmt *AStmt) {
12471   if (!AStmt)
12472     return StmtError();
12473 
12474   auto *CS = cast<CapturedStmt>(AStmt);
12475   // 1.2.2 OpenMP Language Terminology
12476   // Structured block - An executable statement with a single entry at the
12477   // top and a single exit at the bottom.
12478   // The point of exit cannot be a branch out of the structured block.
12479   // longjmp() and throw() must not violate the entry/exit criteria.
12480   CS->getCapturedDecl()->setNothrow();
12481   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
12482        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12483     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12484     // 1.2.2 OpenMP Language Terminology
12485     // Structured block - An executable statement with a single entry at the
12486     // top and a single exit at the bottom.
12487     // The point of exit cannot be a branch out of the structured block.
12488     // longjmp() and throw() must not violate the entry/exit criteria.
12489     CS->getCapturedDecl()->setNothrow();
12490   }
12491 
12492   // OpenMP [2.10.2, Restrictions, p. 99]
12493   // At least one map clause must appear on the directive.
12494   if (!hasClauses(Clauses, OMPC_map)) {
12495     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
12496         << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
12497     return StmtError();
12498   }
12499 
12500   return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
12501                                              AStmt);
12502 }
12503 
12504 StmtResult
12505 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
12506                                          SourceLocation StartLoc,
12507                                          SourceLocation EndLoc, Stmt *AStmt) {
12508   if (!AStmt)
12509     return StmtError();
12510 
12511   auto *CS = cast<CapturedStmt>(AStmt);
12512   // 1.2.2 OpenMP Language Terminology
12513   // Structured block - An executable statement with a single entry at the
12514   // top and a single exit at the bottom.
12515   // The point of exit cannot be a branch out of the structured block.
12516   // longjmp() and throw() must not violate the entry/exit criteria.
12517   CS->getCapturedDecl()->setNothrow();
12518   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
12519        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12520     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12521     // 1.2.2 OpenMP Language Terminology
12522     // Structured block - An executable statement with a single entry at the
12523     // top and a single exit at the bottom.
12524     // The point of exit cannot be a branch out of the structured block.
12525     // longjmp() and throw() must not violate the entry/exit criteria.
12526     CS->getCapturedDecl()->setNothrow();
12527   }
12528 
12529   // OpenMP [2.10.3, Restrictions, p. 102]
12530   // At least one map clause must appear on the directive.
12531   if (!hasClauses(Clauses, OMPC_map)) {
12532     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
12533         << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
12534     return StmtError();
12535   }
12536 
12537   return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
12538                                             AStmt);
12539 }
12540 
12541 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
12542                                                   SourceLocation StartLoc,
12543                                                   SourceLocation EndLoc,
12544                                                   Stmt *AStmt) {
12545   if (!AStmt)
12546     return StmtError();
12547 
12548   auto *CS = cast<CapturedStmt>(AStmt);
12549   // 1.2.2 OpenMP Language Terminology
12550   // Structured block - An executable statement with a single entry at the
12551   // top and a single exit at the bottom.
12552   // The point of exit cannot be a branch out of the structured block.
12553   // longjmp() and throw() must not violate the entry/exit criteria.
12554   CS->getCapturedDecl()->setNothrow();
12555   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
12556        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12557     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12558     // 1.2.2 OpenMP Language Terminology
12559     // Structured block - An executable statement with a single entry at the
12560     // top and a single exit at the bottom.
12561     // The point of exit cannot be a branch out of the structured block.
12562     // longjmp() and throw() must not violate the entry/exit criteria.
12563     CS->getCapturedDecl()->setNothrow();
12564   }
12565 
12566   if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
12567     Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
12568     return StmtError();
12569   }
12570   return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
12571                                           AStmt);
12572 }
12573 
12574 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
12575                                            Stmt *AStmt, SourceLocation StartLoc,
12576                                            SourceLocation EndLoc) {
12577   if (!AStmt)
12578     return StmtError();
12579 
12580   auto *CS = cast<CapturedStmt>(AStmt);
12581   // 1.2.2 OpenMP Language Terminology
12582   // Structured block - An executable statement with a single entry at the
12583   // top and a single exit at the bottom.
12584   // The point of exit cannot be a branch out of the structured block.
12585   // longjmp() and throw() must not violate the entry/exit criteria.
12586   CS->getCapturedDecl()->setNothrow();
12587 
12588   setFunctionHasBranchProtectedScope();
12589 
12590   DSAStack->setParentTeamsRegionLoc(StartLoc);
12591 
12592   return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
12593 }
12594 
12595 StmtResult
12596 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
12597                                             SourceLocation EndLoc,
12598                                             OpenMPDirectiveKind CancelRegion) {
12599   if (DSAStack->isParentNowaitRegion()) {
12600     Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
12601     return StmtError();
12602   }
12603   if (DSAStack->isParentOrderedRegion()) {
12604     Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
12605     return StmtError();
12606   }
12607   return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
12608                                                CancelRegion);
12609 }
12610 
12611 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
12612                                             SourceLocation StartLoc,
12613                                             SourceLocation EndLoc,
12614                                             OpenMPDirectiveKind CancelRegion) {
12615   if (DSAStack->isParentNowaitRegion()) {
12616     Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
12617     return StmtError();
12618   }
12619   if (DSAStack->isParentOrderedRegion()) {
12620     Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
12621     return StmtError();
12622   }
12623   DSAStack->setParentCancelRegion(/*Cancel=*/true);
12624   return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
12625                                     CancelRegion);
12626 }
12627 
12628 static bool checkReductionClauseWithNogroup(Sema &S,
12629                                             ArrayRef<OMPClause *> Clauses) {
12630   const OMPClause *ReductionClause = nullptr;
12631   const OMPClause *NogroupClause = nullptr;
12632   for (const OMPClause *C : Clauses) {
12633     if (C->getClauseKind() == OMPC_reduction) {
12634       ReductionClause = C;
12635       if (NogroupClause)
12636         break;
12637       continue;
12638     }
12639     if (C->getClauseKind() == OMPC_nogroup) {
12640       NogroupClause = C;
12641       if (ReductionClause)
12642         break;
12643       continue;
12644     }
12645   }
12646   if (ReductionClause && NogroupClause) {
12647     S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
12648         << SourceRange(NogroupClause->getBeginLoc(),
12649                        NogroupClause->getEndLoc());
12650     return true;
12651   }
12652   return false;
12653 }
12654 
12655 StmtResult Sema::ActOnOpenMPTaskLoopDirective(
12656     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12657     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12658   if (!AStmt)
12659     return StmtError();
12660 
12661   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
12662   OMPLoopBasedDirective::HelperExprs B;
12663   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
12664   // define the nested loops number.
12665   unsigned NestedLoopCount =
12666       checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
12667                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
12668                       VarsWithImplicitDSA, B);
12669   if (NestedLoopCount == 0)
12670     return StmtError();
12671 
12672   assert((CurContext->isDependentContext() || B.builtAll()) &&
12673          "omp for loop exprs were not built");
12674 
12675   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
12676   // The grainsize clause and num_tasks clause are mutually exclusive and may
12677   // not appear on the same taskloop directive.
12678   if (checkMutuallyExclusiveClauses(*this, Clauses,
12679                                     {OMPC_grainsize, OMPC_num_tasks}))
12680     return StmtError();
12681   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
12682   // If a reduction clause is present on the taskloop directive, the nogroup
12683   // clause must not be specified.
12684   if (checkReductionClauseWithNogroup(*this, Clauses))
12685     return StmtError();
12686 
12687   setFunctionHasBranchProtectedScope();
12688   return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
12689                                       NestedLoopCount, Clauses, AStmt, B,
12690                                       DSAStack->isCancelRegion());
12691 }
12692 
12693 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
12694     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12695     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12696   if (!AStmt)
12697     return StmtError();
12698 
12699   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
12700   OMPLoopBasedDirective::HelperExprs B;
12701   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
12702   // define the nested loops number.
12703   unsigned NestedLoopCount =
12704       checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
12705                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
12706                       VarsWithImplicitDSA, B);
12707   if (NestedLoopCount == 0)
12708     return StmtError();
12709 
12710   assert((CurContext->isDependentContext() || B.builtAll()) &&
12711          "omp for loop exprs were not built");
12712 
12713   if (!CurContext->isDependentContext()) {
12714     // Finalize the clauses that need pre-built expressions for CodeGen.
12715     for (OMPClause *C : Clauses) {
12716       if (auto *LC = dyn_cast<OMPLinearClause>(C))
12717         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12718                                      B.NumIterations, *this, CurScope,
12719                                      DSAStack))
12720           return StmtError();
12721     }
12722   }
12723 
12724   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
12725   // The grainsize clause and num_tasks clause are mutually exclusive and may
12726   // not appear on the same taskloop directive.
12727   if (checkMutuallyExclusiveClauses(*this, Clauses,
12728                                     {OMPC_grainsize, OMPC_num_tasks}))
12729     return StmtError();
12730   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
12731   // If a reduction clause is present on the taskloop directive, the nogroup
12732   // clause must not be specified.
12733   if (checkReductionClauseWithNogroup(*this, Clauses))
12734     return StmtError();
12735   if (checkSimdlenSafelenSpecified(*this, Clauses))
12736     return StmtError();
12737 
12738   setFunctionHasBranchProtectedScope();
12739   return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
12740                                           NestedLoopCount, Clauses, AStmt, B);
12741 }
12742 
12743 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective(
12744     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12745     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12746   if (!AStmt)
12747     return StmtError();
12748 
12749   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
12750   OMPLoopBasedDirective::HelperExprs B;
12751   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
12752   // define the nested loops number.
12753   unsigned NestedLoopCount =
12754       checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses),
12755                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
12756                       VarsWithImplicitDSA, B);
12757   if (NestedLoopCount == 0)
12758     return StmtError();
12759 
12760   assert((CurContext->isDependentContext() || B.builtAll()) &&
12761          "omp for loop exprs were not built");
12762 
12763   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
12764   // The grainsize clause and num_tasks clause are mutually exclusive and may
12765   // not appear on the same taskloop directive.
12766   if (checkMutuallyExclusiveClauses(*this, Clauses,
12767                                     {OMPC_grainsize, OMPC_num_tasks}))
12768     return StmtError();
12769   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
12770   // If a reduction clause is present on the taskloop directive, the nogroup
12771   // clause must not be specified.
12772   if (checkReductionClauseWithNogroup(*this, Clauses))
12773     return StmtError();
12774 
12775   setFunctionHasBranchProtectedScope();
12776   return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc,
12777                                             NestedLoopCount, Clauses, AStmt, B,
12778                                             DSAStack->isCancelRegion());
12779 }
12780 
12781 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective(
12782     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12783     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12784   if (!AStmt)
12785     return StmtError();
12786 
12787   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
12788   OMPLoopBasedDirective::HelperExprs B;
12789   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
12790   // define the nested loops number.
12791   unsigned NestedLoopCount =
12792       checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses),
12793                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
12794                       VarsWithImplicitDSA, B);
12795   if (NestedLoopCount == 0)
12796     return StmtError();
12797 
12798   assert((CurContext->isDependentContext() || B.builtAll()) &&
12799          "omp for loop exprs were not built");
12800 
12801   if (!CurContext->isDependentContext()) {
12802     // Finalize the clauses that need pre-built expressions for CodeGen.
12803     for (OMPClause *C : Clauses) {
12804       if (auto *LC = dyn_cast<OMPLinearClause>(C))
12805         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12806                                      B.NumIterations, *this, CurScope,
12807                                      DSAStack))
12808           return StmtError();
12809     }
12810   }
12811 
12812   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
12813   // The grainsize clause and num_tasks clause are mutually exclusive and may
12814   // not appear on the same taskloop directive.
12815   if (checkMutuallyExclusiveClauses(*this, Clauses,
12816                                     {OMPC_grainsize, OMPC_num_tasks}))
12817     return StmtError();
12818   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
12819   // If a reduction clause is present on the taskloop directive, the nogroup
12820   // clause must not be specified.
12821   if (checkReductionClauseWithNogroup(*this, Clauses))
12822     return StmtError();
12823   if (checkSimdlenSafelenSpecified(*this, Clauses))
12824     return StmtError();
12825 
12826   setFunctionHasBranchProtectedScope();
12827   return OMPMasterTaskLoopSimdDirective::Create(
12828       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12829 }
12830 
12831 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective(
12832     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12833     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12834   if (!AStmt)
12835     return StmtError();
12836 
12837   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
12838   auto *CS = cast<CapturedStmt>(AStmt);
12839   // 1.2.2 OpenMP Language Terminology
12840   // Structured block - An executable statement with a single entry at the
12841   // top and a single exit at the bottom.
12842   // The point of exit cannot be a branch out of the structured block.
12843   // longjmp() and throw() must not violate the entry/exit criteria.
12844   CS->getCapturedDecl()->setNothrow();
12845   for (int ThisCaptureLevel =
12846            getOpenMPCaptureLevels(OMPD_parallel_master_taskloop);
12847        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12848     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12849     // 1.2.2 OpenMP Language Terminology
12850     // Structured block - An executable statement with a single entry at the
12851     // top and a single exit at the bottom.
12852     // The point of exit cannot be a branch out of the structured block.
12853     // longjmp() and throw() must not violate the entry/exit criteria.
12854     CS->getCapturedDecl()->setNothrow();
12855   }
12856 
12857   OMPLoopBasedDirective::HelperExprs B;
12858   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
12859   // define the nested loops number.
12860   unsigned NestedLoopCount = checkOpenMPLoop(
12861       OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses),
12862       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
12863       VarsWithImplicitDSA, B);
12864   if (NestedLoopCount == 0)
12865     return StmtError();
12866 
12867   assert((CurContext->isDependentContext() || B.builtAll()) &&
12868          "omp for loop exprs were not built");
12869 
12870   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
12871   // The grainsize clause and num_tasks clause are mutually exclusive and may
12872   // not appear on the same taskloop directive.
12873   if (checkMutuallyExclusiveClauses(*this, Clauses,
12874                                     {OMPC_grainsize, OMPC_num_tasks}))
12875     return StmtError();
12876   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
12877   // If a reduction clause is present on the taskloop directive, the nogroup
12878   // clause must not be specified.
12879   if (checkReductionClauseWithNogroup(*this, Clauses))
12880     return StmtError();
12881 
12882   setFunctionHasBranchProtectedScope();
12883   return OMPParallelMasterTaskLoopDirective::Create(
12884       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
12885       DSAStack->isCancelRegion());
12886 }
12887 
12888 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective(
12889     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12890     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12891   if (!AStmt)
12892     return StmtError();
12893 
12894   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
12895   auto *CS = cast<CapturedStmt>(AStmt);
12896   // 1.2.2 OpenMP Language Terminology
12897   // Structured block - An executable statement with a single entry at the
12898   // top and a single exit at the bottom.
12899   // The point of exit cannot be a branch out of the structured block.
12900   // longjmp() and throw() must not violate the entry/exit criteria.
12901   CS->getCapturedDecl()->setNothrow();
12902   for (int ThisCaptureLevel =
12903            getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd);
12904        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12905     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12906     // 1.2.2 OpenMP Language Terminology
12907     // Structured block - An executable statement with a single entry at the
12908     // top and a single exit at the bottom.
12909     // The point of exit cannot be a branch out of the structured block.
12910     // longjmp() and throw() must not violate the entry/exit criteria.
12911     CS->getCapturedDecl()->setNothrow();
12912   }
12913 
12914   OMPLoopBasedDirective::HelperExprs B;
12915   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
12916   // define the nested loops number.
12917   unsigned NestedLoopCount = checkOpenMPLoop(
12918       OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses),
12919       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
12920       VarsWithImplicitDSA, B);
12921   if (NestedLoopCount == 0)
12922     return StmtError();
12923 
12924   assert((CurContext->isDependentContext() || B.builtAll()) &&
12925          "omp for loop exprs were not built");
12926 
12927   if (!CurContext->isDependentContext()) {
12928     // Finalize the clauses that need pre-built expressions for CodeGen.
12929     for (OMPClause *C : Clauses) {
12930       if (auto *LC = dyn_cast<OMPLinearClause>(C))
12931         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12932                                      B.NumIterations, *this, CurScope,
12933                                      DSAStack))
12934           return StmtError();
12935     }
12936   }
12937 
12938   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
12939   // The grainsize clause and num_tasks clause are mutually exclusive and may
12940   // not appear on the same taskloop directive.
12941   if (checkMutuallyExclusiveClauses(*this, Clauses,
12942                                     {OMPC_grainsize, OMPC_num_tasks}))
12943     return StmtError();
12944   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
12945   // If a reduction clause is present on the taskloop directive, the nogroup
12946   // clause must not be specified.
12947   if (checkReductionClauseWithNogroup(*this, Clauses))
12948     return StmtError();
12949   if (checkSimdlenSafelenSpecified(*this, Clauses))
12950     return StmtError();
12951 
12952   setFunctionHasBranchProtectedScope();
12953   return OMPParallelMasterTaskLoopSimdDirective::Create(
12954       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12955 }
12956 
12957 StmtResult Sema::ActOnOpenMPDistributeDirective(
12958     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12959     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12960   if (!AStmt)
12961     return StmtError();
12962 
12963   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
12964   OMPLoopBasedDirective::HelperExprs B;
12965   // In presence of clause 'collapse' with number of loops, it will
12966   // define the nested loops number.
12967   unsigned NestedLoopCount =
12968       checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
12969                       nullptr /*ordered not a clause on distribute*/, AStmt,
12970                       *this, *DSAStack, VarsWithImplicitDSA, B);
12971   if (NestedLoopCount == 0)
12972     return StmtError();
12973 
12974   assert((CurContext->isDependentContext() || B.builtAll()) &&
12975          "omp for loop exprs were not built");
12976 
12977   setFunctionHasBranchProtectedScope();
12978   return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
12979                                         NestedLoopCount, Clauses, AStmt, B);
12980 }
12981 
12982 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
12983     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12984     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12985   if (!AStmt)
12986     return StmtError();
12987 
12988   auto *CS = cast<CapturedStmt>(AStmt);
12989   // 1.2.2 OpenMP Language Terminology
12990   // Structured block - An executable statement with a single entry at the
12991   // top and a single exit at the bottom.
12992   // The point of exit cannot be a branch out of the structured block.
12993   // longjmp() and throw() must not violate the entry/exit criteria.
12994   CS->getCapturedDecl()->setNothrow();
12995   for (int ThisCaptureLevel =
12996            getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
12997        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12998     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12999     // 1.2.2 OpenMP Language Terminology
13000     // Structured block - An executable statement with a single entry at the
13001     // top and a single exit at the bottom.
13002     // The point of exit cannot be a branch out of the structured block.
13003     // longjmp() and throw() must not violate the entry/exit criteria.
13004     CS->getCapturedDecl()->setNothrow();
13005   }
13006 
13007   OMPLoopBasedDirective::HelperExprs B;
13008   // In presence of clause 'collapse' with number of loops, it will
13009   // define the nested loops number.
13010   unsigned NestedLoopCount = checkOpenMPLoop(
13011       OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
13012       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
13013       VarsWithImplicitDSA, B);
13014   if (NestedLoopCount == 0)
13015     return StmtError();
13016 
13017   assert((CurContext->isDependentContext() || B.builtAll()) &&
13018          "omp for loop exprs were not built");
13019 
13020   setFunctionHasBranchProtectedScope();
13021   return OMPDistributeParallelForDirective::Create(
13022       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13023       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
13024 }
13025 
13026 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
13027     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13028     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13029   if (!AStmt)
13030     return StmtError();
13031 
13032   auto *CS = cast<CapturedStmt>(AStmt);
13033   // 1.2.2 OpenMP Language Terminology
13034   // Structured block - An executable statement with a single entry at the
13035   // top and a single exit at the bottom.
13036   // The point of exit cannot be a branch out of the structured block.
13037   // longjmp() and throw() must not violate the entry/exit criteria.
13038   CS->getCapturedDecl()->setNothrow();
13039   for (int ThisCaptureLevel =
13040            getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
13041        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13042     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13043     // 1.2.2 OpenMP Language Terminology
13044     // Structured block - An executable statement with a single entry at the
13045     // top and a single exit at the bottom.
13046     // The point of exit cannot be a branch out of the structured block.
13047     // longjmp() and throw() must not violate the entry/exit criteria.
13048     CS->getCapturedDecl()->setNothrow();
13049   }
13050 
13051   OMPLoopBasedDirective::HelperExprs B;
13052   // In presence of clause 'collapse' with number of loops, it will
13053   // define the nested loops number.
13054   unsigned NestedLoopCount = checkOpenMPLoop(
13055       OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
13056       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
13057       VarsWithImplicitDSA, B);
13058   if (NestedLoopCount == 0)
13059     return StmtError();
13060 
13061   assert((CurContext->isDependentContext() || B.builtAll()) &&
13062          "omp for loop exprs were not built");
13063 
13064   if (!CurContext->isDependentContext()) {
13065     // Finalize the clauses that need pre-built expressions for CodeGen.
13066     for (OMPClause *C : Clauses) {
13067       if (auto *LC = dyn_cast<OMPLinearClause>(C))
13068         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13069                                      B.NumIterations, *this, CurScope,
13070                                      DSAStack))
13071           return StmtError();
13072     }
13073   }
13074 
13075   if (checkSimdlenSafelenSpecified(*this, Clauses))
13076     return StmtError();
13077 
13078   setFunctionHasBranchProtectedScope();
13079   return OMPDistributeParallelForSimdDirective::Create(
13080       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13081 }
13082 
13083 StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
13084     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13085     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13086   if (!AStmt)
13087     return StmtError();
13088 
13089   auto *CS = cast<CapturedStmt>(AStmt);
13090   // 1.2.2 OpenMP Language Terminology
13091   // Structured block - An executable statement with a single entry at the
13092   // top and a single exit at the bottom.
13093   // The point of exit cannot be a branch out of the structured block.
13094   // longjmp() and throw() must not violate the entry/exit criteria.
13095   CS->getCapturedDecl()->setNothrow();
13096   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
13097        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13098     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13099     // 1.2.2 OpenMP Language Terminology
13100     // Structured block - An executable statement with a single entry at the
13101     // top and a single exit at the bottom.
13102     // The point of exit cannot be a branch out of the structured block.
13103     // longjmp() and throw() must not violate the entry/exit criteria.
13104     CS->getCapturedDecl()->setNothrow();
13105   }
13106 
13107   OMPLoopBasedDirective::HelperExprs B;
13108   // In presence of clause 'collapse' with number of loops, it will
13109   // define the nested loops number.
13110   unsigned NestedLoopCount =
13111       checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
13112                       nullptr /*ordered not a clause on distribute*/, CS, *this,
13113                       *DSAStack, VarsWithImplicitDSA, B);
13114   if (NestedLoopCount == 0)
13115     return StmtError();
13116 
13117   assert((CurContext->isDependentContext() || B.builtAll()) &&
13118          "omp for loop exprs were not built");
13119 
13120   if (!CurContext->isDependentContext()) {
13121     // Finalize the clauses that need pre-built expressions for CodeGen.
13122     for (OMPClause *C : Clauses) {
13123       if (auto *LC = dyn_cast<OMPLinearClause>(C))
13124         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13125                                      B.NumIterations, *this, CurScope,
13126                                      DSAStack))
13127           return StmtError();
13128     }
13129   }
13130 
13131   if (checkSimdlenSafelenSpecified(*this, Clauses))
13132     return StmtError();
13133 
13134   setFunctionHasBranchProtectedScope();
13135   return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
13136                                             NestedLoopCount, Clauses, AStmt, B);
13137 }
13138 
13139 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
13140     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13141     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13142   if (!AStmt)
13143     return StmtError();
13144 
13145   auto *CS = cast<CapturedStmt>(AStmt);
13146   // 1.2.2 OpenMP Language Terminology
13147   // Structured block - An executable statement with a single entry at the
13148   // top and a single exit at the bottom.
13149   // The point of exit cannot be a branch out of the structured block.
13150   // longjmp() and throw() must not violate the entry/exit criteria.
13151   CS->getCapturedDecl()->setNothrow();
13152   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
13153        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13154     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13155     // 1.2.2 OpenMP Language Terminology
13156     // Structured block - An executable statement with a single entry at the
13157     // top and a single exit at the bottom.
13158     // The point of exit cannot be a branch out of the structured block.
13159     // longjmp() and throw() must not violate the entry/exit criteria.
13160     CS->getCapturedDecl()->setNothrow();
13161   }
13162 
13163   OMPLoopBasedDirective::HelperExprs B;
13164   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
13165   // define the nested loops number.
13166   unsigned NestedLoopCount = checkOpenMPLoop(
13167       OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
13168       getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, VarsWithImplicitDSA,
13169       B);
13170   if (NestedLoopCount == 0)
13171     return StmtError();
13172 
13173   assert((CurContext->isDependentContext() || B.builtAll()) &&
13174          "omp target parallel for simd loop exprs were not built");
13175 
13176   if (!CurContext->isDependentContext()) {
13177     // Finalize the clauses that need pre-built expressions for CodeGen.
13178     for (OMPClause *C : Clauses) {
13179       if (auto *LC = dyn_cast<OMPLinearClause>(C))
13180         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13181                                      B.NumIterations, *this, CurScope,
13182                                      DSAStack))
13183           return StmtError();
13184     }
13185   }
13186   if (checkSimdlenSafelenSpecified(*this, Clauses))
13187     return StmtError();
13188 
13189   setFunctionHasBranchProtectedScope();
13190   return OMPTargetParallelForSimdDirective::Create(
13191       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13192 }
13193 
13194 StmtResult Sema::ActOnOpenMPTargetSimdDirective(
13195     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13196     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13197   if (!AStmt)
13198     return StmtError();
13199 
13200   auto *CS = cast<CapturedStmt>(AStmt);
13201   // 1.2.2 OpenMP Language Terminology
13202   // Structured block - An executable statement with a single entry at the
13203   // top and a single exit at the bottom.
13204   // The point of exit cannot be a branch out of the structured block.
13205   // longjmp() and throw() must not violate the entry/exit criteria.
13206   CS->getCapturedDecl()->setNothrow();
13207   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
13208        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13209     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13210     // 1.2.2 OpenMP Language Terminology
13211     // Structured block - An executable statement with a single entry at the
13212     // top and a single exit at the bottom.
13213     // The point of exit cannot be a branch out of the structured block.
13214     // longjmp() and throw() must not violate the entry/exit criteria.
13215     CS->getCapturedDecl()->setNothrow();
13216   }
13217 
13218   OMPLoopBasedDirective::HelperExprs B;
13219   // In presence of clause 'collapse' with number of loops, it will define the
13220   // nested loops number.
13221   unsigned NestedLoopCount =
13222       checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
13223                       getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
13224                       VarsWithImplicitDSA, B);
13225   if (NestedLoopCount == 0)
13226     return StmtError();
13227 
13228   assert((CurContext->isDependentContext() || B.builtAll()) &&
13229          "omp target simd loop exprs were not built");
13230 
13231   if (!CurContext->isDependentContext()) {
13232     // Finalize the clauses that need pre-built expressions for CodeGen.
13233     for (OMPClause *C : Clauses) {
13234       if (auto *LC = dyn_cast<OMPLinearClause>(C))
13235         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13236                                      B.NumIterations, *this, CurScope,
13237                                      DSAStack))
13238           return StmtError();
13239     }
13240   }
13241 
13242   if (checkSimdlenSafelenSpecified(*this, Clauses))
13243     return StmtError();
13244 
13245   setFunctionHasBranchProtectedScope();
13246   return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
13247                                         NestedLoopCount, Clauses, AStmt, B);
13248 }
13249 
13250 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
13251     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13252     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13253   if (!AStmt)
13254     return StmtError();
13255 
13256   auto *CS = cast<CapturedStmt>(AStmt);
13257   // 1.2.2 OpenMP Language Terminology
13258   // Structured block - An executable statement with a single entry at the
13259   // top and a single exit at the bottom.
13260   // The point of exit cannot be a branch out of the structured block.
13261   // longjmp() and throw() must not violate the entry/exit criteria.
13262   CS->getCapturedDecl()->setNothrow();
13263   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
13264        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13265     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13266     // 1.2.2 OpenMP Language Terminology
13267     // Structured block - An executable statement with a single entry at the
13268     // top and a single exit at the bottom.
13269     // The point of exit cannot be a branch out of the structured block.
13270     // longjmp() and throw() must not violate the entry/exit criteria.
13271     CS->getCapturedDecl()->setNothrow();
13272   }
13273 
13274   OMPLoopBasedDirective::HelperExprs B;
13275   // In presence of clause 'collapse' with number of loops, it will
13276   // define the nested loops number.
13277   unsigned NestedLoopCount =
13278       checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
13279                       nullptr /*ordered not a clause on distribute*/, CS, *this,
13280                       *DSAStack, VarsWithImplicitDSA, B);
13281   if (NestedLoopCount == 0)
13282     return StmtError();
13283 
13284   assert((CurContext->isDependentContext() || B.builtAll()) &&
13285          "omp teams distribute loop exprs were not built");
13286 
13287   setFunctionHasBranchProtectedScope();
13288 
13289   DSAStack->setParentTeamsRegionLoc(StartLoc);
13290 
13291   return OMPTeamsDistributeDirective::Create(
13292       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13293 }
13294 
13295 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
13296     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13297     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13298   if (!AStmt)
13299     return StmtError();
13300 
13301   auto *CS = cast<CapturedStmt>(AStmt);
13302   // 1.2.2 OpenMP Language Terminology
13303   // Structured block - An executable statement with a single entry at the
13304   // top and a single exit at the bottom.
13305   // The point of exit cannot be a branch out of the structured block.
13306   // longjmp() and throw() must not violate the entry/exit criteria.
13307   CS->getCapturedDecl()->setNothrow();
13308   for (int ThisCaptureLevel =
13309            getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
13310        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13311     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13312     // 1.2.2 OpenMP Language Terminology
13313     // Structured block - An executable statement with a single entry at the
13314     // top and a single exit at the bottom.
13315     // The point of exit cannot be a branch out of the structured block.
13316     // longjmp() and throw() must not violate the entry/exit criteria.
13317     CS->getCapturedDecl()->setNothrow();
13318   }
13319 
13320   OMPLoopBasedDirective::HelperExprs B;
13321   // In presence of clause 'collapse' with number of loops, it will
13322   // define the nested loops number.
13323   unsigned NestedLoopCount = checkOpenMPLoop(
13324       OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
13325       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
13326       VarsWithImplicitDSA, B);
13327 
13328   if (NestedLoopCount == 0)
13329     return StmtError();
13330 
13331   assert((CurContext->isDependentContext() || B.builtAll()) &&
13332          "omp teams distribute simd loop exprs were not built");
13333 
13334   if (!CurContext->isDependentContext()) {
13335     // Finalize the clauses that need pre-built expressions for CodeGen.
13336     for (OMPClause *C : Clauses) {
13337       if (auto *LC = dyn_cast<OMPLinearClause>(C))
13338         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13339                                      B.NumIterations, *this, CurScope,
13340                                      DSAStack))
13341           return StmtError();
13342     }
13343   }
13344 
13345   if (checkSimdlenSafelenSpecified(*this, Clauses))
13346     return StmtError();
13347 
13348   setFunctionHasBranchProtectedScope();
13349 
13350   DSAStack->setParentTeamsRegionLoc(StartLoc);
13351 
13352   return OMPTeamsDistributeSimdDirective::Create(
13353       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13354 }
13355 
13356 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
13357     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13358     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13359   if (!AStmt)
13360     return StmtError();
13361 
13362   auto *CS = cast<CapturedStmt>(AStmt);
13363   // 1.2.2 OpenMP Language Terminology
13364   // Structured block - An executable statement with a single entry at the
13365   // top and a single exit at the bottom.
13366   // The point of exit cannot be a branch out of the structured block.
13367   // longjmp() and throw() must not violate the entry/exit criteria.
13368   CS->getCapturedDecl()->setNothrow();
13369 
13370   for (int ThisCaptureLevel =
13371            getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
13372        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13373     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13374     // 1.2.2 OpenMP Language Terminology
13375     // Structured block - An executable statement with a single entry at the
13376     // top and a single exit at the bottom.
13377     // The point of exit cannot be a branch out of the structured block.
13378     // longjmp() and throw() must not violate the entry/exit criteria.
13379     CS->getCapturedDecl()->setNothrow();
13380   }
13381 
13382   OMPLoopBasedDirective::HelperExprs B;
13383   // In presence of clause 'collapse' with number of loops, it will
13384   // define the nested loops number.
13385   unsigned NestedLoopCount = checkOpenMPLoop(
13386       OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
13387       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
13388       VarsWithImplicitDSA, B);
13389 
13390   if (NestedLoopCount == 0)
13391     return StmtError();
13392 
13393   assert((CurContext->isDependentContext() || B.builtAll()) &&
13394          "omp for loop exprs were not built");
13395 
13396   if (!CurContext->isDependentContext()) {
13397     // Finalize the clauses that need pre-built expressions for CodeGen.
13398     for (OMPClause *C : Clauses) {
13399       if (auto *LC = dyn_cast<OMPLinearClause>(C))
13400         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13401                                      B.NumIterations, *this, CurScope,
13402                                      DSAStack))
13403           return StmtError();
13404     }
13405   }
13406 
13407   if (checkSimdlenSafelenSpecified(*this, Clauses))
13408     return StmtError();
13409 
13410   setFunctionHasBranchProtectedScope();
13411 
13412   DSAStack->setParentTeamsRegionLoc(StartLoc);
13413 
13414   return OMPTeamsDistributeParallelForSimdDirective::Create(
13415       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13416 }
13417 
13418 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
13419     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13420     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13421   if (!AStmt)
13422     return StmtError();
13423 
13424   auto *CS = cast<CapturedStmt>(AStmt);
13425   // 1.2.2 OpenMP Language Terminology
13426   // Structured block - An executable statement with a single entry at the
13427   // top and a single exit at the bottom.
13428   // The point of exit cannot be a branch out of the structured block.
13429   // longjmp() and throw() must not violate the entry/exit criteria.
13430   CS->getCapturedDecl()->setNothrow();
13431 
13432   for (int ThisCaptureLevel =
13433            getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
13434        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13435     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13436     // 1.2.2 OpenMP Language Terminology
13437     // Structured block - An executable statement with a single entry at the
13438     // top and a single exit at the bottom.
13439     // The point of exit cannot be a branch out of the structured block.
13440     // longjmp() and throw() must not violate the entry/exit criteria.
13441     CS->getCapturedDecl()->setNothrow();
13442   }
13443 
13444   OMPLoopBasedDirective::HelperExprs B;
13445   // In presence of clause 'collapse' with number of loops, it will
13446   // define the nested loops number.
13447   unsigned NestedLoopCount = checkOpenMPLoop(
13448       OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
13449       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
13450       VarsWithImplicitDSA, B);
13451 
13452   if (NestedLoopCount == 0)
13453     return StmtError();
13454 
13455   assert((CurContext->isDependentContext() || B.builtAll()) &&
13456          "omp for loop exprs were not built");
13457 
13458   setFunctionHasBranchProtectedScope();
13459 
13460   DSAStack->setParentTeamsRegionLoc(StartLoc);
13461 
13462   return OMPTeamsDistributeParallelForDirective::Create(
13463       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13464       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
13465 }
13466 
13467 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
13468                                                  Stmt *AStmt,
13469                                                  SourceLocation StartLoc,
13470                                                  SourceLocation EndLoc) {
13471   if (!AStmt)
13472     return StmtError();
13473 
13474   auto *CS = cast<CapturedStmt>(AStmt);
13475   // 1.2.2 OpenMP Language Terminology
13476   // Structured block - An executable statement with a single entry at the
13477   // top and a single exit at the bottom.
13478   // The point of exit cannot be a branch out of the structured block.
13479   // longjmp() and throw() must not violate the entry/exit criteria.
13480   CS->getCapturedDecl()->setNothrow();
13481 
13482   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
13483        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13484     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13485     // 1.2.2 OpenMP Language Terminology
13486     // Structured block - An executable statement with a single entry at the
13487     // top and a single exit at the bottom.
13488     // The point of exit cannot be a branch out of the structured block.
13489     // longjmp() and throw() must not violate the entry/exit criteria.
13490     CS->getCapturedDecl()->setNothrow();
13491   }
13492   setFunctionHasBranchProtectedScope();
13493 
13494   return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
13495                                          AStmt);
13496 }
13497 
13498 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
13499     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13500     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13501   if (!AStmt)
13502     return StmtError();
13503 
13504   auto *CS = cast<CapturedStmt>(AStmt);
13505   // 1.2.2 OpenMP Language Terminology
13506   // Structured block - An executable statement with a single entry at the
13507   // top and a single exit at the bottom.
13508   // The point of exit cannot be a branch out of the structured block.
13509   // longjmp() and throw() must not violate the entry/exit criteria.
13510   CS->getCapturedDecl()->setNothrow();
13511   for (int ThisCaptureLevel =
13512            getOpenMPCaptureLevels(OMPD_target_teams_distribute);
13513        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13514     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13515     // 1.2.2 OpenMP Language Terminology
13516     // Structured block - An executable statement with a single entry at the
13517     // top and a single exit at the bottom.
13518     // The point of exit cannot be a branch out of the structured block.
13519     // longjmp() and throw() must not violate the entry/exit criteria.
13520     CS->getCapturedDecl()->setNothrow();
13521   }
13522 
13523   OMPLoopBasedDirective::HelperExprs B;
13524   // In presence of clause 'collapse' with number of loops, it will
13525   // define the nested loops number.
13526   unsigned NestedLoopCount = checkOpenMPLoop(
13527       OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
13528       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
13529       VarsWithImplicitDSA, B);
13530   if (NestedLoopCount == 0)
13531     return StmtError();
13532 
13533   assert((CurContext->isDependentContext() || B.builtAll()) &&
13534          "omp target teams distribute loop exprs were not built");
13535 
13536   setFunctionHasBranchProtectedScope();
13537   return OMPTargetTeamsDistributeDirective::Create(
13538       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13539 }
13540 
13541 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
13542     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13543     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13544   if (!AStmt)
13545     return StmtError();
13546 
13547   auto *CS = cast<CapturedStmt>(AStmt);
13548   // 1.2.2 OpenMP Language Terminology
13549   // Structured block - An executable statement with a single entry at the
13550   // top and a single exit at the bottom.
13551   // The point of exit cannot be a branch out of the structured block.
13552   // longjmp() and throw() must not violate the entry/exit criteria.
13553   CS->getCapturedDecl()->setNothrow();
13554   for (int ThisCaptureLevel =
13555            getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
13556        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13557     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13558     // 1.2.2 OpenMP Language Terminology
13559     // Structured block - An executable statement with a single entry at the
13560     // top and a single exit at the bottom.
13561     // The point of exit cannot be a branch out of the structured block.
13562     // longjmp() and throw() must not violate the entry/exit criteria.
13563     CS->getCapturedDecl()->setNothrow();
13564   }
13565 
13566   OMPLoopBasedDirective::HelperExprs B;
13567   // In presence of clause 'collapse' with number of loops, it will
13568   // define the nested loops number.
13569   unsigned NestedLoopCount = checkOpenMPLoop(
13570       OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
13571       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
13572       VarsWithImplicitDSA, B);
13573   if (NestedLoopCount == 0)
13574     return StmtError();
13575 
13576   assert((CurContext->isDependentContext() || B.builtAll()) &&
13577          "omp target teams distribute parallel for loop exprs were not built");
13578 
13579   if (!CurContext->isDependentContext()) {
13580     // Finalize the clauses that need pre-built expressions for CodeGen.
13581     for (OMPClause *C : Clauses) {
13582       if (auto *LC = dyn_cast<OMPLinearClause>(C))
13583         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13584                                      B.NumIterations, *this, CurScope,
13585                                      DSAStack))
13586           return StmtError();
13587     }
13588   }
13589 
13590   setFunctionHasBranchProtectedScope();
13591   return OMPTargetTeamsDistributeParallelForDirective::Create(
13592       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
13593       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
13594 }
13595 
13596 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
13597     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13598     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13599   if (!AStmt)
13600     return StmtError();
13601 
13602   auto *CS = cast<CapturedStmt>(AStmt);
13603   // 1.2.2 OpenMP Language Terminology
13604   // Structured block - An executable statement with a single entry at the
13605   // top and a single exit at the bottom.
13606   // The point of exit cannot be a branch out of the structured block.
13607   // longjmp() and throw() must not violate the entry/exit criteria.
13608   CS->getCapturedDecl()->setNothrow();
13609   for (int ThisCaptureLevel = getOpenMPCaptureLevels(
13610            OMPD_target_teams_distribute_parallel_for_simd);
13611        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13612     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13613     // 1.2.2 OpenMP Language Terminology
13614     // Structured block - An executable statement with a single entry at the
13615     // top and a single exit at the bottom.
13616     // The point of exit cannot be a branch out of the structured block.
13617     // longjmp() and throw() must not violate the entry/exit criteria.
13618     CS->getCapturedDecl()->setNothrow();
13619   }
13620 
13621   OMPLoopBasedDirective::HelperExprs B;
13622   // In presence of clause 'collapse' with number of loops, it will
13623   // define the nested loops number.
13624   unsigned NestedLoopCount =
13625       checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
13626                       getCollapseNumberExpr(Clauses),
13627                       nullptr /*ordered not a clause on distribute*/, CS, *this,
13628                       *DSAStack, VarsWithImplicitDSA, B);
13629   if (NestedLoopCount == 0)
13630     return StmtError();
13631 
13632   assert((CurContext->isDependentContext() || B.builtAll()) &&
13633          "omp target teams distribute parallel for simd loop exprs were not "
13634          "built");
13635 
13636   if (!CurContext->isDependentContext()) {
13637     // Finalize the clauses that need pre-built expressions for CodeGen.
13638     for (OMPClause *C : Clauses) {
13639       if (auto *LC = dyn_cast<OMPLinearClause>(C))
13640         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13641                                      B.NumIterations, *this, CurScope,
13642                                      DSAStack))
13643           return StmtError();
13644     }
13645   }
13646 
13647   if (checkSimdlenSafelenSpecified(*this, Clauses))
13648     return StmtError();
13649 
13650   setFunctionHasBranchProtectedScope();
13651   return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
13652       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13653 }
13654 
13655 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
13656     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
13657     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
13658   if (!AStmt)
13659     return StmtError();
13660 
13661   auto *CS = cast<CapturedStmt>(AStmt);
13662   // 1.2.2 OpenMP Language Terminology
13663   // Structured block - An executable statement with a single entry at the
13664   // top and a single exit at the bottom.
13665   // The point of exit cannot be a branch out of the structured block.
13666   // longjmp() and throw() must not violate the entry/exit criteria.
13667   CS->getCapturedDecl()->setNothrow();
13668   for (int ThisCaptureLevel =
13669            getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
13670        ThisCaptureLevel > 1; --ThisCaptureLevel) {
13671     CS = cast<CapturedStmt>(CS->getCapturedStmt());
13672     // 1.2.2 OpenMP Language Terminology
13673     // Structured block - An executable statement with a single entry at the
13674     // top and a single exit at the bottom.
13675     // The point of exit cannot be a branch out of the structured block.
13676     // longjmp() and throw() must not violate the entry/exit criteria.
13677     CS->getCapturedDecl()->setNothrow();
13678   }
13679 
13680   OMPLoopBasedDirective::HelperExprs B;
13681   // In presence of clause 'collapse' with number of loops, it will
13682   // define the nested loops number.
13683   unsigned NestedLoopCount = checkOpenMPLoop(
13684       OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
13685       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
13686       VarsWithImplicitDSA, B);
13687   if (NestedLoopCount == 0)
13688     return StmtError();
13689 
13690   assert((CurContext->isDependentContext() || B.builtAll()) &&
13691          "omp target teams distribute simd loop exprs were not built");
13692 
13693   if (!CurContext->isDependentContext()) {
13694     // Finalize the clauses that need pre-built expressions for CodeGen.
13695     for (OMPClause *C : Clauses) {
13696       if (auto *LC = dyn_cast<OMPLinearClause>(C))
13697         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
13698                                      B.NumIterations, *this, CurScope,
13699                                      DSAStack))
13700           return StmtError();
13701     }
13702   }
13703 
13704   if (checkSimdlenSafelenSpecified(*this, Clauses))
13705     return StmtError();
13706 
13707   setFunctionHasBranchProtectedScope();
13708   return OMPTargetTeamsDistributeSimdDirective::Create(
13709       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
13710 }
13711 
13712 bool Sema::checkTransformableLoopNest(
13713     OpenMPDirectiveKind Kind, Stmt *AStmt, int NumLoops,
13714     SmallVectorImpl<OMPLoopBasedDirective::HelperExprs> &LoopHelpers,
13715     Stmt *&Body,
13716     SmallVectorImpl<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>>
13717         &OriginalInits) {
13718   OriginalInits.emplace_back();
13719   bool Result = OMPLoopBasedDirective::doForAllLoops(
13720       AStmt->IgnoreContainers(), /*TryImperfectlyNestedLoops=*/false, NumLoops,
13721       [this, &LoopHelpers, &Body, &OriginalInits, Kind](unsigned Cnt,
13722                                                         Stmt *CurStmt) {
13723         VarsWithInheritedDSAType TmpDSA;
13724         unsigned SingleNumLoops =
13725             checkOpenMPLoop(Kind, nullptr, nullptr, CurStmt, *this, *DSAStack,
13726                             TmpDSA, LoopHelpers[Cnt]);
13727         if (SingleNumLoops == 0)
13728           return true;
13729         assert(SingleNumLoops == 1 && "Expect single loop iteration space");
13730         if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
13731           OriginalInits.back().push_back(For->getInit());
13732           Body = For->getBody();
13733         } else {
13734           assert(isa<CXXForRangeStmt>(CurStmt) &&
13735                  "Expected canonical for or range-based for loops.");
13736           auto *CXXFor = cast<CXXForRangeStmt>(CurStmt);
13737           OriginalInits.back().push_back(CXXFor->getBeginStmt());
13738           Body = CXXFor->getBody();
13739         }
13740         OriginalInits.emplace_back();
13741         return false;
13742       },
13743       [&OriginalInits](OMPLoopBasedDirective *Transform) {
13744         Stmt *DependentPreInits;
13745         if (auto *Dir = dyn_cast<OMPTileDirective>(Transform))
13746           DependentPreInits = Dir->getPreInits();
13747         else if (auto *Dir = dyn_cast<OMPUnrollDirective>(Transform))
13748           DependentPreInits = Dir->getPreInits();
13749         else
13750           llvm_unreachable("Unhandled loop transformation");
13751         if (!DependentPreInits)
13752           return;
13753         for (Decl *C : cast<DeclStmt>(DependentPreInits)->getDeclGroup())
13754           OriginalInits.back().push_back(C);
13755       });
13756   assert(OriginalInits.back().empty() && "No preinit after innermost loop");
13757   OriginalInits.pop_back();
13758   return Result;
13759 }
13760 
13761 StmtResult Sema::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses,
13762                                           Stmt *AStmt, SourceLocation StartLoc,
13763                                           SourceLocation EndLoc) {
13764   auto SizesClauses =
13765       OMPExecutableDirective::getClausesOfKind<OMPSizesClause>(Clauses);
13766   if (SizesClauses.empty()) {
13767     // A missing 'sizes' clause is already reported by the parser.
13768     return StmtError();
13769   }
13770   const OMPSizesClause *SizesClause = *SizesClauses.begin();
13771   unsigned NumLoops = SizesClause->getNumSizes();
13772 
13773   // Empty statement should only be possible if there already was an error.
13774   if (!AStmt)
13775     return StmtError();
13776 
13777   // Verify and diagnose loop nest.
13778   SmallVector<OMPLoopBasedDirective::HelperExprs, 4> LoopHelpers(NumLoops);
13779   Stmt *Body = nullptr;
13780   SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, 4>
13781       OriginalInits;
13782   if (!checkTransformableLoopNest(OMPD_tile, AStmt, NumLoops, LoopHelpers, Body,
13783                                   OriginalInits))
13784     return StmtError();
13785 
13786   // Delay tiling to when template is completely instantiated.
13787   if (CurContext->isDependentContext())
13788     return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses,
13789                                     NumLoops, AStmt, nullptr, nullptr);
13790 
13791   SmallVector<Decl *, 4> PreInits;
13792 
13793   // Create iteration variables for the generated loops.
13794   SmallVector<VarDecl *, 4> FloorIndVars;
13795   SmallVector<VarDecl *, 4> TileIndVars;
13796   FloorIndVars.resize(NumLoops);
13797   TileIndVars.resize(NumLoops);
13798   for (unsigned I = 0; I < NumLoops; ++I) {
13799     OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
13800 
13801     assert(LoopHelper.Counters.size() == 1 &&
13802            "Expect single-dimensional loop iteration space");
13803     auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
13804     std::string OrigVarName = OrigCntVar->getNameInfo().getAsString();
13805     DeclRefExpr *IterVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
13806     QualType CntTy = IterVarRef->getType();
13807 
13808     // Iteration variable for the floor (i.e. outer) loop.
13809     {
13810       std::string FloorCntName =
13811           (Twine(".floor_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
13812       VarDecl *FloorCntDecl =
13813           buildVarDecl(*this, {}, CntTy, FloorCntName, nullptr, OrigCntVar);
13814       FloorIndVars[I] = FloorCntDecl;
13815     }
13816 
13817     // Iteration variable for the tile (i.e. inner) loop.
13818     {
13819       std::string TileCntName =
13820           (Twine(".tile_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
13821 
13822       // Reuse the iteration variable created by checkOpenMPLoop. It is also
13823       // used by the expressions to derive the original iteration variable's
13824       // value from the logical iteration number.
13825       auto *TileCntDecl = cast<VarDecl>(IterVarRef->getDecl());
13826       TileCntDecl->setDeclName(&PP.getIdentifierTable().get(TileCntName));
13827       TileIndVars[I] = TileCntDecl;
13828     }
13829     for (auto &P : OriginalInits[I]) {
13830       if (auto *D = P.dyn_cast<Decl *>())
13831         PreInits.push_back(D);
13832       else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>()))
13833         PreInits.append(PI->decl_begin(), PI->decl_end());
13834     }
13835     if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
13836       PreInits.append(PI->decl_begin(), PI->decl_end());
13837     // Gather declarations for the data members used as counters.
13838     for (Expr *CounterRef : LoopHelper.Counters) {
13839       auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
13840       if (isa<OMPCapturedExprDecl>(CounterDecl))
13841         PreInits.push_back(CounterDecl);
13842     }
13843   }
13844 
13845   // Once the original iteration values are set, append the innermost body.
13846   Stmt *Inner = Body;
13847 
13848   // Create tile loops from the inside to the outside.
13849   for (int I = NumLoops - 1; I >= 0; --I) {
13850     OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
13851     Expr *NumIterations = LoopHelper.NumIterations;
13852     auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
13853     QualType CntTy = OrigCntVar->getType();
13854     Expr *DimTileSize = SizesClause->getSizesRefs()[I];
13855     Scope *CurScope = getCurScope();
13856 
13857     // Commonly used variables.
13858     DeclRefExpr *TileIV = buildDeclRefExpr(*this, TileIndVars[I], CntTy,
13859                                            OrigCntVar->getExprLoc());
13860     DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
13861                                             OrigCntVar->getExprLoc());
13862 
13863     // For init-statement: auto .tile.iv = .floor.iv
13864     AddInitializerToDecl(TileIndVars[I], DefaultLvalueConversion(FloorIV).get(),
13865                          /*DirectInit=*/false);
13866     Decl *CounterDecl = TileIndVars[I];
13867     StmtResult InitStmt = new (Context)
13868         DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
13869                  OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
13870     if (!InitStmt.isUsable())
13871       return StmtError();
13872 
13873     // For cond-expression: .tile.iv < min(.floor.iv + DimTileSize,
13874     // NumIterations)
13875     ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
13876                                       BO_Add, FloorIV, DimTileSize);
13877     if (!EndOfTile.isUsable())
13878       return StmtError();
13879     ExprResult IsPartialTile =
13880         BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT,
13881                    NumIterations, EndOfTile.get());
13882     if (!IsPartialTile.isUsable())
13883       return StmtError();
13884     ExprResult MinTileAndIterSpace = ActOnConditionalOp(
13885         LoopHelper.Cond->getBeginLoc(), LoopHelper.Cond->getEndLoc(),
13886         IsPartialTile.get(), NumIterations, EndOfTile.get());
13887     if (!MinTileAndIterSpace.isUsable())
13888       return StmtError();
13889     ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
13890                                      BO_LT, TileIV, MinTileAndIterSpace.get());
13891     if (!CondExpr.isUsable())
13892       return StmtError();
13893 
13894     // For incr-statement: ++.tile.iv
13895     ExprResult IncrStmt =
13896         BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), UO_PreInc, TileIV);
13897     if (!IncrStmt.isUsable())
13898       return StmtError();
13899 
13900     // Statements to set the original iteration variable's value from the
13901     // logical iteration number.
13902     // Generated for loop is:
13903     // Original_for_init;
13904     // for (auto .tile.iv = .floor.iv; .tile.iv < min(.floor.iv + DimTileSize,
13905     // NumIterations); ++.tile.iv) {
13906     //   Original_Body;
13907     //   Original_counter_update;
13908     // }
13909     // FIXME: If the innermost body is an loop itself, inserting these
13910     // statements stops it being recognized  as a perfectly nested loop (e.g.
13911     // for applying tiling again). If this is the case, sink the expressions
13912     // further into the inner loop.
13913     SmallVector<Stmt *, 4> BodyParts;
13914     BodyParts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
13915     BodyParts.push_back(Inner);
13916     Inner = CompoundStmt::Create(Context, BodyParts, Inner->getBeginLoc(),
13917                                  Inner->getEndLoc());
13918     Inner = new (Context)
13919         ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
13920                 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
13921                 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
13922   }
13923 
13924   // Create floor loops from the inside to the outside.
13925   for (int I = NumLoops - 1; I >= 0; --I) {
13926     auto &LoopHelper = LoopHelpers[I];
13927     Expr *NumIterations = LoopHelper.NumIterations;
13928     DeclRefExpr *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
13929     QualType CntTy = OrigCntVar->getType();
13930     Expr *DimTileSize = SizesClause->getSizesRefs()[I];
13931     Scope *CurScope = getCurScope();
13932 
13933     // Commonly used variables.
13934     DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
13935                                             OrigCntVar->getExprLoc());
13936 
13937     // For init-statement: auto .floor.iv = 0
13938     AddInitializerToDecl(
13939         FloorIndVars[I],
13940         ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
13941         /*DirectInit=*/false);
13942     Decl *CounterDecl = FloorIndVars[I];
13943     StmtResult InitStmt = new (Context)
13944         DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
13945                  OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
13946     if (!InitStmt.isUsable())
13947       return StmtError();
13948 
13949     // For cond-expression: .floor.iv < NumIterations
13950     ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
13951                                      BO_LT, FloorIV, NumIterations);
13952     if (!CondExpr.isUsable())
13953       return StmtError();
13954 
13955     // For incr-statement: .floor.iv += DimTileSize
13956     ExprResult IncrStmt = BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(),
13957                                      BO_AddAssign, FloorIV, DimTileSize);
13958     if (!IncrStmt.isUsable())
13959       return StmtError();
13960 
13961     Inner = new (Context)
13962         ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
13963                 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
13964                 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
13965   }
13966 
13967   return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, NumLoops,
13968                                   AStmt, Inner,
13969                                   buildPreInits(Context, PreInits));
13970 }
13971 
13972 StmtResult Sema::ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses,
13973                                             Stmt *AStmt,
13974                                             SourceLocation StartLoc,
13975                                             SourceLocation EndLoc) {
13976   // Empty statement should only be possible if there already was an error.
13977   if (!AStmt)
13978     return StmtError();
13979 
13980   if (checkMutuallyExclusiveClauses(*this, Clauses, {OMPC_partial, OMPC_full}))
13981     return StmtError();
13982 
13983   const OMPFullClause *FullClause =
13984       OMPExecutableDirective::getSingleClause<OMPFullClause>(Clauses);
13985   const OMPPartialClause *PartialClause =
13986       OMPExecutableDirective::getSingleClause<OMPPartialClause>(Clauses);
13987   assert(!(FullClause && PartialClause) &&
13988          "mutual exclusivity must have been checked before");
13989 
13990   constexpr unsigned NumLoops = 1;
13991   Stmt *Body = nullptr;
13992   SmallVector<OMPLoopBasedDirective::HelperExprs, NumLoops> LoopHelpers(
13993       NumLoops);
13994   SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, NumLoops + 1>
13995       OriginalInits;
13996   if (!checkTransformableLoopNest(OMPD_unroll, AStmt, NumLoops, LoopHelpers,
13997                                   Body, OriginalInits))
13998     return StmtError();
13999 
14000   unsigned NumGeneratedLoops = PartialClause ? 1 : 0;
14001 
14002   // Delay unrolling to when template is completely instantiated.
14003   if (CurContext->isDependentContext())
14004     return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
14005                                       NumGeneratedLoops, nullptr, nullptr);
14006 
14007   OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front();
14008 
14009   if (FullClause) {
14010     if (!VerifyPositiveIntegerConstantInClause(
14011              LoopHelper.NumIterations, OMPC_full, /*StrictlyPositive=*/false,
14012              /*SuppressExprDiags=*/true)
14013              .isUsable()) {
14014       Diag(AStmt->getBeginLoc(), diag::err_omp_unroll_full_variable_trip_count);
14015       Diag(FullClause->getBeginLoc(), diag::note_omp_directive_here)
14016           << "#pragma omp unroll full";
14017       return StmtError();
14018     }
14019   }
14020 
14021   // The generated loop may only be passed to other loop-associated directive
14022   // when a partial clause is specified. Without the requirement it is
14023   // sufficient to generate loop unroll metadata at code-generation.
14024   if (NumGeneratedLoops == 0)
14025     return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
14026                                       NumGeneratedLoops, nullptr, nullptr);
14027 
14028   // Otherwise, we need to provide a de-sugared/transformed AST that can be
14029   // associated with another loop directive.
14030   //
14031   // The canonical loop analysis return by checkTransformableLoopNest assumes
14032   // the following structure to be the same loop without transformations or
14033   // directives applied: \code OriginalInits; LoopHelper.PreInits;
14034   // LoopHelper.Counters;
14035   // for (; IV < LoopHelper.NumIterations; ++IV) {
14036   //   LoopHelper.Updates;
14037   //   Body;
14038   // }
14039   // \endcode
14040   // where IV is a variable declared and initialized to 0 in LoopHelper.PreInits
14041   // and referenced by LoopHelper.IterationVarRef.
14042   //
14043   // The unrolling directive transforms this into the following loop:
14044   // \code
14045   // OriginalInits;         \
14046   // LoopHelper.PreInits;    > NewPreInits
14047   // LoopHelper.Counters;   /
14048   // for (auto UIV = 0; UIV < LoopHelper.NumIterations; UIV+=Factor) {
14049   //   #pragma clang loop unroll_count(Factor)
14050   //   for (IV = UIV; IV < UIV + Factor && UIV < LoopHelper.NumIterations; ++IV)
14051   //   {
14052   //     LoopHelper.Updates;
14053   //     Body;
14054   //   }
14055   // }
14056   // \endcode
14057   // where UIV is a new logical iteration counter. IV must be the same VarDecl
14058   // as the original LoopHelper.IterationVarRef because LoopHelper.Updates
14059   // references it. If the partially unrolled loop is associated with another
14060   // loop directive (like an OMPForDirective), it will use checkOpenMPLoop to
14061   // analyze this loop, i.e. the outer loop must fulfill the constraints of an
14062   // OpenMP canonical loop. The inner loop is not an associable canonical loop
14063   // and only exists to defer its unrolling to LLVM's LoopUnroll instead of
14064   // doing it in the frontend (by adding loop metadata). NewPreInits becomes a
14065   // property of the OMPLoopBasedDirective instead of statements in
14066   // CompoundStatement. This is to allow the loop to become a non-outermost loop
14067   // of a canonical loop nest where these PreInits are emitted before the
14068   // outermost directive.
14069 
14070   // Determine the PreInit declarations.
14071   SmallVector<Decl *, 4> PreInits;
14072   assert(OriginalInits.size() == 1 &&
14073          "Expecting a single-dimensional loop iteration space");
14074   for (auto &P : OriginalInits[0]) {
14075     if (auto *D = P.dyn_cast<Decl *>())
14076       PreInits.push_back(D);
14077     else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>()))
14078       PreInits.append(PI->decl_begin(), PI->decl_end());
14079   }
14080   if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
14081     PreInits.append(PI->decl_begin(), PI->decl_end());
14082   // Gather declarations for the data members used as counters.
14083   for (Expr *CounterRef : LoopHelper.Counters) {
14084     auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
14085     if (isa<OMPCapturedExprDecl>(CounterDecl))
14086       PreInits.push_back(CounterDecl);
14087   }
14088 
14089   auto *IterationVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
14090   QualType IVTy = IterationVarRef->getType();
14091   assert(LoopHelper.Counters.size() == 1 &&
14092          "Expecting a single-dimensional loop iteration space");
14093   auto *OrigVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
14094 
14095   // Determine the unroll factor.
14096   uint64_t Factor;
14097   SourceLocation FactorLoc;
14098   if (Expr *FactorVal = PartialClause->getFactor()) {
14099     Factor =
14100         FactorVal->getIntegerConstantExpr(Context).getValue().getZExtValue();
14101     FactorLoc = FactorVal->getExprLoc();
14102   } else {
14103     // TODO: Use a better profitability model.
14104     Factor = 2;
14105   }
14106   assert(Factor > 0 && "Expected positive unroll factor");
14107   auto MakeFactorExpr = [this, Factor, IVTy, FactorLoc]() {
14108     return IntegerLiteral::Create(
14109         Context, llvm::APInt(Context.getIntWidth(IVTy), Factor), IVTy,
14110         FactorLoc);
14111   };
14112 
14113   // Iteration variable SourceLocations.
14114   SourceLocation OrigVarLoc = OrigVar->getExprLoc();
14115   SourceLocation OrigVarLocBegin = OrigVar->getBeginLoc();
14116   SourceLocation OrigVarLocEnd = OrigVar->getEndLoc();
14117 
14118   // Internal variable names.
14119   std::string OrigVarName = OrigVar->getNameInfo().getAsString();
14120   std::string OuterIVName = (Twine(".unrolled.iv.") + OrigVarName).str();
14121   std::string InnerIVName = (Twine(".unroll_inner.iv.") + OrigVarName).str();
14122   std::string InnerTripCountName =
14123       (Twine(".unroll_inner.tripcount.") + OrigVarName).str();
14124 
14125   // Create the iteration variable for the unrolled loop.
14126   VarDecl *OuterIVDecl =
14127       buildVarDecl(*this, {}, IVTy, OuterIVName, nullptr, OrigVar);
14128   auto MakeOuterRef = [this, OuterIVDecl, IVTy, OrigVarLoc]() {
14129     return buildDeclRefExpr(*this, OuterIVDecl, IVTy, OrigVarLoc);
14130   };
14131 
14132   // Iteration variable for the inner loop: Reuse the iteration variable created
14133   // by checkOpenMPLoop.
14134   auto *InnerIVDecl = cast<VarDecl>(IterationVarRef->getDecl());
14135   InnerIVDecl->setDeclName(&PP.getIdentifierTable().get(InnerIVName));
14136   auto MakeInnerRef = [this, InnerIVDecl, IVTy, OrigVarLoc]() {
14137     return buildDeclRefExpr(*this, InnerIVDecl, IVTy, OrigVarLoc);
14138   };
14139 
14140   // Make a copy of the NumIterations expression for each use: By the AST
14141   // constraints, every expression object in a DeclContext must be unique.
14142   CaptureVars CopyTransformer(*this);
14143   auto MakeNumIterations = [&CopyTransformer, &LoopHelper]() -> Expr * {
14144     return AssertSuccess(
14145         CopyTransformer.TransformExpr(LoopHelper.NumIterations));
14146   };
14147 
14148   // Inner For init-statement: auto .unroll_inner.iv = .unrolled.iv
14149   ExprResult LValueConv = DefaultLvalueConversion(MakeOuterRef());
14150   AddInitializerToDecl(InnerIVDecl, LValueConv.get(), /*DirectInit=*/false);
14151   StmtResult InnerInit = new (Context)
14152       DeclStmt(DeclGroupRef(InnerIVDecl), OrigVarLocBegin, OrigVarLocEnd);
14153   if (!InnerInit.isUsable())
14154     return StmtError();
14155 
14156   // Inner For cond-expression:
14157   // \code
14158   //   .unroll_inner.iv < .unrolled.iv + Factor &&
14159   //   .unroll_inner.iv < NumIterations
14160   // \endcode
14161   // This conjunction of two conditions allows ScalarEvolution to derive the
14162   // maximum trip count of the inner loop.
14163   ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
14164                                     BO_Add, MakeOuterRef(), MakeFactorExpr());
14165   if (!EndOfTile.isUsable())
14166     return StmtError();
14167   ExprResult InnerCond1 = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
14168                                      BO_LE, MakeInnerRef(), EndOfTile.get());
14169   if (!InnerCond1.isUsable())
14170     return StmtError();
14171   ExprResult InnerCond2 =
14172       BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LE, MakeInnerRef(),
14173                  MakeNumIterations());
14174   if (!InnerCond2.isUsable())
14175     return StmtError();
14176   ExprResult InnerCond =
14177       BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LAnd,
14178                  InnerCond1.get(), InnerCond2.get());
14179   if (!InnerCond.isUsable())
14180     return StmtError();
14181 
14182   // Inner For incr-statement: ++.unroll_inner.iv
14183   ExprResult InnerIncr = BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(),
14184                                       UO_PreInc, MakeInnerRef());
14185   if (!InnerIncr.isUsable())
14186     return StmtError();
14187 
14188   // Inner For statement.
14189   SmallVector<Stmt *> InnerBodyStmts;
14190   InnerBodyStmts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
14191   InnerBodyStmts.push_back(Body);
14192   CompoundStmt *InnerBody = CompoundStmt::Create(
14193       Context, InnerBodyStmts, Body->getBeginLoc(), Body->getEndLoc());
14194   ForStmt *InnerFor = new (Context)
14195       ForStmt(Context, InnerInit.get(), InnerCond.get(), nullptr,
14196               InnerIncr.get(), InnerBody, LoopHelper.Init->getBeginLoc(),
14197               LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
14198 
14199   // Unroll metadata for the inner loop.
14200   // This needs to take into account the remainder portion of the unrolled loop,
14201   // hence `unroll(full)` does not apply here, even though the LoopUnroll pass
14202   // supports multiple loop exits. Instead, unroll using a factor equivalent to
14203   // the maximum trip count, which will also generate a remainder loop. Just
14204   // `unroll(enable)` (which could have been useful if the user has not
14205   // specified a concrete factor; even though the outer loop cannot be
14206   // influenced anymore, would avoid more code bloat than necessary) will refuse
14207   // the loop because "Won't unroll; remainder loop could not be generated when
14208   // assuming runtime trip count". Even if it did work, it must not choose a
14209   // larger unroll factor than the maximum loop length, or it would always just
14210   // execute the remainder loop.
14211   LoopHintAttr *UnrollHintAttr =
14212       LoopHintAttr::CreateImplicit(Context, LoopHintAttr::UnrollCount,
14213                                    LoopHintAttr::Numeric, MakeFactorExpr());
14214   AttributedStmt *InnerUnrolled =
14215       AttributedStmt::Create(Context, StartLoc, {UnrollHintAttr}, InnerFor);
14216 
14217   // Outer For init-statement: auto .unrolled.iv = 0
14218   AddInitializerToDecl(
14219       OuterIVDecl, ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
14220       /*DirectInit=*/false);
14221   StmtResult OuterInit = new (Context)
14222       DeclStmt(DeclGroupRef(OuterIVDecl), OrigVarLocBegin, OrigVarLocEnd);
14223   if (!OuterInit.isUsable())
14224     return StmtError();
14225 
14226   // Outer For cond-expression: .unrolled.iv < NumIterations
14227   ExprResult OuterConde =
14228       BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeOuterRef(),
14229                  MakeNumIterations());
14230   if (!OuterConde.isUsable())
14231     return StmtError();
14232 
14233   // Outer For incr-statement: .unrolled.iv += Factor
14234   ExprResult OuterIncr =
14235       BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(), BO_AddAssign,
14236                  MakeOuterRef(), MakeFactorExpr());
14237   if (!OuterIncr.isUsable())
14238     return StmtError();
14239 
14240   // Outer For statement.
14241   ForStmt *OuterFor = new (Context)
14242       ForStmt(Context, OuterInit.get(), OuterConde.get(), nullptr,
14243               OuterIncr.get(), InnerUnrolled, LoopHelper.Init->getBeginLoc(),
14244               LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
14245 
14246   return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
14247                                     NumGeneratedLoops, OuterFor,
14248                                     buildPreInits(Context, PreInits));
14249 }
14250 
14251 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
14252                                              SourceLocation StartLoc,
14253                                              SourceLocation LParenLoc,
14254                                              SourceLocation EndLoc) {
14255   OMPClause *Res = nullptr;
14256   switch (Kind) {
14257   case OMPC_final:
14258     Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
14259     break;
14260   case OMPC_num_threads:
14261     Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
14262     break;
14263   case OMPC_safelen:
14264     Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
14265     break;
14266   case OMPC_simdlen:
14267     Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
14268     break;
14269   case OMPC_allocator:
14270     Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
14271     break;
14272   case OMPC_collapse:
14273     Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
14274     break;
14275   case OMPC_ordered:
14276     Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
14277     break;
14278   case OMPC_num_teams:
14279     Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
14280     break;
14281   case OMPC_thread_limit:
14282     Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
14283     break;
14284   case OMPC_priority:
14285     Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
14286     break;
14287   case OMPC_grainsize:
14288     Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
14289     break;
14290   case OMPC_num_tasks:
14291     Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
14292     break;
14293   case OMPC_hint:
14294     Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
14295     break;
14296   case OMPC_depobj:
14297     Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc);
14298     break;
14299   case OMPC_detach:
14300     Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc);
14301     break;
14302   case OMPC_novariants:
14303     Res = ActOnOpenMPNovariantsClause(Expr, StartLoc, LParenLoc, EndLoc);
14304     break;
14305   case OMPC_nocontext:
14306     Res = ActOnOpenMPNocontextClause(Expr, StartLoc, LParenLoc, EndLoc);
14307     break;
14308   case OMPC_filter:
14309     Res = ActOnOpenMPFilterClause(Expr, StartLoc, LParenLoc, EndLoc);
14310     break;
14311   case OMPC_partial:
14312     Res = ActOnOpenMPPartialClause(Expr, StartLoc, LParenLoc, EndLoc);
14313     break;
14314   case OMPC_align:
14315     Res = ActOnOpenMPAlignClause(Expr, StartLoc, LParenLoc, EndLoc);
14316     break;
14317   case OMPC_device:
14318   case OMPC_if:
14319   case OMPC_default:
14320   case OMPC_proc_bind:
14321   case OMPC_schedule:
14322   case OMPC_private:
14323   case OMPC_firstprivate:
14324   case OMPC_lastprivate:
14325   case OMPC_shared:
14326   case OMPC_reduction:
14327   case OMPC_task_reduction:
14328   case OMPC_in_reduction:
14329   case OMPC_linear:
14330   case OMPC_aligned:
14331   case OMPC_copyin:
14332   case OMPC_copyprivate:
14333   case OMPC_nowait:
14334   case OMPC_untied:
14335   case OMPC_mergeable:
14336   case OMPC_threadprivate:
14337   case OMPC_sizes:
14338   case OMPC_allocate:
14339   case OMPC_flush:
14340   case OMPC_read:
14341   case OMPC_write:
14342   case OMPC_update:
14343   case OMPC_capture:
14344   case OMPC_compare:
14345   case OMPC_seq_cst:
14346   case OMPC_acq_rel:
14347   case OMPC_acquire:
14348   case OMPC_release:
14349   case OMPC_relaxed:
14350   case OMPC_depend:
14351   case OMPC_threads:
14352   case OMPC_simd:
14353   case OMPC_map:
14354   case OMPC_nogroup:
14355   case OMPC_dist_schedule:
14356   case OMPC_defaultmap:
14357   case OMPC_unknown:
14358   case OMPC_uniform:
14359   case OMPC_to:
14360   case OMPC_from:
14361   case OMPC_use_device_ptr:
14362   case OMPC_use_device_addr:
14363   case OMPC_is_device_ptr:
14364   case OMPC_unified_address:
14365   case OMPC_unified_shared_memory:
14366   case OMPC_reverse_offload:
14367   case OMPC_dynamic_allocators:
14368   case OMPC_atomic_default_mem_order:
14369   case OMPC_device_type:
14370   case OMPC_match:
14371   case OMPC_nontemporal:
14372   case OMPC_order:
14373   case OMPC_destroy:
14374   case OMPC_inclusive:
14375   case OMPC_exclusive:
14376   case OMPC_uses_allocators:
14377   case OMPC_affinity:
14378   case OMPC_when:
14379   case OMPC_bind:
14380   default:
14381     llvm_unreachable("Clause is not allowed.");
14382   }
14383   return Res;
14384 }
14385 
14386 // An OpenMP directive such as 'target parallel' has two captured regions:
14387 // for the 'target' and 'parallel' respectively.  This function returns
14388 // the region in which to capture expressions associated with a clause.
14389 // A return value of OMPD_unknown signifies that the expression should not
14390 // be captured.
14391 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
14392     OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion,
14393     OpenMPDirectiveKind NameModifier = OMPD_unknown) {
14394   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
14395   switch (CKind) {
14396   case OMPC_if:
14397     switch (DKind) {
14398     case OMPD_target_parallel_for_simd:
14399       if (OpenMPVersion >= 50 &&
14400           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
14401         CaptureRegion = OMPD_parallel;
14402         break;
14403       }
14404       LLVM_FALLTHROUGH;
14405     case OMPD_target_parallel:
14406     case OMPD_target_parallel_for:
14407       // If this clause applies to the nested 'parallel' region, capture within
14408       // the 'target' region, otherwise do not capture.
14409       if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
14410         CaptureRegion = OMPD_target;
14411       break;
14412     case OMPD_target_teams_distribute_parallel_for_simd:
14413       if (OpenMPVersion >= 50 &&
14414           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
14415         CaptureRegion = OMPD_parallel;
14416         break;
14417       }
14418       LLVM_FALLTHROUGH;
14419     case OMPD_target_teams_distribute_parallel_for:
14420       // If this clause applies to the nested 'parallel' region, capture within
14421       // the 'teams' region, otherwise do not capture.
14422       if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
14423         CaptureRegion = OMPD_teams;
14424       break;
14425     case OMPD_teams_distribute_parallel_for_simd:
14426       if (OpenMPVersion >= 50 &&
14427           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
14428         CaptureRegion = OMPD_parallel;
14429         break;
14430       }
14431       LLVM_FALLTHROUGH;
14432     case OMPD_teams_distribute_parallel_for:
14433       CaptureRegion = OMPD_teams;
14434       break;
14435     case OMPD_target_update:
14436     case OMPD_target_enter_data:
14437     case OMPD_target_exit_data:
14438       CaptureRegion = OMPD_task;
14439       break;
14440     case OMPD_parallel_master_taskloop:
14441       if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
14442         CaptureRegion = OMPD_parallel;
14443       break;
14444     case OMPD_parallel_master_taskloop_simd:
14445       if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
14446           NameModifier == OMPD_taskloop) {
14447         CaptureRegion = OMPD_parallel;
14448         break;
14449       }
14450       if (OpenMPVersion <= 45)
14451         break;
14452       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
14453         CaptureRegion = OMPD_taskloop;
14454       break;
14455     case OMPD_parallel_for_simd:
14456       if (OpenMPVersion <= 45)
14457         break;
14458       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
14459         CaptureRegion = OMPD_parallel;
14460       break;
14461     case OMPD_taskloop_simd:
14462     case OMPD_master_taskloop_simd:
14463       if (OpenMPVersion <= 45)
14464         break;
14465       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
14466         CaptureRegion = OMPD_taskloop;
14467       break;
14468     case OMPD_distribute_parallel_for_simd:
14469       if (OpenMPVersion <= 45)
14470         break;
14471       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
14472         CaptureRegion = OMPD_parallel;
14473       break;
14474     case OMPD_target_simd:
14475       if (OpenMPVersion >= 50 &&
14476           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
14477         CaptureRegion = OMPD_target;
14478       break;
14479     case OMPD_teams_distribute_simd:
14480     case OMPD_target_teams_distribute_simd:
14481       if (OpenMPVersion >= 50 &&
14482           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
14483         CaptureRegion = OMPD_teams;
14484       break;
14485     case OMPD_cancel:
14486     case OMPD_parallel:
14487     case OMPD_parallel_master:
14488     case OMPD_parallel_sections:
14489     case OMPD_parallel_for:
14490     case OMPD_target:
14491     case OMPD_target_teams:
14492     case OMPD_target_teams_distribute:
14493     case OMPD_distribute_parallel_for:
14494     case OMPD_task:
14495     case OMPD_taskloop:
14496     case OMPD_master_taskloop:
14497     case OMPD_target_data:
14498     case OMPD_simd:
14499     case OMPD_for_simd:
14500     case OMPD_distribute_simd:
14501       // Do not capture if-clause expressions.
14502       break;
14503     case OMPD_threadprivate:
14504     case OMPD_allocate:
14505     case OMPD_taskyield:
14506     case OMPD_barrier:
14507     case OMPD_taskwait:
14508     case OMPD_cancellation_point:
14509     case OMPD_flush:
14510     case OMPD_depobj:
14511     case OMPD_scan:
14512     case OMPD_declare_reduction:
14513     case OMPD_declare_mapper:
14514     case OMPD_declare_simd:
14515     case OMPD_declare_variant:
14516     case OMPD_begin_declare_variant:
14517     case OMPD_end_declare_variant:
14518     case OMPD_declare_target:
14519     case OMPD_end_declare_target:
14520     case OMPD_loop:
14521     case OMPD_teams:
14522     case OMPD_tile:
14523     case OMPD_unroll:
14524     case OMPD_for:
14525     case OMPD_sections:
14526     case OMPD_section:
14527     case OMPD_single:
14528     case OMPD_master:
14529     case OMPD_masked:
14530     case OMPD_critical:
14531     case OMPD_taskgroup:
14532     case OMPD_distribute:
14533     case OMPD_ordered:
14534     case OMPD_atomic:
14535     case OMPD_teams_distribute:
14536     case OMPD_requires:
14537     case OMPD_metadirective:
14538       llvm_unreachable("Unexpected OpenMP directive with if-clause");
14539     case OMPD_unknown:
14540     default:
14541       llvm_unreachable("Unknown OpenMP directive");
14542     }
14543     break;
14544   case OMPC_num_threads:
14545     switch (DKind) {
14546     case OMPD_target_parallel:
14547     case OMPD_target_parallel_for:
14548     case OMPD_target_parallel_for_simd:
14549       CaptureRegion = OMPD_target;
14550       break;
14551     case OMPD_teams_distribute_parallel_for:
14552     case OMPD_teams_distribute_parallel_for_simd:
14553     case OMPD_target_teams_distribute_parallel_for:
14554     case OMPD_target_teams_distribute_parallel_for_simd:
14555       CaptureRegion = OMPD_teams;
14556       break;
14557     case OMPD_parallel:
14558     case OMPD_parallel_master:
14559     case OMPD_parallel_sections:
14560     case OMPD_parallel_for:
14561     case OMPD_parallel_for_simd:
14562     case OMPD_distribute_parallel_for:
14563     case OMPD_distribute_parallel_for_simd:
14564     case OMPD_parallel_master_taskloop:
14565     case OMPD_parallel_master_taskloop_simd:
14566       // Do not capture num_threads-clause expressions.
14567       break;
14568     case OMPD_target_data:
14569     case OMPD_target_enter_data:
14570     case OMPD_target_exit_data:
14571     case OMPD_target_update:
14572     case OMPD_target:
14573     case OMPD_target_simd:
14574     case OMPD_target_teams:
14575     case OMPD_target_teams_distribute:
14576     case OMPD_target_teams_distribute_simd:
14577     case OMPD_cancel:
14578     case OMPD_task:
14579     case OMPD_taskloop:
14580     case OMPD_taskloop_simd:
14581     case OMPD_master_taskloop:
14582     case OMPD_master_taskloop_simd:
14583     case OMPD_threadprivate:
14584     case OMPD_allocate:
14585     case OMPD_taskyield:
14586     case OMPD_barrier:
14587     case OMPD_taskwait:
14588     case OMPD_cancellation_point:
14589     case OMPD_flush:
14590     case OMPD_depobj:
14591     case OMPD_scan:
14592     case OMPD_declare_reduction:
14593     case OMPD_declare_mapper:
14594     case OMPD_declare_simd:
14595     case OMPD_declare_variant:
14596     case OMPD_begin_declare_variant:
14597     case OMPD_end_declare_variant:
14598     case OMPD_declare_target:
14599     case OMPD_end_declare_target:
14600     case OMPD_loop:
14601     case OMPD_teams:
14602     case OMPD_simd:
14603     case OMPD_tile:
14604     case OMPD_unroll:
14605     case OMPD_for:
14606     case OMPD_for_simd:
14607     case OMPD_sections:
14608     case OMPD_section:
14609     case OMPD_single:
14610     case OMPD_master:
14611     case OMPD_masked:
14612     case OMPD_critical:
14613     case OMPD_taskgroup:
14614     case OMPD_distribute:
14615     case OMPD_ordered:
14616     case OMPD_atomic:
14617     case OMPD_distribute_simd:
14618     case OMPD_teams_distribute:
14619     case OMPD_teams_distribute_simd:
14620     case OMPD_requires:
14621     case OMPD_metadirective:
14622       llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
14623     case OMPD_unknown:
14624     default:
14625       llvm_unreachable("Unknown OpenMP directive");
14626     }
14627     break;
14628   case OMPC_num_teams:
14629     switch (DKind) {
14630     case OMPD_target_teams:
14631     case OMPD_target_teams_distribute:
14632     case OMPD_target_teams_distribute_simd:
14633     case OMPD_target_teams_distribute_parallel_for:
14634     case OMPD_target_teams_distribute_parallel_for_simd:
14635       CaptureRegion = OMPD_target;
14636       break;
14637     case OMPD_teams_distribute_parallel_for:
14638     case OMPD_teams_distribute_parallel_for_simd:
14639     case OMPD_teams:
14640     case OMPD_teams_distribute:
14641     case OMPD_teams_distribute_simd:
14642       // Do not capture num_teams-clause expressions.
14643       break;
14644     case OMPD_distribute_parallel_for:
14645     case OMPD_distribute_parallel_for_simd:
14646     case OMPD_task:
14647     case OMPD_taskloop:
14648     case OMPD_taskloop_simd:
14649     case OMPD_master_taskloop:
14650     case OMPD_master_taskloop_simd:
14651     case OMPD_parallel_master_taskloop:
14652     case OMPD_parallel_master_taskloop_simd:
14653     case OMPD_target_data:
14654     case OMPD_target_enter_data:
14655     case OMPD_target_exit_data:
14656     case OMPD_target_update:
14657     case OMPD_cancel:
14658     case OMPD_parallel:
14659     case OMPD_parallel_master:
14660     case OMPD_parallel_sections:
14661     case OMPD_parallel_for:
14662     case OMPD_parallel_for_simd:
14663     case OMPD_target:
14664     case OMPD_target_simd:
14665     case OMPD_target_parallel:
14666     case OMPD_target_parallel_for:
14667     case OMPD_target_parallel_for_simd:
14668     case OMPD_threadprivate:
14669     case OMPD_allocate:
14670     case OMPD_taskyield:
14671     case OMPD_barrier:
14672     case OMPD_taskwait:
14673     case OMPD_cancellation_point:
14674     case OMPD_flush:
14675     case OMPD_depobj:
14676     case OMPD_scan:
14677     case OMPD_declare_reduction:
14678     case OMPD_declare_mapper:
14679     case OMPD_declare_simd:
14680     case OMPD_declare_variant:
14681     case OMPD_begin_declare_variant:
14682     case OMPD_end_declare_variant:
14683     case OMPD_declare_target:
14684     case OMPD_end_declare_target:
14685     case OMPD_loop:
14686     case OMPD_simd:
14687     case OMPD_tile:
14688     case OMPD_unroll:
14689     case OMPD_for:
14690     case OMPD_for_simd:
14691     case OMPD_sections:
14692     case OMPD_section:
14693     case OMPD_single:
14694     case OMPD_master:
14695     case OMPD_masked:
14696     case OMPD_critical:
14697     case OMPD_taskgroup:
14698     case OMPD_distribute:
14699     case OMPD_ordered:
14700     case OMPD_atomic:
14701     case OMPD_distribute_simd:
14702     case OMPD_requires:
14703     case OMPD_metadirective:
14704       llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
14705     case OMPD_unknown:
14706     default:
14707       llvm_unreachable("Unknown OpenMP directive");
14708     }
14709     break;
14710   case OMPC_thread_limit:
14711     switch (DKind) {
14712     case OMPD_target_teams:
14713     case OMPD_target_teams_distribute:
14714     case OMPD_target_teams_distribute_simd:
14715     case OMPD_target_teams_distribute_parallel_for:
14716     case OMPD_target_teams_distribute_parallel_for_simd:
14717       CaptureRegion = OMPD_target;
14718       break;
14719     case OMPD_teams_distribute_parallel_for:
14720     case OMPD_teams_distribute_parallel_for_simd:
14721     case OMPD_teams:
14722     case OMPD_teams_distribute:
14723     case OMPD_teams_distribute_simd:
14724       // Do not capture thread_limit-clause expressions.
14725       break;
14726     case OMPD_distribute_parallel_for:
14727     case OMPD_distribute_parallel_for_simd:
14728     case OMPD_task:
14729     case OMPD_taskloop:
14730     case OMPD_taskloop_simd:
14731     case OMPD_master_taskloop:
14732     case OMPD_master_taskloop_simd:
14733     case OMPD_parallel_master_taskloop:
14734     case OMPD_parallel_master_taskloop_simd:
14735     case OMPD_target_data:
14736     case OMPD_target_enter_data:
14737     case OMPD_target_exit_data:
14738     case OMPD_target_update:
14739     case OMPD_cancel:
14740     case OMPD_parallel:
14741     case OMPD_parallel_master:
14742     case OMPD_parallel_sections:
14743     case OMPD_parallel_for:
14744     case OMPD_parallel_for_simd:
14745     case OMPD_target:
14746     case OMPD_target_simd:
14747     case OMPD_target_parallel:
14748     case OMPD_target_parallel_for:
14749     case OMPD_target_parallel_for_simd:
14750     case OMPD_threadprivate:
14751     case OMPD_allocate:
14752     case OMPD_taskyield:
14753     case OMPD_barrier:
14754     case OMPD_taskwait:
14755     case OMPD_cancellation_point:
14756     case OMPD_flush:
14757     case OMPD_depobj:
14758     case OMPD_scan:
14759     case OMPD_declare_reduction:
14760     case OMPD_declare_mapper:
14761     case OMPD_declare_simd:
14762     case OMPD_declare_variant:
14763     case OMPD_begin_declare_variant:
14764     case OMPD_end_declare_variant:
14765     case OMPD_declare_target:
14766     case OMPD_end_declare_target:
14767     case OMPD_loop:
14768     case OMPD_simd:
14769     case OMPD_tile:
14770     case OMPD_unroll:
14771     case OMPD_for:
14772     case OMPD_for_simd:
14773     case OMPD_sections:
14774     case OMPD_section:
14775     case OMPD_single:
14776     case OMPD_master:
14777     case OMPD_masked:
14778     case OMPD_critical:
14779     case OMPD_taskgroup:
14780     case OMPD_distribute:
14781     case OMPD_ordered:
14782     case OMPD_atomic:
14783     case OMPD_distribute_simd:
14784     case OMPD_requires:
14785     case OMPD_metadirective:
14786       llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
14787     case OMPD_unknown:
14788     default:
14789       llvm_unreachable("Unknown OpenMP directive");
14790     }
14791     break;
14792   case OMPC_schedule:
14793     switch (DKind) {
14794     case OMPD_parallel_for:
14795     case OMPD_parallel_for_simd:
14796     case OMPD_distribute_parallel_for:
14797     case OMPD_distribute_parallel_for_simd:
14798     case OMPD_teams_distribute_parallel_for:
14799     case OMPD_teams_distribute_parallel_for_simd:
14800     case OMPD_target_parallel_for:
14801     case OMPD_target_parallel_for_simd:
14802     case OMPD_target_teams_distribute_parallel_for:
14803     case OMPD_target_teams_distribute_parallel_for_simd:
14804       CaptureRegion = OMPD_parallel;
14805       break;
14806     case OMPD_for:
14807     case OMPD_for_simd:
14808       // Do not capture schedule-clause expressions.
14809       break;
14810     case OMPD_task:
14811     case OMPD_taskloop:
14812     case OMPD_taskloop_simd:
14813     case OMPD_master_taskloop:
14814     case OMPD_master_taskloop_simd:
14815     case OMPD_parallel_master_taskloop:
14816     case OMPD_parallel_master_taskloop_simd:
14817     case OMPD_target_data:
14818     case OMPD_target_enter_data:
14819     case OMPD_target_exit_data:
14820     case OMPD_target_update:
14821     case OMPD_teams:
14822     case OMPD_teams_distribute:
14823     case OMPD_teams_distribute_simd:
14824     case OMPD_target_teams_distribute:
14825     case OMPD_target_teams_distribute_simd:
14826     case OMPD_target:
14827     case OMPD_target_simd:
14828     case OMPD_target_parallel:
14829     case OMPD_cancel:
14830     case OMPD_parallel:
14831     case OMPD_parallel_master:
14832     case OMPD_parallel_sections:
14833     case OMPD_threadprivate:
14834     case OMPD_allocate:
14835     case OMPD_taskyield:
14836     case OMPD_barrier:
14837     case OMPD_taskwait:
14838     case OMPD_cancellation_point:
14839     case OMPD_flush:
14840     case OMPD_depobj:
14841     case OMPD_scan:
14842     case OMPD_declare_reduction:
14843     case OMPD_declare_mapper:
14844     case OMPD_declare_simd:
14845     case OMPD_declare_variant:
14846     case OMPD_begin_declare_variant:
14847     case OMPD_end_declare_variant:
14848     case OMPD_declare_target:
14849     case OMPD_end_declare_target:
14850     case OMPD_loop:
14851     case OMPD_simd:
14852     case OMPD_tile:
14853     case OMPD_unroll:
14854     case OMPD_sections:
14855     case OMPD_section:
14856     case OMPD_single:
14857     case OMPD_master:
14858     case OMPD_masked:
14859     case OMPD_critical:
14860     case OMPD_taskgroup:
14861     case OMPD_distribute:
14862     case OMPD_ordered:
14863     case OMPD_atomic:
14864     case OMPD_distribute_simd:
14865     case OMPD_target_teams:
14866     case OMPD_requires:
14867     case OMPD_metadirective:
14868       llvm_unreachable("Unexpected OpenMP directive with schedule clause");
14869     case OMPD_unknown:
14870     default:
14871       llvm_unreachable("Unknown OpenMP directive");
14872     }
14873     break;
14874   case OMPC_dist_schedule:
14875     switch (DKind) {
14876     case OMPD_teams_distribute_parallel_for:
14877     case OMPD_teams_distribute_parallel_for_simd:
14878     case OMPD_teams_distribute:
14879     case OMPD_teams_distribute_simd:
14880     case OMPD_target_teams_distribute_parallel_for:
14881     case OMPD_target_teams_distribute_parallel_for_simd:
14882     case OMPD_target_teams_distribute:
14883     case OMPD_target_teams_distribute_simd:
14884       CaptureRegion = OMPD_teams;
14885       break;
14886     case OMPD_distribute_parallel_for:
14887     case OMPD_distribute_parallel_for_simd:
14888     case OMPD_distribute:
14889     case OMPD_distribute_simd:
14890       // Do not capture dist_schedule-clause expressions.
14891       break;
14892     case OMPD_parallel_for:
14893     case OMPD_parallel_for_simd:
14894     case OMPD_target_parallel_for_simd:
14895     case OMPD_target_parallel_for:
14896     case OMPD_task:
14897     case OMPD_taskloop:
14898     case OMPD_taskloop_simd:
14899     case OMPD_master_taskloop:
14900     case OMPD_master_taskloop_simd:
14901     case OMPD_parallel_master_taskloop:
14902     case OMPD_parallel_master_taskloop_simd:
14903     case OMPD_target_data:
14904     case OMPD_target_enter_data:
14905     case OMPD_target_exit_data:
14906     case OMPD_target_update:
14907     case OMPD_teams:
14908     case OMPD_target:
14909     case OMPD_target_simd:
14910     case OMPD_target_parallel:
14911     case OMPD_cancel:
14912     case OMPD_parallel:
14913     case OMPD_parallel_master:
14914     case OMPD_parallel_sections:
14915     case OMPD_threadprivate:
14916     case OMPD_allocate:
14917     case OMPD_taskyield:
14918     case OMPD_barrier:
14919     case OMPD_taskwait:
14920     case OMPD_cancellation_point:
14921     case OMPD_flush:
14922     case OMPD_depobj:
14923     case OMPD_scan:
14924     case OMPD_declare_reduction:
14925     case OMPD_declare_mapper:
14926     case OMPD_declare_simd:
14927     case OMPD_declare_variant:
14928     case OMPD_begin_declare_variant:
14929     case OMPD_end_declare_variant:
14930     case OMPD_declare_target:
14931     case OMPD_end_declare_target:
14932     case OMPD_loop:
14933     case OMPD_simd:
14934     case OMPD_tile:
14935     case OMPD_unroll:
14936     case OMPD_for:
14937     case OMPD_for_simd:
14938     case OMPD_sections:
14939     case OMPD_section:
14940     case OMPD_single:
14941     case OMPD_master:
14942     case OMPD_masked:
14943     case OMPD_critical:
14944     case OMPD_taskgroup:
14945     case OMPD_ordered:
14946     case OMPD_atomic:
14947     case OMPD_target_teams:
14948     case OMPD_requires:
14949     case OMPD_metadirective:
14950       llvm_unreachable("Unexpected OpenMP directive with dist_schedule clause");
14951     case OMPD_unknown:
14952     default:
14953       llvm_unreachable("Unknown OpenMP directive");
14954     }
14955     break;
14956   case OMPC_device:
14957     switch (DKind) {
14958     case OMPD_target_update:
14959     case OMPD_target_enter_data:
14960     case OMPD_target_exit_data:
14961     case OMPD_target:
14962     case OMPD_target_simd:
14963     case OMPD_target_teams:
14964     case OMPD_target_parallel:
14965     case OMPD_target_teams_distribute:
14966     case OMPD_target_teams_distribute_simd:
14967     case OMPD_target_parallel_for:
14968     case OMPD_target_parallel_for_simd:
14969     case OMPD_target_teams_distribute_parallel_for:
14970     case OMPD_target_teams_distribute_parallel_for_simd:
14971     case OMPD_dispatch:
14972       CaptureRegion = OMPD_task;
14973       break;
14974     case OMPD_target_data:
14975     case OMPD_interop:
14976       // Do not capture device-clause expressions.
14977       break;
14978     case OMPD_teams_distribute_parallel_for:
14979     case OMPD_teams_distribute_parallel_for_simd:
14980     case OMPD_teams:
14981     case OMPD_teams_distribute:
14982     case OMPD_teams_distribute_simd:
14983     case OMPD_distribute_parallel_for:
14984     case OMPD_distribute_parallel_for_simd:
14985     case OMPD_task:
14986     case OMPD_taskloop:
14987     case OMPD_taskloop_simd:
14988     case OMPD_master_taskloop:
14989     case OMPD_master_taskloop_simd:
14990     case OMPD_parallel_master_taskloop:
14991     case OMPD_parallel_master_taskloop_simd:
14992     case OMPD_cancel:
14993     case OMPD_parallel:
14994     case OMPD_parallel_master:
14995     case OMPD_parallel_sections:
14996     case OMPD_parallel_for:
14997     case OMPD_parallel_for_simd:
14998     case OMPD_threadprivate:
14999     case OMPD_allocate:
15000     case OMPD_taskyield:
15001     case OMPD_barrier:
15002     case OMPD_taskwait:
15003     case OMPD_cancellation_point:
15004     case OMPD_flush:
15005     case OMPD_depobj:
15006     case OMPD_scan:
15007     case OMPD_declare_reduction:
15008     case OMPD_declare_mapper:
15009     case OMPD_declare_simd:
15010     case OMPD_declare_variant:
15011     case OMPD_begin_declare_variant:
15012     case OMPD_end_declare_variant:
15013     case OMPD_declare_target:
15014     case OMPD_end_declare_target:
15015     case OMPD_loop:
15016     case OMPD_simd:
15017     case OMPD_tile:
15018     case OMPD_unroll:
15019     case OMPD_for:
15020     case OMPD_for_simd:
15021     case OMPD_sections:
15022     case OMPD_section:
15023     case OMPD_single:
15024     case OMPD_master:
15025     case OMPD_masked:
15026     case OMPD_critical:
15027     case OMPD_taskgroup:
15028     case OMPD_distribute:
15029     case OMPD_ordered:
15030     case OMPD_atomic:
15031     case OMPD_distribute_simd:
15032     case OMPD_requires:
15033     case OMPD_metadirective:
15034       llvm_unreachable("Unexpected OpenMP directive with device-clause");
15035     case OMPD_unknown:
15036     default:
15037       llvm_unreachable("Unknown OpenMP directive");
15038     }
15039     break;
15040   case OMPC_grainsize:
15041   case OMPC_num_tasks:
15042   case OMPC_final:
15043   case OMPC_priority:
15044     switch (DKind) {
15045     case OMPD_task:
15046     case OMPD_taskloop:
15047     case OMPD_taskloop_simd:
15048     case OMPD_master_taskloop:
15049     case OMPD_master_taskloop_simd:
15050       break;
15051     case OMPD_parallel_master_taskloop:
15052     case OMPD_parallel_master_taskloop_simd:
15053       CaptureRegion = OMPD_parallel;
15054       break;
15055     case OMPD_target_update:
15056     case OMPD_target_enter_data:
15057     case OMPD_target_exit_data:
15058     case OMPD_target:
15059     case OMPD_target_simd:
15060     case OMPD_target_teams:
15061     case OMPD_target_parallel:
15062     case OMPD_target_teams_distribute:
15063     case OMPD_target_teams_distribute_simd:
15064     case OMPD_target_parallel_for:
15065     case OMPD_target_parallel_for_simd:
15066     case OMPD_target_teams_distribute_parallel_for:
15067     case OMPD_target_teams_distribute_parallel_for_simd:
15068     case OMPD_target_data:
15069     case OMPD_teams_distribute_parallel_for:
15070     case OMPD_teams_distribute_parallel_for_simd:
15071     case OMPD_teams:
15072     case OMPD_teams_distribute:
15073     case OMPD_teams_distribute_simd:
15074     case OMPD_distribute_parallel_for:
15075     case OMPD_distribute_parallel_for_simd:
15076     case OMPD_cancel:
15077     case OMPD_parallel:
15078     case OMPD_parallel_master:
15079     case OMPD_parallel_sections:
15080     case OMPD_parallel_for:
15081     case OMPD_parallel_for_simd:
15082     case OMPD_threadprivate:
15083     case OMPD_allocate:
15084     case OMPD_taskyield:
15085     case OMPD_barrier:
15086     case OMPD_taskwait:
15087     case OMPD_cancellation_point:
15088     case OMPD_flush:
15089     case OMPD_depobj:
15090     case OMPD_scan:
15091     case OMPD_declare_reduction:
15092     case OMPD_declare_mapper:
15093     case OMPD_declare_simd:
15094     case OMPD_declare_variant:
15095     case OMPD_begin_declare_variant:
15096     case OMPD_end_declare_variant:
15097     case OMPD_declare_target:
15098     case OMPD_end_declare_target:
15099     case OMPD_loop:
15100     case OMPD_simd:
15101     case OMPD_tile:
15102     case OMPD_unroll:
15103     case OMPD_for:
15104     case OMPD_for_simd:
15105     case OMPD_sections:
15106     case OMPD_section:
15107     case OMPD_single:
15108     case OMPD_master:
15109     case OMPD_masked:
15110     case OMPD_critical:
15111     case OMPD_taskgroup:
15112     case OMPD_distribute:
15113     case OMPD_ordered:
15114     case OMPD_atomic:
15115     case OMPD_distribute_simd:
15116     case OMPD_requires:
15117     case OMPD_metadirective:
15118       llvm_unreachable("Unexpected OpenMP directive with grainsize-clause");
15119     case OMPD_unknown:
15120     default:
15121       llvm_unreachable("Unknown OpenMP directive");
15122     }
15123     break;
15124   case OMPC_novariants:
15125   case OMPC_nocontext:
15126     switch (DKind) {
15127     case OMPD_dispatch:
15128       CaptureRegion = OMPD_task;
15129       break;
15130     default:
15131       llvm_unreachable("Unexpected OpenMP directive");
15132     }
15133     break;
15134   case OMPC_filter:
15135     // Do not capture filter-clause expressions.
15136     break;
15137   case OMPC_when:
15138     if (DKind == OMPD_metadirective) {
15139       CaptureRegion = OMPD_metadirective;
15140     } else if (DKind == OMPD_unknown) {
15141       llvm_unreachable("Unknown OpenMP directive");
15142     } else {
15143       llvm_unreachable("Unexpected OpenMP directive with when clause");
15144     }
15145     break;
15146   case OMPC_firstprivate:
15147   case OMPC_lastprivate:
15148   case OMPC_reduction:
15149   case OMPC_task_reduction:
15150   case OMPC_in_reduction:
15151   case OMPC_linear:
15152   case OMPC_default:
15153   case OMPC_proc_bind:
15154   case OMPC_safelen:
15155   case OMPC_simdlen:
15156   case OMPC_sizes:
15157   case OMPC_allocator:
15158   case OMPC_collapse:
15159   case OMPC_private:
15160   case OMPC_shared:
15161   case OMPC_aligned:
15162   case OMPC_copyin:
15163   case OMPC_copyprivate:
15164   case OMPC_ordered:
15165   case OMPC_nowait:
15166   case OMPC_untied:
15167   case OMPC_mergeable:
15168   case OMPC_threadprivate:
15169   case OMPC_allocate:
15170   case OMPC_flush:
15171   case OMPC_depobj:
15172   case OMPC_read:
15173   case OMPC_write:
15174   case OMPC_update:
15175   case OMPC_capture:
15176   case OMPC_compare:
15177   case OMPC_seq_cst:
15178   case OMPC_acq_rel:
15179   case OMPC_acquire:
15180   case OMPC_release:
15181   case OMPC_relaxed:
15182   case OMPC_depend:
15183   case OMPC_threads:
15184   case OMPC_simd:
15185   case OMPC_map:
15186   case OMPC_nogroup:
15187   case OMPC_hint:
15188   case OMPC_defaultmap:
15189   case OMPC_unknown:
15190   case OMPC_uniform:
15191   case OMPC_to:
15192   case OMPC_from:
15193   case OMPC_use_device_ptr:
15194   case OMPC_use_device_addr:
15195   case OMPC_is_device_ptr:
15196   case OMPC_unified_address:
15197   case OMPC_unified_shared_memory:
15198   case OMPC_reverse_offload:
15199   case OMPC_dynamic_allocators:
15200   case OMPC_atomic_default_mem_order:
15201   case OMPC_device_type:
15202   case OMPC_match:
15203   case OMPC_nontemporal:
15204   case OMPC_order:
15205   case OMPC_destroy:
15206   case OMPC_detach:
15207   case OMPC_inclusive:
15208   case OMPC_exclusive:
15209   case OMPC_uses_allocators:
15210   case OMPC_affinity:
15211   case OMPC_bind:
15212   default:
15213     llvm_unreachable("Unexpected OpenMP clause.");
15214   }
15215   return CaptureRegion;
15216 }
15217 
15218 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
15219                                      Expr *Condition, SourceLocation StartLoc,
15220                                      SourceLocation LParenLoc,
15221                                      SourceLocation NameModifierLoc,
15222                                      SourceLocation ColonLoc,
15223                                      SourceLocation EndLoc) {
15224   Expr *ValExpr = Condition;
15225   Stmt *HelperValStmt = nullptr;
15226   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
15227   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
15228       !Condition->isInstantiationDependent() &&
15229       !Condition->containsUnexpandedParameterPack()) {
15230     ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
15231     if (Val.isInvalid())
15232       return nullptr;
15233 
15234     ValExpr = Val.get();
15235 
15236     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
15237     CaptureRegion = getOpenMPCaptureRegionForClause(
15238         DKind, OMPC_if, LangOpts.OpenMP, NameModifier);
15239     if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
15240       ValExpr = MakeFullExpr(ValExpr).get();
15241       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15242       ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
15243       HelperValStmt = buildPreInits(Context, Captures);
15244     }
15245   }
15246 
15247   return new (Context)
15248       OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
15249                   LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
15250 }
15251 
15252 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
15253                                         SourceLocation StartLoc,
15254                                         SourceLocation LParenLoc,
15255                                         SourceLocation EndLoc) {
15256   Expr *ValExpr = Condition;
15257   Stmt *HelperValStmt = nullptr;
15258   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
15259   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
15260       !Condition->isInstantiationDependent() &&
15261       !Condition->containsUnexpandedParameterPack()) {
15262     ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
15263     if (Val.isInvalid())
15264       return nullptr;
15265 
15266     ValExpr = MakeFullExpr(Val.get()).get();
15267 
15268     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
15269     CaptureRegion =
15270         getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP);
15271     if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
15272       ValExpr = MakeFullExpr(ValExpr).get();
15273       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15274       ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
15275       HelperValStmt = buildPreInits(Context, Captures);
15276     }
15277   }
15278 
15279   return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion,
15280                                       StartLoc, LParenLoc, EndLoc);
15281 }
15282 
15283 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
15284                                                         Expr *Op) {
15285   if (!Op)
15286     return ExprError();
15287 
15288   class IntConvertDiagnoser : public ICEConvertDiagnoser {
15289   public:
15290     IntConvertDiagnoser()
15291         : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
15292     SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
15293                                          QualType T) override {
15294       return S.Diag(Loc, diag::err_omp_not_integral) << T;
15295     }
15296     SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
15297                                              QualType T) override {
15298       return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
15299     }
15300     SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
15301                                                QualType T,
15302                                                QualType ConvTy) override {
15303       return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
15304     }
15305     SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
15306                                            QualType ConvTy) override {
15307       return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
15308              << ConvTy->isEnumeralType() << ConvTy;
15309     }
15310     SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
15311                                             QualType T) override {
15312       return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
15313     }
15314     SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
15315                                         QualType ConvTy) override {
15316       return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
15317              << ConvTy->isEnumeralType() << ConvTy;
15318     }
15319     SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
15320                                              QualType) override {
15321       llvm_unreachable("conversion functions are permitted");
15322     }
15323   } ConvertDiagnoser;
15324   return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
15325 }
15326 
15327 static bool
15328 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind,
15329                           bool StrictlyPositive, bool BuildCapture = false,
15330                           OpenMPDirectiveKind DKind = OMPD_unknown,
15331                           OpenMPDirectiveKind *CaptureRegion = nullptr,
15332                           Stmt **HelperValStmt = nullptr) {
15333   if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
15334       !ValExpr->isInstantiationDependent()) {
15335     SourceLocation Loc = ValExpr->getExprLoc();
15336     ExprResult Value =
15337         SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
15338     if (Value.isInvalid())
15339       return false;
15340 
15341     ValExpr = Value.get();
15342     // The expression must evaluate to a non-negative integer value.
15343     if (Optional<llvm::APSInt> Result =
15344             ValExpr->getIntegerConstantExpr(SemaRef.Context)) {
15345       if (Result->isSigned() &&
15346           !((!StrictlyPositive && Result->isNonNegative()) ||
15347             (StrictlyPositive && Result->isStrictlyPositive()))) {
15348         SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
15349             << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
15350             << ValExpr->getSourceRange();
15351         return false;
15352       }
15353     }
15354     if (!BuildCapture)
15355       return true;
15356     *CaptureRegion =
15357         getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP);
15358     if (*CaptureRegion != OMPD_unknown &&
15359         !SemaRef.CurContext->isDependentContext()) {
15360       ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
15361       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15362       ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
15363       *HelperValStmt = buildPreInits(SemaRef.Context, Captures);
15364     }
15365   }
15366   return true;
15367 }
15368 
15369 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
15370                                              SourceLocation StartLoc,
15371                                              SourceLocation LParenLoc,
15372                                              SourceLocation EndLoc) {
15373   Expr *ValExpr = NumThreads;
15374   Stmt *HelperValStmt = nullptr;
15375 
15376   // OpenMP [2.5, Restrictions]
15377   //  The num_threads expression must evaluate to a positive integer value.
15378   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
15379                                  /*StrictlyPositive=*/true))
15380     return nullptr;
15381 
15382   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
15383   OpenMPDirectiveKind CaptureRegion =
15384       getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP);
15385   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
15386     ValExpr = MakeFullExpr(ValExpr).get();
15387     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15388     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
15389     HelperValStmt = buildPreInits(Context, Captures);
15390   }
15391 
15392   return new (Context) OMPNumThreadsClause(
15393       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
15394 }
15395 
15396 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
15397                                                        OpenMPClauseKind CKind,
15398                                                        bool StrictlyPositive,
15399                                                        bool SuppressExprDiags) {
15400   if (!E)
15401     return ExprError();
15402   if (E->isValueDependent() || E->isTypeDependent() ||
15403       E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
15404     return E;
15405 
15406   llvm::APSInt Result;
15407   ExprResult ICE;
15408   if (SuppressExprDiags) {
15409     // Use a custom diagnoser that suppresses 'note' diagnostics about the
15410     // expression.
15411     struct SuppressedDiagnoser : public Sema::VerifyICEDiagnoser {
15412       SuppressedDiagnoser() : VerifyICEDiagnoser(/*Suppress=*/true) {}
15413       Sema::SemaDiagnosticBuilder diagnoseNotICE(Sema &S,
15414                                                  SourceLocation Loc) override {
15415         llvm_unreachable("Diagnostic suppressed");
15416       }
15417     } Diagnoser;
15418     ICE = VerifyIntegerConstantExpression(E, &Result, Diagnoser, AllowFold);
15419   } else {
15420     ICE = VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold);
15421   }
15422   if (ICE.isInvalid())
15423     return ExprError();
15424 
15425   if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
15426       (!StrictlyPositive && !Result.isNonNegative())) {
15427     Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
15428         << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
15429         << E->getSourceRange();
15430     return ExprError();
15431   }
15432   if ((CKind == OMPC_aligned || CKind == OMPC_align) && !Result.isPowerOf2()) {
15433     Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
15434         << E->getSourceRange();
15435     return ExprError();
15436   }
15437   if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
15438     DSAStack->setAssociatedLoops(Result.getExtValue());
15439   else if (CKind == OMPC_ordered)
15440     DSAStack->setAssociatedLoops(Result.getExtValue());
15441   return ICE;
15442 }
15443 
15444 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
15445                                           SourceLocation LParenLoc,
15446                                           SourceLocation EndLoc) {
15447   // OpenMP [2.8.1, simd construct, Description]
15448   // The parameter of the safelen clause must be a constant
15449   // positive integer expression.
15450   ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
15451   if (Safelen.isInvalid())
15452     return nullptr;
15453   return new (Context)
15454       OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
15455 }
15456 
15457 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
15458                                           SourceLocation LParenLoc,
15459                                           SourceLocation EndLoc) {
15460   // OpenMP [2.8.1, simd construct, Description]
15461   // The parameter of the simdlen clause must be a constant
15462   // positive integer expression.
15463   ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
15464   if (Simdlen.isInvalid())
15465     return nullptr;
15466   return new (Context)
15467       OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
15468 }
15469 
15470 /// Tries to find omp_allocator_handle_t type.
15471 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
15472                                     DSAStackTy *Stack) {
15473   QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
15474   if (!OMPAllocatorHandleT.isNull())
15475     return true;
15476   // Build the predefined allocator expressions.
15477   bool ErrorFound = false;
15478   for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
15479     auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
15480     StringRef Allocator =
15481         OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
15482     DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
15483     auto *VD = dyn_cast_or_null<ValueDecl>(
15484         S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
15485     if (!VD) {
15486       ErrorFound = true;
15487       break;
15488     }
15489     QualType AllocatorType =
15490         VD->getType().getNonLValueExprType(S.getASTContext());
15491     ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
15492     if (!Res.isUsable()) {
15493       ErrorFound = true;
15494       break;
15495     }
15496     if (OMPAllocatorHandleT.isNull())
15497       OMPAllocatorHandleT = AllocatorType;
15498     if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) {
15499       ErrorFound = true;
15500       break;
15501     }
15502     Stack->setAllocator(AllocatorKind, Res.get());
15503   }
15504   if (ErrorFound) {
15505     S.Diag(Loc, diag::err_omp_implied_type_not_found)
15506         << "omp_allocator_handle_t";
15507     return false;
15508   }
15509   OMPAllocatorHandleT.addConst();
15510   Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
15511   return true;
15512 }
15513 
15514 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc,
15515                                             SourceLocation LParenLoc,
15516                                             SourceLocation EndLoc) {
15517   // OpenMP [2.11.3, allocate Directive, Description]
15518   // allocator is an expression of omp_allocator_handle_t type.
15519   if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack))
15520     return nullptr;
15521 
15522   ExprResult Allocator = DefaultLvalueConversion(A);
15523   if (Allocator.isInvalid())
15524     return nullptr;
15525   Allocator = PerformImplicitConversion(Allocator.get(),
15526                                         DSAStack->getOMPAllocatorHandleT(),
15527                                         Sema::AA_Initializing,
15528                                         /*AllowExplicit=*/true);
15529   if (Allocator.isInvalid())
15530     return nullptr;
15531   return new (Context)
15532       OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
15533 }
15534 
15535 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
15536                                            SourceLocation StartLoc,
15537                                            SourceLocation LParenLoc,
15538                                            SourceLocation EndLoc) {
15539   // OpenMP [2.7.1, loop construct, Description]
15540   // OpenMP [2.8.1, simd construct, Description]
15541   // OpenMP [2.9.6, distribute construct, Description]
15542   // The parameter of the collapse clause must be a constant
15543   // positive integer expression.
15544   ExprResult NumForLoopsResult =
15545       VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
15546   if (NumForLoopsResult.isInvalid())
15547     return nullptr;
15548   return new (Context)
15549       OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
15550 }
15551 
15552 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
15553                                           SourceLocation EndLoc,
15554                                           SourceLocation LParenLoc,
15555                                           Expr *NumForLoops) {
15556   // OpenMP [2.7.1, loop construct, Description]
15557   // OpenMP [2.8.1, simd construct, Description]
15558   // OpenMP [2.9.6, distribute construct, Description]
15559   // The parameter of the ordered clause must be a constant
15560   // positive integer expression if any.
15561   if (NumForLoops && LParenLoc.isValid()) {
15562     ExprResult NumForLoopsResult =
15563         VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
15564     if (NumForLoopsResult.isInvalid())
15565       return nullptr;
15566     NumForLoops = NumForLoopsResult.get();
15567   } else {
15568     NumForLoops = nullptr;
15569   }
15570   auto *Clause = OMPOrderedClause::Create(
15571       Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0,
15572       StartLoc, LParenLoc, EndLoc);
15573   DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
15574   return Clause;
15575 }
15576 
15577 OMPClause *Sema::ActOnOpenMPSimpleClause(
15578     OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
15579     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
15580   OMPClause *Res = nullptr;
15581   switch (Kind) {
15582   case OMPC_default:
15583     Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument),
15584                                    ArgumentLoc, StartLoc, LParenLoc, EndLoc);
15585     break;
15586   case OMPC_proc_bind:
15587     Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument),
15588                                     ArgumentLoc, StartLoc, LParenLoc, EndLoc);
15589     break;
15590   case OMPC_atomic_default_mem_order:
15591     Res = ActOnOpenMPAtomicDefaultMemOrderClause(
15592         static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
15593         ArgumentLoc, StartLoc, LParenLoc, EndLoc);
15594     break;
15595   case OMPC_order:
15596     Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument),
15597                                  ArgumentLoc, StartLoc, LParenLoc, EndLoc);
15598     break;
15599   case OMPC_update:
15600     Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
15601                                   ArgumentLoc, StartLoc, LParenLoc, EndLoc);
15602     break;
15603   case OMPC_bind:
15604     Res = ActOnOpenMPBindClause(static_cast<OpenMPBindClauseKind>(Argument),
15605                                 ArgumentLoc, StartLoc, LParenLoc, EndLoc);
15606     break;
15607   case OMPC_if:
15608   case OMPC_final:
15609   case OMPC_num_threads:
15610   case OMPC_safelen:
15611   case OMPC_simdlen:
15612   case OMPC_sizes:
15613   case OMPC_allocator:
15614   case OMPC_collapse:
15615   case OMPC_schedule:
15616   case OMPC_private:
15617   case OMPC_firstprivate:
15618   case OMPC_lastprivate:
15619   case OMPC_shared:
15620   case OMPC_reduction:
15621   case OMPC_task_reduction:
15622   case OMPC_in_reduction:
15623   case OMPC_linear:
15624   case OMPC_aligned:
15625   case OMPC_copyin:
15626   case OMPC_copyprivate:
15627   case OMPC_ordered:
15628   case OMPC_nowait:
15629   case OMPC_untied:
15630   case OMPC_mergeable:
15631   case OMPC_threadprivate:
15632   case OMPC_allocate:
15633   case OMPC_flush:
15634   case OMPC_depobj:
15635   case OMPC_read:
15636   case OMPC_write:
15637   case OMPC_capture:
15638   case OMPC_compare:
15639   case OMPC_seq_cst:
15640   case OMPC_acq_rel:
15641   case OMPC_acquire:
15642   case OMPC_release:
15643   case OMPC_relaxed:
15644   case OMPC_depend:
15645   case OMPC_device:
15646   case OMPC_threads:
15647   case OMPC_simd:
15648   case OMPC_map:
15649   case OMPC_num_teams:
15650   case OMPC_thread_limit:
15651   case OMPC_priority:
15652   case OMPC_grainsize:
15653   case OMPC_nogroup:
15654   case OMPC_num_tasks:
15655   case OMPC_hint:
15656   case OMPC_dist_schedule:
15657   case OMPC_defaultmap:
15658   case OMPC_unknown:
15659   case OMPC_uniform:
15660   case OMPC_to:
15661   case OMPC_from:
15662   case OMPC_use_device_ptr:
15663   case OMPC_use_device_addr:
15664   case OMPC_is_device_ptr:
15665   case OMPC_unified_address:
15666   case OMPC_unified_shared_memory:
15667   case OMPC_reverse_offload:
15668   case OMPC_dynamic_allocators:
15669   case OMPC_device_type:
15670   case OMPC_match:
15671   case OMPC_nontemporal:
15672   case OMPC_destroy:
15673   case OMPC_novariants:
15674   case OMPC_nocontext:
15675   case OMPC_detach:
15676   case OMPC_inclusive:
15677   case OMPC_exclusive:
15678   case OMPC_uses_allocators:
15679   case OMPC_affinity:
15680   case OMPC_when:
15681   default:
15682     llvm_unreachable("Clause is not allowed.");
15683   }
15684   return Res;
15685 }
15686 
15687 static std::string
15688 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
15689                         ArrayRef<unsigned> Exclude = llvm::None) {
15690   SmallString<256> Buffer;
15691   llvm::raw_svector_ostream Out(Buffer);
15692   unsigned Skipped = Exclude.size();
15693   auto S = Exclude.begin(), E = Exclude.end();
15694   for (unsigned I = First; I < Last; ++I) {
15695     if (std::find(S, E, I) != E) {
15696       --Skipped;
15697       continue;
15698     }
15699     Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
15700     if (I + Skipped + 2 == Last)
15701       Out << " or ";
15702     else if (I + Skipped + 1 != Last)
15703       Out << ", ";
15704   }
15705   return std::string(Out.str());
15706 }
15707 
15708 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind,
15709                                           SourceLocation KindKwLoc,
15710                                           SourceLocation StartLoc,
15711                                           SourceLocation LParenLoc,
15712                                           SourceLocation EndLoc) {
15713   if (Kind == OMP_DEFAULT_unknown) {
15714     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
15715         << getListOfPossibleValues(OMPC_default, /*First=*/0,
15716                                    /*Last=*/unsigned(OMP_DEFAULT_unknown))
15717         << getOpenMPClauseName(OMPC_default);
15718     return nullptr;
15719   }
15720 
15721   switch (Kind) {
15722   case OMP_DEFAULT_none:
15723     DSAStack->setDefaultDSANone(KindKwLoc);
15724     break;
15725   case OMP_DEFAULT_shared:
15726     DSAStack->setDefaultDSAShared(KindKwLoc);
15727     break;
15728   case OMP_DEFAULT_firstprivate:
15729     DSAStack->setDefaultDSAFirstPrivate(KindKwLoc);
15730     break;
15731   default:
15732     llvm_unreachable("DSA unexpected in OpenMP default clause");
15733   }
15734 
15735   return new (Context)
15736       OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
15737 }
15738 
15739 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind,
15740                                            SourceLocation KindKwLoc,
15741                                            SourceLocation StartLoc,
15742                                            SourceLocation LParenLoc,
15743                                            SourceLocation EndLoc) {
15744   if (Kind == OMP_PROC_BIND_unknown) {
15745     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
15746         << getListOfPossibleValues(OMPC_proc_bind,
15747                                    /*First=*/unsigned(OMP_PROC_BIND_master),
15748                                    /*Last=*/
15749                                    unsigned(LangOpts.OpenMP > 50
15750                                                 ? OMP_PROC_BIND_primary
15751                                                 : OMP_PROC_BIND_spread) +
15752                                        1)
15753         << getOpenMPClauseName(OMPC_proc_bind);
15754     return nullptr;
15755   }
15756   if (Kind == OMP_PROC_BIND_primary && LangOpts.OpenMP < 51)
15757     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
15758         << getListOfPossibleValues(OMPC_proc_bind,
15759                                    /*First=*/unsigned(OMP_PROC_BIND_master),
15760                                    /*Last=*/
15761                                    unsigned(OMP_PROC_BIND_spread) + 1)
15762         << getOpenMPClauseName(OMPC_proc_bind);
15763   return new (Context)
15764       OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
15765 }
15766 
15767 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause(
15768     OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc,
15769     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
15770   if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) {
15771     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
15772         << getListOfPossibleValues(
15773                OMPC_atomic_default_mem_order, /*First=*/0,
15774                /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown)
15775         << getOpenMPClauseName(OMPC_atomic_default_mem_order);
15776     return nullptr;
15777   }
15778   return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
15779                                                       LParenLoc, EndLoc);
15780 }
15781 
15782 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,
15783                                         SourceLocation KindKwLoc,
15784                                         SourceLocation StartLoc,
15785                                         SourceLocation LParenLoc,
15786                                         SourceLocation EndLoc) {
15787   if (Kind == OMPC_ORDER_unknown) {
15788     static_assert(OMPC_ORDER_unknown > 0,
15789                   "OMPC_ORDER_unknown not greater than 0");
15790     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
15791         << getListOfPossibleValues(OMPC_order, /*First=*/0,
15792                                    /*Last=*/OMPC_ORDER_unknown)
15793         << getOpenMPClauseName(OMPC_order);
15794     return nullptr;
15795   }
15796   return new (Context)
15797       OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
15798 }
15799 
15800 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,
15801                                          SourceLocation KindKwLoc,
15802                                          SourceLocation StartLoc,
15803                                          SourceLocation LParenLoc,
15804                                          SourceLocation EndLoc) {
15805   if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source ||
15806       Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) {
15807     SmallVector<unsigned> Except = {OMPC_DEPEND_source, OMPC_DEPEND_sink,
15808                                     OMPC_DEPEND_depobj};
15809     if (LangOpts.OpenMP < 51)
15810       Except.push_back(OMPC_DEPEND_inoutset);
15811     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
15812         << getListOfPossibleValues(OMPC_depend, /*First=*/0,
15813                                    /*Last=*/OMPC_DEPEND_unknown, Except)
15814         << getOpenMPClauseName(OMPC_update);
15815     return nullptr;
15816   }
15817   return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind,
15818                                  EndLoc);
15819 }
15820 
15821 OMPClause *Sema::ActOnOpenMPSizesClause(ArrayRef<Expr *> SizeExprs,
15822                                         SourceLocation StartLoc,
15823                                         SourceLocation LParenLoc,
15824                                         SourceLocation EndLoc) {
15825   for (Expr *SizeExpr : SizeExprs) {
15826     ExprResult NumForLoopsResult = VerifyPositiveIntegerConstantInClause(
15827         SizeExpr, OMPC_sizes, /*StrictlyPositive=*/true);
15828     if (!NumForLoopsResult.isUsable())
15829       return nullptr;
15830   }
15831 
15832   DSAStack->setAssociatedLoops(SizeExprs.size());
15833   return OMPSizesClause::Create(Context, StartLoc, LParenLoc, EndLoc,
15834                                 SizeExprs);
15835 }
15836 
15837 OMPClause *Sema::ActOnOpenMPFullClause(SourceLocation StartLoc,
15838                                        SourceLocation EndLoc) {
15839   return OMPFullClause::Create(Context, StartLoc, EndLoc);
15840 }
15841 
15842 OMPClause *Sema::ActOnOpenMPPartialClause(Expr *FactorExpr,
15843                                           SourceLocation StartLoc,
15844                                           SourceLocation LParenLoc,
15845                                           SourceLocation EndLoc) {
15846   if (FactorExpr) {
15847     // If an argument is specified, it must be a constant (or an unevaluated
15848     // template expression).
15849     ExprResult FactorResult = VerifyPositiveIntegerConstantInClause(
15850         FactorExpr, OMPC_partial, /*StrictlyPositive=*/true);
15851     if (FactorResult.isInvalid())
15852       return nullptr;
15853     FactorExpr = FactorResult.get();
15854   }
15855 
15856   return OMPPartialClause::Create(Context, StartLoc, LParenLoc, EndLoc,
15857                                   FactorExpr);
15858 }
15859 
15860 OMPClause *Sema::ActOnOpenMPAlignClause(Expr *A, SourceLocation StartLoc,
15861                                         SourceLocation LParenLoc,
15862                                         SourceLocation EndLoc) {
15863   ExprResult AlignVal;
15864   AlignVal = VerifyPositiveIntegerConstantInClause(A, OMPC_align);
15865   if (AlignVal.isInvalid())
15866     return nullptr;
15867   return OMPAlignClause::Create(Context, AlignVal.get(), StartLoc, LParenLoc,
15868                                 EndLoc);
15869 }
15870 
15871 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
15872     OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
15873     SourceLocation StartLoc, SourceLocation LParenLoc,
15874     ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
15875     SourceLocation EndLoc) {
15876   OMPClause *Res = nullptr;
15877   switch (Kind) {
15878   case OMPC_schedule:
15879     enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
15880     assert(Argument.size() == NumberOfElements &&
15881            ArgumentLoc.size() == NumberOfElements);
15882     Res = ActOnOpenMPScheduleClause(
15883         static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
15884         static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
15885         static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
15886         StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
15887         ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
15888     break;
15889   case OMPC_if:
15890     assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
15891     Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
15892                               Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
15893                               DelimLoc, EndLoc);
15894     break;
15895   case OMPC_dist_schedule:
15896     Res = ActOnOpenMPDistScheduleClause(
15897         static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
15898         StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
15899     break;
15900   case OMPC_defaultmap:
15901     enum { Modifier, DefaultmapKind };
15902     Res = ActOnOpenMPDefaultmapClause(
15903         static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
15904         static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
15905         StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
15906         EndLoc);
15907     break;
15908   case OMPC_device:
15909     assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
15910     Res = ActOnOpenMPDeviceClause(
15911         static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr,
15912         StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
15913     break;
15914   case OMPC_final:
15915   case OMPC_num_threads:
15916   case OMPC_safelen:
15917   case OMPC_simdlen:
15918   case OMPC_sizes:
15919   case OMPC_allocator:
15920   case OMPC_collapse:
15921   case OMPC_default:
15922   case OMPC_proc_bind:
15923   case OMPC_private:
15924   case OMPC_firstprivate:
15925   case OMPC_lastprivate:
15926   case OMPC_shared:
15927   case OMPC_reduction:
15928   case OMPC_task_reduction:
15929   case OMPC_in_reduction:
15930   case OMPC_linear:
15931   case OMPC_aligned:
15932   case OMPC_copyin:
15933   case OMPC_copyprivate:
15934   case OMPC_ordered:
15935   case OMPC_nowait:
15936   case OMPC_untied:
15937   case OMPC_mergeable:
15938   case OMPC_threadprivate:
15939   case OMPC_allocate:
15940   case OMPC_flush:
15941   case OMPC_depobj:
15942   case OMPC_read:
15943   case OMPC_write:
15944   case OMPC_update:
15945   case OMPC_capture:
15946   case OMPC_compare:
15947   case OMPC_seq_cst:
15948   case OMPC_acq_rel:
15949   case OMPC_acquire:
15950   case OMPC_release:
15951   case OMPC_relaxed:
15952   case OMPC_depend:
15953   case OMPC_threads:
15954   case OMPC_simd:
15955   case OMPC_map:
15956   case OMPC_num_teams:
15957   case OMPC_thread_limit:
15958   case OMPC_priority:
15959   case OMPC_grainsize:
15960   case OMPC_nogroup:
15961   case OMPC_num_tasks:
15962   case OMPC_hint:
15963   case OMPC_unknown:
15964   case OMPC_uniform:
15965   case OMPC_to:
15966   case OMPC_from:
15967   case OMPC_use_device_ptr:
15968   case OMPC_use_device_addr:
15969   case OMPC_is_device_ptr:
15970   case OMPC_unified_address:
15971   case OMPC_unified_shared_memory:
15972   case OMPC_reverse_offload:
15973   case OMPC_dynamic_allocators:
15974   case OMPC_atomic_default_mem_order:
15975   case OMPC_device_type:
15976   case OMPC_match:
15977   case OMPC_nontemporal:
15978   case OMPC_order:
15979   case OMPC_destroy:
15980   case OMPC_novariants:
15981   case OMPC_nocontext:
15982   case OMPC_detach:
15983   case OMPC_inclusive:
15984   case OMPC_exclusive:
15985   case OMPC_uses_allocators:
15986   case OMPC_affinity:
15987   case OMPC_when:
15988   case OMPC_bind:
15989   default:
15990     llvm_unreachable("Clause is not allowed.");
15991   }
15992   return Res;
15993 }
15994 
15995 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
15996                                    OpenMPScheduleClauseModifier M2,
15997                                    SourceLocation M1Loc, SourceLocation M2Loc) {
15998   if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
15999     SmallVector<unsigned, 2> Excluded;
16000     if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
16001       Excluded.push_back(M2);
16002     if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
16003       Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
16004     if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
16005       Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
16006     S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
16007         << getListOfPossibleValues(OMPC_schedule,
16008                                    /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
16009                                    /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
16010                                    Excluded)
16011         << getOpenMPClauseName(OMPC_schedule);
16012     return true;
16013   }
16014   return false;
16015 }
16016 
16017 OMPClause *Sema::ActOnOpenMPScheduleClause(
16018     OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
16019     OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
16020     SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
16021     SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
16022   if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
16023       checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
16024     return nullptr;
16025   // OpenMP, 2.7.1, Loop Construct, Restrictions
16026   // Either the monotonic modifier or the nonmonotonic modifier can be specified
16027   // but not both.
16028   if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
16029       (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
16030        M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
16031       (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
16032        M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
16033     Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
16034         << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
16035         << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
16036     return nullptr;
16037   }
16038   if (Kind == OMPC_SCHEDULE_unknown) {
16039     std::string Values;
16040     if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
16041       unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
16042       Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
16043                                        /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
16044                                        Exclude);
16045     } else {
16046       Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
16047                                        /*Last=*/OMPC_SCHEDULE_unknown);
16048     }
16049     Diag(KindLoc, diag::err_omp_unexpected_clause_value)
16050         << Values << getOpenMPClauseName(OMPC_schedule);
16051     return nullptr;
16052   }
16053   // OpenMP, 2.7.1, Loop Construct, Restrictions
16054   // The nonmonotonic modifier can only be specified with schedule(dynamic) or
16055   // schedule(guided).
16056   // OpenMP 5.0 does not have this restriction.
16057   if (LangOpts.OpenMP < 50 &&
16058       (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
16059        M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
16060       Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
16061     Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
16062          diag::err_omp_schedule_nonmonotonic_static);
16063     return nullptr;
16064   }
16065   Expr *ValExpr = ChunkSize;
16066   Stmt *HelperValStmt = nullptr;
16067   if (ChunkSize) {
16068     if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
16069         !ChunkSize->isInstantiationDependent() &&
16070         !ChunkSize->containsUnexpandedParameterPack()) {
16071       SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
16072       ExprResult Val =
16073           PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
16074       if (Val.isInvalid())
16075         return nullptr;
16076 
16077       ValExpr = Val.get();
16078 
16079       // OpenMP [2.7.1, Restrictions]
16080       //  chunk_size must be a loop invariant integer expression with a positive
16081       //  value.
16082       if (Optional<llvm::APSInt> Result =
16083               ValExpr->getIntegerConstantExpr(Context)) {
16084         if (Result->isSigned() && !Result->isStrictlyPositive()) {
16085           Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
16086               << "schedule" << 1 << ChunkSize->getSourceRange();
16087           return nullptr;
16088         }
16089       } else if (getOpenMPCaptureRegionForClause(
16090                      DSAStack->getCurrentDirective(), OMPC_schedule,
16091                      LangOpts.OpenMP) != OMPD_unknown &&
16092                  !CurContext->isDependentContext()) {
16093         ValExpr = MakeFullExpr(ValExpr).get();
16094         llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16095         ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16096         HelperValStmt = buildPreInits(Context, Captures);
16097       }
16098     }
16099   }
16100 
16101   return new (Context)
16102       OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
16103                         ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
16104 }
16105 
16106 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
16107                                    SourceLocation StartLoc,
16108                                    SourceLocation EndLoc) {
16109   OMPClause *Res = nullptr;
16110   switch (Kind) {
16111   case OMPC_ordered:
16112     Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
16113     break;
16114   case OMPC_nowait:
16115     Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
16116     break;
16117   case OMPC_untied:
16118     Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
16119     break;
16120   case OMPC_mergeable:
16121     Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
16122     break;
16123   case OMPC_read:
16124     Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
16125     break;
16126   case OMPC_write:
16127     Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
16128     break;
16129   case OMPC_update:
16130     Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
16131     break;
16132   case OMPC_capture:
16133     Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
16134     break;
16135   case OMPC_compare:
16136     Res = ActOnOpenMPCompareClause(StartLoc, EndLoc);
16137     break;
16138   case OMPC_seq_cst:
16139     Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
16140     break;
16141   case OMPC_acq_rel:
16142     Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc);
16143     break;
16144   case OMPC_acquire:
16145     Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc);
16146     break;
16147   case OMPC_release:
16148     Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc);
16149     break;
16150   case OMPC_relaxed:
16151     Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc);
16152     break;
16153   case OMPC_threads:
16154     Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
16155     break;
16156   case OMPC_simd:
16157     Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
16158     break;
16159   case OMPC_nogroup:
16160     Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
16161     break;
16162   case OMPC_unified_address:
16163     Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
16164     break;
16165   case OMPC_unified_shared_memory:
16166     Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
16167     break;
16168   case OMPC_reverse_offload:
16169     Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
16170     break;
16171   case OMPC_dynamic_allocators:
16172     Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
16173     break;
16174   case OMPC_destroy:
16175     Res = ActOnOpenMPDestroyClause(/*InteropVar=*/nullptr, StartLoc,
16176                                    /*LParenLoc=*/SourceLocation(),
16177                                    /*VarLoc=*/SourceLocation(), EndLoc);
16178     break;
16179   case OMPC_full:
16180     Res = ActOnOpenMPFullClause(StartLoc, EndLoc);
16181     break;
16182   case OMPC_partial:
16183     Res = ActOnOpenMPPartialClause(nullptr, StartLoc, /*LParenLoc=*/{}, EndLoc);
16184     break;
16185   case OMPC_if:
16186   case OMPC_final:
16187   case OMPC_num_threads:
16188   case OMPC_safelen:
16189   case OMPC_simdlen:
16190   case OMPC_sizes:
16191   case OMPC_allocator:
16192   case OMPC_collapse:
16193   case OMPC_schedule:
16194   case OMPC_private:
16195   case OMPC_firstprivate:
16196   case OMPC_lastprivate:
16197   case OMPC_shared:
16198   case OMPC_reduction:
16199   case OMPC_task_reduction:
16200   case OMPC_in_reduction:
16201   case OMPC_linear:
16202   case OMPC_aligned:
16203   case OMPC_copyin:
16204   case OMPC_copyprivate:
16205   case OMPC_default:
16206   case OMPC_proc_bind:
16207   case OMPC_threadprivate:
16208   case OMPC_allocate:
16209   case OMPC_flush:
16210   case OMPC_depobj:
16211   case OMPC_depend:
16212   case OMPC_device:
16213   case OMPC_map:
16214   case OMPC_num_teams:
16215   case OMPC_thread_limit:
16216   case OMPC_priority:
16217   case OMPC_grainsize:
16218   case OMPC_num_tasks:
16219   case OMPC_hint:
16220   case OMPC_dist_schedule:
16221   case OMPC_defaultmap:
16222   case OMPC_unknown:
16223   case OMPC_uniform:
16224   case OMPC_to:
16225   case OMPC_from:
16226   case OMPC_use_device_ptr:
16227   case OMPC_use_device_addr:
16228   case OMPC_is_device_ptr:
16229   case OMPC_atomic_default_mem_order:
16230   case OMPC_device_type:
16231   case OMPC_match:
16232   case OMPC_nontemporal:
16233   case OMPC_order:
16234   case OMPC_novariants:
16235   case OMPC_nocontext:
16236   case OMPC_detach:
16237   case OMPC_inclusive:
16238   case OMPC_exclusive:
16239   case OMPC_uses_allocators:
16240   case OMPC_affinity:
16241   case OMPC_when:
16242   default:
16243     llvm_unreachable("Clause is not allowed.");
16244   }
16245   return Res;
16246 }
16247 
16248 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
16249                                          SourceLocation EndLoc) {
16250   DSAStack->setNowaitRegion();
16251   return new (Context) OMPNowaitClause(StartLoc, EndLoc);
16252 }
16253 
16254 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
16255                                          SourceLocation EndLoc) {
16256   DSAStack->setUntiedRegion();
16257   return new (Context) OMPUntiedClause(StartLoc, EndLoc);
16258 }
16259 
16260 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
16261                                             SourceLocation EndLoc) {
16262   return new (Context) OMPMergeableClause(StartLoc, EndLoc);
16263 }
16264 
16265 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
16266                                        SourceLocation EndLoc) {
16267   return new (Context) OMPReadClause(StartLoc, EndLoc);
16268 }
16269 
16270 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
16271                                         SourceLocation EndLoc) {
16272   return new (Context) OMPWriteClause(StartLoc, EndLoc);
16273 }
16274 
16275 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
16276                                          SourceLocation EndLoc) {
16277   return OMPUpdateClause::Create(Context, StartLoc, EndLoc);
16278 }
16279 
16280 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
16281                                           SourceLocation EndLoc) {
16282   return new (Context) OMPCaptureClause(StartLoc, EndLoc);
16283 }
16284 
16285 OMPClause *Sema::ActOnOpenMPCompareClause(SourceLocation StartLoc,
16286                                           SourceLocation EndLoc) {
16287   return new (Context) OMPCompareClause(StartLoc, EndLoc);
16288 }
16289 
16290 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
16291                                          SourceLocation EndLoc) {
16292   return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
16293 }
16294 
16295 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc,
16296                                          SourceLocation EndLoc) {
16297   return new (Context) OMPAcqRelClause(StartLoc, EndLoc);
16298 }
16299 
16300 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc,
16301                                           SourceLocation EndLoc) {
16302   return new (Context) OMPAcquireClause(StartLoc, EndLoc);
16303 }
16304 
16305 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc,
16306                                           SourceLocation EndLoc) {
16307   return new (Context) OMPReleaseClause(StartLoc, EndLoc);
16308 }
16309 
16310 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc,
16311                                           SourceLocation EndLoc) {
16312   return new (Context) OMPRelaxedClause(StartLoc, EndLoc);
16313 }
16314 
16315 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
16316                                           SourceLocation EndLoc) {
16317   return new (Context) OMPThreadsClause(StartLoc, EndLoc);
16318 }
16319 
16320 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
16321                                        SourceLocation EndLoc) {
16322   return new (Context) OMPSIMDClause(StartLoc, EndLoc);
16323 }
16324 
16325 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
16326                                           SourceLocation EndLoc) {
16327   return new (Context) OMPNogroupClause(StartLoc, EndLoc);
16328 }
16329 
16330 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
16331                                                  SourceLocation EndLoc) {
16332   return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
16333 }
16334 
16335 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
16336                                                       SourceLocation EndLoc) {
16337   return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
16338 }
16339 
16340 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
16341                                                  SourceLocation EndLoc) {
16342   return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
16343 }
16344 
16345 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
16346                                                     SourceLocation EndLoc) {
16347   return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
16348 }
16349 
16350 StmtResult Sema::ActOnOpenMPInteropDirective(ArrayRef<OMPClause *> Clauses,
16351                                              SourceLocation StartLoc,
16352                                              SourceLocation EndLoc) {
16353 
16354   // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
16355   // At least one action-clause must appear on a directive.
16356   if (!hasClauses(Clauses, OMPC_init, OMPC_use, OMPC_destroy, OMPC_nowait)) {
16357     StringRef Expected = "'init', 'use', 'destroy', or 'nowait'";
16358     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
16359         << Expected << getOpenMPDirectiveName(OMPD_interop);
16360     return StmtError();
16361   }
16362 
16363   // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
16364   // A depend clause can only appear on the directive if a targetsync
16365   // interop-type is present or the interop-var was initialized with
16366   // the targetsync interop-type.
16367 
16368   // If there is any 'init' clause diagnose if there is no 'init' clause with
16369   // interop-type of 'targetsync'. Cases involving other directives cannot be
16370   // diagnosed.
16371   const OMPDependClause *DependClause = nullptr;
16372   bool HasInitClause = false;
16373   bool IsTargetSync = false;
16374   for (const OMPClause *C : Clauses) {
16375     if (IsTargetSync)
16376       break;
16377     if (const auto *InitClause = dyn_cast<OMPInitClause>(C)) {
16378       HasInitClause = true;
16379       if (InitClause->getIsTargetSync())
16380         IsTargetSync = true;
16381     } else if (const auto *DC = dyn_cast<OMPDependClause>(C)) {
16382       DependClause = DC;
16383     }
16384   }
16385   if (DependClause && HasInitClause && !IsTargetSync) {
16386     Diag(DependClause->getBeginLoc(), diag::err_omp_interop_bad_depend_clause);
16387     return StmtError();
16388   }
16389 
16390   // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
16391   // Each interop-var may be specified for at most one action-clause of each
16392   // interop construct.
16393   llvm::SmallPtrSet<const VarDecl *, 4> InteropVars;
16394   for (const OMPClause *C : Clauses) {
16395     OpenMPClauseKind ClauseKind = C->getClauseKind();
16396     const DeclRefExpr *DRE = nullptr;
16397     SourceLocation VarLoc;
16398 
16399     if (ClauseKind == OMPC_init) {
16400       const auto *IC = cast<OMPInitClause>(C);
16401       VarLoc = IC->getVarLoc();
16402       DRE = dyn_cast_or_null<DeclRefExpr>(IC->getInteropVar());
16403     } else if (ClauseKind == OMPC_use) {
16404       const auto *UC = cast<OMPUseClause>(C);
16405       VarLoc = UC->getVarLoc();
16406       DRE = dyn_cast_or_null<DeclRefExpr>(UC->getInteropVar());
16407     } else if (ClauseKind == OMPC_destroy) {
16408       const auto *DC = cast<OMPDestroyClause>(C);
16409       VarLoc = DC->getVarLoc();
16410       DRE = dyn_cast_or_null<DeclRefExpr>(DC->getInteropVar());
16411     }
16412 
16413     if (!DRE)
16414       continue;
16415 
16416     if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
16417       if (!InteropVars.insert(VD->getCanonicalDecl()).second) {
16418         Diag(VarLoc, diag::err_omp_interop_var_multiple_actions) << VD;
16419         return StmtError();
16420       }
16421     }
16422   }
16423 
16424   return OMPInteropDirective::Create(Context, StartLoc, EndLoc, Clauses);
16425 }
16426 
16427 static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr,
16428                                    SourceLocation VarLoc,
16429                                    OpenMPClauseKind Kind) {
16430   if (InteropVarExpr->isValueDependent() || InteropVarExpr->isTypeDependent() ||
16431       InteropVarExpr->isInstantiationDependent() ||
16432       InteropVarExpr->containsUnexpandedParameterPack())
16433     return true;
16434 
16435   const auto *DRE = dyn_cast<DeclRefExpr>(InteropVarExpr);
16436   if (!DRE || !isa<VarDecl>(DRE->getDecl())) {
16437     SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected) << 0;
16438     return false;
16439   }
16440 
16441   // Interop variable should be of type omp_interop_t.
16442   bool HasError = false;
16443   QualType InteropType;
16444   LookupResult Result(SemaRef, &SemaRef.Context.Idents.get("omp_interop_t"),
16445                       VarLoc, Sema::LookupOrdinaryName);
16446   if (SemaRef.LookupName(Result, SemaRef.getCurScope())) {
16447     NamedDecl *ND = Result.getFoundDecl();
16448     if (const auto *TD = dyn_cast<TypeDecl>(ND)) {
16449       InteropType = QualType(TD->getTypeForDecl(), 0);
16450     } else {
16451       HasError = true;
16452     }
16453   } else {
16454     HasError = true;
16455   }
16456 
16457   if (HasError) {
16458     SemaRef.Diag(VarLoc, diag::err_omp_implied_type_not_found)
16459         << "omp_interop_t";
16460     return false;
16461   }
16462 
16463   QualType VarType = InteropVarExpr->getType().getUnqualifiedType();
16464   if (!SemaRef.Context.hasSameType(InteropType, VarType)) {
16465     SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_wrong_type);
16466     return false;
16467   }
16468 
16469   // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
16470   // The interop-var passed to init or destroy must be non-const.
16471   if ((Kind == OMPC_init || Kind == OMPC_destroy) &&
16472       isConstNotMutableType(SemaRef, InteropVarExpr->getType())) {
16473     SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected)
16474         << /*non-const*/ 1;
16475     return false;
16476   }
16477   return true;
16478 }
16479 
16480 OMPClause *
16481 Sema::ActOnOpenMPInitClause(Expr *InteropVar, ArrayRef<Expr *> PrefExprs,
16482                             bool IsTarget, bool IsTargetSync,
16483                             SourceLocation StartLoc, SourceLocation LParenLoc,
16484                             SourceLocation VarLoc, SourceLocation EndLoc) {
16485 
16486   if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_init))
16487     return nullptr;
16488 
16489   // Check prefer_type values.  These foreign-runtime-id values are either
16490   // string literals or constant integral expressions.
16491   for (const Expr *E : PrefExprs) {
16492     if (E->isValueDependent() || E->isTypeDependent() ||
16493         E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
16494       continue;
16495     if (E->isIntegerConstantExpr(Context))
16496       continue;
16497     if (isa<StringLiteral>(E))
16498       continue;
16499     Diag(E->getExprLoc(), diag::err_omp_interop_prefer_type);
16500     return nullptr;
16501   }
16502 
16503   return OMPInitClause::Create(Context, InteropVar, PrefExprs, IsTarget,
16504                                IsTargetSync, StartLoc, LParenLoc, VarLoc,
16505                                EndLoc);
16506 }
16507 
16508 OMPClause *Sema::ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
16509                                       SourceLocation LParenLoc,
16510                                       SourceLocation VarLoc,
16511                                       SourceLocation EndLoc) {
16512 
16513   if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_use))
16514     return nullptr;
16515 
16516   return new (Context)
16517       OMPUseClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
16518 }
16519 
16520 OMPClause *Sema::ActOnOpenMPDestroyClause(Expr *InteropVar,
16521                                           SourceLocation StartLoc,
16522                                           SourceLocation LParenLoc,
16523                                           SourceLocation VarLoc,
16524                                           SourceLocation EndLoc) {
16525   if (InteropVar &&
16526       !isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_destroy))
16527     return nullptr;
16528 
16529   return new (Context)
16530       OMPDestroyClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
16531 }
16532 
16533 OMPClause *Sema::ActOnOpenMPNovariantsClause(Expr *Condition,
16534                                              SourceLocation StartLoc,
16535                                              SourceLocation LParenLoc,
16536                                              SourceLocation EndLoc) {
16537   Expr *ValExpr = Condition;
16538   Stmt *HelperValStmt = nullptr;
16539   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
16540   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
16541       !Condition->isInstantiationDependent() &&
16542       !Condition->containsUnexpandedParameterPack()) {
16543     ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
16544     if (Val.isInvalid())
16545       return nullptr;
16546 
16547     ValExpr = MakeFullExpr(Val.get()).get();
16548 
16549     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16550     CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_novariants,
16551                                                     LangOpts.OpenMP);
16552     if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16553       ValExpr = MakeFullExpr(ValExpr).get();
16554       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16555       ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16556       HelperValStmt = buildPreInits(Context, Captures);
16557     }
16558   }
16559 
16560   return new (Context) OMPNovariantsClause(
16561       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
16562 }
16563 
16564 OMPClause *Sema::ActOnOpenMPNocontextClause(Expr *Condition,
16565                                             SourceLocation StartLoc,
16566                                             SourceLocation LParenLoc,
16567                                             SourceLocation EndLoc) {
16568   Expr *ValExpr = Condition;
16569   Stmt *HelperValStmt = nullptr;
16570   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
16571   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
16572       !Condition->isInstantiationDependent() &&
16573       !Condition->containsUnexpandedParameterPack()) {
16574     ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
16575     if (Val.isInvalid())
16576       return nullptr;
16577 
16578     ValExpr = MakeFullExpr(Val.get()).get();
16579 
16580     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16581     CaptureRegion =
16582         getOpenMPCaptureRegionForClause(DKind, OMPC_nocontext, LangOpts.OpenMP);
16583     if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16584       ValExpr = MakeFullExpr(ValExpr).get();
16585       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16586       ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16587       HelperValStmt = buildPreInits(Context, Captures);
16588     }
16589   }
16590 
16591   return new (Context) OMPNocontextClause(ValExpr, HelperValStmt, CaptureRegion,
16592                                           StartLoc, LParenLoc, EndLoc);
16593 }
16594 
16595 OMPClause *Sema::ActOnOpenMPFilterClause(Expr *ThreadID,
16596                                          SourceLocation StartLoc,
16597                                          SourceLocation LParenLoc,
16598                                          SourceLocation EndLoc) {
16599   Expr *ValExpr = ThreadID;
16600   Stmt *HelperValStmt = nullptr;
16601 
16602   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
16603   OpenMPDirectiveKind CaptureRegion =
16604       getOpenMPCaptureRegionForClause(DKind, OMPC_filter, LangOpts.OpenMP);
16605   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
16606     ValExpr = MakeFullExpr(ValExpr).get();
16607     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
16608     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
16609     HelperValStmt = buildPreInits(Context, Captures);
16610   }
16611 
16612   return new (Context) OMPFilterClause(ValExpr, HelperValStmt, CaptureRegion,
16613                                        StartLoc, LParenLoc, EndLoc);
16614 }
16615 
16616 OMPClause *Sema::ActOnOpenMPVarListClause(
16617     OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr,
16618     const OMPVarListLocTy &Locs, SourceLocation ColonLoc,
16619     CXXScopeSpec &ReductionOrMapperIdScopeSpec,
16620     DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier,
16621     ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
16622     ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit,
16623     SourceLocation ExtraModifierLoc,
16624     ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
16625     ArrayRef<SourceLocation> MotionModifiersLoc) {
16626   SourceLocation StartLoc = Locs.StartLoc;
16627   SourceLocation LParenLoc = Locs.LParenLoc;
16628   SourceLocation EndLoc = Locs.EndLoc;
16629   OMPClause *Res = nullptr;
16630   switch (Kind) {
16631   case OMPC_private:
16632     Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
16633     break;
16634   case OMPC_firstprivate:
16635     Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
16636     break;
16637   case OMPC_lastprivate:
16638     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown &&
16639            "Unexpected lastprivate modifier.");
16640     Res = ActOnOpenMPLastprivateClause(
16641         VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier),
16642         ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
16643     break;
16644   case OMPC_shared:
16645     Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
16646     break;
16647   case OMPC_reduction:
16648     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown &&
16649            "Unexpected lastprivate modifier.");
16650     Res = ActOnOpenMPReductionClause(
16651         VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier),
16652         StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
16653         ReductionOrMapperIdScopeSpec, ReductionOrMapperId);
16654     break;
16655   case OMPC_task_reduction:
16656     Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
16657                                          EndLoc, ReductionOrMapperIdScopeSpec,
16658                                          ReductionOrMapperId);
16659     break;
16660   case OMPC_in_reduction:
16661     Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
16662                                        EndLoc, ReductionOrMapperIdScopeSpec,
16663                                        ReductionOrMapperId);
16664     break;
16665   case OMPC_linear:
16666     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown &&
16667            "Unexpected linear modifier.");
16668     Res = ActOnOpenMPLinearClause(
16669         VarList, DepModOrTailExpr, StartLoc, LParenLoc,
16670         static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc,
16671         ColonLoc, EndLoc);
16672     break;
16673   case OMPC_aligned:
16674     Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc,
16675                                    LParenLoc, ColonLoc, EndLoc);
16676     break;
16677   case OMPC_copyin:
16678     Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
16679     break;
16680   case OMPC_copyprivate:
16681     Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
16682     break;
16683   case OMPC_flush:
16684     Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
16685     break;
16686   case OMPC_depend:
16687     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown &&
16688            "Unexpected depend modifier.");
16689     Res = ActOnOpenMPDependClause(
16690         DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier),
16691         ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
16692     break;
16693   case OMPC_map:
16694     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown &&
16695            "Unexpected map modifier.");
16696     Res = ActOnOpenMPMapClause(
16697         MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec,
16698         ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier),
16699         IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs);
16700     break;
16701   case OMPC_to:
16702     Res = ActOnOpenMPToClause(MotionModifiers, MotionModifiersLoc,
16703                               ReductionOrMapperIdScopeSpec, ReductionOrMapperId,
16704                               ColonLoc, VarList, Locs);
16705     break;
16706   case OMPC_from:
16707     Res = ActOnOpenMPFromClause(MotionModifiers, MotionModifiersLoc,
16708                                 ReductionOrMapperIdScopeSpec,
16709                                 ReductionOrMapperId, ColonLoc, VarList, Locs);
16710     break;
16711   case OMPC_use_device_ptr:
16712     Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
16713     break;
16714   case OMPC_use_device_addr:
16715     Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
16716     break;
16717   case OMPC_is_device_ptr:
16718     Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
16719     break;
16720   case OMPC_allocate:
16721     Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc,
16722                                     LParenLoc, ColonLoc, EndLoc);
16723     break;
16724   case OMPC_nontemporal:
16725     Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc);
16726     break;
16727   case OMPC_inclusive:
16728     Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
16729     break;
16730   case OMPC_exclusive:
16731     Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
16732     break;
16733   case OMPC_affinity:
16734     Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc,
16735                                     DepModOrTailExpr, VarList);
16736     break;
16737   case OMPC_if:
16738   case OMPC_depobj:
16739   case OMPC_final:
16740   case OMPC_num_threads:
16741   case OMPC_safelen:
16742   case OMPC_simdlen:
16743   case OMPC_sizes:
16744   case OMPC_allocator:
16745   case OMPC_collapse:
16746   case OMPC_default:
16747   case OMPC_proc_bind:
16748   case OMPC_schedule:
16749   case OMPC_ordered:
16750   case OMPC_nowait:
16751   case OMPC_untied:
16752   case OMPC_mergeable:
16753   case OMPC_threadprivate:
16754   case OMPC_read:
16755   case OMPC_write:
16756   case OMPC_update:
16757   case OMPC_capture:
16758   case OMPC_compare:
16759   case OMPC_seq_cst:
16760   case OMPC_acq_rel:
16761   case OMPC_acquire:
16762   case OMPC_release:
16763   case OMPC_relaxed:
16764   case OMPC_device:
16765   case OMPC_threads:
16766   case OMPC_simd:
16767   case OMPC_num_teams:
16768   case OMPC_thread_limit:
16769   case OMPC_priority:
16770   case OMPC_grainsize:
16771   case OMPC_nogroup:
16772   case OMPC_num_tasks:
16773   case OMPC_hint:
16774   case OMPC_dist_schedule:
16775   case OMPC_defaultmap:
16776   case OMPC_unknown:
16777   case OMPC_uniform:
16778   case OMPC_unified_address:
16779   case OMPC_unified_shared_memory:
16780   case OMPC_reverse_offload:
16781   case OMPC_dynamic_allocators:
16782   case OMPC_atomic_default_mem_order:
16783   case OMPC_device_type:
16784   case OMPC_match:
16785   case OMPC_order:
16786   case OMPC_destroy:
16787   case OMPC_novariants:
16788   case OMPC_nocontext:
16789   case OMPC_detach:
16790   case OMPC_uses_allocators:
16791   case OMPC_when:
16792   case OMPC_bind:
16793   default:
16794     llvm_unreachable("Clause is not allowed.");
16795   }
16796   return Res;
16797 }
16798 
16799 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
16800                                        ExprObjectKind OK, SourceLocation Loc) {
16801   ExprResult Res = BuildDeclRefExpr(
16802       Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
16803   if (!Res.isUsable())
16804     return ExprError();
16805   if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
16806     Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
16807     if (!Res.isUsable())
16808       return ExprError();
16809   }
16810   if (VK != VK_LValue && Res.get()->isGLValue()) {
16811     Res = DefaultLvalueConversion(Res.get());
16812     if (!Res.isUsable())
16813       return ExprError();
16814   }
16815   return Res;
16816 }
16817 
16818 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
16819                                           SourceLocation StartLoc,
16820                                           SourceLocation LParenLoc,
16821                                           SourceLocation EndLoc) {
16822   SmallVector<Expr *, 8> Vars;
16823   SmallVector<Expr *, 8> PrivateCopies;
16824   for (Expr *RefExpr : VarList) {
16825     assert(RefExpr && "NULL expr in OpenMP private clause.");
16826     SourceLocation ELoc;
16827     SourceRange ERange;
16828     Expr *SimpleRefExpr = RefExpr;
16829     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
16830     if (Res.second) {
16831       // It will be analyzed later.
16832       Vars.push_back(RefExpr);
16833       PrivateCopies.push_back(nullptr);
16834     }
16835     ValueDecl *D = Res.first;
16836     if (!D)
16837       continue;
16838 
16839     QualType Type = D->getType();
16840     auto *VD = dyn_cast<VarDecl>(D);
16841 
16842     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
16843     //  A variable that appears in a private clause must not have an incomplete
16844     //  type or a reference type.
16845     if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
16846       continue;
16847     Type = Type.getNonReferenceType();
16848 
16849     // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
16850     // A variable that is privatized must not have a const-qualified type
16851     // unless it is of class type with a mutable member. This restriction does
16852     // not apply to the firstprivate clause.
16853     //
16854     // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
16855     // A variable that appears in a private clause must not have a
16856     // const-qualified type unless it is of class type with a mutable member.
16857     if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
16858       continue;
16859 
16860     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
16861     // in a Construct]
16862     //  Variables with the predetermined data-sharing attributes may not be
16863     //  listed in data-sharing attributes clauses, except for the cases
16864     //  listed below. For these exceptions only, listing a predetermined
16865     //  variable in a data-sharing attribute clause is allowed and overrides
16866     //  the variable's predetermined data-sharing attributes.
16867     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
16868     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
16869       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
16870                                           << getOpenMPClauseName(OMPC_private);
16871       reportOriginalDsa(*this, DSAStack, D, DVar);
16872       continue;
16873     }
16874 
16875     OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
16876     // Variably modified types are not supported for tasks.
16877     if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
16878         isOpenMPTaskingDirective(CurrDir)) {
16879       Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
16880           << getOpenMPClauseName(OMPC_private) << Type
16881           << getOpenMPDirectiveName(CurrDir);
16882       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
16883                                VarDecl::DeclarationOnly;
16884       Diag(D->getLocation(),
16885            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16886           << D;
16887       continue;
16888     }
16889 
16890     // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
16891     // A list item cannot appear in both a map clause and a data-sharing
16892     // attribute clause on the same construct
16893     //
16894     // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
16895     // A list item cannot appear in both a map clause and a data-sharing
16896     // attribute clause on the same construct unless the construct is a
16897     // combined construct.
16898     if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) ||
16899         CurrDir == OMPD_target) {
16900       OpenMPClauseKind ConflictKind;
16901       if (DSAStack->checkMappableExprComponentListsForDecl(
16902               VD, /*CurrentRegionOnly=*/true,
16903               [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
16904                   OpenMPClauseKind WhereFoundClauseKind) -> bool {
16905                 ConflictKind = WhereFoundClauseKind;
16906                 return true;
16907               })) {
16908         Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
16909             << getOpenMPClauseName(OMPC_private)
16910             << getOpenMPClauseName(ConflictKind)
16911             << getOpenMPDirectiveName(CurrDir);
16912         reportOriginalDsa(*this, DSAStack, D, DVar);
16913         continue;
16914       }
16915     }
16916 
16917     // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
16918     //  A variable of class type (or array thereof) that appears in a private
16919     //  clause requires an accessible, unambiguous default constructor for the
16920     //  class type.
16921     // Generate helper private variable and initialize it with the default
16922     // value. The address of the original variable is replaced by the address of
16923     // the new private variable in CodeGen. This new variable is not added to
16924     // IdResolver, so the code in the OpenMP region uses original variable for
16925     // proper diagnostics.
16926     Type = Type.getUnqualifiedType();
16927     VarDecl *VDPrivate =
16928         buildVarDecl(*this, ELoc, Type, D->getName(),
16929                      D->hasAttrs() ? &D->getAttrs() : nullptr,
16930                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
16931     ActOnUninitializedDecl(VDPrivate);
16932     if (VDPrivate->isInvalidDecl())
16933       continue;
16934     DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
16935         *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
16936 
16937     DeclRefExpr *Ref = nullptr;
16938     if (!VD && !CurContext->isDependentContext())
16939       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
16940     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
16941     Vars.push_back((VD || CurContext->isDependentContext())
16942                        ? RefExpr->IgnoreParens()
16943                        : Ref);
16944     PrivateCopies.push_back(VDPrivateRefExpr);
16945   }
16946 
16947   if (Vars.empty())
16948     return nullptr;
16949 
16950   return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
16951                                   PrivateCopies);
16952 }
16953 
16954 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
16955                                                SourceLocation StartLoc,
16956                                                SourceLocation LParenLoc,
16957                                                SourceLocation EndLoc) {
16958   SmallVector<Expr *, 8> Vars;
16959   SmallVector<Expr *, 8> PrivateCopies;
16960   SmallVector<Expr *, 8> Inits;
16961   SmallVector<Decl *, 4> ExprCaptures;
16962   bool IsImplicitClause =
16963       StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
16964   SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc();
16965 
16966   for (Expr *RefExpr : VarList) {
16967     assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
16968     SourceLocation ELoc;
16969     SourceRange ERange;
16970     Expr *SimpleRefExpr = RefExpr;
16971     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
16972     if (Res.second) {
16973       // It will be analyzed later.
16974       Vars.push_back(RefExpr);
16975       PrivateCopies.push_back(nullptr);
16976       Inits.push_back(nullptr);
16977     }
16978     ValueDecl *D = Res.first;
16979     if (!D)
16980       continue;
16981 
16982     ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
16983     QualType Type = D->getType();
16984     auto *VD = dyn_cast<VarDecl>(D);
16985 
16986     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
16987     //  A variable that appears in a private clause must not have an incomplete
16988     //  type or a reference type.
16989     if (RequireCompleteType(ELoc, Type,
16990                             diag::err_omp_firstprivate_incomplete_type))
16991       continue;
16992     Type = Type.getNonReferenceType();
16993 
16994     // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
16995     //  A variable of class type (or array thereof) that appears in a private
16996     //  clause requires an accessible, unambiguous copy constructor for the
16997     //  class type.
16998     QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
16999 
17000     // If an implicit firstprivate variable found it was checked already.
17001     DSAStackTy::DSAVarData TopDVar;
17002     if (!IsImplicitClause) {
17003       DSAStackTy::DSAVarData DVar =
17004           DSAStack->getTopDSA(D, /*FromParent=*/false);
17005       TopDVar = DVar;
17006       OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
17007       bool IsConstant = ElemType.isConstant(Context);
17008       // OpenMP [2.4.13, Data-sharing Attribute Clauses]
17009       //  A list item that specifies a given variable may not appear in more
17010       // than one clause on the same directive, except that a variable may be
17011       //  specified in both firstprivate and lastprivate clauses.
17012       // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
17013       // A list item may appear in a firstprivate or lastprivate clause but not
17014       // both.
17015       if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
17016           (isOpenMPDistributeDirective(CurrDir) ||
17017            DVar.CKind != OMPC_lastprivate) &&
17018           DVar.RefExpr) {
17019         Diag(ELoc, diag::err_omp_wrong_dsa)
17020             << getOpenMPClauseName(DVar.CKind)
17021             << getOpenMPClauseName(OMPC_firstprivate);
17022         reportOriginalDsa(*this, DSAStack, D, DVar);
17023         continue;
17024       }
17025 
17026       // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
17027       // in a Construct]
17028       //  Variables with the predetermined data-sharing attributes may not be
17029       //  listed in data-sharing attributes clauses, except for the cases
17030       //  listed below. For these exceptions only, listing a predetermined
17031       //  variable in a data-sharing attribute clause is allowed and overrides
17032       //  the variable's predetermined data-sharing attributes.
17033       // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
17034       // in a Construct, C/C++, p.2]
17035       //  Variables with const-qualified type having no mutable member may be
17036       //  listed in a firstprivate clause, even if they are static data members.
17037       if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
17038           DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
17039         Diag(ELoc, diag::err_omp_wrong_dsa)
17040             << getOpenMPClauseName(DVar.CKind)
17041             << getOpenMPClauseName(OMPC_firstprivate);
17042         reportOriginalDsa(*this, DSAStack, D, DVar);
17043         continue;
17044       }
17045 
17046       // OpenMP [2.9.3.4, Restrictions, p.2]
17047       //  A list item that is private within a parallel region must not appear
17048       //  in a firstprivate clause on a worksharing construct if any of the
17049       //  worksharing regions arising from the worksharing construct ever bind
17050       //  to any of the parallel regions arising from the parallel construct.
17051       // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
17052       // A list item that is private within a teams region must not appear in a
17053       // firstprivate clause on a distribute construct if any of the distribute
17054       // regions arising from the distribute construct ever bind to any of the
17055       // teams regions arising from the teams construct.
17056       // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
17057       // A list item that appears in a reduction clause of a teams construct
17058       // must not appear in a firstprivate clause on a distribute construct if
17059       // any of the distribute regions arising from the distribute construct
17060       // ever bind to any of the teams regions arising from the teams construct.
17061       if ((isOpenMPWorksharingDirective(CurrDir) ||
17062            isOpenMPDistributeDirective(CurrDir)) &&
17063           !isOpenMPParallelDirective(CurrDir) &&
17064           !isOpenMPTeamsDirective(CurrDir)) {
17065         DVar = DSAStack->getImplicitDSA(D, true);
17066         if (DVar.CKind != OMPC_shared &&
17067             (isOpenMPParallelDirective(DVar.DKind) ||
17068              isOpenMPTeamsDirective(DVar.DKind) ||
17069              DVar.DKind == OMPD_unknown)) {
17070           Diag(ELoc, diag::err_omp_required_access)
17071               << getOpenMPClauseName(OMPC_firstprivate)
17072               << getOpenMPClauseName(OMPC_shared);
17073           reportOriginalDsa(*this, DSAStack, D, DVar);
17074           continue;
17075         }
17076       }
17077       // OpenMP [2.9.3.4, Restrictions, p.3]
17078       //  A list item that appears in a reduction clause of a parallel construct
17079       //  must not appear in a firstprivate clause on a worksharing or task
17080       //  construct if any of the worksharing or task regions arising from the
17081       //  worksharing or task construct ever bind to any of the parallel regions
17082       //  arising from the parallel construct.
17083       // OpenMP [2.9.3.4, Restrictions, p.4]
17084       //  A list item that appears in a reduction clause in worksharing
17085       //  construct must not appear in a firstprivate clause in a task construct
17086       //  encountered during execution of any of the worksharing regions arising
17087       //  from the worksharing construct.
17088       if (isOpenMPTaskingDirective(CurrDir)) {
17089         DVar = DSAStack->hasInnermostDSA(
17090             D,
17091             [](OpenMPClauseKind C, bool AppliedToPointee) {
17092               return C == OMPC_reduction && !AppliedToPointee;
17093             },
17094             [](OpenMPDirectiveKind K) {
17095               return isOpenMPParallelDirective(K) ||
17096                      isOpenMPWorksharingDirective(K) ||
17097                      isOpenMPTeamsDirective(K);
17098             },
17099             /*FromParent=*/true);
17100         if (DVar.CKind == OMPC_reduction &&
17101             (isOpenMPParallelDirective(DVar.DKind) ||
17102              isOpenMPWorksharingDirective(DVar.DKind) ||
17103              isOpenMPTeamsDirective(DVar.DKind))) {
17104           Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
17105               << getOpenMPDirectiveName(DVar.DKind);
17106           reportOriginalDsa(*this, DSAStack, D, DVar);
17107           continue;
17108         }
17109       }
17110 
17111       // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
17112       // A list item cannot appear in both a map clause and a data-sharing
17113       // attribute clause on the same construct
17114       //
17115       // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
17116       // A list item cannot appear in both a map clause and a data-sharing
17117       // attribute clause on the same construct unless the construct is a
17118       // combined construct.
17119       if ((LangOpts.OpenMP <= 45 &&
17120            isOpenMPTargetExecutionDirective(CurrDir)) ||
17121           CurrDir == OMPD_target) {
17122         OpenMPClauseKind ConflictKind;
17123         if (DSAStack->checkMappableExprComponentListsForDecl(
17124                 VD, /*CurrentRegionOnly=*/true,
17125                 [&ConflictKind](
17126                     OMPClauseMappableExprCommon::MappableExprComponentListRef,
17127                     OpenMPClauseKind WhereFoundClauseKind) {
17128                   ConflictKind = WhereFoundClauseKind;
17129                   return true;
17130                 })) {
17131           Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
17132               << getOpenMPClauseName(OMPC_firstprivate)
17133               << getOpenMPClauseName(ConflictKind)
17134               << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
17135           reportOriginalDsa(*this, DSAStack, D, DVar);
17136           continue;
17137         }
17138       }
17139     }
17140 
17141     // Variably modified types are not supported for tasks.
17142     if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
17143         isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
17144       Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
17145           << getOpenMPClauseName(OMPC_firstprivate) << Type
17146           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
17147       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
17148                                VarDecl::DeclarationOnly;
17149       Diag(D->getLocation(),
17150            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17151           << D;
17152       continue;
17153     }
17154 
17155     Type = Type.getUnqualifiedType();
17156     VarDecl *VDPrivate =
17157         buildVarDecl(*this, ELoc, Type, D->getName(),
17158                      D->hasAttrs() ? &D->getAttrs() : nullptr,
17159                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
17160     // Generate helper private variable and initialize it with the value of the
17161     // original variable. The address of the original variable is replaced by
17162     // the address of the new private variable in the CodeGen. This new variable
17163     // is not added to IdResolver, so the code in the OpenMP region uses
17164     // original variable for proper diagnostics and variable capturing.
17165     Expr *VDInitRefExpr = nullptr;
17166     // For arrays generate initializer for single element and replace it by the
17167     // original array element in CodeGen.
17168     if (Type->isArrayType()) {
17169       VarDecl *VDInit =
17170           buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
17171       VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
17172       Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
17173       ElemType = ElemType.getUnqualifiedType();
17174       VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
17175                                          ".firstprivate.temp");
17176       InitializedEntity Entity =
17177           InitializedEntity::InitializeVariable(VDInitTemp);
17178       InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
17179 
17180       InitializationSequence InitSeq(*this, Entity, Kind, Init);
17181       ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
17182       if (Result.isInvalid())
17183         VDPrivate->setInvalidDecl();
17184       else
17185         VDPrivate->setInit(Result.getAs<Expr>());
17186       // Remove temp variable declaration.
17187       Context.Deallocate(VDInitTemp);
17188     } else {
17189       VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
17190                                      ".firstprivate.temp");
17191       VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
17192                                        RefExpr->getExprLoc());
17193       AddInitializerToDecl(VDPrivate,
17194                            DefaultLvalueConversion(VDInitRefExpr).get(),
17195                            /*DirectInit=*/false);
17196     }
17197     if (VDPrivate->isInvalidDecl()) {
17198       if (IsImplicitClause) {
17199         Diag(RefExpr->getExprLoc(),
17200              diag::note_omp_task_predetermined_firstprivate_here);
17201       }
17202       continue;
17203     }
17204     CurContext->addDecl(VDPrivate);
17205     DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
17206         *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
17207         RefExpr->getExprLoc());
17208     DeclRefExpr *Ref = nullptr;
17209     if (!VD && !CurContext->isDependentContext()) {
17210       if (TopDVar.CKind == OMPC_lastprivate) {
17211         Ref = TopDVar.PrivateCopy;
17212       } else {
17213         Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
17214         if (!isOpenMPCapturedDecl(D))
17215           ExprCaptures.push_back(Ref->getDecl());
17216       }
17217     }
17218     if (!IsImplicitClause)
17219       DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
17220     Vars.push_back((VD || CurContext->isDependentContext())
17221                        ? RefExpr->IgnoreParens()
17222                        : Ref);
17223     PrivateCopies.push_back(VDPrivateRefExpr);
17224     Inits.push_back(VDInitRefExpr);
17225   }
17226 
17227   if (Vars.empty())
17228     return nullptr;
17229 
17230   return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
17231                                        Vars, PrivateCopies, Inits,
17232                                        buildPreInits(Context, ExprCaptures));
17233 }
17234 
17235 OMPClause *Sema::ActOnOpenMPLastprivateClause(
17236     ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind,
17237     SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc,
17238     SourceLocation LParenLoc, SourceLocation EndLoc) {
17239   if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) {
17240     assert(ColonLoc.isValid() && "Colon location must be valid.");
17241     Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
17242         << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0,
17243                                    /*Last=*/OMPC_LASTPRIVATE_unknown)
17244         << getOpenMPClauseName(OMPC_lastprivate);
17245     return nullptr;
17246   }
17247 
17248   SmallVector<Expr *, 8> Vars;
17249   SmallVector<Expr *, 8> SrcExprs;
17250   SmallVector<Expr *, 8> DstExprs;
17251   SmallVector<Expr *, 8> AssignmentOps;
17252   SmallVector<Decl *, 4> ExprCaptures;
17253   SmallVector<Expr *, 4> ExprPostUpdates;
17254   for (Expr *RefExpr : VarList) {
17255     assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
17256     SourceLocation ELoc;
17257     SourceRange ERange;
17258     Expr *SimpleRefExpr = RefExpr;
17259     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17260     if (Res.second) {
17261       // It will be analyzed later.
17262       Vars.push_back(RefExpr);
17263       SrcExprs.push_back(nullptr);
17264       DstExprs.push_back(nullptr);
17265       AssignmentOps.push_back(nullptr);
17266     }
17267     ValueDecl *D = Res.first;
17268     if (!D)
17269       continue;
17270 
17271     QualType Type = D->getType();
17272     auto *VD = dyn_cast<VarDecl>(D);
17273 
17274     // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
17275     //  A variable that appears in a lastprivate clause must not have an
17276     //  incomplete type or a reference type.
17277     if (RequireCompleteType(ELoc, Type,
17278                             diag::err_omp_lastprivate_incomplete_type))
17279       continue;
17280     Type = Type.getNonReferenceType();
17281 
17282     // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
17283     // A variable that is privatized must not have a const-qualified type
17284     // unless it is of class type with a mutable member. This restriction does
17285     // not apply to the firstprivate clause.
17286     //
17287     // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
17288     // A variable that appears in a lastprivate clause must not have a
17289     // const-qualified type unless it is of class type with a mutable member.
17290     if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
17291       continue;
17292 
17293     // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions]
17294     // A list item that appears in a lastprivate clause with the conditional
17295     // modifier must be a scalar variable.
17296     if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) {
17297       Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
17298       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
17299                                VarDecl::DeclarationOnly;
17300       Diag(D->getLocation(),
17301            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17302           << D;
17303       continue;
17304     }
17305 
17306     OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
17307     // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
17308     // in a Construct]
17309     //  Variables with the predetermined data-sharing attributes may not be
17310     //  listed in data-sharing attributes clauses, except for the cases
17311     //  listed below.
17312     // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
17313     // A list item may appear in a firstprivate or lastprivate clause but not
17314     // both.
17315     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
17316     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
17317         (isOpenMPDistributeDirective(CurrDir) ||
17318          DVar.CKind != OMPC_firstprivate) &&
17319         (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
17320       Diag(ELoc, diag::err_omp_wrong_dsa)
17321           << getOpenMPClauseName(DVar.CKind)
17322           << getOpenMPClauseName(OMPC_lastprivate);
17323       reportOriginalDsa(*this, DSAStack, D, DVar);
17324       continue;
17325     }
17326 
17327     // OpenMP [2.14.3.5, Restrictions, p.2]
17328     // A list item that is private within a parallel region, or that appears in
17329     // the reduction clause of a parallel construct, must not appear in a
17330     // lastprivate clause on a worksharing construct if any of the corresponding
17331     // worksharing regions ever binds to any of the corresponding parallel
17332     // regions.
17333     DSAStackTy::DSAVarData TopDVar = DVar;
17334     if (isOpenMPWorksharingDirective(CurrDir) &&
17335         !isOpenMPParallelDirective(CurrDir) &&
17336         !isOpenMPTeamsDirective(CurrDir)) {
17337       DVar = DSAStack->getImplicitDSA(D, true);
17338       if (DVar.CKind != OMPC_shared) {
17339         Diag(ELoc, diag::err_omp_required_access)
17340             << getOpenMPClauseName(OMPC_lastprivate)
17341             << getOpenMPClauseName(OMPC_shared);
17342         reportOriginalDsa(*this, DSAStack, D, DVar);
17343         continue;
17344       }
17345     }
17346 
17347     // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
17348     //  A variable of class type (or array thereof) that appears in a
17349     //  lastprivate clause requires an accessible, unambiguous default
17350     //  constructor for the class type, unless the list item is also specified
17351     //  in a firstprivate clause.
17352     //  A variable of class type (or array thereof) that appears in a
17353     //  lastprivate clause requires an accessible, unambiguous copy assignment
17354     //  operator for the class type.
17355     Type = Context.getBaseElementType(Type).getNonReferenceType();
17356     VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
17357                                   Type.getUnqualifiedType(), ".lastprivate.src",
17358                                   D->hasAttrs() ? &D->getAttrs() : nullptr);
17359     DeclRefExpr *PseudoSrcExpr =
17360         buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
17361     VarDecl *DstVD =
17362         buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
17363                      D->hasAttrs() ? &D->getAttrs() : nullptr);
17364     DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
17365     // For arrays generate assignment operation for single element and replace
17366     // it by the original array element in CodeGen.
17367     ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
17368                                          PseudoDstExpr, PseudoSrcExpr);
17369     if (AssignmentOp.isInvalid())
17370       continue;
17371     AssignmentOp =
17372         ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
17373     if (AssignmentOp.isInvalid())
17374       continue;
17375 
17376     DeclRefExpr *Ref = nullptr;
17377     if (!VD && !CurContext->isDependentContext()) {
17378       if (TopDVar.CKind == OMPC_firstprivate) {
17379         Ref = TopDVar.PrivateCopy;
17380       } else {
17381         Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
17382         if (!isOpenMPCapturedDecl(D))
17383           ExprCaptures.push_back(Ref->getDecl());
17384       }
17385       if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) ||
17386           (!isOpenMPCapturedDecl(D) &&
17387            Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
17388         ExprResult RefRes = DefaultLvalueConversion(Ref);
17389         if (!RefRes.isUsable())
17390           continue;
17391         ExprResult PostUpdateRes =
17392             BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
17393                        RefRes.get());
17394         if (!PostUpdateRes.isUsable())
17395           continue;
17396         ExprPostUpdates.push_back(
17397             IgnoredValueConversions(PostUpdateRes.get()).get());
17398       }
17399     }
17400     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
17401     Vars.push_back((VD || CurContext->isDependentContext())
17402                        ? RefExpr->IgnoreParens()
17403                        : Ref);
17404     SrcExprs.push_back(PseudoSrcExpr);
17405     DstExprs.push_back(PseudoDstExpr);
17406     AssignmentOps.push_back(AssignmentOp.get());
17407   }
17408 
17409   if (Vars.empty())
17410     return nullptr;
17411 
17412   return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
17413                                       Vars, SrcExprs, DstExprs, AssignmentOps,
17414                                       LPKind, LPKindLoc, ColonLoc,
17415                                       buildPreInits(Context, ExprCaptures),
17416                                       buildPostUpdate(*this, ExprPostUpdates));
17417 }
17418 
17419 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
17420                                          SourceLocation StartLoc,
17421                                          SourceLocation LParenLoc,
17422                                          SourceLocation EndLoc) {
17423   SmallVector<Expr *, 8> Vars;
17424   for (Expr *RefExpr : VarList) {
17425     assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
17426     SourceLocation ELoc;
17427     SourceRange ERange;
17428     Expr *SimpleRefExpr = RefExpr;
17429     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17430     if (Res.second) {
17431       // It will be analyzed later.
17432       Vars.push_back(RefExpr);
17433     }
17434     ValueDecl *D = Res.first;
17435     if (!D)
17436       continue;
17437 
17438     auto *VD = dyn_cast<VarDecl>(D);
17439     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
17440     // in a Construct]
17441     //  Variables with the predetermined data-sharing attributes may not be
17442     //  listed in data-sharing attributes clauses, except for the cases
17443     //  listed below. For these exceptions only, listing a predetermined
17444     //  variable in a data-sharing attribute clause is allowed and overrides
17445     //  the variable's predetermined data-sharing attributes.
17446     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
17447     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
17448         DVar.RefExpr) {
17449       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
17450                                           << getOpenMPClauseName(OMPC_shared);
17451       reportOriginalDsa(*this, DSAStack, D, DVar);
17452       continue;
17453     }
17454 
17455     DeclRefExpr *Ref = nullptr;
17456     if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
17457       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
17458     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
17459     Vars.push_back((VD || !Ref || CurContext->isDependentContext())
17460                        ? RefExpr->IgnoreParens()
17461                        : Ref);
17462   }
17463 
17464   if (Vars.empty())
17465     return nullptr;
17466 
17467   return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
17468 }
17469 
17470 namespace {
17471 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
17472   DSAStackTy *Stack;
17473 
17474 public:
17475   bool VisitDeclRefExpr(DeclRefExpr *E) {
17476     if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
17477       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
17478       if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
17479         return false;
17480       if (DVar.CKind != OMPC_unknown)
17481         return true;
17482       DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
17483           VD,
17484           [](OpenMPClauseKind C, bool AppliedToPointee) {
17485             return isOpenMPPrivate(C) && !AppliedToPointee;
17486           },
17487           [](OpenMPDirectiveKind) { return true; },
17488           /*FromParent=*/true);
17489       return DVarPrivate.CKind != OMPC_unknown;
17490     }
17491     return false;
17492   }
17493   bool VisitStmt(Stmt *S) {
17494     for (Stmt *Child : S->children()) {
17495       if (Child && Visit(Child))
17496         return true;
17497     }
17498     return false;
17499   }
17500   explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
17501 };
17502 } // namespace
17503 
17504 namespace {
17505 // Transform MemberExpression for specified FieldDecl of current class to
17506 // DeclRefExpr to specified OMPCapturedExprDecl.
17507 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
17508   typedef TreeTransform<TransformExprToCaptures> BaseTransform;
17509   ValueDecl *Field = nullptr;
17510   DeclRefExpr *CapturedExpr = nullptr;
17511 
17512 public:
17513   TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
17514       : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
17515 
17516   ExprResult TransformMemberExpr(MemberExpr *E) {
17517     if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
17518         E->getMemberDecl() == Field) {
17519       CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
17520       return CapturedExpr;
17521     }
17522     return BaseTransform::TransformMemberExpr(E);
17523   }
17524   DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
17525 };
17526 } // namespace
17527 
17528 template <typename T, typename U>
17529 static T filterLookupForUDReductionAndMapper(
17530     SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
17531   for (U &Set : Lookups) {
17532     for (auto *D : Set) {
17533       if (T Res = Gen(cast<ValueDecl>(D)))
17534         return Res;
17535     }
17536   }
17537   return T();
17538 }
17539 
17540 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
17541   assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case");
17542 
17543   for (auto RD : D->redecls()) {
17544     // Don't bother with extra checks if we already know this one isn't visible.
17545     if (RD == D)
17546       continue;
17547 
17548     auto ND = cast<NamedDecl>(RD);
17549     if (LookupResult::isVisible(SemaRef, ND))
17550       return ND;
17551   }
17552 
17553   return nullptr;
17554 }
17555 
17556 static void
17557 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id,
17558                         SourceLocation Loc, QualType Ty,
17559                         SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
17560   // Find all of the associated namespaces and classes based on the
17561   // arguments we have.
17562   Sema::AssociatedNamespaceSet AssociatedNamespaces;
17563   Sema::AssociatedClassSet AssociatedClasses;
17564   OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
17565   SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
17566                                              AssociatedClasses);
17567 
17568   // C++ [basic.lookup.argdep]p3:
17569   //   Let X be the lookup set produced by unqualified lookup (3.4.1)
17570   //   and let Y be the lookup set produced by argument dependent
17571   //   lookup (defined as follows). If X contains [...] then Y is
17572   //   empty. Otherwise Y is the set of declarations found in the
17573   //   namespaces associated with the argument types as described
17574   //   below. The set of declarations found by the lookup of the name
17575   //   is the union of X and Y.
17576   //
17577   // Here, we compute Y and add its members to the overloaded
17578   // candidate set.
17579   for (auto *NS : AssociatedNamespaces) {
17580     //   When considering an associated namespace, the lookup is the
17581     //   same as the lookup performed when the associated namespace is
17582     //   used as a qualifier (3.4.3.2) except that:
17583     //
17584     //     -- Any using-directives in the associated namespace are
17585     //        ignored.
17586     //
17587     //     -- Any namespace-scope friend functions declared in
17588     //        associated classes are visible within their respective
17589     //        namespaces even if they are not visible during an ordinary
17590     //        lookup (11.4).
17591     DeclContext::lookup_result R = NS->lookup(Id.getName());
17592     for (auto *D : R) {
17593       auto *Underlying = D;
17594       if (auto *USD = dyn_cast<UsingShadowDecl>(D))
17595         Underlying = USD->getTargetDecl();
17596 
17597       if (!isa<OMPDeclareReductionDecl>(Underlying) &&
17598           !isa<OMPDeclareMapperDecl>(Underlying))
17599         continue;
17600 
17601       if (!SemaRef.isVisible(D)) {
17602         D = findAcceptableDecl(SemaRef, D);
17603         if (!D)
17604           continue;
17605         if (auto *USD = dyn_cast<UsingShadowDecl>(D))
17606           Underlying = USD->getTargetDecl();
17607       }
17608       Lookups.emplace_back();
17609       Lookups.back().addDecl(Underlying);
17610     }
17611   }
17612 }
17613 
17614 static ExprResult
17615 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
17616                          Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
17617                          const DeclarationNameInfo &ReductionId, QualType Ty,
17618                          CXXCastPath &BasePath, Expr *UnresolvedReduction) {
17619   if (ReductionIdScopeSpec.isInvalid())
17620     return ExprError();
17621   SmallVector<UnresolvedSet<8>, 4> Lookups;
17622   if (S) {
17623     LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
17624     Lookup.suppressDiagnostics();
17625     while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
17626       NamedDecl *D = Lookup.getRepresentativeDecl();
17627       do {
17628         S = S->getParent();
17629       } while (S && !S->isDeclScope(D));
17630       if (S)
17631         S = S->getParent();
17632       Lookups.emplace_back();
17633       Lookups.back().append(Lookup.begin(), Lookup.end());
17634       Lookup.clear();
17635     }
17636   } else if (auto *ULE =
17637                  cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
17638     Lookups.push_back(UnresolvedSet<8>());
17639     Decl *PrevD = nullptr;
17640     for (NamedDecl *D : ULE->decls()) {
17641       if (D == PrevD)
17642         Lookups.push_back(UnresolvedSet<8>());
17643       else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
17644         Lookups.back().addDecl(DRD);
17645       PrevD = D;
17646     }
17647   }
17648   if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
17649       Ty->isInstantiationDependentType() ||
17650       Ty->containsUnexpandedParameterPack() ||
17651       filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
17652         return !D->isInvalidDecl() &&
17653                (D->getType()->isDependentType() ||
17654                 D->getType()->isInstantiationDependentType() ||
17655                 D->getType()->containsUnexpandedParameterPack());
17656       })) {
17657     UnresolvedSet<8> ResSet;
17658     for (const UnresolvedSet<8> &Set : Lookups) {
17659       if (Set.empty())
17660         continue;
17661       ResSet.append(Set.begin(), Set.end());
17662       // The last item marks the end of all declarations at the specified scope.
17663       ResSet.addDecl(Set[Set.size() - 1]);
17664     }
17665     return UnresolvedLookupExpr::Create(
17666         SemaRef.Context, /*NamingClass=*/nullptr,
17667         ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
17668         /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
17669   }
17670   // Lookup inside the classes.
17671   // C++ [over.match.oper]p3:
17672   //   For a unary operator @ with an operand of a type whose
17673   //   cv-unqualified version is T1, and for a binary operator @ with
17674   //   a left operand of a type whose cv-unqualified version is T1 and
17675   //   a right operand of a type whose cv-unqualified version is T2,
17676   //   three sets of candidate functions, designated member
17677   //   candidates, non-member candidates and built-in candidates, are
17678   //   constructed as follows:
17679   //     -- If T1 is a complete class type or a class currently being
17680   //        defined, the set of member candidates is the result of the
17681   //        qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
17682   //        the set of member candidates is empty.
17683   LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
17684   Lookup.suppressDiagnostics();
17685   if (const auto *TyRec = Ty->getAs<RecordType>()) {
17686     // Complete the type if it can be completed.
17687     // If the type is neither complete nor being defined, bail out now.
17688     if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
17689         TyRec->getDecl()->getDefinition()) {
17690       Lookup.clear();
17691       SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
17692       if (Lookup.empty()) {
17693         Lookups.emplace_back();
17694         Lookups.back().append(Lookup.begin(), Lookup.end());
17695       }
17696     }
17697   }
17698   // Perform ADL.
17699   if (SemaRef.getLangOpts().CPlusPlus)
17700     argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
17701   if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
17702           Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
17703             if (!D->isInvalidDecl() &&
17704                 SemaRef.Context.hasSameType(D->getType(), Ty))
17705               return D;
17706             return nullptr;
17707           }))
17708     return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
17709                                     VK_LValue, Loc);
17710   if (SemaRef.getLangOpts().CPlusPlus) {
17711     if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
17712             Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
17713               if (!D->isInvalidDecl() &&
17714                   SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
17715                   !Ty.isMoreQualifiedThan(D->getType()))
17716                 return D;
17717               return nullptr;
17718             })) {
17719       CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
17720                          /*DetectVirtual=*/false);
17721       if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
17722         if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
17723                 VD->getType().getUnqualifiedType()))) {
17724           if (SemaRef.CheckBaseClassAccess(
17725                   Loc, VD->getType(), Ty, Paths.front(),
17726                   /*DiagID=*/0) != Sema::AR_inaccessible) {
17727             SemaRef.BuildBasePathArray(Paths, BasePath);
17728             return SemaRef.BuildDeclRefExpr(
17729                 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
17730           }
17731         }
17732       }
17733     }
17734   }
17735   if (ReductionIdScopeSpec.isSet()) {
17736     SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
17737         << Ty << Range;
17738     return ExprError();
17739   }
17740   return ExprEmpty();
17741 }
17742 
17743 namespace {
17744 /// Data for the reduction-based clauses.
17745 struct ReductionData {
17746   /// List of original reduction items.
17747   SmallVector<Expr *, 8> Vars;
17748   /// List of private copies of the reduction items.
17749   SmallVector<Expr *, 8> Privates;
17750   /// LHS expressions for the reduction_op expressions.
17751   SmallVector<Expr *, 8> LHSs;
17752   /// RHS expressions for the reduction_op expressions.
17753   SmallVector<Expr *, 8> RHSs;
17754   /// Reduction operation expression.
17755   SmallVector<Expr *, 8> ReductionOps;
17756   /// inscan copy operation expressions.
17757   SmallVector<Expr *, 8> InscanCopyOps;
17758   /// inscan copy temp array expressions for prefix sums.
17759   SmallVector<Expr *, 8> InscanCopyArrayTemps;
17760   /// inscan copy temp array element expressions for prefix sums.
17761   SmallVector<Expr *, 8> InscanCopyArrayElems;
17762   /// Taskgroup descriptors for the corresponding reduction items in
17763   /// in_reduction clauses.
17764   SmallVector<Expr *, 8> TaskgroupDescriptors;
17765   /// List of captures for clause.
17766   SmallVector<Decl *, 4> ExprCaptures;
17767   /// List of postupdate expressions.
17768   SmallVector<Expr *, 4> ExprPostUpdates;
17769   /// Reduction modifier.
17770   unsigned RedModifier = 0;
17771   ReductionData() = delete;
17772   /// Reserves required memory for the reduction data.
17773   ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) {
17774     Vars.reserve(Size);
17775     Privates.reserve(Size);
17776     LHSs.reserve(Size);
17777     RHSs.reserve(Size);
17778     ReductionOps.reserve(Size);
17779     if (RedModifier == OMPC_REDUCTION_inscan) {
17780       InscanCopyOps.reserve(Size);
17781       InscanCopyArrayTemps.reserve(Size);
17782       InscanCopyArrayElems.reserve(Size);
17783     }
17784     TaskgroupDescriptors.reserve(Size);
17785     ExprCaptures.reserve(Size);
17786     ExprPostUpdates.reserve(Size);
17787   }
17788   /// Stores reduction item and reduction operation only (required for dependent
17789   /// reduction item).
17790   void push(Expr *Item, Expr *ReductionOp) {
17791     Vars.emplace_back(Item);
17792     Privates.emplace_back(nullptr);
17793     LHSs.emplace_back(nullptr);
17794     RHSs.emplace_back(nullptr);
17795     ReductionOps.emplace_back(ReductionOp);
17796     TaskgroupDescriptors.emplace_back(nullptr);
17797     if (RedModifier == OMPC_REDUCTION_inscan) {
17798       InscanCopyOps.push_back(nullptr);
17799       InscanCopyArrayTemps.push_back(nullptr);
17800       InscanCopyArrayElems.push_back(nullptr);
17801     }
17802   }
17803   /// Stores reduction data.
17804   void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
17805             Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp,
17806             Expr *CopyArrayElem) {
17807     Vars.emplace_back(Item);
17808     Privates.emplace_back(Private);
17809     LHSs.emplace_back(LHS);
17810     RHSs.emplace_back(RHS);
17811     ReductionOps.emplace_back(ReductionOp);
17812     TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
17813     if (RedModifier == OMPC_REDUCTION_inscan) {
17814       InscanCopyOps.push_back(CopyOp);
17815       InscanCopyArrayTemps.push_back(CopyArrayTemp);
17816       InscanCopyArrayElems.push_back(CopyArrayElem);
17817     } else {
17818       assert(CopyOp == nullptr && CopyArrayTemp == nullptr &&
17819              CopyArrayElem == nullptr &&
17820              "Copy operation must be used for inscan reductions only.");
17821     }
17822   }
17823 };
17824 } // namespace
17825 
17826 static bool checkOMPArraySectionConstantForReduction(
17827     ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
17828     SmallVectorImpl<llvm::APSInt> &ArraySizes) {
17829   const Expr *Length = OASE->getLength();
17830   if (Length == nullptr) {
17831     // For array sections of the form [1:] or [:], we would need to analyze
17832     // the lower bound...
17833     if (OASE->getColonLocFirst().isValid())
17834       return false;
17835 
17836     // This is an array subscript which has implicit length 1!
17837     SingleElement = true;
17838     ArraySizes.push_back(llvm::APSInt::get(1));
17839   } else {
17840     Expr::EvalResult Result;
17841     if (!Length->EvaluateAsInt(Result, Context))
17842       return false;
17843 
17844     llvm::APSInt ConstantLengthValue = Result.Val.getInt();
17845     SingleElement = (ConstantLengthValue.getSExtValue() == 1);
17846     ArraySizes.push_back(ConstantLengthValue);
17847   }
17848 
17849   // Get the base of this array section and walk up from there.
17850   const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
17851 
17852   // We require length = 1 for all array sections except the right-most to
17853   // guarantee that the memory region is contiguous and has no holes in it.
17854   while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
17855     Length = TempOASE->getLength();
17856     if (Length == nullptr) {
17857       // For array sections of the form [1:] or [:], we would need to analyze
17858       // the lower bound...
17859       if (OASE->getColonLocFirst().isValid())
17860         return false;
17861 
17862       // This is an array subscript which has implicit length 1!
17863       ArraySizes.push_back(llvm::APSInt::get(1));
17864     } else {
17865       Expr::EvalResult Result;
17866       if (!Length->EvaluateAsInt(Result, Context))
17867         return false;
17868 
17869       llvm::APSInt ConstantLengthValue = Result.Val.getInt();
17870       if (ConstantLengthValue.getSExtValue() != 1)
17871         return false;
17872 
17873       ArraySizes.push_back(ConstantLengthValue);
17874     }
17875     Base = TempOASE->getBase()->IgnoreParenImpCasts();
17876   }
17877 
17878   // If we have a single element, we don't need to add the implicit lengths.
17879   if (!SingleElement) {
17880     while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
17881       // Has implicit length 1!
17882       ArraySizes.push_back(llvm::APSInt::get(1));
17883       Base = TempASE->getBase()->IgnoreParenImpCasts();
17884     }
17885   }
17886 
17887   // This array section can be privatized as a single value or as a constant
17888   // sized array.
17889   return true;
17890 }
17891 
17892 static BinaryOperatorKind
17893 getRelatedCompoundReductionOp(BinaryOperatorKind BOK) {
17894   if (BOK == BO_Add)
17895     return BO_AddAssign;
17896   if (BOK == BO_Mul)
17897     return BO_MulAssign;
17898   if (BOK == BO_And)
17899     return BO_AndAssign;
17900   if (BOK == BO_Or)
17901     return BO_OrAssign;
17902   if (BOK == BO_Xor)
17903     return BO_XorAssign;
17904   return BOK;
17905 }
17906 
17907 static bool actOnOMPReductionKindClause(
17908     Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
17909     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
17910     SourceLocation ColonLoc, SourceLocation EndLoc,
17911     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
17912     ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
17913   DeclarationName DN = ReductionId.getName();
17914   OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator();
17915   BinaryOperatorKind BOK = BO_Comma;
17916 
17917   ASTContext &Context = S.Context;
17918   // OpenMP [2.14.3.6, reduction clause]
17919   // C
17920   // reduction-identifier is either an identifier or one of the following
17921   // operators: +, -, *,  &, |, ^, && and ||
17922   // C++
17923   // reduction-identifier is either an id-expression or one of the following
17924   // operators: +, -, *, &, |, ^, && and ||
17925   switch (OOK) {
17926   case OO_Plus:
17927   case OO_Minus:
17928     BOK = BO_Add;
17929     break;
17930   case OO_Star:
17931     BOK = BO_Mul;
17932     break;
17933   case OO_Amp:
17934     BOK = BO_And;
17935     break;
17936   case OO_Pipe:
17937     BOK = BO_Or;
17938     break;
17939   case OO_Caret:
17940     BOK = BO_Xor;
17941     break;
17942   case OO_AmpAmp:
17943     BOK = BO_LAnd;
17944     break;
17945   case OO_PipePipe:
17946     BOK = BO_LOr;
17947     break;
17948   case OO_New:
17949   case OO_Delete:
17950   case OO_Array_New:
17951   case OO_Array_Delete:
17952   case OO_Slash:
17953   case OO_Percent:
17954   case OO_Tilde:
17955   case OO_Exclaim:
17956   case OO_Equal:
17957   case OO_Less:
17958   case OO_Greater:
17959   case OO_LessEqual:
17960   case OO_GreaterEqual:
17961   case OO_PlusEqual:
17962   case OO_MinusEqual:
17963   case OO_StarEqual:
17964   case OO_SlashEqual:
17965   case OO_PercentEqual:
17966   case OO_CaretEqual:
17967   case OO_AmpEqual:
17968   case OO_PipeEqual:
17969   case OO_LessLess:
17970   case OO_GreaterGreater:
17971   case OO_LessLessEqual:
17972   case OO_GreaterGreaterEqual:
17973   case OO_EqualEqual:
17974   case OO_ExclaimEqual:
17975   case OO_Spaceship:
17976   case OO_PlusPlus:
17977   case OO_MinusMinus:
17978   case OO_Comma:
17979   case OO_ArrowStar:
17980   case OO_Arrow:
17981   case OO_Call:
17982   case OO_Subscript:
17983   case OO_Conditional:
17984   case OO_Coawait:
17985   case NUM_OVERLOADED_OPERATORS:
17986     llvm_unreachable("Unexpected reduction identifier");
17987   case OO_None:
17988     if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
17989       if (II->isStr("max"))
17990         BOK = BO_GT;
17991       else if (II->isStr("min"))
17992         BOK = BO_LT;
17993     }
17994     break;
17995   }
17996   SourceRange ReductionIdRange;
17997   if (ReductionIdScopeSpec.isValid())
17998     ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
17999   else
18000     ReductionIdRange.setBegin(ReductionId.getBeginLoc());
18001   ReductionIdRange.setEnd(ReductionId.getEndLoc());
18002 
18003   auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
18004   bool FirstIter = true;
18005   for (Expr *RefExpr : VarList) {
18006     assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
18007     // OpenMP [2.1, C/C++]
18008     //  A list item is a variable or array section, subject to the restrictions
18009     //  specified in Section 2.4 on page 42 and in each of the sections
18010     // describing clauses and directives for which a list appears.
18011     // OpenMP  [2.14.3.3, Restrictions, p.1]
18012     //  A variable that is part of another variable (as an array or
18013     //  structure element) cannot appear in a private clause.
18014     if (!FirstIter && IR != ER)
18015       ++IR;
18016     FirstIter = false;
18017     SourceLocation ELoc;
18018     SourceRange ERange;
18019     Expr *SimpleRefExpr = RefExpr;
18020     auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
18021                               /*AllowArraySection=*/true);
18022     if (Res.second) {
18023       // Try to find 'declare reduction' corresponding construct before using
18024       // builtin/overloaded operators.
18025       QualType Type = Context.DependentTy;
18026       CXXCastPath BasePath;
18027       ExprResult DeclareReductionRef = buildDeclareReductionRef(
18028           S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
18029           ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
18030       Expr *ReductionOp = nullptr;
18031       if (S.CurContext->isDependentContext() &&
18032           (DeclareReductionRef.isUnset() ||
18033            isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
18034         ReductionOp = DeclareReductionRef.get();
18035       // It will be analyzed later.
18036       RD.push(RefExpr, ReductionOp);
18037     }
18038     ValueDecl *D = Res.first;
18039     if (!D)
18040       continue;
18041 
18042     Expr *TaskgroupDescriptor = nullptr;
18043     QualType Type;
18044     auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
18045     auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
18046     if (ASE) {
18047       Type = ASE->getType().getNonReferenceType();
18048     } else if (OASE) {
18049       QualType BaseType =
18050           OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
18051       if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
18052         Type = ATy->getElementType();
18053       else
18054         Type = BaseType->getPointeeType();
18055       Type = Type.getNonReferenceType();
18056     } else {
18057       Type = Context.getBaseElementType(D->getType().getNonReferenceType());
18058     }
18059     auto *VD = dyn_cast<VarDecl>(D);
18060 
18061     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
18062     //  A variable that appears in a private clause must not have an incomplete
18063     //  type or a reference type.
18064     if (S.RequireCompleteType(ELoc, D->getType(),
18065                               diag::err_omp_reduction_incomplete_type))
18066       continue;
18067     // OpenMP [2.14.3.6, reduction clause, Restrictions]
18068     // A list item that appears in a reduction clause must not be
18069     // const-qualified.
18070     if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
18071                                   /*AcceptIfMutable*/ false, ASE || OASE))
18072       continue;
18073 
18074     OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
18075     // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
18076     //  If a list-item is a reference type then it must bind to the same object
18077     //  for all threads of the team.
18078     if (!ASE && !OASE) {
18079       if (VD) {
18080         VarDecl *VDDef = VD->getDefinition();
18081         if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
18082           DSARefChecker Check(Stack);
18083           if (Check.Visit(VDDef->getInit())) {
18084             S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
18085                 << getOpenMPClauseName(ClauseKind) << ERange;
18086             S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
18087             continue;
18088           }
18089         }
18090       }
18091 
18092       // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
18093       // in a Construct]
18094       //  Variables with the predetermined data-sharing attributes may not be
18095       //  listed in data-sharing attributes clauses, except for the cases
18096       //  listed below. For these exceptions only, listing a predetermined
18097       //  variable in a data-sharing attribute clause is allowed and overrides
18098       //  the variable's predetermined data-sharing attributes.
18099       // OpenMP [2.14.3.6, Restrictions, p.3]
18100       //  Any number of reduction clauses can be specified on the directive,
18101       //  but a list item can appear only once in the reduction clauses for that
18102       //  directive.
18103       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
18104       if (DVar.CKind == OMPC_reduction) {
18105         S.Diag(ELoc, diag::err_omp_once_referenced)
18106             << getOpenMPClauseName(ClauseKind);
18107         if (DVar.RefExpr)
18108           S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
18109         continue;
18110       }
18111       if (DVar.CKind != OMPC_unknown) {
18112         S.Diag(ELoc, diag::err_omp_wrong_dsa)
18113             << getOpenMPClauseName(DVar.CKind)
18114             << getOpenMPClauseName(OMPC_reduction);
18115         reportOriginalDsa(S, Stack, D, DVar);
18116         continue;
18117       }
18118 
18119       // OpenMP [2.14.3.6, Restrictions, p.1]
18120       //  A list item that appears in a reduction clause of a worksharing
18121       //  construct must be shared in the parallel regions to which any of the
18122       //  worksharing regions arising from the worksharing construct bind.
18123       if (isOpenMPWorksharingDirective(CurrDir) &&
18124           !isOpenMPParallelDirective(CurrDir) &&
18125           !isOpenMPTeamsDirective(CurrDir)) {
18126         DVar = Stack->getImplicitDSA(D, true);
18127         if (DVar.CKind != OMPC_shared) {
18128           S.Diag(ELoc, diag::err_omp_required_access)
18129               << getOpenMPClauseName(OMPC_reduction)
18130               << getOpenMPClauseName(OMPC_shared);
18131           reportOriginalDsa(S, Stack, D, DVar);
18132           continue;
18133         }
18134       }
18135     } else {
18136       // Threadprivates cannot be shared between threads, so dignose if the base
18137       // is a threadprivate variable.
18138       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
18139       if (DVar.CKind == OMPC_threadprivate) {
18140         S.Diag(ELoc, diag::err_omp_wrong_dsa)
18141             << getOpenMPClauseName(DVar.CKind)
18142             << getOpenMPClauseName(OMPC_reduction);
18143         reportOriginalDsa(S, Stack, D, DVar);
18144         continue;
18145       }
18146     }
18147 
18148     // Try to find 'declare reduction' corresponding construct before using
18149     // builtin/overloaded operators.
18150     CXXCastPath BasePath;
18151     ExprResult DeclareReductionRef = buildDeclareReductionRef(
18152         S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
18153         ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
18154     if (DeclareReductionRef.isInvalid())
18155       continue;
18156     if (S.CurContext->isDependentContext() &&
18157         (DeclareReductionRef.isUnset() ||
18158          isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
18159       RD.push(RefExpr, DeclareReductionRef.get());
18160       continue;
18161     }
18162     if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
18163       // Not allowed reduction identifier is found.
18164       S.Diag(ReductionId.getBeginLoc(),
18165              diag::err_omp_unknown_reduction_identifier)
18166           << Type << ReductionIdRange;
18167       continue;
18168     }
18169 
18170     // OpenMP [2.14.3.6, reduction clause, Restrictions]
18171     // The type of a list item that appears in a reduction clause must be valid
18172     // for the reduction-identifier. For a max or min reduction in C, the type
18173     // of the list item must be an allowed arithmetic data type: char, int,
18174     // float, double, or _Bool, possibly modified with long, short, signed, or
18175     // unsigned. For a max or min reduction in C++, the type of the list item
18176     // must be an allowed arithmetic data type: char, wchar_t, int, float,
18177     // double, or bool, possibly modified with long, short, signed, or unsigned.
18178     if (DeclareReductionRef.isUnset()) {
18179       if ((BOK == BO_GT || BOK == BO_LT) &&
18180           !(Type->isScalarType() ||
18181             (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
18182         S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
18183             << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
18184         if (!ASE && !OASE) {
18185           bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18186                                    VarDecl::DeclarationOnly;
18187           S.Diag(D->getLocation(),
18188                  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18189               << D;
18190         }
18191         continue;
18192       }
18193       if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
18194           !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
18195         S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
18196             << getOpenMPClauseName(ClauseKind);
18197         if (!ASE && !OASE) {
18198           bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18199                                    VarDecl::DeclarationOnly;
18200           S.Diag(D->getLocation(),
18201                  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18202               << D;
18203         }
18204         continue;
18205       }
18206     }
18207 
18208     Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
18209     VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
18210                                   D->hasAttrs() ? &D->getAttrs() : nullptr);
18211     VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
18212                                   D->hasAttrs() ? &D->getAttrs() : nullptr);
18213     QualType PrivateTy = Type;
18214 
18215     // Try if we can determine constant lengths for all array sections and avoid
18216     // the VLA.
18217     bool ConstantLengthOASE = false;
18218     if (OASE) {
18219       bool SingleElement;
18220       llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
18221       ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
18222           Context, OASE, SingleElement, ArraySizes);
18223 
18224       // If we don't have a single element, we must emit a constant array type.
18225       if (ConstantLengthOASE && !SingleElement) {
18226         for (llvm::APSInt &Size : ArraySizes)
18227           PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr,
18228                                                    ArrayType::Normal,
18229                                                    /*IndexTypeQuals=*/0);
18230       }
18231     }
18232 
18233     if ((OASE && !ConstantLengthOASE) ||
18234         (!OASE && !ASE &&
18235          D->getType().getNonReferenceType()->isVariablyModifiedType())) {
18236       if (!Context.getTargetInfo().isVLASupported()) {
18237         if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) {
18238           S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
18239           S.Diag(ELoc, diag::note_vla_unsupported);
18240           continue;
18241         } else {
18242           S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
18243           S.targetDiag(ELoc, diag::note_vla_unsupported);
18244         }
18245       }
18246       // For arrays/array sections only:
18247       // Create pseudo array type for private copy. The size for this array will
18248       // be generated during codegen.
18249       // For array subscripts or single variables Private Ty is the same as Type
18250       // (type of the variable or single array element).
18251       PrivateTy = Context.getVariableArrayType(
18252           Type,
18253           new (Context)
18254               OpaqueValueExpr(ELoc, Context.getSizeType(), VK_PRValue),
18255           ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
18256     } else if (!ASE && !OASE &&
18257                Context.getAsArrayType(D->getType().getNonReferenceType())) {
18258       PrivateTy = D->getType().getNonReferenceType();
18259     }
18260     // Private copy.
18261     VarDecl *PrivateVD =
18262         buildVarDecl(S, ELoc, PrivateTy, D->getName(),
18263                      D->hasAttrs() ? &D->getAttrs() : nullptr,
18264                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
18265     // Add initializer for private variable.
18266     Expr *Init = nullptr;
18267     DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
18268     DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
18269     if (DeclareReductionRef.isUsable()) {
18270       auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
18271       auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
18272       if (DRD->getInitializer()) {
18273         Init = DRDRef;
18274         RHSVD->setInit(DRDRef);
18275         RHSVD->setInitStyle(VarDecl::CallInit);
18276       }
18277     } else {
18278       switch (BOK) {
18279       case BO_Add:
18280       case BO_Xor:
18281       case BO_Or:
18282       case BO_LOr:
18283         // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
18284         if (Type->isScalarType() || Type->isAnyComplexType())
18285           Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
18286         break;
18287       case BO_Mul:
18288       case BO_LAnd:
18289         if (Type->isScalarType() || Type->isAnyComplexType()) {
18290           // '*' and '&&' reduction ops - initializer is '1'.
18291           Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
18292         }
18293         break;
18294       case BO_And: {
18295         // '&' reduction op - initializer is '~0'.
18296         QualType OrigType = Type;
18297         if (auto *ComplexTy = OrigType->getAs<ComplexType>())
18298           Type = ComplexTy->getElementType();
18299         if (Type->isRealFloatingType()) {
18300           llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue(
18301               Context.getFloatTypeSemantics(Type));
18302           Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
18303                                          Type, ELoc);
18304         } else if (Type->isScalarType()) {
18305           uint64_t Size = Context.getTypeSize(Type);
18306           QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
18307           llvm::APInt InitValue = llvm::APInt::getAllOnes(Size);
18308           Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
18309         }
18310         if (Init && OrigType->isAnyComplexType()) {
18311           // Init = 0xFFFF + 0xFFFFi;
18312           auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
18313           Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
18314         }
18315         Type = OrigType;
18316         break;
18317       }
18318       case BO_LT:
18319       case BO_GT: {
18320         // 'min' reduction op - initializer is 'Largest representable number in
18321         // the reduction list item type'.
18322         // 'max' reduction op - initializer is 'Least representable number in
18323         // the reduction list item type'.
18324         if (Type->isIntegerType() || Type->isPointerType()) {
18325           bool IsSigned = Type->hasSignedIntegerRepresentation();
18326           uint64_t Size = Context.getTypeSize(Type);
18327           QualType IntTy =
18328               Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
18329           llvm::APInt InitValue =
18330               (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
18331                                         : llvm::APInt::getMinValue(Size)
18332               : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
18333                              : llvm::APInt::getMaxValue(Size);
18334           Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
18335           if (Type->isPointerType()) {
18336             // Cast to pointer type.
18337             ExprResult CastExpr = S.BuildCStyleCastExpr(
18338                 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
18339             if (CastExpr.isInvalid())
18340               continue;
18341             Init = CastExpr.get();
18342           }
18343         } else if (Type->isRealFloatingType()) {
18344           llvm::APFloat InitValue = llvm::APFloat::getLargest(
18345               Context.getFloatTypeSemantics(Type), BOK != BO_LT);
18346           Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
18347                                          Type, ELoc);
18348         }
18349         break;
18350       }
18351       case BO_PtrMemD:
18352       case BO_PtrMemI:
18353       case BO_MulAssign:
18354       case BO_Div:
18355       case BO_Rem:
18356       case BO_Sub:
18357       case BO_Shl:
18358       case BO_Shr:
18359       case BO_LE:
18360       case BO_GE:
18361       case BO_EQ:
18362       case BO_NE:
18363       case BO_Cmp:
18364       case BO_AndAssign:
18365       case BO_XorAssign:
18366       case BO_OrAssign:
18367       case BO_Assign:
18368       case BO_AddAssign:
18369       case BO_SubAssign:
18370       case BO_DivAssign:
18371       case BO_RemAssign:
18372       case BO_ShlAssign:
18373       case BO_ShrAssign:
18374       case BO_Comma:
18375         llvm_unreachable("Unexpected reduction operation");
18376       }
18377     }
18378     if (Init && DeclareReductionRef.isUnset()) {
18379       S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
18380       // Store initializer for single element in private copy. Will be used
18381       // during codegen.
18382       PrivateVD->setInit(RHSVD->getInit());
18383       PrivateVD->setInitStyle(RHSVD->getInitStyle());
18384     } else if (!Init) {
18385       S.ActOnUninitializedDecl(RHSVD);
18386       // Store initializer for single element in private copy. Will be used
18387       // during codegen.
18388       PrivateVD->setInit(RHSVD->getInit());
18389       PrivateVD->setInitStyle(RHSVD->getInitStyle());
18390     }
18391     if (RHSVD->isInvalidDecl())
18392       continue;
18393     if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) {
18394       S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
18395           << Type << ReductionIdRange;
18396       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18397                                VarDecl::DeclarationOnly;
18398       S.Diag(D->getLocation(),
18399              IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18400           << D;
18401       continue;
18402     }
18403     DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
18404     ExprResult ReductionOp;
18405     if (DeclareReductionRef.isUsable()) {
18406       QualType RedTy = DeclareReductionRef.get()->getType();
18407       QualType PtrRedTy = Context.getPointerType(RedTy);
18408       ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
18409       ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
18410       if (!BasePath.empty()) {
18411         LHS = S.DefaultLvalueConversion(LHS.get());
18412         RHS = S.DefaultLvalueConversion(RHS.get());
18413         LHS = ImplicitCastExpr::Create(
18414             Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath,
18415             LHS.get()->getValueKind(), FPOptionsOverride());
18416         RHS = ImplicitCastExpr::Create(
18417             Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath,
18418             RHS.get()->getValueKind(), FPOptionsOverride());
18419       }
18420       FunctionProtoType::ExtProtoInfo EPI;
18421       QualType Params[] = {PtrRedTy, PtrRedTy};
18422       QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
18423       auto *OVE = new (Context) OpaqueValueExpr(
18424           ELoc, Context.getPointerType(FnTy), VK_PRValue, OK_Ordinary,
18425           S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
18426       Expr *Args[] = {LHS.get(), RHS.get()};
18427       ReductionOp =
18428           CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_PRValue, ELoc,
18429                            S.CurFPFeatureOverrides());
18430     } else {
18431       BinaryOperatorKind CombBOK = getRelatedCompoundReductionOp(BOK);
18432       if (Type->isRecordType() && CombBOK != BOK) {
18433         Sema::TentativeAnalysisScope Trap(S);
18434         ReductionOp =
18435             S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
18436                          CombBOK, LHSDRE, RHSDRE);
18437       }
18438       if (!ReductionOp.isUsable()) {
18439         ReductionOp =
18440             S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), BOK,
18441                          LHSDRE, RHSDRE);
18442         if (ReductionOp.isUsable()) {
18443           if (BOK != BO_LT && BOK != BO_GT) {
18444             ReductionOp =
18445                 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
18446                              BO_Assign, LHSDRE, ReductionOp.get());
18447           } else {
18448             auto *ConditionalOp = new (Context)
18449                 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc,
18450                                     RHSDRE, Type, VK_LValue, OK_Ordinary);
18451             ReductionOp =
18452                 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
18453                              BO_Assign, LHSDRE, ConditionalOp);
18454           }
18455         }
18456       }
18457       if (ReductionOp.isUsable())
18458         ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
18459                                             /*DiscardedValue*/ false);
18460       if (!ReductionOp.isUsable())
18461         continue;
18462     }
18463 
18464     // Add copy operations for inscan reductions.
18465     // LHS = RHS;
18466     ExprResult CopyOpRes, TempArrayRes, TempArrayElem;
18467     if (ClauseKind == OMPC_reduction &&
18468         RD.RedModifier == OMPC_REDUCTION_inscan) {
18469       ExprResult RHS = S.DefaultLvalueConversion(RHSDRE);
18470       CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE,
18471                                RHS.get());
18472       if (!CopyOpRes.isUsable())
18473         continue;
18474       CopyOpRes =
18475           S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true);
18476       if (!CopyOpRes.isUsable())
18477         continue;
18478       // For simd directive and simd-based directives in simd mode no need to
18479       // construct temp array, need just a single temp element.
18480       if (Stack->getCurrentDirective() == OMPD_simd ||
18481           (S.getLangOpts().OpenMPSimd &&
18482            isOpenMPSimdDirective(Stack->getCurrentDirective()))) {
18483         VarDecl *TempArrayVD =
18484             buildVarDecl(S, ELoc, PrivateTy, D->getName(),
18485                          D->hasAttrs() ? &D->getAttrs() : nullptr);
18486         // Add a constructor to the temp decl.
18487         S.ActOnUninitializedDecl(TempArrayVD);
18488         TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc);
18489       } else {
18490         // Build temp array for prefix sum.
18491         auto *Dim = new (S.Context)
18492             OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue);
18493         QualType ArrayTy =
18494             S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal,
18495                                            /*IndexTypeQuals=*/0, {ELoc, ELoc});
18496         VarDecl *TempArrayVD =
18497             buildVarDecl(S, ELoc, ArrayTy, D->getName(),
18498                          D->hasAttrs() ? &D->getAttrs() : nullptr);
18499         // Add a constructor to the temp decl.
18500         S.ActOnUninitializedDecl(TempArrayVD);
18501         TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc);
18502         TempArrayElem =
18503             S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get());
18504         auto *Idx = new (S.Context)
18505             OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue);
18506         TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(),
18507                                                           ELoc, Idx, ELoc);
18508       }
18509     }
18510 
18511     // OpenMP [2.15.4.6, Restrictions, p.2]
18512     // A list item that appears in an in_reduction clause of a task construct
18513     // must appear in a task_reduction clause of a construct associated with a
18514     // taskgroup region that includes the participating task in its taskgroup
18515     // set. The construct associated with the innermost region that meets this
18516     // condition must specify the same reduction-identifier as the in_reduction
18517     // clause.
18518     if (ClauseKind == OMPC_in_reduction) {
18519       SourceRange ParentSR;
18520       BinaryOperatorKind ParentBOK;
18521       const Expr *ParentReductionOp = nullptr;
18522       Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr;
18523       DSAStackTy::DSAVarData ParentBOKDSA =
18524           Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
18525                                                   ParentBOKTD);
18526       DSAStackTy::DSAVarData ParentReductionOpDSA =
18527           Stack->getTopMostTaskgroupReductionData(
18528               D, ParentSR, ParentReductionOp, ParentReductionOpTD);
18529       bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
18530       bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
18531       if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
18532           (DeclareReductionRef.isUsable() && IsParentBOK) ||
18533           (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) {
18534         bool EmitError = true;
18535         if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
18536           llvm::FoldingSetNodeID RedId, ParentRedId;
18537           ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
18538           DeclareReductionRef.get()->Profile(RedId, Context,
18539                                              /*Canonical=*/true);
18540           EmitError = RedId != ParentRedId;
18541         }
18542         if (EmitError) {
18543           S.Diag(ReductionId.getBeginLoc(),
18544                  diag::err_omp_reduction_identifier_mismatch)
18545               << ReductionIdRange << RefExpr->getSourceRange();
18546           S.Diag(ParentSR.getBegin(),
18547                  diag::note_omp_previous_reduction_identifier)
18548               << ParentSR
18549               << (IsParentBOK ? ParentBOKDSA.RefExpr
18550                               : ParentReductionOpDSA.RefExpr)
18551                      ->getSourceRange();
18552           continue;
18553         }
18554       }
18555       TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
18556     }
18557 
18558     DeclRefExpr *Ref = nullptr;
18559     Expr *VarsExpr = RefExpr->IgnoreParens();
18560     if (!VD && !S.CurContext->isDependentContext()) {
18561       if (ASE || OASE) {
18562         TransformExprToCaptures RebuildToCapture(S, D);
18563         VarsExpr =
18564             RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
18565         Ref = RebuildToCapture.getCapturedExpr();
18566       } else {
18567         VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
18568       }
18569       if (!S.isOpenMPCapturedDecl(D)) {
18570         RD.ExprCaptures.emplace_back(Ref->getDecl());
18571         if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
18572           ExprResult RefRes = S.DefaultLvalueConversion(Ref);
18573           if (!RefRes.isUsable())
18574             continue;
18575           ExprResult PostUpdateRes =
18576               S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
18577                            RefRes.get());
18578           if (!PostUpdateRes.isUsable())
18579             continue;
18580           if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
18581               Stack->getCurrentDirective() == OMPD_taskgroup) {
18582             S.Diag(RefExpr->getExprLoc(),
18583                    diag::err_omp_reduction_non_addressable_expression)
18584                 << RefExpr->getSourceRange();
18585             continue;
18586           }
18587           RD.ExprPostUpdates.emplace_back(
18588               S.IgnoredValueConversions(PostUpdateRes.get()).get());
18589         }
18590       }
18591     }
18592     // All reduction items are still marked as reduction (to do not increase
18593     // code base size).
18594     unsigned Modifier = RD.RedModifier;
18595     // Consider task_reductions as reductions with task modifier. Required for
18596     // correct analysis of in_reduction clauses.
18597     if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction)
18598       Modifier = OMPC_REDUCTION_task;
18599     Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier,
18600                   ASE || OASE);
18601     if (Modifier == OMPC_REDUCTION_task &&
18602         (CurrDir == OMPD_taskgroup ||
18603          ((isOpenMPParallelDirective(CurrDir) ||
18604            isOpenMPWorksharingDirective(CurrDir)) &&
18605           !isOpenMPSimdDirective(CurrDir)))) {
18606       if (DeclareReductionRef.isUsable())
18607         Stack->addTaskgroupReductionData(D, ReductionIdRange,
18608                                          DeclareReductionRef.get());
18609       else
18610         Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
18611     }
18612     RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
18613             TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(),
18614             TempArrayElem.get());
18615   }
18616   return RD.Vars.empty();
18617 }
18618 
18619 OMPClause *Sema::ActOnOpenMPReductionClause(
18620     ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
18621     SourceLocation StartLoc, SourceLocation LParenLoc,
18622     SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
18623     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
18624     ArrayRef<Expr *> UnresolvedReductions) {
18625   if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) {
18626     Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
18627         << getListOfPossibleValues(OMPC_reduction, /*First=*/0,
18628                                    /*Last=*/OMPC_REDUCTION_unknown)
18629         << getOpenMPClauseName(OMPC_reduction);
18630     return nullptr;
18631   }
18632   // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions
18633   // A reduction clause with the inscan reduction-modifier may only appear on a
18634   // worksharing-loop construct, a worksharing-loop SIMD construct, a simd
18635   // construct, a parallel worksharing-loop construct or a parallel
18636   // worksharing-loop SIMD construct.
18637   if (Modifier == OMPC_REDUCTION_inscan &&
18638       (DSAStack->getCurrentDirective() != OMPD_for &&
18639        DSAStack->getCurrentDirective() != OMPD_for_simd &&
18640        DSAStack->getCurrentDirective() != OMPD_simd &&
18641        DSAStack->getCurrentDirective() != OMPD_parallel_for &&
18642        DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) {
18643     Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
18644     return nullptr;
18645   }
18646 
18647   ReductionData RD(VarList.size(), Modifier);
18648   if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList,
18649                                   StartLoc, LParenLoc, ColonLoc, EndLoc,
18650                                   ReductionIdScopeSpec, ReductionId,
18651                                   UnresolvedReductions, RD))
18652     return nullptr;
18653 
18654   return OMPReductionClause::Create(
18655       Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier,
18656       RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
18657       RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps,
18658       RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems,
18659       buildPreInits(Context, RD.ExprCaptures),
18660       buildPostUpdate(*this, RD.ExprPostUpdates));
18661 }
18662 
18663 OMPClause *Sema::ActOnOpenMPTaskReductionClause(
18664     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
18665     SourceLocation ColonLoc, SourceLocation EndLoc,
18666     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
18667     ArrayRef<Expr *> UnresolvedReductions) {
18668   ReductionData RD(VarList.size());
18669   if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList,
18670                                   StartLoc, LParenLoc, ColonLoc, EndLoc,
18671                                   ReductionIdScopeSpec, ReductionId,
18672                                   UnresolvedReductions, RD))
18673     return nullptr;
18674 
18675   return OMPTaskReductionClause::Create(
18676       Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
18677       ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
18678       RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
18679       buildPreInits(Context, RD.ExprCaptures),
18680       buildPostUpdate(*this, RD.ExprPostUpdates));
18681 }
18682 
18683 OMPClause *Sema::ActOnOpenMPInReductionClause(
18684     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
18685     SourceLocation ColonLoc, SourceLocation EndLoc,
18686     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
18687     ArrayRef<Expr *> UnresolvedReductions) {
18688   ReductionData RD(VarList.size());
18689   if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList,
18690                                   StartLoc, LParenLoc, ColonLoc, EndLoc,
18691                                   ReductionIdScopeSpec, ReductionId,
18692                                   UnresolvedReductions, RD))
18693     return nullptr;
18694 
18695   return OMPInReductionClause::Create(
18696       Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
18697       ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
18698       RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
18699       buildPreInits(Context, RD.ExprCaptures),
18700       buildPostUpdate(*this, RD.ExprPostUpdates));
18701 }
18702 
18703 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
18704                                      SourceLocation LinLoc) {
18705   if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
18706       LinKind == OMPC_LINEAR_unknown) {
18707     Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
18708     return true;
18709   }
18710   return false;
18711 }
18712 
18713 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
18714                                  OpenMPLinearClauseKind LinKind, QualType Type,
18715                                  bool IsDeclareSimd) {
18716   const auto *VD = dyn_cast_or_null<VarDecl>(D);
18717   // A variable must not have an incomplete type or a reference type.
18718   if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
18719     return true;
18720   if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
18721       !Type->isReferenceType()) {
18722     Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
18723         << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
18724     return true;
18725   }
18726   Type = Type.getNonReferenceType();
18727 
18728   // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
18729   // A variable that is privatized must not have a const-qualified type
18730   // unless it is of class type with a mutable member. This restriction does
18731   // not apply to the firstprivate clause, nor to the linear clause on
18732   // declarative directives (like declare simd).
18733   if (!IsDeclareSimd &&
18734       rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
18735     return true;
18736 
18737   // A list item must be of integral or pointer type.
18738   Type = Type.getUnqualifiedType().getCanonicalType();
18739   const auto *Ty = Type.getTypePtrOrNull();
18740   if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
18741               !Ty->isIntegralType(Context) && !Ty->isPointerType())) {
18742     Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
18743     if (D) {
18744       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
18745                                VarDecl::DeclarationOnly;
18746       Diag(D->getLocation(),
18747            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18748           << D;
18749     }
18750     return true;
18751   }
18752   return false;
18753 }
18754 
18755 OMPClause *Sema::ActOnOpenMPLinearClause(
18756     ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
18757     SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
18758     SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
18759   SmallVector<Expr *, 8> Vars;
18760   SmallVector<Expr *, 8> Privates;
18761   SmallVector<Expr *, 8> Inits;
18762   SmallVector<Decl *, 4> ExprCaptures;
18763   SmallVector<Expr *, 4> ExprPostUpdates;
18764   if (CheckOpenMPLinearModifier(LinKind, LinLoc))
18765     LinKind = OMPC_LINEAR_val;
18766   for (Expr *RefExpr : VarList) {
18767     assert(RefExpr && "NULL expr in OpenMP linear clause.");
18768     SourceLocation ELoc;
18769     SourceRange ERange;
18770     Expr *SimpleRefExpr = RefExpr;
18771     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
18772     if (Res.second) {
18773       // It will be analyzed later.
18774       Vars.push_back(RefExpr);
18775       Privates.push_back(nullptr);
18776       Inits.push_back(nullptr);
18777     }
18778     ValueDecl *D = Res.first;
18779     if (!D)
18780       continue;
18781 
18782     QualType Type = D->getType();
18783     auto *VD = dyn_cast<VarDecl>(D);
18784 
18785     // OpenMP [2.14.3.7, linear clause]
18786     //  A list-item cannot appear in more than one linear clause.
18787     //  A list-item that appears in a linear clause cannot appear in any
18788     //  other data-sharing attribute clause.
18789     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
18790     if (DVar.RefExpr) {
18791       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
18792                                           << getOpenMPClauseName(OMPC_linear);
18793       reportOriginalDsa(*this, DSAStack, D, DVar);
18794       continue;
18795     }
18796 
18797     if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
18798       continue;
18799     Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
18800 
18801     // Build private copy of original var.
18802     VarDecl *Private =
18803         buildVarDecl(*this, ELoc, Type, D->getName(),
18804                      D->hasAttrs() ? &D->getAttrs() : nullptr,
18805                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
18806     DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
18807     // Build var to save initial value.
18808     VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
18809     Expr *InitExpr;
18810     DeclRefExpr *Ref = nullptr;
18811     if (!VD && !CurContext->isDependentContext()) {
18812       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
18813       if (!isOpenMPCapturedDecl(D)) {
18814         ExprCaptures.push_back(Ref->getDecl());
18815         if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
18816           ExprResult RefRes = DefaultLvalueConversion(Ref);
18817           if (!RefRes.isUsable())
18818             continue;
18819           ExprResult PostUpdateRes =
18820               BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
18821                          SimpleRefExpr, RefRes.get());
18822           if (!PostUpdateRes.isUsable())
18823             continue;
18824           ExprPostUpdates.push_back(
18825               IgnoredValueConversions(PostUpdateRes.get()).get());
18826         }
18827       }
18828     }
18829     if (LinKind == OMPC_LINEAR_uval)
18830       InitExpr = VD ? VD->getInit() : SimpleRefExpr;
18831     else
18832       InitExpr = VD ? SimpleRefExpr : Ref;
18833     AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
18834                          /*DirectInit=*/false);
18835     DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
18836 
18837     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
18838     Vars.push_back((VD || CurContext->isDependentContext())
18839                        ? RefExpr->IgnoreParens()
18840                        : Ref);
18841     Privates.push_back(PrivateRef);
18842     Inits.push_back(InitRef);
18843   }
18844 
18845   if (Vars.empty())
18846     return nullptr;
18847 
18848   Expr *StepExpr = Step;
18849   Expr *CalcStepExpr = nullptr;
18850   if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
18851       !Step->isInstantiationDependent() &&
18852       !Step->containsUnexpandedParameterPack()) {
18853     SourceLocation StepLoc = Step->getBeginLoc();
18854     ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
18855     if (Val.isInvalid())
18856       return nullptr;
18857     StepExpr = Val.get();
18858 
18859     // Build var to save the step value.
18860     VarDecl *SaveVar =
18861         buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
18862     ExprResult SaveRef =
18863         buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
18864     ExprResult CalcStep =
18865         BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
18866     CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
18867 
18868     // Warn about zero linear step (it would be probably better specified as
18869     // making corresponding variables 'const').
18870     if (Optional<llvm::APSInt> Result =
18871             StepExpr->getIntegerConstantExpr(Context)) {
18872       if (!Result->isNegative() && !Result->isStrictlyPositive())
18873         Diag(StepLoc, diag::warn_omp_linear_step_zero)
18874             << Vars[0] << (Vars.size() > 1);
18875     } else if (CalcStep.isUsable()) {
18876       // Calculate the step beforehand instead of doing this on each iteration.
18877       // (This is not used if the number of iterations may be kfold-ed).
18878       CalcStepExpr = CalcStep.get();
18879     }
18880   }
18881 
18882   return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
18883                                  ColonLoc, EndLoc, Vars, Privates, Inits,
18884                                  StepExpr, CalcStepExpr,
18885                                  buildPreInits(Context, ExprCaptures),
18886                                  buildPostUpdate(*this, ExprPostUpdates));
18887 }
18888 
18889 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
18890                                      Expr *NumIterations, Sema &SemaRef,
18891                                      Scope *S, DSAStackTy *Stack) {
18892   // Walk the vars and build update/final expressions for the CodeGen.
18893   SmallVector<Expr *, 8> Updates;
18894   SmallVector<Expr *, 8> Finals;
18895   SmallVector<Expr *, 8> UsedExprs;
18896   Expr *Step = Clause.getStep();
18897   Expr *CalcStep = Clause.getCalcStep();
18898   // OpenMP [2.14.3.7, linear clause]
18899   // If linear-step is not specified it is assumed to be 1.
18900   if (!Step)
18901     Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
18902   else if (CalcStep)
18903     Step = cast<BinaryOperator>(CalcStep)->getLHS();
18904   bool HasErrors = false;
18905   auto CurInit = Clause.inits().begin();
18906   auto CurPrivate = Clause.privates().begin();
18907   OpenMPLinearClauseKind LinKind = Clause.getModifier();
18908   for (Expr *RefExpr : Clause.varlists()) {
18909     SourceLocation ELoc;
18910     SourceRange ERange;
18911     Expr *SimpleRefExpr = RefExpr;
18912     auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
18913     ValueDecl *D = Res.first;
18914     if (Res.second || !D) {
18915       Updates.push_back(nullptr);
18916       Finals.push_back(nullptr);
18917       HasErrors = true;
18918       continue;
18919     }
18920     auto &&Info = Stack->isLoopControlVariable(D);
18921     // OpenMP [2.15.11, distribute simd Construct]
18922     // A list item may not appear in a linear clause, unless it is the loop
18923     // iteration variable.
18924     if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
18925         isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
18926       SemaRef.Diag(ELoc,
18927                    diag::err_omp_linear_distribute_var_non_loop_iteration);
18928       Updates.push_back(nullptr);
18929       Finals.push_back(nullptr);
18930       HasErrors = true;
18931       continue;
18932     }
18933     Expr *InitExpr = *CurInit;
18934 
18935     // Build privatized reference to the current linear var.
18936     auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
18937     Expr *CapturedRef;
18938     if (LinKind == OMPC_LINEAR_uval)
18939       CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
18940     else
18941       CapturedRef =
18942           buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
18943                            DE->getType().getUnqualifiedType(), DE->getExprLoc(),
18944                            /*RefersToCapture=*/true);
18945 
18946     // Build update: Var = InitExpr + IV * Step
18947     ExprResult Update;
18948     if (!Info.first)
18949       Update = buildCounterUpdate(
18950           SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
18951           /*Subtract=*/false, /*IsNonRectangularLB=*/false);
18952     else
18953       Update = *CurPrivate;
18954     Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
18955                                          /*DiscardedValue*/ false);
18956 
18957     // Build final: Var = PrivCopy;
18958     ExprResult Final;
18959     if (!Info.first)
18960       Final = SemaRef.BuildBinOp(
18961           S, RefExpr->getExprLoc(), BO_Assign, CapturedRef,
18962           SemaRef.DefaultLvalueConversion(*CurPrivate).get());
18963     else
18964       Final = *CurPrivate;
18965     Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
18966                                         /*DiscardedValue*/ false);
18967 
18968     if (!Update.isUsable() || !Final.isUsable()) {
18969       Updates.push_back(nullptr);
18970       Finals.push_back(nullptr);
18971       UsedExprs.push_back(nullptr);
18972       HasErrors = true;
18973     } else {
18974       Updates.push_back(Update.get());
18975       Finals.push_back(Final.get());
18976       if (!Info.first)
18977         UsedExprs.push_back(SimpleRefExpr);
18978     }
18979     ++CurInit;
18980     ++CurPrivate;
18981   }
18982   if (Expr *S = Clause.getStep())
18983     UsedExprs.push_back(S);
18984   // Fill the remaining part with the nullptr.
18985   UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr);
18986   Clause.setUpdates(Updates);
18987   Clause.setFinals(Finals);
18988   Clause.setUsedExprs(UsedExprs);
18989   return HasErrors;
18990 }
18991 
18992 OMPClause *Sema::ActOnOpenMPAlignedClause(
18993     ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
18994     SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
18995   SmallVector<Expr *, 8> Vars;
18996   for (Expr *RefExpr : VarList) {
18997     assert(RefExpr && "NULL expr in OpenMP linear clause.");
18998     SourceLocation ELoc;
18999     SourceRange ERange;
19000     Expr *SimpleRefExpr = RefExpr;
19001     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
19002     if (Res.second) {
19003       // It will be analyzed later.
19004       Vars.push_back(RefExpr);
19005     }
19006     ValueDecl *D = Res.first;
19007     if (!D)
19008       continue;
19009 
19010     QualType QType = D->getType();
19011     auto *VD = dyn_cast<VarDecl>(D);
19012 
19013     // OpenMP  [2.8.1, simd construct, Restrictions]
19014     // The type of list items appearing in the aligned clause must be
19015     // array, pointer, reference to array, or reference to pointer.
19016     QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
19017     const Type *Ty = QType.getTypePtrOrNull();
19018     if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
19019       Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
19020           << QType << getLangOpts().CPlusPlus << ERange;
19021       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19022                                VarDecl::DeclarationOnly;
19023       Diag(D->getLocation(),
19024            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19025           << D;
19026       continue;
19027     }
19028 
19029     // OpenMP  [2.8.1, simd construct, Restrictions]
19030     // A list-item cannot appear in more than one aligned clause.
19031     if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
19032       Diag(ELoc, diag::err_omp_used_in_clause_twice)
19033           << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
19034       Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
19035           << getOpenMPClauseName(OMPC_aligned);
19036       continue;
19037     }
19038 
19039     DeclRefExpr *Ref = nullptr;
19040     if (!VD && isOpenMPCapturedDecl(D))
19041       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
19042     Vars.push_back(DefaultFunctionArrayConversion(
19043                        (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
19044                        .get());
19045   }
19046 
19047   // OpenMP [2.8.1, simd construct, Description]
19048   // The parameter of the aligned clause, alignment, must be a constant
19049   // positive integer expression.
19050   // If no optional parameter is specified, implementation-defined default
19051   // alignments for SIMD instructions on the target platforms are assumed.
19052   if (Alignment != nullptr) {
19053     ExprResult AlignResult =
19054         VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
19055     if (AlignResult.isInvalid())
19056       return nullptr;
19057     Alignment = AlignResult.get();
19058   }
19059   if (Vars.empty())
19060     return nullptr;
19061 
19062   return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
19063                                   EndLoc, Vars, Alignment);
19064 }
19065 
19066 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
19067                                          SourceLocation StartLoc,
19068                                          SourceLocation LParenLoc,
19069                                          SourceLocation EndLoc) {
19070   SmallVector<Expr *, 8> Vars;
19071   SmallVector<Expr *, 8> SrcExprs;
19072   SmallVector<Expr *, 8> DstExprs;
19073   SmallVector<Expr *, 8> AssignmentOps;
19074   for (Expr *RefExpr : VarList) {
19075     assert(RefExpr && "NULL expr in OpenMP copyin clause.");
19076     if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
19077       // It will be analyzed later.
19078       Vars.push_back(RefExpr);
19079       SrcExprs.push_back(nullptr);
19080       DstExprs.push_back(nullptr);
19081       AssignmentOps.push_back(nullptr);
19082       continue;
19083     }
19084 
19085     SourceLocation ELoc = RefExpr->getExprLoc();
19086     // OpenMP [2.1, C/C++]
19087     //  A list item is a variable name.
19088     // OpenMP  [2.14.4.1, Restrictions, p.1]
19089     //  A list item that appears in a copyin clause must be threadprivate.
19090     auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
19091     if (!DE || !isa<VarDecl>(DE->getDecl())) {
19092       Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
19093           << 0 << RefExpr->getSourceRange();
19094       continue;
19095     }
19096 
19097     Decl *D = DE->getDecl();
19098     auto *VD = cast<VarDecl>(D);
19099 
19100     QualType Type = VD->getType();
19101     if (Type->isDependentType() || Type->isInstantiationDependentType()) {
19102       // It will be analyzed later.
19103       Vars.push_back(DE);
19104       SrcExprs.push_back(nullptr);
19105       DstExprs.push_back(nullptr);
19106       AssignmentOps.push_back(nullptr);
19107       continue;
19108     }
19109 
19110     // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
19111     //  A list item that appears in a copyin clause must be threadprivate.
19112     if (!DSAStack->isThreadPrivate(VD)) {
19113       Diag(ELoc, diag::err_omp_required_access)
19114           << getOpenMPClauseName(OMPC_copyin)
19115           << getOpenMPDirectiveName(OMPD_threadprivate);
19116       continue;
19117     }
19118 
19119     // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
19120     //  A variable of class type (or array thereof) that appears in a
19121     //  copyin clause requires an accessible, unambiguous copy assignment
19122     //  operator for the class type.
19123     QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
19124     VarDecl *SrcVD =
19125         buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
19126                      ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
19127     DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
19128         *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
19129     VarDecl *DstVD =
19130         buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
19131                      VD->hasAttrs() ? &VD->getAttrs() : nullptr);
19132     DeclRefExpr *PseudoDstExpr =
19133         buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
19134     // For arrays generate assignment operation for single element and replace
19135     // it by the original array element in CodeGen.
19136     ExprResult AssignmentOp =
19137         BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
19138                    PseudoSrcExpr);
19139     if (AssignmentOp.isInvalid())
19140       continue;
19141     AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
19142                                        /*DiscardedValue*/ false);
19143     if (AssignmentOp.isInvalid())
19144       continue;
19145 
19146     DSAStack->addDSA(VD, DE, OMPC_copyin);
19147     Vars.push_back(DE);
19148     SrcExprs.push_back(PseudoSrcExpr);
19149     DstExprs.push_back(PseudoDstExpr);
19150     AssignmentOps.push_back(AssignmentOp.get());
19151   }
19152 
19153   if (Vars.empty())
19154     return nullptr;
19155 
19156   return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
19157                                  SrcExprs, DstExprs, AssignmentOps);
19158 }
19159 
19160 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
19161                                               SourceLocation StartLoc,
19162                                               SourceLocation LParenLoc,
19163                                               SourceLocation EndLoc) {
19164   SmallVector<Expr *, 8> Vars;
19165   SmallVector<Expr *, 8> SrcExprs;
19166   SmallVector<Expr *, 8> DstExprs;
19167   SmallVector<Expr *, 8> AssignmentOps;
19168   for (Expr *RefExpr : VarList) {
19169     assert(RefExpr && "NULL expr in OpenMP linear clause.");
19170     SourceLocation ELoc;
19171     SourceRange ERange;
19172     Expr *SimpleRefExpr = RefExpr;
19173     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
19174     if (Res.second) {
19175       // It will be analyzed later.
19176       Vars.push_back(RefExpr);
19177       SrcExprs.push_back(nullptr);
19178       DstExprs.push_back(nullptr);
19179       AssignmentOps.push_back(nullptr);
19180     }
19181     ValueDecl *D = Res.first;
19182     if (!D)
19183       continue;
19184 
19185     QualType Type = D->getType();
19186     auto *VD = dyn_cast<VarDecl>(D);
19187 
19188     // OpenMP [2.14.4.2, Restrictions, p.2]
19189     //  A list item that appears in a copyprivate clause may not appear in a
19190     //  private or firstprivate clause on the single construct.
19191     if (!VD || !DSAStack->isThreadPrivate(VD)) {
19192       DSAStackTy::DSAVarData DVar =
19193           DSAStack->getTopDSA(D, /*FromParent=*/false);
19194       if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
19195           DVar.RefExpr) {
19196         Diag(ELoc, diag::err_omp_wrong_dsa)
19197             << getOpenMPClauseName(DVar.CKind)
19198             << getOpenMPClauseName(OMPC_copyprivate);
19199         reportOriginalDsa(*this, DSAStack, D, DVar);
19200         continue;
19201       }
19202 
19203       // OpenMP [2.11.4.2, Restrictions, p.1]
19204       //  All list items that appear in a copyprivate clause must be either
19205       //  threadprivate or private in the enclosing context.
19206       if (DVar.CKind == OMPC_unknown) {
19207         DVar = DSAStack->getImplicitDSA(D, false);
19208         if (DVar.CKind == OMPC_shared) {
19209           Diag(ELoc, diag::err_omp_required_access)
19210               << getOpenMPClauseName(OMPC_copyprivate)
19211               << "threadprivate or private in the enclosing context";
19212           reportOriginalDsa(*this, DSAStack, D, DVar);
19213           continue;
19214         }
19215       }
19216     }
19217 
19218     // Variably modified types are not supported.
19219     if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
19220       Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
19221           << getOpenMPClauseName(OMPC_copyprivate) << Type
19222           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
19223       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
19224                                VarDecl::DeclarationOnly;
19225       Diag(D->getLocation(),
19226            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
19227           << D;
19228       continue;
19229     }
19230 
19231     // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
19232     //  A variable of class type (or array thereof) that appears in a
19233     //  copyin clause requires an accessible, unambiguous copy assignment
19234     //  operator for the class type.
19235     Type = Context.getBaseElementType(Type.getNonReferenceType())
19236                .getUnqualifiedType();
19237     VarDecl *SrcVD =
19238         buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
19239                      D->hasAttrs() ? &D->getAttrs() : nullptr);
19240     DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
19241     VarDecl *DstVD =
19242         buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
19243                      D->hasAttrs() ? &D->getAttrs() : nullptr);
19244     DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
19245     ExprResult AssignmentOp = BuildBinOp(
19246         DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
19247     if (AssignmentOp.isInvalid())
19248       continue;
19249     AssignmentOp =
19250         ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
19251     if (AssignmentOp.isInvalid())
19252       continue;
19253 
19254     // No need to mark vars as copyprivate, they are already threadprivate or
19255     // implicitly private.
19256     assert(VD || isOpenMPCapturedDecl(D));
19257     Vars.push_back(
19258         VD ? RefExpr->IgnoreParens()
19259            : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
19260     SrcExprs.push_back(PseudoSrcExpr);
19261     DstExprs.push_back(PseudoDstExpr);
19262     AssignmentOps.push_back(AssignmentOp.get());
19263   }
19264 
19265   if (Vars.empty())
19266     return nullptr;
19267 
19268   return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
19269                                       Vars, SrcExprs, DstExprs, AssignmentOps);
19270 }
19271 
19272 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
19273                                         SourceLocation StartLoc,
19274                                         SourceLocation LParenLoc,
19275                                         SourceLocation EndLoc) {
19276   if (VarList.empty())
19277     return nullptr;
19278 
19279   return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
19280 }
19281 
19282 /// Tries to find omp_depend_t. type.
19283 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack,
19284                            bool Diagnose = true) {
19285   QualType OMPDependT = Stack->getOMPDependT();
19286   if (!OMPDependT.isNull())
19287     return true;
19288   IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t");
19289   ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
19290   if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
19291     if (Diagnose)
19292       S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t";
19293     return false;
19294   }
19295   Stack->setOMPDependT(PT.get());
19296   return true;
19297 }
19298 
19299 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
19300                                          SourceLocation LParenLoc,
19301                                          SourceLocation EndLoc) {
19302   if (!Depobj)
19303     return nullptr;
19304 
19305   bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack);
19306 
19307   // OpenMP 5.0, 2.17.10.1 depobj Construct
19308   // depobj is an lvalue expression of type omp_depend_t.
19309   if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() &&
19310       !Depobj->isInstantiationDependent() &&
19311       !Depobj->containsUnexpandedParameterPack() &&
19312       (OMPDependTFound &&
19313        !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(),
19314                                    /*CompareUnqualified=*/true))) {
19315     Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
19316         << 0 << Depobj->getType() << Depobj->getSourceRange();
19317   }
19318 
19319   if (!Depobj->isLValue()) {
19320     Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
19321         << 1 << Depobj->getSourceRange();
19322   }
19323 
19324   return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj);
19325 }
19326 
19327 OMPClause *
19328 Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind,
19329                               SourceLocation DepLoc, SourceLocation ColonLoc,
19330                               ArrayRef<Expr *> VarList, SourceLocation StartLoc,
19331                               SourceLocation LParenLoc, SourceLocation EndLoc) {
19332   if (DSAStack->getCurrentDirective() == OMPD_ordered &&
19333       DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
19334     Diag(DepLoc, diag::err_omp_unexpected_clause_value)
19335         << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
19336     return nullptr;
19337   }
19338   if (DSAStack->getCurrentDirective() == OMPD_taskwait &&
19339       DepKind == OMPC_DEPEND_mutexinoutset) {
19340     Diag(DepLoc, diag::err_omp_taskwait_depend_mutexinoutset_not_allowed);
19341     return nullptr;
19342   }
19343   if ((DSAStack->getCurrentDirective() != OMPD_ordered ||
19344        DSAStack->getCurrentDirective() == OMPD_depobj) &&
19345       (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
19346        DepKind == OMPC_DEPEND_sink ||
19347        ((LangOpts.OpenMP < 50 ||
19348          DSAStack->getCurrentDirective() == OMPD_depobj) &&
19349         DepKind == OMPC_DEPEND_depobj))) {
19350     SmallVector<unsigned, 3> Except;
19351     Except.push_back(OMPC_DEPEND_source);
19352     Except.push_back(OMPC_DEPEND_sink);
19353     if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj)
19354       Except.push_back(OMPC_DEPEND_depobj);
19355     if (LangOpts.OpenMP < 51)
19356       Except.push_back(OMPC_DEPEND_inoutset);
19357     std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier)
19358                                ? "depend modifier(iterator) or "
19359                                : "";
19360     Diag(DepLoc, diag::err_omp_unexpected_clause_value)
19361         << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0,
19362                                               /*Last=*/OMPC_DEPEND_unknown,
19363                                               Except)
19364         << getOpenMPClauseName(OMPC_depend);
19365     return nullptr;
19366   }
19367   if (DepModifier &&
19368       (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) {
19369     Diag(DepModifier->getExprLoc(),
19370          diag::err_omp_depend_sink_source_with_modifier);
19371     return nullptr;
19372   }
19373   if (DepModifier &&
19374       !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator))
19375     Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator);
19376 
19377   SmallVector<Expr *, 8> Vars;
19378   DSAStackTy::OperatorOffsetTy OpsOffs;
19379   llvm::APSInt DepCounter(/*BitWidth=*/32);
19380   llvm::APSInt TotalDepCount(/*BitWidth=*/32);
19381   if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
19382     if (const Expr *OrderedCountExpr =
19383             DSAStack->getParentOrderedRegionParam().first) {
19384       TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
19385       TotalDepCount.setIsUnsigned(/*Val=*/true);
19386     }
19387   }
19388   for (Expr *RefExpr : VarList) {
19389     assert(RefExpr && "NULL expr in OpenMP shared clause.");
19390     if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
19391       // It will be analyzed later.
19392       Vars.push_back(RefExpr);
19393       continue;
19394     }
19395 
19396     SourceLocation ELoc = RefExpr->getExprLoc();
19397     Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
19398     if (DepKind == OMPC_DEPEND_sink) {
19399       if (DSAStack->getParentOrderedRegionParam().first &&
19400           DepCounter >= TotalDepCount) {
19401         Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
19402         continue;
19403       }
19404       ++DepCounter;
19405       // OpenMP  [2.13.9, Summary]
19406       // depend(dependence-type : vec), where dependence-type is:
19407       // 'sink' and where vec is the iteration vector, which has the form:
19408       //  x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
19409       // where n is the value specified by the ordered clause in the loop
19410       // directive, xi denotes the loop iteration variable of the i-th nested
19411       // loop associated with the loop directive, and di is a constant
19412       // non-negative integer.
19413       if (CurContext->isDependentContext()) {
19414         // It will be analyzed later.
19415         Vars.push_back(RefExpr);
19416         continue;
19417       }
19418       SimpleExpr = SimpleExpr->IgnoreImplicit();
19419       OverloadedOperatorKind OOK = OO_None;
19420       SourceLocation OOLoc;
19421       Expr *LHS = SimpleExpr;
19422       Expr *RHS = nullptr;
19423       if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
19424         OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
19425         OOLoc = BO->getOperatorLoc();
19426         LHS = BO->getLHS()->IgnoreParenImpCasts();
19427         RHS = BO->getRHS()->IgnoreParenImpCasts();
19428       } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
19429         OOK = OCE->getOperator();
19430         OOLoc = OCE->getOperatorLoc();
19431         LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
19432         RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
19433       } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
19434         OOK = MCE->getMethodDecl()
19435                   ->getNameInfo()
19436                   .getName()
19437                   .getCXXOverloadedOperator();
19438         OOLoc = MCE->getCallee()->getExprLoc();
19439         LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
19440         RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
19441       }
19442       SourceLocation ELoc;
19443       SourceRange ERange;
19444       auto Res = getPrivateItem(*this, LHS, ELoc, ERange);
19445       if (Res.second) {
19446         // It will be analyzed later.
19447         Vars.push_back(RefExpr);
19448       }
19449       ValueDecl *D = Res.first;
19450       if (!D)
19451         continue;
19452 
19453       if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
19454         Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
19455         continue;
19456       }
19457       if (RHS) {
19458         ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
19459             RHS, OMPC_depend, /*StrictlyPositive=*/false);
19460         if (RHSRes.isInvalid())
19461           continue;
19462       }
19463       if (!CurContext->isDependentContext() &&
19464           DSAStack->getParentOrderedRegionParam().first &&
19465           DepCounter != DSAStack->isParentLoopControlVariable(D).first) {
19466         const ValueDecl *VD =
19467             DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue());
19468         if (VD)
19469           Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
19470               << 1 << VD;
19471         else
19472           Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
19473         continue;
19474       }
19475       OpsOffs.emplace_back(RHS, OOK);
19476     } else {
19477       bool OMPDependTFound = LangOpts.OpenMP >= 50;
19478       if (OMPDependTFound)
19479         OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack,
19480                                          DepKind == OMPC_DEPEND_depobj);
19481       if (DepKind == OMPC_DEPEND_depobj) {
19482         // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
19483         // List items used in depend clauses with the depobj dependence type
19484         // must be expressions of the omp_depend_t type.
19485         if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
19486             !RefExpr->isInstantiationDependent() &&
19487             !RefExpr->containsUnexpandedParameterPack() &&
19488             (OMPDependTFound &&
19489              !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(),
19490                                              RefExpr->getType()))) {
19491           Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
19492               << 0 << RefExpr->getType() << RefExpr->getSourceRange();
19493           continue;
19494         }
19495         if (!RefExpr->isLValue()) {
19496           Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
19497               << 1 << RefExpr->getType() << RefExpr->getSourceRange();
19498           continue;
19499         }
19500       } else {
19501         // OpenMP 5.0 [2.17.11, Restrictions]
19502         // List items used in depend clauses cannot be zero-length array
19503         // sections.
19504         QualType ExprTy = RefExpr->getType().getNonReferenceType();
19505         const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
19506         if (OASE) {
19507           QualType BaseType =
19508               OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
19509           if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
19510             ExprTy = ATy->getElementType();
19511           else
19512             ExprTy = BaseType->getPointeeType();
19513           ExprTy = ExprTy.getNonReferenceType();
19514           const Expr *Length = OASE->getLength();
19515           Expr::EvalResult Result;
19516           if (Length && !Length->isValueDependent() &&
19517               Length->EvaluateAsInt(Result, Context) &&
19518               Result.Val.getInt().isZero()) {
19519             Diag(ELoc,
19520                  diag::err_omp_depend_zero_length_array_section_not_allowed)
19521                 << SimpleExpr->getSourceRange();
19522             continue;
19523           }
19524         }
19525 
19526         // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
19527         // List items used in depend clauses with the in, out, inout,
19528         // inoutset, or mutexinoutset dependence types cannot be
19529         // expressions of the omp_depend_t type.
19530         if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
19531             !RefExpr->isInstantiationDependent() &&
19532             !RefExpr->containsUnexpandedParameterPack() &&
19533             (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
19534              (OMPDependTFound &&
19535               DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr()))) {
19536           Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
19537               << (LangOpts.OpenMP >= 50 ? 1 : 0)
19538               << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
19539           continue;
19540         }
19541 
19542         auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
19543         if (ASE && !ASE->getBase()->isTypeDependent() &&
19544             !ASE->getBase()->getType().getNonReferenceType()->isPointerType() &&
19545             !ASE->getBase()->getType().getNonReferenceType()->isArrayType()) {
19546           Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
19547               << (LangOpts.OpenMP >= 50 ? 1 : 0)
19548               << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
19549           continue;
19550         }
19551 
19552         ExprResult Res;
19553         {
19554           Sema::TentativeAnalysisScope Trap(*this);
19555           Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
19556                                      RefExpr->IgnoreParenImpCasts());
19557         }
19558         if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
19559             !isa<OMPArrayShapingExpr>(SimpleExpr)) {
19560           Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
19561               << (LangOpts.OpenMP >= 50 ? 1 : 0)
19562               << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
19563           continue;
19564         }
19565       }
19566     }
19567     Vars.push_back(RefExpr->IgnoreParenImpCasts());
19568   }
19569 
19570   if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
19571       TotalDepCount > VarList.size() &&
19572       DSAStack->getParentOrderedRegionParam().first &&
19573       DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
19574     Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
19575         << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1);
19576   }
19577   if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
19578       Vars.empty())
19579     return nullptr;
19580 
19581   auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
19582                                     DepModifier, DepKind, DepLoc, ColonLoc,
19583                                     Vars, TotalDepCount.getZExtValue());
19584   if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
19585       DSAStack->isParentOrderedRegion())
19586     DSAStack->addDoacrossDependClause(C, OpsOffs);
19587   return C;
19588 }
19589 
19590 OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
19591                                          Expr *Device, SourceLocation StartLoc,
19592                                          SourceLocation LParenLoc,
19593                                          SourceLocation ModifierLoc,
19594                                          SourceLocation EndLoc) {
19595   assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) &&
19596          "Unexpected device modifier in OpenMP < 50.");
19597 
19598   bool ErrorFound = false;
19599   if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) {
19600     std::string Values =
19601         getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown);
19602     Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
19603         << Values << getOpenMPClauseName(OMPC_device);
19604     ErrorFound = true;
19605   }
19606 
19607   Expr *ValExpr = Device;
19608   Stmt *HelperValStmt = nullptr;
19609 
19610   // OpenMP [2.9.1, Restrictions]
19611   // The device expression must evaluate to a non-negative integer value.
19612   ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
19613                                           /*StrictlyPositive=*/false) ||
19614                ErrorFound;
19615   if (ErrorFound)
19616     return nullptr;
19617 
19618   // OpenMP 5.0 [2.12.5, Restrictions]
19619   // In case of ancestor device-modifier, a requires directive with
19620   // the reverse_offload clause must be specified.
19621   if (Modifier == OMPC_DEVICE_ancestor) {
19622     if (!DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>()) {
19623       targetDiag(
19624           StartLoc,
19625           diag::err_omp_device_ancestor_without_requires_reverse_offload);
19626       ErrorFound = true;
19627     }
19628   }
19629 
19630   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
19631   OpenMPDirectiveKind CaptureRegion =
19632       getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP);
19633   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
19634     ValExpr = MakeFullExpr(ValExpr).get();
19635     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
19636     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
19637     HelperValStmt = buildPreInits(Context, Captures);
19638   }
19639 
19640   return new (Context)
19641       OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
19642                       LParenLoc, ModifierLoc, EndLoc);
19643 }
19644 
19645 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
19646                               DSAStackTy *Stack, QualType QTy,
19647                               bool FullCheck = true) {
19648   if (SemaRef.RequireCompleteType(SL, QTy, diag::err_incomplete_type))
19649     return false;
19650   if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
19651       !QTy.isTriviallyCopyableType(SemaRef.Context))
19652     SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
19653   return true;
19654 }
19655 
19656 /// Return true if it can be proven that the provided array expression
19657 /// (array section or array subscript) does NOT specify the whole size of the
19658 /// array whose base type is \a BaseQTy.
19659 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
19660                                                         const Expr *E,
19661                                                         QualType BaseQTy) {
19662   const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
19663 
19664   // If this is an array subscript, it refers to the whole size if the size of
19665   // the dimension is constant and equals 1. Also, an array section assumes the
19666   // format of an array subscript if no colon is used.
19667   if (isa<ArraySubscriptExpr>(E) ||
19668       (OASE && OASE->getColonLocFirst().isInvalid())) {
19669     if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
19670       return ATy->getSize().getSExtValue() != 1;
19671     // Size can't be evaluated statically.
19672     return false;
19673   }
19674 
19675   assert(OASE && "Expecting array section if not an array subscript.");
19676   const Expr *LowerBound = OASE->getLowerBound();
19677   const Expr *Length = OASE->getLength();
19678 
19679   // If there is a lower bound that does not evaluates to zero, we are not
19680   // covering the whole dimension.
19681   if (LowerBound) {
19682     Expr::EvalResult Result;
19683     if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
19684       return false; // Can't get the integer value as a constant.
19685 
19686     llvm::APSInt ConstLowerBound = Result.Val.getInt();
19687     if (ConstLowerBound.getSExtValue())
19688       return true;
19689   }
19690 
19691   // If we don't have a length we covering the whole dimension.
19692   if (!Length)
19693     return false;
19694 
19695   // If the base is a pointer, we don't have a way to get the size of the
19696   // pointee.
19697   if (BaseQTy->isPointerType())
19698     return false;
19699 
19700   // We can only check if the length is the same as the size of the dimension
19701   // if we have a constant array.
19702   const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
19703   if (!CATy)
19704     return false;
19705 
19706   Expr::EvalResult Result;
19707   if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
19708     return false; // Can't get the integer value as a constant.
19709 
19710   llvm::APSInt ConstLength = Result.Val.getInt();
19711   return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
19712 }
19713 
19714 // Return true if it can be proven that the provided array expression (array
19715 // section or array subscript) does NOT specify a single element of the array
19716 // whose base type is \a BaseQTy.
19717 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
19718                                                         const Expr *E,
19719                                                         QualType BaseQTy) {
19720   const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
19721 
19722   // An array subscript always refer to a single element. Also, an array section
19723   // assumes the format of an array subscript if no colon is used.
19724   if (isa<ArraySubscriptExpr>(E) ||
19725       (OASE && OASE->getColonLocFirst().isInvalid()))
19726     return false;
19727 
19728   assert(OASE && "Expecting array section if not an array subscript.");
19729   const Expr *Length = OASE->getLength();
19730 
19731   // If we don't have a length we have to check if the array has unitary size
19732   // for this dimension. Also, we should always expect a length if the base type
19733   // is pointer.
19734   if (!Length) {
19735     if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
19736       return ATy->getSize().getSExtValue() != 1;
19737     // We cannot assume anything.
19738     return false;
19739   }
19740 
19741   // Check if the length evaluates to 1.
19742   Expr::EvalResult Result;
19743   if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
19744     return false; // Can't get the integer value as a constant.
19745 
19746   llvm::APSInt ConstLength = Result.Val.getInt();
19747   return ConstLength.getSExtValue() != 1;
19748 }
19749 
19750 // The base of elements of list in a map clause have to be either:
19751 //  - a reference to variable or field.
19752 //  - a member expression.
19753 //  - an array expression.
19754 //
19755 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
19756 // reference to 'r'.
19757 //
19758 // If we have:
19759 //
19760 // struct SS {
19761 //   Bla S;
19762 //   foo() {
19763 //     #pragma omp target map (S.Arr[:12]);
19764 //   }
19765 // }
19766 //
19767 // We want to retrieve the member expression 'this->S';
19768 
19769 // OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2]
19770 //  If a list item is an array section, it must specify contiguous storage.
19771 //
19772 // For this restriction it is sufficient that we make sure only references
19773 // to variables or fields and array expressions, and that no array sections
19774 // exist except in the rightmost expression (unless they cover the whole
19775 // dimension of the array). E.g. these would be invalid:
19776 //
19777 //   r.ArrS[3:5].Arr[6:7]
19778 //
19779 //   r.ArrS[3:5].x
19780 //
19781 // but these would be valid:
19782 //   r.ArrS[3].Arr[6:7]
19783 //
19784 //   r.ArrS[3].x
19785 namespace {
19786 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> {
19787   Sema &SemaRef;
19788   OpenMPClauseKind CKind = OMPC_unknown;
19789   OpenMPDirectiveKind DKind = OMPD_unknown;
19790   OMPClauseMappableExprCommon::MappableExprComponentList &Components;
19791   bool IsNonContiguous = false;
19792   bool NoDiagnose = false;
19793   const Expr *RelevantExpr = nullptr;
19794   bool AllowUnitySizeArraySection = true;
19795   bool AllowWholeSizeArraySection = true;
19796   bool AllowAnotherPtr = true;
19797   SourceLocation ELoc;
19798   SourceRange ERange;
19799 
19800   void emitErrorMsg() {
19801     // If nothing else worked, this is not a valid map clause expression.
19802     if (SemaRef.getLangOpts().OpenMP < 50) {
19803       SemaRef.Diag(ELoc,
19804                    diag::err_omp_expected_named_var_member_or_array_expression)
19805           << ERange;
19806     } else {
19807       SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
19808           << getOpenMPClauseName(CKind) << ERange;
19809     }
19810   }
19811 
19812 public:
19813   bool VisitDeclRefExpr(DeclRefExpr *DRE) {
19814     if (!isa<VarDecl>(DRE->getDecl())) {
19815       emitErrorMsg();
19816       return false;
19817     }
19818     assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
19819     RelevantExpr = DRE;
19820     // Record the component.
19821     Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous);
19822     return true;
19823   }
19824 
19825   bool VisitMemberExpr(MemberExpr *ME) {
19826     Expr *E = ME;
19827     Expr *BaseE = ME->getBase()->IgnoreParenCasts();
19828 
19829     if (isa<CXXThisExpr>(BaseE)) {
19830       assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
19831       // We found a base expression: this->Val.
19832       RelevantExpr = ME;
19833     } else {
19834       E = BaseE;
19835     }
19836 
19837     if (!isa<FieldDecl>(ME->getMemberDecl())) {
19838       if (!NoDiagnose) {
19839         SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
19840             << ME->getSourceRange();
19841         return false;
19842       }
19843       if (RelevantExpr)
19844         return false;
19845       return Visit(E);
19846     }
19847 
19848     auto *FD = cast<FieldDecl>(ME->getMemberDecl());
19849 
19850     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
19851     //  A bit-field cannot appear in a map clause.
19852     //
19853     if (FD->isBitField()) {
19854       if (!NoDiagnose) {
19855         SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
19856             << ME->getSourceRange() << getOpenMPClauseName(CKind);
19857         return false;
19858       }
19859       if (RelevantExpr)
19860         return false;
19861       return Visit(E);
19862     }
19863 
19864     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
19865     //  If the type of a list item is a reference to a type T then the type
19866     //  will be considered to be T for all purposes of this clause.
19867     QualType CurType = BaseE->getType().getNonReferenceType();
19868 
19869     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
19870     //  A list item cannot be a variable that is a member of a structure with
19871     //  a union type.
19872     //
19873     if (CurType->isUnionType()) {
19874       if (!NoDiagnose) {
19875         SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
19876             << ME->getSourceRange();
19877         return false;
19878       }
19879       return RelevantExpr || Visit(E);
19880     }
19881 
19882     // If we got a member expression, we should not expect any array section
19883     // before that:
19884     //
19885     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
19886     //  If a list item is an element of a structure, only the rightmost symbol
19887     //  of the variable reference can be an array section.
19888     //
19889     AllowUnitySizeArraySection = false;
19890     AllowWholeSizeArraySection = false;
19891 
19892     // Record the component.
19893     Components.emplace_back(ME, FD, IsNonContiguous);
19894     return RelevantExpr || Visit(E);
19895   }
19896 
19897   bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) {
19898     Expr *E = AE->getBase()->IgnoreParenImpCasts();
19899 
19900     if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
19901       if (!NoDiagnose) {
19902         SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
19903             << 0 << AE->getSourceRange();
19904         return false;
19905       }
19906       return RelevantExpr || Visit(E);
19907     }
19908 
19909     // If we got an array subscript that express the whole dimension we
19910     // can have any array expressions before. If it only expressing part of
19911     // the dimension, we can only have unitary-size array expressions.
19912     if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, E->getType()))
19913       AllowWholeSizeArraySection = false;
19914 
19915     if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) {
19916       Expr::EvalResult Result;
19917       if (!AE->getIdx()->isValueDependent() &&
19918           AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) &&
19919           !Result.Val.getInt().isZero()) {
19920         SemaRef.Diag(AE->getIdx()->getExprLoc(),
19921                      diag::err_omp_invalid_map_this_expr);
19922         SemaRef.Diag(AE->getIdx()->getExprLoc(),
19923                      diag::note_omp_invalid_subscript_on_this_ptr_map);
19924       }
19925       assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
19926       RelevantExpr = TE;
19927     }
19928 
19929     // Record the component - we don't have any declaration associated.
19930     Components.emplace_back(AE, nullptr, IsNonContiguous);
19931 
19932     return RelevantExpr || Visit(E);
19933   }
19934 
19935   bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) {
19936     // After OMP 5.0  Array section in reduction clause will be implicitly
19937     // mapped
19938     assert(!(SemaRef.getLangOpts().OpenMP < 50 && NoDiagnose) &&
19939            "Array sections cannot be implicitly mapped.");
19940     Expr *E = OASE->getBase()->IgnoreParenImpCasts();
19941     QualType CurType =
19942         OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
19943 
19944     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
19945     //  If the type of a list item is a reference to a type T then the type
19946     //  will be considered to be T for all purposes of this clause.
19947     if (CurType->isReferenceType())
19948       CurType = CurType->getPointeeType();
19949 
19950     bool IsPointer = CurType->isAnyPointerType();
19951 
19952     if (!IsPointer && !CurType->isArrayType()) {
19953       SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
19954           << 0 << OASE->getSourceRange();
19955       return false;
19956     }
19957 
19958     bool NotWhole =
19959         checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType);
19960     bool NotUnity =
19961         checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType);
19962 
19963     if (AllowWholeSizeArraySection) {
19964       // Any array section is currently allowed. Allowing a whole size array
19965       // section implies allowing a unity array section as well.
19966       //
19967       // If this array section refers to the whole dimension we can still
19968       // accept other array sections before this one, except if the base is a
19969       // pointer. Otherwise, only unitary sections are accepted.
19970       if (NotWhole || IsPointer)
19971         AllowWholeSizeArraySection = false;
19972     } else if (DKind == OMPD_target_update &&
19973                SemaRef.getLangOpts().OpenMP >= 50) {
19974       if (IsPointer && !AllowAnotherPtr)
19975         SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined)
19976             << /*array of unknown bound */ 1;
19977       else
19978         IsNonContiguous = true;
19979     } else if (AllowUnitySizeArraySection && NotUnity) {
19980       // A unity or whole array section is not allowed and that is not
19981       // compatible with the properties of the current array section.
19982       if (NoDiagnose)
19983         return false;
19984       SemaRef.Diag(ELoc,
19985                    diag::err_array_section_does_not_specify_contiguous_storage)
19986           << OASE->getSourceRange();
19987       return false;
19988     }
19989 
19990     if (IsPointer)
19991       AllowAnotherPtr = false;
19992 
19993     if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
19994       Expr::EvalResult ResultR;
19995       Expr::EvalResult ResultL;
19996       if (!OASE->getLength()->isValueDependent() &&
19997           OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) &&
19998           !ResultR.Val.getInt().isOne()) {
19999         SemaRef.Diag(OASE->getLength()->getExprLoc(),
20000                      diag::err_omp_invalid_map_this_expr);
20001         SemaRef.Diag(OASE->getLength()->getExprLoc(),
20002                      diag::note_omp_invalid_length_on_this_ptr_mapping);
20003       }
20004       if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() &&
20005           OASE->getLowerBound()->EvaluateAsInt(ResultL,
20006                                                SemaRef.getASTContext()) &&
20007           !ResultL.Val.getInt().isZero()) {
20008         SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
20009                      diag::err_omp_invalid_map_this_expr);
20010         SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
20011                      diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
20012       }
20013       assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
20014       RelevantExpr = TE;
20015     }
20016 
20017     // Record the component - we don't have any declaration associated.
20018     Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false);
20019     return RelevantExpr || Visit(E);
20020   }
20021   bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
20022     Expr *Base = E->getBase();
20023 
20024     // Record the component - we don't have any declaration associated.
20025     Components.emplace_back(E, nullptr, IsNonContiguous);
20026 
20027     return Visit(Base->IgnoreParenImpCasts());
20028   }
20029 
20030   bool VisitUnaryOperator(UnaryOperator *UO) {
20031     if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() ||
20032         UO->getOpcode() != UO_Deref) {
20033       emitErrorMsg();
20034       return false;
20035     }
20036     if (!RelevantExpr) {
20037       // Record the component if haven't found base decl.
20038       Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false);
20039     }
20040     return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts());
20041   }
20042   bool VisitBinaryOperator(BinaryOperator *BO) {
20043     if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) {
20044       emitErrorMsg();
20045       return false;
20046     }
20047 
20048     // Pointer arithmetic is the only thing we expect to happen here so after we
20049     // make sure the binary operator is a pointer type, the we only thing need
20050     // to to is to visit the subtree that has the same type as root (so that we
20051     // know the other subtree is just an offset)
20052     Expr *LE = BO->getLHS()->IgnoreParenImpCasts();
20053     Expr *RE = BO->getRHS()->IgnoreParenImpCasts();
20054     Components.emplace_back(BO, nullptr, false);
20055     assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() ||
20056             RE->getType().getTypePtr() == BO->getType().getTypePtr()) &&
20057            "Either LHS or RHS have base decl inside");
20058     if (BO->getType().getTypePtr() == LE->getType().getTypePtr())
20059       return RelevantExpr || Visit(LE);
20060     return RelevantExpr || Visit(RE);
20061   }
20062   bool VisitCXXThisExpr(CXXThisExpr *CTE) {
20063     assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
20064     RelevantExpr = CTE;
20065     Components.emplace_back(CTE, nullptr, IsNonContiguous);
20066     return true;
20067   }
20068   bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) {
20069     assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
20070     Components.emplace_back(COCE, nullptr, IsNonContiguous);
20071     return true;
20072   }
20073   bool VisitOpaqueValueExpr(OpaqueValueExpr *E) {
20074     Expr *Source = E->getSourceExpr();
20075     if (!Source) {
20076       emitErrorMsg();
20077       return false;
20078     }
20079     return Visit(Source);
20080   }
20081   bool VisitStmt(Stmt *) {
20082     emitErrorMsg();
20083     return false;
20084   }
20085   const Expr *getFoundBase() const { return RelevantExpr; }
20086   explicit MapBaseChecker(
20087       Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind,
20088       OMPClauseMappableExprCommon::MappableExprComponentList &Components,
20089       bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange)
20090       : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components),
20091         NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
20092 };
20093 } // namespace
20094 
20095 /// Return the expression of the base of the mappable expression or null if it
20096 /// cannot be determined and do all the necessary checks to see if the
20097 /// expression is valid as a standalone mappable expression. In the process,
20098 /// record all the components of the expression.
20099 static const Expr *checkMapClauseExpressionBase(
20100     Sema &SemaRef, Expr *E,
20101     OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
20102     OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) {
20103   SourceLocation ELoc = E->getExprLoc();
20104   SourceRange ERange = E->getSourceRange();
20105   MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc,
20106                          ERange);
20107   if (Checker.Visit(E->IgnoreParens())) {
20108     // Check if the highest dimension array section has length specified
20109     if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() &&
20110         (CKind == OMPC_to || CKind == OMPC_from)) {
20111       auto CI = CurComponents.rbegin();
20112       auto CE = CurComponents.rend();
20113       for (; CI != CE; ++CI) {
20114         const auto *OASE =
20115             dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression());
20116         if (!OASE)
20117           continue;
20118         if (OASE && OASE->getLength())
20119           break;
20120         SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length)
20121             << ERange;
20122       }
20123     }
20124     return Checker.getFoundBase();
20125   }
20126   return nullptr;
20127 }
20128 
20129 // Return true if expression E associated with value VD has conflicts with other
20130 // map information.
20131 static bool checkMapConflicts(
20132     Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
20133     bool CurrentRegionOnly,
20134     OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
20135     OpenMPClauseKind CKind) {
20136   assert(VD && E);
20137   SourceLocation ELoc = E->getExprLoc();
20138   SourceRange ERange = E->getSourceRange();
20139 
20140   // In order to easily check the conflicts we need to match each component of
20141   // the expression under test with the components of the expressions that are
20142   // already in the stack.
20143 
20144   assert(!CurComponents.empty() && "Map clause expression with no components!");
20145   assert(CurComponents.back().getAssociatedDeclaration() == VD &&
20146          "Map clause expression with unexpected base!");
20147 
20148   // Variables to help detecting enclosing problems in data environment nests.
20149   bool IsEnclosedByDataEnvironmentExpr = false;
20150   const Expr *EnclosingExpr = nullptr;
20151 
20152   bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
20153       VD, CurrentRegionOnly,
20154       [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
20155        ERange, CKind, &EnclosingExpr,
20156        CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef
20157                           StackComponents,
20158                       OpenMPClauseKind Kind) {
20159         if (CKind == Kind && SemaRef.LangOpts.OpenMP >= 50)
20160           return false;
20161         assert(!StackComponents.empty() &&
20162                "Map clause expression with no components!");
20163         assert(StackComponents.back().getAssociatedDeclaration() == VD &&
20164                "Map clause expression with unexpected base!");
20165         (void)VD;
20166 
20167         // The whole expression in the stack.
20168         const Expr *RE = StackComponents.front().getAssociatedExpression();
20169 
20170         // Expressions must start from the same base. Here we detect at which
20171         // point both expressions diverge from each other and see if we can
20172         // detect if the memory referred to both expressions is contiguous and
20173         // do not overlap.
20174         auto CI = CurComponents.rbegin();
20175         auto CE = CurComponents.rend();
20176         auto SI = StackComponents.rbegin();
20177         auto SE = StackComponents.rend();
20178         for (; CI != CE && SI != SE; ++CI, ++SI) {
20179 
20180           // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
20181           //  At most one list item can be an array item derived from a given
20182           //  variable in map clauses of the same construct.
20183           if (CurrentRegionOnly &&
20184               (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
20185                isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) ||
20186                isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) &&
20187               (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
20188                isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) ||
20189                isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) {
20190             SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
20191                          diag::err_omp_multiple_array_items_in_map_clause)
20192                 << CI->getAssociatedExpression()->getSourceRange();
20193             SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
20194                          diag::note_used_here)
20195                 << SI->getAssociatedExpression()->getSourceRange();
20196             return true;
20197           }
20198 
20199           // Do both expressions have the same kind?
20200           if (CI->getAssociatedExpression()->getStmtClass() !=
20201               SI->getAssociatedExpression()->getStmtClass())
20202             break;
20203 
20204           // Are we dealing with different variables/fields?
20205           if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
20206             break;
20207         }
20208         // Check if the extra components of the expressions in the enclosing
20209         // data environment are redundant for the current base declaration.
20210         // If they are, the maps completely overlap, which is legal.
20211         for (; SI != SE; ++SI) {
20212           QualType Type;
20213           if (const auto *ASE =
20214                   dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
20215             Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
20216           } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
20217                          SI->getAssociatedExpression())) {
20218             const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
20219             Type =
20220                 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
20221           } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>(
20222                          SI->getAssociatedExpression())) {
20223             Type = OASE->getBase()->getType()->getPointeeType();
20224           }
20225           if (Type.isNull() || Type->isAnyPointerType() ||
20226               checkArrayExpressionDoesNotReferToWholeSize(
20227                   SemaRef, SI->getAssociatedExpression(), Type))
20228             break;
20229         }
20230 
20231         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
20232         //  List items of map clauses in the same construct must not share
20233         //  original storage.
20234         //
20235         // If the expressions are exactly the same or one is a subset of the
20236         // other, it means they are sharing storage.
20237         if (CI == CE && SI == SE) {
20238           if (CurrentRegionOnly) {
20239             if (CKind == OMPC_map) {
20240               SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
20241             } else {
20242               assert(CKind == OMPC_to || CKind == OMPC_from);
20243               SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
20244                   << ERange;
20245             }
20246             SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
20247                 << RE->getSourceRange();
20248             return true;
20249           }
20250           // If we find the same expression in the enclosing data environment,
20251           // that is legal.
20252           IsEnclosedByDataEnvironmentExpr = true;
20253           return false;
20254         }
20255 
20256         QualType DerivedType =
20257             std::prev(CI)->getAssociatedDeclaration()->getType();
20258         SourceLocation DerivedLoc =
20259             std::prev(CI)->getAssociatedExpression()->getExprLoc();
20260 
20261         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
20262         //  If the type of a list item is a reference to a type T then the type
20263         //  will be considered to be T for all purposes of this clause.
20264         DerivedType = DerivedType.getNonReferenceType();
20265 
20266         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
20267         //  A variable for which the type is pointer and an array section
20268         //  derived from that variable must not appear as list items of map
20269         //  clauses of the same construct.
20270         //
20271         // Also, cover one of the cases in:
20272         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
20273         //  If any part of the original storage of a list item has corresponding
20274         //  storage in the device data environment, all of the original storage
20275         //  must have corresponding storage in the device data environment.
20276         //
20277         if (DerivedType->isAnyPointerType()) {
20278           if (CI == CE || SI == SE) {
20279             SemaRef.Diag(
20280                 DerivedLoc,
20281                 diag::err_omp_pointer_mapped_along_with_derived_section)
20282                 << DerivedLoc;
20283             SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
20284                 << RE->getSourceRange();
20285             return true;
20286           }
20287           if (CI->getAssociatedExpression()->getStmtClass() !=
20288                   SI->getAssociatedExpression()->getStmtClass() ||
20289               CI->getAssociatedDeclaration()->getCanonicalDecl() ==
20290                   SI->getAssociatedDeclaration()->getCanonicalDecl()) {
20291             assert(CI != CE && SI != SE);
20292             SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
20293                 << DerivedLoc;
20294             SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
20295                 << RE->getSourceRange();
20296             return true;
20297           }
20298         }
20299 
20300         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
20301         //  List items of map clauses in the same construct must not share
20302         //  original storage.
20303         //
20304         // An expression is a subset of the other.
20305         if (CurrentRegionOnly && (CI == CE || SI == SE)) {
20306           if (CKind == OMPC_map) {
20307             if (CI != CE || SI != SE) {
20308               // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
20309               // a pointer.
20310               auto Begin =
20311                   CI != CE ? CurComponents.begin() : StackComponents.begin();
20312               auto End = CI != CE ? CurComponents.end() : StackComponents.end();
20313               auto It = Begin;
20314               while (It != End && !It->getAssociatedDeclaration())
20315                 std::advance(It, 1);
20316               assert(It != End &&
20317                      "Expected at least one component with the declaration.");
20318               if (It != Begin && It->getAssociatedDeclaration()
20319                                      ->getType()
20320                                      .getCanonicalType()
20321                                      ->isAnyPointerType()) {
20322                 IsEnclosedByDataEnvironmentExpr = false;
20323                 EnclosingExpr = nullptr;
20324                 return false;
20325               }
20326             }
20327             SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
20328           } else {
20329             assert(CKind == OMPC_to || CKind == OMPC_from);
20330             SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
20331                 << ERange;
20332           }
20333           SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
20334               << RE->getSourceRange();
20335           return true;
20336         }
20337 
20338         // The current expression uses the same base as other expression in the
20339         // data environment but does not contain it completely.
20340         if (!CurrentRegionOnly && SI != SE)
20341           EnclosingExpr = RE;
20342 
20343         // The current expression is a subset of the expression in the data
20344         // environment.
20345         IsEnclosedByDataEnvironmentExpr |=
20346             (!CurrentRegionOnly && CI != CE && SI == SE);
20347 
20348         return false;
20349       });
20350 
20351   if (CurrentRegionOnly)
20352     return FoundError;
20353 
20354   // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
20355   //  If any part of the original storage of a list item has corresponding
20356   //  storage in the device data environment, all of the original storage must
20357   //  have corresponding storage in the device data environment.
20358   // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
20359   //  If a list item is an element of a structure, and a different element of
20360   //  the structure has a corresponding list item in the device data environment
20361   //  prior to a task encountering the construct associated with the map clause,
20362   //  then the list item must also have a corresponding list item in the device
20363   //  data environment prior to the task encountering the construct.
20364   //
20365   if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
20366     SemaRef.Diag(ELoc,
20367                  diag::err_omp_original_storage_is_shared_and_does_not_contain)
20368         << ERange;
20369     SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
20370         << EnclosingExpr->getSourceRange();
20371     return true;
20372   }
20373 
20374   return FoundError;
20375 }
20376 
20377 // Look up the user-defined mapper given the mapper name and mapped type, and
20378 // build a reference to it.
20379 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
20380                                             CXXScopeSpec &MapperIdScopeSpec,
20381                                             const DeclarationNameInfo &MapperId,
20382                                             QualType Type,
20383                                             Expr *UnresolvedMapper) {
20384   if (MapperIdScopeSpec.isInvalid())
20385     return ExprError();
20386   // Get the actual type for the array type.
20387   if (Type->isArrayType()) {
20388     assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type");
20389     Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType();
20390   }
20391   // Find all user-defined mappers with the given MapperId.
20392   SmallVector<UnresolvedSet<8>, 4> Lookups;
20393   LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
20394   Lookup.suppressDiagnostics();
20395   if (S) {
20396     while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) {
20397       NamedDecl *D = Lookup.getRepresentativeDecl();
20398       while (S && !S->isDeclScope(D))
20399         S = S->getParent();
20400       if (S)
20401         S = S->getParent();
20402       Lookups.emplace_back();
20403       Lookups.back().append(Lookup.begin(), Lookup.end());
20404       Lookup.clear();
20405     }
20406   } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
20407     // Extract the user-defined mappers with the given MapperId.
20408     Lookups.push_back(UnresolvedSet<8>());
20409     for (NamedDecl *D : ULE->decls()) {
20410       auto *DMD = cast<OMPDeclareMapperDecl>(D);
20411       assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation.");
20412       Lookups.back().addDecl(DMD);
20413     }
20414   }
20415   // Defer the lookup for dependent types. The results will be passed through
20416   // UnresolvedMapper on instantiation.
20417   if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
20418       Type->isInstantiationDependentType() ||
20419       Type->containsUnexpandedParameterPack() ||
20420       filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
20421         return !D->isInvalidDecl() &&
20422                (D->getType()->isDependentType() ||
20423                 D->getType()->isInstantiationDependentType() ||
20424                 D->getType()->containsUnexpandedParameterPack());
20425       })) {
20426     UnresolvedSet<8> URS;
20427     for (const UnresolvedSet<8> &Set : Lookups) {
20428       if (Set.empty())
20429         continue;
20430       URS.append(Set.begin(), Set.end());
20431     }
20432     return UnresolvedLookupExpr::Create(
20433         SemaRef.Context, /*NamingClass=*/nullptr,
20434         MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
20435         /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end());
20436   }
20437   SourceLocation Loc = MapperId.getLoc();
20438   // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
20439   //  The type must be of struct, union or class type in C and C++
20440   if (!Type->isStructureOrClassType() && !Type->isUnionType() &&
20441       (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) {
20442     SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type);
20443     return ExprError();
20444   }
20445   // Perform argument dependent lookup.
20446   if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
20447     argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
20448   // Return the first user-defined mapper with the desired type.
20449   if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
20450           Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
20451             if (!D->isInvalidDecl() &&
20452                 SemaRef.Context.hasSameType(D->getType(), Type))
20453               return D;
20454             return nullptr;
20455           }))
20456     return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
20457   // Find the first user-defined mapper with a type derived from the desired
20458   // type.
20459   if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
20460           Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
20461             if (!D->isInvalidDecl() &&
20462                 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
20463                 !Type.isMoreQualifiedThan(D->getType()))
20464               return D;
20465             return nullptr;
20466           })) {
20467     CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
20468                        /*DetectVirtual=*/false);
20469     if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
20470       if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
20471               VD->getType().getUnqualifiedType()))) {
20472         if (SemaRef.CheckBaseClassAccess(
20473                 Loc, VD->getType(), Type, Paths.front(),
20474                 /*DiagID=*/0) != Sema::AR_inaccessible) {
20475           return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
20476         }
20477       }
20478     }
20479   }
20480   // Report error if a mapper is specified, but cannot be found.
20481   if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
20482     SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
20483         << Type << MapperId.getName();
20484     return ExprError();
20485   }
20486   return ExprEmpty();
20487 }
20488 
20489 namespace {
20490 // Utility struct that gathers all the related lists associated with a mappable
20491 // expression.
20492 struct MappableVarListInfo {
20493   // The list of expressions.
20494   ArrayRef<Expr *> VarList;
20495   // The list of processed expressions.
20496   SmallVector<Expr *, 16> ProcessedVarList;
20497   // The mappble components for each expression.
20498   OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
20499   // The base declaration of the variable.
20500   SmallVector<ValueDecl *, 16> VarBaseDeclarations;
20501   // The reference to the user-defined mapper associated with every expression.
20502   SmallVector<Expr *, 16> UDMapperList;
20503 
20504   MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
20505     // We have a list of components and base declarations for each entry in the
20506     // variable list.
20507     VarComponents.reserve(VarList.size());
20508     VarBaseDeclarations.reserve(VarList.size());
20509   }
20510 };
20511 } // namespace
20512 
20513 // Check the validity of the provided variable list for the provided clause kind
20514 // \a CKind. In the check process the valid expressions, mappable expression
20515 // components, variables, and user-defined mappers are extracted and used to
20516 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
20517 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
20518 // and \a MapperId are expected to be valid if the clause kind is 'map'.
20519 static void checkMappableExpressionList(
20520     Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
20521     MappableVarListInfo &MVLI, SourceLocation StartLoc,
20522     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
20523     ArrayRef<Expr *> UnresolvedMappers,
20524     OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
20525     ArrayRef<OpenMPMapModifierKind> Modifiers = None,
20526     bool IsMapTypeImplicit = false, bool NoDiagnose = false) {
20527   // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
20528   assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
20529          "Unexpected clause kind with mappable expressions!");
20530 
20531   // If the identifier of user-defined mapper is not specified, it is "default".
20532   // We do not change the actual name in this clause to distinguish whether a
20533   // mapper is specified explicitly, i.e., it is not explicitly specified when
20534   // MapperId.getName() is empty.
20535   if (!MapperId.getName() || MapperId.getName().isEmpty()) {
20536     auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
20537     MapperId.setName(DeclNames.getIdentifier(
20538         &SemaRef.getASTContext().Idents.get("default")));
20539     MapperId.setLoc(StartLoc);
20540   }
20541 
20542   // Iterators to find the current unresolved mapper expression.
20543   auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
20544   bool UpdateUMIt = false;
20545   Expr *UnresolvedMapper = nullptr;
20546 
20547   bool HasHoldModifier =
20548       llvm::is_contained(Modifiers, OMPC_MAP_MODIFIER_ompx_hold);
20549 
20550   // Keep track of the mappable components and base declarations in this clause.
20551   // Each entry in the list is going to have a list of components associated. We
20552   // record each set of the components so that we can build the clause later on.
20553   // In the end we should have the same amount of declarations and component
20554   // lists.
20555 
20556   for (Expr *RE : MVLI.VarList) {
20557     assert(RE && "Null expr in omp to/from/map clause");
20558     SourceLocation ELoc = RE->getExprLoc();
20559 
20560     // Find the current unresolved mapper expression.
20561     if (UpdateUMIt && UMIt != UMEnd) {
20562       UMIt++;
20563       assert(
20564           UMIt != UMEnd &&
20565           "Expect the size of UnresolvedMappers to match with that of VarList");
20566     }
20567     UpdateUMIt = true;
20568     if (UMIt != UMEnd)
20569       UnresolvedMapper = *UMIt;
20570 
20571     const Expr *VE = RE->IgnoreParenLValueCasts();
20572 
20573     if (VE->isValueDependent() || VE->isTypeDependent() ||
20574         VE->isInstantiationDependent() ||
20575         VE->containsUnexpandedParameterPack()) {
20576       // Try to find the associated user-defined mapper.
20577       ExprResult ER = buildUserDefinedMapperRef(
20578           SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
20579           VE->getType().getCanonicalType(), UnresolvedMapper);
20580       if (ER.isInvalid())
20581         continue;
20582       MVLI.UDMapperList.push_back(ER.get());
20583       // We can only analyze this information once the missing information is
20584       // resolved.
20585       MVLI.ProcessedVarList.push_back(RE);
20586       continue;
20587     }
20588 
20589     Expr *SimpleExpr = RE->IgnoreParenCasts();
20590 
20591     if (!RE->isLValue()) {
20592       if (SemaRef.getLangOpts().OpenMP < 50) {
20593         SemaRef.Diag(
20594             ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
20595             << RE->getSourceRange();
20596       } else {
20597         SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
20598             << getOpenMPClauseName(CKind) << RE->getSourceRange();
20599       }
20600       continue;
20601     }
20602 
20603     OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
20604     ValueDecl *CurDeclaration = nullptr;
20605 
20606     // Obtain the array or member expression bases if required. Also, fill the
20607     // components array with all the components identified in the process.
20608     const Expr *BE =
20609         checkMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents, CKind,
20610                                      DSAS->getCurrentDirective(), NoDiagnose);
20611     if (!BE)
20612       continue;
20613 
20614     assert(!CurComponents.empty() &&
20615            "Invalid mappable expression information.");
20616 
20617     if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
20618       // Add store "this" pointer to class in DSAStackTy for future checking
20619       DSAS->addMappedClassesQualTypes(TE->getType());
20620       // Try to find the associated user-defined mapper.
20621       ExprResult ER = buildUserDefinedMapperRef(
20622           SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
20623           VE->getType().getCanonicalType(), UnresolvedMapper);
20624       if (ER.isInvalid())
20625         continue;
20626       MVLI.UDMapperList.push_back(ER.get());
20627       // Skip restriction checking for variable or field declarations
20628       MVLI.ProcessedVarList.push_back(RE);
20629       MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
20630       MVLI.VarComponents.back().append(CurComponents.begin(),
20631                                        CurComponents.end());
20632       MVLI.VarBaseDeclarations.push_back(nullptr);
20633       continue;
20634     }
20635 
20636     // For the following checks, we rely on the base declaration which is
20637     // expected to be associated with the last component. The declaration is
20638     // expected to be a variable or a field (if 'this' is being mapped).
20639     CurDeclaration = CurComponents.back().getAssociatedDeclaration();
20640     assert(CurDeclaration && "Null decl on map clause.");
20641     assert(
20642         CurDeclaration->isCanonicalDecl() &&
20643         "Expecting components to have associated only canonical declarations.");
20644 
20645     auto *VD = dyn_cast<VarDecl>(CurDeclaration);
20646     const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
20647 
20648     assert((VD || FD) && "Only variables or fields are expected here!");
20649     (void)FD;
20650 
20651     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
20652     // threadprivate variables cannot appear in a map clause.
20653     // OpenMP 4.5 [2.10.5, target update Construct]
20654     // threadprivate variables cannot appear in a from clause.
20655     if (VD && DSAS->isThreadPrivate(VD)) {
20656       if (NoDiagnose)
20657         continue;
20658       DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
20659       SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
20660           << getOpenMPClauseName(CKind);
20661       reportOriginalDsa(SemaRef, DSAS, VD, DVar);
20662       continue;
20663     }
20664 
20665     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
20666     //  A list item cannot appear in both a map clause and a data-sharing
20667     //  attribute clause on the same construct.
20668 
20669     // Check conflicts with other map clause expressions. We check the conflicts
20670     // with the current construct separately from the enclosing data
20671     // environment, because the restrictions are different. We only have to
20672     // check conflicts across regions for the map clauses.
20673     if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
20674                           /*CurrentRegionOnly=*/true, CurComponents, CKind))
20675       break;
20676     if (CKind == OMPC_map &&
20677         (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) &&
20678         checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
20679                           /*CurrentRegionOnly=*/false, CurComponents, CKind))
20680       break;
20681 
20682     // OpenMP 4.5 [2.10.5, target update Construct]
20683     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
20684     //  If the type of a list item is a reference to a type T then the type will
20685     //  be considered to be T for all purposes of this clause.
20686     auto I = llvm::find_if(
20687         CurComponents,
20688         [](const OMPClauseMappableExprCommon::MappableComponent &MC) {
20689           return MC.getAssociatedDeclaration();
20690         });
20691     assert(I != CurComponents.end() && "Null decl on map clause.");
20692     (void)I;
20693     QualType Type;
20694     auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens());
20695     auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens());
20696     auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens());
20697     if (ASE) {
20698       Type = ASE->getType().getNonReferenceType();
20699     } else if (OASE) {
20700       QualType BaseType =
20701           OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
20702       if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
20703         Type = ATy->getElementType();
20704       else
20705         Type = BaseType->getPointeeType();
20706       Type = Type.getNonReferenceType();
20707     } else if (OAShE) {
20708       Type = OAShE->getBase()->getType()->getPointeeType();
20709     } else {
20710       Type = VE->getType();
20711     }
20712 
20713     // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
20714     // A list item in a to or from clause must have a mappable type.
20715     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
20716     //  A list item must have a mappable type.
20717     if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
20718                            DSAS, Type, /*FullCheck=*/true))
20719       continue;
20720 
20721     if (CKind == OMPC_map) {
20722       // target enter data
20723       // OpenMP [2.10.2, Restrictions, p. 99]
20724       // A map-type must be specified in all map clauses and must be either
20725       // to or alloc.
20726       OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
20727       if (DKind == OMPD_target_enter_data &&
20728           !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
20729         SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
20730             << (IsMapTypeImplicit ? 1 : 0)
20731             << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
20732             << getOpenMPDirectiveName(DKind);
20733         continue;
20734       }
20735 
20736       // target exit_data
20737       // OpenMP [2.10.3, Restrictions, p. 102]
20738       // A map-type must be specified in all map clauses and must be either
20739       // from, release, or delete.
20740       if (DKind == OMPD_target_exit_data &&
20741           !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
20742             MapType == OMPC_MAP_delete)) {
20743         SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
20744             << (IsMapTypeImplicit ? 1 : 0)
20745             << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
20746             << getOpenMPDirectiveName(DKind);
20747         continue;
20748       }
20749 
20750       // The 'ompx_hold' modifier is specifically intended to be used on a
20751       // 'target' or 'target data' directive to prevent data from being unmapped
20752       // during the associated statement.  It is not permitted on a 'target
20753       // enter data' or 'target exit data' directive, which have no associated
20754       // statement.
20755       if ((DKind == OMPD_target_enter_data || DKind == OMPD_target_exit_data) &&
20756           HasHoldModifier) {
20757         SemaRef.Diag(StartLoc,
20758                      diag::err_omp_invalid_map_type_modifier_for_directive)
20759             << getOpenMPSimpleClauseTypeName(OMPC_map,
20760                                              OMPC_MAP_MODIFIER_ompx_hold)
20761             << getOpenMPDirectiveName(DKind);
20762         continue;
20763       }
20764 
20765       // target, target data
20766       // OpenMP 5.0 [2.12.2, Restrictions, p. 163]
20767       // OpenMP 5.0 [2.12.5, Restrictions, p. 174]
20768       // A map-type in a map clause must be to, from, tofrom or alloc
20769       if ((DKind == OMPD_target_data ||
20770            isOpenMPTargetExecutionDirective(DKind)) &&
20771           !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
20772             MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) {
20773         SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
20774             << (IsMapTypeImplicit ? 1 : 0)
20775             << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
20776             << getOpenMPDirectiveName(DKind);
20777         continue;
20778       }
20779 
20780       // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
20781       // A list item cannot appear in both a map clause and a data-sharing
20782       // attribute clause on the same construct
20783       //
20784       // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
20785       // A list item cannot appear in both a map clause and a data-sharing
20786       // attribute clause on the same construct unless the construct is a
20787       // combined construct.
20788       if (VD && ((SemaRef.LangOpts.OpenMP <= 45 &&
20789                   isOpenMPTargetExecutionDirective(DKind)) ||
20790                  DKind == OMPD_target)) {
20791         DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
20792         if (isOpenMPPrivate(DVar.CKind)) {
20793           SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
20794               << getOpenMPClauseName(DVar.CKind)
20795               << getOpenMPClauseName(OMPC_map)
20796               << getOpenMPDirectiveName(DSAS->getCurrentDirective());
20797           reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
20798           continue;
20799         }
20800       }
20801     }
20802 
20803     // Try to find the associated user-defined mapper.
20804     ExprResult ER = buildUserDefinedMapperRef(
20805         SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
20806         Type.getCanonicalType(), UnresolvedMapper);
20807     if (ER.isInvalid())
20808       continue;
20809     MVLI.UDMapperList.push_back(ER.get());
20810 
20811     // Save the current expression.
20812     MVLI.ProcessedVarList.push_back(RE);
20813 
20814     // Store the components in the stack so that they can be used to check
20815     // against other clauses later on.
20816     DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
20817                                           /*WhereFoundClauseKind=*/OMPC_map);
20818 
20819     // Save the components and declaration to create the clause. For purposes of
20820     // the clause creation, any component list that has has base 'this' uses
20821     // null as base declaration.
20822     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
20823     MVLI.VarComponents.back().append(CurComponents.begin(),
20824                                      CurComponents.end());
20825     MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
20826                                                            : CurDeclaration);
20827   }
20828 }
20829 
20830 OMPClause *Sema::ActOnOpenMPMapClause(
20831     ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
20832     ArrayRef<SourceLocation> MapTypeModifiersLoc,
20833     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
20834     OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
20835     SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
20836     const OMPVarListLocTy &Locs, bool NoDiagnose,
20837     ArrayRef<Expr *> UnresolvedMappers) {
20838   OpenMPMapModifierKind Modifiers[] = {
20839       OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
20840       OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
20841       OMPC_MAP_MODIFIER_unknown};
20842   SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers];
20843 
20844   // Process map-type-modifiers, flag errors for duplicate modifiers.
20845   unsigned Count = 0;
20846   for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
20847     if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
20848         llvm::is_contained(Modifiers, MapTypeModifiers[I])) {
20849       Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
20850       continue;
20851     }
20852     assert(Count < NumberOfOMPMapClauseModifiers &&
20853            "Modifiers exceed the allowed number of map type modifiers");
20854     Modifiers[Count] = MapTypeModifiers[I];
20855     ModifiersLoc[Count] = MapTypeModifiersLoc[I];
20856     ++Count;
20857   }
20858 
20859   MappableVarListInfo MVLI(VarList);
20860   checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc,
20861                               MapperIdScopeSpec, MapperId, UnresolvedMappers,
20862                               MapType, Modifiers, IsMapTypeImplicit,
20863                               NoDiagnose);
20864 
20865   // We need to produce a map clause even if we don't have variables so that
20866   // other diagnostics related with non-existing map clauses are accurate.
20867   return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList,
20868                               MVLI.VarBaseDeclarations, MVLI.VarComponents,
20869                               MVLI.UDMapperList, Modifiers, ModifiersLoc,
20870                               MapperIdScopeSpec.getWithLocInContext(Context),
20871                               MapperId, MapType, IsMapTypeImplicit, MapLoc);
20872 }
20873 
20874 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
20875                                                TypeResult ParsedType) {
20876   assert(ParsedType.isUsable());
20877 
20878   QualType ReductionType = GetTypeFromParser(ParsedType.get());
20879   if (ReductionType.isNull())
20880     return QualType();
20881 
20882   // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
20883   // A type name in a declare reduction directive cannot be a function type, an
20884   // array type, a reference type, or a type qualified with const, volatile or
20885   // restrict.
20886   if (ReductionType.hasQualifiers()) {
20887     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
20888     return QualType();
20889   }
20890 
20891   if (ReductionType->isFunctionType()) {
20892     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
20893     return QualType();
20894   }
20895   if (ReductionType->isReferenceType()) {
20896     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
20897     return QualType();
20898   }
20899   if (ReductionType->isArrayType()) {
20900     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
20901     return QualType();
20902   }
20903   return ReductionType;
20904 }
20905 
20906 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
20907     Scope *S, DeclContext *DC, DeclarationName Name,
20908     ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
20909     AccessSpecifier AS, Decl *PrevDeclInScope) {
20910   SmallVector<Decl *, 8> Decls;
20911   Decls.reserve(ReductionTypes.size());
20912 
20913   LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
20914                       forRedeclarationInCurContext());
20915   // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
20916   // A reduction-identifier may not be re-declared in the current scope for the
20917   // same type or for a type that is compatible according to the base language
20918   // rules.
20919   llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
20920   OMPDeclareReductionDecl *PrevDRD = nullptr;
20921   bool InCompoundScope = true;
20922   if (S != nullptr) {
20923     // Find previous declaration with the same name not referenced in other
20924     // declarations.
20925     FunctionScopeInfo *ParentFn = getEnclosingFunction();
20926     InCompoundScope =
20927         (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
20928     LookupName(Lookup, S);
20929     FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
20930                          /*AllowInlineNamespace=*/false);
20931     llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
20932     LookupResult::Filter Filter = Lookup.makeFilter();
20933     while (Filter.hasNext()) {
20934       auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
20935       if (InCompoundScope) {
20936         auto I = UsedAsPrevious.find(PrevDecl);
20937         if (I == UsedAsPrevious.end())
20938           UsedAsPrevious[PrevDecl] = false;
20939         if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
20940           UsedAsPrevious[D] = true;
20941       }
20942       PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
20943           PrevDecl->getLocation();
20944     }
20945     Filter.done();
20946     if (InCompoundScope) {
20947       for (const auto &PrevData : UsedAsPrevious) {
20948         if (!PrevData.second) {
20949           PrevDRD = PrevData.first;
20950           break;
20951         }
20952       }
20953     }
20954   } else if (PrevDeclInScope != nullptr) {
20955     auto *PrevDRDInScope = PrevDRD =
20956         cast<OMPDeclareReductionDecl>(PrevDeclInScope);
20957     do {
20958       PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
20959           PrevDRDInScope->getLocation();
20960       PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
20961     } while (PrevDRDInScope != nullptr);
20962   }
20963   for (const auto &TyData : ReductionTypes) {
20964     const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
20965     bool Invalid = false;
20966     if (I != PreviousRedeclTypes.end()) {
20967       Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
20968           << TyData.first;
20969       Diag(I->second, diag::note_previous_definition);
20970       Invalid = true;
20971     }
20972     PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
20973     auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
20974                                                 Name, TyData.first, PrevDRD);
20975     DC->addDecl(DRD);
20976     DRD->setAccess(AS);
20977     Decls.push_back(DRD);
20978     if (Invalid)
20979       DRD->setInvalidDecl();
20980     else
20981       PrevDRD = DRD;
20982   }
20983 
20984   return DeclGroupPtrTy::make(
20985       DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
20986 }
20987 
20988 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
20989   auto *DRD = cast<OMPDeclareReductionDecl>(D);
20990 
20991   // Enter new function scope.
20992   PushFunctionScope();
20993   setFunctionHasBranchProtectedScope();
20994   getCurFunction()->setHasOMPDeclareReductionCombiner();
20995 
20996   if (S != nullptr)
20997     PushDeclContext(S, DRD);
20998   else
20999     CurContext = DRD;
21000 
21001   PushExpressionEvaluationContext(
21002       ExpressionEvaluationContext::PotentiallyEvaluated);
21003 
21004   QualType ReductionType = DRD->getType();
21005   // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
21006   // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
21007   // uses semantics of argument handles by value, but it should be passed by
21008   // reference. C lang does not support references, so pass all parameters as
21009   // pointers.
21010   // Create 'T omp_in;' variable.
21011   VarDecl *OmpInParm =
21012       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
21013   // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
21014   // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
21015   // uses semantics of argument handles by value, but it should be passed by
21016   // reference. C lang does not support references, so pass all parameters as
21017   // pointers.
21018   // Create 'T omp_out;' variable.
21019   VarDecl *OmpOutParm =
21020       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
21021   if (S != nullptr) {
21022     PushOnScopeChains(OmpInParm, S);
21023     PushOnScopeChains(OmpOutParm, S);
21024   } else {
21025     DRD->addDecl(OmpInParm);
21026     DRD->addDecl(OmpOutParm);
21027   }
21028   Expr *InE =
21029       ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
21030   Expr *OutE =
21031       ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
21032   DRD->setCombinerData(InE, OutE);
21033 }
21034 
21035 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
21036   auto *DRD = cast<OMPDeclareReductionDecl>(D);
21037   DiscardCleanupsInEvaluationContext();
21038   PopExpressionEvaluationContext();
21039 
21040   PopDeclContext();
21041   PopFunctionScopeInfo();
21042 
21043   if (Combiner != nullptr)
21044     DRD->setCombiner(Combiner);
21045   else
21046     DRD->setInvalidDecl();
21047 }
21048 
21049 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
21050   auto *DRD = cast<OMPDeclareReductionDecl>(D);
21051 
21052   // Enter new function scope.
21053   PushFunctionScope();
21054   setFunctionHasBranchProtectedScope();
21055 
21056   if (S != nullptr)
21057     PushDeclContext(S, DRD);
21058   else
21059     CurContext = DRD;
21060 
21061   PushExpressionEvaluationContext(
21062       ExpressionEvaluationContext::PotentiallyEvaluated);
21063 
21064   QualType ReductionType = DRD->getType();
21065   // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
21066   // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
21067   // uses semantics of argument handles by value, but it should be passed by
21068   // reference. C lang does not support references, so pass all parameters as
21069   // pointers.
21070   // Create 'T omp_priv;' variable.
21071   VarDecl *OmpPrivParm =
21072       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
21073   // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
21074   // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
21075   // uses semantics of argument handles by value, but it should be passed by
21076   // reference. C lang does not support references, so pass all parameters as
21077   // pointers.
21078   // Create 'T omp_orig;' variable.
21079   VarDecl *OmpOrigParm =
21080       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
21081   if (S != nullptr) {
21082     PushOnScopeChains(OmpPrivParm, S);
21083     PushOnScopeChains(OmpOrigParm, S);
21084   } else {
21085     DRD->addDecl(OmpPrivParm);
21086     DRD->addDecl(OmpOrigParm);
21087   }
21088   Expr *OrigE =
21089       ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
21090   Expr *PrivE =
21091       ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
21092   DRD->setInitializerData(OrigE, PrivE);
21093   return OmpPrivParm;
21094 }
21095 
21096 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
21097                                                      VarDecl *OmpPrivParm) {
21098   auto *DRD = cast<OMPDeclareReductionDecl>(D);
21099   DiscardCleanupsInEvaluationContext();
21100   PopExpressionEvaluationContext();
21101 
21102   PopDeclContext();
21103   PopFunctionScopeInfo();
21104 
21105   if (Initializer != nullptr) {
21106     DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
21107   } else if (OmpPrivParm->hasInit()) {
21108     DRD->setInitializer(OmpPrivParm->getInit(),
21109                         OmpPrivParm->isDirectInit()
21110                             ? OMPDeclareReductionDecl::DirectInit
21111                             : OMPDeclareReductionDecl::CopyInit);
21112   } else {
21113     DRD->setInvalidDecl();
21114   }
21115 }
21116 
21117 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
21118     Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
21119   for (Decl *D : DeclReductions.get()) {
21120     if (IsValid) {
21121       if (S)
21122         PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
21123                           /*AddToContext=*/false);
21124     } else {
21125       D->setInvalidDecl();
21126     }
21127   }
21128   return DeclReductions;
21129 }
21130 
21131 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) {
21132   TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
21133   QualType T = TInfo->getType();
21134   if (D.isInvalidType())
21135     return true;
21136 
21137   if (getLangOpts().CPlusPlus) {
21138     // Check that there are no default arguments (C++ only).
21139     CheckExtraCXXDefaultArguments(D);
21140   }
21141 
21142   return CreateParsedType(T, TInfo);
21143 }
21144 
21145 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
21146                                             TypeResult ParsedType) {
21147   assert(ParsedType.isUsable() && "Expect usable parsed mapper type");
21148 
21149   QualType MapperType = GetTypeFromParser(ParsedType.get());
21150   assert(!MapperType.isNull() && "Expect valid mapper type");
21151 
21152   // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
21153   //  The type must be of struct, union or class type in C and C++
21154   if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
21155     Diag(TyLoc, diag::err_omp_mapper_wrong_type);
21156     return QualType();
21157   }
21158   return MapperType;
21159 }
21160 
21161 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective(
21162     Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
21163     SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
21164     Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) {
21165   LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
21166                       forRedeclarationInCurContext());
21167   // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
21168   //  A mapper-identifier may not be redeclared in the current scope for the
21169   //  same type or for a type that is compatible according to the base language
21170   //  rules.
21171   llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
21172   OMPDeclareMapperDecl *PrevDMD = nullptr;
21173   bool InCompoundScope = true;
21174   if (S != nullptr) {
21175     // Find previous declaration with the same name not referenced in other
21176     // declarations.
21177     FunctionScopeInfo *ParentFn = getEnclosingFunction();
21178     InCompoundScope =
21179         (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
21180     LookupName(Lookup, S);
21181     FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
21182                          /*AllowInlineNamespace=*/false);
21183     llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
21184     LookupResult::Filter Filter = Lookup.makeFilter();
21185     while (Filter.hasNext()) {
21186       auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
21187       if (InCompoundScope) {
21188         auto I = UsedAsPrevious.find(PrevDecl);
21189         if (I == UsedAsPrevious.end())
21190           UsedAsPrevious[PrevDecl] = false;
21191         if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
21192           UsedAsPrevious[D] = true;
21193       }
21194       PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
21195           PrevDecl->getLocation();
21196     }
21197     Filter.done();
21198     if (InCompoundScope) {
21199       for (const auto &PrevData : UsedAsPrevious) {
21200         if (!PrevData.second) {
21201           PrevDMD = PrevData.first;
21202           break;
21203         }
21204       }
21205     }
21206   } else if (PrevDeclInScope) {
21207     auto *PrevDMDInScope = PrevDMD =
21208         cast<OMPDeclareMapperDecl>(PrevDeclInScope);
21209     do {
21210       PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
21211           PrevDMDInScope->getLocation();
21212       PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
21213     } while (PrevDMDInScope != nullptr);
21214   }
21215   const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
21216   bool Invalid = false;
21217   if (I != PreviousRedeclTypes.end()) {
21218     Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
21219         << MapperType << Name;
21220     Diag(I->second, diag::note_previous_definition);
21221     Invalid = true;
21222   }
21223   // Build expressions for implicit maps of data members with 'default'
21224   // mappers.
21225   SmallVector<OMPClause *, 4> ClausesWithImplicit(Clauses.begin(),
21226                                                   Clauses.end());
21227   if (LangOpts.OpenMP >= 50)
21228     processImplicitMapsWithDefaultMappers(*this, DSAStack, ClausesWithImplicit);
21229   auto *DMD =
21230       OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, MapperType, VN,
21231                                    ClausesWithImplicit, PrevDMD);
21232   if (S)
21233     PushOnScopeChains(DMD, S);
21234   else
21235     DC->addDecl(DMD);
21236   DMD->setAccess(AS);
21237   if (Invalid)
21238     DMD->setInvalidDecl();
21239 
21240   auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl();
21241   VD->setDeclContext(DMD);
21242   VD->setLexicalDeclContext(DMD);
21243   DMD->addDecl(VD);
21244   DMD->setMapperVarRef(MapperVarRef);
21245 
21246   return DeclGroupPtrTy::make(DeclGroupRef(DMD));
21247 }
21248 
21249 ExprResult
21250 Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType,
21251                                                SourceLocation StartLoc,
21252                                                DeclarationName VN) {
21253   TypeSourceInfo *TInfo =
21254       Context.getTrivialTypeSourceInfo(MapperType, StartLoc);
21255   auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(),
21256                              StartLoc, StartLoc, VN.getAsIdentifierInfo(),
21257                              MapperType, TInfo, SC_None);
21258   if (S)
21259     PushOnScopeChains(VD, S, /*AddToContext=*/false);
21260   Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
21261   DSAStack->addDeclareMapperVarRef(E);
21262   return E;
21263 }
21264 
21265 bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const {
21266   assert(LangOpts.OpenMP && "Expected OpenMP mode.");
21267   const Expr *Ref = DSAStack->getDeclareMapperVarRef();
21268   if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref)) {
21269     if (VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl())
21270       return true;
21271     if (VD->isUsableInConstantExpressions(Context))
21272       return true;
21273     return false;
21274   }
21275   return true;
21276 }
21277 
21278 const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const {
21279   assert(LangOpts.OpenMP && "Expected OpenMP mode.");
21280   return cast<DeclRefExpr>(DSAStack->getDeclareMapperVarRef())->getDecl();
21281 }
21282 
21283 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
21284                                            SourceLocation StartLoc,
21285                                            SourceLocation LParenLoc,
21286                                            SourceLocation EndLoc) {
21287   Expr *ValExpr = NumTeams;
21288   Stmt *HelperValStmt = nullptr;
21289 
21290   // OpenMP [teams Constrcut, Restrictions]
21291   // The num_teams expression must evaluate to a positive integer value.
21292   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
21293                                  /*StrictlyPositive=*/true))
21294     return nullptr;
21295 
21296   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
21297   OpenMPDirectiveKind CaptureRegion =
21298       getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP);
21299   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
21300     ValExpr = MakeFullExpr(ValExpr).get();
21301     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
21302     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
21303     HelperValStmt = buildPreInits(Context, Captures);
21304   }
21305 
21306   return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
21307                                          StartLoc, LParenLoc, EndLoc);
21308 }
21309 
21310 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
21311                                               SourceLocation StartLoc,
21312                                               SourceLocation LParenLoc,
21313                                               SourceLocation EndLoc) {
21314   Expr *ValExpr = ThreadLimit;
21315   Stmt *HelperValStmt = nullptr;
21316 
21317   // OpenMP [teams Constrcut, Restrictions]
21318   // The thread_limit expression must evaluate to a positive integer value.
21319   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
21320                                  /*StrictlyPositive=*/true))
21321     return nullptr;
21322 
21323   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
21324   OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
21325       DKind, OMPC_thread_limit, LangOpts.OpenMP);
21326   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
21327     ValExpr = MakeFullExpr(ValExpr).get();
21328     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
21329     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
21330     HelperValStmt = buildPreInits(Context, Captures);
21331   }
21332 
21333   return new (Context) OMPThreadLimitClause(
21334       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
21335 }
21336 
21337 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
21338                                            SourceLocation StartLoc,
21339                                            SourceLocation LParenLoc,
21340                                            SourceLocation EndLoc) {
21341   Expr *ValExpr = Priority;
21342   Stmt *HelperValStmt = nullptr;
21343   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
21344 
21345   // OpenMP [2.9.1, task Constrcut]
21346   // The priority-value is a non-negative numerical scalar expression.
21347   if (!isNonNegativeIntegerValue(
21348           ValExpr, *this, OMPC_priority,
21349           /*StrictlyPositive=*/false, /*BuildCapture=*/true,
21350           DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
21351     return nullptr;
21352 
21353   return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion,
21354                                          StartLoc, LParenLoc, EndLoc);
21355 }
21356 
21357 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize,
21358                                             SourceLocation StartLoc,
21359                                             SourceLocation LParenLoc,
21360                                             SourceLocation EndLoc) {
21361   Expr *ValExpr = Grainsize;
21362   Stmt *HelperValStmt = nullptr;
21363   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
21364 
21365   // OpenMP [2.9.2, taskloop Constrcut]
21366   // The parameter of the grainsize clause must be a positive integer
21367   // expression.
21368   if (!isNonNegativeIntegerValue(
21369           ValExpr, *this, OMPC_grainsize,
21370           /*StrictlyPositive=*/true, /*BuildCapture=*/true,
21371           DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
21372     return nullptr;
21373 
21374   return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion,
21375                                           StartLoc, LParenLoc, EndLoc);
21376 }
21377 
21378 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
21379                                            SourceLocation StartLoc,
21380                                            SourceLocation LParenLoc,
21381                                            SourceLocation EndLoc) {
21382   Expr *ValExpr = NumTasks;
21383   Stmt *HelperValStmt = nullptr;
21384   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
21385 
21386   // OpenMP [2.9.2, taskloop Constrcut]
21387   // The parameter of the num_tasks clause must be a positive integer
21388   // expression.
21389   if (!isNonNegativeIntegerValue(
21390           ValExpr, *this, OMPC_num_tasks,
21391           /*StrictlyPositive=*/true, /*BuildCapture=*/true,
21392           DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
21393     return nullptr;
21394 
21395   return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion,
21396                                          StartLoc, LParenLoc, EndLoc);
21397 }
21398 
21399 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
21400                                        SourceLocation LParenLoc,
21401                                        SourceLocation EndLoc) {
21402   // OpenMP [2.13.2, critical construct, Description]
21403   // ... where hint-expression is an integer constant expression that evaluates
21404   // to a valid lock hint.
21405   ExprResult HintExpr =
21406       VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint, false);
21407   if (HintExpr.isInvalid())
21408     return nullptr;
21409   return new (Context)
21410       OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
21411 }
21412 
21413 /// Tries to find omp_event_handle_t type.
21414 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc,
21415                                 DSAStackTy *Stack) {
21416   QualType OMPEventHandleT = Stack->getOMPEventHandleT();
21417   if (!OMPEventHandleT.isNull())
21418     return true;
21419   IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t");
21420   ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
21421   if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
21422     S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t";
21423     return false;
21424   }
21425   Stack->setOMPEventHandleT(PT.get());
21426   return true;
21427 }
21428 
21429 OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc,
21430                                          SourceLocation LParenLoc,
21431                                          SourceLocation EndLoc) {
21432   if (!Evt->isValueDependent() && !Evt->isTypeDependent() &&
21433       !Evt->isInstantiationDependent() &&
21434       !Evt->containsUnexpandedParameterPack()) {
21435     if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack))
21436       return nullptr;
21437     // OpenMP 5.0, 2.10.1 task Construct.
21438     // event-handle is a variable of the omp_event_handle_t type.
21439     auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts());
21440     if (!Ref) {
21441       Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
21442           << "omp_event_handle_t" << 0 << Evt->getSourceRange();
21443       return nullptr;
21444     }
21445     auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl());
21446     if (!VD) {
21447       Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
21448           << "omp_event_handle_t" << 0 << Evt->getSourceRange();
21449       return nullptr;
21450     }
21451     if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(),
21452                                         VD->getType()) ||
21453         VD->getType().isConstant(Context)) {
21454       Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
21455           << "omp_event_handle_t" << 1 << VD->getType()
21456           << Evt->getSourceRange();
21457       return nullptr;
21458     }
21459     // OpenMP 5.0, 2.10.1 task Construct
21460     // [detach clause]... The event-handle will be considered as if it was
21461     // specified on a firstprivate clause.
21462     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false);
21463     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
21464         DVar.RefExpr) {
21465       Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa)
21466           << getOpenMPClauseName(DVar.CKind)
21467           << getOpenMPClauseName(OMPC_firstprivate);
21468       reportOriginalDsa(*this, DSAStack, VD, DVar);
21469       return nullptr;
21470     }
21471   }
21472 
21473   return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc);
21474 }
21475 
21476 OMPClause *Sema::ActOnOpenMPDistScheduleClause(
21477     OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
21478     SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
21479     SourceLocation EndLoc) {
21480   if (Kind == OMPC_DIST_SCHEDULE_unknown) {
21481     std::string Values;
21482     Values += "'";
21483     Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
21484     Values += "'";
21485     Diag(KindLoc, diag::err_omp_unexpected_clause_value)
21486         << Values << getOpenMPClauseName(OMPC_dist_schedule);
21487     return nullptr;
21488   }
21489   Expr *ValExpr = ChunkSize;
21490   Stmt *HelperValStmt = nullptr;
21491   if (ChunkSize) {
21492     if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
21493         !ChunkSize->isInstantiationDependent() &&
21494         !ChunkSize->containsUnexpandedParameterPack()) {
21495       SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
21496       ExprResult Val =
21497           PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
21498       if (Val.isInvalid())
21499         return nullptr;
21500 
21501       ValExpr = Val.get();
21502 
21503       // OpenMP [2.7.1, Restrictions]
21504       //  chunk_size must be a loop invariant integer expression with a positive
21505       //  value.
21506       if (Optional<llvm::APSInt> Result =
21507               ValExpr->getIntegerConstantExpr(Context)) {
21508         if (Result->isSigned() && !Result->isStrictlyPositive()) {
21509           Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
21510               << "dist_schedule" << ChunkSize->getSourceRange();
21511           return nullptr;
21512         }
21513       } else if (getOpenMPCaptureRegionForClause(
21514                      DSAStack->getCurrentDirective(), OMPC_dist_schedule,
21515                      LangOpts.OpenMP) != OMPD_unknown &&
21516                  !CurContext->isDependentContext()) {
21517         ValExpr = MakeFullExpr(ValExpr).get();
21518         llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
21519         ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
21520         HelperValStmt = buildPreInits(Context, Captures);
21521       }
21522     }
21523   }
21524 
21525   return new (Context)
21526       OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
21527                             Kind, ValExpr, HelperValStmt);
21528 }
21529 
21530 OMPClause *Sema::ActOnOpenMPDefaultmapClause(
21531     OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
21532     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
21533     SourceLocation KindLoc, SourceLocation EndLoc) {
21534   if (getLangOpts().OpenMP < 50) {
21535     if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
21536         Kind != OMPC_DEFAULTMAP_scalar) {
21537       std::string Value;
21538       SourceLocation Loc;
21539       Value += "'";
21540       if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
21541         Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
21542                                                OMPC_DEFAULTMAP_MODIFIER_tofrom);
21543         Loc = MLoc;
21544       } else {
21545         Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
21546                                                OMPC_DEFAULTMAP_scalar);
21547         Loc = KindLoc;
21548       }
21549       Value += "'";
21550       Diag(Loc, diag::err_omp_unexpected_clause_value)
21551           << Value << getOpenMPClauseName(OMPC_defaultmap);
21552       return nullptr;
21553     }
21554   } else {
21555     bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown);
21556     bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) ||
21557                             (LangOpts.OpenMP >= 50 && KindLoc.isInvalid());
21558     if (!isDefaultmapKind || !isDefaultmapModifier) {
21559       StringRef KindValue = "'scalar', 'aggregate', 'pointer'";
21560       if (LangOpts.OpenMP == 50) {
21561         StringRef ModifierValue = "'alloc', 'from', 'to', 'tofrom', "
21562                                   "'firstprivate', 'none', 'default'";
21563         if (!isDefaultmapKind && isDefaultmapModifier) {
21564           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
21565               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
21566         } else if (isDefaultmapKind && !isDefaultmapModifier) {
21567           Diag(MLoc, diag::err_omp_unexpected_clause_value)
21568               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
21569         } else {
21570           Diag(MLoc, diag::err_omp_unexpected_clause_value)
21571               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
21572           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
21573               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
21574         }
21575       } else {
21576         StringRef ModifierValue =
21577             "'alloc', 'from', 'to', 'tofrom', "
21578             "'firstprivate', 'none', 'default', 'present'";
21579         if (!isDefaultmapKind && isDefaultmapModifier) {
21580           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
21581               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
21582         } else if (isDefaultmapKind && !isDefaultmapModifier) {
21583           Diag(MLoc, diag::err_omp_unexpected_clause_value)
21584               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
21585         } else {
21586           Diag(MLoc, diag::err_omp_unexpected_clause_value)
21587               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
21588           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
21589               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
21590         }
21591       }
21592       return nullptr;
21593     }
21594 
21595     // OpenMP [5.0, 2.12.5, Restrictions, p. 174]
21596     //  At most one defaultmap clause for each category can appear on the
21597     //  directive.
21598     if (DSAStack->checkDefaultmapCategory(Kind)) {
21599       Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
21600       return nullptr;
21601     }
21602   }
21603   if (Kind == OMPC_DEFAULTMAP_unknown) {
21604     // Variable category is not specified - mark all categories.
21605     DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc);
21606     DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc);
21607     DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc);
21608   } else {
21609     DSAStack->setDefaultDMAAttr(M, Kind, StartLoc);
21610   }
21611 
21612   return new (Context)
21613       OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
21614 }
21615 
21616 bool Sema::ActOnStartOpenMPDeclareTargetContext(
21617     DeclareTargetContextInfo &DTCI) {
21618   DeclContext *CurLexicalContext = getCurLexicalContext();
21619   if (!CurLexicalContext->isFileContext() &&
21620       !CurLexicalContext->isExternCContext() &&
21621       !CurLexicalContext->isExternCXXContext() &&
21622       !isa<CXXRecordDecl>(CurLexicalContext) &&
21623       !isa<ClassTemplateDecl>(CurLexicalContext) &&
21624       !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
21625       !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
21626     Diag(DTCI.Loc, diag::err_omp_region_not_file_context);
21627     return false;
21628   }
21629   DeclareTargetNesting.push_back(DTCI);
21630   return true;
21631 }
21632 
21633 const Sema::DeclareTargetContextInfo
21634 Sema::ActOnOpenMPEndDeclareTargetDirective() {
21635   assert(!DeclareTargetNesting.empty() &&
21636          "check isInOpenMPDeclareTargetContext() first!");
21637   return DeclareTargetNesting.pop_back_val();
21638 }
21639 
21640 void Sema::ActOnFinishedOpenMPDeclareTargetContext(
21641     DeclareTargetContextInfo &DTCI) {
21642   for (auto &It : DTCI.ExplicitlyMapped)
21643     ActOnOpenMPDeclareTargetName(It.first, It.second.Loc, It.second.MT, DTCI);
21644 }
21645 
21646 NamedDecl *Sema::lookupOpenMPDeclareTargetName(Scope *CurScope,
21647                                                CXXScopeSpec &ScopeSpec,
21648                                                const DeclarationNameInfo &Id) {
21649   LookupResult Lookup(*this, Id, LookupOrdinaryName);
21650   LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
21651 
21652   if (Lookup.isAmbiguous())
21653     return nullptr;
21654   Lookup.suppressDiagnostics();
21655 
21656   if (!Lookup.isSingleResult()) {
21657     VarOrFuncDeclFilterCCC CCC(*this);
21658     if (TypoCorrection Corrected =
21659             CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
21660                         CTK_ErrorRecovery)) {
21661       diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
21662                                   << Id.getName());
21663       checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
21664       return nullptr;
21665     }
21666 
21667     Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
21668     return nullptr;
21669   }
21670 
21671   NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
21672   if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
21673       !isa<FunctionTemplateDecl>(ND)) {
21674     Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
21675     return nullptr;
21676   }
21677   return ND;
21678 }
21679 
21680 void Sema::ActOnOpenMPDeclareTargetName(NamedDecl *ND, SourceLocation Loc,
21681                                         OMPDeclareTargetDeclAttr::MapTypeTy MT,
21682                                         DeclareTargetContextInfo &DTCI) {
21683   assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
21684           isa<FunctionTemplateDecl>(ND)) &&
21685          "Expected variable, function or function template.");
21686 
21687   // Diagnose marking after use as it may lead to incorrect diagnosis and
21688   // codegen.
21689   if (LangOpts.OpenMP >= 50 &&
21690       (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced()))
21691     Diag(Loc, diag::warn_omp_declare_target_after_first_use);
21692 
21693   // Explicit declare target lists have precedence.
21694   const unsigned Level = -1;
21695 
21696   auto *VD = cast<ValueDecl>(ND);
21697   llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
21698       OMPDeclareTargetDeclAttr::getActiveAttr(VD);
21699   if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getDevType() != DTCI.DT &&
21700       ActiveAttr.getValue()->getLevel() == Level) {
21701     Diag(Loc, diag::err_omp_device_type_mismatch)
21702         << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DTCI.DT)
21703         << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(
21704                ActiveAttr.getValue()->getDevType());
21705     return;
21706   }
21707   if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getMapType() != MT &&
21708       ActiveAttr.getValue()->getLevel() == Level) {
21709     Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
21710     return;
21711   }
21712 
21713   if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getLevel() == Level)
21714     return;
21715 
21716   Expr *IndirectE = nullptr;
21717   bool IsIndirect = false;
21718   if (DTCI.Indirect.hasValue()) {
21719     IndirectE = DTCI.Indirect.getValue();
21720     if (!IndirectE)
21721       IsIndirect = true;
21722   }
21723   auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
21724       Context, MT, DTCI.DT, IndirectE, IsIndirect, Level,
21725       SourceRange(Loc, Loc));
21726   ND->addAttr(A);
21727   if (ASTMutationListener *ML = Context.getASTMutationListener())
21728     ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
21729   checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc);
21730 }
21731 
21732 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
21733                                      Sema &SemaRef, Decl *D) {
21734   if (!D || !isa<VarDecl>(D))
21735     return;
21736   auto *VD = cast<VarDecl>(D);
21737   Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
21738       OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
21739   if (SemaRef.LangOpts.OpenMP >= 50 &&
21740       (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) ||
21741        SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) &&
21742       VD->hasGlobalStorage()) {
21743     if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) {
21744       // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
21745       // If a lambda declaration and definition appears between a
21746       // declare target directive and the matching end declare target
21747       // directive, all variables that are captured by the lambda
21748       // expression must also appear in a to clause.
21749       SemaRef.Diag(VD->getLocation(),
21750                    diag::err_omp_lambda_capture_in_declare_target_not_to);
21751       SemaRef.Diag(SL, diag::note_var_explicitly_captured_here)
21752           << VD << 0 << SR;
21753       return;
21754     }
21755   }
21756   if (MapTy.hasValue())
21757     return;
21758   SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
21759   SemaRef.Diag(SL, diag::note_used_here) << SR;
21760 }
21761 
21762 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
21763                                    Sema &SemaRef, DSAStackTy *Stack,
21764                                    ValueDecl *VD) {
21765   return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
21766          checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
21767                            /*FullCheck=*/false);
21768 }
21769 
21770 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
21771                                             SourceLocation IdLoc) {
21772   if (!D || D->isInvalidDecl())
21773     return;
21774   SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
21775   SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
21776   if (auto *VD = dyn_cast<VarDecl>(D)) {
21777     // Only global variables can be marked as declare target.
21778     if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
21779         !VD->isStaticDataMember())
21780       return;
21781     // 2.10.6: threadprivate variable cannot appear in a declare target
21782     // directive.
21783     if (DSAStack->isThreadPrivate(VD)) {
21784       Diag(SL, diag::err_omp_threadprivate_in_target);
21785       reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false));
21786       return;
21787     }
21788   }
21789   if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
21790     D = FTD->getTemplatedDecl();
21791   if (auto *FD = dyn_cast<FunctionDecl>(D)) {
21792     llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
21793         OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
21794     if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
21795       Diag(IdLoc, diag::err_omp_function_in_link_clause);
21796       Diag(FD->getLocation(), diag::note_defined_here) << FD;
21797       return;
21798     }
21799   }
21800   if (auto *VD = dyn_cast<ValueDecl>(D)) {
21801     // Problem if any with var declared with incomplete type will be reported
21802     // as normal, so no need to check it here.
21803     if ((E || !VD->getType()->isIncompleteType()) &&
21804         !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD))
21805       return;
21806     if (!E && isInOpenMPDeclareTargetContext()) {
21807       // Checking declaration inside declare target region.
21808       if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
21809           isa<FunctionTemplateDecl>(D)) {
21810         llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
21811             OMPDeclareTargetDeclAttr::getActiveAttr(VD);
21812         unsigned Level = DeclareTargetNesting.size();
21813         if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getLevel() >= Level)
21814           return;
21815         DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back();
21816         Expr *IndirectE = nullptr;
21817         bool IsIndirect = false;
21818         if (DTCI.Indirect.hasValue()) {
21819           IndirectE = DTCI.Indirect.getValue();
21820           if (!IndirectE)
21821             IsIndirect = true;
21822         }
21823         auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
21824             Context, OMPDeclareTargetDeclAttr::MT_To, DTCI.DT, IndirectE,
21825             IsIndirect, Level, SourceRange(DTCI.Loc, DTCI.Loc));
21826         D->addAttr(A);
21827         if (ASTMutationListener *ML = Context.getASTMutationListener())
21828           ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
21829       }
21830       return;
21831     }
21832   }
21833   if (!E)
21834     return;
21835   checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
21836 }
21837 
21838 OMPClause *Sema::ActOnOpenMPToClause(
21839     ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
21840     ArrayRef<SourceLocation> MotionModifiersLoc,
21841     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
21842     SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
21843     const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
21844   OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
21845                                           OMPC_MOTION_MODIFIER_unknown};
21846   SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
21847 
21848   // Process motion-modifiers, flag errors for duplicate modifiers.
21849   unsigned Count = 0;
21850   for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
21851     if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
21852         llvm::is_contained(Modifiers, MotionModifiers[I])) {
21853       Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
21854       continue;
21855     }
21856     assert(Count < NumberOfOMPMotionModifiers &&
21857            "Modifiers exceed the allowed number of motion modifiers");
21858     Modifiers[Count] = MotionModifiers[I];
21859     ModifiersLoc[Count] = MotionModifiersLoc[I];
21860     ++Count;
21861   }
21862 
21863   MappableVarListInfo MVLI(VarList);
21864   checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc,
21865                               MapperIdScopeSpec, MapperId, UnresolvedMappers);
21866   if (MVLI.ProcessedVarList.empty())
21867     return nullptr;
21868 
21869   return OMPToClause::Create(
21870       Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
21871       MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
21872       MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
21873 }
21874 
21875 OMPClause *Sema::ActOnOpenMPFromClause(
21876     ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
21877     ArrayRef<SourceLocation> MotionModifiersLoc,
21878     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
21879     SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
21880     const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
21881   OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
21882                                           OMPC_MOTION_MODIFIER_unknown};
21883   SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
21884 
21885   // Process motion-modifiers, flag errors for duplicate modifiers.
21886   unsigned Count = 0;
21887   for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
21888     if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
21889         llvm::is_contained(Modifiers, MotionModifiers[I])) {
21890       Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
21891       continue;
21892     }
21893     assert(Count < NumberOfOMPMotionModifiers &&
21894            "Modifiers exceed the allowed number of motion modifiers");
21895     Modifiers[Count] = MotionModifiers[I];
21896     ModifiersLoc[Count] = MotionModifiersLoc[I];
21897     ++Count;
21898   }
21899 
21900   MappableVarListInfo MVLI(VarList);
21901   checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc,
21902                               MapperIdScopeSpec, MapperId, UnresolvedMappers);
21903   if (MVLI.ProcessedVarList.empty())
21904     return nullptr;
21905 
21906   return OMPFromClause::Create(
21907       Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
21908       MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
21909       MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
21910 }
21911 
21912 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
21913                                                const OMPVarListLocTy &Locs) {
21914   MappableVarListInfo MVLI(VarList);
21915   SmallVector<Expr *, 8> PrivateCopies;
21916   SmallVector<Expr *, 8> Inits;
21917 
21918   for (Expr *RefExpr : VarList) {
21919     assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
21920     SourceLocation ELoc;
21921     SourceRange ERange;
21922     Expr *SimpleRefExpr = RefExpr;
21923     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
21924     if (Res.second) {
21925       // It will be analyzed later.
21926       MVLI.ProcessedVarList.push_back(RefExpr);
21927       PrivateCopies.push_back(nullptr);
21928       Inits.push_back(nullptr);
21929     }
21930     ValueDecl *D = Res.first;
21931     if (!D)
21932       continue;
21933 
21934     QualType Type = D->getType();
21935     Type = Type.getNonReferenceType().getUnqualifiedType();
21936 
21937     auto *VD = dyn_cast<VarDecl>(D);
21938 
21939     // Item should be a pointer or reference to pointer.
21940     if (!Type->isPointerType()) {
21941       Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
21942           << 0 << RefExpr->getSourceRange();
21943       continue;
21944     }
21945 
21946     // Build the private variable and the expression that refers to it.
21947     auto VDPrivate =
21948         buildVarDecl(*this, ELoc, Type, D->getName(),
21949                      D->hasAttrs() ? &D->getAttrs() : nullptr,
21950                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
21951     if (VDPrivate->isInvalidDecl())
21952       continue;
21953 
21954     CurContext->addDecl(VDPrivate);
21955     DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
21956         *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
21957 
21958     // Add temporary variable to initialize the private copy of the pointer.
21959     VarDecl *VDInit =
21960         buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
21961     DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
21962         *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
21963     AddInitializerToDecl(VDPrivate,
21964                          DefaultLvalueConversion(VDInitRefExpr).get(),
21965                          /*DirectInit=*/false);
21966 
21967     // If required, build a capture to implement the privatization initialized
21968     // with the current list item value.
21969     DeclRefExpr *Ref = nullptr;
21970     if (!VD)
21971       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
21972     MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
21973     PrivateCopies.push_back(VDPrivateRefExpr);
21974     Inits.push_back(VDInitRefExpr);
21975 
21976     // We need to add a data sharing attribute for this variable to make sure it
21977     // is correctly captured. A variable that shows up in a use_device_ptr has
21978     // similar properties of a first private variable.
21979     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
21980 
21981     // Create a mappable component for the list item. List items in this clause
21982     // only need a component.
21983     MVLI.VarBaseDeclarations.push_back(D);
21984     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
21985     MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D,
21986                                            /*IsNonContiguous=*/false);
21987   }
21988 
21989   if (MVLI.ProcessedVarList.empty())
21990     return nullptr;
21991 
21992   return OMPUseDevicePtrClause::Create(
21993       Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
21994       MVLI.VarBaseDeclarations, MVLI.VarComponents);
21995 }
21996 
21997 OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
21998                                                 const OMPVarListLocTy &Locs) {
21999   MappableVarListInfo MVLI(VarList);
22000 
22001   for (Expr *RefExpr : VarList) {
22002     assert(RefExpr && "NULL expr in OpenMP use_device_addr clause.");
22003     SourceLocation ELoc;
22004     SourceRange ERange;
22005     Expr *SimpleRefExpr = RefExpr;
22006     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
22007                               /*AllowArraySection=*/true);
22008     if (Res.second) {
22009       // It will be analyzed later.
22010       MVLI.ProcessedVarList.push_back(RefExpr);
22011     }
22012     ValueDecl *D = Res.first;
22013     if (!D)
22014       continue;
22015     auto *VD = dyn_cast<VarDecl>(D);
22016 
22017     // If required, build a capture to implement the privatization initialized
22018     // with the current list item value.
22019     DeclRefExpr *Ref = nullptr;
22020     if (!VD)
22021       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
22022     MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
22023 
22024     // We need to add a data sharing attribute for this variable to make sure it
22025     // is correctly captured. A variable that shows up in a use_device_addr has
22026     // similar properties of a first private variable.
22027     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
22028 
22029     // Create a mappable component for the list item. List items in this clause
22030     // only need a component.
22031     MVLI.VarBaseDeclarations.push_back(D);
22032     MVLI.VarComponents.emplace_back();
22033     Expr *Component = SimpleRefExpr;
22034     if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
22035                isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
22036       Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
22037     MVLI.VarComponents.back().emplace_back(Component, D,
22038                                            /*IsNonContiguous=*/false);
22039   }
22040 
22041   if (MVLI.ProcessedVarList.empty())
22042     return nullptr;
22043 
22044   return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
22045                                         MVLI.VarBaseDeclarations,
22046                                         MVLI.VarComponents);
22047 }
22048 
22049 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
22050                                               const OMPVarListLocTy &Locs) {
22051   MappableVarListInfo MVLI(VarList);
22052   for (Expr *RefExpr : VarList) {
22053     assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
22054     SourceLocation ELoc;
22055     SourceRange ERange;
22056     Expr *SimpleRefExpr = RefExpr;
22057     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
22058     if (Res.second) {
22059       // It will be analyzed later.
22060       MVLI.ProcessedVarList.push_back(RefExpr);
22061     }
22062     ValueDecl *D = Res.first;
22063     if (!D)
22064       continue;
22065 
22066     QualType Type = D->getType();
22067     // item should be a pointer or array or reference to pointer or array
22068     if (!Type.getNonReferenceType()->isPointerType() &&
22069         !Type.getNonReferenceType()->isArrayType()) {
22070       Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
22071           << 0 << RefExpr->getSourceRange();
22072       continue;
22073     }
22074 
22075     // Check if the declaration in the clause does not show up in any data
22076     // sharing attribute.
22077     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
22078     if (isOpenMPPrivate(DVar.CKind)) {
22079       Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
22080           << getOpenMPClauseName(DVar.CKind)
22081           << getOpenMPClauseName(OMPC_is_device_ptr)
22082           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
22083       reportOriginalDsa(*this, DSAStack, D, DVar);
22084       continue;
22085     }
22086 
22087     const Expr *ConflictExpr;
22088     if (DSAStack->checkMappableExprComponentListsForDecl(
22089             D, /*CurrentRegionOnly=*/true,
22090             [&ConflictExpr](
22091                 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
22092                 OpenMPClauseKind) -> bool {
22093               ConflictExpr = R.front().getAssociatedExpression();
22094               return true;
22095             })) {
22096       Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
22097       Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
22098           << ConflictExpr->getSourceRange();
22099       continue;
22100     }
22101 
22102     // Store the components in the stack so that they can be used to check
22103     // against other clauses later on.
22104     OMPClauseMappableExprCommon::MappableComponent MC(
22105         SimpleRefExpr, D, /*IsNonContiguous=*/false);
22106     DSAStack->addMappableExpressionComponents(
22107         D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
22108 
22109     // Record the expression we've just processed.
22110     MVLI.ProcessedVarList.push_back(SimpleRefExpr);
22111 
22112     // Create a mappable component for the list item. List items in this clause
22113     // only need a component. We use a null declaration to signal fields in
22114     // 'this'.
22115     assert((isa<DeclRefExpr>(SimpleRefExpr) ||
22116             isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
22117            "Unexpected device pointer expression!");
22118     MVLI.VarBaseDeclarations.push_back(
22119         isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
22120     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
22121     MVLI.VarComponents.back().push_back(MC);
22122   }
22123 
22124   if (MVLI.ProcessedVarList.empty())
22125     return nullptr;
22126 
22127   return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
22128                                       MVLI.VarBaseDeclarations,
22129                                       MVLI.VarComponents);
22130 }
22131 
22132 OMPClause *Sema::ActOnOpenMPAllocateClause(
22133     Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
22134     SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
22135   if (Allocator) {
22136     // OpenMP [2.11.4 allocate Clause, Description]
22137     // allocator is an expression of omp_allocator_handle_t type.
22138     if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack))
22139       return nullptr;
22140 
22141     ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
22142     if (AllocatorRes.isInvalid())
22143       return nullptr;
22144     AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
22145                                              DSAStack->getOMPAllocatorHandleT(),
22146                                              Sema::AA_Initializing,
22147                                              /*AllowExplicit=*/true);
22148     if (AllocatorRes.isInvalid())
22149       return nullptr;
22150     Allocator = AllocatorRes.get();
22151   } else {
22152     // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
22153     // allocate clauses that appear on a target construct or on constructs in a
22154     // target region must specify an allocator expression unless a requires
22155     // directive with the dynamic_allocators clause is present in the same
22156     // compilation unit.
22157     if (LangOpts.OpenMPIsDevice &&
22158         !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
22159       targetDiag(StartLoc, diag::err_expected_allocator_expression);
22160   }
22161   // Analyze and build list of variables.
22162   SmallVector<Expr *, 8> Vars;
22163   for (Expr *RefExpr : VarList) {
22164     assert(RefExpr && "NULL expr in OpenMP private clause.");
22165     SourceLocation ELoc;
22166     SourceRange ERange;
22167     Expr *SimpleRefExpr = RefExpr;
22168     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
22169     if (Res.second) {
22170       // It will be analyzed later.
22171       Vars.push_back(RefExpr);
22172     }
22173     ValueDecl *D = Res.first;
22174     if (!D)
22175       continue;
22176 
22177     auto *VD = dyn_cast<VarDecl>(D);
22178     DeclRefExpr *Ref = nullptr;
22179     if (!VD && !CurContext->isDependentContext())
22180       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
22181     Vars.push_back((VD || CurContext->isDependentContext())
22182                        ? RefExpr->IgnoreParens()
22183                        : Ref);
22184   }
22185 
22186   if (Vars.empty())
22187     return nullptr;
22188 
22189   if (Allocator)
22190     DSAStack->addInnerAllocatorExpr(Allocator);
22191   return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
22192                                    ColonLoc, EndLoc, Vars);
22193 }
22194 
22195 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
22196                                               SourceLocation StartLoc,
22197                                               SourceLocation LParenLoc,
22198                                               SourceLocation EndLoc) {
22199   SmallVector<Expr *, 8> Vars;
22200   for (Expr *RefExpr : VarList) {
22201     assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
22202     SourceLocation ELoc;
22203     SourceRange ERange;
22204     Expr *SimpleRefExpr = RefExpr;
22205     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
22206     if (Res.second)
22207       // It will be analyzed later.
22208       Vars.push_back(RefExpr);
22209     ValueDecl *D = Res.first;
22210     if (!D)
22211       continue;
22212 
22213     // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions.
22214     // A list-item cannot appear in more than one nontemporal clause.
22215     if (const Expr *PrevRef =
22216             DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) {
22217       Diag(ELoc, diag::err_omp_used_in_clause_twice)
22218           << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
22219       Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
22220           << getOpenMPClauseName(OMPC_nontemporal);
22221       continue;
22222     }
22223 
22224     Vars.push_back(RefExpr);
22225   }
22226 
22227   if (Vars.empty())
22228     return nullptr;
22229 
22230   return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc,
22231                                       Vars);
22232 }
22233 
22234 OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList,
22235                                             SourceLocation StartLoc,
22236                                             SourceLocation LParenLoc,
22237                                             SourceLocation EndLoc) {
22238   SmallVector<Expr *, 8> Vars;
22239   for (Expr *RefExpr : VarList) {
22240     assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
22241     SourceLocation ELoc;
22242     SourceRange ERange;
22243     Expr *SimpleRefExpr = RefExpr;
22244     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
22245                               /*AllowArraySection=*/true);
22246     if (Res.second)
22247       // It will be analyzed later.
22248       Vars.push_back(RefExpr);
22249     ValueDecl *D = Res.first;
22250     if (!D)
22251       continue;
22252 
22253     const DSAStackTy::DSAVarData DVar =
22254         DSAStack->getTopDSA(D, /*FromParent=*/true);
22255     // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
22256     // A list item that appears in the inclusive or exclusive clause must appear
22257     // in a reduction clause with the inscan modifier on the enclosing
22258     // worksharing-loop, worksharing-loop SIMD, or simd construct.
22259     if (DVar.CKind != OMPC_reduction || DVar.Modifier != OMPC_REDUCTION_inscan)
22260       Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
22261           << RefExpr->getSourceRange();
22262 
22263     if (DSAStack->getParentDirective() != OMPD_unknown)
22264       DSAStack->markDeclAsUsedInScanDirective(D);
22265     Vars.push_back(RefExpr);
22266   }
22267 
22268   if (Vars.empty())
22269     return nullptr;
22270 
22271   return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
22272 }
22273 
22274 OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList,
22275                                             SourceLocation StartLoc,
22276                                             SourceLocation LParenLoc,
22277                                             SourceLocation EndLoc) {
22278   SmallVector<Expr *, 8> Vars;
22279   for (Expr *RefExpr : VarList) {
22280     assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
22281     SourceLocation ELoc;
22282     SourceRange ERange;
22283     Expr *SimpleRefExpr = RefExpr;
22284     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
22285                               /*AllowArraySection=*/true);
22286     if (Res.second)
22287       // It will be analyzed later.
22288       Vars.push_back(RefExpr);
22289     ValueDecl *D = Res.first;
22290     if (!D)
22291       continue;
22292 
22293     OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective();
22294     DSAStackTy::DSAVarData DVar;
22295     if (ParentDirective != OMPD_unknown)
22296       DVar = DSAStack->getTopDSA(D, /*FromParent=*/true);
22297     // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
22298     // A list item that appears in the inclusive or exclusive clause must appear
22299     // in a reduction clause with the inscan modifier on the enclosing
22300     // worksharing-loop, worksharing-loop SIMD, or simd construct.
22301     if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction ||
22302         DVar.Modifier != OMPC_REDUCTION_inscan) {
22303       Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
22304           << RefExpr->getSourceRange();
22305     } else {
22306       DSAStack->markDeclAsUsedInScanDirective(D);
22307     }
22308     Vars.push_back(RefExpr);
22309   }
22310 
22311   if (Vars.empty())
22312     return nullptr;
22313 
22314   return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
22315 }
22316 
22317 /// Tries to find omp_alloctrait_t type.
22318 static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) {
22319   QualType OMPAlloctraitT = Stack->getOMPAlloctraitT();
22320   if (!OMPAlloctraitT.isNull())
22321     return true;
22322   IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t");
22323   ParsedType PT = S.getTypeName(II, Loc, S.getCurScope());
22324   if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
22325     S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t";
22326     return false;
22327   }
22328   Stack->setOMPAlloctraitT(PT.get());
22329   return true;
22330 }
22331 
22332 OMPClause *Sema::ActOnOpenMPUsesAllocatorClause(
22333     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
22334     ArrayRef<UsesAllocatorsData> Data) {
22335   // OpenMP [2.12.5, target Construct]
22336   // allocator is an identifier of omp_allocator_handle_t type.
22337   if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack))
22338     return nullptr;
22339   // OpenMP [2.12.5, target Construct]
22340   // allocator-traits-array is an identifier of const omp_alloctrait_t * type.
22341   if (llvm::any_of(
22342           Data,
22343           [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) &&
22344       !findOMPAlloctraitT(*this, StartLoc, DSAStack))
22345     return nullptr;
22346   llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators;
22347   for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
22348     auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
22349     StringRef Allocator =
22350         OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
22351     DeclarationName AllocatorName = &Context.Idents.get(Allocator);
22352     PredefinedAllocators.insert(LookupSingleName(
22353         TUScope, AllocatorName, StartLoc, Sema::LookupAnyName));
22354   }
22355 
22356   SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData;
22357   for (const UsesAllocatorsData &D : Data) {
22358     Expr *AllocatorExpr = nullptr;
22359     // Check allocator expression.
22360     if (D.Allocator->isTypeDependent()) {
22361       AllocatorExpr = D.Allocator;
22362     } else {
22363       // Traits were specified - need to assign new allocator to the specified
22364       // allocator, so it must be an lvalue.
22365       AllocatorExpr = D.Allocator->IgnoreParenImpCasts();
22366       auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr);
22367       bool IsPredefinedAllocator = false;
22368       if (DRE)
22369         IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl());
22370       if (!DRE ||
22371           !(Context.hasSameUnqualifiedType(
22372                 AllocatorExpr->getType(), DSAStack->getOMPAllocatorHandleT()) ||
22373             Context.typesAreCompatible(AllocatorExpr->getType(),
22374                                        DSAStack->getOMPAllocatorHandleT(),
22375                                        /*CompareUnqualified=*/true)) ||
22376           (!IsPredefinedAllocator &&
22377            (AllocatorExpr->getType().isConstant(Context) ||
22378             !AllocatorExpr->isLValue()))) {
22379         Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected)
22380             << "omp_allocator_handle_t" << (DRE ? 1 : 0)
22381             << AllocatorExpr->getType() << D.Allocator->getSourceRange();
22382         continue;
22383       }
22384       // OpenMP [2.12.5, target Construct]
22385       // Predefined allocators appearing in a uses_allocators clause cannot have
22386       // traits specified.
22387       if (IsPredefinedAllocator && D.AllocatorTraits) {
22388         Diag(D.AllocatorTraits->getExprLoc(),
22389              diag::err_omp_predefined_allocator_with_traits)
22390             << D.AllocatorTraits->getSourceRange();
22391         Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator)
22392             << cast<NamedDecl>(DRE->getDecl())->getName()
22393             << D.Allocator->getSourceRange();
22394         continue;
22395       }
22396       // OpenMP [2.12.5, target Construct]
22397       // Non-predefined allocators appearing in a uses_allocators clause must
22398       // have traits specified.
22399       if (!IsPredefinedAllocator && !D.AllocatorTraits) {
22400         Diag(D.Allocator->getExprLoc(),
22401              diag::err_omp_nonpredefined_allocator_without_traits);
22402         continue;
22403       }
22404       // No allocator traits - just convert it to rvalue.
22405       if (!D.AllocatorTraits)
22406         AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get();
22407       DSAStack->addUsesAllocatorsDecl(
22408           DRE->getDecl(),
22409           IsPredefinedAllocator
22410               ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator
22411               : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator);
22412     }
22413     Expr *AllocatorTraitsExpr = nullptr;
22414     if (D.AllocatorTraits) {
22415       if (D.AllocatorTraits->isTypeDependent()) {
22416         AllocatorTraitsExpr = D.AllocatorTraits;
22417       } else {
22418         // OpenMP [2.12.5, target Construct]
22419         // Arrays that contain allocator traits that appear in a uses_allocators
22420         // clause must be constant arrays, have constant values and be defined
22421         // in the same scope as the construct in which the clause appears.
22422         AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts();
22423         // Check that traits expr is a constant array.
22424         QualType TraitTy;
22425         if (const ArrayType *Ty =
22426                 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe())
22427           if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty))
22428             TraitTy = ConstArrayTy->getElementType();
22429         if (TraitTy.isNull() ||
22430             !(Context.hasSameUnqualifiedType(TraitTy,
22431                                              DSAStack->getOMPAlloctraitT()) ||
22432               Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(),
22433                                          /*CompareUnqualified=*/true))) {
22434           Diag(D.AllocatorTraits->getExprLoc(),
22435                diag::err_omp_expected_array_alloctraits)
22436               << AllocatorTraitsExpr->getType();
22437           continue;
22438         }
22439         // Do not map by default allocator traits if it is a standalone
22440         // variable.
22441         if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr))
22442           DSAStack->addUsesAllocatorsDecl(
22443               DRE->getDecl(),
22444               DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait);
22445       }
22446     }
22447     OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back();
22448     NewD.Allocator = AllocatorExpr;
22449     NewD.AllocatorTraits = AllocatorTraitsExpr;
22450     NewD.LParenLoc = D.LParenLoc;
22451     NewD.RParenLoc = D.RParenLoc;
22452   }
22453   return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc,
22454                                          NewData);
22455 }
22456 
22457 OMPClause *Sema::ActOnOpenMPAffinityClause(
22458     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
22459     SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) {
22460   SmallVector<Expr *, 8> Vars;
22461   for (Expr *RefExpr : Locators) {
22462     assert(RefExpr && "NULL expr in OpenMP shared clause.");
22463     if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) {
22464       // It will be analyzed later.
22465       Vars.push_back(RefExpr);
22466       continue;
22467     }
22468 
22469     SourceLocation ELoc = RefExpr->getExprLoc();
22470     Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts();
22471 
22472     if (!SimpleExpr->isLValue()) {
22473       Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
22474           << 1 << 0 << RefExpr->getSourceRange();
22475       continue;
22476     }
22477 
22478     ExprResult Res;
22479     {
22480       Sema::TentativeAnalysisScope Trap(*this);
22481       Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr);
22482     }
22483     if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
22484         !isa<OMPArrayShapingExpr>(SimpleExpr)) {
22485       Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
22486           << 1 << 0 << RefExpr->getSourceRange();
22487       continue;
22488     }
22489     Vars.push_back(SimpleExpr);
22490   }
22491 
22492   return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
22493                                    EndLoc, Modifier, Vars);
22494 }
22495 
22496 OMPClause *Sema::ActOnOpenMPBindClause(OpenMPBindClauseKind Kind,
22497                                        SourceLocation KindLoc,
22498                                        SourceLocation StartLoc,
22499                                        SourceLocation LParenLoc,
22500                                        SourceLocation EndLoc) {
22501   if (Kind == OMPC_BIND_unknown) {
22502     Diag(KindLoc, diag::err_omp_unexpected_clause_value)
22503         << getListOfPossibleValues(OMPC_bind, /*First=*/0,
22504                                    /*Last=*/unsigned(OMPC_BIND_unknown))
22505         << getOpenMPClauseName(OMPC_bind);
22506     return nullptr;
22507   }
22508 
22509   return OMPBindClause::Create(Context, Kind, KindLoc, StartLoc, LParenLoc,
22510                                EndLoc);
22511 }
22512