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/StringExtras.h"
39 #include "llvm/Frontend/OpenMP/OMPConstants.h"
40 #include <set>
41 
42 using namespace clang;
43 using namespace llvm::omp;
44 
45 //===----------------------------------------------------------------------===//
46 // Stack of data-sharing attributes for variables
47 //===----------------------------------------------------------------------===//
48 
49 static const Expr *checkMapClauseExpressionBase(
50     Sema &SemaRef, Expr *E,
51     OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
52     OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose);
53 
54 namespace {
55 /// Default data sharing attributes, which can be applied to directive.
56 enum DefaultDataSharingAttributes {
57   DSA_unspecified = 0,       /// Data sharing attribute not specified.
58   DSA_none = 1 << 0,         /// Default data sharing attribute 'none'.
59   DSA_shared = 1 << 1,       /// Default data sharing attribute 'shared'.
60   DSA_firstprivate = 1 << 2, /// Default data sharing attribute 'firstprivate'.
61 };
62 
63 /// Stack for tracking declarations used in OpenMP directives and
64 /// clauses and their data-sharing attributes.
65 class DSAStackTy {
66 public:
67   struct DSAVarData {
68     OpenMPDirectiveKind DKind = OMPD_unknown;
69     OpenMPClauseKind CKind = OMPC_unknown;
70     unsigned Modifier = 0;
71     const Expr *RefExpr = nullptr;
72     DeclRefExpr *PrivateCopy = nullptr;
73     SourceLocation ImplicitDSALoc;
74     bool AppliedToPointee = false;
75     DSAVarData() = default;
DSAVarData__anon022d4e250111::DSAStackTy::DSAVarData76     DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind,
77                const Expr *RefExpr, DeclRefExpr *PrivateCopy,
78                SourceLocation ImplicitDSALoc, unsigned Modifier,
79                bool AppliedToPointee)
80         : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr),
81           PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc),
82           AppliedToPointee(AppliedToPointee) {}
83   };
84   using OperatorOffsetTy =
85       llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>;
86   using DoacrossDependMapTy =
87       llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>;
88   /// Kind of the declaration used in the uses_allocators clauses.
89   enum class UsesAllocatorsDeclKind {
90     /// Predefined allocator
91     PredefinedAllocator,
92     /// User-defined allocator
93     UserDefinedAllocator,
94     /// The declaration that represent allocator trait
95     AllocatorTrait,
96   };
97 
98 private:
99   struct DSAInfo {
100     OpenMPClauseKind Attributes = OMPC_unknown;
101     unsigned Modifier = 0;
102     /// Pointer to a reference expression and a flag which shows that the
103     /// variable is marked as lastprivate(true) or not (false).
104     llvm::PointerIntPair<const Expr *, 1, bool> RefExpr;
105     DeclRefExpr *PrivateCopy = nullptr;
106     /// true if the attribute is applied to the pointee, not the variable
107     /// itself.
108     bool AppliedToPointee = false;
109   };
110   using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>;
111   using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>;
112   using LCDeclInfo = std::pair<unsigned, VarDecl *>;
113   using LoopControlVariablesMapTy =
114       llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>;
115   /// Struct that associates a component with the clause kind where they are
116   /// found.
117   struct MappedExprComponentTy {
118     OMPClauseMappableExprCommon::MappableExprComponentLists Components;
119     OpenMPClauseKind Kind = OMPC_unknown;
120   };
121   using MappedExprComponentsTy =
122       llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>;
123   using CriticalsWithHintsTy =
124       llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>;
125   struct ReductionData {
126     using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>;
127     SourceRange ReductionRange;
128     llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp;
129     ReductionData() = default;
set__anon022d4e250111::DSAStackTy::ReductionData130     void set(BinaryOperatorKind BO, SourceRange RR) {
131       ReductionRange = RR;
132       ReductionOp = BO;
133     }
set__anon022d4e250111::DSAStackTy::ReductionData134     void set(const Expr *RefExpr, SourceRange RR) {
135       ReductionRange = RR;
136       ReductionOp = RefExpr;
137     }
138   };
139   using DeclReductionMapTy =
140       llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>;
141   struct DefaultmapInfo {
142     OpenMPDefaultmapClauseModifier ImplicitBehavior =
143         OMPC_DEFAULTMAP_MODIFIER_unknown;
144     SourceLocation SLoc;
145     DefaultmapInfo() = default;
DefaultmapInfo__anon022d4e250111::DSAStackTy::DefaultmapInfo146     DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc)
147         : ImplicitBehavior(M), SLoc(Loc) {}
148   };
149 
150   struct SharingMapTy {
151     DeclSAMapTy SharingMap;
152     DeclReductionMapTy ReductionMap;
153     UsedRefMapTy AlignedMap;
154     UsedRefMapTy NontemporalMap;
155     MappedExprComponentsTy MappedExprComponents;
156     LoopControlVariablesMapTy LCVMap;
157     DefaultDataSharingAttributes DefaultAttr = DSA_unspecified;
158     SourceLocation DefaultAttrLoc;
159     DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown];
160     OpenMPDirectiveKind Directive = OMPD_unknown;
161     DeclarationNameInfo DirectiveName;
162     Scope *CurScope = nullptr;
163     DeclContext *Context = nullptr;
164     SourceLocation ConstructLoc;
165     /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to
166     /// get the data (loop counters etc.) about enclosing loop-based construct.
167     /// This data is required during codegen.
168     DoacrossDependMapTy DoacrossDepends;
169     /// First argument (Expr *) contains optional argument of the
170     /// 'ordered' clause, the second one is true if the regions has 'ordered'
171     /// clause, false otherwise.
172     llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion;
173     unsigned AssociatedLoops = 1;
174     bool HasMutipleLoops = false;
175     const Decl *PossiblyLoopCounter = nullptr;
176     bool NowaitRegion = false;
177     bool CancelRegion = false;
178     bool LoopStart = false;
179     bool BodyComplete = false;
180     SourceLocation PrevScanLocation;
181     SourceLocation PrevOrderedLocation;
182     SourceLocation InnerTeamsRegionLoc;
183     /// Reference to the taskgroup task_reduction reference expression.
184     Expr *TaskgroupReductionRef = nullptr;
185     llvm::DenseSet<QualType> MappedClassesQualTypes;
186     SmallVector<Expr *, 4> InnerUsedAllocators;
187     llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates;
188     /// List of globals marked as declare target link in this target region
189     /// (isOpenMPTargetExecutionDirective(Directive) == true).
190     llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls;
191     /// List of decls used in inclusive/exclusive clauses of the scan directive.
192     llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective;
193     llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind>
194         UsesAllocatorsDecls;
195     Expr *DeclareMapperVar = nullptr;
SharingMapTy__anon022d4e250111::DSAStackTy::SharingMapTy196     SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name,
197                  Scope *CurScope, SourceLocation Loc)
198         : Directive(DKind), DirectiveName(Name), CurScope(CurScope),
199           ConstructLoc(Loc) {}
200     SharingMapTy() = default;
201   };
202 
203   using StackTy = SmallVector<SharingMapTy, 4>;
204 
205   /// Stack of used declaration and their data-sharing attributes.
206   DeclSAMapTy Threadprivates;
207   const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr;
208   SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack;
209   /// true, if check for DSA must be from parent directive, false, if
210   /// from current directive.
211   OpenMPClauseKind ClauseKindMode = OMPC_unknown;
212   Sema &SemaRef;
213   bool ForceCapturing = false;
214   /// true if all the variables in the target executable directives must be
215   /// captured by reference.
216   bool ForceCaptureByReferenceInTargetExecutable = false;
217   CriticalsWithHintsTy Criticals;
218   unsigned IgnoredStackElements = 0;
219 
220   /// Iterators over the stack iterate in order from innermost to outermost
221   /// directive.
222   using const_iterator = StackTy::const_reverse_iterator;
begin() const223   const_iterator begin() const {
224     return Stack.empty() ? const_iterator()
225                          : Stack.back().first.rbegin() + IgnoredStackElements;
226   }
end() const227   const_iterator end() const {
228     return Stack.empty() ? const_iterator() : Stack.back().first.rend();
229   }
230   using iterator = StackTy::reverse_iterator;
begin()231   iterator begin() {
232     return Stack.empty() ? iterator()
233                          : Stack.back().first.rbegin() + IgnoredStackElements;
234   }
end()235   iterator end() {
236     return Stack.empty() ? iterator() : Stack.back().first.rend();
237   }
238 
239   // Convenience operations to get at the elements of the stack.
240 
isStackEmpty() const241   bool isStackEmpty() const {
242     return Stack.empty() ||
243            Stack.back().second != CurrentNonCapturingFunctionScope ||
244            Stack.back().first.size() <= IgnoredStackElements;
245   }
getStackSize() const246   size_t getStackSize() const {
247     return isStackEmpty() ? 0
248                           : Stack.back().first.size() - IgnoredStackElements;
249   }
250 
getTopOfStackOrNull()251   SharingMapTy *getTopOfStackOrNull() {
252     size_t Size = getStackSize();
253     if (Size == 0)
254       return nullptr;
255     return &Stack.back().first[Size - 1];
256   }
getTopOfStackOrNull() const257   const SharingMapTy *getTopOfStackOrNull() const {
258     return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull();
259   }
getTopOfStack()260   SharingMapTy &getTopOfStack() {
261     assert(!isStackEmpty() && "no current directive");
262     return *getTopOfStackOrNull();
263   }
getTopOfStack() const264   const SharingMapTy &getTopOfStack() const {
265     return const_cast<DSAStackTy&>(*this).getTopOfStack();
266   }
267 
getSecondOnStackOrNull()268   SharingMapTy *getSecondOnStackOrNull() {
269     size_t Size = getStackSize();
270     if (Size <= 1)
271       return nullptr;
272     return &Stack.back().first[Size - 2];
273   }
getSecondOnStackOrNull() const274   const SharingMapTy *getSecondOnStackOrNull() const {
275     return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull();
276   }
277 
278   /// Get the stack element at a certain level (previously returned by
279   /// \c getNestingLevel).
280   ///
281   /// Note that nesting levels count from outermost to innermost, and this is
282   /// the reverse of our iteration order where new inner levels are pushed at
283   /// the front of the stack.
getStackElemAtLevel(unsigned Level)284   SharingMapTy &getStackElemAtLevel(unsigned Level) {
285     assert(Level < getStackSize() && "no such stack element");
286     return Stack.back().first[Level];
287   }
getStackElemAtLevel(unsigned Level) const288   const SharingMapTy &getStackElemAtLevel(unsigned Level) const {
289     return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level);
290   }
291 
292   DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const;
293 
294   /// Checks if the variable is a local for OpenMP region.
295   bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const;
296 
297   /// Vector of previously declared requires directives
298   SmallVector<const OMPRequiresDecl *, 2> RequiresDecls;
299   /// omp_allocator_handle_t type.
300   QualType OMPAllocatorHandleT;
301   /// omp_depend_t type.
302   QualType OMPDependT;
303   /// omp_event_handle_t type.
304   QualType OMPEventHandleT;
305   /// omp_alloctrait_t type.
306   QualType OMPAlloctraitT;
307   /// Expression for the predefined allocators.
308   Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = {
309       nullptr};
310   /// Vector of previously encountered target directives
311   SmallVector<SourceLocation, 2> TargetLocations;
312   SourceLocation AtomicLocation;
313 
314 public:
DSAStackTy(Sema & S)315   explicit DSAStackTy(Sema &S) : SemaRef(S) {}
316 
317   /// Sets omp_allocator_handle_t type.
setOMPAllocatorHandleT(QualType Ty)318   void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; }
319   /// Gets omp_allocator_handle_t type.
getOMPAllocatorHandleT() const320   QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; }
321   /// Sets omp_alloctrait_t type.
setOMPAlloctraitT(QualType Ty)322   void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; }
323   /// Gets omp_alloctrait_t type.
getOMPAlloctraitT() const324   QualType getOMPAlloctraitT() const { return OMPAlloctraitT; }
325   /// Sets the given default allocator.
setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,Expr * Allocator)326   void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
327                     Expr *Allocator) {
328     OMPPredefinedAllocators[AllocatorKind] = Allocator;
329   }
330   /// Returns the specified default allocator.
getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const331   Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const {
332     return OMPPredefinedAllocators[AllocatorKind];
333   }
334   /// Sets omp_depend_t type.
setOMPDependT(QualType Ty)335   void setOMPDependT(QualType Ty) { OMPDependT = Ty; }
336   /// Gets omp_depend_t type.
getOMPDependT() const337   QualType getOMPDependT() const { return OMPDependT; }
338 
339   /// Sets omp_event_handle_t type.
setOMPEventHandleT(QualType Ty)340   void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; }
341   /// Gets omp_event_handle_t type.
getOMPEventHandleT() const342   QualType getOMPEventHandleT() const { return OMPEventHandleT; }
343 
isClauseParsingMode() const344   bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; }
getClauseParsingMode() const345   OpenMPClauseKind getClauseParsingMode() const {
346     assert(isClauseParsingMode() && "Must be in clause parsing mode.");
347     return ClauseKindMode;
348   }
setClauseParsingMode(OpenMPClauseKind K)349   void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; }
350 
isBodyComplete() const351   bool isBodyComplete() const {
352     const SharingMapTy *Top = getTopOfStackOrNull();
353     return Top && Top->BodyComplete;
354   }
setBodyComplete()355   void setBodyComplete() {
356     getTopOfStack().BodyComplete = true;
357   }
358 
isForceVarCapturing() const359   bool isForceVarCapturing() const { return ForceCapturing; }
setForceVarCapturing(bool V)360   void setForceVarCapturing(bool V) { ForceCapturing = V; }
361 
setForceCaptureByReferenceInTargetExecutable(bool V)362   void setForceCaptureByReferenceInTargetExecutable(bool V) {
363     ForceCaptureByReferenceInTargetExecutable = V;
364   }
isForceCaptureByReferenceInTargetExecutable() const365   bool isForceCaptureByReferenceInTargetExecutable() const {
366     return ForceCaptureByReferenceInTargetExecutable;
367   }
368 
push(OpenMPDirectiveKind DKind,const DeclarationNameInfo & DirName,Scope * CurScope,SourceLocation Loc)369   void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName,
370             Scope *CurScope, SourceLocation Loc) {
371     assert(!IgnoredStackElements &&
372            "cannot change stack while ignoring elements");
373     if (Stack.empty() ||
374         Stack.back().second != CurrentNonCapturingFunctionScope)
375       Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope);
376     Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc);
377     Stack.back().first.back().DefaultAttrLoc = Loc;
378   }
379 
pop()380   void pop() {
381     assert(!IgnoredStackElements &&
382            "cannot change stack while ignoring elements");
383     assert(!Stack.back().first.empty() &&
384            "Data-sharing attributes stack is empty!");
385     Stack.back().first.pop_back();
386   }
387 
388   /// RAII object to temporarily leave the scope of a directive when we want to
389   /// logically operate in its parent.
390   class ParentDirectiveScope {
391     DSAStackTy &Self;
392     bool Active;
393   public:
ParentDirectiveScope(DSAStackTy & Self,bool Activate)394     ParentDirectiveScope(DSAStackTy &Self, bool Activate)
395         : Self(Self), Active(false) {
396       if (Activate)
397         enable();
398     }
~ParentDirectiveScope()399     ~ParentDirectiveScope() { disable(); }
disable()400     void disable() {
401       if (Active) {
402         --Self.IgnoredStackElements;
403         Active = false;
404       }
405     }
enable()406     void enable() {
407       if (!Active) {
408         ++Self.IgnoredStackElements;
409         Active = true;
410       }
411     }
412   };
413 
414   /// Marks that we're started loop parsing.
loopInit()415   void loopInit() {
416     assert(isOpenMPLoopDirective(getCurrentDirective()) &&
417            "Expected loop-based directive.");
418     getTopOfStack().LoopStart = true;
419   }
420   /// Start capturing of the variables in the loop context.
loopStart()421   void loopStart() {
422     assert(isOpenMPLoopDirective(getCurrentDirective()) &&
423            "Expected loop-based directive.");
424     getTopOfStack().LoopStart = false;
425   }
426   /// true, if variables are captured, false otherwise.
isLoopStarted() const427   bool isLoopStarted() const {
428     assert(isOpenMPLoopDirective(getCurrentDirective()) &&
429            "Expected loop-based directive.");
430     return !getTopOfStack().LoopStart;
431   }
432   /// Marks (or clears) declaration as possibly loop counter.
resetPossibleLoopCounter(const Decl * D=nullptr)433   void resetPossibleLoopCounter(const Decl *D = nullptr) {
434     getTopOfStack().PossiblyLoopCounter =
435         D ? D->getCanonicalDecl() : D;
436   }
437   /// Gets the possible loop counter decl.
getPossiblyLoopCunter() const438   const Decl *getPossiblyLoopCunter() const {
439     return getTopOfStack().PossiblyLoopCounter;
440   }
441   /// Start new OpenMP region stack in new non-capturing function.
pushFunction()442   void pushFunction() {
443     assert(!IgnoredStackElements &&
444            "cannot change stack while ignoring elements");
445     const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction();
446     assert(!isa<CapturingScopeInfo>(CurFnScope));
447     CurrentNonCapturingFunctionScope = CurFnScope;
448   }
449   /// Pop region stack for non-capturing function.
popFunction(const FunctionScopeInfo * OldFSI)450   void popFunction(const FunctionScopeInfo *OldFSI) {
451     assert(!IgnoredStackElements &&
452            "cannot change stack while ignoring elements");
453     if (!Stack.empty() && Stack.back().second == OldFSI) {
454       assert(Stack.back().first.empty());
455       Stack.pop_back();
456     }
457     CurrentNonCapturingFunctionScope = nullptr;
458     for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) {
459       if (!isa<CapturingScopeInfo>(FSI)) {
460         CurrentNonCapturingFunctionScope = FSI;
461         break;
462       }
463     }
464   }
465 
addCriticalWithHint(const OMPCriticalDirective * D,llvm::APSInt Hint)466   void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) {
467     Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint);
468   }
469   const std::pair<const OMPCriticalDirective *, llvm::APSInt>
getCriticalWithHint(const DeclarationNameInfo & Name) const470   getCriticalWithHint(const DeclarationNameInfo &Name) const {
471     auto I = Criticals.find(Name.getAsString());
472     if (I != Criticals.end())
473       return I->second;
474     return std::make_pair(nullptr, llvm::APSInt());
475   }
476   /// If 'aligned' declaration for given variable \a D was not seen yet,
477   /// add it and return NULL; otherwise return previous occurrence's expression
478   /// for diagnostics.
479   const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE);
480   /// If 'nontemporal' declaration for given variable \a D was not seen yet,
481   /// add it and return NULL; otherwise return previous occurrence's expression
482   /// for diagnostics.
483   const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE);
484 
485   /// Register specified variable as loop control variable.
486   void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture);
487   /// Check if the specified variable is a loop control variable for
488   /// current region.
489   /// \return The index of the loop control variable in the list of associated
490   /// for-loops (from outer to inner).
491   const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const;
492   /// Check if the specified variable is a loop control variable for
493   /// parent region.
494   /// \return The index of the loop control variable in the list of associated
495   /// for-loops (from outer to inner).
496   const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const;
497   /// Check if the specified variable is a loop control variable for
498   /// current region.
499   /// \return The index of the loop control variable in the list of associated
500   /// for-loops (from outer to inner).
501   const LCDeclInfo isLoopControlVariable(const ValueDecl *D,
502                                          unsigned Level) const;
503   /// Get the loop control variable for the I-th loop (or nullptr) in
504   /// parent directive.
505   const ValueDecl *getParentLoopControlVariable(unsigned I) const;
506 
507   /// Marks the specified decl \p D as used in scan directive.
markDeclAsUsedInScanDirective(ValueDecl * D)508   void markDeclAsUsedInScanDirective(ValueDecl *D) {
509     if (SharingMapTy *Stack = getSecondOnStackOrNull())
510       Stack->UsedInScanDirective.insert(D);
511   }
512 
513   /// Checks if the specified declaration was used in the inner scan directive.
isUsedInScanDirective(ValueDecl * D) const514   bool isUsedInScanDirective(ValueDecl *D) const {
515     if (const SharingMapTy *Stack = getTopOfStackOrNull())
516       return Stack->UsedInScanDirective.count(D) > 0;
517     return false;
518   }
519 
520   /// Adds explicit data sharing attribute to the specified declaration.
521   void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
522               DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0,
523               bool AppliedToPointee = false);
524 
525   /// Adds additional information for the reduction items with the reduction id
526   /// represented as an operator.
527   void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
528                                  BinaryOperatorKind BOK);
529   /// Adds additional information for the reduction items with the reduction id
530   /// represented as reduction identifier.
531   void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
532                                  const Expr *ReductionRef);
533   /// Returns the location and reduction operation from the innermost parent
534   /// region for the given \p D.
535   const DSAVarData
536   getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
537                                    BinaryOperatorKind &BOK,
538                                    Expr *&TaskgroupDescriptor) const;
539   /// Returns the location and reduction operation from the innermost parent
540   /// region for the given \p D.
541   const DSAVarData
542   getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR,
543                                    const Expr *&ReductionRef,
544                                    Expr *&TaskgroupDescriptor) const;
545   /// Return reduction reference expression for the current taskgroup or
546   /// parallel/worksharing directives with task reductions.
getTaskgroupReductionRef() const547   Expr *getTaskgroupReductionRef() const {
548     assert((getTopOfStack().Directive == OMPD_taskgroup ||
549             ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
550               isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
551              !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
552            "taskgroup reference expression requested for non taskgroup or "
553            "parallel/worksharing directive.");
554     return getTopOfStack().TaskgroupReductionRef;
555   }
556   /// Checks if the given \p VD declaration is actually a taskgroup reduction
557   /// descriptor variable at the \p Level of OpenMP regions.
isTaskgroupReductionRef(const ValueDecl * VD,unsigned Level) const558   bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const {
559     return getStackElemAtLevel(Level).TaskgroupReductionRef &&
560            cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef)
561                    ->getDecl() == VD;
562   }
563 
564   /// Returns data sharing attributes from top of the stack for the
565   /// specified declaration.
566   const DSAVarData getTopDSA(ValueDecl *D, bool FromParent);
567   /// Returns data-sharing attributes for the specified declaration.
568   const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const;
569   /// Returns data-sharing attributes for the specified declaration.
570   const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const;
571   /// Checks if the specified variables has data-sharing attributes which
572   /// match specified \a CPred predicate in any directive which matches \a DPred
573   /// predicate.
574   const DSAVarData
575   hasDSA(ValueDecl *D,
576          const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
577          const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
578          bool FromParent) const;
579   /// Checks if the specified variables has data-sharing attributes which
580   /// match specified \a CPred predicate in any innermost directive which
581   /// matches \a DPred predicate.
582   const DSAVarData
583   hasInnermostDSA(ValueDecl *D,
584                   const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
585                   const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
586                   bool FromParent) const;
587   /// Checks if the specified variables has explicit data-sharing
588   /// attributes which match specified \a CPred predicate at the specified
589   /// OpenMP region.
590   bool
591   hasExplicitDSA(const ValueDecl *D,
592                  const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
593                  unsigned Level, bool NotLastprivate = false) const;
594 
595   /// Returns true if the directive at level \Level matches in the
596   /// specified \a DPred predicate.
597   bool hasExplicitDirective(
598       const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
599       unsigned Level) const;
600 
601   /// Finds a directive which matches specified \a DPred predicate.
602   bool hasDirective(
603       const llvm::function_ref<bool(
604           OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)>
605           DPred,
606       bool FromParent) const;
607 
608   /// Returns currently analyzed directive.
getCurrentDirective() const609   OpenMPDirectiveKind getCurrentDirective() const {
610     const SharingMapTy *Top = getTopOfStackOrNull();
611     return Top ? Top->Directive : OMPD_unknown;
612   }
613   /// Returns directive kind at specified level.
getDirective(unsigned Level) const614   OpenMPDirectiveKind getDirective(unsigned Level) const {
615     assert(!isStackEmpty() && "No directive at specified level.");
616     return getStackElemAtLevel(Level).Directive;
617   }
618   /// Returns the capture region at the specified level.
getCaptureRegion(unsigned Level,unsigned OpenMPCaptureLevel) const619   OpenMPDirectiveKind getCaptureRegion(unsigned Level,
620                                        unsigned OpenMPCaptureLevel) const {
621     SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
622     getOpenMPCaptureRegions(CaptureRegions, getDirective(Level));
623     return CaptureRegions[OpenMPCaptureLevel];
624   }
625   /// Returns parent directive.
getParentDirective() const626   OpenMPDirectiveKind getParentDirective() const {
627     const SharingMapTy *Parent = getSecondOnStackOrNull();
628     return Parent ? Parent->Directive : OMPD_unknown;
629   }
630 
631   /// Add requires decl to internal vector
addRequiresDecl(OMPRequiresDecl * RD)632   void addRequiresDecl(OMPRequiresDecl *RD) {
633     RequiresDecls.push_back(RD);
634   }
635 
636   /// Checks if the defined 'requires' directive has specified type of clause.
637   template <typename ClauseType>
hasRequiresDeclWithClause() const638   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
hasDuplicateRequiresClause(ArrayRef<OMPClause * > ClauseList) const648   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
addTargetDirLocation(SourceLocation LocStart)669   void addTargetDirLocation(SourceLocation LocStart) {
670     TargetLocations.push_back(LocStart);
671   }
672 
673   /// Add location for the first encountered atomicc directive.
addAtomicDirectiveLoc(SourceLocation Loc)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.
getAtomicDirectiveLoc() const681   SourceLocation getAtomicDirectiveLoc() const {
682     return AtomicLocation;
683   }
684 
685   // Return previously encountered target region locations.
getEncounteredTargetLocs() const686   ArrayRef<SourceLocation> getEncounteredTargetLocs() const {
687     return TargetLocations;
688   }
689 
690   /// Set default data sharing attribute to none.
setDefaultDSANone(SourceLocation Loc)691   void setDefaultDSANone(SourceLocation Loc) {
692     getTopOfStack().DefaultAttr = DSA_none;
693     getTopOfStack().DefaultAttrLoc = Loc;
694   }
695   /// Set default data sharing attribute to shared.
setDefaultDSAShared(SourceLocation Loc)696   void setDefaultDSAShared(SourceLocation Loc) {
697     getTopOfStack().DefaultAttr = DSA_shared;
698     getTopOfStack().DefaultAttrLoc = Loc;
699   }
700   /// Set default data sharing attribute to firstprivate.
setDefaultDSAFirstPrivate(SourceLocation Loc)701   void setDefaultDSAFirstPrivate(SourceLocation Loc) {
702     getTopOfStack().DefaultAttr = DSA_firstprivate;
703     getTopOfStack().DefaultAttrLoc = Loc;
704   }
705   /// Set default data mapping attribute to Modifier:Kind
setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,OpenMPDefaultmapClauseKind Kind,SourceLocation Loc)706   void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M,
707                          OpenMPDefaultmapClauseKind Kind,
708                          SourceLocation Loc) {
709     DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind];
710     DMI.ImplicitBehavior = M;
711     DMI.SLoc = Loc;
712   }
713   /// Check whether the implicit-behavior has been set in defaultmap
checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory)714   bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) {
715     if (VariableCategory == OMPC_DEFAULTMAP_unknown)
716       return getTopOfStack()
717                      .DefaultmapMap[OMPC_DEFAULTMAP_aggregate]
718                      .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
719              getTopOfStack()
720                      .DefaultmapMap[OMPC_DEFAULTMAP_scalar]
721                      .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown ||
722              getTopOfStack()
723                      .DefaultmapMap[OMPC_DEFAULTMAP_pointer]
724                      .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown;
725     return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior !=
726            OMPC_DEFAULTMAP_MODIFIER_unknown;
727   }
728 
getDefaultDSA(unsigned Level) const729   DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const {
730     return getStackSize() <= Level ? DSA_unspecified
731                                    : getStackElemAtLevel(Level).DefaultAttr;
732   }
getDefaultDSA() const733   DefaultDataSharingAttributes getDefaultDSA() const {
734     return isStackEmpty() ? DSA_unspecified
735                           : getTopOfStack().DefaultAttr;
736   }
getDefaultDSALocation() const737   SourceLocation getDefaultDSALocation() const {
738     return isStackEmpty() ? SourceLocation()
739                           : getTopOfStack().DefaultAttrLoc;
740   }
741   OpenMPDefaultmapClauseModifier
getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const742   getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const {
743     return isStackEmpty()
744                ? OMPC_DEFAULTMAP_MODIFIER_unknown
745                : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior;
746   }
747   OpenMPDefaultmapClauseModifier
getDefaultmapModifierAtLevel(unsigned Level,OpenMPDefaultmapClauseKind Kind) const748   getDefaultmapModifierAtLevel(unsigned Level,
749                                OpenMPDefaultmapClauseKind Kind) const {
750     return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior;
751   }
isDefaultmapCapturedByRef(unsigned Level,OpenMPDefaultmapClauseKind Kind) const752   bool isDefaultmapCapturedByRef(unsigned Level,
753                                  OpenMPDefaultmapClauseKind Kind) const {
754     OpenMPDefaultmapClauseModifier M =
755         getDefaultmapModifierAtLevel(Level, Kind);
756     if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) {
757       return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) ||
758              (M == OMPC_DEFAULTMAP_MODIFIER_to) ||
759              (M == OMPC_DEFAULTMAP_MODIFIER_from) ||
760              (M == OMPC_DEFAULTMAP_MODIFIER_tofrom);
761     }
762     return true;
763   }
mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M,OpenMPDefaultmapClauseKind Kind)764   static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M,
765                                      OpenMPDefaultmapClauseKind Kind) {
766     switch (Kind) {
767     case OMPC_DEFAULTMAP_scalar:
768     case OMPC_DEFAULTMAP_pointer:
769       return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) ||
770              (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) ||
771              (M == OMPC_DEFAULTMAP_MODIFIER_default);
772     case OMPC_DEFAULTMAP_aggregate:
773       return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate;
774     default:
775       break;
776     }
777     llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum");
778   }
mustBeFirstprivateAtLevel(unsigned Level,OpenMPDefaultmapClauseKind Kind) const779   bool mustBeFirstprivateAtLevel(unsigned Level,
780                                  OpenMPDefaultmapClauseKind Kind) const {
781     OpenMPDefaultmapClauseModifier M =
782         getDefaultmapModifierAtLevel(Level, Kind);
783     return mustBeFirstprivateBase(M, Kind);
784   }
mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const785   bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const {
786     OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind);
787     return mustBeFirstprivateBase(M, Kind);
788   }
789 
790   /// Checks if the specified variable is a threadprivate.
isThreadPrivate(VarDecl * D)791   bool isThreadPrivate(VarDecl *D) {
792     const DSAVarData DVar = getTopDSA(D, false);
793     return isOpenMPThreadPrivate(DVar.CKind);
794   }
795 
796   /// Marks current region as ordered (it has an 'ordered' clause).
setOrderedRegion(bool IsOrdered,const Expr * Param,OMPOrderedClause * Clause)797   void setOrderedRegion(bool IsOrdered, const Expr *Param,
798                         OMPOrderedClause *Clause) {
799     if (IsOrdered)
800       getTopOfStack().OrderedRegion.emplace(Param, Clause);
801     else
802       getTopOfStack().OrderedRegion.reset();
803   }
804   /// Returns true, if region is ordered (has associated 'ordered' clause),
805   /// false - otherwise.
isOrderedRegion() const806   bool isOrderedRegion() const {
807     if (const SharingMapTy *Top = getTopOfStackOrNull())
808       return Top->OrderedRegion.hasValue();
809     return false;
810   }
811   /// Returns optional parameter for the ordered region.
getOrderedRegionParam() const812   std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const {
813     if (const SharingMapTy *Top = getTopOfStackOrNull())
814       if (Top->OrderedRegion.hasValue())
815         return Top->OrderedRegion.getValue();
816     return std::make_pair(nullptr, nullptr);
817   }
818   /// Returns true, if parent region is ordered (has associated
819   /// 'ordered' clause), false - otherwise.
isParentOrderedRegion() const820   bool isParentOrderedRegion() const {
821     if (const SharingMapTy *Parent = getSecondOnStackOrNull())
822       return Parent->OrderedRegion.hasValue();
823     return false;
824   }
825   /// Returns optional parameter for the ordered region.
826   std::pair<const Expr *, OMPOrderedClause *>
getParentOrderedRegionParam() const827   getParentOrderedRegionParam() const {
828     if (const SharingMapTy *Parent = getSecondOnStackOrNull())
829       if (Parent->OrderedRegion.hasValue())
830         return Parent->OrderedRegion.getValue();
831     return std::make_pair(nullptr, nullptr);
832   }
833   /// Marks current region as nowait (it has a 'nowait' clause).
setNowaitRegion(bool IsNowait=true)834   void setNowaitRegion(bool IsNowait = true) {
835     getTopOfStack().NowaitRegion = IsNowait;
836   }
837   /// Returns true, if parent region is nowait (has associated
838   /// 'nowait' clause), false - otherwise.
isParentNowaitRegion() const839   bool isParentNowaitRegion() const {
840     if (const SharingMapTy *Parent = getSecondOnStackOrNull())
841       return Parent->NowaitRegion;
842     return false;
843   }
844   /// Marks parent region as cancel region.
setParentCancelRegion(bool Cancel=true)845   void setParentCancelRegion(bool Cancel = true) {
846     if (SharingMapTy *Parent = getSecondOnStackOrNull())
847       Parent->CancelRegion |= Cancel;
848   }
849   /// Return true if current region has inner cancel construct.
isCancelRegion() const850   bool isCancelRegion() const {
851     const SharingMapTy *Top = getTopOfStackOrNull();
852     return Top ? Top->CancelRegion : false;
853   }
854 
855   /// Mark that parent region already has scan directive.
setParentHasScanDirective(SourceLocation Loc)856   void setParentHasScanDirective(SourceLocation Loc) {
857     if (SharingMapTy *Parent = getSecondOnStackOrNull())
858       Parent->PrevScanLocation = Loc;
859   }
860   /// Return true if current region has inner cancel construct.
doesParentHasScanDirective() const861   bool doesParentHasScanDirective() const {
862     const SharingMapTy *Top = getSecondOnStackOrNull();
863     return Top ? Top->PrevScanLocation.isValid() : false;
864   }
865   /// Return true if current region has inner cancel construct.
getParentScanDirectiveLoc() const866   SourceLocation getParentScanDirectiveLoc() const {
867     const SharingMapTy *Top = getSecondOnStackOrNull();
868     return Top ? Top->PrevScanLocation : SourceLocation();
869   }
870   /// Mark that parent region already has ordered directive.
setParentHasOrderedDirective(SourceLocation Loc)871   void setParentHasOrderedDirective(SourceLocation Loc) {
872     if (SharingMapTy *Parent = getSecondOnStackOrNull())
873       Parent->PrevOrderedLocation = Loc;
874   }
875   /// Return true if current region has inner ordered construct.
doesParentHasOrderedDirective() const876   bool doesParentHasOrderedDirective() const {
877     const SharingMapTy *Top = getSecondOnStackOrNull();
878     return Top ? Top->PrevOrderedLocation.isValid() : false;
879   }
880   /// Returns the location of the previously specified ordered directive.
getParentOrderedDirectiveLoc() const881   SourceLocation getParentOrderedDirectiveLoc() const {
882     const SharingMapTy *Top = getSecondOnStackOrNull();
883     return Top ? Top->PrevOrderedLocation : SourceLocation();
884   }
885 
886   /// Set collapse value for the region.
setAssociatedLoops(unsigned Val)887   void setAssociatedLoops(unsigned Val) {
888     getTopOfStack().AssociatedLoops = Val;
889     if (Val > 1)
890       getTopOfStack().HasMutipleLoops = true;
891   }
892   /// Return collapse value for region.
getAssociatedLoops() const893   unsigned getAssociatedLoops() const {
894     const SharingMapTy *Top = getTopOfStackOrNull();
895     return Top ? Top->AssociatedLoops : 0;
896   }
897   /// Returns true if the construct is associated with multiple loops.
hasMutipleLoops() const898   bool hasMutipleLoops() const {
899     const SharingMapTy *Top = getTopOfStackOrNull();
900     return Top ? Top->HasMutipleLoops : false;
901   }
902 
903   /// Marks current target region as one with closely nested teams
904   /// region.
setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc)905   void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) {
906     if (SharingMapTy *Parent = getSecondOnStackOrNull())
907       Parent->InnerTeamsRegionLoc = TeamsRegionLoc;
908   }
909   /// Returns true, if current region has closely nested teams region.
hasInnerTeamsRegion() const910   bool hasInnerTeamsRegion() const {
911     return getInnerTeamsRegionLoc().isValid();
912   }
913   /// Returns location of the nested teams region (if any).
getInnerTeamsRegionLoc() const914   SourceLocation getInnerTeamsRegionLoc() const {
915     const SharingMapTy *Top = getTopOfStackOrNull();
916     return Top ? Top->InnerTeamsRegionLoc : SourceLocation();
917   }
918 
getCurScope() const919   Scope *getCurScope() const {
920     const SharingMapTy *Top = getTopOfStackOrNull();
921     return Top ? Top->CurScope : nullptr;
922   }
setContext(DeclContext * DC)923   void setContext(DeclContext *DC) { getTopOfStack().Context = DC; }
getConstructLoc() const924   SourceLocation getConstructLoc() const {
925     const SharingMapTy *Top = getTopOfStackOrNull();
926     return Top ? Top->ConstructLoc : SourceLocation();
927   }
928 
929   /// Do the check specified in \a Check to all component lists and return true
930   /// if any issue is found.
checkMappableExprComponentListsForDecl(const ValueDecl * VD,bool CurrentRegionOnly,const llvm::function_ref<bool (OMPClauseMappableExprCommon::MappableExprComponentListRef,OpenMPClauseKind)> Check) const931   bool checkMappableExprComponentListsForDecl(
932       const ValueDecl *VD, bool CurrentRegionOnly,
933       const llvm::function_ref<
934           bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
935                OpenMPClauseKind)>
936           Check) const {
937     if (isStackEmpty())
938       return false;
939     auto SI = begin();
940     auto SE = end();
941 
942     if (SI == SE)
943       return false;
944 
945     if (CurrentRegionOnly)
946       SE = std::next(SI);
947     else
948       std::advance(SI, 1);
949 
950     for (; SI != SE; ++SI) {
951       auto MI = SI->MappedExprComponents.find(VD);
952       if (MI != SI->MappedExprComponents.end())
953         for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
954              MI->second.Components)
955           if (Check(L, MI->second.Kind))
956             return true;
957     }
958     return false;
959   }
960 
961   /// Do the check specified in \a Check to all component lists at a given level
962   /// and return true if any issue is found.
checkMappableExprComponentListsForDeclAtLevel(const ValueDecl * VD,unsigned Level,const llvm::function_ref<bool (OMPClauseMappableExprCommon::MappableExprComponentListRef,OpenMPClauseKind)> Check) const963   bool checkMappableExprComponentListsForDeclAtLevel(
964       const ValueDecl *VD, unsigned Level,
965       const llvm::function_ref<
966           bool(OMPClauseMappableExprCommon::MappableExprComponentListRef,
967                OpenMPClauseKind)>
968           Check) const {
969     if (getStackSize() <= Level)
970       return false;
971 
972     const SharingMapTy &StackElem = getStackElemAtLevel(Level);
973     auto MI = StackElem.MappedExprComponents.find(VD);
974     if (MI != StackElem.MappedExprComponents.end())
975       for (OMPClauseMappableExprCommon::MappableExprComponentListRef L :
976            MI->second.Components)
977         if (Check(L, MI->second.Kind))
978           return true;
979     return false;
980   }
981 
982   /// Create a new mappable expression component list associated with a given
983   /// declaration and initialize it with the provided list of components.
addMappableExpressionComponents(const ValueDecl * VD,OMPClauseMappableExprCommon::MappableExprComponentListRef Components,OpenMPClauseKind WhereFoundClauseKind)984   void addMappableExpressionComponents(
985       const ValueDecl *VD,
986       OMPClauseMappableExprCommon::MappableExprComponentListRef Components,
987       OpenMPClauseKind WhereFoundClauseKind) {
988     MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD];
989     // Create new entry and append the new components there.
990     MEC.Components.resize(MEC.Components.size() + 1);
991     MEC.Components.back().append(Components.begin(), Components.end());
992     MEC.Kind = WhereFoundClauseKind;
993   }
994 
getNestingLevel() const995   unsigned getNestingLevel() const {
996     assert(!isStackEmpty());
997     return getStackSize() - 1;
998   }
addDoacrossDependClause(OMPDependClause * C,const OperatorOffsetTy & OpsOffs)999   void addDoacrossDependClause(OMPDependClause *C,
1000                                const OperatorOffsetTy &OpsOffs) {
1001     SharingMapTy *Parent = getSecondOnStackOrNull();
1002     assert(Parent && isOpenMPWorksharingDirective(Parent->Directive));
1003     Parent->DoacrossDepends.try_emplace(C, OpsOffs);
1004   }
1005   llvm::iterator_range<DoacrossDependMapTy::const_iterator>
getDoacrossDependClauses() const1006   getDoacrossDependClauses() const {
1007     const SharingMapTy &StackElem = getTopOfStack();
1008     if (isOpenMPWorksharingDirective(StackElem.Directive)) {
1009       const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends;
1010       return llvm::make_range(Ref.begin(), Ref.end());
1011     }
1012     return llvm::make_range(StackElem.DoacrossDepends.end(),
1013                             StackElem.DoacrossDepends.end());
1014   }
1015 
1016   // Store types of classes which have been explicitly mapped
addMappedClassesQualTypes(QualType QT)1017   void addMappedClassesQualTypes(QualType QT) {
1018     SharingMapTy &StackElem = getTopOfStack();
1019     StackElem.MappedClassesQualTypes.insert(QT);
1020   }
1021 
1022   // Return set of mapped classes types
isClassPreviouslyMapped(QualType QT) const1023   bool isClassPreviouslyMapped(QualType QT) const {
1024     const SharingMapTy &StackElem = getTopOfStack();
1025     return StackElem.MappedClassesQualTypes.count(QT) != 0;
1026   }
1027 
1028   /// Adds global declare target to the parent target region.
addToParentTargetRegionLinkGlobals(DeclRefExpr * E)1029   void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) {
1030     assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(
1031                E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link &&
1032            "Expected declare target link global.");
1033     for (auto &Elem : *this) {
1034       if (isOpenMPTargetExecutionDirective(Elem.Directive)) {
1035         Elem.DeclareTargetLinkVarDecls.push_back(E);
1036         return;
1037       }
1038     }
1039   }
1040 
1041   /// Returns the list of globals with declare target link if current directive
1042   /// is target.
getLinkGlobals() const1043   ArrayRef<DeclRefExpr *> getLinkGlobals() const {
1044     assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) &&
1045            "Expected target executable directive.");
1046     return getTopOfStack().DeclareTargetLinkVarDecls;
1047   }
1048 
1049   /// Adds list of allocators expressions.
addInnerAllocatorExpr(Expr * E)1050   void addInnerAllocatorExpr(Expr *E) {
1051     getTopOfStack().InnerUsedAllocators.push_back(E);
1052   }
1053   /// Return list of used allocators.
getInnerAllocators() const1054   ArrayRef<Expr *> getInnerAllocators() const {
1055     return getTopOfStack().InnerUsedAllocators;
1056   }
1057   /// Marks the declaration as implicitly firstprivate nin the task-based
1058   /// regions.
addImplicitTaskFirstprivate(unsigned Level,Decl * D)1059   void addImplicitTaskFirstprivate(unsigned Level, Decl *D) {
1060     getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D);
1061   }
1062   /// Checks if the decl is implicitly firstprivate in the task-based region.
isImplicitTaskFirstprivate(Decl * D) const1063   bool isImplicitTaskFirstprivate(Decl *D) const {
1064     return getTopOfStack().ImplicitTaskFirstprivates.count(D) > 0;
1065   }
1066 
1067   /// Marks decl as used in uses_allocators clause as the allocator.
addUsesAllocatorsDecl(const Decl * D,UsesAllocatorsDeclKind Kind)1068   void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) {
1069     getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind);
1070   }
1071   /// Checks if specified decl is used in uses allocator clause as the
1072   /// allocator.
isUsesAllocatorsDecl(unsigned Level,const Decl * D) const1073   Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(unsigned Level,
1074                                                         const Decl *D) const {
1075     const SharingMapTy &StackElem = getTopOfStack();
1076     auto I = StackElem.UsesAllocatorsDecls.find(D);
1077     if (I == StackElem.UsesAllocatorsDecls.end())
1078       return None;
1079     return I->getSecond();
1080   }
isUsesAllocatorsDecl(const Decl * D) const1081   Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(const Decl *D) const {
1082     const SharingMapTy &StackElem = getTopOfStack();
1083     auto I = StackElem.UsesAllocatorsDecls.find(D);
1084     if (I == StackElem.UsesAllocatorsDecls.end())
1085       return None;
1086     return I->getSecond();
1087   }
1088 
addDeclareMapperVarRef(Expr * Ref)1089   void addDeclareMapperVarRef(Expr *Ref) {
1090     SharingMapTy &StackElem = getTopOfStack();
1091     StackElem.DeclareMapperVar = Ref;
1092   }
getDeclareMapperVarRef() const1093   const Expr *getDeclareMapperVarRef() const {
1094     const SharingMapTy *Top = getTopOfStackOrNull();
1095     return Top ? Top->DeclareMapperVar : nullptr;
1096   }
1097 };
1098 
isImplicitTaskingRegion(OpenMPDirectiveKind DKind)1099 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1100   return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind);
1101 }
1102 
isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind)1103 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) {
1104   return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) ||
1105          DKind == OMPD_unknown;
1106 }
1107 
1108 } // namespace
1109 
getExprAsWritten(const Expr * E)1110 static const Expr *getExprAsWritten(const Expr *E) {
1111   if (const auto *FE = dyn_cast<FullExpr>(E))
1112     E = FE->getSubExpr();
1113 
1114   if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E))
1115     E = MTE->getSubExpr();
1116 
1117   while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E))
1118     E = Binder->getSubExpr();
1119 
1120   if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E))
1121     E = ICE->getSubExprAsWritten();
1122   return E->IgnoreParens();
1123 }
1124 
getExprAsWritten(Expr * E)1125 static Expr *getExprAsWritten(Expr *E) {
1126   return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E)));
1127 }
1128 
getCanonicalDecl(const ValueDecl * D)1129 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) {
1130   if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D))
1131     if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
1132       D = ME->getMemberDecl();
1133   const auto *VD = dyn_cast<VarDecl>(D);
1134   const auto *FD = dyn_cast<FieldDecl>(D);
1135   if (VD != nullptr) {
1136     VD = VD->getCanonicalDecl();
1137     D = VD;
1138   } else {
1139     assert(FD);
1140     FD = FD->getCanonicalDecl();
1141     D = FD;
1142   }
1143   return D;
1144 }
1145 
getCanonicalDecl(ValueDecl * D)1146 static ValueDecl *getCanonicalDecl(ValueDecl *D) {
1147   return const_cast<ValueDecl *>(
1148       getCanonicalDecl(const_cast<const ValueDecl *>(D)));
1149 }
1150 
getDSA(const_iterator & Iter,ValueDecl * D) const1151 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter,
1152                                           ValueDecl *D) const {
1153   D = getCanonicalDecl(D);
1154   auto *VD = dyn_cast<VarDecl>(D);
1155   const auto *FD = dyn_cast<FieldDecl>(D);
1156   DSAVarData DVar;
1157   if (Iter == end()) {
1158     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1159     // in a region but not in construct]
1160     //  File-scope or namespace-scope variables referenced in called routines
1161     //  in the region are shared unless they appear in a threadprivate
1162     //  directive.
1163     if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD))
1164       DVar.CKind = OMPC_shared;
1165 
1166     // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced
1167     // in a region but not in construct]
1168     //  Variables with static storage duration that are declared in called
1169     //  routines in the region are shared.
1170     if (VD && VD->hasGlobalStorage())
1171       DVar.CKind = OMPC_shared;
1172 
1173     // Non-static data members are shared by default.
1174     if (FD)
1175       DVar.CKind = OMPC_shared;
1176 
1177     return DVar;
1178   }
1179 
1180   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1181   // in a Construct, C/C++, predetermined, p.1]
1182   // Variables with automatic storage duration that are declared in a scope
1183   // inside the construct are private.
1184   if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() &&
1185       (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) {
1186     DVar.CKind = OMPC_private;
1187     return DVar;
1188   }
1189 
1190   DVar.DKind = Iter->Directive;
1191   // Explicitly specified attributes and local variables with predetermined
1192   // attributes.
1193   if (Iter->SharingMap.count(D)) {
1194     const DSAInfo &Data = Iter->SharingMap.lookup(D);
1195     DVar.RefExpr = Data.RefExpr.getPointer();
1196     DVar.PrivateCopy = Data.PrivateCopy;
1197     DVar.CKind = Data.Attributes;
1198     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1199     DVar.Modifier = Data.Modifier;
1200     DVar.AppliedToPointee = Data.AppliedToPointee;
1201     return DVar;
1202   }
1203 
1204   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1205   // in a Construct, C/C++, implicitly determined, p.1]
1206   //  In a parallel or task construct, the data-sharing attributes of these
1207   //  variables are determined by the default clause, if present.
1208   switch (Iter->DefaultAttr) {
1209   case DSA_shared:
1210     DVar.CKind = OMPC_shared;
1211     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1212     return DVar;
1213   case DSA_none:
1214     return DVar;
1215   case DSA_firstprivate:
1216     if (VD->getStorageDuration() == SD_Static &&
1217         VD->getDeclContext()->isFileContext()) {
1218       DVar.CKind = OMPC_unknown;
1219     } else {
1220       DVar.CKind = OMPC_firstprivate;
1221     }
1222     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1223     return DVar;
1224   case DSA_unspecified:
1225     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1226     // in a Construct, implicitly determined, p.2]
1227     //  In a parallel construct, if no default clause is present, these
1228     //  variables are shared.
1229     DVar.ImplicitDSALoc = Iter->DefaultAttrLoc;
1230     if ((isOpenMPParallelDirective(DVar.DKind) &&
1231          !isOpenMPTaskLoopDirective(DVar.DKind)) ||
1232         isOpenMPTeamsDirective(DVar.DKind)) {
1233       DVar.CKind = OMPC_shared;
1234       return DVar;
1235     }
1236 
1237     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1238     // in a Construct, implicitly determined, p.4]
1239     //  In a task construct, if no default clause is present, a variable that in
1240     //  the enclosing context is determined to be shared by all implicit tasks
1241     //  bound to the current team is shared.
1242     if (isOpenMPTaskingDirective(DVar.DKind)) {
1243       DSAVarData DVarTemp;
1244       const_iterator I = Iter, E = end();
1245       do {
1246         ++I;
1247         // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables
1248         // Referenced in a Construct, implicitly determined, p.6]
1249         //  In a task construct, if no default clause is present, a variable
1250         //  whose data-sharing attribute is not determined by the rules above is
1251         //  firstprivate.
1252         DVarTemp = getDSA(I, D);
1253         if (DVarTemp.CKind != OMPC_shared) {
1254           DVar.RefExpr = nullptr;
1255           DVar.CKind = OMPC_firstprivate;
1256           return DVar;
1257         }
1258       } while (I != E && !isImplicitTaskingRegion(I->Directive));
1259       DVar.CKind =
1260           (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared;
1261       return DVar;
1262     }
1263   }
1264   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1265   // in a Construct, implicitly determined, p.3]
1266   //  For constructs other than task, if no default clause is present, these
1267   //  variables inherit their data-sharing attributes from the enclosing
1268   //  context.
1269   return getDSA(++Iter, D);
1270 }
1271 
addUniqueAligned(const ValueDecl * D,const Expr * NewDE)1272 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D,
1273                                          const Expr *NewDE) {
1274   assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1275   D = getCanonicalDecl(D);
1276   SharingMapTy &StackElem = getTopOfStack();
1277   auto It = StackElem.AlignedMap.find(D);
1278   if (It == StackElem.AlignedMap.end()) {
1279     assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1280     StackElem.AlignedMap[D] = NewDE;
1281     return nullptr;
1282   }
1283   assert(It->second && "Unexpected nullptr expr in the aligned map");
1284   return It->second;
1285 }
1286 
addUniqueNontemporal(const ValueDecl * D,const Expr * NewDE)1287 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D,
1288                                              const Expr *NewDE) {
1289   assert(!isStackEmpty() && "Data sharing attributes stack is empty");
1290   D = getCanonicalDecl(D);
1291   SharingMapTy &StackElem = getTopOfStack();
1292   auto It = StackElem.NontemporalMap.find(D);
1293   if (It == StackElem.NontemporalMap.end()) {
1294     assert(NewDE && "Unexpected nullptr expr to be added into aligned map");
1295     StackElem.NontemporalMap[D] = NewDE;
1296     return nullptr;
1297   }
1298   assert(It->second && "Unexpected nullptr expr in the aligned map");
1299   return It->second;
1300 }
1301 
addLoopControlVariable(const ValueDecl * D,VarDecl * Capture)1302 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) {
1303   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1304   D = getCanonicalDecl(D);
1305   SharingMapTy &StackElem = getTopOfStack();
1306   StackElem.LCVMap.try_emplace(
1307       D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture));
1308 }
1309 
1310 const DSAStackTy::LCDeclInfo
isLoopControlVariable(const ValueDecl * D) const1311 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const {
1312   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1313   D = getCanonicalDecl(D);
1314   const SharingMapTy &StackElem = getTopOfStack();
1315   auto It = StackElem.LCVMap.find(D);
1316   if (It != StackElem.LCVMap.end())
1317     return It->second;
1318   return {0, nullptr};
1319 }
1320 
1321 const DSAStackTy::LCDeclInfo
isLoopControlVariable(const ValueDecl * D,unsigned Level) const1322 DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const {
1323   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1324   D = getCanonicalDecl(D);
1325   for (unsigned I = Level + 1; I > 0; --I) {
1326     const SharingMapTy &StackElem = getStackElemAtLevel(I - 1);
1327     auto It = StackElem.LCVMap.find(D);
1328     if (It != StackElem.LCVMap.end())
1329       return It->second;
1330   }
1331   return {0, nullptr};
1332 }
1333 
1334 const DSAStackTy::LCDeclInfo
isParentLoopControlVariable(const ValueDecl * D) const1335 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const {
1336   const SharingMapTy *Parent = getSecondOnStackOrNull();
1337   assert(Parent && "Data-sharing attributes stack is empty");
1338   D = getCanonicalDecl(D);
1339   auto It = Parent->LCVMap.find(D);
1340   if (It != Parent->LCVMap.end())
1341     return It->second;
1342   return {0, nullptr};
1343 }
1344 
getParentLoopControlVariable(unsigned I) const1345 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const {
1346   const SharingMapTy *Parent = getSecondOnStackOrNull();
1347   assert(Parent && "Data-sharing attributes stack is empty");
1348   if (Parent->LCVMap.size() < I)
1349     return nullptr;
1350   for (const auto &Pair : Parent->LCVMap)
1351     if (Pair.second.first == I)
1352       return Pair.first;
1353   return nullptr;
1354 }
1355 
addDSA(const ValueDecl * D,const Expr * E,OpenMPClauseKind A,DeclRefExpr * PrivateCopy,unsigned Modifier,bool AppliedToPointee)1356 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A,
1357                         DeclRefExpr *PrivateCopy, unsigned Modifier,
1358                         bool AppliedToPointee) {
1359   D = getCanonicalDecl(D);
1360   if (A == OMPC_threadprivate) {
1361     DSAInfo &Data = Threadprivates[D];
1362     Data.Attributes = A;
1363     Data.RefExpr.setPointer(E);
1364     Data.PrivateCopy = nullptr;
1365     Data.Modifier = Modifier;
1366   } else {
1367     DSAInfo &Data = getTopOfStack().SharingMap[D];
1368     assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) ||
1369            (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) ||
1370            (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) ||
1371            (isLoopControlVariable(D).first && A == OMPC_private));
1372     Data.Modifier = Modifier;
1373     if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) {
1374       Data.RefExpr.setInt(/*IntVal=*/true);
1375       return;
1376     }
1377     const bool IsLastprivate =
1378         A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate;
1379     Data.Attributes = A;
1380     Data.RefExpr.setPointerAndInt(E, IsLastprivate);
1381     Data.PrivateCopy = PrivateCopy;
1382     Data.AppliedToPointee = AppliedToPointee;
1383     if (PrivateCopy) {
1384       DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()];
1385       Data.Modifier = Modifier;
1386       Data.Attributes = A;
1387       Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate);
1388       Data.PrivateCopy = nullptr;
1389       Data.AppliedToPointee = AppliedToPointee;
1390     }
1391   }
1392 }
1393 
1394 /// Build a variable declaration for OpenMP loop iteration variable.
buildVarDecl(Sema & SemaRef,SourceLocation Loc,QualType Type,StringRef Name,const AttrVec * Attrs=nullptr,DeclRefExpr * OrigRef=nullptr)1395 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type,
1396                              StringRef Name, const AttrVec *Attrs = nullptr,
1397                              DeclRefExpr *OrigRef = nullptr) {
1398   DeclContext *DC = SemaRef.CurContext;
1399   IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name);
1400   TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc);
1401   auto *Decl =
1402       VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None);
1403   if (Attrs) {
1404     for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end());
1405          I != E; ++I)
1406       Decl->addAttr(*I);
1407   }
1408   Decl->setImplicit();
1409   if (OrigRef) {
1410     Decl->addAttr(
1411         OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef));
1412   }
1413   return Decl;
1414 }
1415 
buildDeclRefExpr(Sema & S,VarDecl * D,QualType Ty,SourceLocation Loc,bool RefersToCapture=false)1416 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty,
1417                                      SourceLocation Loc,
1418                                      bool RefersToCapture = false) {
1419   D->setReferenced();
1420   D->markUsed(S.Context);
1421   return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(),
1422                              SourceLocation(), D, RefersToCapture, Loc, Ty,
1423                              VK_LValue);
1424 }
1425 
addTaskgroupReductionData(const ValueDecl * D,SourceRange SR,BinaryOperatorKind BOK)1426 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1427                                            BinaryOperatorKind BOK) {
1428   D = getCanonicalDecl(D);
1429   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1430   assert(
1431       getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1432       "Additional reduction info may be specified only for reduction items.");
1433   ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1434   assert(ReductionData.ReductionRange.isInvalid() &&
1435          (getTopOfStack().Directive == OMPD_taskgroup ||
1436           ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1437             isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1438            !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1439          "Additional reduction info may be specified only once for reduction "
1440          "items.");
1441   ReductionData.set(BOK, SR);
1442   Expr *&TaskgroupReductionRef =
1443       getTopOfStack().TaskgroupReductionRef;
1444   if (!TaskgroupReductionRef) {
1445     VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1446                                SemaRef.Context.VoidPtrTy, ".task_red.");
1447     TaskgroupReductionRef =
1448         buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1449   }
1450 }
1451 
addTaskgroupReductionData(const ValueDecl * D,SourceRange SR,const Expr * ReductionRef)1452 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR,
1453                                            const Expr *ReductionRef) {
1454   D = getCanonicalDecl(D);
1455   assert(!isStackEmpty() && "Data-sharing attributes stack is empty");
1456   assert(
1457       getTopOfStack().SharingMap[D].Attributes == OMPC_reduction &&
1458       "Additional reduction info may be specified only for reduction items.");
1459   ReductionData &ReductionData = getTopOfStack().ReductionMap[D];
1460   assert(ReductionData.ReductionRange.isInvalid() &&
1461          (getTopOfStack().Directive == OMPD_taskgroup ||
1462           ((isOpenMPParallelDirective(getTopOfStack().Directive) ||
1463             isOpenMPWorksharingDirective(getTopOfStack().Directive)) &&
1464            !isOpenMPSimdDirective(getTopOfStack().Directive))) &&
1465          "Additional reduction info may be specified only once for reduction "
1466          "items.");
1467   ReductionData.set(ReductionRef, SR);
1468   Expr *&TaskgroupReductionRef =
1469       getTopOfStack().TaskgroupReductionRef;
1470   if (!TaskgroupReductionRef) {
1471     VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(),
1472                                SemaRef.Context.VoidPtrTy, ".task_red.");
1473     TaskgroupReductionRef =
1474         buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin());
1475   }
1476 }
1477 
getTopMostTaskgroupReductionData(const ValueDecl * D,SourceRange & SR,BinaryOperatorKind & BOK,Expr * & TaskgroupDescriptor) const1478 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1479     const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK,
1480     Expr *&TaskgroupDescriptor) const {
1481   D = getCanonicalDecl(D);
1482   assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1483   for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1484     const DSAInfo &Data = I->SharingMap.lookup(D);
1485     if (Data.Attributes != OMPC_reduction ||
1486         Data.Modifier != OMPC_REDUCTION_task)
1487       continue;
1488     const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1489     if (!ReductionData.ReductionOp ||
1490         ReductionData.ReductionOp.is<const Expr *>())
1491       return DSAVarData();
1492     SR = ReductionData.ReductionRange;
1493     BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>();
1494     assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1495                                        "expression for the descriptor is not "
1496                                        "set.");
1497     TaskgroupDescriptor = I->TaskgroupReductionRef;
1498     return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1499                       Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1500                       /*AppliedToPointee=*/false);
1501   }
1502   return DSAVarData();
1503 }
1504 
getTopMostTaskgroupReductionData(const ValueDecl * D,SourceRange & SR,const Expr * & ReductionRef,Expr * & TaskgroupDescriptor) const1505 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData(
1506     const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef,
1507     Expr *&TaskgroupDescriptor) const {
1508   D = getCanonicalDecl(D);
1509   assert(!isStackEmpty() && "Data-sharing attributes stack is empty.");
1510   for (const_iterator I = begin() + 1, E = end(); I != E; ++I) {
1511     const DSAInfo &Data = I->SharingMap.lookup(D);
1512     if (Data.Attributes != OMPC_reduction ||
1513         Data.Modifier != OMPC_REDUCTION_task)
1514       continue;
1515     const ReductionData &ReductionData = I->ReductionMap.lookup(D);
1516     if (!ReductionData.ReductionOp ||
1517         !ReductionData.ReductionOp.is<const Expr *>())
1518       return DSAVarData();
1519     SR = ReductionData.ReductionRange;
1520     ReductionRef = ReductionData.ReductionOp.get<const Expr *>();
1521     assert(I->TaskgroupReductionRef && "taskgroup reduction reference "
1522                                        "expression for the descriptor is not "
1523                                        "set.");
1524     TaskgroupDescriptor = I->TaskgroupReductionRef;
1525     return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(),
1526                       Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task,
1527                       /*AppliedToPointee=*/false);
1528   }
1529   return DSAVarData();
1530 }
1531 
isOpenMPLocal(VarDecl * D,const_iterator I) const1532 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const {
1533   D = D->getCanonicalDecl();
1534   for (const_iterator E = end(); I != E; ++I) {
1535     if (isImplicitOrExplicitTaskingRegion(I->Directive) ||
1536         isOpenMPTargetExecutionDirective(I->Directive)) {
1537       if (I->CurScope) {
1538         Scope *TopScope = I->CurScope->getParent();
1539         Scope *CurScope = getCurScope();
1540         while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D))
1541           CurScope = CurScope->getParent();
1542         return CurScope != TopScope;
1543       }
1544       for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent())
1545         if (I->Context == DC)
1546           return true;
1547       return false;
1548     }
1549   }
1550   return false;
1551 }
1552 
isConstNotMutableType(Sema & SemaRef,QualType Type,bool AcceptIfMutable=true,bool * IsClassType=nullptr)1553 static bool isConstNotMutableType(Sema &SemaRef, QualType Type,
1554                                   bool AcceptIfMutable = true,
1555                                   bool *IsClassType = nullptr) {
1556   ASTContext &Context = SemaRef.getASTContext();
1557   Type = Type.getNonReferenceType().getCanonicalType();
1558   bool IsConstant = Type.isConstant(Context);
1559   Type = Context.getBaseElementType(Type);
1560   const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus
1561                                 ? Type->getAsCXXRecordDecl()
1562                                 : nullptr;
1563   if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD))
1564     if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate())
1565       RD = CTD->getTemplatedDecl();
1566   if (IsClassType)
1567     *IsClassType = RD;
1568   return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD &&
1569                          RD->hasDefinition() && RD->hasMutableFields());
1570 }
1571 
rejectConstNotMutableType(Sema & SemaRef,const ValueDecl * D,QualType Type,OpenMPClauseKind CKind,SourceLocation ELoc,bool AcceptIfMutable=true,bool ListItemNotVar=false)1572 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D,
1573                                       QualType Type, OpenMPClauseKind CKind,
1574                                       SourceLocation ELoc,
1575                                       bool AcceptIfMutable = true,
1576                                       bool ListItemNotVar = false) {
1577   ASTContext &Context = SemaRef.getASTContext();
1578   bool IsClassType;
1579   if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) {
1580     unsigned Diag = ListItemNotVar
1581                         ? diag::err_omp_const_list_item
1582                         : IsClassType ? diag::err_omp_const_not_mutable_variable
1583                                       : diag::err_omp_const_variable;
1584     SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind);
1585     if (!ListItemNotVar && D) {
1586       const VarDecl *VD = dyn_cast<VarDecl>(D);
1587       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
1588                                VarDecl::DeclarationOnly;
1589       SemaRef.Diag(D->getLocation(),
1590                    IsDecl ? diag::note_previous_decl : diag::note_defined_here)
1591           << D;
1592     }
1593     return true;
1594   }
1595   return false;
1596 }
1597 
getTopDSA(ValueDecl * D,bool FromParent)1598 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D,
1599                                                    bool FromParent) {
1600   D = getCanonicalDecl(D);
1601   DSAVarData DVar;
1602 
1603   auto *VD = dyn_cast<VarDecl>(D);
1604   auto TI = Threadprivates.find(D);
1605   if (TI != Threadprivates.end()) {
1606     DVar.RefExpr = TI->getSecond().RefExpr.getPointer();
1607     DVar.CKind = OMPC_threadprivate;
1608     DVar.Modifier = TI->getSecond().Modifier;
1609     return DVar;
1610   }
1611   if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) {
1612     DVar.RefExpr = buildDeclRefExpr(
1613         SemaRef, VD, D->getType().getNonReferenceType(),
1614         VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation());
1615     DVar.CKind = OMPC_threadprivate;
1616     addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1617     return DVar;
1618   }
1619   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1620   // in a Construct, C/C++, predetermined, p.1]
1621   //  Variables appearing in threadprivate directives are threadprivate.
1622   if ((VD && VD->getTLSKind() != VarDecl::TLS_None &&
1623        !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
1624          SemaRef.getLangOpts().OpenMPUseTLS &&
1625          SemaRef.getASTContext().getTargetInfo().isTLSSupported())) ||
1626       (VD && VD->getStorageClass() == SC_Register &&
1627        VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) {
1628     DVar.RefExpr = buildDeclRefExpr(
1629         SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation());
1630     DVar.CKind = OMPC_threadprivate;
1631     addDSA(D, DVar.RefExpr, OMPC_threadprivate);
1632     return DVar;
1633   }
1634   if (SemaRef.getLangOpts().OpenMPCUDAMode && VD &&
1635       VD->isLocalVarDeclOrParm() && !isStackEmpty() &&
1636       !isLoopControlVariable(D).first) {
1637     const_iterator IterTarget =
1638         std::find_if(begin(), end(), [](const SharingMapTy &Data) {
1639           return isOpenMPTargetExecutionDirective(Data.Directive);
1640         });
1641     if (IterTarget != end()) {
1642       const_iterator ParentIterTarget = IterTarget + 1;
1643       for (const_iterator Iter = begin();
1644            Iter != ParentIterTarget; ++Iter) {
1645         if (isOpenMPLocal(VD, Iter)) {
1646           DVar.RefExpr =
1647               buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1648                                D->getLocation());
1649           DVar.CKind = OMPC_threadprivate;
1650           return DVar;
1651         }
1652       }
1653       if (!isClauseParsingMode() || IterTarget != begin()) {
1654         auto DSAIter = IterTarget->SharingMap.find(D);
1655         if (DSAIter != IterTarget->SharingMap.end() &&
1656             isOpenMPPrivate(DSAIter->getSecond().Attributes)) {
1657           DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer();
1658           DVar.CKind = OMPC_threadprivate;
1659           return DVar;
1660         }
1661         const_iterator End = end();
1662         if (!SemaRef.isOpenMPCapturedByRef(
1663                 D, std::distance(ParentIterTarget, End),
1664                 /*OpenMPCaptureLevel=*/0)) {
1665           DVar.RefExpr =
1666               buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(),
1667                                IterTarget->ConstructLoc);
1668           DVar.CKind = OMPC_threadprivate;
1669           return DVar;
1670         }
1671       }
1672     }
1673   }
1674 
1675   if (isStackEmpty())
1676     // Not in OpenMP execution region and top scope was already checked.
1677     return DVar;
1678 
1679   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1680   // in a Construct, C/C++, predetermined, p.4]
1681   //  Static data members are shared.
1682   // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1683   // in a Construct, C/C++, predetermined, p.7]
1684   //  Variables with static storage duration that are declared in a scope
1685   //  inside the construct are shared.
1686   if (VD && VD->isStaticDataMember()) {
1687     // Check for explicitly specified attributes.
1688     const_iterator I = begin();
1689     const_iterator EndI = end();
1690     if (FromParent && I != EndI)
1691       ++I;
1692     if (I != EndI) {
1693       auto It = I->SharingMap.find(D);
1694       if (It != I->SharingMap.end()) {
1695         const DSAInfo &Data = It->getSecond();
1696         DVar.RefExpr = Data.RefExpr.getPointer();
1697         DVar.PrivateCopy = Data.PrivateCopy;
1698         DVar.CKind = Data.Attributes;
1699         DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1700         DVar.DKind = I->Directive;
1701         DVar.Modifier = Data.Modifier;
1702         DVar.AppliedToPointee = Data.AppliedToPointee;
1703         return DVar;
1704       }
1705     }
1706 
1707     DVar.CKind = OMPC_shared;
1708     return DVar;
1709   }
1710 
1711   auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; };
1712   // The predetermined shared attribute for const-qualified types having no
1713   // mutable members was removed after OpenMP 3.1.
1714   if (SemaRef.LangOpts.OpenMP <= 31) {
1715     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
1716     // in a Construct, C/C++, predetermined, p.6]
1717     //  Variables with const qualified type having no mutable member are
1718     //  shared.
1719     if (isConstNotMutableType(SemaRef, D->getType())) {
1720       // Variables with const-qualified type having no mutable member may be
1721       // listed in a firstprivate clause, even if they are static data members.
1722       DSAVarData DVarTemp = hasInnermostDSA(
1723           D,
1724           [](OpenMPClauseKind C, bool) {
1725             return C == OMPC_firstprivate || C == OMPC_shared;
1726           },
1727           MatchesAlways, FromParent);
1728       if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr)
1729         return DVarTemp;
1730 
1731       DVar.CKind = OMPC_shared;
1732       return DVar;
1733     }
1734   }
1735 
1736   // Explicitly specified attributes and local variables with predetermined
1737   // attributes.
1738   const_iterator I = begin();
1739   const_iterator EndI = end();
1740   if (FromParent && I != EndI)
1741     ++I;
1742   if (I == EndI)
1743     return DVar;
1744   auto It = I->SharingMap.find(D);
1745   if (It != I->SharingMap.end()) {
1746     const DSAInfo &Data = It->getSecond();
1747     DVar.RefExpr = Data.RefExpr.getPointer();
1748     DVar.PrivateCopy = Data.PrivateCopy;
1749     DVar.CKind = Data.Attributes;
1750     DVar.ImplicitDSALoc = I->DefaultAttrLoc;
1751     DVar.DKind = I->Directive;
1752     DVar.Modifier = Data.Modifier;
1753     DVar.AppliedToPointee = Data.AppliedToPointee;
1754   }
1755 
1756   return DVar;
1757 }
1758 
getImplicitDSA(ValueDecl * D,bool FromParent) const1759 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1760                                                         bool FromParent) const {
1761   if (isStackEmpty()) {
1762     const_iterator I;
1763     return getDSA(I, D);
1764   }
1765   D = getCanonicalDecl(D);
1766   const_iterator StartI = begin();
1767   const_iterator EndI = end();
1768   if (FromParent && StartI != EndI)
1769     ++StartI;
1770   return getDSA(StartI, D);
1771 }
1772 
getImplicitDSA(ValueDecl * D,unsigned Level) const1773 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D,
1774                                                         unsigned Level) const {
1775   if (getStackSize() <= Level)
1776     return DSAVarData();
1777   D = getCanonicalDecl(D);
1778   const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level);
1779   return getDSA(StartI, D);
1780 }
1781 
1782 const DSAStackTy::DSAVarData
hasDSA(ValueDecl * D,const llvm::function_ref<bool (OpenMPClauseKind,bool)> CPred,const llvm::function_ref<bool (OpenMPDirectiveKind)> DPred,bool FromParent) const1783 DSAStackTy::hasDSA(ValueDecl *D,
1784                    const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1785                    const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1786                    bool FromParent) const {
1787   if (isStackEmpty())
1788     return {};
1789   D = getCanonicalDecl(D);
1790   const_iterator I = begin();
1791   const_iterator EndI = end();
1792   if (FromParent && I != EndI)
1793     ++I;
1794   for (; I != EndI; ++I) {
1795     if (!DPred(I->Directive) &&
1796         !isImplicitOrExplicitTaskingRegion(I->Directive))
1797       continue;
1798     const_iterator NewI = I;
1799     DSAVarData DVar = getDSA(NewI, D);
1800     if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee))
1801       return DVar;
1802   }
1803   return {};
1804 }
1805 
hasInnermostDSA(ValueDecl * D,const llvm::function_ref<bool (OpenMPClauseKind,bool)> CPred,const llvm::function_ref<bool (OpenMPDirectiveKind)> DPred,bool FromParent) const1806 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA(
1807     ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1808     const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1809     bool FromParent) const {
1810   if (isStackEmpty())
1811     return {};
1812   D = getCanonicalDecl(D);
1813   const_iterator StartI = begin();
1814   const_iterator EndI = end();
1815   if (FromParent && StartI != EndI)
1816     ++StartI;
1817   if (StartI == EndI || !DPred(StartI->Directive))
1818     return {};
1819   const_iterator NewI = StartI;
1820   DSAVarData DVar = getDSA(NewI, D);
1821   return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee))
1822              ? DVar
1823              : DSAVarData();
1824 }
1825 
hasExplicitDSA(const ValueDecl * D,const llvm::function_ref<bool (OpenMPClauseKind,bool)> CPred,unsigned Level,bool NotLastprivate) const1826 bool DSAStackTy::hasExplicitDSA(
1827     const ValueDecl *D,
1828     const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred,
1829     unsigned Level, bool NotLastprivate) const {
1830   if (getStackSize() <= Level)
1831     return false;
1832   D = getCanonicalDecl(D);
1833   const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1834   auto I = StackElem.SharingMap.find(D);
1835   if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() &&
1836       CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) &&
1837       (!NotLastprivate || !I->getSecond().RefExpr.getInt()))
1838     return true;
1839   // Check predetermined rules for the loop control variables.
1840   auto LI = StackElem.LCVMap.find(D);
1841   if (LI != StackElem.LCVMap.end())
1842     return CPred(OMPC_private, /*AppliedToPointee=*/false);
1843   return false;
1844 }
1845 
hasExplicitDirective(const llvm::function_ref<bool (OpenMPDirectiveKind)> DPred,unsigned Level) const1846 bool DSAStackTy::hasExplicitDirective(
1847     const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred,
1848     unsigned Level) const {
1849   if (getStackSize() <= Level)
1850     return false;
1851   const SharingMapTy &StackElem = getStackElemAtLevel(Level);
1852   return DPred(StackElem.Directive);
1853 }
1854 
hasDirective(const llvm::function_ref<bool (OpenMPDirectiveKind,const DeclarationNameInfo &,SourceLocation)> DPred,bool FromParent) const1855 bool DSAStackTy::hasDirective(
1856     const llvm::function_ref<bool(OpenMPDirectiveKind,
1857                                   const DeclarationNameInfo &, SourceLocation)>
1858         DPred,
1859     bool FromParent) const {
1860   // We look only in the enclosing region.
1861   size_t Skip = FromParent ? 2 : 1;
1862   for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end();
1863        I != E; ++I) {
1864     if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc))
1865       return true;
1866   }
1867   return false;
1868 }
1869 
InitDataSharingAttributesStack()1870 void Sema::InitDataSharingAttributesStack() {
1871   VarDataSharingAttributesStack = new DSAStackTy(*this);
1872 }
1873 
1874 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack)
1875 
pushOpenMPFunctionRegion()1876 void Sema::pushOpenMPFunctionRegion() {
1877   DSAStack->pushFunction();
1878 }
1879 
popOpenMPFunctionRegion(const FunctionScopeInfo * OldFSI)1880 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) {
1881   DSAStack->popFunction(OldFSI);
1882 }
1883 
isOpenMPDeviceDelayedContext(Sema & S)1884 static bool isOpenMPDeviceDelayedContext(Sema &S) {
1885   assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice &&
1886          "Expected OpenMP device compilation.");
1887   return !S.isInOpenMPTargetExecutionDirective();
1888 }
1889 
1890 namespace {
1891 /// Status of the function emission on the host/device.
1892 enum class FunctionEmissionStatus {
1893   Emitted,
1894   Discarded,
1895   Unknown,
1896 };
1897 } // anonymous namespace
1898 
diagIfOpenMPDeviceCode(SourceLocation Loc,unsigned DiagID,FunctionDecl * FD)1899 Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc,
1900                                                          unsigned DiagID,
1901                                                          FunctionDecl *FD) {
1902   assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice &&
1903          "Expected OpenMP device compilation.");
1904 
1905   SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
1906   if (FD) {
1907     FunctionEmissionStatus FES = getEmissionStatus(FD);
1908     switch (FES) {
1909     case FunctionEmissionStatus::Emitted:
1910       Kind = SemaDiagnosticBuilder::K_Immediate;
1911       break;
1912     case FunctionEmissionStatus::Unknown:
1913       // TODO: We should always delay diagnostics here in case a target
1914       //       region is in a function we do not emit. However, as the
1915       //       current diagnostics are associated with the function containing
1916       //       the target region and we do not emit that one, we would miss out
1917       //       on diagnostics for the target region itself. We need to anchor
1918       //       the diagnostics with the new generated function *or* ensure we
1919       //       emit diagnostics associated with the surrounding function.
1920       Kind = isOpenMPDeviceDelayedContext(*this)
1921                  ? SemaDiagnosticBuilder::K_Deferred
1922                  : SemaDiagnosticBuilder::K_Immediate;
1923       break;
1924     case FunctionEmissionStatus::TemplateDiscarded:
1925     case FunctionEmissionStatus::OMPDiscarded:
1926       Kind = SemaDiagnosticBuilder::K_Nop;
1927       break;
1928     case FunctionEmissionStatus::CUDADiscarded:
1929       llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation");
1930       break;
1931     }
1932   }
1933 
1934   return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this);
1935 }
1936 
diagIfOpenMPHostCode(SourceLocation Loc,unsigned DiagID,FunctionDecl * FD)1937 Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc,
1938                                                        unsigned DiagID,
1939                                                        FunctionDecl *FD) {
1940   assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice &&
1941          "Expected OpenMP host compilation.");
1942 
1943   SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop;
1944   if (FD) {
1945     FunctionEmissionStatus FES = getEmissionStatus(FD);
1946     switch (FES) {
1947     case FunctionEmissionStatus::Emitted:
1948       Kind = SemaDiagnosticBuilder::K_Immediate;
1949       break;
1950     case FunctionEmissionStatus::Unknown:
1951       Kind = SemaDiagnosticBuilder::K_Deferred;
1952       break;
1953     case FunctionEmissionStatus::TemplateDiscarded:
1954     case FunctionEmissionStatus::OMPDiscarded:
1955     case FunctionEmissionStatus::CUDADiscarded:
1956       Kind = SemaDiagnosticBuilder::K_Nop;
1957       break;
1958     }
1959   }
1960 
1961   return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this);
1962 }
1963 
1964 static OpenMPDefaultmapClauseKind
getVariableCategoryFromDecl(const LangOptions & LO,const ValueDecl * VD)1965 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) {
1966   if (LO.OpenMP <= 45) {
1967     if (VD->getType().getNonReferenceType()->isScalarType())
1968       return OMPC_DEFAULTMAP_scalar;
1969     return OMPC_DEFAULTMAP_aggregate;
1970   }
1971   if (VD->getType().getNonReferenceType()->isAnyPointerType())
1972     return OMPC_DEFAULTMAP_pointer;
1973   if (VD->getType().getNonReferenceType()->isScalarType())
1974     return OMPC_DEFAULTMAP_scalar;
1975   return OMPC_DEFAULTMAP_aggregate;
1976 }
1977 
isOpenMPCapturedByRef(const ValueDecl * D,unsigned Level,unsigned OpenMPCaptureLevel) const1978 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level,
1979                                  unsigned OpenMPCaptureLevel) const {
1980   assert(LangOpts.OpenMP && "OpenMP is not allowed");
1981 
1982   ASTContext &Ctx = getASTContext();
1983   bool IsByRef = true;
1984 
1985   // Find the directive that is associated with the provided scope.
1986   D = cast<ValueDecl>(D->getCanonicalDecl());
1987   QualType Ty = D->getType();
1988 
1989   bool IsVariableUsedInMapClause = false;
1990   if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) {
1991     // This table summarizes how a given variable should be passed to the device
1992     // given its type and the clauses where it appears. This table is based on
1993     // the description in OpenMP 4.5 [2.10.4, target Construct] and
1994     // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses].
1995     //
1996     // =========================================================================
1997     // | type |  defaultmap   | pvt | first | is_device_ptr |    map   | res.  |
1998     // |      |(tofrom:scalar)|     |  pvt  |               |          |       |
1999     // =========================================================================
2000     // | scl  |               |     |       |       -       |          | bycopy|
2001     // | scl  |               |  -  |   x   |       -       |     -    | bycopy|
2002     // | scl  |               |  x  |   -   |       -       |     -    | null  |
2003     // | scl  |       x       |     |       |       -       |          | byref |
2004     // | scl  |       x       |  -  |   x   |       -       |     -    | bycopy|
2005     // | scl  |       x       |  x  |   -   |       -       |     -    | null  |
2006     // | scl  |               |  -  |   -   |       -       |     x    | byref |
2007     // | scl  |       x       |  -  |   -   |       -       |     x    | byref |
2008     //
2009     // | agg  |      n.a.     |     |       |       -       |          | byref |
2010     // | agg  |      n.a.     |  -  |   x   |       -       |     -    | byref |
2011     // | agg  |      n.a.     |  x  |   -   |       -       |     -    | null  |
2012     // | agg  |      n.a.     |  -  |   -   |       -       |     x    | byref |
2013     // | agg  |      n.a.     |  -  |   -   |       -       |    x[]   | byref |
2014     //
2015     // | ptr  |      n.a.     |     |       |       -       |          | bycopy|
2016     // | ptr  |      n.a.     |  -  |   x   |       -       |     -    | bycopy|
2017     // | ptr  |      n.a.     |  x  |   -   |       -       |     -    | null  |
2018     // | ptr  |      n.a.     |  -  |   -   |       -       |     x    | byref |
2019     // | ptr  |      n.a.     |  -  |   -   |       -       |    x[]   | bycopy|
2020     // | ptr  |      n.a.     |  -  |   -   |       x       |          | bycopy|
2021     // | ptr  |      n.a.     |  -  |   -   |       x       |     x    | bycopy|
2022     // | ptr  |      n.a.     |  -  |   -   |       x       |    x[]   | bycopy|
2023     // =========================================================================
2024     // Legend:
2025     //  scl - scalar
2026     //  ptr - pointer
2027     //  agg - aggregate
2028     //  x - applies
2029     //  - - invalid in this combination
2030     //  [] - mapped with an array section
2031     //  byref - should be mapped by reference
2032     //  byval - should be mapped by value
2033     //  null - initialize a local variable to null on the device
2034     //
2035     // Observations:
2036     //  - All scalar declarations that show up in a map clause have to be passed
2037     //    by reference, because they may have been mapped in the enclosing data
2038     //    environment.
2039     //  - If the scalar value does not fit the size of uintptr, it has to be
2040     //    passed by reference, regardless the result in the table above.
2041     //  - For pointers mapped by value that have either an implicit map or an
2042     //    array section, the runtime library may pass the NULL value to the
2043     //    device instead of the value passed to it by the compiler.
2044 
2045     if (Ty->isReferenceType())
2046       Ty = Ty->castAs<ReferenceType>()->getPointeeType();
2047 
2048     // Locate map clauses and see if the variable being captured is referred to
2049     // in any of those clauses. Here we only care about variables, not fields,
2050     // because fields are part of aggregates.
2051     bool IsVariableAssociatedWithSection = false;
2052 
2053     DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2054         D, Level,
2055         [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D](
2056             OMPClauseMappableExprCommon::MappableExprComponentListRef
2057                 MapExprComponents,
2058             OpenMPClauseKind WhereFoundClauseKind) {
2059           // Only the map clause information influences how a variable is
2060           // captured. E.g. is_device_ptr does not require changing the default
2061           // behavior.
2062           if (WhereFoundClauseKind != OMPC_map)
2063             return false;
2064 
2065           auto EI = MapExprComponents.rbegin();
2066           auto EE = MapExprComponents.rend();
2067 
2068           assert(EI != EE && "Invalid map expression!");
2069 
2070           if (isa<DeclRefExpr>(EI->getAssociatedExpression()))
2071             IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D;
2072 
2073           ++EI;
2074           if (EI == EE)
2075             return false;
2076 
2077           if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) ||
2078               isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) ||
2079               isa<MemberExpr>(EI->getAssociatedExpression()) ||
2080               isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) {
2081             IsVariableAssociatedWithSection = true;
2082             // There is nothing more we need to know about this variable.
2083             return true;
2084           }
2085 
2086           // Keep looking for more map info.
2087           return false;
2088         });
2089 
2090     if (IsVariableUsedInMapClause) {
2091       // If variable is identified in a map clause it is always captured by
2092       // reference except if it is a pointer that is dereferenced somehow.
2093       IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection);
2094     } else {
2095       // By default, all the data that has a scalar type is mapped by copy
2096       // (except for reduction variables).
2097       // Defaultmap scalar is mutual exclusive to defaultmap pointer
2098       IsByRef = (DSAStack->isForceCaptureByReferenceInTargetExecutable() &&
2099                  !Ty->isAnyPointerType()) ||
2100                 !Ty->isScalarType() ||
2101                 DSAStack->isDefaultmapCapturedByRef(
2102                     Level, getVariableCategoryFromDecl(LangOpts, D)) ||
2103                 DSAStack->hasExplicitDSA(
2104                     D,
2105                     [](OpenMPClauseKind K, bool AppliedToPointee) {
2106                       return K == OMPC_reduction && !AppliedToPointee;
2107                     },
2108                     Level);
2109     }
2110   }
2111 
2112   if (IsByRef && Ty.getNonReferenceType()->isScalarType()) {
2113     IsByRef =
2114         ((IsVariableUsedInMapClause &&
2115           DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) ==
2116               OMPD_target) ||
2117          !(DSAStack->hasExplicitDSA(
2118                D,
2119                [](OpenMPClauseKind K, bool AppliedToPointee) -> bool {
2120                  return K == OMPC_firstprivate ||
2121                         (K == OMPC_reduction && AppliedToPointee);
2122                },
2123                Level, /*NotLastprivate=*/true) ||
2124            DSAStack->isUsesAllocatorsDecl(Level, D))) &&
2125         // If the variable is artificial and must be captured by value - try to
2126         // capture by value.
2127         !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() &&
2128           !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) &&
2129         // If the variable is implicitly firstprivate and scalar - capture by
2130         // copy
2131         !(DSAStack->getDefaultDSA() == DSA_firstprivate &&
2132           !DSAStack->hasExplicitDSA(
2133               D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; },
2134               Level) &&
2135           !DSAStack->isLoopControlVariable(D, Level).first);
2136   }
2137 
2138   // When passing data by copy, we need to make sure it fits the uintptr size
2139   // and alignment, because the runtime library only deals with uintptr types.
2140   // If it does not fit the uintptr size, we need to pass the data by reference
2141   // instead.
2142   if (!IsByRef &&
2143       (Ctx.getTypeSizeInChars(Ty) >
2144            Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) ||
2145        Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) {
2146     IsByRef = true;
2147   }
2148 
2149   return IsByRef;
2150 }
2151 
getOpenMPNestingLevel() const2152 unsigned Sema::getOpenMPNestingLevel() const {
2153   assert(getLangOpts().OpenMP);
2154   return DSAStack->getNestingLevel();
2155 }
2156 
isInOpenMPTargetExecutionDirective() const2157 bool Sema::isInOpenMPTargetExecutionDirective() const {
2158   return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) &&
2159           !DSAStack->isClauseParsingMode()) ||
2160          DSAStack->hasDirective(
2161              [](OpenMPDirectiveKind K, const DeclarationNameInfo &,
2162                 SourceLocation) -> bool {
2163                return isOpenMPTargetExecutionDirective(K);
2164              },
2165              false);
2166 }
2167 
isOpenMPCapturedDecl(ValueDecl * D,bool CheckScopeInfo,unsigned StopAt)2168 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo,
2169                                     unsigned StopAt) {
2170   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2171   D = getCanonicalDecl(D);
2172 
2173   auto *VD = dyn_cast<VarDecl>(D);
2174   // Do not capture constexpr variables.
2175   if (VD && VD->isConstexpr())
2176     return nullptr;
2177 
2178   // If we want to determine whether the variable should be captured from the
2179   // perspective of the current capturing scope, and we've already left all the
2180   // capturing scopes of the top directive on the stack, check from the
2181   // perspective of its parent directive (if any) instead.
2182   DSAStackTy::ParentDirectiveScope InParentDirectiveRAII(
2183       *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete());
2184 
2185   // If we are attempting to capture a global variable in a directive with
2186   // 'target' we return true so that this global is also mapped to the device.
2187   //
2188   if (VD && !VD->hasLocalStorage() &&
2189       (getCurCapturedRegion() || getCurBlock() || getCurLambda())) {
2190     if (isInOpenMPTargetExecutionDirective()) {
2191       DSAStackTy::DSAVarData DVarTop =
2192           DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
2193       if (DVarTop.CKind != OMPC_unknown && DVarTop.RefExpr)
2194         return VD;
2195       // If the declaration is enclosed in a 'declare target' directive,
2196       // then it should not be captured.
2197       //
2198       if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2199         return nullptr;
2200       CapturedRegionScopeInfo *CSI = nullptr;
2201       for (FunctionScopeInfo *FSI : llvm::drop_begin(
2202                llvm::reverse(FunctionScopes),
2203                CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) {
2204         if (!isa<CapturingScopeInfo>(FSI))
2205           return nullptr;
2206         if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2207           if (RSI->CapRegionKind == CR_OpenMP) {
2208             CSI = RSI;
2209             break;
2210           }
2211       }
2212       assert(CSI && "Failed to find CapturedRegionScopeInfo");
2213       SmallVector<OpenMPDirectiveKind, 4> Regions;
2214       getOpenMPCaptureRegions(Regions,
2215                               DSAStack->getDirective(CSI->OpenMPLevel));
2216       if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task)
2217         return VD;
2218     }
2219     if (isInOpenMPDeclareTargetContext()) {
2220       // Try to mark variable as declare target if it is used in capturing
2221       // regions.
2222       if (LangOpts.OpenMP <= 45 &&
2223           !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD))
2224         checkDeclIsAllowedInOpenMPTarget(nullptr, VD);
2225       return nullptr;
2226     }
2227   }
2228 
2229   if (CheckScopeInfo) {
2230     bool OpenMPFound = false;
2231     for (unsigned I = StopAt + 1; I > 0; --I) {
2232       FunctionScopeInfo *FSI = FunctionScopes[I - 1];
2233       if(!isa<CapturingScopeInfo>(FSI))
2234         return nullptr;
2235       if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI))
2236         if (RSI->CapRegionKind == CR_OpenMP) {
2237           OpenMPFound = true;
2238           break;
2239         }
2240     }
2241     if (!OpenMPFound)
2242       return nullptr;
2243   }
2244 
2245   if (DSAStack->getCurrentDirective() != OMPD_unknown &&
2246       (!DSAStack->isClauseParsingMode() ||
2247        DSAStack->getParentDirective() != OMPD_unknown)) {
2248     auto &&Info = DSAStack->isLoopControlVariable(D);
2249     if (Info.first ||
2250         (VD && VD->hasLocalStorage() &&
2251          isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) ||
2252         (VD && DSAStack->isForceVarCapturing()))
2253       return VD ? VD : Info.second;
2254     DSAStackTy::DSAVarData DVarTop =
2255         DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode());
2256     if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) &&
2257         (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee))
2258       return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl());
2259     // Threadprivate variables must not be captured.
2260     if (isOpenMPThreadPrivate(DVarTop.CKind))
2261       return nullptr;
2262     // The variable is not private or it is the variable in the directive with
2263     // default(none) clause and not used in any clause.
2264     DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA(
2265         D,
2266         [](OpenMPClauseKind C, bool AppliedToPointee) {
2267           return isOpenMPPrivate(C) && !AppliedToPointee;
2268         },
2269         [](OpenMPDirectiveKind) { return true; },
2270         DSAStack->isClauseParsingMode());
2271     // Global shared must not be captured.
2272     if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown &&
2273         ((DSAStack->getDefaultDSA() != DSA_none &&
2274           DSAStack->getDefaultDSA() != DSA_firstprivate) ||
2275          DVarTop.CKind == OMPC_shared))
2276       return nullptr;
2277     if (DVarPrivate.CKind != OMPC_unknown ||
2278         (VD && (DSAStack->getDefaultDSA() == DSA_none ||
2279                 DSAStack->getDefaultDSA() == DSA_firstprivate)))
2280       return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl());
2281   }
2282   return nullptr;
2283 }
2284 
adjustOpenMPTargetScopeIndex(unsigned & FunctionScopesIndex,unsigned Level) const2285 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex,
2286                                         unsigned Level) const {
2287   FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2288 }
2289 
startOpenMPLoop()2290 void Sema::startOpenMPLoop() {
2291   assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2292   if (isOpenMPLoopDirective(DSAStack->getCurrentDirective()))
2293     DSAStack->loopInit();
2294 }
2295 
startOpenMPCXXRangeFor()2296 void Sema::startOpenMPCXXRangeFor() {
2297   assert(LangOpts.OpenMP && "OpenMP must be enabled.");
2298   if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2299     DSAStack->resetPossibleLoopCounter();
2300     DSAStack->loopStart();
2301   }
2302 }
2303 
isOpenMPPrivateDecl(ValueDecl * D,unsigned Level,unsigned CapLevel) const2304 OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level,
2305                                            unsigned CapLevel) const {
2306   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2307   if (DSAStack->hasExplicitDirective(
2308           [](OpenMPDirectiveKind K) { return isOpenMPTaskingDirective(K); },
2309           Level)) {
2310     bool IsTriviallyCopyable =
2311         D->getType().getNonReferenceType().isTriviallyCopyableType(Context) &&
2312         !D->getType()
2313              .getNonReferenceType()
2314              .getCanonicalType()
2315              ->getAsCXXRecordDecl();
2316     OpenMPDirectiveKind DKind = DSAStack->getDirective(Level);
2317     SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
2318     getOpenMPCaptureRegions(CaptureRegions, DKind);
2319     if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) &&
2320         (IsTriviallyCopyable ||
2321          !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) {
2322       if (DSAStack->hasExplicitDSA(
2323               D,
2324               [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; },
2325               Level, /*NotLastprivate=*/true))
2326         return OMPC_firstprivate;
2327       DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2328       if (DVar.CKind != OMPC_shared &&
2329           !DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) {
2330         DSAStack->addImplicitTaskFirstprivate(Level, D);
2331         return OMPC_firstprivate;
2332       }
2333     }
2334   }
2335   if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
2336     if (DSAStack->getAssociatedLoops() > 0 &&
2337         !DSAStack->isLoopStarted()) {
2338       DSAStack->resetPossibleLoopCounter(D);
2339       DSAStack->loopStart();
2340       return OMPC_private;
2341     }
2342     if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() ||
2343          DSAStack->isLoopControlVariable(D).first) &&
2344         !DSAStack->hasExplicitDSA(
2345             D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; },
2346             Level) &&
2347         !isOpenMPSimdDirective(DSAStack->getCurrentDirective()))
2348       return OMPC_private;
2349   }
2350   if (const auto *VD = dyn_cast<VarDecl>(D)) {
2351     if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) &&
2352         DSAStack->isForceVarCapturing() &&
2353         !DSAStack->hasExplicitDSA(
2354             D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; },
2355             Level))
2356       return OMPC_private;
2357   }
2358   // User-defined allocators are private since they must be defined in the
2359   // context of target region.
2360   if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) &&
2361       DSAStack->isUsesAllocatorsDecl(Level, D).getValueOr(
2362           DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
2363           DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator)
2364     return OMPC_private;
2365   return (DSAStack->hasExplicitDSA(
2366               D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; },
2367               Level) ||
2368           (DSAStack->isClauseParsingMode() &&
2369            DSAStack->getClauseParsingMode() == OMPC_private) ||
2370           // Consider taskgroup reduction descriptor variable a private
2371           // to avoid possible capture in the region.
2372           (DSAStack->hasExplicitDirective(
2373                [](OpenMPDirectiveKind K) {
2374                  return K == OMPD_taskgroup ||
2375                         ((isOpenMPParallelDirective(K) ||
2376                           isOpenMPWorksharingDirective(K)) &&
2377                          !isOpenMPSimdDirective(K));
2378                },
2379                Level) &&
2380            DSAStack->isTaskgroupReductionRef(D, Level)))
2381              ? OMPC_private
2382              : OMPC_unknown;
2383 }
2384 
setOpenMPCaptureKind(FieldDecl * FD,const ValueDecl * D,unsigned Level)2385 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D,
2386                                 unsigned Level) {
2387   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2388   D = getCanonicalDecl(D);
2389   OpenMPClauseKind OMPC = OMPC_unknown;
2390   for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) {
2391     const unsigned NewLevel = I - 1;
2392     if (DSAStack->hasExplicitDSA(
2393             D,
2394             [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) {
2395               if (isOpenMPPrivate(K) && !AppliedToPointee) {
2396                 OMPC = K;
2397                 return true;
2398               }
2399               return false;
2400             },
2401             NewLevel))
2402       break;
2403     if (DSAStack->checkMappableExprComponentListsForDeclAtLevel(
2404             D, NewLevel,
2405             [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
2406                OpenMPClauseKind) { return true; })) {
2407       OMPC = OMPC_map;
2408       break;
2409     }
2410     if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2411                                        NewLevel)) {
2412       OMPC = OMPC_map;
2413       if (DSAStack->mustBeFirstprivateAtLevel(
2414               NewLevel, getVariableCategoryFromDecl(LangOpts, D)))
2415         OMPC = OMPC_firstprivate;
2416       break;
2417     }
2418   }
2419   if (OMPC != OMPC_unknown)
2420     FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC)));
2421 }
2422 
isOpenMPTargetCapturedDecl(const ValueDecl * D,unsigned Level,unsigned CaptureLevel) const2423 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level,
2424                                       unsigned CaptureLevel) const {
2425   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2426   // Return true if the current level is no longer enclosed in a target region.
2427 
2428   SmallVector<OpenMPDirectiveKind, 4> Regions;
2429   getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level));
2430   const auto *VD = dyn_cast<VarDecl>(D);
2431   return VD && !VD->hasLocalStorage() &&
2432          DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective,
2433                                         Level) &&
2434          Regions[CaptureLevel] != OMPD_task;
2435 }
2436 
isOpenMPGlobalCapturedDecl(ValueDecl * D,unsigned Level,unsigned CaptureLevel) const2437 bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level,
2438                                       unsigned CaptureLevel) const {
2439   assert(LangOpts.OpenMP && "OpenMP is not allowed");
2440   // Return true if the current level is no longer enclosed in a target region.
2441 
2442   if (const auto *VD = dyn_cast<VarDecl>(D)) {
2443     if (!VD->hasLocalStorage()) {
2444       if (isInOpenMPTargetExecutionDirective())
2445         return true;
2446       DSAStackTy::DSAVarData TopDVar =
2447           DSAStack->getTopDSA(D, /*FromParent=*/false);
2448       unsigned NumLevels =
2449           getOpenMPCaptureLevels(DSAStack->getDirective(Level));
2450       if (Level == 0)
2451         return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared;
2452       do {
2453         --Level;
2454         DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level);
2455         if (DVar.CKind != OMPC_shared)
2456           return true;
2457       } while (Level > 0);
2458     }
2459   }
2460   return true;
2461 }
2462 
DestroyDataSharingAttributesStack()2463 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; }
2464 
ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,OMPTraitInfo & TI)2465 void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc,
2466                                           OMPTraitInfo &TI) {
2467   OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI));
2468 }
2469 
ActOnOpenMPEndDeclareVariant()2470 void Sema::ActOnOpenMPEndDeclareVariant() {
2471   assert(isInOpenMPDeclareVariantScope() &&
2472          "Not in OpenMP declare variant scope!");
2473 
2474   OMPDeclareVariantScopes.pop_back();
2475 }
2476 
finalizeOpenMPDelayedAnalysis(const FunctionDecl * Caller,const FunctionDecl * Callee,SourceLocation Loc)2477 void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller,
2478                                          const FunctionDecl *Callee,
2479                                          SourceLocation Loc) {
2480   assert(LangOpts.OpenMP && "Expected OpenMP compilation mode.");
2481   Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy =
2482       OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl());
2483   // Ignore host functions during device analyzis.
2484   if (LangOpts.OpenMPIsDevice &&
2485       (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host))
2486     return;
2487   // Ignore nohost functions during host analyzis.
2488   if (!LangOpts.OpenMPIsDevice && DevTy &&
2489       *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost)
2490     return;
2491   const FunctionDecl *FD = Callee->getMostRecentDecl();
2492   DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD);
2493   if (LangOpts.OpenMPIsDevice && DevTy &&
2494       *DevTy == OMPDeclareTargetDeclAttr::DT_Host) {
2495     // Diagnose host function called during device codegen.
2496     StringRef HostDevTy =
2497         getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host);
2498     Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0;
2499     Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2500          diag::note_omp_marked_device_type_here)
2501         << HostDevTy;
2502     return;
2503   }
2504       if (!LangOpts.OpenMPIsDevice && DevTy &&
2505           *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) {
2506         // Diagnose nohost function called during host codegen.
2507         StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName(
2508             OMPC_device_type, OMPC_DEVICE_TYPE_nohost);
2509         Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1;
2510         Diag(*OMPDeclareTargetDeclAttr::getLocation(FD),
2511              diag::note_omp_marked_device_type_here)
2512             << NoHostDevTy;
2513       }
2514 }
2515 
StartOpenMPDSABlock(OpenMPDirectiveKind DKind,const DeclarationNameInfo & DirName,Scope * CurScope,SourceLocation Loc)2516 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind,
2517                                const DeclarationNameInfo &DirName,
2518                                Scope *CurScope, SourceLocation Loc) {
2519   DSAStack->push(DKind, DirName, CurScope, Loc);
2520   PushExpressionEvaluationContext(
2521       ExpressionEvaluationContext::PotentiallyEvaluated);
2522 }
2523 
StartOpenMPClause(OpenMPClauseKind K)2524 void Sema::StartOpenMPClause(OpenMPClauseKind K) {
2525   DSAStack->setClauseParsingMode(K);
2526 }
2527 
EndOpenMPClause()2528 void Sema::EndOpenMPClause() {
2529   DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown);
2530   CleanupVarDeclMarking();
2531 }
2532 
2533 static std::pair<ValueDecl *, bool>
2534 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc,
2535                SourceRange &ERange, bool AllowArraySection = false);
2536 
2537 /// Check consistency of the reduction clauses.
checkReductionClauses(Sema & S,DSAStackTy * Stack,ArrayRef<OMPClause * > Clauses)2538 static void checkReductionClauses(Sema &S, DSAStackTy *Stack,
2539                                   ArrayRef<OMPClause *> Clauses) {
2540   bool InscanFound = false;
2541   SourceLocation InscanLoc;
2542   // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions.
2543   // A reduction clause without the inscan reduction-modifier may not appear on
2544   // a construct on which a reduction clause with the inscan reduction-modifier
2545   // appears.
2546   for (OMPClause *C : Clauses) {
2547     if (C->getClauseKind() != OMPC_reduction)
2548       continue;
2549     auto *RC = cast<OMPReductionClause>(C);
2550     if (RC->getModifier() == OMPC_REDUCTION_inscan) {
2551       InscanFound = true;
2552       InscanLoc = RC->getModifierLoc();
2553       continue;
2554     }
2555     if (RC->getModifier() == OMPC_REDUCTION_task) {
2556       // OpenMP 5.0, 2.19.5.4 reduction Clause.
2557       // A reduction clause with the task reduction-modifier may only appear on
2558       // a parallel construct, a worksharing construct or a combined or
2559       // composite construct for which any of the aforementioned constructs is a
2560       // constituent construct and simd or loop are not constituent constructs.
2561       OpenMPDirectiveKind CurDir = Stack->getCurrentDirective();
2562       if (!(isOpenMPParallelDirective(CurDir) ||
2563             isOpenMPWorksharingDirective(CurDir)) ||
2564           isOpenMPSimdDirective(CurDir))
2565         S.Diag(RC->getModifierLoc(),
2566                diag::err_omp_reduction_task_not_parallel_or_worksharing);
2567       continue;
2568     }
2569   }
2570   if (InscanFound) {
2571     for (OMPClause *C : Clauses) {
2572       if (C->getClauseKind() != OMPC_reduction)
2573         continue;
2574       auto *RC = cast<OMPReductionClause>(C);
2575       if (RC->getModifier() != OMPC_REDUCTION_inscan) {
2576         S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown
2577                    ? RC->getBeginLoc()
2578                    : RC->getModifierLoc(),
2579                diag::err_omp_inscan_reduction_expected);
2580         S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction);
2581         continue;
2582       }
2583       for (Expr *Ref : RC->varlists()) {
2584         assert(Ref && "NULL expr in OpenMP nontemporal clause.");
2585         SourceLocation ELoc;
2586         SourceRange ERange;
2587         Expr *SimpleRefExpr = Ref;
2588         auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
2589                                   /*AllowArraySection=*/true);
2590         ValueDecl *D = Res.first;
2591         if (!D)
2592           continue;
2593         if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) {
2594           S.Diag(Ref->getExprLoc(),
2595                  diag::err_omp_reduction_not_inclusive_exclusive)
2596               << Ref->getSourceRange();
2597         }
2598       }
2599     }
2600   }
2601 }
2602 
2603 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
2604                                  ArrayRef<OMPClause *> Clauses);
2605 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
2606                                  bool WithInit);
2607 
2608 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
2609                               const ValueDecl *D,
2610                               const DSAStackTy::DSAVarData &DVar,
2611                               bool IsLoopIterVar = false);
2612 
EndOpenMPDSABlock(Stmt * CurDirective)2613 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) {
2614   // OpenMP [2.14.3.5, Restrictions, C/C++, p.1]
2615   //  A variable of class type (or array thereof) that appears in a lastprivate
2616   //  clause requires an accessible, unambiguous default constructor for the
2617   //  class type, unless the list item is also specified in a firstprivate
2618   //  clause.
2619   if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) {
2620     for (OMPClause *C : D->clauses()) {
2621       if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) {
2622         SmallVector<Expr *, 8> PrivateCopies;
2623         for (Expr *DE : Clause->varlists()) {
2624           if (DE->isValueDependent() || DE->isTypeDependent()) {
2625             PrivateCopies.push_back(nullptr);
2626             continue;
2627           }
2628           auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens());
2629           auto *VD = cast<VarDecl>(DRE->getDecl());
2630           QualType Type = VD->getType().getNonReferenceType();
2631           const DSAStackTy::DSAVarData DVar =
2632               DSAStack->getTopDSA(VD, /*FromParent=*/false);
2633           if (DVar.CKind == OMPC_lastprivate) {
2634             // Generate helper private variable and initialize it with the
2635             // default value. The address of the original variable is replaced
2636             // by the address of the new private variable in CodeGen. This new
2637             // variable is not added to IdResolver, so the code in the OpenMP
2638             // region uses original variable for proper diagnostics.
2639             VarDecl *VDPrivate = buildVarDecl(
2640                 *this, DE->getExprLoc(), Type.getUnqualifiedType(),
2641                 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE);
2642             ActOnUninitializedDecl(VDPrivate);
2643             if (VDPrivate->isInvalidDecl()) {
2644               PrivateCopies.push_back(nullptr);
2645               continue;
2646             }
2647             PrivateCopies.push_back(buildDeclRefExpr(
2648                 *this, VDPrivate, DE->getType(), DE->getExprLoc()));
2649           } else {
2650             // The variable is also a firstprivate, so initialization sequence
2651             // for private copy is generated already.
2652             PrivateCopies.push_back(nullptr);
2653           }
2654         }
2655         Clause->setPrivateCopies(PrivateCopies);
2656         continue;
2657       }
2658       // Finalize nontemporal clause by handling private copies, if any.
2659       if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) {
2660         SmallVector<Expr *, 8> PrivateRefs;
2661         for (Expr *RefExpr : Clause->varlists()) {
2662           assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
2663           SourceLocation ELoc;
2664           SourceRange ERange;
2665           Expr *SimpleRefExpr = RefExpr;
2666           auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
2667           if (Res.second)
2668             // It will be analyzed later.
2669             PrivateRefs.push_back(RefExpr);
2670           ValueDecl *D = Res.first;
2671           if (!D)
2672             continue;
2673 
2674           const DSAStackTy::DSAVarData DVar =
2675               DSAStack->getTopDSA(D, /*FromParent=*/false);
2676           PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy
2677                                                  : SimpleRefExpr);
2678         }
2679         Clause->setPrivateRefs(PrivateRefs);
2680         continue;
2681       }
2682       if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) {
2683         for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) {
2684           OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I);
2685           auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts());
2686           if (!DRE)
2687             continue;
2688           ValueDecl *VD = DRE->getDecl();
2689           if (!VD || !isa<VarDecl>(VD))
2690             continue;
2691           DSAStackTy::DSAVarData DVar =
2692               DSAStack->getTopDSA(VD, /*FromParent=*/false);
2693           // OpenMP [2.12.5, target Construct]
2694           // Memory allocators that appear in a uses_allocators clause cannot
2695           // appear in other data-sharing attribute clauses or data-mapping
2696           // attribute clauses in the same construct.
2697           Expr *MapExpr = nullptr;
2698           if (DVar.RefExpr ||
2699               DSAStack->checkMappableExprComponentListsForDecl(
2700                   VD, /*CurrentRegionOnly=*/true,
2701                   [VD, &MapExpr](
2702                       OMPClauseMappableExprCommon::MappableExprComponentListRef
2703                           MapExprComponents,
2704                       OpenMPClauseKind C) {
2705                     auto MI = MapExprComponents.rbegin();
2706                     auto ME = MapExprComponents.rend();
2707                     if (MI != ME &&
2708                         MI->getAssociatedDeclaration()->getCanonicalDecl() ==
2709                             VD->getCanonicalDecl()) {
2710                       MapExpr = MI->getAssociatedExpression();
2711                       return true;
2712                     }
2713                     return false;
2714                   })) {
2715             Diag(D.Allocator->getExprLoc(),
2716                  diag::err_omp_allocator_used_in_clauses)
2717                 << D.Allocator->getSourceRange();
2718             if (DVar.RefExpr)
2719               reportOriginalDsa(*this, DSAStack, VD, DVar);
2720             else
2721               Diag(MapExpr->getExprLoc(), diag::note_used_here)
2722                   << MapExpr->getSourceRange();
2723           }
2724         }
2725         continue;
2726       }
2727     }
2728     // Check allocate clauses.
2729     if (!CurContext->isDependentContext())
2730       checkAllocateClauses(*this, DSAStack, D->clauses());
2731     checkReductionClauses(*this, DSAStack, D->clauses());
2732   }
2733 
2734   DSAStack->pop();
2735   DiscardCleanupsInEvaluationContext();
2736   PopExpressionEvaluationContext();
2737 }
2738 
2739 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
2740                                      Expr *NumIterations, Sema &SemaRef,
2741                                      Scope *S, DSAStackTy *Stack);
2742 
2743 namespace {
2744 
2745 class VarDeclFilterCCC final : public CorrectionCandidateCallback {
2746 private:
2747   Sema &SemaRef;
2748 
2749 public:
VarDeclFilterCCC(Sema & S)2750   explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {}
ValidateCandidate(const TypoCorrection & Candidate)2751   bool ValidateCandidate(const TypoCorrection &Candidate) override {
2752     NamedDecl *ND = Candidate.getCorrectionDecl();
2753     if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) {
2754       return VD->hasGlobalStorage() &&
2755              SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2756                                    SemaRef.getCurScope());
2757     }
2758     return false;
2759   }
2760 
clone()2761   std::unique_ptr<CorrectionCandidateCallback> clone() override {
2762     return std::make_unique<VarDeclFilterCCC>(*this);
2763   }
2764 
2765 };
2766 
2767 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback {
2768 private:
2769   Sema &SemaRef;
2770 
2771 public:
VarOrFuncDeclFilterCCC(Sema & S)2772   explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {}
ValidateCandidate(const TypoCorrection & Candidate)2773   bool ValidateCandidate(const TypoCorrection &Candidate) override {
2774     NamedDecl *ND = Candidate.getCorrectionDecl();
2775     if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) ||
2776                isa<FunctionDecl>(ND))) {
2777       return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(),
2778                                    SemaRef.getCurScope());
2779     }
2780     return false;
2781   }
2782 
clone()2783   std::unique_ptr<CorrectionCandidateCallback> clone() override {
2784     return std::make_unique<VarOrFuncDeclFilterCCC>(*this);
2785   }
2786 };
2787 
2788 } // namespace
2789 
ActOnOpenMPIdExpression(Scope * CurScope,CXXScopeSpec & ScopeSpec,const DeclarationNameInfo & Id,OpenMPDirectiveKind Kind)2790 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope,
2791                                          CXXScopeSpec &ScopeSpec,
2792                                          const DeclarationNameInfo &Id,
2793                                          OpenMPDirectiveKind Kind) {
2794   LookupResult Lookup(*this, Id, LookupOrdinaryName);
2795   LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
2796 
2797   if (Lookup.isAmbiguous())
2798     return ExprError();
2799 
2800   VarDecl *VD;
2801   if (!Lookup.isSingleResult()) {
2802     VarDeclFilterCCC CCC(*this);
2803     if (TypoCorrection Corrected =
2804             CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
2805                         CTK_ErrorRecovery)) {
2806       diagnoseTypo(Corrected,
2807                    PDiag(Lookup.empty()
2808                              ? diag::err_undeclared_var_use_suggest
2809                              : diag::err_omp_expected_var_arg_suggest)
2810                        << Id.getName());
2811       VD = Corrected.getCorrectionDeclAs<VarDecl>();
2812     } else {
2813       Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use
2814                                        : diag::err_omp_expected_var_arg)
2815           << Id.getName();
2816       return ExprError();
2817     }
2818   } else if (!(VD = Lookup.getAsSingle<VarDecl>())) {
2819     Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName();
2820     Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at);
2821     return ExprError();
2822   }
2823   Lookup.suppressDiagnostics();
2824 
2825   // OpenMP [2.9.2, Syntax, C/C++]
2826   //   Variables must be file-scope, namespace-scope, or static block-scope.
2827   if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) {
2828     Diag(Id.getLoc(), diag::err_omp_global_var_arg)
2829         << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal();
2830     bool IsDecl =
2831         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2832     Diag(VD->getLocation(),
2833          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2834         << VD;
2835     return ExprError();
2836   }
2837 
2838   VarDecl *CanonicalVD = VD->getCanonicalDecl();
2839   NamedDecl *ND = CanonicalVD;
2840   // OpenMP [2.9.2, Restrictions, C/C++, p.2]
2841   //   A threadprivate directive for file-scope variables must appear outside
2842   //   any definition or declaration.
2843   if (CanonicalVD->getDeclContext()->isTranslationUnit() &&
2844       !getCurLexicalContext()->isTranslationUnit()) {
2845     Diag(Id.getLoc(), diag::err_omp_var_scope)
2846         << getOpenMPDirectiveName(Kind) << VD;
2847     bool IsDecl =
2848         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2849     Diag(VD->getLocation(),
2850          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2851         << VD;
2852     return ExprError();
2853   }
2854   // OpenMP [2.9.2, Restrictions, C/C++, p.3]
2855   //   A threadprivate directive for static class member variables must appear
2856   //   in the class definition, in the same scope in which the member
2857   //   variables are declared.
2858   if (CanonicalVD->isStaticDataMember() &&
2859       !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) {
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.4]
2870   //   A threadprivate directive for namespace-scope variables must appear
2871   //   outside any definition or declaration other than the namespace
2872   //   definition itself.
2873   if (CanonicalVD->getDeclContext()->isNamespace() &&
2874       (!getCurLexicalContext()->isFileContext() ||
2875        !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) {
2876     Diag(Id.getLoc(), diag::err_omp_var_scope)
2877         << getOpenMPDirectiveName(Kind) << VD;
2878     bool IsDecl =
2879         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2880     Diag(VD->getLocation(),
2881          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2882         << VD;
2883     return ExprError();
2884   }
2885   // OpenMP [2.9.2, Restrictions, C/C++, p.6]
2886   //   A threadprivate directive for static block-scope variables must appear
2887   //   in the scope of the variable and not in a nested scope.
2888   if (CanonicalVD->isLocalVarDecl() && CurScope &&
2889       !isDeclInScope(ND, getCurLexicalContext(), CurScope)) {
2890     Diag(Id.getLoc(), diag::err_omp_var_scope)
2891         << getOpenMPDirectiveName(Kind) << VD;
2892     bool IsDecl =
2893         VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2894     Diag(VD->getLocation(),
2895          IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2896         << VD;
2897     return ExprError();
2898   }
2899 
2900   // OpenMP [2.9.2, Restrictions, C/C++, p.2-6]
2901   //   A threadprivate directive must lexically precede all references to any
2902   //   of the variables in its list.
2903   if (Kind == OMPD_threadprivate && VD->isUsed() &&
2904       !DSAStack->isThreadPrivate(VD)) {
2905     Diag(Id.getLoc(), diag::err_omp_var_used)
2906         << getOpenMPDirectiveName(Kind) << VD;
2907     return ExprError();
2908   }
2909 
2910   QualType ExprType = VD->getType().getNonReferenceType();
2911   return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(),
2912                              SourceLocation(), VD,
2913                              /*RefersToEnclosingVariableOrCapture=*/false,
2914                              Id.getLoc(), ExprType, VK_LValue);
2915 }
2916 
2917 Sema::DeclGroupPtrTy
ActOnOpenMPThreadprivateDirective(SourceLocation Loc,ArrayRef<Expr * > VarList)2918 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc,
2919                                         ArrayRef<Expr *> VarList) {
2920   if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) {
2921     CurContext->addDecl(D);
2922     return DeclGroupPtrTy::make(DeclGroupRef(D));
2923   }
2924   return nullptr;
2925 }
2926 
2927 namespace {
2928 class LocalVarRefChecker final
2929     : public ConstStmtVisitor<LocalVarRefChecker, bool> {
2930   Sema &SemaRef;
2931 
2932 public:
VisitDeclRefExpr(const DeclRefExpr * E)2933   bool VisitDeclRefExpr(const DeclRefExpr *E) {
2934     if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
2935       if (VD->hasLocalStorage()) {
2936         SemaRef.Diag(E->getBeginLoc(),
2937                      diag::err_omp_local_var_in_threadprivate_init)
2938             << E->getSourceRange();
2939         SemaRef.Diag(VD->getLocation(), diag::note_defined_here)
2940             << VD << VD->getSourceRange();
2941         return true;
2942       }
2943     }
2944     return false;
2945   }
VisitStmt(const Stmt * S)2946   bool VisitStmt(const Stmt *S) {
2947     for (const Stmt *Child : S->children()) {
2948       if (Child && Visit(Child))
2949         return true;
2950     }
2951     return false;
2952   }
LocalVarRefChecker(Sema & SemaRef)2953   explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {}
2954 };
2955 } // namespace
2956 
2957 OMPThreadPrivateDecl *
CheckOMPThreadPrivateDecl(SourceLocation Loc,ArrayRef<Expr * > VarList)2958 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) {
2959   SmallVector<Expr *, 8> Vars;
2960   for (Expr *RefExpr : VarList) {
2961     auto *DE = cast<DeclRefExpr>(RefExpr);
2962     auto *VD = cast<VarDecl>(DE->getDecl());
2963     SourceLocation ILoc = DE->getExprLoc();
2964 
2965     // Mark variable as used.
2966     VD->setReferenced();
2967     VD->markUsed(Context);
2968 
2969     QualType QType = VD->getType();
2970     if (QType->isDependentType() || QType->isInstantiationDependentType()) {
2971       // It will be analyzed later.
2972       Vars.push_back(DE);
2973       continue;
2974     }
2975 
2976     // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2977     //   A threadprivate variable must not have an incomplete type.
2978     if (RequireCompleteType(ILoc, VD->getType(),
2979                             diag::err_omp_threadprivate_incomplete_type)) {
2980       continue;
2981     }
2982 
2983     // OpenMP [2.9.2, Restrictions, C/C++, p.10]
2984     //   A threadprivate variable must not have a reference type.
2985     if (VD->getType()->isReferenceType()) {
2986       Diag(ILoc, diag::err_omp_ref_type_arg)
2987           << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType();
2988       bool IsDecl =
2989           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
2990       Diag(VD->getLocation(),
2991            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
2992           << VD;
2993       continue;
2994     }
2995 
2996     // Check if this is a TLS variable. If TLS is not being supported, produce
2997     // the corresponding diagnostic.
2998     if ((VD->getTLSKind() != VarDecl::TLS_None &&
2999          !(VD->hasAttr<OMPThreadPrivateDeclAttr>() &&
3000            getLangOpts().OpenMPUseTLS &&
3001            getASTContext().getTargetInfo().isTLSSupported())) ||
3002         (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3003          !VD->isLocalVarDecl())) {
3004       Diag(ILoc, diag::err_omp_var_thread_local)
3005           << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1);
3006       bool IsDecl =
3007           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
3008       Diag(VD->getLocation(),
3009            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3010           << VD;
3011       continue;
3012     }
3013 
3014     // Check if initial value of threadprivate variable reference variable with
3015     // local storage (it is not supported by runtime).
3016     if (const Expr *Init = VD->getAnyInitializer()) {
3017       LocalVarRefChecker Checker(*this);
3018       if (Checker.Visit(Init))
3019         continue;
3020     }
3021 
3022     Vars.push_back(RefExpr);
3023     DSAStack->addDSA(VD, DE, OMPC_threadprivate);
3024     VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit(
3025         Context, SourceRange(Loc, Loc)));
3026     if (ASTMutationListener *ML = Context.getASTMutationListener())
3027       ML->DeclarationMarkedOpenMPThreadPrivate(VD);
3028   }
3029   OMPThreadPrivateDecl *D = nullptr;
3030   if (!Vars.empty()) {
3031     D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc,
3032                                      Vars);
3033     D->setAccess(AS_public);
3034   }
3035   return D;
3036 }
3037 
3038 static OMPAllocateDeclAttr::AllocatorTypeTy
getAllocatorKind(Sema & S,DSAStackTy * Stack,Expr * Allocator)3039 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) {
3040   if (!Allocator)
3041     return OMPAllocateDeclAttr::OMPNullMemAlloc;
3042   if (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3043       Allocator->isInstantiationDependent() ||
3044       Allocator->containsUnexpandedParameterPack())
3045     return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3046   auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc;
3047   const Expr *AE = Allocator->IgnoreParenImpCasts();
3048   for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
3049     auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
3050     const Expr *DefAllocator = Stack->getAllocator(AllocatorKind);
3051     llvm::FoldingSetNodeID AEId, DAEId;
3052     AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true);
3053     DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true);
3054     if (AEId == DAEId) {
3055       AllocatorKindRes = AllocatorKind;
3056       break;
3057     }
3058   }
3059   return AllocatorKindRes;
3060 }
3061 
checkPreviousOMPAllocateAttribute(Sema & S,DSAStackTy * Stack,Expr * RefExpr,VarDecl * VD,OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,Expr * Allocator)3062 static bool checkPreviousOMPAllocateAttribute(
3063     Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD,
3064     OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) {
3065   if (!VD->hasAttr<OMPAllocateDeclAttr>())
3066     return false;
3067   const auto *A = VD->getAttr<OMPAllocateDeclAttr>();
3068   Expr *PrevAllocator = A->getAllocator();
3069   OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind =
3070       getAllocatorKind(S, Stack, PrevAllocator);
3071   bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind;
3072   if (AllocatorsMatch &&
3073       AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc &&
3074       Allocator && PrevAllocator) {
3075     const Expr *AE = Allocator->IgnoreParenImpCasts();
3076     const Expr *PAE = PrevAllocator->IgnoreParenImpCasts();
3077     llvm::FoldingSetNodeID AEId, PAEId;
3078     AE->Profile(AEId, S.Context, /*Canonical=*/true);
3079     PAE->Profile(PAEId, S.Context, /*Canonical=*/true);
3080     AllocatorsMatch = AEId == PAEId;
3081   }
3082   if (!AllocatorsMatch) {
3083     SmallString<256> AllocatorBuffer;
3084     llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer);
3085     if (Allocator)
3086       Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy());
3087     SmallString<256> PrevAllocatorBuffer;
3088     llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer);
3089     if (PrevAllocator)
3090       PrevAllocator->printPretty(PrevAllocatorStream, nullptr,
3091                                  S.getPrintingPolicy());
3092 
3093     SourceLocation AllocatorLoc =
3094         Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc();
3095     SourceRange AllocatorRange =
3096         Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange();
3097     SourceLocation PrevAllocatorLoc =
3098         PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation();
3099     SourceRange PrevAllocatorRange =
3100         PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange();
3101     S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator)
3102         << (Allocator ? 1 : 0) << AllocatorStream.str()
3103         << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str()
3104         << AllocatorRange;
3105     S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator)
3106         << PrevAllocatorRange;
3107     return true;
3108   }
3109   return false;
3110 }
3111 
3112 static void
applyOMPAllocateAttribute(Sema & S,VarDecl * VD,OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,Expr * Allocator,SourceRange SR)3113 applyOMPAllocateAttribute(Sema &S, VarDecl *VD,
3114                           OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind,
3115                           Expr *Allocator, SourceRange SR) {
3116   if (VD->hasAttr<OMPAllocateDeclAttr>())
3117     return;
3118   if (Allocator &&
3119       (Allocator->isTypeDependent() || Allocator->isValueDependent() ||
3120        Allocator->isInstantiationDependent() ||
3121        Allocator->containsUnexpandedParameterPack()))
3122     return;
3123   auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind,
3124                                                 Allocator, SR);
3125   VD->addAttr(A);
3126   if (ASTMutationListener *ML = S.Context.getASTMutationListener())
3127     ML->DeclarationMarkedOpenMPAllocate(VD, A);
3128 }
3129 
ActOnOpenMPAllocateDirective(SourceLocation Loc,ArrayRef<Expr * > VarList,ArrayRef<OMPClause * > Clauses,DeclContext * Owner)3130 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective(
3131     SourceLocation Loc, ArrayRef<Expr *> VarList,
3132     ArrayRef<OMPClause *> Clauses, DeclContext *Owner) {
3133   assert(Clauses.size() <= 1 && "Expected at most one clause.");
3134   Expr *Allocator = nullptr;
3135   if (Clauses.empty()) {
3136     // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions.
3137     // allocate directives that appear in a target region must specify an
3138     // allocator clause unless a requires directive with the dynamic_allocators
3139     // clause is present in the same compilation unit.
3140     if (LangOpts.OpenMPIsDevice &&
3141         !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
3142       targetDiag(Loc, diag::err_expected_allocator_clause);
3143   } else {
3144     Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator();
3145   }
3146   OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
3147       getAllocatorKind(*this, DSAStack, Allocator);
3148   SmallVector<Expr *, 8> Vars;
3149   for (Expr *RefExpr : VarList) {
3150     auto *DE = cast<DeclRefExpr>(RefExpr);
3151     auto *VD = cast<VarDecl>(DE->getDecl());
3152 
3153     // Check if this is a TLS variable or global register.
3154     if (VD->getTLSKind() != VarDecl::TLS_None ||
3155         VD->hasAttr<OMPThreadPrivateDeclAttr>() ||
3156         (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() &&
3157          !VD->isLocalVarDecl()))
3158       continue;
3159 
3160     // If the used several times in the allocate directive, the same allocator
3161     // must be used.
3162     if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD,
3163                                           AllocatorKind, Allocator))
3164       continue;
3165 
3166     // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++
3167     // If a list item has a static storage type, the allocator expression in the
3168     // allocator clause must be a constant expression that evaluates to one of
3169     // the predefined memory allocator values.
3170     if (Allocator && VD->hasGlobalStorage()) {
3171       if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) {
3172         Diag(Allocator->getExprLoc(),
3173              diag::err_omp_expected_predefined_allocator)
3174             << Allocator->getSourceRange();
3175         bool IsDecl = VD->isThisDeclarationADefinition(Context) ==
3176                       VarDecl::DeclarationOnly;
3177         Diag(VD->getLocation(),
3178              IsDecl ? diag::note_previous_decl : diag::note_defined_here)
3179             << VD;
3180         continue;
3181       }
3182     }
3183 
3184     Vars.push_back(RefExpr);
3185     applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator,
3186                               DE->getSourceRange());
3187   }
3188   if (Vars.empty())
3189     return nullptr;
3190   if (!Owner)
3191     Owner = getCurLexicalContext();
3192   auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses);
3193   D->setAccess(AS_public);
3194   Owner->addDecl(D);
3195   return DeclGroupPtrTy::make(DeclGroupRef(D));
3196 }
3197 
3198 Sema::DeclGroupPtrTy
ActOnOpenMPRequiresDirective(SourceLocation Loc,ArrayRef<OMPClause * > ClauseList)3199 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc,
3200                                    ArrayRef<OMPClause *> ClauseList) {
3201   OMPRequiresDecl *D = nullptr;
3202   if (!CurContext->isFileContext()) {
3203     Diag(Loc, diag::err_omp_invalid_scope) << "requires";
3204   } else {
3205     D = CheckOMPRequiresDecl(Loc, ClauseList);
3206     if (D) {
3207       CurContext->addDecl(D);
3208       DSAStack->addRequiresDecl(D);
3209     }
3210   }
3211   return DeclGroupPtrTy::make(DeclGroupRef(D));
3212 }
3213 
ActOnOpenMPAssumesDirective(SourceLocation Loc,OpenMPDirectiveKind DKind,ArrayRef<StringRef> Assumptions,bool SkippedClauses)3214 void Sema::ActOnOpenMPAssumesDirective(SourceLocation Loc,
3215                                        OpenMPDirectiveKind DKind,
3216                                        ArrayRef<StringRef> Assumptions,
3217                                        bool SkippedClauses) {
3218   if (!SkippedClauses && Assumptions.empty())
3219     Diag(Loc, diag::err_omp_no_clause_for_directive)
3220         << llvm::omp::getAllAssumeClauseOptions()
3221         << llvm::omp::getOpenMPDirectiveName(DKind);
3222 
3223   auto *AA = AssumptionAttr::Create(Context, llvm::join(Assumptions, ","), Loc);
3224   if (DKind == llvm::omp::Directive::OMPD_begin_assumes) {
3225     OMPAssumeScoped.push_back(AA);
3226     return;
3227   }
3228 
3229   // Global assumes without assumption clauses are ignored.
3230   if (Assumptions.empty())
3231     return;
3232 
3233   assert(DKind == llvm::omp::Directive::OMPD_assumes &&
3234          "Unexpected omp assumption directive!");
3235   OMPAssumeGlobal.push_back(AA);
3236 
3237   // The OMPAssumeGlobal scope above will take care of new declarations but
3238   // we also want to apply the assumption to existing ones, e.g., to
3239   // declarations in included headers. To this end, we traverse all existing
3240   // declaration contexts and annotate function declarations here.
3241   SmallVector<DeclContext *, 8> DeclContexts;
3242   auto *Ctx = CurContext;
3243   while (Ctx->getLexicalParent())
3244     Ctx = Ctx->getLexicalParent();
3245   DeclContexts.push_back(Ctx);
3246   while (!DeclContexts.empty()) {
3247     DeclContext *DC = DeclContexts.pop_back_val();
3248     for (auto *SubDC : DC->decls()) {
3249       if (SubDC->isInvalidDecl())
3250         continue;
3251       if (auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) {
3252         DeclContexts.push_back(CTD->getTemplatedDecl());
3253         for (auto *S : CTD->specializations())
3254           DeclContexts.push_back(S);
3255         continue;
3256       }
3257       if (auto *DC = dyn_cast<DeclContext>(SubDC))
3258         DeclContexts.push_back(DC);
3259       if (auto *F = dyn_cast<FunctionDecl>(SubDC)) {
3260         F->addAttr(AA);
3261         continue;
3262       }
3263     }
3264   }
3265 }
3266 
ActOnOpenMPEndAssumesDirective()3267 void Sema::ActOnOpenMPEndAssumesDirective() {
3268   assert(isInOpenMPAssumeScope() && "Not in OpenMP assumes scope!");
3269   OMPAssumeScoped.pop_back();
3270 }
3271 
CheckOMPRequiresDecl(SourceLocation Loc,ArrayRef<OMPClause * > ClauseList)3272 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc,
3273                                             ArrayRef<OMPClause *> ClauseList) {
3274   /// For target specific clauses, the requires directive cannot be
3275   /// specified after the handling of any of the target regions in the
3276   /// current compilation unit.
3277   ArrayRef<SourceLocation> TargetLocations =
3278       DSAStack->getEncounteredTargetLocs();
3279   SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc();
3280   if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) {
3281     for (const OMPClause *CNew : ClauseList) {
3282       // Check if any of the requires clauses affect target regions.
3283       if (isa<OMPUnifiedSharedMemoryClause>(CNew) ||
3284           isa<OMPUnifiedAddressClause>(CNew) ||
3285           isa<OMPReverseOffloadClause>(CNew) ||
3286           isa<OMPDynamicAllocatorsClause>(CNew)) {
3287         Diag(Loc, diag::err_omp_directive_before_requires)
3288             << "target" << getOpenMPClauseName(CNew->getClauseKind());
3289         for (SourceLocation TargetLoc : TargetLocations) {
3290           Diag(TargetLoc, diag::note_omp_requires_encountered_directive)
3291               << "target";
3292         }
3293       } else if (!AtomicLoc.isInvalid() &&
3294                  isa<OMPAtomicDefaultMemOrderClause>(CNew)) {
3295         Diag(Loc, diag::err_omp_directive_before_requires)
3296             << "atomic" << getOpenMPClauseName(CNew->getClauseKind());
3297         Diag(AtomicLoc, diag::note_omp_requires_encountered_directive)
3298             << "atomic";
3299       }
3300     }
3301   }
3302 
3303   if (!DSAStack->hasDuplicateRequiresClause(ClauseList))
3304     return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc,
3305                                    ClauseList);
3306   return nullptr;
3307 }
3308 
reportOriginalDsa(Sema & SemaRef,const DSAStackTy * Stack,const ValueDecl * D,const DSAStackTy::DSAVarData & DVar,bool IsLoopIterVar)3309 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack,
3310                               const ValueDecl *D,
3311                               const DSAStackTy::DSAVarData &DVar,
3312                               bool IsLoopIterVar) {
3313   if (DVar.RefExpr) {
3314     SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa)
3315         << getOpenMPClauseName(DVar.CKind);
3316     return;
3317   }
3318   enum {
3319     PDSA_StaticMemberShared,
3320     PDSA_StaticLocalVarShared,
3321     PDSA_LoopIterVarPrivate,
3322     PDSA_LoopIterVarLinear,
3323     PDSA_LoopIterVarLastprivate,
3324     PDSA_ConstVarShared,
3325     PDSA_GlobalVarShared,
3326     PDSA_TaskVarFirstprivate,
3327     PDSA_LocalVarPrivate,
3328     PDSA_Implicit
3329   } Reason = PDSA_Implicit;
3330   bool ReportHint = false;
3331   auto ReportLoc = D->getLocation();
3332   auto *VD = dyn_cast<VarDecl>(D);
3333   if (IsLoopIterVar) {
3334     if (DVar.CKind == OMPC_private)
3335       Reason = PDSA_LoopIterVarPrivate;
3336     else if (DVar.CKind == OMPC_lastprivate)
3337       Reason = PDSA_LoopIterVarLastprivate;
3338     else
3339       Reason = PDSA_LoopIterVarLinear;
3340   } else if (isOpenMPTaskingDirective(DVar.DKind) &&
3341              DVar.CKind == OMPC_firstprivate) {
3342     Reason = PDSA_TaskVarFirstprivate;
3343     ReportLoc = DVar.ImplicitDSALoc;
3344   } else if (VD && VD->isStaticLocal())
3345     Reason = PDSA_StaticLocalVarShared;
3346   else if (VD && VD->isStaticDataMember())
3347     Reason = PDSA_StaticMemberShared;
3348   else if (VD && VD->isFileVarDecl())
3349     Reason = PDSA_GlobalVarShared;
3350   else if (D->getType().isConstant(SemaRef.getASTContext()))
3351     Reason = PDSA_ConstVarShared;
3352   else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) {
3353     ReportHint = true;
3354     Reason = PDSA_LocalVarPrivate;
3355   }
3356   if (Reason != PDSA_Implicit) {
3357     SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa)
3358         << Reason << ReportHint
3359         << getOpenMPDirectiveName(Stack->getCurrentDirective());
3360   } else if (DVar.ImplicitDSALoc.isValid()) {
3361     SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa)
3362         << getOpenMPClauseName(DVar.CKind);
3363   }
3364 }
3365 
3366 static OpenMPMapClauseKind
getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,bool IsAggregateOrDeclareTarget)3367 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M,
3368                              bool IsAggregateOrDeclareTarget) {
3369   OpenMPMapClauseKind Kind = OMPC_MAP_unknown;
3370   switch (M) {
3371   case OMPC_DEFAULTMAP_MODIFIER_alloc:
3372     Kind = OMPC_MAP_alloc;
3373     break;
3374   case OMPC_DEFAULTMAP_MODIFIER_to:
3375     Kind = OMPC_MAP_to;
3376     break;
3377   case OMPC_DEFAULTMAP_MODIFIER_from:
3378     Kind = OMPC_MAP_from;
3379     break;
3380   case OMPC_DEFAULTMAP_MODIFIER_tofrom:
3381     Kind = OMPC_MAP_tofrom;
3382     break;
3383   case OMPC_DEFAULTMAP_MODIFIER_present:
3384     // OpenMP 5.1 [2.21.7.3] defaultmap clause, Description]
3385     // If implicit-behavior is present, each variable referenced in the
3386     // construct in the category specified by variable-category is treated as if
3387     // it had been listed in a map clause with the map-type of alloc and
3388     // map-type-modifier of present.
3389     Kind = OMPC_MAP_alloc;
3390     break;
3391   case OMPC_DEFAULTMAP_MODIFIER_firstprivate:
3392   case OMPC_DEFAULTMAP_MODIFIER_last:
3393     llvm_unreachable("Unexpected defaultmap implicit behavior");
3394   case OMPC_DEFAULTMAP_MODIFIER_none:
3395   case OMPC_DEFAULTMAP_MODIFIER_default:
3396   case OMPC_DEFAULTMAP_MODIFIER_unknown:
3397     // IsAggregateOrDeclareTarget could be true if:
3398     // 1. the implicit behavior for aggregate is tofrom
3399     // 2. it's a declare target link
3400     if (IsAggregateOrDeclareTarget) {
3401       Kind = OMPC_MAP_tofrom;
3402       break;
3403     }
3404     llvm_unreachable("Unexpected defaultmap implicit behavior");
3405   }
3406   assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known");
3407   return Kind;
3408 }
3409 
3410 namespace {
3411 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> {
3412   DSAStackTy *Stack;
3413   Sema &SemaRef;
3414   bool ErrorFound = false;
3415   bool TryCaptureCXXThisMembers = false;
3416   CapturedStmt *CS = nullptr;
3417   const static unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
3418   llvm::SmallVector<Expr *, 4> ImplicitFirstprivate;
3419   llvm::SmallVector<Expr *, 4> ImplicitMap[DefaultmapKindNum][OMPC_MAP_delete];
3420   llvm::SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
3421       ImplicitMapModifier[DefaultmapKindNum];
3422   Sema::VarsWithInheritedDSAType VarsWithInheritedDSA;
3423   llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations;
3424 
VisitSubCaptures(OMPExecutableDirective * S)3425   void VisitSubCaptures(OMPExecutableDirective *S) {
3426     // Check implicitly captured variables.
3427     if (!S->hasAssociatedStmt() || !S->getAssociatedStmt())
3428       return;
3429     if (S->getDirectiveKind() == OMPD_atomic ||
3430         S->getDirectiveKind() == OMPD_critical ||
3431         S->getDirectiveKind() == OMPD_section ||
3432         S->getDirectiveKind() == OMPD_master ||
3433         S->getDirectiveKind() == OMPD_masked ||
3434         isOpenMPLoopTransformationDirective(S->getDirectiveKind())) {
3435       Visit(S->getAssociatedStmt());
3436       return;
3437     }
3438     visitSubCaptures(S->getInnermostCapturedStmt());
3439     // Try to capture inner this->member references to generate correct mappings
3440     // and diagnostics.
3441     if (TryCaptureCXXThisMembers ||
3442         (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3443          llvm::any_of(S->getInnermostCapturedStmt()->captures(),
3444                       [](const CapturedStmt::Capture &C) {
3445                         return C.capturesThis();
3446                       }))) {
3447       bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers;
3448       TryCaptureCXXThisMembers = true;
3449       Visit(S->getInnermostCapturedStmt()->getCapturedStmt());
3450       TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers;
3451     }
3452     // In tasks firstprivates are not captured anymore, need to analyze them
3453     // explicitly.
3454     if (isOpenMPTaskingDirective(S->getDirectiveKind()) &&
3455         !isOpenMPTaskLoopDirective(S->getDirectiveKind())) {
3456       for (OMPClause *C : S->clauses())
3457         if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) {
3458           for (Expr *Ref : FC->varlists())
3459             Visit(Ref);
3460         }
3461     }
3462   }
3463 
3464 public:
VisitDeclRefExpr(DeclRefExpr * E)3465   void VisitDeclRefExpr(DeclRefExpr *E) {
3466     if (TryCaptureCXXThisMembers || E->isTypeDependent() ||
3467         E->isValueDependent() || E->containsUnexpandedParameterPack() ||
3468         E->isInstantiationDependent())
3469       return;
3470     if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
3471       // Check the datasharing rules for the expressions in the clauses.
3472       if (!CS) {
3473         if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD))
3474           if (!CED->hasAttr<OMPCaptureNoInitAttr>()) {
3475             Visit(CED->getInit());
3476             return;
3477           }
3478       } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD))
3479         // Do not analyze internal variables and do not enclose them into
3480         // implicit clauses.
3481         return;
3482       VD = VD->getCanonicalDecl();
3483       // Skip internally declared variables.
3484       if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) &&
3485           !Stack->isImplicitTaskFirstprivate(VD))
3486         return;
3487       // Skip allocators in uses_allocators clauses.
3488       if (Stack->isUsesAllocatorsDecl(VD).hasValue())
3489         return;
3490 
3491       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
3492       // Check if the variable has explicit DSA set and stop analysis if it so.
3493       if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second)
3494         return;
3495 
3496       // Skip internally declared static variables.
3497       llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
3498           OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
3499       if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) &&
3500           (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
3501            !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) &&
3502           !Stack->isImplicitTaskFirstprivate(VD))
3503         return;
3504 
3505       SourceLocation ELoc = E->getExprLoc();
3506       OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3507       // The default(none) clause requires that each variable that is referenced
3508       // in the construct, and does not have a predetermined data-sharing
3509       // attribute, must have its data-sharing attribute explicitly determined
3510       // by being listed in a data-sharing attribute clause.
3511       if (DVar.CKind == OMPC_unknown &&
3512           (Stack->getDefaultDSA() == DSA_none ||
3513            Stack->getDefaultDSA() == DSA_firstprivate) &&
3514           isImplicitOrExplicitTaskingRegion(DKind) &&
3515           VarsWithInheritedDSA.count(VD) == 0) {
3516         bool InheritedDSA = Stack->getDefaultDSA() == DSA_none;
3517         if (!InheritedDSA && Stack->getDefaultDSA() == DSA_firstprivate) {
3518           DSAStackTy::DSAVarData DVar =
3519               Stack->getImplicitDSA(VD, /*FromParent=*/false);
3520           InheritedDSA = DVar.CKind == OMPC_unknown;
3521         }
3522         if (InheritedDSA)
3523           VarsWithInheritedDSA[VD] = E;
3524         return;
3525       }
3526 
3527       // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description]
3528       // If implicit-behavior is none, each variable referenced in the
3529       // construct that does not have a predetermined data-sharing attribute
3530       // and does not appear in a to or link clause on a declare target
3531       // directive must be listed in a data-mapping attribute clause, a
3532       // data-haring attribute clause (including a data-sharing attribute
3533       // clause on a combined construct where target. is one of the
3534       // constituent constructs), or an is_device_ptr clause.
3535       OpenMPDefaultmapClauseKind ClauseKind =
3536           getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD);
3537       if (SemaRef.getLangOpts().OpenMP >= 50) {
3538         bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) ==
3539                               OMPC_DEFAULTMAP_MODIFIER_none;
3540         if (DVar.CKind == OMPC_unknown && IsModifierNone &&
3541             VarsWithInheritedDSA.count(VD) == 0 && !Res) {
3542           // Only check for data-mapping attribute and is_device_ptr here
3543           // since we have already make sure that the declaration does not
3544           // have a data-sharing attribute above
3545           if (!Stack->checkMappableExprComponentListsForDecl(
3546                   VD, /*CurrentRegionOnly=*/true,
3547                   [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef
3548                            MapExprComponents,
3549                        OpenMPClauseKind) {
3550                     auto MI = MapExprComponents.rbegin();
3551                     auto ME = MapExprComponents.rend();
3552                     return MI != ME && MI->getAssociatedDeclaration() == VD;
3553                   })) {
3554             VarsWithInheritedDSA[VD] = E;
3555             return;
3556           }
3557         }
3558       }
3559       if (SemaRef.getLangOpts().OpenMP > 50) {
3560         bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) ==
3561                                  OMPC_DEFAULTMAP_MODIFIER_present;
3562         if (IsModifierPresent) {
3563           if (llvm::find(ImplicitMapModifier[ClauseKind],
3564                          OMPC_MAP_MODIFIER_present) ==
3565               std::end(ImplicitMapModifier[ClauseKind])) {
3566             ImplicitMapModifier[ClauseKind].push_back(
3567                 OMPC_MAP_MODIFIER_present);
3568           }
3569         }
3570       }
3571 
3572       if (isOpenMPTargetExecutionDirective(DKind) &&
3573           !Stack->isLoopControlVariable(VD).first) {
3574         if (!Stack->checkMappableExprComponentListsForDecl(
3575                 VD, /*CurrentRegionOnly=*/true,
3576                 [this](OMPClauseMappableExprCommon::MappableExprComponentListRef
3577                            StackComponents,
3578                        OpenMPClauseKind) {
3579                   if (SemaRef.LangOpts.OpenMP >= 50)
3580                     return !StackComponents.empty();
3581                   // Variable is used if it has been marked as an array, array
3582                   // section, array shaping or the variable iself.
3583                   return StackComponents.size() == 1 ||
3584                          std::all_of(
3585                              std::next(StackComponents.rbegin()),
3586                              StackComponents.rend(),
3587                              [](const OMPClauseMappableExprCommon::
3588                                     MappableComponent &MC) {
3589                                return MC.getAssociatedDeclaration() ==
3590                                           nullptr &&
3591                                       (isa<OMPArraySectionExpr>(
3592                                            MC.getAssociatedExpression()) ||
3593                                        isa<OMPArrayShapingExpr>(
3594                                            MC.getAssociatedExpression()) ||
3595                                        isa<ArraySubscriptExpr>(
3596                                            MC.getAssociatedExpression()));
3597                              });
3598                 })) {
3599           bool IsFirstprivate = false;
3600           // By default lambdas are captured as firstprivates.
3601           if (const auto *RD =
3602                   VD->getType().getNonReferenceType()->getAsCXXRecordDecl())
3603             IsFirstprivate = RD->isLambda();
3604           IsFirstprivate =
3605               IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res);
3606           if (IsFirstprivate) {
3607             ImplicitFirstprivate.emplace_back(E);
3608           } else {
3609             OpenMPDefaultmapClauseModifier M =
3610                 Stack->getDefaultmapModifier(ClauseKind);
3611             OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3612                 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res);
3613             ImplicitMap[ClauseKind][Kind].emplace_back(E);
3614           }
3615           return;
3616         }
3617       }
3618 
3619       // OpenMP [2.9.3.6, Restrictions, p.2]
3620       //  A list item that appears in a reduction clause of the innermost
3621       //  enclosing worksharing or parallel construct may not be accessed in an
3622       //  explicit task.
3623       DVar = Stack->hasInnermostDSA(
3624           VD,
3625           [](OpenMPClauseKind C, bool AppliedToPointee) {
3626             return C == OMPC_reduction && !AppliedToPointee;
3627           },
3628           [](OpenMPDirectiveKind K) {
3629             return isOpenMPParallelDirective(K) ||
3630                    isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3631           },
3632           /*FromParent=*/true);
3633       if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3634         ErrorFound = true;
3635         SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3636         reportOriginalDsa(SemaRef, Stack, VD, DVar);
3637         return;
3638       }
3639 
3640       // Define implicit data-sharing attributes for task.
3641       DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false);
3642       if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) ||
3643            (Stack->getDefaultDSA() == DSA_firstprivate &&
3644             DVar.CKind == OMPC_firstprivate && !DVar.RefExpr)) &&
3645           !Stack->isLoopControlVariable(VD).first) {
3646         ImplicitFirstprivate.push_back(E);
3647         return;
3648       }
3649 
3650       // Store implicitly used globals with declare target link for parent
3651       // target.
3652       if (!isOpenMPTargetExecutionDirective(DKind) && Res &&
3653           *Res == OMPDeclareTargetDeclAttr::MT_Link) {
3654         Stack->addToParentTargetRegionLinkGlobals(E);
3655         return;
3656       }
3657     }
3658   }
VisitMemberExpr(MemberExpr * E)3659   void VisitMemberExpr(MemberExpr *E) {
3660     if (E->isTypeDependent() || E->isValueDependent() ||
3661         E->containsUnexpandedParameterPack() || E->isInstantiationDependent())
3662       return;
3663     auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
3664     OpenMPDirectiveKind DKind = Stack->getCurrentDirective();
3665     if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) {
3666       if (!FD)
3667         return;
3668       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false);
3669       // Check if the variable has explicit DSA set and stop analysis if it
3670       // so.
3671       if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second)
3672         return;
3673 
3674       if (isOpenMPTargetExecutionDirective(DKind) &&
3675           !Stack->isLoopControlVariable(FD).first &&
3676           !Stack->checkMappableExprComponentListsForDecl(
3677               FD, /*CurrentRegionOnly=*/true,
3678               [](OMPClauseMappableExprCommon::MappableExprComponentListRef
3679                      StackComponents,
3680                  OpenMPClauseKind) {
3681                 return isa<CXXThisExpr>(
3682                     cast<MemberExpr>(
3683                         StackComponents.back().getAssociatedExpression())
3684                         ->getBase()
3685                         ->IgnoreParens());
3686               })) {
3687         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
3688         //  A bit-field cannot appear in a map clause.
3689         //
3690         if (FD->isBitField())
3691           return;
3692 
3693         // Check to see if the member expression is referencing a class that
3694         // has already been explicitly mapped
3695         if (Stack->isClassPreviouslyMapped(TE->getType()))
3696           return;
3697 
3698         OpenMPDefaultmapClauseModifier Modifier =
3699             Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate);
3700         OpenMPDefaultmapClauseKind ClauseKind =
3701             getVariableCategoryFromDecl(SemaRef.getLangOpts(), FD);
3702         OpenMPMapClauseKind Kind = getMapClauseKindFromModifier(
3703             Modifier, /*IsAggregateOrDeclareTarget*/ true);
3704         ImplicitMap[ClauseKind][Kind].emplace_back(E);
3705         return;
3706       }
3707 
3708       SourceLocation ELoc = E->getExprLoc();
3709       // OpenMP [2.9.3.6, Restrictions, p.2]
3710       //  A list item that appears in a reduction clause of the innermost
3711       //  enclosing worksharing or parallel construct may not be accessed in
3712       //  an  explicit task.
3713       DVar = Stack->hasInnermostDSA(
3714           FD,
3715           [](OpenMPClauseKind C, bool AppliedToPointee) {
3716             return C == OMPC_reduction && !AppliedToPointee;
3717           },
3718           [](OpenMPDirectiveKind K) {
3719             return isOpenMPParallelDirective(K) ||
3720                    isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K);
3721           },
3722           /*FromParent=*/true);
3723       if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) {
3724         ErrorFound = true;
3725         SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task);
3726         reportOriginalDsa(SemaRef, Stack, FD, DVar);
3727         return;
3728       }
3729 
3730       // Define implicit data-sharing attributes for task.
3731       DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false);
3732       if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared &&
3733           !Stack->isLoopControlVariable(FD).first) {
3734         // Check if there is a captured expression for the current field in the
3735         // region. Do not mark it as firstprivate unless there is no captured
3736         // expression.
3737         // TODO: try to make it firstprivate.
3738         if (DVar.CKind != OMPC_unknown)
3739           ImplicitFirstprivate.push_back(E);
3740       }
3741       return;
3742     }
3743     if (isOpenMPTargetExecutionDirective(DKind)) {
3744       OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
3745       if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map,
3746                                         Stack->getCurrentDirective(),
3747                                         /*NoDiagnose=*/true))
3748         return;
3749       const auto *VD = cast<ValueDecl>(
3750           CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl());
3751       if (!Stack->checkMappableExprComponentListsForDecl(
3752               VD, /*CurrentRegionOnly=*/true,
3753               [&CurComponents](
3754                   OMPClauseMappableExprCommon::MappableExprComponentListRef
3755                       StackComponents,
3756                   OpenMPClauseKind) {
3757                 auto CCI = CurComponents.rbegin();
3758                 auto CCE = CurComponents.rend();
3759                 for (const auto &SC : llvm::reverse(StackComponents)) {
3760                   // Do both expressions have the same kind?
3761                   if (CCI->getAssociatedExpression()->getStmtClass() !=
3762                       SC.getAssociatedExpression()->getStmtClass())
3763                     if (!((isa<OMPArraySectionExpr>(
3764                                SC.getAssociatedExpression()) ||
3765                            isa<OMPArrayShapingExpr>(
3766                                SC.getAssociatedExpression())) &&
3767                           isa<ArraySubscriptExpr>(
3768                               CCI->getAssociatedExpression())))
3769                       return false;
3770 
3771                   const Decl *CCD = CCI->getAssociatedDeclaration();
3772                   const Decl *SCD = SC.getAssociatedDeclaration();
3773                   CCD = CCD ? CCD->getCanonicalDecl() : nullptr;
3774                   SCD = SCD ? SCD->getCanonicalDecl() : nullptr;
3775                   if (SCD != CCD)
3776                     return false;
3777                   std::advance(CCI, 1);
3778                   if (CCI == CCE)
3779                     break;
3780                 }
3781                 return true;
3782               })) {
3783         Visit(E->getBase());
3784       }
3785     } else if (!TryCaptureCXXThisMembers) {
3786       Visit(E->getBase());
3787     }
3788   }
VisitOMPExecutableDirective(OMPExecutableDirective * S)3789   void VisitOMPExecutableDirective(OMPExecutableDirective *S) {
3790     for (OMPClause *C : S->clauses()) {
3791       // Skip analysis of arguments of implicitly defined firstprivate clause
3792       // for task|target directives.
3793       // Skip analysis of arguments of implicitly defined map clause for target
3794       // directives.
3795       if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) &&
3796                  C->isImplicit() &&
3797                  !isOpenMPTaskingDirective(Stack->getCurrentDirective()))) {
3798         for (Stmt *CC : C->children()) {
3799           if (CC)
3800             Visit(CC);
3801         }
3802       }
3803     }
3804     // Check implicitly captured variables.
3805     VisitSubCaptures(S);
3806   }
3807 
VisitOMPTileDirective(OMPTileDirective * S)3808   void VisitOMPTileDirective(OMPTileDirective *S) {
3809     // #pragma omp tile does not introduce data sharing.
3810     VisitStmt(S);
3811   }
3812 
VisitStmt(Stmt * S)3813   void VisitStmt(Stmt *S) {
3814     for (Stmt *C : S->children()) {
3815       if (C) {
3816         // Check implicitly captured variables in the task-based directives to
3817         // check if they must be firstprivatized.
3818         Visit(C);
3819       }
3820     }
3821   }
3822 
visitSubCaptures(CapturedStmt * S)3823   void visitSubCaptures(CapturedStmt *S) {
3824     for (const CapturedStmt::Capture &Cap : S->captures()) {
3825       if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
3826         continue;
3827       VarDecl *VD = Cap.getCapturedVar();
3828       // Do not try to map the variable if it or its sub-component was mapped
3829       // already.
3830       if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3831           Stack->checkMappableExprComponentListsForDecl(
3832               VD, /*CurrentRegionOnly=*/true,
3833               [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
3834                  OpenMPClauseKind) { return true; }))
3835         continue;
3836       DeclRefExpr *DRE = buildDeclRefExpr(
3837           SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
3838           Cap.getLocation(), /*RefersToCapture=*/true);
3839       Visit(DRE);
3840     }
3841   }
isErrorFound() const3842   bool isErrorFound() const { return ErrorFound; }
getImplicitFirstprivate() const3843   ArrayRef<Expr *> getImplicitFirstprivate() const {
3844     return ImplicitFirstprivate;
3845   }
getImplicitMap(OpenMPDefaultmapClauseKind DK,OpenMPMapClauseKind MK) const3846   ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind DK,
3847                                   OpenMPMapClauseKind MK) const {
3848     return ImplicitMap[DK][MK];
3849   }
3850   ArrayRef<OpenMPMapModifierKind>
getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const3851   getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const {
3852     return ImplicitMapModifier[Kind];
3853   }
getVarsWithInheritedDSA() const3854   const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
3855     return VarsWithInheritedDSA;
3856   }
3857 
DSAAttrChecker(DSAStackTy * S,Sema & SemaRef,CapturedStmt * CS)3858   DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
3859       : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
3860     // Process declare target link variables for the target directives.
3861     if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
3862       for (DeclRefExpr *E : Stack->getLinkGlobals())
3863         Visit(E);
3864     }
3865   }
3866 };
3867 } // namespace
3868 
ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind,Scope * CurScope)3869 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
3870   switch (DKind) {
3871   case OMPD_parallel:
3872   case OMPD_parallel_for:
3873   case OMPD_parallel_for_simd:
3874   case OMPD_parallel_sections:
3875   case OMPD_parallel_master:
3876   case OMPD_teams:
3877   case OMPD_teams_distribute:
3878   case OMPD_teams_distribute_simd: {
3879     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3880     QualType KmpInt32PtrTy =
3881         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3882     Sema::CapturedParamNameType Params[] = {
3883         std::make_pair(".global_tid.", KmpInt32PtrTy),
3884         std::make_pair(".bound_tid.", KmpInt32PtrTy),
3885         std::make_pair(StringRef(), QualType()) // __context with shared vars
3886     };
3887     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3888                              Params);
3889     break;
3890   }
3891   case OMPD_target_teams:
3892   case OMPD_target_parallel:
3893   case OMPD_target_parallel_for:
3894   case OMPD_target_parallel_for_simd:
3895   case OMPD_target_teams_distribute:
3896   case OMPD_target_teams_distribute_simd: {
3897     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3898     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3899     QualType KmpInt32PtrTy =
3900         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3901     QualType Args[] = {VoidPtrTy};
3902     FunctionProtoType::ExtProtoInfo EPI;
3903     EPI.Variadic = true;
3904     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3905     Sema::CapturedParamNameType Params[] = {
3906         std::make_pair(".global_tid.", KmpInt32Ty),
3907         std::make_pair(".part_id.", KmpInt32PtrTy),
3908         std::make_pair(".privates.", VoidPtrTy),
3909         std::make_pair(
3910             ".copy_fn.",
3911             Context.getPointerType(CopyFnType).withConst().withRestrict()),
3912         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3913         std::make_pair(StringRef(), QualType()) // __context with shared vars
3914     };
3915     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3916                              Params, /*OpenMPCaptureLevel=*/0);
3917     // Mark this captured region as inlined, because we don't use outlined
3918     // function directly.
3919     getCurCapturedRegion()->TheCapturedDecl->addAttr(
3920         AlwaysInlineAttr::CreateImplicit(
3921             Context, {}, AttributeCommonInfo::AS_Keyword,
3922             AlwaysInlineAttr::Keyword_forceinline));
3923     Sema::CapturedParamNameType ParamsTarget[] = {
3924         std::make_pair(StringRef(), QualType()) // __context with shared vars
3925     };
3926     // Start a captured region for 'target' with no implicit parameters.
3927     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3928                              ParamsTarget, /*OpenMPCaptureLevel=*/1);
3929     Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
3930         std::make_pair(".global_tid.", KmpInt32PtrTy),
3931         std::make_pair(".bound_tid.", KmpInt32PtrTy),
3932         std::make_pair(StringRef(), QualType()) // __context with shared vars
3933     };
3934     // Start a captured region for 'teams' or 'parallel'.  Both regions have
3935     // the same implicit parameters.
3936     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3937                              ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
3938     break;
3939   }
3940   case OMPD_target:
3941   case OMPD_target_simd: {
3942     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3943     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3944     QualType KmpInt32PtrTy =
3945         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3946     QualType Args[] = {VoidPtrTy};
3947     FunctionProtoType::ExtProtoInfo EPI;
3948     EPI.Variadic = true;
3949     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3950     Sema::CapturedParamNameType Params[] = {
3951         std::make_pair(".global_tid.", KmpInt32Ty),
3952         std::make_pair(".part_id.", KmpInt32PtrTy),
3953         std::make_pair(".privates.", VoidPtrTy),
3954         std::make_pair(
3955             ".copy_fn.",
3956             Context.getPointerType(CopyFnType).withConst().withRestrict()),
3957         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3958         std::make_pair(StringRef(), QualType()) // __context with shared vars
3959     };
3960     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3961                              Params, /*OpenMPCaptureLevel=*/0);
3962     // Mark this captured region as inlined, because we don't use outlined
3963     // function directly.
3964     getCurCapturedRegion()->TheCapturedDecl->addAttr(
3965         AlwaysInlineAttr::CreateImplicit(
3966             Context, {}, AttributeCommonInfo::AS_Keyword,
3967             AlwaysInlineAttr::Keyword_forceinline));
3968     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3969                              std::make_pair(StringRef(), QualType()),
3970                              /*OpenMPCaptureLevel=*/1);
3971     break;
3972   }
3973   case OMPD_atomic:
3974   case OMPD_critical:
3975   case OMPD_section:
3976   case OMPD_master:
3977   case OMPD_masked:
3978   case OMPD_tile:
3979     break;
3980   case OMPD_simd:
3981   case OMPD_for:
3982   case OMPD_for_simd:
3983   case OMPD_sections:
3984   case OMPD_single:
3985   case OMPD_taskgroup:
3986   case OMPD_distribute:
3987   case OMPD_distribute_simd:
3988   case OMPD_ordered:
3989   case OMPD_target_data:
3990   case OMPD_dispatch: {
3991     Sema::CapturedParamNameType Params[] = {
3992         std::make_pair(StringRef(), QualType()) // __context with shared vars
3993     };
3994     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3995                              Params);
3996     break;
3997   }
3998   case OMPD_task: {
3999     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4000     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4001     QualType KmpInt32PtrTy =
4002         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4003     QualType Args[] = {VoidPtrTy};
4004     FunctionProtoType::ExtProtoInfo EPI;
4005     EPI.Variadic = true;
4006     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4007     Sema::CapturedParamNameType Params[] = {
4008         std::make_pair(".global_tid.", KmpInt32Ty),
4009         std::make_pair(".part_id.", KmpInt32PtrTy),
4010         std::make_pair(".privates.", VoidPtrTy),
4011         std::make_pair(
4012             ".copy_fn.",
4013             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4014         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4015         std::make_pair(StringRef(), QualType()) // __context with shared vars
4016     };
4017     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4018                              Params);
4019     // Mark this captured region as inlined, because we don't use outlined
4020     // function directly.
4021     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4022         AlwaysInlineAttr::CreateImplicit(
4023             Context, {}, AttributeCommonInfo::AS_Keyword,
4024             AlwaysInlineAttr::Keyword_forceinline));
4025     break;
4026   }
4027   case OMPD_taskloop:
4028   case OMPD_taskloop_simd:
4029   case OMPD_master_taskloop:
4030   case OMPD_master_taskloop_simd: {
4031     QualType KmpInt32Ty =
4032         Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4033             .withConst();
4034     QualType KmpUInt64Ty =
4035         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4036             .withConst();
4037     QualType KmpInt64Ty =
4038         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4039             .withConst();
4040     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4041     QualType KmpInt32PtrTy =
4042         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4043     QualType Args[] = {VoidPtrTy};
4044     FunctionProtoType::ExtProtoInfo EPI;
4045     EPI.Variadic = true;
4046     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4047     Sema::CapturedParamNameType Params[] = {
4048         std::make_pair(".global_tid.", KmpInt32Ty),
4049         std::make_pair(".part_id.", KmpInt32PtrTy),
4050         std::make_pair(".privates.", VoidPtrTy),
4051         std::make_pair(
4052             ".copy_fn.",
4053             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4054         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4055         std::make_pair(".lb.", KmpUInt64Ty),
4056         std::make_pair(".ub.", KmpUInt64Ty),
4057         std::make_pair(".st.", KmpInt64Ty),
4058         std::make_pair(".liter.", KmpInt32Ty),
4059         std::make_pair(".reductions.", VoidPtrTy),
4060         std::make_pair(StringRef(), QualType()) // __context with shared vars
4061     };
4062     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4063                              Params);
4064     // Mark this captured region as inlined, because we don't use outlined
4065     // function directly.
4066     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4067         AlwaysInlineAttr::CreateImplicit(
4068             Context, {}, AttributeCommonInfo::AS_Keyword,
4069             AlwaysInlineAttr::Keyword_forceinline));
4070     break;
4071   }
4072   case OMPD_parallel_master_taskloop:
4073   case OMPD_parallel_master_taskloop_simd: {
4074     QualType KmpInt32Ty =
4075         Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4076             .withConst();
4077     QualType KmpUInt64Ty =
4078         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4079             .withConst();
4080     QualType KmpInt64Ty =
4081         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4082             .withConst();
4083     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4084     QualType KmpInt32PtrTy =
4085         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4086     Sema::CapturedParamNameType ParamsParallel[] = {
4087         std::make_pair(".global_tid.", KmpInt32PtrTy),
4088         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4089         std::make_pair(StringRef(), QualType()) // __context with shared vars
4090     };
4091     // Start a captured region for 'parallel'.
4092     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4093                              ParamsParallel, /*OpenMPCaptureLevel=*/0);
4094     QualType Args[] = {VoidPtrTy};
4095     FunctionProtoType::ExtProtoInfo EPI;
4096     EPI.Variadic = true;
4097     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4098     Sema::CapturedParamNameType Params[] = {
4099         std::make_pair(".global_tid.", KmpInt32Ty),
4100         std::make_pair(".part_id.", KmpInt32PtrTy),
4101         std::make_pair(".privates.", VoidPtrTy),
4102         std::make_pair(
4103             ".copy_fn.",
4104             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4105         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4106         std::make_pair(".lb.", KmpUInt64Ty),
4107         std::make_pair(".ub.", KmpUInt64Ty),
4108         std::make_pair(".st.", KmpInt64Ty),
4109         std::make_pair(".liter.", KmpInt32Ty),
4110         std::make_pair(".reductions.", VoidPtrTy),
4111         std::make_pair(StringRef(), QualType()) // __context with shared vars
4112     };
4113     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4114                              Params, /*OpenMPCaptureLevel=*/1);
4115     // Mark this captured region as inlined, because we don't use outlined
4116     // function directly.
4117     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4118         AlwaysInlineAttr::CreateImplicit(
4119             Context, {}, AttributeCommonInfo::AS_Keyword,
4120             AlwaysInlineAttr::Keyword_forceinline));
4121     break;
4122   }
4123   case OMPD_distribute_parallel_for_simd:
4124   case OMPD_distribute_parallel_for: {
4125     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4126     QualType KmpInt32PtrTy =
4127         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4128     Sema::CapturedParamNameType Params[] = {
4129         std::make_pair(".global_tid.", KmpInt32PtrTy),
4130         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4131         std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4132         std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4133         std::make_pair(StringRef(), QualType()) // __context with shared vars
4134     };
4135     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4136                              Params);
4137     break;
4138   }
4139   case OMPD_target_teams_distribute_parallel_for:
4140   case OMPD_target_teams_distribute_parallel_for_simd: {
4141     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4142     QualType KmpInt32PtrTy =
4143         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4144     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4145 
4146     QualType Args[] = {VoidPtrTy};
4147     FunctionProtoType::ExtProtoInfo EPI;
4148     EPI.Variadic = true;
4149     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4150     Sema::CapturedParamNameType Params[] = {
4151         std::make_pair(".global_tid.", KmpInt32Ty),
4152         std::make_pair(".part_id.", KmpInt32PtrTy),
4153         std::make_pair(".privates.", VoidPtrTy),
4154         std::make_pair(
4155             ".copy_fn.",
4156             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4157         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4158         std::make_pair(StringRef(), QualType()) // __context with shared vars
4159     };
4160     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4161                              Params, /*OpenMPCaptureLevel=*/0);
4162     // Mark this captured region as inlined, because we don't use outlined
4163     // function directly.
4164     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4165         AlwaysInlineAttr::CreateImplicit(
4166             Context, {}, AttributeCommonInfo::AS_Keyword,
4167             AlwaysInlineAttr::Keyword_forceinline));
4168     Sema::CapturedParamNameType ParamsTarget[] = {
4169         std::make_pair(StringRef(), QualType()) // __context with shared vars
4170     };
4171     // Start a captured region for 'target' with no implicit parameters.
4172     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4173                              ParamsTarget, /*OpenMPCaptureLevel=*/1);
4174 
4175     Sema::CapturedParamNameType ParamsTeams[] = {
4176         std::make_pair(".global_tid.", KmpInt32PtrTy),
4177         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4178         std::make_pair(StringRef(), QualType()) // __context with shared vars
4179     };
4180     // Start a captured region for 'target' with no implicit parameters.
4181     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4182                              ParamsTeams, /*OpenMPCaptureLevel=*/2);
4183 
4184     Sema::CapturedParamNameType ParamsParallel[] = {
4185         std::make_pair(".global_tid.", KmpInt32PtrTy),
4186         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4187         std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4188         std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4189         std::make_pair(StringRef(), QualType()) // __context with shared vars
4190     };
4191     // Start a captured region for 'teams' or 'parallel'.  Both regions have
4192     // the same implicit parameters.
4193     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4194                              ParamsParallel, /*OpenMPCaptureLevel=*/3);
4195     break;
4196   }
4197 
4198   case OMPD_teams_distribute_parallel_for:
4199   case OMPD_teams_distribute_parallel_for_simd: {
4200     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4201     QualType KmpInt32PtrTy =
4202         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4203 
4204     Sema::CapturedParamNameType ParamsTeams[] = {
4205         std::make_pair(".global_tid.", KmpInt32PtrTy),
4206         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4207         std::make_pair(StringRef(), QualType()) // __context with shared vars
4208     };
4209     // Start a captured region for 'target' with no implicit parameters.
4210     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4211                              ParamsTeams, /*OpenMPCaptureLevel=*/0);
4212 
4213     Sema::CapturedParamNameType ParamsParallel[] = {
4214         std::make_pair(".global_tid.", KmpInt32PtrTy),
4215         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4216         std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4217         std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4218         std::make_pair(StringRef(), QualType()) // __context with shared vars
4219     };
4220     // Start a captured region for 'teams' or 'parallel'.  Both regions have
4221     // the same implicit parameters.
4222     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4223                              ParamsParallel, /*OpenMPCaptureLevel=*/1);
4224     break;
4225   }
4226   case OMPD_target_update:
4227   case OMPD_target_enter_data:
4228   case OMPD_target_exit_data: {
4229     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4230     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4231     QualType KmpInt32PtrTy =
4232         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4233     QualType Args[] = {VoidPtrTy};
4234     FunctionProtoType::ExtProtoInfo EPI;
4235     EPI.Variadic = true;
4236     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4237     Sema::CapturedParamNameType Params[] = {
4238         std::make_pair(".global_tid.", KmpInt32Ty),
4239         std::make_pair(".part_id.", KmpInt32PtrTy),
4240         std::make_pair(".privates.", VoidPtrTy),
4241         std::make_pair(
4242             ".copy_fn.",
4243             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4244         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4245         std::make_pair(StringRef(), QualType()) // __context with shared vars
4246     };
4247     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4248                              Params);
4249     // Mark this captured region as inlined, because we don't use outlined
4250     // function directly.
4251     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4252         AlwaysInlineAttr::CreateImplicit(
4253             Context, {}, AttributeCommonInfo::AS_Keyword,
4254             AlwaysInlineAttr::Keyword_forceinline));
4255     break;
4256   }
4257   case OMPD_threadprivate:
4258   case OMPD_allocate:
4259   case OMPD_taskyield:
4260   case OMPD_barrier:
4261   case OMPD_taskwait:
4262   case OMPD_cancellation_point:
4263   case OMPD_cancel:
4264   case OMPD_flush:
4265   case OMPD_depobj:
4266   case OMPD_scan:
4267   case OMPD_declare_reduction:
4268   case OMPD_declare_mapper:
4269   case OMPD_declare_simd:
4270   case OMPD_declare_target:
4271   case OMPD_end_declare_target:
4272   case OMPD_requires:
4273   case OMPD_declare_variant:
4274   case OMPD_begin_declare_variant:
4275   case OMPD_end_declare_variant:
4276     llvm_unreachable("OpenMP Directive is not allowed");
4277   case OMPD_unknown:
4278   default:
4279     llvm_unreachable("Unknown OpenMP directive");
4280   }
4281   DSAStack->setContext(CurContext);
4282 }
4283 
getNumberOfConstructScopes(unsigned Level) const4284 int Sema::getNumberOfConstructScopes(unsigned Level) const {
4285   return getOpenMPCaptureLevels(DSAStack->getDirective(Level));
4286 }
4287 
getOpenMPCaptureLevels(OpenMPDirectiveKind DKind)4288 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
4289   SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4290   getOpenMPCaptureRegions(CaptureRegions, DKind);
4291   return CaptureRegions.size();
4292 }
4293 
buildCaptureDecl(Sema & S,IdentifierInfo * Id,Expr * CaptureExpr,bool WithInit,bool AsExpression)4294 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
4295                                              Expr *CaptureExpr, bool WithInit,
4296                                              bool AsExpression) {
4297   assert(CaptureExpr);
4298   ASTContext &C = S.getASTContext();
4299   Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
4300   QualType Ty = Init->getType();
4301   if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
4302     if (S.getLangOpts().CPlusPlus) {
4303       Ty = C.getLValueReferenceType(Ty);
4304     } else {
4305       Ty = C.getPointerType(Ty);
4306       ExprResult Res =
4307           S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
4308       if (!Res.isUsable())
4309         return nullptr;
4310       Init = Res.get();
4311     }
4312     WithInit = true;
4313   }
4314   auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
4315                                           CaptureExpr->getBeginLoc());
4316   if (!WithInit)
4317     CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
4318   S.CurContext->addHiddenDecl(CED);
4319   Sema::TentativeAnalysisScope Trap(S);
4320   S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
4321   return CED;
4322 }
4323 
buildCapture(Sema & S,ValueDecl * D,Expr * CaptureExpr,bool WithInit)4324 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
4325                                  bool WithInit) {
4326   OMPCapturedExprDecl *CD;
4327   if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
4328     CD = cast<OMPCapturedExprDecl>(VD);
4329   else
4330     CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
4331                           /*AsExpression=*/false);
4332   return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4333                           CaptureExpr->getExprLoc());
4334 }
4335 
buildCapture(Sema & S,Expr * CaptureExpr,DeclRefExpr * & Ref)4336 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
4337   CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
4338   if (!Ref) {
4339     OMPCapturedExprDecl *CD = buildCaptureDecl(
4340         S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
4341         /*WithInit=*/true, /*AsExpression=*/true);
4342     Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4343                            CaptureExpr->getExprLoc());
4344   }
4345   ExprResult Res = Ref;
4346   if (!S.getLangOpts().CPlusPlus &&
4347       CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
4348       Ref->getType()->isPointerType()) {
4349     Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
4350     if (!Res.isUsable())
4351       return ExprError();
4352   }
4353   return S.DefaultLvalueConversion(Res.get());
4354 }
4355 
4356 namespace {
4357 // OpenMP directives parsed in this section are represented as a
4358 // CapturedStatement with an associated statement.  If a syntax error
4359 // is detected during the parsing of the associated statement, the
4360 // compiler must abort processing and close the CapturedStatement.
4361 //
4362 // Combined directives such as 'target parallel' have more than one
4363 // nested CapturedStatements.  This RAII ensures that we unwind out
4364 // of all the nested CapturedStatements when an error is found.
4365 class CaptureRegionUnwinderRAII {
4366 private:
4367   Sema &S;
4368   bool &ErrorFound;
4369   OpenMPDirectiveKind DKind = OMPD_unknown;
4370 
4371 public:
CaptureRegionUnwinderRAII(Sema & S,bool & ErrorFound,OpenMPDirectiveKind DKind)4372   CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
4373                             OpenMPDirectiveKind DKind)
4374       : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
~CaptureRegionUnwinderRAII()4375   ~CaptureRegionUnwinderRAII() {
4376     if (ErrorFound) {
4377       int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
4378       while (--ThisCaptureLevel >= 0)
4379         S.ActOnCapturedRegionError();
4380     }
4381   }
4382 };
4383 } // namespace
4384 
tryCaptureOpenMPLambdas(ValueDecl * V)4385 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) {
4386   // Capture variables captured by reference in lambdas for target-based
4387   // directives.
4388   if (!CurContext->isDependentContext() &&
4389       (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) ||
4390        isOpenMPTargetDataManagementDirective(
4391            DSAStack->getCurrentDirective()))) {
4392     QualType Type = V->getType();
4393     if (const auto *RD = Type.getCanonicalType()
4394                              .getNonReferenceType()
4395                              ->getAsCXXRecordDecl()) {
4396       bool SavedForceCaptureByReferenceInTargetExecutable =
4397           DSAStack->isForceCaptureByReferenceInTargetExecutable();
4398       DSAStack->setForceCaptureByReferenceInTargetExecutable(
4399           /*V=*/true);
4400       if (RD->isLambda()) {
4401         llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
4402         FieldDecl *ThisCapture;
4403         RD->getCaptureFields(Captures, ThisCapture);
4404         for (const LambdaCapture &LC : RD->captures()) {
4405           if (LC.getCaptureKind() == LCK_ByRef) {
4406             VarDecl *VD = LC.getCapturedVar();
4407             DeclContext *VDC = VD->getDeclContext();
4408             if (!VDC->Encloses(CurContext))
4409               continue;
4410             MarkVariableReferenced(LC.getLocation(), VD);
4411           } else if (LC.getCaptureKind() == LCK_This) {
4412             QualType ThisTy = getCurrentThisType();
4413             if (!ThisTy.isNull() &&
4414                 Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
4415               CheckCXXThisCapture(LC.getLocation());
4416           }
4417         }
4418       }
4419       DSAStack->setForceCaptureByReferenceInTargetExecutable(
4420           SavedForceCaptureByReferenceInTargetExecutable);
4421     }
4422   }
4423 }
4424 
checkOrderedOrderSpecified(Sema & S,const ArrayRef<OMPClause * > Clauses)4425 static bool checkOrderedOrderSpecified(Sema &S,
4426                                        const ArrayRef<OMPClause *> Clauses) {
4427   const OMPOrderedClause *Ordered = nullptr;
4428   const OMPOrderClause *Order = nullptr;
4429 
4430   for (const OMPClause *Clause : Clauses) {
4431     if (Clause->getClauseKind() == OMPC_ordered)
4432       Ordered = cast<OMPOrderedClause>(Clause);
4433     else if (Clause->getClauseKind() == OMPC_order) {
4434       Order = cast<OMPOrderClause>(Clause);
4435       if (Order->getKind() != OMPC_ORDER_concurrent)
4436         Order = nullptr;
4437     }
4438     if (Ordered && Order)
4439       break;
4440   }
4441 
4442   if (Ordered && Order) {
4443     S.Diag(Order->getKindKwLoc(),
4444            diag::err_omp_simple_clause_incompatible_with_ordered)
4445         << getOpenMPClauseName(OMPC_order)
4446         << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent)
4447         << SourceRange(Order->getBeginLoc(), Order->getEndLoc());
4448     S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param)
4449         << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc());
4450     return true;
4451   }
4452   return false;
4453 }
4454 
ActOnOpenMPRegionEnd(StmtResult S,ArrayRef<OMPClause * > Clauses)4455 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
4456                                       ArrayRef<OMPClause *> Clauses) {
4457   if (DSAStack->getCurrentDirective() == OMPD_atomic ||
4458       DSAStack->getCurrentDirective() == OMPD_critical ||
4459       DSAStack->getCurrentDirective() == OMPD_section ||
4460       DSAStack->getCurrentDirective() == OMPD_master ||
4461       DSAStack->getCurrentDirective() == OMPD_masked)
4462     return S;
4463 
4464   bool ErrorFound = false;
4465   CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4466       *this, ErrorFound, DSAStack->getCurrentDirective());
4467   if (!S.isUsable()) {
4468     ErrorFound = true;
4469     return StmtError();
4470   }
4471 
4472   SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4473   getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective());
4474   OMPOrderedClause *OC = nullptr;
4475   OMPScheduleClause *SC = nullptr;
4476   SmallVector<const OMPLinearClause *, 4> LCs;
4477   SmallVector<const OMPClauseWithPreInit *, 4> PICs;
4478   // This is required for proper codegen.
4479   for (OMPClause *Clause : Clauses) {
4480     if (!LangOpts.OpenMPSimd &&
4481         isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
4482         Clause->getClauseKind() == OMPC_in_reduction) {
4483       // Capture taskgroup task_reduction descriptors inside the tasking regions
4484       // with the corresponding in_reduction items.
4485       auto *IRC = cast<OMPInReductionClause>(Clause);
4486       for (Expr *E : IRC->taskgroup_descriptors())
4487         if (E)
4488           MarkDeclarationsReferencedInExpr(E);
4489     }
4490     if (isOpenMPPrivate(Clause->getClauseKind()) ||
4491         Clause->getClauseKind() == OMPC_copyprivate ||
4492         (getLangOpts().OpenMPUseTLS &&
4493          getASTContext().getTargetInfo().isTLSSupported() &&
4494          Clause->getClauseKind() == OMPC_copyin)) {
4495       DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
4496       // Mark all variables in private list clauses as used in inner region.
4497       for (Stmt *VarRef : Clause->children()) {
4498         if (auto *E = cast_or_null<Expr>(VarRef)) {
4499           MarkDeclarationsReferencedInExpr(E);
4500         }
4501       }
4502       DSAStack->setForceVarCapturing(/*V=*/false);
4503     } else if (isOpenMPLoopTransformationDirective(
4504                    DSAStack->getCurrentDirective())) {
4505       assert(CaptureRegions.empty() &&
4506              "No captured regions in loop transformation directives.");
4507     } else if (CaptureRegions.size() > 1 ||
4508                CaptureRegions.back() != OMPD_unknown) {
4509       if (auto *C = OMPClauseWithPreInit::get(Clause))
4510         PICs.push_back(C);
4511       if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
4512         if (Expr *E = C->getPostUpdateExpr())
4513           MarkDeclarationsReferencedInExpr(E);
4514       }
4515     }
4516     if (Clause->getClauseKind() == OMPC_schedule)
4517       SC = cast<OMPScheduleClause>(Clause);
4518     else if (Clause->getClauseKind() == OMPC_ordered)
4519       OC = cast<OMPOrderedClause>(Clause);
4520     else if (Clause->getClauseKind() == OMPC_linear)
4521       LCs.push_back(cast<OMPLinearClause>(Clause));
4522   }
4523   // Capture allocator expressions if used.
4524   for (Expr *E : DSAStack->getInnerAllocators())
4525     MarkDeclarationsReferencedInExpr(E);
4526   // OpenMP, 2.7.1 Loop Construct, Restrictions
4527   // The nonmonotonic modifier cannot be specified if an ordered clause is
4528   // specified.
4529   if (SC &&
4530       (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
4531        SC->getSecondScheduleModifier() ==
4532            OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4533       OC) {
4534     Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
4535              ? SC->getFirstScheduleModifierLoc()
4536              : SC->getSecondScheduleModifierLoc(),
4537          diag::err_omp_simple_clause_incompatible_with_ordered)
4538         << getOpenMPClauseName(OMPC_schedule)
4539         << getOpenMPSimpleClauseTypeName(OMPC_schedule,
4540                                          OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4541         << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4542     ErrorFound = true;
4543   }
4544   // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions.
4545   // If an order(concurrent) clause is present, an ordered clause may not appear
4546   // on the same directive.
4547   if (checkOrderedOrderSpecified(*this, Clauses))
4548     ErrorFound = true;
4549   if (!LCs.empty() && OC && OC->getNumForLoops()) {
4550     for (const OMPLinearClause *C : LCs) {
4551       Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
4552           << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4553     }
4554     ErrorFound = true;
4555   }
4556   if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
4557       isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
4558       OC->getNumForLoops()) {
4559     Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
4560         << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
4561     ErrorFound = true;
4562   }
4563   if (ErrorFound) {
4564     return StmtError();
4565   }
4566   StmtResult SR = S;
4567   unsigned CompletedRegions = 0;
4568   for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
4569     // Mark all variables in private list clauses as used in inner region.
4570     // Required for proper codegen of combined directives.
4571     // TODO: add processing for other clauses.
4572     if (ThisCaptureRegion != OMPD_unknown) {
4573       for (const clang::OMPClauseWithPreInit *C : PICs) {
4574         OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
4575         // Find the particular capture region for the clause if the
4576         // directive is a combined one with multiple capture regions.
4577         // If the directive is not a combined one, the capture region
4578         // associated with the clause is OMPD_unknown and is generated
4579         // only once.
4580         if (CaptureRegion == ThisCaptureRegion ||
4581             CaptureRegion == OMPD_unknown) {
4582           if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
4583             for (Decl *D : DS->decls())
4584               MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
4585           }
4586         }
4587       }
4588     }
4589     if (ThisCaptureRegion == OMPD_target) {
4590       // Capture allocator traits in the target region. They are used implicitly
4591       // and, thus, are not captured by default.
4592       for (OMPClause *C : Clauses) {
4593         if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) {
4594           for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4595                ++I) {
4596             OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I);
4597             if (Expr *E = D.AllocatorTraits)
4598               MarkDeclarationsReferencedInExpr(E);
4599           }
4600           continue;
4601         }
4602       }
4603     }
4604     if (ThisCaptureRegion == OMPD_parallel) {
4605       // Capture temp arrays for inscan reductions.
4606       for (OMPClause *C : Clauses) {
4607         if (auto *RC = dyn_cast<OMPReductionClause>(C)) {
4608           if (RC->getModifier() != OMPC_REDUCTION_inscan)
4609             continue;
4610           for (Expr *E : RC->copy_array_temps())
4611             MarkDeclarationsReferencedInExpr(E);
4612         }
4613       }
4614     }
4615     if (++CompletedRegions == CaptureRegions.size())
4616       DSAStack->setBodyComplete();
4617     SR = ActOnCapturedRegionEnd(SR.get());
4618   }
4619   return SR;
4620 }
4621 
checkCancelRegion(Sema & SemaRef,OpenMPDirectiveKind CurrentRegion,OpenMPDirectiveKind CancelRegion,SourceLocation StartLoc)4622 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
4623                               OpenMPDirectiveKind CancelRegion,
4624                               SourceLocation StartLoc) {
4625   // CancelRegion is only needed for cancel and cancellation_point.
4626   if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4627     return false;
4628 
4629   if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4630       CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4631     return false;
4632 
4633   SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4634       << getOpenMPDirectiveName(CancelRegion);
4635   return true;
4636 }
4637 
checkNestingOfRegions(Sema & SemaRef,const DSAStackTy * Stack,OpenMPDirectiveKind CurrentRegion,const DeclarationNameInfo & CurrentName,OpenMPDirectiveKind CancelRegion,SourceLocation StartLoc)4638 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4639                                   OpenMPDirectiveKind CurrentRegion,
4640                                   const DeclarationNameInfo &CurrentName,
4641                                   OpenMPDirectiveKind CancelRegion,
4642                                   SourceLocation StartLoc) {
4643   if (Stack->getCurScope()) {
4644     OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
4645     OpenMPDirectiveKind OffendingRegion = ParentRegion;
4646     bool NestingProhibited = false;
4647     bool CloseNesting = true;
4648     bool OrphanSeen = false;
4649     enum {
4650       NoRecommend,
4651       ShouldBeInParallelRegion,
4652       ShouldBeInOrderedRegion,
4653       ShouldBeInTargetRegion,
4654       ShouldBeInTeamsRegion,
4655       ShouldBeInLoopSimdRegion,
4656     } Recommend = NoRecommend;
4657     if (isOpenMPSimdDirective(ParentRegion) &&
4658         ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
4659          (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
4660           CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
4661           CurrentRegion != OMPD_scan))) {
4662       // OpenMP [2.16, Nesting of Regions]
4663       // OpenMP constructs may not be nested inside a simd region.
4664       // OpenMP [2.8.1,simd Construct, Restrictions]
4665       // An ordered construct with the simd clause is the only OpenMP
4666       // construct that can appear in the simd region.
4667       // Allowing a SIMD construct nested in another SIMD construct is an
4668       // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
4669       // message.
4670       // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions]
4671       // The only OpenMP constructs that can be encountered during execution of
4672       // a simd region are the atomic construct, the loop construct, the simd
4673       // construct and the ordered construct with the simd clause.
4674       SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
4675                                  ? diag::err_omp_prohibited_region_simd
4676                                  : diag::warn_omp_nesting_simd)
4677           << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0);
4678       return CurrentRegion != OMPD_simd;
4679     }
4680     if (ParentRegion == OMPD_atomic) {
4681       // OpenMP [2.16, Nesting of Regions]
4682       // OpenMP constructs may not be nested inside an atomic region.
4683       SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
4684       return true;
4685     }
4686     if (CurrentRegion == OMPD_section) {
4687       // OpenMP [2.7.2, sections Construct, Restrictions]
4688       // Orphaned section directives are prohibited. That is, the section
4689       // directives must appear within the sections construct and must not be
4690       // encountered elsewhere in the sections region.
4691       if (ParentRegion != OMPD_sections &&
4692           ParentRegion != OMPD_parallel_sections) {
4693         SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
4694             << (ParentRegion != OMPD_unknown)
4695             << getOpenMPDirectiveName(ParentRegion);
4696         return true;
4697       }
4698       return false;
4699     }
4700     // Allow some constructs (except teams and cancellation constructs) to be
4701     // orphaned (they could be used in functions, called from OpenMP regions
4702     // with the required preconditions).
4703     if (ParentRegion == OMPD_unknown &&
4704         !isOpenMPNestingTeamsDirective(CurrentRegion) &&
4705         CurrentRegion != OMPD_cancellation_point &&
4706         CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
4707       return false;
4708     if (CurrentRegion == OMPD_cancellation_point ||
4709         CurrentRegion == OMPD_cancel) {
4710       // OpenMP [2.16, Nesting of Regions]
4711       // A cancellation point construct for which construct-type-clause is
4712       // taskgroup must be nested inside a task construct. A cancellation
4713       // point construct for which construct-type-clause is not taskgroup must
4714       // be closely nested inside an OpenMP construct that matches the type
4715       // specified in construct-type-clause.
4716       // A cancel construct for which construct-type-clause is taskgroup must be
4717       // nested inside a task construct. A cancel construct for which
4718       // construct-type-clause is not taskgroup must be closely nested inside an
4719       // OpenMP construct that matches the type specified in
4720       // construct-type-clause.
4721       NestingProhibited =
4722           !((CancelRegion == OMPD_parallel &&
4723              (ParentRegion == OMPD_parallel ||
4724               ParentRegion == OMPD_target_parallel)) ||
4725             (CancelRegion == OMPD_for &&
4726              (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
4727               ParentRegion == OMPD_target_parallel_for ||
4728               ParentRegion == OMPD_distribute_parallel_for ||
4729               ParentRegion == OMPD_teams_distribute_parallel_for ||
4730               ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
4731             (CancelRegion == OMPD_taskgroup &&
4732              (ParentRegion == OMPD_task ||
4733               (SemaRef.getLangOpts().OpenMP >= 50 &&
4734                (ParentRegion == OMPD_taskloop ||
4735                 ParentRegion == OMPD_master_taskloop ||
4736                 ParentRegion == OMPD_parallel_master_taskloop)))) ||
4737             (CancelRegion == OMPD_sections &&
4738              (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
4739               ParentRegion == OMPD_parallel_sections)));
4740       OrphanSeen = ParentRegion == OMPD_unknown;
4741     } else if (CurrentRegion == OMPD_master || CurrentRegion == OMPD_masked) {
4742       // OpenMP 5.1 [2.22, Nesting of Regions]
4743       // A masked region may not be closely nested inside a worksharing, loop,
4744       // atomic, task, or taskloop region.
4745       NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4746                           isOpenMPTaskingDirective(ParentRegion);
4747     } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
4748       // OpenMP [2.16, Nesting of Regions]
4749       // A critical region may not be nested (closely or otherwise) inside a
4750       // critical region with the same name. Note that this restriction is not
4751       // sufficient to prevent deadlock.
4752       SourceLocation PreviousCriticalLoc;
4753       bool DeadLock = Stack->hasDirective(
4754           [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
4755                                               const DeclarationNameInfo &DNI,
4756                                               SourceLocation Loc) {
4757             if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
4758               PreviousCriticalLoc = Loc;
4759               return true;
4760             }
4761             return false;
4762           },
4763           false /* skip top directive */);
4764       if (DeadLock) {
4765         SemaRef.Diag(StartLoc,
4766                      diag::err_omp_prohibited_region_critical_same_name)
4767             << CurrentName.getName();
4768         if (PreviousCriticalLoc.isValid())
4769           SemaRef.Diag(PreviousCriticalLoc,
4770                        diag::note_omp_previous_critical_region);
4771         return true;
4772       }
4773     } else if (CurrentRegion == OMPD_barrier) {
4774       // OpenMP 5.1 [2.22, Nesting of Regions]
4775       // A barrier region may not be closely nested inside a worksharing, loop,
4776       // task, taskloop, critical, ordered, atomic, or masked region.
4777       NestingProhibited =
4778           isOpenMPWorksharingDirective(ParentRegion) ||
4779           isOpenMPTaskingDirective(ParentRegion) ||
4780           ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
4781           ParentRegion == OMPD_parallel_master ||
4782           ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
4783     } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
4784                !isOpenMPParallelDirective(CurrentRegion) &&
4785                !isOpenMPTeamsDirective(CurrentRegion)) {
4786       // OpenMP 5.1 [2.22, Nesting of Regions]
4787       // A loop region that binds to a parallel region or a worksharing region
4788       // may not be closely nested inside a worksharing, loop, task, taskloop,
4789       // critical, ordered, atomic, or masked region.
4790       NestingProhibited =
4791           isOpenMPWorksharingDirective(ParentRegion) ||
4792           isOpenMPTaskingDirective(ParentRegion) ||
4793           ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
4794           ParentRegion == OMPD_parallel_master ||
4795           ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
4796       Recommend = ShouldBeInParallelRegion;
4797     } else if (CurrentRegion == OMPD_ordered) {
4798       // OpenMP [2.16, Nesting of Regions]
4799       // An ordered region may not be closely nested inside a critical,
4800       // atomic, or explicit task region.
4801       // An ordered region must be closely nested inside a loop region (or
4802       // parallel loop region) with an ordered clause.
4803       // OpenMP [2.8.1,simd Construct, Restrictions]
4804       // An ordered construct with the simd clause is the only OpenMP construct
4805       // that can appear in the simd region.
4806       NestingProhibited = ParentRegion == OMPD_critical ||
4807                           isOpenMPTaskingDirective(ParentRegion) ||
4808                           !(isOpenMPSimdDirective(ParentRegion) ||
4809                             Stack->isParentOrderedRegion());
4810       Recommend = ShouldBeInOrderedRegion;
4811     } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
4812       // OpenMP [2.16, Nesting of Regions]
4813       // If specified, a teams construct must be contained within a target
4814       // construct.
4815       NestingProhibited =
4816           (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
4817           (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
4818            ParentRegion != OMPD_target);
4819       OrphanSeen = ParentRegion == OMPD_unknown;
4820       Recommend = ShouldBeInTargetRegion;
4821     } else if (CurrentRegion == OMPD_scan) {
4822       // OpenMP [2.16, Nesting of Regions]
4823       // If specified, a teams construct must be contained within a target
4824       // construct.
4825       NestingProhibited =
4826           SemaRef.LangOpts.OpenMP < 50 ||
4827           (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
4828            ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
4829            ParentRegion != OMPD_parallel_for_simd);
4830       OrphanSeen = ParentRegion == OMPD_unknown;
4831       Recommend = ShouldBeInLoopSimdRegion;
4832     }
4833     if (!NestingProhibited &&
4834         !isOpenMPTargetExecutionDirective(CurrentRegion) &&
4835         !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
4836         (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
4837       // OpenMP [2.16, Nesting of Regions]
4838       // distribute, parallel, parallel sections, parallel workshare, and the
4839       // parallel loop and parallel loop SIMD constructs are the only OpenMP
4840       // constructs that can be closely nested in the teams region.
4841       NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
4842                           !isOpenMPDistributeDirective(CurrentRegion);
4843       Recommend = ShouldBeInParallelRegion;
4844     }
4845     if (!NestingProhibited &&
4846         isOpenMPNestingDistributeDirective(CurrentRegion)) {
4847       // OpenMP 4.5 [2.17 Nesting of Regions]
4848       // The region associated with the distribute construct must be strictly
4849       // nested inside a teams region
4850       NestingProhibited =
4851           (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
4852       Recommend = ShouldBeInTeamsRegion;
4853     }
4854     if (!NestingProhibited &&
4855         (isOpenMPTargetExecutionDirective(CurrentRegion) ||
4856          isOpenMPTargetDataManagementDirective(CurrentRegion))) {
4857       // OpenMP 4.5 [2.17 Nesting of Regions]
4858       // If a target, target update, target data, target enter data, or
4859       // target exit data construct is encountered during execution of a
4860       // target region, the behavior is unspecified.
4861       NestingProhibited = Stack->hasDirective(
4862           [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
4863                              SourceLocation) {
4864             if (isOpenMPTargetExecutionDirective(K)) {
4865               OffendingRegion = K;
4866               return true;
4867             }
4868             return false;
4869           },
4870           false /* don't skip top directive */);
4871       CloseNesting = false;
4872     }
4873     if (NestingProhibited) {
4874       if (OrphanSeen) {
4875         SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
4876             << getOpenMPDirectiveName(CurrentRegion) << Recommend;
4877       } else {
4878         SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
4879             << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
4880             << Recommend << getOpenMPDirectiveName(CurrentRegion);
4881       }
4882       return true;
4883     }
4884   }
4885   return false;
4886 }
4887 
4888 struct Kind2Unsigned {
4889   using argument_type = OpenMPDirectiveKind;
operator ()Kind2Unsigned4890   unsigned operator()(argument_type DK) { return unsigned(DK); }
4891 };
checkIfClauses(Sema & S,OpenMPDirectiveKind Kind,ArrayRef<OMPClause * > Clauses,ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers)4892 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
4893                            ArrayRef<OMPClause *> Clauses,
4894                            ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
4895   bool ErrorFound = false;
4896   unsigned NamedModifiersNumber = 0;
4897   llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
4898   FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
4899   SmallVector<SourceLocation, 4> NameModifierLoc;
4900   for (const OMPClause *C : Clauses) {
4901     if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
4902       // At most one if clause without a directive-name-modifier can appear on
4903       // the directive.
4904       OpenMPDirectiveKind CurNM = IC->getNameModifier();
4905       if (FoundNameModifiers[CurNM]) {
4906         S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
4907             << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
4908             << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
4909         ErrorFound = true;
4910       } else if (CurNM != OMPD_unknown) {
4911         NameModifierLoc.push_back(IC->getNameModifierLoc());
4912         ++NamedModifiersNumber;
4913       }
4914       FoundNameModifiers[CurNM] = IC;
4915       if (CurNM == OMPD_unknown)
4916         continue;
4917       // Check if the specified name modifier is allowed for the current
4918       // directive.
4919       // At most one if clause with the particular directive-name-modifier can
4920       // appear on the directive.
4921       bool MatchFound = false;
4922       for (auto NM : AllowedNameModifiers) {
4923         if (CurNM == NM) {
4924           MatchFound = true;
4925           break;
4926         }
4927       }
4928       if (!MatchFound) {
4929         S.Diag(IC->getNameModifierLoc(),
4930                diag::err_omp_wrong_if_directive_name_modifier)
4931             << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
4932         ErrorFound = true;
4933       }
4934     }
4935   }
4936   // If any if clause on the directive includes a directive-name-modifier then
4937   // all if clauses on the directive must include a directive-name-modifier.
4938   if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
4939     if (NamedModifiersNumber == AllowedNameModifiers.size()) {
4940       S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
4941              diag::err_omp_no_more_if_clause);
4942     } else {
4943       std::string Values;
4944       std::string Sep(", ");
4945       unsigned AllowedCnt = 0;
4946       unsigned TotalAllowedNum =
4947           AllowedNameModifiers.size() - NamedModifiersNumber;
4948       for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
4949            ++Cnt) {
4950         OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
4951         if (!FoundNameModifiers[NM]) {
4952           Values += "'";
4953           Values += getOpenMPDirectiveName(NM);
4954           Values += "'";
4955           if (AllowedCnt + 2 == TotalAllowedNum)
4956             Values += " or ";
4957           else if (AllowedCnt + 1 != TotalAllowedNum)
4958             Values += Sep;
4959           ++AllowedCnt;
4960         }
4961       }
4962       S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
4963              diag::err_omp_unnamed_if_clause)
4964           << (TotalAllowedNum > 1) << Values;
4965     }
4966     for (SourceLocation Loc : NameModifierLoc) {
4967       S.Diag(Loc, diag::note_omp_previous_named_if_clause);
4968     }
4969     ErrorFound = true;
4970   }
4971   return ErrorFound;
4972 }
4973 
getPrivateItem(Sema & S,Expr * & RefExpr,SourceLocation & ELoc,SourceRange & ERange,bool AllowArraySection)4974 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
4975                                                    SourceLocation &ELoc,
4976                                                    SourceRange &ERange,
4977                                                    bool AllowArraySection) {
4978   if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
4979       RefExpr->containsUnexpandedParameterPack())
4980     return std::make_pair(nullptr, true);
4981 
4982   // OpenMP [3.1, C/C++]
4983   //  A list item is a variable name.
4984   // OpenMP  [2.9.3.3, Restrictions, p.1]
4985   //  A variable that is part of another variable (as an array or
4986   //  structure element) cannot appear in a private clause.
4987   RefExpr = RefExpr->IgnoreParens();
4988   enum {
4989     NoArrayExpr = -1,
4990     ArraySubscript = 0,
4991     OMPArraySection = 1
4992   } IsArrayExpr = NoArrayExpr;
4993   if (AllowArraySection) {
4994     if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
4995       Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
4996       while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
4997         Base = TempASE->getBase()->IgnoreParenImpCasts();
4998       RefExpr = Base;
4999       IsArrayExpr = ArraySubscript;
5000     } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
5001       Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
5002       while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
5003         Base = TempOASE->getBase()->IgnoreParenImpCasts();
5004       while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
5005         Base = TempASE->getBase()->IgnoreParenImpCasts();
5006       RefExpr = Base;
5007       IsArrayExpr = OMPArraySection;
5008     }
5009   }
5010   ELoc = RefExpr->getExprLoc();
5011   ERange = RefExpr->getSourceRange();
5012   RefExpr = RefExpr->IgnoreParenImpCasts();
5013   auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
5014   auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
5015   if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
5016       (S.getCurrentThisType().isNull() || !ME ||
5017        !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
5018        !isa<FieldDecl>(ME->getMemberDecl()))) {
5019     if (IsArrayExpr != NoArrayExpr) {
5020       S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
5021                                                          << ERange;
5022     } else {
5023       S.Diag(ELoc,
5024              AllowArraySection
5025                  ? diag::err_omp_expected_var_name_member_expr_or_array_item
5026                  : diag::err_omp_expected_var_name_member_expr)
5027           << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
5028     }
5029     return std::make_pair(nullptr, false);
5030   }
5031   return std::make_pair(
5032       getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
5033 }
5034 
5035 namespace {
5036 /// Checks if the allocator is used in uses_allocators clause to be allowed in
5037 /// target regions.
5038 class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> {
5039   DSAStackTy *S = nullptr;
5040 
5041 public:
VisitDeclRefExpr(const DeclRefExpr * E)5042   bool VisitDeclRefExpr(const DeclRefExpr *E) {
5043     return S->isUsesAllocatorsDecl(E->getDecl())
5044                .getValueOr(
5045                    DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
5046            DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
5047   }
VisitStmt(const Stmt * S)5048   bool VisitStmt(const Stmt *S) {
5049     for (const Stmt *Child : S->children()) {
5050       if (Child && Visit(Child))
5051         return true;
5052     }
5053     return false;
5054   }
AllocatorChecker(DSAStackTy * S)5055   explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
5056 };
5057 } // namespace
5058 
checkAllocateClauses(Sema & S,DSAStackTy * Stack,ArrayRef<OMPClause * > Clauses)5059 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
5060                                  ArrayRef<OMPClause *> Clauses) {
5061   assert(!S.CurContext->isDependentContext() &&
5062          "Expected non-dependent context.");
5063   auto AllocateRange =
5064       llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
5065   llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>>
5066       DeclToCopy;
5067   auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
5068     return isOpenMPPrivate(C->getClauseKind());
5069   });
5070   for (OMPClause *Cl : PrivateRange) {
5071     MutableArrayRef<Expr *>::iterator I, It, Et;
5072     if (Cl->getClauseKind() == OMPC_private) {
5073       auto *PC = cast<OMPPrivateClause>(Cl);
5074       I = PC->private_copies().begin();
5075       It = PC->varlist_begin();
5076       Et = PC->varlist_end();
5077     } else if (Cl->getClauseKind() == OMPC_firstprivate) {
5078       auto *PC = cast<OMPFirstprivateClause>(Cl);
5079       I = PC->private_copies().begin();
5080       It = PC->varlist_begin();
5081       Et = PC->varlist_end();
5082     } else if (Cl->getClauseKind() == OMPC_lastprivate) {
5083       auto *PC = cast<OMPLastprivateClause>(Cl);
5084       I = PC->private_copies().begin();
5085       It = PC->varlist_begin();
5086       Et = PC->varlist_end();
5087     } else if (Cl->getClauseKind() == OMPC_linear) {
5088       auto *PC = cast<OMPLinearClause>(Cl);
5089       I = PC->privates().begin();
5090       It = PC->varlist_begin();
5091       Et = PC->varlist_end();
5092     } else if (Cl->getClauseKind() == OMPC_reduction) {
5093       auto *PC = cast<OMPReductionClause>(Cl);
5094       I = PC->privates().begin();
5095       It = PC->varlist_begin();
5096       Et = PC->varlist_end();
5097     } else if (Cl->getClauseKind() == OMPC_task_reduction) {
5098       auto *PC = cast<OMPTaskReductionClause>(Cl);
5099       I = PC->privates().begin();
5100       It = PC->varlist_begin();
5101       Et = PC->varlist_end();
5102     } else if (Cl->getClauseKind() == OMPC_in_reduction) {
5103       auto *PC = cast<OMPInReductionClause>(Cl);
5104       I = PC->privates().begin();
5105       It = PC->varlist_begin();
5106       Et = PC->varlist_end();
5107     } else {
5108       llvm_unreachable("Expected private clause.");
5109     }
5110     for (Expr *E : llvm::make_range(It, Et)) {
5111       if (!*I) {
5112         ++I;
5113         continue;
5114       }
5115       SourceLocation ELoc;
5116       SourceRange ERange;
5117       Expr *SimpleRefExpr = E;
5118       auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
5119                                 /*AllowArraySection=*/true);
5120       DeclToCopy.try_emplace(Res.first,
5121                              cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
5122       ++I;
5123     }
5124   }
5125   for (OMPClause *C : AllocateRange) {
5126     auto *AC = cast<OMPAllocateClause>(C);
5127     if (S.getLangOpts().OpenMP >= 50 &&
5128         !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() &&
5129         isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
5130         AC->getAllocator()) {
5131       Expr *Allocator = AC->getAllocator();
5132       // OpenMP, 2.12.5 target Construct
5133       // Memory allocators that do not appear in a uses_allocators clause cannot
5134       // appear as an allocator in an allocate clause or be used in the target
5135       // region unless a requires directive with the dynamic_allocators clause
5136       // is present in the same compilation unit.
5137       AllocatorChecker Checker(Stack);
5138       if (Checker.Visit(Allocator))
5139         S.Diag(Allocator->getExprLoc(),
5140                diag::err_omp_allocator_not_in_uses_allocators)
5141             << Allocator->getSourceRange();
5142     }
5143     OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
5144         getAllocatorKind(S, Stack, AC->getAllocator());
5145     // OpenMP, 2.11.4 allocate Clause, Restrictions.
5146     // For task, taskloop or target directives, allocation requests to memory
5147     // allocators with the trait access set to thread result in unspecified
5148     // behavior.
5149     if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
5150         (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
5151          isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
5152       S.Diag(AC->getAllocator()->getExprLoc(),
5153              diag::warn_omp_allocate_thread_on_task_target_directive)
5154           << getOpenMPDirectiveName(Stack->getCurrentDirective());
5155     }
5156     for (Expr *E : AC->varlists()) {
5157       SourceLocation ELoc;
5158       SourceRange ERange;
5159       Expr *SimpleRefExpr = E;
5160       auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
5161       ValueDecl *VD = Res.first;
5162       DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
5163       if (!isOpenMPPrivate(Data.CKind)) {
5164         S.Diag(E->getExprLoc(),
5165                diag::err_omp_expected_private_copy_for_allocate);
5166         continue;
5167       }
5168       VarDecl *PrivateVD = DeclToCopy[VD];
5169       if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
5170                                             AllocatorKind, AC->getAllocator()))
5171         continue;
5172       applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
5173                                 E->getSourceRange());
5174     }
5175   }
5176 }
5177 
5178 namespace {
5179 /// Rewrite statements and expressions for Sema \p Actions CurContext.
5180 ///
5181 /// Used to wrap already parsed statements/expressions into a new CapturedStmt
5182 /// context. DeclRefExpr used inside the new context are changed to refer to the
5183 /// captured variable instead.
5184 class CaptureVars : public TreeTransform<CaptureVars> {
5185   using BaseTransform = TreeTransform<CaptureVars>;
5186 
5187 public:
CaptureVars(Sema & Actions)5188   CaptureVars(Sema &Actions) : BaseTransform(Actions) {}
5189 
AlwaysRebuild()5190   bool AlwaysRebuild() { return true; }
5191 };
5192 } // namespace
5193 
precomputeExpr(Sema & Actions,SmallVectorImpl<Stmt * > & BodyStmts,Expr * E,StringRef Name)5194 static VarDecl *precomputeExpr(Sema &Actions,
5195                                SmallVectorImpl<Stmt *> &BodyStmts, Expr *E,
5196                                StringRef Name) {
5197   Expr *NewE = AssertSuccess(CaptureVars(Actions).TransformExpr(E));
5198   VarDecl *NewVar = buildVarDecl(Actions, {}, NewE->getType(), Name, nullptr,
5199                                  dyn_cast<DeclRefExpr>(E->IgnoreImplicit()));
5200   auto *NewDeclStmt = cast<DeclStmt>(AssertSuccess(
5201       Actions.ActOnDeclStmt(Actions.ConvertDeclToDeclGroup(NewVar), {}, {})));
5202   Actions.AddInitializerToDecl(NewDeclStmt->getSingleDecl(), NewE, false);
5203   BodyStmts.push_back(NewDeclStmt);
5204   return NewVar;
5205 }
5206 
5207 /// Create a closure that computes the number of iterations of a loop.
5208 ///
5209 /// \param Actions   The Sema object.
5210 /// \param LogicalTy Type for the logical iteration number.
5211 /// \param Rel       Comparison operator of the loop condition.
5212 /// \param StartExpr Value of the loop counter at the first iteration.
5213 /// \param StopExpr  Expression the loop counter is compared against in the loop
5214 /// condition. \param StepExpr      Amount of increment after each iteration.
5215 ///
5216 /// \return Closure (CapturedStmt) of the distance calculation.
buildDistanceFunc(Sema & Actions,QualType LogicalTy,BinaryOperator::Opcode Rel,Expr * StartExpr,Expr * StopExpr,Expr * StepExpr)5217 static CapturedStmt *buildDistanceFunc(Sema &Actions, QualType LogicalTy,
5218                                        BinaryOperator::Opcode Rel,
5219                                        Expr *StartExpr, Expr *StopExpr,
5220                                        Expr *StepExpr) {
5221   ASTContext &Ctx = Actions.getASTContext();
5222   TypeSourceInfo *LogicalTSI = Ctx.getTrivialTypeSourceInfo(LogicalTy);
5223 
5224   // Captured regions currently don't support return values, we use an
5225   // out-parameter instead. All inputs are implicit captures.
5226   // TODO: Instead of capturing each DeclRefExpr occurring in
5227   // StartExpr/StopExpr/Step, these could also be passed as a value capture.
5228   QualType ResultTy = Ctx.getLValueReferenceType(LogicalTy);
5229   Sema::CapturedParamNameType Params[] = {{"Distance", ResultTy},
5230                                           {StringRef(), QualType()}};
5231   Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5232 
5233   Stmt *Body;
5234   {
5235     Sema::CompoundScopeRAII CompoundScope(Actions);
5236     CapturedDecl *CS = cast<CapturedDecl>(Actions.CurContext);
5237 
5238     // Get the LValue expression for the result.
5239     ImplicitParamDecl *DistParam = CS->getParam(0);
5240     DeclRefExpr *DistRef = Actions.BuildDeclRefExpr(
5241         DistParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5242 
5243     SmallVector<Stmt *, 4> BodyStmts;
5244 
5245     // Capture all referenced variable references.
5246     // TODO: Instead of computing NewStart/NewStop/NewStep inside the
5247     // CapturedStmt, we could compute them before and capture the result, to be
5248     // used jointly with the LoopVar function.
5249     VarDecl *NewStart = precomputeExpr(Actions, BodyStmts, StartExpr, ".start");
5250     VarDecl *NewStop = precomputeExpr(Actions, BodyStmts, StopExpr, ".stop");
5251     VarDecl *NewStep = precomputeExpr(Actions, BodyStmts, StepExpr, ".step");
5252     auto BuildVarRef = [&](VarDecl *VD) {
5253       return buildDeclRefExpr(Actions, VD, VD->getType(), {});
5254     };
5255 
5256     IntegerLiteral *Zero = IntegerLiteral::Create(
5257         Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 0), LogicalTy, {});
5258     Expr *Dist;
5259     if (Rel == BO_NE) {
5260       // When using a != comparison, the increment can be +1 or -1. This can be
5261       // dynamic at runtime, so we need to check for the direction.
5262       Expr *IsNegStep = AssertSuccess(
5263           Actions.BuildBinOp(nullptr, {}, BO_LT, BuildVarRef(NewStep), Zero));
5264 
5265       // Positive increment.
5266       Expr *ForwardRange = AssertSuccess(Actions.BuildBinOp(
5267           nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5268       ForwardRange = AssertSuccess(
5269           Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, ForwardRange));
5270       Expr *ForwardDist = AssertSuccess(Actions.BuildBinOp(
5271           nullptr, {}, BO_Div, ForwardRange, BuildVarRef(NewStep)));
5272 
5273       // Negative increment.
5274       Expr *BackwardRange = AssertSuccess(Actions.BuildBinOp(
5275           nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5276       BackwardRange = AssertSuccess(
5277           Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, BackwardRange));
5278       Expr *NegIncAmount = AssertSuccess(
5279           Actions.BuildUnaryOp(nullptr, {}, UO_Minus, BuildVarRef(NewStep)));
5280       Expr *BackwardDist = AssertSuccess(
5281           Actions.BuildBinOp(nullptr, {}, BO_Div, BackwardRange, NegIncAmount));
5282 
5283       // Use the appropriate case.
5284       Dist = AssertSuccess(Actions.ActOnConditionalOp(
5285           {}, {}, IsNegStep, BackwardDist, ForwardDist));
5286     } else {
5287       assert((Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT) &&
5288              "Expected one of these relational operators");
5289 
5290       // We can derive the direction from any other comparison operator. It is
5291       // non well-formed OpenMP if Step increments/decrements in the other
5292       // directions. Whether at least the first iteration passes the loop
5293       // condition.
5294       Expr *HasAnyIteration = AssertSuccess(Actions.BuildBinOp(
5295           nullptr, {}, Rel, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5296 
5297       // Compute the range between first and last counter value.
5298       Expr *Range;
5299       if (Rel == BO_GE || Rel == BO_GT)
5300         Range = AssertSuccess(Actions.BuildBinOp(
5301             nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5302       else
5303         Range = AssertSuccess(Actions.BuildBinOp(
5304             nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5305 
5306       // Ensure unsigned range space.
5307       Range =
5308           AssertSuccess(Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, Range));
5309 
5310       if (Rel == BO_LE || Rel == BO_GE) {
5311         // Add one to the range if the relational operator is inclusive.
5312         Range =
5313             AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_PreInc, Range));
5314       }
5315 
5316       // Divide by the absolute step amount.
5317       Expr *Divisor = BuildVarRef(NewStep);
5318       if (Rel == BO_GE || Rel == BO_GT)
5319         Divisor =
5320             AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Minus, Divisor));
5321       Dist = AssertSuccess(
5322           Actions.BuildBinOp(nullptr, {}, BO_Div, Range, Divisor));
5323 
5324       // If there is not at least one iteration, the range contains garbage. Fix
5325       // to zero in this case.
5326       Dist = AssertSuccess(
5327           Actions.ActOnConditionalOp({}, {}, HasAnyIteration, Dist, Zero));
5328     }
5329 
5330     // Assign the result to the out-parameter.
5331     Stmt *ResultAssign = AssertSuccess(Actions.BuildBinOp(
5332         Actions.getCurScope(), {}, BO_Assign, DistRef, Dist));
5333     BodyStmts.push_back(ResultAssign);
5334 
5335     Body = AssertSuccess(Actions.ActOnCompoundStmt({}, {}, BodyStmts, false));
5336   }
5337 
5338   return cast<CapturedStmt>(
5339       AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5340 }
5341 
5342 /// Create a closure that computes the loop variable from the logical iteration
5343 /// number.
5344 ///
5345 /// \param Actions   The Sema object.
5346 /// \param LoopVarTy Type for the loop variable used for result value.
5347 /// \param LogicalTy Type for the logical iteration number.
5348 /// \param StartExpr Value of the loop counter at the first iteration.
5349 /// \param Step      Amount of increment after each iteration.
5350 /// \param Deref     Whether the loop variable is a dereference of the loop
5351 /// counter variable.
5352 ///
5353 /// \return Closure (CapturedStmt) of the loop value calculation.
buildLoopVarFunc(Sema & Actions,QualType LoopVarTy,QualType LogicalTy,DeclRefExpr * StartExpr,Expr * Step,bool Deref)5354 static CapturedStmt *buildLoopVarFunc(Sema &Actions, QualType LoopVarTy,
5355                                       QualType LogicalTy,
5356                                       DeclRefExpr *StartExpr, Expr *Step,
5357                                       bool Deref) {
5358   ASTContext &Ctx = Actions.getASTContext();
5359 
5360   // Pass the result as an out-parameter. Passing as return value would require
5361   // the OpenMPIRBuilder to know additional C/C++ semantics, such as how to
5362   // invoke a copy constructor.
5363   QualType TargetParamTy = Ctx.getLValueReferenceType(LoopVarTy);
5364   Sema::CapturedParamNameType Params[] = {{"LoopVar", TargetParamTy},
5365                                           {"Logical", LogicalTy},
5366                                           {StringRef(), QualType()}};
5367   Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5368 
5369   // Capture the initial iterator which represents the LoopVar value at the
5370   // zero's logical iteration. Since the original ForStmt/CXXForRangeStmt update
5371   // it in every iteration, capture it by value before it is modified.
5372   VarDecl *StartVar = cast<VarDecl>(StartExpr->getDecl());
5373   bool Invalid = Actions.tryCaptureVariable(StartVar, {},
5374                                             Sema::TryCapture_ExplicitByVal, {});
5375   (void)Invalid;
5376   assert(!Invalid && "Expecting capture-by-value to work.");
5377 
5378   Expr *Body;
5379   {
5380     Sema::CompoundScopeRAII CompoundScope(Actions);
5381     auto *CS = cast<CapturedDecl>(Actions.CurContext);
5382 
5383     ImplicitParamDecl *TargetParam = CS->getParam(0);
5384     DeclRefExpr *TargetRef = Actions.BuildDeclRefExpr(
5385         TargetParam, LoopVarTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5386     ImplicitParamDecl *IndvarParam = CS->getParam(1);
5387     DeclRefExpr *LogicalRef = Actions.BuildDeclRefExpr(
5388         IndvarParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5389 
5390     // Capture the Start expression.
5391     CaptureVars Recap(Actions);
5392     Expr *NewStart = AssertSuccess(Recap.TransformExpr(StartExpr));
5393     Expr *NewStep = AssertSuccess(Recap.TransformExpr(Step));
5394 
5395     Expr *Skip = AssertSuccess(
5396         Actions.BuildBinOp(nullptr, {}, BO_Mul, NewStep, LogicalRef));
5397     // TODO: Explicitly cast to the iterator's difference_type instead of
5398     // relying on implicit conversion.
5399     Expr *Advanced =
5400         AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, NewStart, Skip));
5401 
5402     if (Deref) {
5403       // For range-based for-loops convert the loop counter value to a concrete
5404       // loop variable value by dereferencing the iterator.
5405       Advanced =
5406           AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Deref, Advanced));
5407     }
5408 
5409     // Assign the result to the output parameter.
5410     Body = AssertSuccess(Actions.BuildBinOp(Actions.getCurScope(), {},
5411                                             BO_Assign, TargetRef, Advanced));
5412   }
5413   return cast<CapturedStmt>(
5414       AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5415 }
5416 
ActOnOpenMPCanonicalLoop(Stmt * AStmt)5417 StmtResult Sema::ActOnOpenMPCanonicalLoop(Stmt *AStmt) {
5418   ASTContext &Ctx = getASTContext();
5419 
5420   // Extract the common elements of ForStmt and CXXForRangeStmt:
5421   // Loop variable, repeat condition, increment
5422   Expr *Cond, *Inc;
5423   VarDecl *LIVDecl, *LUVDecl;
5424   if (auto *For = dyn_cast<ForStmt>(AStmt)) {
5425     Stmt *Init = For->getInit();
5426     if (auto *LCVarDeclStmt = dyn_cast<DeclStmt>(Init)) {
5427       // For statement declares loop variable.
5428       LIVDecl = cast<VarDecl>(LCVarDeclStmt->getSingleDecl());
5429     } else if (auto *LCAssign = dyn_cast<BinaryOperator>(Init)) {
5430       // For statement reuses variable.
5431       assert(LCAssign->getOpcode() == BO_Assign &&
5432              "init part must be a loop variable assignment");
5433       auto *CounterRef = cast<DeclRefExpr>(LCAssign->getLHS());
5434       LIVDecl = cast<VarDecl>(CounterRef->getDecl());
5435     } else
5436       llvm_unreachable("Cannot determine loop variable");
5437     LUVDecl = LIVDecl;
5438 
5439     Cond = For->getCond();
5440     Inc = For->getInc();
5441   } else if (auto *RangeFor = dyn_cast<CXXForRangeStmt>(AStmt)) {
5442     DeclStmt *BeginStmt = RangeFor->getBeginStmt();
5443     LIVDecl = cast<VarDecl>(BeginStmt->getSingleDecl());
5444     LUVDecl = RangeFor->getLoopVariable();
5445 
5446     Cond = RangeFor->getCond();
5447     Inc = RangeFor->getInc();
5448   } else
5449     llvm_unreachable("unhandled kind of loop");
5450 
5451   QualType CounterTy = LIVDecl->getType();
5452   QualType LVTy = LUVDecl->getType();
5453 
5454   // Analyze the loop condition.
5455   Expr *LHS, *RHS;
5456   BinaryOperator::Opcode CondRel;
5457   Cond = Cond->IgnoreImplicit();
5458   if (auto *CondBinExpr = dyn_cast<BinaryOperator>(Cond)) {
5459     LHS = CondBinExpr->getLHS();
5460     RHS = CondBinExpr->getRHS();
5461     CondRel = CondBinExpr->getOpcode();
5462   } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Cond)) {
5463     assert(CondCXXOp->getNumArgs() == 2 && "Comparison should have 2 operands");
5464     LHS = CondCXXOp->getArg(0);
5465     RHS = CondCXXOp->getArg(1);
5466     switch (CondCXXOp->getOperator()) {
5467     case OO_ExclaimEqual:
5468       CondRel = BO_NE;
5469       break;
5470     case OO_Less:
5471       CondRel = BO_LT;
5472       break;
5473     case OO_LessEqual:
5474       CondRel = BO_LE;
5475       break;
5476     case OO_Greater:
5477       CondRel = BO_GT;
5478       break;
5479     case OO_GreaterEqual:
5480       CondRel = BO_GE;
5481       break;
5482     default:
5483       llvm_unreachable("unexpected iterator operator");
5484     }
5485   } else
5486     llvm_unreachable("unexpected loop condition");
5487 
5488   // Normalize such that the loop counter is on the LHS.
5489   if (!isa<DeclRefExpr>(LHS->IgnoreImplicit()) ||
5490       cast<DeclRefExpr>(LHS->IgnoreImplicit())->getDecl() != LIVDecl) {
5491     std::swap(LHS, RHS);
5492     CondRel = BinaryOperator::reverseComparisonOp(CondRel);
5493   }
5494   auto *CounterRef = cast<DeclRefExpr>(LHS->IgnoreImplicit());
5495 
5496   // Decide the bit width for the logical iteration counter. By default use the
5497   // unsigned ptrdiff_t integer size (for iterators and pointers).
5498   // TODO: For iterators, use iterator::difference_type,
5499   // std::iterator_traits<>::difference_type or decltype(it - end).
5500   QualType LogicalTy = Ctx.getUnsignedPointerDiffType();
5501   if (CounterTy->isIntegerType()) {
5502     unsigned BitWidth = Ctx.getIntWidth(CounterTy);
5503     LogicalTy = Ctx.getIntTypeForBitwidth(BitWidth, false);
5504   }
5505 
5506   // Analyze the loop increment.
5507   Expr *Step;
5508   if (auto *IncUn = dyn_cast<UnaryOperator>(Inc)) {
5509     int Direction;
5510     switch (IncUn->getOpcode()) {
5511     case UO_PreInc:
5512     case UO_PostInc:
5513       Direction = 1;
5514       break;
5515     case UO_PreDec:
5516     case UO_PostDec:
5517       Direction = -1;
5518       break;
5519     default:
5520       llvm_unreachable("unhandled unary increment operator");
5521     }
5522     Step = IntegerLiteral::Create(
5523         Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), Direction), LogicalTy, {});
5524   } else if (auto *IncBin = dyn_cast<BinaryOperator>(Inc)) {
5525     if (IncBin->getOpcode() == BO_AddAssign) {
5526       Step = IncBin->getRHS();
5527     } else if (IncBin->getOpcode() == BO_SubAssign) {
5528       Step =
5529           AssertSuccess(BuildUnaryOp(nullptr, {}, UO_Minus, IncBin->getRHS()));
5530     } else
5531       llvm_unreachable("unhandled binary increment operator");
5532   } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Inc)) {
5533     switch (CondCXXOp->getOperator()) {
5534     case OO_PlusPlus:
5535       Step = IntegerLiteral::Create(
5536           Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {});
5537       break;
5538     case OO_MinusMinus:
5539       Step = IntegerLiteral::Create(
5540           Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), -1), LogicalTy, {});
5541       break;
5542     case OO_PlusEqual:
5543       Step = CondCXXOp->getArg(1);
5544       break;
5545     case OO_MinusEqual:
5546       Step = AssertSuccess(
5547           BuildUnaryOp(nullptr, {}, UO_Minus, CondCXXOp->getArg(1)));
5548       break;
5549     default:
5550       llvm_unreachable("unhandled overloaded increment operator");
5551     }
5552   } else
5553     llvm_unreachable("unknown increment expression");
5554 
5555   CapturedStmt *DistanceFunc =
5556       buildDistanceFunc(*this, LogicalTy, CondRel, LHS, RHS, Step);
5557   CapturedStmt *LoopVarFunc = buildLoopVarFunc(
5558       *this, LVTy, LogicalTy, CounterRef, Step, isa<CXXForRangeStmt>(AStmt));
5559   DeclRefExpr *LVRef = BuildDeclRefExpr(LUVDecl, LUVDecl->getType(), VK_LValue,
5560                                         {}, nullptr, nullptr, {}, nullptr);
5561   return OMPCanonicalLoop::create(getASTContext(), AStmt, DistanceFunc,
5562                                   LoopVarFunc, LVRef);
5563 }
5564 
5565 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
5566                                             CXXScopeSpec &MapperIdScopeSpec,
5567                                             const DeclarationNameInfo &MapperId,
5568                                             QualType Type,
5569                                             Expr *UnresolvedMapper);
5570 
5571 /// Perform DFS through the structure/class data members trying to find
5572 /// member(s) with user-defined 'default' mapper and generate implicit map
5573 /// clauses for such members with the found 'default' mapper.
5574 static void
processImplicitMapsWithDefaultMappers(Sema & S,DSAStackTy * Stack,SmallVectorImpl<OMPClause * > & Clauses)5575 processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack,
5576                                       SmallVectorImpl<OMPClause *> &Clauses) {
5577   // Check for the deault mapper for data members.
5578   if (S.getLangOpts().OpenMP < 50)
5579     return;
5580   SmallVector<OMPClause *, 4> ImplicitMaps;
5581   for (int Cnt = 0, EndCnt = Clauses.size(); Cnt < EndCnt; ++Cnt) {
5582     auto *C = dyn_cast<OMPMapClause>(Clauses[Cnt]);
5583     if (!C)
5584       continue;
5585     SmallVector<Expr *, 4> SubExprs;
5586     auto *MI = C->mapperlist_begin();
5587     for (auto I = C->varlist_begin(), End = C->varlist_end(); I != End;
5588          ++I, ++MI) {
5589       // Expression is mapped using mapper - skip it.
5590       if (*MI)
5591         continue;
5592       Expr *E = *I;
5593       // Expression is dependent - skip it, build the mapper when it gets
5594       // instantiated.
5595       if (E->isTypeDependent() || E->isValueDependent() ||
5596           E->containsUnexpandedParameterPack())
5597         continue;
5598       // Array section - need to check for the mapping of the array section
5599       // element.
5600       QualType CanonType = E->getType().getCanonicalType();
5601       if (CanonType->isSpecificBuiltinType(BuiltinType::OMPArraySection)) {
5602         const auto *OASE = cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts());
5603         QualType BaseType =
5604             OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
5605         QualType ElemType;
5606         if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
5607           ElemType = ATy->getElementType();
5608         else
5609           ElemType = BaseType->getPointeeType();
5610         CanonType = ElemType;
5611       }
5612 
5613       // DFS over data members in structures/classes.
5614       SmallVector<std::pair<QualType, FieldDecl *>, 4> Types(
5615           1, {CanonType, nullptr});
5616       llvm::DenseMap<const Type *, Expr *> Visited;
5617       SmallVector<std::pair<FieldDecl *, unsigned>, 4> ParentChain(
5618           1, {nullptr, 1});
5619       while (!Types.empty()) {
5620         QualType BaseType;
5621         FieldDecl *CurFD;
5622         std::tie(BaseType, CurFD) = Types.pop_back_val();
5623         while (ParentChain.back().second == 0)
5624           ParentChain.pop_back();
5625         --ParentChain.back().second;
5626         if (BaseType.isNull())
5627           continue;
5628         // Only structs/classes are allowed to have mappers.
5629         const RecordDecl *RD = BaseType.getCanonicalType()->getAsRecordDecl();
5630         if (!RD)
5631           continue;
5632         auto It = Visited.find(BaseType.getTypePtr());
5633         if (It == Visited.end()) {
5634           // Try to find the associated user-defined mapper.
5635           CXXScopeSpec MapperIdScopeSpec;
5636           DeclarationNameInfo DefaultMapperId;
5637           DefaultMapperId.setName(S.Context.DeclarationNames.getIdentifier(
5638               &S.Context.Idents.get("default")));
5639           DefaultMapperId.setLoc(E->getExprLoc());
5640           ExprResult ER = buildUserDefinedMapperRef(
5641               S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId,
5642               BaseType, /*UnresolvedMapper=*/nullptr);
5643           if (ER.isInvalid())
5644             continue;
5645           It = Visited.try_emplace(BaseType.getTypePtr(), ER.get()).first;
5646         }
5647         // Found default mapper.
5648         if (It->second) {
5649           auto *OE = new (S.Context) OpaqueValueExpr(E->getExprLoc(), CanonType,
5650                                                      VK_LValue, OK_Ordinary, E);
5651           OE->setIsUnique(/*V=*/true);
5652           Expr *BaseExpr = OE;
5653           for (const auto &P : ParentChain) {
5654             if (P.first) {
5655               BaseExpr = S.BuildMemberExpr(
5656                   BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
5657                   NestedNameSpecifierLoc(), SourceLocation(), P.first,
5658                   DeclAccessPair::make(P.first, P.first->getAccess()),
5659                   /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
5660                   P.first->getType(), VK_LValue, OK_Ordinary);
5661               BaseExpr = S.DefaultLvalueConversion(BaseExpr).get();
5662             }
5663           }
5664           if (CurFD)
5665             BaseExpr = S.BuildMemberExpr(
5666                 BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
5667                 NestedNameSpecifierLoc(), SourceLocation(), CurFD,
5668                 DeclAccessPair::make(CurFD, CurFD->getAccess()),
5669                 /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
5670                 CurFD->getType(), VK_LValue, OK_Ordinary);
5671           SubExprs.push_back(BaseExpr);
5672           continue;
5673         }
5674         // Check for the "default" mapper for data memebers.
5675         bool FirstIter = true;
5676         for (FieldDecl *FD : RD->fields()) {
5677           if (!FD)
5678             continue;
5679           QualType FieldTy = FD->getType();
5680           if (FieldTy.isNull() ||
5681               !(FieldTy->isStructureOrClassType() || FieldTy->isUnionType()))
5682             continue;
5683           if (FirstIter) {
5684             FirstIter = false;
5685             ParentChain.emplace_back(CurFD, 1);
5686           } else {
5687             ++ParentChain.back().second;
5688           }
5689           Types.emplace_back(FieldTy, FD);
5690         }
5691       }
5692     }
5693     if (SubExprs.empty())
5694       continue;
5695     CXXScopeSpec MapperIdScopeSpec;
5696     DeclarationNameInfo MapperId;
5697     if (OMPClause *NewClause = S.ActOnOpenMPMapClause(
5698             C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
5699             MapperIdScopeSpec, MapperId, C->getMapType(),
5700             /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
5701             SubExprs, OMPVarListLocTy()))
5702       Clauses.push_back(NewClause);
5703   }
5704 }
5705 
ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,const DeclarationNameInfo & DirName,OpenMPDirectiveKind CancelRegion,ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)5706 StmtResult Sema::ActOnOpenMPExecutableDirective(
5707     OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
5708     OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
5709     Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
5710   StmtResult Res = StmtError();
5711   // First check CancelRegion which is then used in checkNestingOfRegions.
5712   if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
5713       checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
5714                             StartLoc))
5715     return StmtError();
5716 
5717   llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
5718   VarsWithInheritedDSAType VarsWithInheritedDSA;
5719   bool ErrorFound = false;
5720   ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
5721   if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic &&
5722       Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master &&
5723       Kind != OMPD_masked && !isOpenMPLoopTransformationDirective(Kind)) {
5724     assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5725 
5726     // Check default data sharing attributes for referenced variables.
5727     DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
5728     int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
5729     Stmt *S = AStmt;
5730     while (--ThisCaptureLevel >= 0)
5731       S = cast<CapturedStmt>(S)->getCapturedStmt();
5732     DSAChecker.Visit(S);
5733     if (!isOpenMPTargetDataManagementDirective(Kind) &&
5734         !isOpenMPTaskingDirective(Kind)) {
5735       // Visit subcaptures to generate implicit clauses for captured vars.
5736       auto *CS = cast<CapturedStmt>(AStmt);
5737       SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
5738       getOpenMPCaptureRegions(CaptureRegions, Kind);
5739       // Ignore outer tasking regions for target directives.
5740       if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
5741         CS = cast<CapturedStmt>(CS->getCapturedStmt());
5742       DSAChecker.visitSubCaptures(CS);
5743     }
5744     if (DSAChecker.isErrorFound())
5745       return StmtError();
5746     // Generate list of implicitly defined firstprivate variables.
5747     VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
5748 
5749     SmallVector<Expr *, 4> ImplicitFirstprivates(
5750         DSAChecker.getImplicitFirstprivate().begin(),
5751         DSAChecker.getImplicitFirstprivate().end());
5752     const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
5753     SmallVector<Expr *, 4> ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete];
5754     SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
5755         ImplicitMapModifiers[DefaultmapKindNum];
5756     SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers>
5757         ImplicitMapModifiersLoc[DefaultmapKindNum];
5758     // Get the original location of present modifier from Defaultmap clause.
5759     SourceLocation PresentModifierLocs[DefaultmapKindNum];
5760     for (OMPClause *C : Clauses) {
5761       if (auto *DMC = dyn_cast<OMPDefaultmapClause>(C))
5762         if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present)
5763           PresentModifierLocs[DMC->getDefaultmapKind()] =
5764               DMC->getDefaultmapModifierLoc();
5765     }
5766     for (unsigned VC = 0; VC < DefaultmapKindNum; ++VC) {
5767       auto Kind = static_cast<OpenMPDefaultmapClauseKind>(VC);
5768       for (unsigned I = 0; I < OMPC_MAP_delete; ++I) {
5769         ArrayRef<Expr *> ImplicitMap = DSAChecker.getImplicitMap(
5770             Kind, static_cast<OpenMPMapClauseKind>(I));
5771         ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end());
5772       }
5773       ArrayRef<OpenMPMapModifierKind> ImplicitModifier =
5774           DSAChecker.getImplicitMapModifier(Kind);
5775       ImplicitMapModifiers[VC].append(ImplicitModifier.begin(),
5776                                       ImplicitModifier.end());
5777       std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]),
5778                   ImplicitModifier.size(), PresentModifierLocs[VC]);
5779     }
5780     // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
5781     for (OMPClause *C : Clauses) {
5782       if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
5783         for (Expr *E : IRC->taskgroup_descriptors())
5784           if (E)
5785             ImplicitFirstprivates.emplace_back(E);
5786       }
5787       // OpenMP 5.0, 2.10.1 task Construct
5788       // [detach clause]... The event-handle will be considered as if it was
5789       // specified on a firstprivate clause.
5790       if (auto *DC = dyn_cast<OMPDetachClause>(C))
5791         ImplicitFirstprivates.push_back(DC->getEventHandler());
5792     }
5793     if (!ImplicitFirstprivates.empty()) {
5794       if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
5795               ImplicitFirstprivates, SourceLocation(), SourceLocation(),
5796               SourceLocation())) {
5797         ClausesWithImplicit.push_back(Implicit);
5798         ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
5799                      ImplicitFirstprivates.size();
5800       } else {
5801         ErrorFound = true;
5802       }
5803     }
5804     for (unsigned I = 0, E = DefaultmapKindNum; I < E; ++I) {
5805       int ClauseKindCnt = -1;
5806       for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps[I]) {
5807         ++ClauseKindCnt;
5808         if (ImplicitMap.empty())
5809           continue;
5810         CXXScopeSpec MapperIdScopeSpec;
5811         DeclarationNameInfo MapperId;
5812         auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
5813         if (OMPClause *Implicit = ActOnOpenMPMapClause(
5814                 ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I],
5815                 MapperIdScopeSpec, MapperId, Kind, /*IsMapTypeImplicit=*/true,
5816                 SourceLocation(), SourceLocation(), ImplicitMap,
5817                 OMPVarListLocTy())) {
5818           ClausesWithImplicit.emplace_back(Implicit);
5819           ErrorFound |= cast<OMPMapClause>(Implicit)->varlist_size() !=
5820                         ImplicitMap.size();
5821         } else {
5822           ErrorFound = true;
5823         }
5824       }
5825     }
5826     // Build expressions for implicit maps of data members with 'default'
5827     // mappers.
5828     if (LangOpts.OpenMP >= 50)
5829       processImplicitMapsWithDefaultMappers(*this, DSAStack,
5830                                             ClausesWithImplicit);
5831   }
5832 
5833   llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
5834   switch (Kind) {
5835   case OMPD_parallel:
5836     Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
5837                                        EndLoc);
5838     AllowedNameModifiers.push_back(OMPD_parallel);
5839     break;
5840   case OMPD_simd:
5841     Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5842                                    VarsWithInheritedDSA);
5843     if (LangOpts.OpenMP >= 50)
5844       AllowedNameModifiers.push_back(OMPD_simd);
5845     break;
5846   case OMPD_tile:
5847     Res =
5848         ActOnOpenMPTileDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5849     break;
5850   case OMPD_for:
5851     Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5852                                   VarsWithInheritedDSA);
5853     break;
5854   case OMPD_for_simd:
5855     Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5856                                       EndLoc, VarsWithInheritedDSA);
5857     if (LangOpts.OpenMP >= 50)
5858       AllowedNameModifiers.push_back(OMPD_simd);
5859     break;
5860   case OMPD_sections:
5861     Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
5862                                        EndLoc);
5863     break;
5864   case OMPD_section:
5865     assert(ClausesWithImplicit.empty() &&
5866            "No clauses are allowed for 'omp section' directive");
5867     Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
5868     break;
5869   case OMPD_single:
5870     Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
5871                                      EndLoc);
5872     break;
5873   case OMPD_master:
5874     assert(ClausesWithImplicit.empty() &&
5875            "No clauses are allowed for 'omp master' directive");
5876     Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
5877     break;
5878   case OMPD_masked:
5879     Res = ActOnOpenMPMaskedDirective(ClausesWithImplicit, AStmt, StartLoc,
5880                                      EndLoc);
5881     break;
5882   case OMPD_critical:
5883     Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
5884                                        StartLoc, EndLoc);
5885     break;
5886   case OMPD_parallel_for:
5887     Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
5888                                           EndLoc, VarsWithInheritedDSA);
5889     AllowedNameModifiers.push_back(OMPD_parallel);
5890     break;
5891   case OMPD_parallel_for_simd:
5892     Res = ActOnOpenMPParallelForSimdDirective(
5893         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5894     AllowedNameModifiers.push_back(OMPD_parallel);
5895     if (LangOpts.OpenMP >= 50)
5896       AllowedNameModifiers.push_back(OMPD_simd);
5897     break;
5898   case OMPD_parallel_master:
5899     Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
5900                                                StartLoc, EndLoc);
5901     AllowedNameModifiers.push_back(OMPD_parallel);
5902     break;
5903   case OMPD_parallel_sections:
5904     Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
5905                                                StartLoc, EndLoc);
5906     AllowedNameModifiers.push_back(OMPD_parallel);
5907     break;
5908   case OMPD_task:
5909     Res =
5910         ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5911     AllowedNameModifiers.push_back(OMPD_task);
5912     break;
5913   case OMPD_taskyield:
5914     assert(ClausesWithImplicit.empty() &&
5915            "No clauses are allowed for 'omp taskyield' directive");
5916     assert(AStmt == nullptr &&
5917            "No associated statement allowed for 'omp taskyield' directive");
5918     Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
5919     break;
5920   case OMPD_barrier:
5921     assert(ClausesWithImplicit.empty() &&
5922            "No clauses are allowed for 'omp barrier' directive");
5923     assert(AStmt == nullptr &&
5924            "No associated statement allowed for 'omp barrier' directive");
5925     Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
5926     break;
5927   case OMPD_taskwait:
5928     assert(ClausesWithImplicit.empty() &&
5929            "No clauses are allowed for 'omp taskwait' directive");
5930     assert(AStmt == nullptr &&
5931            "No associated statement allowed for 'omp taskwait' directive");
5932     Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
5933     break;
5934   case OMPD_taskgroup:
5935     Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
5936                                         EndLoc);
5937     break;
5938   case OMPD_flush:
5939     assert(AStmt == nullptr &&
5940            "No associated statement allowed for 'omp flush' directive");
5941     Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
5942     break;
5943   case OMPD_depobj:
5944     assert(AStmt == nullptr &&
5945            "No associated statement allowed for 'omp depobj' directive");
5946     Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc);
5947     break;
5948   case OMPD_scan:
5949     assert(AStmt == nullptr &&
5950            "No associated statement allowed for 'omp scan' directive");
5951     Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc);
5952     break;
5953   case OMPD_ordered:
5954     Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
5955                                       EndLoc);
5956     break;
5957   case OMPD_atomic:
5958     Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
5959                                      EndLoc);
5960     break;
5961   case OMPD_teams:
5962     Res =
5963         ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5964     break;
5965   case OMPD_target:
5966     Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
5967                                      EndLoc);
5968     AllowedNameModifiers.push_back(OMPD_target);
5969     break;
5970   case OMPD_target_parallel:
5971     Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
5972                                              StartLoc, EndLoc);
5973     AllowedNameModifiers.push_back(OMPD_target);
5974     AllowedNameModifiers.push_back(OMPD_parallel);
5975     break;
5976   case OMPD_target_parallel_for:
5977     Res = ActOnOpenMPTargetParallelForDirective(
5978         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5979     AllowedNameModifiers.push_back(OMPD_target);
5980     AllowedNameModifiers.push_back(OMPD_parallel);
5981     break;
5982   case OMPD_cancellation_point:
5983     assert(ClausesWithImplicit.empty() &&
5984            "No clauses are allowed for 'omp cancellation point' directive");
5985     assert(AStmt == nullptr && "No associated statement allowed for 'omp "
5986                                "cancellation point' directive");
5987     Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
5988     break;
5989   case OMPD_cancel:
5990     assert(AStmt == nullptr &&
5991            "No associated statement allowed for 'omp cancel' directive");
5992     Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
5993                                      CancelRegion);
5994     AllowedNameModifiers.push_back(OMPD_cancel);
5995     break;
5996   case OMPD_target_data:
5997     Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
5998                                          EndLoc);
5999     AllowedNameModifiers.push_back(OMPD_target_data);
6000     break;
6001   case OMPD_target_enter_data:
6002     Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
6003                                               EndLoc, AStmt);
6004     AllowedNameModifiers.push_back(OMPD_target_enter_data);
6005     break;
6006   case OMPD_target_exit_data:
6007     Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
6008                                              EndLoc, AStmt);
6009     AllowedNameModifiers.push_back(OMPD_target_exit_data);
6010     break;
6011   case OMPD_taskloop:
6012     Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
6013                                        EndLoc, VarsWithInheritedDSA);
6014     AllowedNameModifiers.push_back(OMPD_taskloop);
6015     break;
6016   case OMPD_taskloop_simd:
6017     Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6018                                            EndLoc, VarsWithInheritedDSA);
6019     AllowedNameModifiers.push_back(OMPD_taskloop);
6020     if (LangOpts.OpenMP >= 50)
6021       AllowedNameModifiers.push_back(OMPD_simd);
6022     break;
6023   case OMPD_master_taskloop:
6024     Res = ActOnOpenMPMasterTaskLoopDirective(
6025         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6026     AllowedNameModifiers.push_back(OMPD_taskloop);
6027     break;
6028   case OMPD_master_taskloop_simd:
6029     Res = ActOnOpenMPMasterTaskLoopSimdDirective(
6030         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6031     AllowedNameModifiers.push_back(OMPD_taskloop);
6032     if (LangOpts.OpenMP >= 50)
6033       AllowedNameModifiers.push_back(OMPD_simd);
6034     break;
6035   case OMPD_parallel_master_taskloop:
6036     Res = ActOnOpenMPParallelMasterTaskLoopDirective(
6037         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6038     AllowedNameModifiers.push_back(OMPD_taskloop);
6039     AllowedNameModifiers.push_back(OMPD_parallel);
6040     break;
6041   case OMPD_parallel_master_taskloop_simd:
6042     Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective(
6043         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6044     AllowedNameModifiers.push_back(OMPD_taskloop);
6045     AllowedNameModifiers.push_back(OMPD_parallel);
6046     if (LangOpts.OpenMP >= 50)
6047       AllowedNameModifiers.push_back(OMPD_simd);
6048     break;
6049   case OMPD_distribute:
6050     Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
6051                                          EndLoc, VarsWithInheritedDSA);
6052     break;
6053   case OMPD_target_update:
6054     Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
6055                                            EndLoc, AStmt);
6056     AllowedNameModifiers.push_back(OMPD_target_update);
6057     break;
6058   case OMPD_distribute_parallel_for:
6059     Res = ActOnOpenMPDistributeParallelForDirective(
6060         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6061     AllowedNameModifiers.push_back(OMPD_parallel);
6062     break;
6063   case OMPD_distribute_parallel_for_simd:
6064     Res = ActOnOpenMPDistributeParallelForSimdDirective(
6065         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6066     AllowedNameModifiers.push_back(OMPD_parallel);
6067     if (LangOpts.OpenMP >= 50)
6068       AllowedNameModifiers.push_back(OMPD_simd);
6069     break;
6070   case OMPD_distribute_simd:
6071     Res = ActOnOpenMPDistributeSimdDirective(
6072         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6073     if (LangOpts.OpenMP >= 50)
6074       AllowedNameModifiers.push_back(OMPD_simd);
6075     break;
6076   case OMPD_target_parallel_for_simd:
6077     Res = ActOnOpenMPTargetParallelForSimdDirective(
6078         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6079     AllowedNameModifiers.push_back(OMPD_target);
6080     AllowedNameModifiers.push_back(OMPD_parallel);
6081     if (LangOpts.OpenMP >= 50)
6082       AllowedNameModifiers.push_back(OMPD_simd);
6083     break;
6084   case OMPD_target_simd:
6085     Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6086                                          EndLoc, VarsWithInheritedDSA);
6087     AllowedNameModifiers.push_back(OMPD_target);
6088     if (LangOpts.OpenMP >= 50)
6089       AllowedNameModifiers.push_back(OMPD_simd);
6090     break;
6091   case OMPD_teams_distribute:
6092     Res = ActOnOpenMPTeamsDistributeDirective(
6093         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6094     break;
6095   case OMPD_teams_distribute_simd:
6096     Res = ActOnOpenMPTeamsDistributeSimdDirective(
6097         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6098     if (LangOpts.OpenMP >= 50)
6099       AllowedNameModifiers.push_back(OMPD_simd);
6100     break;
6101   case OMPD_teams_distribute_parallel_for_simd:
6102     Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
6103         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6104     AllowedNameModifiers.push_back(OMPD_parallel);
6105     if (LangOpts.OpenMP >= 50)
6106       AllowedNameModifiers.push_back(OMPD_simd);
6107     break;
6108   case OMPD_teams_distribute_parallel_for:
6109     Res = ActOnOpenMPTeamsDistributeParallelForDirective(
6110         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6111     AllowedNameModifiers.push_back(OMPD_parallel);
6112     break;
6113   case OMPD_target_teams:
6114     Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
6115                                           EndLoc);
6116     AllowedNameModifiers.push_back(OMPD_target);
6117     break;
6118   case OMPD_target_teams_distribute:
6119     Res = ActOnOpenMPTargetTeamsDistributeDirective(
6120         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6121     AllowedNameModifiers.push_back(OMPD_target);
6122     break;
6123   case OMPD_target_teams_distribute_parallel_for:
6124     Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
6125         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6126     AllowedNameModifiers.push_back(OMPD_target);
6127     AllowedNameModifiers.push_back(OMPD_parallel);
6128     break;
6129   case OMPD_target_teams_distribute_parallel_for_simd:
6130     Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
6131         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6132     AllowedNameModifiers.push_back(OMPD_target);
6133     AllowedNameModifiers.push_back(OMPD_parallel);
6134     if (LangOpts.OpenMP >= 50)
6135       AllowedNameModifiers.push_back(OMPD_simd);
6136     break;
6137   case OMPD_target_teams_distribute_simd:
6138     Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
6139         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6140     AllowedNameModifiers.push_back(OMPD_target);
6141     if (LangOpts.OpenMP >= 50)
6142       AllowedNameModifiers.push_back(OMPD_simd);
6143     break;
6144   case OMPD_interop:
6145     assert(AStmt == nullptr &&
6146            "No associated statement allowed for 'omp interop' directive");
6147     Res = ActOnOpenMPInteropDirective(ClausesWithImplicit, StartLoc, EndLoc);
6148     break;
6149   case OMPD_dispatch:
6150     Res = ActOnOpenMPDispatchDirective(ClausesWithImplicit, AStmt, StartLoc,
6151                                        EndLoc);
6152     break;
6153   case OMPD_declare_target:
6154   case OMPD_end_declare_target:
6155   case OMPD_threadprivate:
6156   case OMPD_allocate:
6157   case OMPD_declare_reduction:
6158   case OMPD_declare_mapper:
6159   case OMPD_declare_simd:
6160   case OMPD_requires:
6161   case OMPD_declare_variant:
6162   case OMPD_begin_declare_variant:
6163   case OMPD_end_declare_variant:
6164     llvm_unreachable("OpenMP Directive is not allowed");
6165   case OMPD_unknown:
6166   default:
6167     llvm_unreachable("Unknown OpenMP directive");
6168   }
6169 
6170   ErrorFound = Res.isInvalid() || ErrorFound;
6171 
6172   // Check variables in the clauses if default(none) or
6173   // default(firstprivate) was specified.
6174   if (DSAStack->getDefaultDSA() == DSA_none ||
6175       DSAStack->getDefaultDSA() == DSA_firstprivate) {
6176     DSAAttrChecker DSAChecker(DSAStack, *this, nullptr);
6177     for (OMPClause *C : Clauses) {
6178       switch (C->getClauseKind()) {
6179       case OMPC_num_threads:
6180       case OMPC_dist_schedule:
6181         // Do not analyse if no parent teams directive.
6182         if (isOpenMPTeamsDirective(Kind))
6183           break;
6184         continue;
6185       case OMPC_if:
6186         if (isOpenMPTeamsDirective(Kind) &&
6187             cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
6188           break;
6189         if (isOpenMPParallelDirective(Kind) &&
6190             isOpenMPTaskLoopDirective(Kind) &&
6191             cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel)
6192           break;
6193         continue;
6194       case OMPC_schedule:
6195       case OMPC_detach:
6196         break;
6197       case OMPC_grainsize:
6198       case OMPC_num_tasks:
6199       case OMPC_final:
6200       case OMPC_priority:
6201       case OMPC_novariants:
6202       case OMPC_nocontext:
6203         // Do not analyze if no parent parallel directive.
6204         if (isOpenMPParallelDirective(Kind))
6205           break;
6206         continue;
6207       case OMPC_ordered:
6208       case OMPC_device:
6209       case OMPC_num_teams:
6210       case OMPC_thread_limit:
6211       case OMPC_hint:
6212       case OMPC_collapse:
6213       case OMPC_safelen:
6214       case OMPC_simdlen:
6215       case OMPC_sizes:
6216       case OMPC_default:
6217       case OMPC_proc_bind:
6218       case OMPC_private:
6219       case OMPC_firstprivate:
6220       case OMPC_lastprivate:
6221       case OMPC_shared:
6222       case OMPC_reduction:
6223       case OMPC_task_reduction:
6224       case OMPC_in_reduction:
6225       case OMPC_linear:
6226       case OMPC_aligned:
6227       case OMPC_copyin:
6228       case OMPC_copyprivate:
6229       case OMPC_nowait:
6230       case OMPC_untied:
6231       case OMPC_mergeable:
6232       case OMPC_allocate:
6233       case OMPC_read:
6234       case OMPC_write:
6235       case OMPC_update:
6236       case OMPC_capture:
6237       case OMPC_seq_cst:
6238       case OMPC_acq_rel:
6239       case OMPC_acquire:
6240       case OMPC_release:
6241       case OMPC_relaxed:
6242       case OMPC_depend:
6243       case OMPC_threads:
6244       case OMPC_simd:
6245       case OMPC_map:
6246       case OMPC_nogroup:
6247       case OMPC_defaultmap:
6248       case OMPC_to:
6249       case OMPC_from:
6250       case OMPC_use_device_ptr:
6251       case OMPC_use_device_addr:
6252       case OMPC_is_device_ptr:
6253       case OMPC_nontemporal:
6254       case OMPC_order:
6255       case OMPC_destroy:
6256       case OMPC_inclusive:
6257       case OMPC_exclusive:
6258       case OMPC_uses_allocators:
6259       case OMPC_affinity:
6260         continue;
6261       case OMPC_allocator:
6262       case OMPC_flush:
6263       case OMPC_depobj:
6264       case OMPC_threadprivate:
6265       case OMPC_uniform:
6266       case OMPC_unknown:
6267       case OMPC_unified_address:
6268       case OMPC_unified_shared_memory:
6269       case OMPC_reverse_offload:
6270       case OMPC_dynamic_allocators:
6271       case OMPC_atomic_default_mem_order:
6272       case OMPC_device_type:
6273       case OMPC_match:
6274       default:
6275         llvm_unreachable("Unexpected clause");
6276       }
6277       for (Stmt *CC : C->children()) {
6278         if (CC)
6279           DSAChecker.Visit(CC);
6280       }
6281     }
6282     for (const auto &P : DSAChecker.getVarsWithInheritedDSA())
6283       VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
6284   }
6285   for (const auto &P : VarsWithInheritedDSA) {
6286     if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
6287       continue;
6288     ErrorFound = true;
6289     if (DSAStack->getDefaultDSA() == DSA_none ||
6290         DSAStack->getDefaultDSA() == DSA_firstprivate) {
6291       Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
6292           << P.first << P.second->getSourceRange();
6293       Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
6294     } else if (getLangOpts().OpenMP >= 50) {
6295       Diag(P.second->getExprLoc(),
6296            diag::err_omp_defaultmap_no_attr_for_variable)
6297           << P.first << P.second->getSourceRange();
6298       Diag(DSAStack->getDefaultDSALocation(),
6299            diag::note_omp_defaultmap_attr_none);
6300     }
6301   }
6302 
6303   if (!AllowedNameModifiers.empty())
6304     ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
6305                  ErrorFound;
6306 
6307   if (ErrorFound)
6308     return StmtError();
6309 
6310   if (!CurContext->isDependentContext() &&
6311       isOpenMPTargetExecutionDirective(Kind) &&
6312       !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
6313         DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
6314         DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
6315         DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
6316     // Register target to DSA Stack.
6317     DSAStack->addTargetDirLocation(StartLoc);
6318   }
6319 
6320   return Res;
6321 }
6322 
ActOnOpenMPDeclareSimdDirective(DeclGroupPtrTy DG,OMPDeclareSimdDeclAttr::BranchStateTy BS,Expr * Simdlen,ArrayRef<Expr * > Uniforms,ArrayRef<Expr * > Aligneds,ArrayRef<Expr * > Alignments,ArrayRef<Expr * > Linears,ArrayRef<unsigned> LinModifiers,ArrayRef<Expr * > Steps,SourceRange SR)6323 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
6324     DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
6325     ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
6326     ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
6327     ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
6328   assert(Aligneds.size() == Alignments.size());
6329   assert(Linears.size() == LinModifiers.size());
6330   assert(Linears.size() == Steps.size());
6331   if (!DG || DG.get().isNull())
6332     return DeclGroupPtrTy();
6333 
6334   const int SimdId = 0;
6335   if (!DG.get().isSingleDecl()) {
6336     Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
6337         << SimdId;
6338     return DG;
6339   }
6340   Decl *ADecl = DG.get().getSingleDecl();
6341   if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
6342     ADecl = FTD->getTemplatedDecl();
6343 
6344   auto *FD = dyn_cast<FunctionDecl>(ADecl);
6345   if (!FD) {
6346     Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId;
6347     return DeclGroupPtrTy();
6348   }
6349 
6350   // OpenMP [2.8.2, declare simd construct, Description]
6351   // The parameter of the simdlen clause must be a constant positive integer
6352   // expression.
6353   ExprResult SL;
6354   if (Simdlen)
6355     SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
6356   // OpenMP [2.8.2, declare simd construct, Description]
6357   // The special this pointer can be used as if was one of the arguments to the
6358   // function in any of the linear, aligned, or uniform clauses.
6359   // The uniform clause declares one or more arguments to have an invariant
6360   // value for all concurrent invocations of the function in the execution of a
6361   // single SIMD loop.
6362   llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
6363   const Expr *UniformedLinearThis = nullptr;
6364   for (const Expr *E : Uniforms) {
6365     E = E->IgnoreParenImpCasts();
6366     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6367       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
6368         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6369             FD->getParamDecl(PVD->getFunctionScopeIndex())
6370                     ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
6371           UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
6372           continue;
6373         }
6374     if (isa<CXXThisExpr>(E)) {
6375       UniformedLinearThis = E;
6376       continue;
6377     }
6378     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6379         << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6380   }
6381   // OpenMP [2.8.2, declare simd construct, Description]
6382   // The aligned clause declares that the object to which each list item points
6383   // is aligned to the number of bytes expressed in the optional parameter of
6384   // the aligned clause.
6385   // The special this pointer can be used as if was one of the arguments to the
6386   // function in any of the linear, aligned, or uniform clauses.
6387   // The type of list items appearing in the aligned clause must be array,
6388   // pointer, reference to array, or reference to pointer.
6389   llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
6390   const Expr *AlignedThis = nullptr;
6391   for (const Expr *E : Aligneds) {
6392     E = E->IgnoreParenImpCasts();
6393     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6394       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6395         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6396         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6397             FD->getParamDecl(PVD->getFunctionScopeIndex())
6398                     ->getCanonicalDecl() == CanonPVD) {
6399           // OpenMP  [2.8.1, simd construct, Restrictions]
6400           // A list-item cannot appear in more than one aligned clause.
6401           if (AlignedArgs.count(CanonPVD) > 0) {
6402             Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
6403                 << 1 << getOpenMPClauseName(OMPC_aligned)
6404                 << E->getSourceRange();
6405             Diag(AlignedArgs[CanonPVD]->getExprLoc(),
6406                  diag::note_omp_explicit_dsa)
6407                 << getOpenMPClauseName(OMPC_aligned);
6408             continue;
6409           }
6410           AlignedArgs[CanonPVD] = E;
6411           QualType QTy = PVD->getType()
6412                              .getNonReferenceType()
6413                              .getUnqualifiedType()
6414                              .getCanonicalType();
6415           const Type *Ty = QTy.getTypePtrOrNull();
6416           if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
6417             Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
6418                 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
6419             Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
6420           }
6421           continue;
6422         }
6423       }
6424     if (isa<CXXThisExpr>(E)) {
6425       if (AlignedThis) {
6426         Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
6427             << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange();
6428         Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
6429             << getOpenMPClauseName(OMPC_aligned);
6430       }
6431       AlignedThis = E;
6432       continue;
6433     }
6434     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6435         << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6436   }
6437   // The optional parameter of the aligned clause, alignment, must be a constant
6438   // positive integer expression. If no optional parameter is specified,
6439   // implementation-defined default alignments for SIMD instructions on the
6440   // target platforms are assumed.
6441   SmallVector<const Expr *, 4> NewAligns;
6442   for (Expr *E : Alignments) {
6443     ExprResult Align;
6444     if (E)
6445       Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
6446     NewAligns.push_back(Align.get());
6447   }
6448   // OpenMP [2.8.2, declare simd construct, Description]
6449   // The linear clause declares one or more list items to be private to a SIMD
6450   // lane and to have a linear relationship with respect to the iteration space
6451   // of a loop.
6452   // The special this pointer can be used as if was one of the arguments to the
6453   // function in any of the linear, aligned, or uniform clauses.
6454   // When a linear-step expression is specified in a linear clause it must be
6455   // either a constant integer expression or an integer-typed parameter that is
6456   // specified in a uniform clause on the directive.
6457   llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
6458   const bool IsUniformedThis = UniformedLinearThis != nullptr;
6459   auto MI = LinModifiers.begin();
6460   for (const Expr *E : Linears) {
6461     auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
6462     ++MI;
6463     E = E->IgnoreParenImpCasts();
6464     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6465       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6466         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6467         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6468             FD->getParamDecl(PVD->getFunctionScopeIndex())
6469                     ->getCanonicalDecl() == CanonPVD) {
6470           // OpenMP  [2.15.3.7, linear Clause, Restrictions]
6471           // A list-item cannot appear in more than one linear clause.
6472           if (LinearArgs.count(CanonPVD) > 0) {
6473             Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6474                 << getOpenMPClauseName(OMPC_linear)
6475                 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
6476             Diag(LinearArgs[CanonPVD]->getExprLoc(),
6477                  diag::note_omp_explicit_dsa)
6478                 << getOpenMPClauseName(OMPC_linear);
6479             continue;
6480           }
6481           // Each argument can appear in at most one uniform or linear clause.
6482           if (UniformedArgs.count(CanonPVD) > 0) {
6483             Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6484                 << getOpenMPClauseName(OMPC_linear)
6485                 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
6486             Diag(UniformedArgs[CanonPVD]->getExprLoc(),
6487                  diag::note_omp_explicit_dsa)
6488                 << getOpenMPClauseName(OMPC_uniform);
6489             continue;
6490           }
6491           LinearArgs[CanonPVD] = E;
6492           if (E->isValueDependent() || E->isTypeDependent() ||
6493               E->isInstantiationDependent() ||
6494               E->containsUnexpandedParameterPack())
6495             continue;
6496           (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
6497                                       PVD->getOriginalType(),
6498                                       /*IsDeclareSimd=*/true);
6499           continue;
6500         }
6501       }
6502     if (isa<CXXThisExpr>(E)) {
6503       if (UniformedLinearThis) {
6504         Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6505             << getOpenMPClauseName(OMPC_linear)
6506             << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
6507             << E->getSourceRange();
6508         Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
6509             << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
6510                                                    : OMPC_linear);
6511         continue;
6512       }
6513       UniformedLinearThis = E;
6514       if (E->isValueDependent() || E->isTypeDependent() ||
6515           E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
6516         continue;
6517       (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
6518                                   E->getType(), /*IsDeclareSimd=*/true);
6519       continue;
6520     }
6521     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6522         << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6523   }
6524   Expr *Step = nullptr;
6525   Expr *NewStep = nullptr;
6526   SmallVector<Expr *, 4> NewSteps;
6527   for (Expr *E : Steps) {
6528     // Skip the same step expression, it was checked already.
6529     if (Step == E || !E) {
6530       NewSteps.push_back(E ? NewStep : nullptr);
6531       continue;
6532     }
6533     Step = E;
6534     if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
6535       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6536         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6537         if (UniformedArgs.count(CanonPVD) == 0) {
6538           Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
6539               << Step->getSourceRange();
6540         } else if (E->isValueDependent() || E->isTypeDependent() ||
6541                    E->isInstantiationDependent() ||
6542                    E->containsUnexpandedParameterPack() ||
6543                    CanonPVD->getType()->hasIntegerRepresentation()) {
6544           NewSteps.push_back(Step);
6545         } else {
6546           Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
6547               << Step->getSourceRange();
6548         }
6549         continue;
6550       }
6551     NewStep = Step;
6552     if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
6553         !Step->isInstantiationDependent() &&
6554         !Step->containsUnexpandedParameterPack()) {
6555       NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
6556                     .get();
6557       if (NewStep)
6558         NewStep =
6559             VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get();
6560     }
6561     NewSteps.push_back(NewStep);
6562   }
6563   auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
6564       Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
6565       Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
6566       const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
6567       const_cast<Expr **>(Linears.data()), Linears.size(),
6568       const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
6569       NewSteps.data(), NewSteps.size(), SR);
6570   ADecl->addAttr(NewAttr);
6571   return DG;
6572 }
6573 
setPrototype(Sema & S,FunctionDecl * FD,FunctionDecl * FDWithProto,QualType NewType)6574 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
6575                          QualType NewType) {
6576   assert(NewType->isFunctionProtoType() &&
6577          "Expected function type with prototype.");
6578   assert(FD->getType()->isFunctionNoProtoType() &&
6579          "Expected function with type with no prototype.");
6580   assert(FDWithProto->getType()->isFunctionProtoType() &&
6581          "Expected function with prototype.");
6582   // Synthesize parameters with the same types.
6583   FD->setType(NewType);
6584   SmallVector<ParmVarDecl *, 16> Params;
6585   for (const ParmVarDecl *P : FDWithProto->parameters()) {
6586     auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(),
6587                                       SourceLocation(), nullptr, P->getType(),
6588                                       /*TInfo=*/nullptr, SC_None, nullptr);
6589     Param->setScopeInfo(0, Params.size());
6590     Param->setImplicit();
6591     Params.push_back(Param);
6592   }
6593 
6594   FD->setParams(Params);
6595 }
6596 
ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl * D)6597 void Sema::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D) {
6598   if (D->isInvalidDecl())
6599     return;
6600   FunctionDecl *FD = nullptr;
6601   if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
6602     FD = UTemplDecl->getTemplatedDecl();
6603   else
6604     FD = cast<FunctionDecl>(D);
6605   assert(FD && "Expected a function declaration!");
6606 
6607   // If we are intantiating templates we do *not* apply scoped assumptions but
6608   // only global ones. We apply scoped assumption to the template definition
6609   // though.
6610   if (!inTemplateInstantiation()) {
6611     for (AssumptionAttr *AA : OMPAssumeScoped)
6612       FD->addAttr(AA);
6613   }
6614   for (AssumptionAttr *AA : OMPAssumeGlobal)
6615     FD->addAttr(AA);
6616 }
6617 
OMPDeclareVariantScope(OMPTraitInfo & TI)6618 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI)
6619     : TI(&TI), NameSuffix(TI.getMangledName()) {}
6620 
ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope * S,Declarator & D,MultiTemplateParamsArg TemplateParamLists,SmallVectorImpl<FunctionDecl * > & Bases)6621 void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(
6622     Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists,
6623     SmallVectorImpl<FunctionDecl *> &Bases) {
6624   if (!D.getIdentifier())
6625     return;
6626 
6627   OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
6628 
6629   // Template specialization is an extension, check if we do it.
6630   bool IsTemplated = !TemplateParamLists.empty();
6631   if (IsTemplated &
6632       !DVScope.TI->isExtensionActive(
6633           llvm::omp::TraitProperty::implementation_extension_allow_templates))
6634     return;
6635 
6636   IdentifierInfo *BaseII = D.getIdentifier();
6637   LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(),
6638                       LookupOrdinaryName);
6639   LookupParsedName(Lookup, S, &D.getCXXScopeSpec());
6640 
6641   TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
6642   QualType FType = TInfo->getType();
6643 
6644   bool IsConstexpr =
6645       D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr;
6646   bool IsConsteval =
6647       D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Consteval;
6648 
6649   for (auto *Candidate : Lookup) {
6650     auto *CandidateDecl = Candidate->getUnderlyingDecl();
6651     FunctionDecl *UDecl = nullptr;
6652     if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl))
6653       UDecl = cast<FunctionTemplateDecl>(CandidateDecl)->getTemplatedDecl();
6654     else if (!IsTemplated)
6655       UDecl = dyn_cast<FunctionDecl>(CandidateDecl);
6656     if (!UDecl)
6657       continue;
6658 
6659     // Don't specialize constexpr/consteval functions with
6660     // non-constexpr/consteval functions.
6661     if (UDecl->isConstexpr() && !IsConstexpr)
6662       continue;
6663     if (UDecl->isConsteval() && !IsConsteval)
6664       continue;
6665 
6666     QualType UDeclTy = UDecl->getType();
6667     if (!UDeclTy->isDependentType()) {
6668       QualType NewType = Context.mergeFunctionTypes(
6669           FType, UDeclTy, /* OfBlockPointer */ false,
6670           /* Unqualified */ false, /* AllowCXX */ true);
6671       if (NewType.isNull())
6672         continue;
6673     }
6674 
6675     // Found a base!
6676     Bases.push_back(UDecl);
6677   }
6678 
6679   bool UseImplicitBase = !DVScope.TI->isExtensionActive(
6680       llvm::omp::TraitProperty::implementation_extension_disable_implicit_base);
6681   // If no base was found we create a declaration that we use as base.
6682   if (Bases.empty() && UseImplicitBase) {
6683     D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration);
6684     Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists);
6685     BaseD->setImplicit(true);
6686     if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD))
6687       Bases.push_back(BaseTemplD->getTemplatedDecl());
6688     else
6689       Bases.push_back(cast<FunctionDecl>(BaseD));
6690   }
6691 
6692   std::string MangledName;
6693   MangledName += D.getIdentifier()->getName();
6694   MangledName += getOpenMPVariantManglingSeparatorStr();
6695   MangledName += DVScope.NameSuffix;
6696   IdentifierInfo &VariantII = Context.Idents.get(MangledName);
6697 
6698   VariantII.setMangledOpenMPVariantName(true);
6699   D.SetIdentifier(&VariantII, D.getBeginLoc());
6700 }
6701 
ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(Decl * D,SmallVectorImpl<FunctionDecl * > & Bases)6702 void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(
6703     Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) {
6704   // Do not mark function as is used to prevent its emission if this is the
6705   // only place where it is used.
6706   EnterExpressionEvaluationContext Unevaluated(
6707       *this, Sema::ExpressionEvaluationContext::Unevaluated);
6708 
6709   FunctionDecl *FD = nullptr;
6710   if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
6711     FD = UTemplDecl->getTemplatedDecl();
6712   else
6713     FD = cast<FunctionDecl>(D);
6714   auto *VariantFuncRef = DeclRefExpr::Create(
6715       Context, NestedNameSpecifierLoc(), SourceLocation(), FD,
6716       /* RefersToEnclosingVariableOrCapture */ false,
6717       /* NameLoc */ FD->getLocation(), FD->getType(), ExprValueKind::VK_RValue);
6718 
6719   OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
6720   auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit(
6721       Context, VariantFuncRef, DVScope.TI);
6722   for (FunctionDecl *BaseFD : Bases)
6723     BaseFD->addAttr(OMPDeclareVariantA);
6724 }
6725 
ActOnOpenMPCall(ExprResult Call,Scope * Scope,SourceLocation LParenLoc,MultiExprArg ArgExprs,SourceLocation RParenLoc,Expr * ExecConfig)6726 ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
6727                                  SourceLocation LParenLoc,
6728                                  MultiExprArg ArgExprs,
6729                                  SourceLocation RParenLoc, Expr *ExecConfig) {
6730   // The common case is a regular call we do not want to specialize at all. Try
6731   // to make that case fast by bailing early.
6732   CallExpr *CE = dyn_cast<CallExpr>(Call.get());
6733   if (!CE)
6734     return Call;
6735 
6736   FunctionDecl *CalleeFnDecl = CE->getDirectCallee();
6737   if (!CalleeFnDecl)
6738     return Call;
6739 
6740   if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>())
6741     return Call;
6742 
6743   ASTContext &Context = getASTContext();
6744   std::function<void(StringRef)> DiagUnknownTrait = [this,
6745                                                      CE](StringRef ISATrait) {
6746     // TODO Track the selector locations in a way that is accessible here to
6747     // improve the diagnostic location.
6748     Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait)
6749         << ISATrait;
6750   };
6751   TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait),
6752                           getCurFunctionDecl());
6753 
6754   QualType CalleeFnType = CalleeFnDecl->getType();
6755 
6756   SmallVector<Expr *, 4> Exprs;
6757   SmallVector<VariantMatchInfo, 4> VMIs;
6758   while (CalleeFnDecl) {
6759     for (OMPDeclareVariantAttr *A :
6760          CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) {
6761       Expr *VariantRef = A->getVariantFuncRef();
6762 
6763       VariantMatchInfo VMI;
6764       OMPTraitInfo &TI = A->getTraitInfo();
6765       TI.getAsVariantMatchInfo(Context, VMI);
6766       if (!isVariantApplicableInContext(VMI, OMPCtx,
6767                                         /* DeviceSetOnly */ false))
6768         continue;
6769 
6770       VMIs.push_back(VMI);
6771       Exprs.push_back(VariantRef);
6772     }
6773 
6774     CalleeFnDecl = CalleeFnDecl->getPreviousDecl();
6775   }
6776 
6777   ExprResult NewCall;
6778   do {
6779     int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
6780     if (BestIdx < 0)
6781       return Call;
6782     Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]);
6783     Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl();
6784 
6785     {
6786       // Try to build a (member) call expression for the current best applicable
6787       // variant expression. We allow this to fail in which case we continue
6788       // with the next best variant expression. The fail case is part of the
6789       // implementation defined behavior in the OpenMP standard when it talks
6790       // about what differences in the function prototypes: "Any differences
6791       // that the specific OpenMP context requires in the prototype of the
6792       // variant from the base function prototype are implementation defined."
6793       // This wording is there to allow the specialized variant to have a
6794       // different type than the base function. This is intended and OK but if
6795       // we cannot create a call the difference is not in the "implementation
6796       // defined range" we allow.
6797       Sema::TentativeAnalysisScope Trap(*this);
6798 
6799       if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) {
6800         auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE);
6801         BestExpr = MemberExpr::CreateImplicit(
6802             Context, MemberCall->getImplicitObjectArgument(),
6803             /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy,
6804             MemberCall->getValueKind(), MemberCall->getObjectKind());
6805       }
6806       NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc,
6807                               ExecConfig);
6808       if (NewCall.isUsable()) {
6809         if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) {
6810           FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee();
6811           QualType NewType = Context.mergeFunctionTypes(
6812               CalleeFnType, NewCalleeFnDecl->getType(),
6813               /* OfBlockPointer */ false,
6814               /* Unqualified */ false, /* AllowCXX */ true);
6815           if (!NewType.isNull())
6816             break;
6817           // Don't use the call if the function type was not compatible.
6818           NewCall = nullptr;
6819         }
6820       }
6821     }
6822 
6823     VMIs.erase(VMIs.begin() + BestIdx);
6824     Exprs.erase(Exprs.begin() + BestIdx);
6825   } while (!VMIs.empty());
6826 
6827   if (!NewCall.isUsable())
6828     return Call;
6829   return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0);
6830 }
6831 
6832 Optional<std::pair<FunctionDecl *, Expr *>>
checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,Expr * VariantRef,OMPTraitInfo & TI,SourceRange SR)6833 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
6834                                         Expr *VariantRef, OMPTraitInfo &TI,
6835                                         SourceRange SR) {
6836   if (!DG || DG.get().isNull())
6837     return None;
6838 
6839   const int VariantId = 1;
6840   // Must be applied only to single decl.
6841   if (!DG.get().isSingleDecl()) {
6842     Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
6843         << VariantId << SR;
6844     return None;
6845   }
6846   Decl *ADecl = DG.get().getSingleDecl();
6847   if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
6848     ADecl = FTD->getTemplatedDecl();
6849 
6850   // Decl must be a function.
6851   auto *FD = dyn_cast<FunctionDecl>(ADecl);
6852   if (!FD) {
6853     Diag(ADecl->getLocation(), diag::err_omp_function_expected)
6854         << VariantId << SR;
6855     return None;
6856   }
6857 
6858   auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
6859     return FD->hasAttrs() &&
6860            (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() ||
6861             FD->hasAttr<TargetAttr>());
6862   };
6863   // OpenMP is not compatible with CPU-specific attributes.
6864   if (HasMultiVersionAttributes(FD)) {
6865     Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
6866         << SR;
6867     return None;
6868   }
6869 
6870   // Allow #pragma omp declare variant only if the function is not used.
6871   if (FD->isUsed(false))
6872     Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
6873         << FD->getLocation();
6874 
6875   // Check if the function was emitted already.
6876   const FunctionDecl *Definition;
6877   if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) &&
6878       (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition)))
6879     Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
6880         << FD->getLocation();
6881 
6882   // The VariantRef must point to function.
6883   if (!VariantRef) {
6884     Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
6885     return None;
6886   }
6887 
6888   auto ShouldDelayChecks = [](Expr *&E, bool) {
6889     return E && (E->isTypeDependent() || E->isValueDependent() ||
6890                  E->containsUnexpandedParameterPack() ||
6891                  E->isInstantiationDependent());
6892   };
6893   // Do not check templates, wait until instantiation.
6894   if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) ||
6895       TI.anyScoreOrCondition(ShouldDelayChecks))
6896     return std::make_pair(FD, VariantRef);
6897 
6898   // Deal with non-constant score and user condition expressions.
6899   auto HandleNonConstantScoresAndConditions = [this](Expr *&E,
6900                                                      bool IsScore) -> bool {
6901     if (!E || E->isIntegerConstantExpr(Context))
6902       return false;
6903 
6904     if (IsScore) {
6905       // We warn on non-constant scores and pretend they were not present.
6906       Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant)
6907           << E;
6908       E = nullptr;
6909     } else {
6910       // We could replace a non-constant user condition with "false" but we
6911       // will soon need to handle these anyway for the dynamic version of
6912       // OpenMP context selectors.
6913       Diag(E->getExprLoc(),
6914            diag::err_omp_declare_variant_user_condition_not_constant)
6915           << E;
6916     }
6917     return true;
6918   };
6919   if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions))
6920     return None;
6921 
6922   // Convert VariantRef expression to the type of the original function to
6923   // resolve possible conflicts.
6924   ExprResult VariantRefCast = VariantRef;
6925   if (LangOpts.CPlusPlus) {
6926     QualType FnPtrType;
6927     auto *Method = dyn_cast<CXXMethodDecl>(FD);
6928     if (Method && !Method->isStatic()) {
6929       const Type *ClassType =
6930           Context.getTypeDeclType(Method->getParent()).getTypePtr();
6931       FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType);
6932       ExprResult ER;
6933       {
6934         // Build adrr_of unary op to correctly handle type checks for member
6935         // functions.
6936         Sema::TentativeAnalysisScope Trap(*this);
6937         ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf,
6938                                   VariantRef);
6939       }
6940       if (!ER.isUsable()) {
6941         Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6942             << VariantId << VariantRef->getSourceRange();
6943         return None;
6944       }
6945       VariantRef = ER.get();
6946     } else {
6947       FnPtrType = Context.getPointerType(FD->getType());
6948     }
6949     QualType VarianPtrType = Context.getPointerType(VariantRef->getType());
6950     if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) {
6951       ImplicitConversionSequence ICS = TryImplicitConversion(
6952           VariantRef, FnPtrType.getUnqualifiedType(),
6953           /*SuppressUserConversions=*/false, AllowedExplicit::None,
6954           /*InOverloadResolution=*/false,
6955           /*CStyle=*/false,
6956           /*AllowObjCWritebackConversion=*/false);
6957       if (ICS.isFailure()) {
6958         Diag(VariantRef->getExprLoc(),
6959              diag::err_omp_declare_variant_incompat_types)
6960             << VariantRef->getType()
6961             << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
6962             << VariantRef->getSourceRange();
6963         return None;
6964       }
6965       VariantRefCast = PerformImplicitConversion(
6966           VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
6967       if (!VariantRefCast.isUsable())
6968         return None;
6969     }
6970     // Drop previously built artificial addr_of unary op for member functions.
6971     if (Method && !Method->isStatic()) {
6972       Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
6973       if (auto *UO = dyn_cast<UnaryOperator>(
6974               PossibleAddrOfVariantRef->IgnoreImplicit()))
6975         VariantRefCast = UO->getSubExpr();
6976     }
6977   }
6978 
6979   ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get());
6980   if (!ER.isUsable() ||
6981       !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
6982     Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6983         << VariantId << VariantRef->getSourceRange();
6984     return None;
6985   }
6986 
6987   // The VariantRef must point to function.
6988   auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts());
6989   if (!DRE) {
6990     Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6991         << VariantId << VariantRef->getSourceRange();
6992     return None;
6993   }
6994   auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
6995   if (!NewFD) {
6996     Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6997         << VariantId << VariantRef->getSourceRange();
6998     return None;
6999   }
7000 
7001   // Check if function types are compatible in C.
7002   if (!LangOpts.CPlusPlus) {
7003     QualType NewType =
7004         Context.mergeFunctionTypes(FD->getType(), NewFD->getType());
7005     if (NewType.isNull()) {
7006       Diag(VariantRef->getExprLoc(),
7007            diag::err_omp_declare_variant_incompat_types)
7008           << NewFD->getType() << FD->getType() << VariantRef->getSourceRange();
7009       return None;
7010     }
7011     if (NewType->isFunctionProtoType()) {
7012       if (FD->getType()->isFunctionNoProtoType())
7013         setPrototype(*this, FD, NewFD, NewType);
7014       else if (NewFD->getType()->isFunctionNoProtoType())
7015         setPrototype(*this, NewFD, FD, NewType);
7016     }
7017   }
7018 
7019   // Check if variant function is not marked with declare variant directive.
7020   if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
7021     Diag(VariantRef->getExprLoc(),
7022          diag::warn_omp_declare_variant_marked_as_declare_variant)
7023         << VariantRef->getSourceRange();
7024     SourceRange SR =
7025         NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
7026     Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
7027     return None;
7028   }
7029 
7030   enum DoesntSupport {
7031     VirtFuncs = 1,
7032     Constructors = 3,
7033     Destructors = 4,
7034     DeletedFuncs = 5,
7035     DefaultedFuncs = 6,
7036     ConstexprFuncs = 7,
7037     ConstevalFuncs = 8,
7038   };
7039   if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
7040     if (CXXFD->isVirtual()) {
7041       Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7042           << VirtFuncs;
7043       return None;
7044     }
7045 
7046     if (isa<CXXConstructorDecl>(FD)) {
7047       Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7048           << Constructors;
7049       return None;
7050     }
7051 
7052     if (isa<CXXDestructorDecl>(FD)) {
7053       Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7054           << Destructors;
7055       return None;
7056     }
7057   }
7058 
7059   if (FD->isDeleted()) {
7060     Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7061         << DeletedFuncs;
7062     return None;
7063   }
7064 
7065   if (FD->isDefaulted()) {
7066     Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7067         << DefaultedFuncs;
7068     return None;
7069   }
7070 
7071   if (FD->isConstexpr()) {
7072     Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7073         << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
7074     return None;
7075   }
7076 
7077   // Check general compatibility.
7078   if (areMultiversionVariantFunctionsCompatible(
7079           FD, NewFD, PartialDiagnostic::NullDiagnostic(),
7080           PartialDiagnosticAt(SourceLocation(),
7081                               PartialDiagnostic::NullDiagnostic()),
7082           PartialDiagnosticAt(
7083               VariantRef->getExprLoc(),
7084               PDiag(diag::err_omp_declare_variant_doesnt_support)),
7085           PartialDiagnosticAt(VariantRef->getExprLoc(),
7086                               PDiag(diag::err_omp_declare_variant_diff)
7087                                   << FD->getLocation()),
7088           /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
7089           /*CLinkageMayDiffer=*/true))
7090     return None;
7091   return std::make_pair(FD, cast<Expr>(DRE));
7092 }
7093 
ActOnOpenMPDeclareVariantDirective(FunctionDecl * FD,Expr * VariantRef,OMPTraitInfo & TI,SourceRange SR)7094 void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD,
7095                                               Expr *VariantRef,
7096                                               OMPTraitInfo &TI,
7097                                               SourceRange SR) {
7098   auto *NewAttr =
7099       OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, &TI, SR);
7100   FD->addAttr(NewAttr);
7101 }
7102 
ActOnOpenMPParallelDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)7103 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
7104                                               Stmt *AStmt,
7105                                               SourceLocation StartLoc,
7106                                               SourceLocation EndLoc) {
7107   if (!AStmt)
7108     return StmtError();
7109 
7110   auto *CS = cast<CapturedStmt>(AStmt);
7111   // 1.2.2 OpenMP Language Terminology
7112   // Structured block - An executable statement with a single entry at the
7113   // top and a single exit at the bottom.
7114   // The point of exit cannot be a branch out of the structured block.
7115   // longjmp() and throw() must not violate the entry/exit criteria.
7116   CS->getCapturedDecl()->setNothrow();
7117 
7118   setFunctionHasBranchProtectedScope();
7119 
7120   return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
7121                                       DSAStack->getTaskgroupReductionRef(),
7122                                       DSAStack->isCancelRegion());
7123 }
7124 
7125 namespace {
7126 /// Iteration space of a single for loop.
7127 struct LoopIterationSpace final {
7128   /// True if the condition operator is the strict compare operator (<, > or
7129   /// !=).
7130   bool IsStrictCompare = false;
7131   /// Condition of the loop.
7132   Expr *PreCond = nullptr;
7133   /// This expression calculates the number of iterations in the loop.
7134   /// It is always possible to calculate it before starting the loop.
7135   Expr *NumIterations = nullptr;
7136   /// The loop counter variable.
7137   Expr *CounterVar = nullptr;
7138   /// Private loop counter variable.
7139   Expr *PrivateCounterVar = nullptr;
7140   /// This is initializer for the initial value of #CounterVar.
7141   Expr *CounterInit = nullptr;
7142   /// This is step for the #CounterVar used to generate its update:
7143   /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
7144   Expr *CounterStep = nullptr;
7145   /// Should step be subtracted?
7146   bool Subtract = false;
7147   /// Source range of the loop init.
7148   SourceRange InitSrcRange;
7149   /// Source range of the loop condition.
7150   SourceRange CondSrcRange;
7151   /// Source range of the loop increment.
7152   SourceRange IncSrcRange;
7153   /// Minimum value that can have the loop control variable. Used to support
7154   /// non-rectangular loops. Applied only for LCV with the non-iterator types,
7155   /// since only such variables can be used in non-loop invariant expressions.
7156   Expr *MinValue = nullptr;
7157   /// Maximum value that can have the loop control variable. Used to support
7158   /// non-rectangular loops. Applied only for LCV with the non-iterator type,
7159   /// since only such variables can be used in non-loop invariant expressions.
7160   Expr *MaxValue = nullptr;
7161   /// true, if the lower bound depends on the outer loop control var.
7162   bool IsNonRectangularLB = false;
7163   /// true, if the upper bound depends on the outer loop control var.
7164   bool IsNonRectangularUB = false;
7165   /// Index of the loop this loop depends on and forms non-rectangular loop
7166   /// nest.
7167   unsigned LoopDependentIdx = 0;
7168   /// Final condition for the non-rectangular loop nest support. It is used to
7169   /// check that the number of iterations for this particular counter must be
7170   /// finished.
7171   Expr *FinalCondition = nullptr;
7172 };
7173 
7174 /// Helper class for checking canonical form of the OpenMP loops and
7175 /// extracting iteration space of each loop in the loop nest, that will be used
7176 /// for IR generation.
7177 class OpenMPIterationSpaceChecker {
7178   /// Reference to Sema.
7179   Sema &SemaRef;
7180   /// Does the loop associated directive support non-rectangular loops?
7181   bool SupportsNonRectangular;
7182   /// Data-sharing stack.
7183   DSAStackTy &Stack;
7184   /// A location for diagnostics (when there is no some better location).
7185   SourceLocation DefaultLoc;
7186   /// A location for diagnostics (when increment is not compatible).
7187   SourceLocation ConditionLoc;
7188   /// A source location for referring to loop init later.
7189   SourceRange InitSrcRange;
7190   /// A source location for referring to condition later.
7191   SourceRange ConditionSrcRange;
7192   /// A source location for referring to increment later.
7193   SourceRange IncrementSrcRange;
7194   /// Loop variable.
7195   ValueDecl *LCDecl = nullptr;
7196   /// Reference to loop variable.
7197   Expr *LCRef = nullptr;
7198   /// Lower bound (initializer for the var).
7199   Expr *LB = nullptr;
7200   /// Upper bound.
7201   Expr *UB = nullptr;
7202   /// Loop step (increment).
7203   Expr *Step = nullptr;
7204   /// This flag is true when condition is one of:
7205   ///   Var <  UB
7206   ///   Var <= UB
7207   ///   UB  >  Var
7208   ///   UB  >= Var
7209   /// This will have no value when the condition is !=
7210   llvm::Optional<bool> TestIsLessOp;
7211   /// This flag is true when condition is strict ( < or > ).
7212   bool TestIsStrictOp = false;
7213   /// This flag is true when step is subtracted on each iteration.
7214   bool SubtractStep = false;
7215   /// The outer loop counter this loop depends on (if any).
7216   const ValueDecl *DepDecl = nullptr;
7217   /// Contains number of loop (starts from 1) on which loop counter init
7218   /// expression of this loop depends on.
7219   Optional<unsigned> InitDependOnLC;
7220   /// Contains number of loop (starts from 1) on which loop counter condition
7221   /// expression of this loop depends on.
7222   Optional<unsigned> CondDependOnLC;
7223   /// Checks if the provide statement depends on the loop counter.
7224   Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer);
7225   /// Original condition required for checking of the exit condition for
7226   /// non-rectangular loop.
7227   Expr *Condition = nullptr;
7228 
7229 public:
OpenMPIterationSpaceChecker(Sema & SemaRef,bool SupportsNonRectangular,DSAStackTy & Stack,SourceLocation DefaultLoc)7230   OpenMPIterationSpaceChecker(Sema &SemaRef, bool SupportsNonRectangular,
7231                               DSAStackTy &Stack, SourceLocation DefaultLoc)
7232       : SemaRef(SemaRef), SupportsNonRectangular(SupportsNonRectangular),
7233         Stack(Stack), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
7234   /// Check init-expr for canonical loop form and save loop counter
7235   /// variable - #Var and its initialization value - #LB.
7236   bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
7237   /// Check test-expr for canonical form, save upper-bound (#UB), flags
7238   /// for less/greater and for strict/non-strict comparison.
7239   bool checkAndSetCond(Expr *S);
7240   /// Check incr-expr for canonical loop form and return true if it
7241   /// does not conform, otherwise save loop step (#Step).
7242   bool checkAndSetInc(Expr *S);
7243   /// Return the loop counter variable.
getLoopDecl() const7244   ValueDecl *getLoopDecl() const { return LCDecl; }
7245   /// Return the reference expression to loop counter variable.
getLoopDeclRefExpr() const7246   Expr *getLoopDeclRefExpr() const { return LCRef; }
7247   /// Source range of the loop init.
getInitSrcRange() const7248   SourceRange getInitSrcRange() const { return InitSrcRange; }
7249   /// Source range of the loop condition.
getConditionSrcRange() const7250   SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
7251   /// Source range of the loop increment.
getIncrementSrcRange() const7252   SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
7253   /// True if the step should be subtracted.
shouldSubtractStep() const7254   bool shouldSubtractStep() const { return SubtractStep; }
7255   /// True, if the compare operator is strict (<, > or !=).
isStrictTestOp() const7256   bool isStrictTestOp() const { return TestIsStrictOp; }
7257   /// Build the expression to calculate the number of iterations.
7258   Expr *buildNumIterations(
7259       Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
7260       llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7261   /// Build the precondition expression for the loops.
7262   Expr *
7263   buildPreCond(Scope *S, Expr *Cond,
7264                llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7265   /// Build reference expression to the counter be used for codegen.
7266   DeclRefExpr *
7267   buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7268                   DSAStackTy &DSA) const;
7269   /// Build reference expression to the private counter be used for
7270   /// codegen.
7271   Expr *buildPrivateCounterVar() const;
7272   /// Build initialization of the counter be used for codegen.
7273   Expr *buildCounterInit() const;
7274   /// Build step of the counter be used for codegen.
7275   Expr *buildCounterStep() const;
7276   /// Build loop data with counter value for depend clauses in ordered
7277   /// directives.
7278   Expr *
7279   buildOrderedLoopData(Scope *S, Expr *Counter,
7280                        llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7281                        SourceLocation Loc, Expr *Inc = nullptr,
7282                        OverloadedOperatorKind OOK = OO_Amp);
7283   /// Builds the minimum value for the loop counter.
7284   std::pair<Expr *, Expr *> buildMinMaxValues(
7285       Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7286   /// Builds final condition for the non-rectangular loops.
7287   Expr *buildFinalCondition(Scope *S) const;
7288   /// Return true if any expression is dependent.
7289   bool dependent() const;
7290   /// Returns true if the initializer forms non-rectangular loop.
doesInitDependOnLC() const7291   bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); }
7292   /// Returns true if the condition forms non-rectangular loop.
doesCondDependOnLC() const7293   bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); }
7294   /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
getLoopDependentIdx() const7295   unsigned getLoopDependentIdx() const {
7296     return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0));
7297   }
7298 
7299 private:
7300   /// Check the right-hand side of an assignment in the increment
7301   /// expression.
7302   bool checkAndSetIncRHS(Expr *RHS);
7303   /// Helper to set loop counter variable and its initializer.
7304   bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
7305                       bool EmitDiags);
7306   /// Helper to set upper bound.
7307   bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp,
7308              SourceRange SR, SourceLocation SL);
7309   /// Helper to set loop increment.
7310   bool setStep(Expr *NewStep, bool Subtract);
7311 };
7312 
dependent() const7313 bool OpenMPIterationSpaceChecker::dependent() const {
7314   if (!LCDecl) {
7315     assert(!LB && !UB && !Step);
7316     return false;
7317   }
7318   return LCDecl->getType()->isDependentType() ||
7319          (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
7320          (Step && Step->isValueDependent());
7321 }
7322 
setLCDeclAndLB(ValueDecl * NewLCDecl,Expr * NewLCRefExpr,Expr * NewLB,bool EmitDiags)7323 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
7324                                                  Expr *NewLCRefExpr,
7325                                                  Expr *NewLB, bool EmitDiags) {
7326   // State consistency checking to ensure correct usage.
7327   assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
7328          UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
7329   if (!NewLCDecl || !NewLB)
7330     return true;
7331   LCDecl = getCanonicalDecl(NewLCDecl);
7332   LCRef = NewLCRefExpr;
7333   if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
7334     if (const CXXConstructorDecl *Ctor = CE->getConstructor())
7335       if ((Ctor->isCopyOrMoveConstructor() ||
7336            Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
7337           CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
7338         NewLB = CE->getArg(0)->IgnoreParenImpCasts();
7339   LB = NewLB;
7340   if (EmitDiags)
7341     InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
7342   return false;
7343 }
7344 
setUB(Expr * NewUB,llvm::Optional<bool> LessOp,bool StrictOp,SourceRange SR,SourceLocation SL)7345 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB,
7346                                         llvm::Optional<bool> LessOp,
7347                                         bool StrictOp, SourceRange SR,
7348                                         SourceLocation SL) {
7349   // State consistency checking to ensure correct usage.
7350   assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&
7351          Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
7352   if (!NewUB)
7353     return true;
7354   UB = NewUB;
7355   if (LessOp)
7356     TestIsLessOp = LessOp;
7357   TestIsStrictOp = StrictOp;
7358   ConditionSrcRange = SR;
7359   ConditionLoc = SL;
7360   CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
7361   return false;
7362 }
7363 
setStep(Expr * NewStep,bool Subtract)7364 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
7365   // State consistency checking to ensure correct usage.
7366   assert(LCDecl != nullptr && LB != nullptr && Step == nullptr);
7367   if (!NewStep)
7368     return true;
7369   if (!NewStep->isValueDependent()) {
7370     // Check that the step is integer expression.
7371     SourceLocation StepLoc = NewStep->getBeginLoc();
7372     ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
7373         StepLoc, getExprAsWritten(NewStep));
7374     if (Val.isInvalid())
7375       return true;
7376     NewStep = Val.get();
7377 
7378     // OpenMP [2.6, Canonical Loop Form, Restrictions]
7379     //  If test-expr is of form var relational-op b and relational-op is < or
7380     //  <= then incr-expr must cause var to increase on each iteration of the
7381     //  loop. If test-expr is of form var relational-op b and relational-op is
7382     //  > or >= then incr-expr must cause var to decrease on each iteration of
7383     //  the loop.
7384     //  If test-expr is of form b relational-op var and relational-op is < or
7385     //  <= then incr-expr must cause var to decrease on each iteration of the
7386     //  loop. If test-expr is of form b relational-op var and relational-op is
7387     //  > or >= then incr-expr must cause var to increase on each iteration of
7388     //  the loop.
7389     Optional<llvm::APSInt> Result =
7390         NewStep->getIntegerConstantExpr(SemaRef.Context);
7391     bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
7392     bool IsConstNeg =
7393         Result && Result->isSigned() && (Subtract != Result->isNegative());
7394     bool IsConstPos =
7395         Result && Result->isSigned() && (Subtract == Result->isNegative());
7396     bool IsConstZero = Result && !Result->getBoolValue();
7397 
7398     // != with increment is treated as <; != with decrement is treated as >
7399     if (!TestIsLessOp.hasValue())
7400       TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
7401     if (UB && (IsConstZero ||
7402                (TestIsLessOp.getValue() ?
7403                   (IsConstNeg || (IsUnsigned && Subtract)) :
7404                   (IsConstPos || (IsUnsigned && !Subtract))))) {
7405       SemaRef.Diag(NewStep->getExprLoc(),
7406                    diag::err_omp_loop_incr_not_compatible)
7407           << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange();
7408       SemaRef.Diag(ConditionLoc,
7409                    diag::note_omp_loop_cond_requres_compatible_incr)
7410           << TestIsLessOp.getValue() << ConditionSrcRange;
7411       return true;
7412     }
7413     if (TestIsLessOp.getValue() == Subtract) {
7414       NewStep =
7415           SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
7416               .get();
7417       Subtract = !Subtract;
7418     }
7419   }
7420 
7421   Step = NewStep;
7422   SubtractStep = Subtract;
7423   return false;
7424 }
7425 
7426 namespace {
7427 /// Checker for the non-rectangular loops. Checks if the initializer or
7428 /// condition expression references loop counter variable.
7429 class LoopCounterRefChecker final
7430     : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
7431   Sema &SemaRef;
7432   DSAStackTy &Stack;
7433   const ValueDecl *CurLCDecl = nullptr;
7434   const ValueDecl *DepDecl = nullptr;
7435   const ValueDecl *PrevDepDecl = nullptr;
7436   bool IsInitializer = true;
7437   bool SupportsNonRectangular;
7438   unsigned BaseLoopId = 0;
checkDecl(const Expr * E,const ValueDecl * VD)7439   bool checkDecl(const Expr *E, const ValueDecl *VD) {
7440     if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
7441       SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
7442           << (IsInitializer ? 0 : 1);
7443       return false;
7444     }
7445     const auto &&Data = Stack.isLoopControlVariable(VD);
7446     // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
7447     // The type of the loop iterator on which we depend may not have a random
7448     // access iterator type.
7449     if (Data.first && VD->getType()->isRecordType()) {
7450       SmallString<128> Name;
7451       llvm::raw_svector_ostream OS(Name);
7452       VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
7453                                /*Qualified=*/true);
7454       SemaRef.Diag(E->getExprLoc(),
7455                    diag::err_omp_wrong_dependency_iterator_type)
7456           << OS.str();
7457       SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
7458       return false;
7459     }
7460     if (Data.first && !SupportsNonRectangular) {
7461       SemaRef.Diag(E->getExprLoc(), diag::err_omp_invariant_dependency);
7462       return false;
7463     }
7464     if (Data.first &&
7465         (DepDecl || (PrevDepDecl &&
7466                      getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
7467       if (!DepDecl && PrevDepDecl)
7468         DepDecl = PrevDepDecl;
7469       SmallString<128> Name;
7470       llvm::raw_svector_ostream OS(Name);
7471       DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
7472                                     /*Qualified=*/true);
7473       SemaRef.Diag(E->getExprLoc(),
7474                    diag::err_omp_invariant_or_linear_dependency)
7475           << OS.str();
7476       return false;
7477     }
7478     if (Data.first) {
7479       DepDecl = VD;
7480       BaseLoopId = Data.first;
7481     }
7482     return Data.first;
7483   }
7484 
7485 public:
VisitDeclRefExpr(const DeclRefExpr * E)7486   bool VisitDeclRefExpr(const DeclRefExpr *E) {
7487     const ValueDecl *VD = E->getDecl();
7488     if (isa<VarDecl>(VD))
7489       return checkDecl(E, VD);
7490     return false;
7491   }
VisitMemberExpr(const MemberExpr * E)7492   bool VisitMemberExpr(const MemberExpr *E) {
7493     if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
7494       const ValueDecl *VD = E->getMemberDecl();
7495       if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
7496         return checkDecl(E, VD);
7497     }
7498     return false;
7499   }
VisitStmt(const Stmt * S)7500   bool VisitStmt(const Stmt *S) {
7501     bool Res = false;
7502     for (const Stmt *Child : S->children())
7503       Res = (Child && Visit(Child)) || Res;
7504     return Res;
7505   }
LoopCounterRefChecker(Sema & SemaRef,DSAStackTy & Stack,const ValueDecl * CurLCDecl,bool IsInitializer,const ValueDecl * PrevDepDecl=nullptr,bool SupportsNonRectangular=true)7506   explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
7507                                  const ValueDecl *CurLCDecl, bool IsInitializer,
7508                                  const ValueDecl *PrevDepDecl = nullptr,
7509                                  bool SupportsNonRectangular = true)
7510       : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
7511         PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer),
7512         SupportsNonRectangular(SupportsNonRectangular) {}
getBaseLoopId() const7513   unsigned getBaseLoopId() const {
7514     assert(CurLCDecl && "Expected loop dependency.");
7515     return BaseLoopId;
7516   }
getDepDecl() const7517   const ValueDecl *getDepDecl() const {
7518     assert(CurLCDecl && "Expected loop dependency.");
7519     return DepDecl;
7520   }
7521 };
7522 } // namespace
7523 
7524 Optional<unsigned>
doesDependOnLoopCounter(const Stmt * S,bool IsInitializer)7525 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
7526                                                      bool IsInitializer) {
7527   // Check for the non-rectangular loops.
7528   LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
7529                                         DepDecl, SupportsNonRectangular);
7530   if (LoopStmtChecker.Visit(S)) {
7531     DepDecl = LoopStmtChecker.getDepDecl();
7532     return LoopStmtChecker.getBaseLoopId();
7533   }
7534   return llvm::None;
7535 }
7536 
checkAndSetInit(Stmt * S,bool EmitDiags)7537 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
7538   // Check init-expr for canonical loop form and save loop counter
7539   // variable - #Var and its initialization value - #LB.
7540   // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
7541   //   var = lb
7542   //   integer-type var = lb
7543   //   random-access-iterator-type var = lb
7544   //   pointer-type var = lb
7545   //
7546   if (!S) {
7547     if (EmitDiags) {
7548       SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
7549     }
7550     return true;
7551   }
7552   if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
7553     if (!ExprTemp->cleanupsHaveSideEffects())
7554       S = ExprTemp->getSubExpr();
7555 
7556   InitSrcRange = S->getSourceRange();
7557   if (Expr *E = dyn_cast<Expr>(S))
7558     S = E->IgnoreParens();
7559   if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7560     if (BO->getOpcode() == BO_Assign) {
7561       Expr *LHS = BO->getLHS()->IgnoreParens();
7562       if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
7563         if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
7564           if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
7565             return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7566                                   EmitDiags);
7567         return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
7568       }
7569       if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
7570         if (ME->isArrow() &&
7571             isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7572           return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7573                                 EmitDiags);
7574       }
7575     }
7576   } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
7577     if (DS->isSingleDecl()) {
7578       if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
7579         if (Var->hasInit() && !Var->getType()->isReferenceType()) {
7580           // Accept non-canonical init form here but emit ext. warning.
7581           if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
7582             SemaRef.Diag(S->getBeginLoc(),
7583                          diag::ext_omp_loop_not_canonical_init)
7584                 << S->getSourceRange();
7585           return setLCDeclAndLB(
7586               Var,
7587               buildDeclRefExpr(SemaRef, Var,
7588                                Var->getType().getNonReferenceType(),
7589                                DS->getBeginLoc()),
7590               Var->getInit(), EmitDiags);
7591         }
7592       }
7593     }
7594   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7595     if (CE->getOperator() == OO_Equal) {
7596       Expr *LHS = CE->getArg(0);
7597       if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
7598         if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
7599           if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
7600             return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7601                                   EmitDiags);
7602         return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
7603       }
7604       if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
7605         if (ME->isArrow() &&
7606             isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7607           return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7608                                 EmitDiags);
7609       }
7610     }
7611   }
7612 
7613   if (dependent() || SemaRef.CurContext->isDependentContext())
7614     return false;
7615   if (EmitDiags) {
7616     SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
7617         << S->getSourceRange();
7618   }
7619   return true;
7620 }
7621 
7622 /// Ignore parenthesizes, implicit casts, copy constructor and return the
7623 /// variable (which may be the loop variable) if possible.
getInitLCDecl(const Expr * E)7624 static const ValueDecl *getInitLCDecl(const Expr *E) {
7625   if (!E)
7626     return nullptr;
7627   E = getExprAsWritten(E);
7628   if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
7629     if (const CXXConstructorDecl *Ctor = CE->getConstructor())
7630       if ((Ctor->isCopyOrMoveConstructor() ||
7631            Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
7632           CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
7633         E = CE->getArg(0)->IgnoreParenImpCasts();
7634   if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
7635     if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
7636       return getCanonicalDecl(VD);
7637   }
7638   if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
7639     if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7640       return getCanonicalDecl(ME->getMemberDecl());
7641   return nullptr;
7642 }
7643 
checkAndSetCond(Expr * S)7644 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
7645   // Check test-expr for canonical form, save upper-bound UB, flags for
7646   // less/greater and for strict/non-strict comparison.
7647   // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following:
7648   //   var relational-op b
7649   //   b relational-op var
7650   //
7651   bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
7652   if (!S) {
7653     SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
7654         << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
7655     return true;
7656   }
7657   Condition = S;
7658   S = getExprAsWritten(S);
7659   SourceLocation CondLoc = S->getBeginLoc();
7660   if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7661     if (BO->isRelationalOp()) {
7662       if (getInitLCDecl(BO->getLHS()) == LCDecl)
7663         return setUB(BO->getRHS(),
7664                      (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE),
7665                      (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
7666                      BO->getSourceRange(), BO->getOperatorLoc());
7667       if (getInitLCDecl(BO->getRHS()) == LCDecl)
7668         return setUB(BO->getLHS(),
7669                      (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE),
7670                      (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT),
7671                      BO->getSourceRange(), BO->getOperatorLoc());
7672     } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE)
7673       return setUB(
7674           getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(),
7675           /*LessOp=*/llvm::None,
7676           /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc());
7677   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7678     if (CE->getNumArgs() == 2) {
7679       auto Op = CE->getOperator();
7680       switch (Op) {
7681       case OO_Greater:
7682       case OO_GreaterEqual:
7683       case OO_Less:
7684       case OO_LessEqual:
7685         if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7686           return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual,
7687                        Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
7688                        CE->getOperatorLoc());
7689         if (getInitLCDecl(CE->getArg(1)) == LCDecl)
7690           return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual,
7691                        Op == OO_Less || Op == OO_Greater, CE->getSourceRange(),
7692                        CE->getOperatorLoc());
7693         break;
7694       case OO_ExclaimEqual:
7695         if (IneqCondIsCanonical)
7696           return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1)
7697                                                               : CE->getArg(0),
7698                        /*LessOp=*/llvm::None,
7699                        /*StrictOp=*/true, CE->getSourceRange(),
7700                        CE->getOperatorLoc());
7701         break;
7702       default:
7703         break;
7704       }
7705     }
7706   }
7707   if (dependent() || SemaRef.CurContext->isDependentContext())
7708     return false;
7709   SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
7710       << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
7711   return true;
7712 }
7713 
checkAndSetIncRHS(Expr * RHS)7714 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
7715   // RHS of canonical loop form increment can be:
7716   //   var + incr
7717   //   incr + var
7718   //   var - incr
7719   //
7720   RHS = RHS->IgnoreParenImpCasts();
7721   if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
7722     if (BO->isAdditiveOp()) {
7723       bool IsAdd = BO->getOpcode() == BO_Add;
7724       if (getInitLCDecl(BO->getLHS()) == LCDecl)
7725         return setStep(BO->getRHS(), !IsAdd);
7726       if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
7727         return setStep(BO->getLHS(), /*Subtract=*/false);
7728     }
7729   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
7730     bool IsAdd = CE->getOperator() == OO_Plus;
7731     if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
7732       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7733         return setStep(CE->getArg(1), !IsAdd);
7734       if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
7735         return setStep(CE->getArg(0), /*Subtract=*/false);
7736     }
7737   }
7738   if (dependent() || SemaRef.CurContext->isDependentContext())
7739     return false;
7740   SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
7741       << RHS->getSourceRange() << LCDecl;
7742   return true;
7743 }
7744 
checkAndSetInc(Expr * S)7745 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
7746   // Check incr-expr for canonical loop form and return true if it
7747   // does not conform.
7748   // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
7749   //   ++var
7750   //   var++
7751   //   --var
7752   //   var--
7753   //   var += incr
7754   //   var -= incr
7755   //   var = var + incr
7756   //   var = incr + var
7757   //   var = var - incr
7758   //
7759   if (!S) {
7760     SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
7761     return true;
7762   }
7763   if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
7764     if (!ExprTemp->cleanupsHaveSideEffects())
7765       S = ExprTemp->getSubExpr();
7766 
7767   IncrementSrcRange = S->getSourceRange();
7768   S = S->IgnoreParens();
7769   if (auto *UO = dyn_cast<UnaryOperator>(S)) {
7770     if (UO->isIncrementDecrementOp() &&
7771         getInitLCDecl(UO->getSubExpr()) == LCDecl)
7772       return setStep(SemaRef
7773                          .ActOnIntegerConstant(UO->getBeginLoc(),
7774                                                (UO->isDecrementOp() ? -1 : 1))
7775                          .get(),
7776                      /*Subtract=*/false);
7777   } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7778     switch (BO->getOpcode()) {
7779     case BO_AddAssign:
7780     case BO_SubAssign:
7781       if (getInitLCDecl(BO->getLHS()) == LCDecl)
7782         return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
7783       break;
7784     case BO_Assign:
7785       if (getInitLCDecl(BO->getLHS()) == LCDecl)
7786         return checkAndSetIncRHS(BO->getRHS());
7787       break;
7788     default:
7789       break;
7790     }
7791   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7792     switch (CE->getOperator()) {
7793     case OO_PlusPlus:
7794     case OO_MinusMinus:
7795       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7796         return setStep(SemaRef
7797                            .ActOnIntegerConstant(
7798                                CE->getBeginLoc(),
7799                                ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
7800                            .get(),
7801                        /*Subtract=*/false);
7802       break;
7803     case OO_PlusEqual:
7804     case OO_MinusEqual:
7805       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7806         return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
7807       break;
7808     case OO_Equal:
7809       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7810         return checkAndSetIncRHS(CE->getArg(1));
7811       break;
7812     default:
7813       break;
7814     }
7815   }
7816   if (dependent() || SemaRef.CurContext->isDependentContext())
7817     return false;
7818   SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
7819       << S->getSourceRange() << LCDecl;
7820   return true;
7821 }
7822 
7823 static ExprResult
tryBuildCapture(Sema & SemaRef,Expr * Capture,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)7824 tryBuildCapture(Sema &SemaRef, Expr *Capture,
7825                 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7826   if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors())
7827     return Capture;
7828   if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
7829     return SemaRef.PerformImplicitConversion(
7830         Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
7831         /*AllowExplicit=*/true);
7832   auto I = Captures.find(Capture);
7833   if (I != Captures.end())
7834     return buildCapture(SemaRef, Capture, I->second);
7835   DeclRefExpr *Ref = nullptr;
7836   ExprResult Res = buildCapture(SemaRef, Capture, Ref);
7837   Captures[Capture] = Ref;
7838   return Res;
7839 }
7840 
7841 /// Calculate number of iterations, transforming to unsigned, if number of
7842 /// iterations may be larger than the original type.
7843 static Expr *
calculateNumIters(Sema & SemaRef,Scope * S,SourceLocation DefaultLoc,Expr * Lower,Expr * Upper,Expr * Step,QualType LCTy,bool TestIsStrictOp,bool RoundToStep,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)7844 calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc,
7845                   Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy,
7846                   bool TestIsStrictOp, bool RoundToStep,
7847                   llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7848   ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
7849   if (!NewStep.isUsable())
7850     return nullptr;
7851   llvm::APSInt LRes, SRes;
7852   bool IsLowerConst = false, IsStepConst = false;
7853   if (Optional<llvm::APSInt> Res = Lower->getIntegerConstantExpr(SemaRef.Context)) {
7854     LRes = *Res;
7855     IsLowerConst = true;
7856   }
7857   if (Optional<llvm::APSInt> Res = Step->getIntegerConstantExpr(SemaRef.Context)) {
7858     SRes = *Res;
7859     IsStepConst = true;
7860   }
7861   bool NoNeedToConvert = IsLowerConst && !RoundToStep &&
7862                          ((!TestIsStrictOp && LRes.isNonNegative()) ||
7863                           (TestIsStrictOp && LRes.isStrictlyPositive()));
7864   bool NeedToReorganize = false;
7865   // Check if any subexpressions in Lower -Step [+ 1] lead to overflow.
7866   if (!NoNeedToConvert && IsLowerConst &&
7867       (TestIsStrictOp || (RoundToStep && IsStepConst))) {
7868     NoNeedToConvert = true;
7869     if (RoundToStep) {
7870       unsigned BW = LRes.getBitWidth() > SRes.getBitWidth()
7871                         ? LRes.getBitWidth()
7872                         : SRes.getBitWidth();
7873       LRes = LRes.extend(BW + 1);
7874       LRes.setIsSigned(true);
7875       SRes = SRes.extend(BW + 1);
7876       SRes.setIsSigned(true);
7877       LRes -= SRes;
7878       NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes;
7879       LRes = LRes.trunc(BW);
7880     }
7881     if (TestIsStrictOp) {
7882       unsigned BW = LRes.getBitWidth();
7883       LRes = LRes.extend(BW + 1);
7884       LRes.setIsSigned(true);
7885       ++LRes;
7886       NoNeedToConvert =
7887           NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes;
7888       // truncate to the original bitwidth.
7889       LRes = LRes.trunc(BW);
7890     }
7891     NeedToReorganize = NoNeedToConvert;
7892   }
7893   llvm::APSInt URes;
7894   bool IsUpperConst = false;
7895   if (Optional<llvm::APSInt> Res = Upper->getIntegerConstantExpr(SemaRef.Context)) {
7896     URes = *Res;
7897     IsUpperConst = true;
7898   }
7899   if (NoNeedToConvert && IsLowerConst && IsUpperConst &&
7900       (!RoundToStep || IsStepConst)) {
7901     unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth()
7902                                                           : URes.getBitWidth();
7903     LRes = LRes.extend(BW + 1);
7904     LRes.setIsSigned(true);
7905     URes = URes.extend(BW + 1);
7906     URes.setIsSigned(true);
7907     URes -= LRes;
7908     NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes;
7909     NeedToReorganize = NoNeedToConvert;
7910   }
7911   // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant
7912   // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to
7913   // unsigned.
7914   if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) &&
7915       !LCTy->isDependentType() && LCTy->isIntegerType()) {
7916     QualType LowerTy = Lower->getType();
7917     QualType UpperTy = Upper->getType();
7918     uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy);
7919     uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy);
7920     if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) ||
7921         (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) {
7922       QualType CastType = SemaRef.Context.getIntTypeForBitwidth(
7923           LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0);
7924       Upper =
7925           SemaRef
7926               .PerformImplicitConversion(
7927                   SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
7928                   CastType, Sema::AA_Converting)
7929               .get();
7930       Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get();
7931       NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get());
7932     }
7933   }
7934   if (!Lower || !Upper || NewStep.isInvalid())
7935     return nullptr;
7936 
7937   ExprResult Diff;
7938   // If need to reorganize, then calculate the form as Upper - (Lower - Step [+
7939   // 1]).
7940   if (NeedToReorganize) {
7941     Diff = Lower;
7942 
7943     if (RoundToStep) {
7944       // Lower - Step
7945       Diff =
7946           SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get());
7947       if (!Diff.isUsable())
7948         return nullptr;
7949     }
7950 
7951     // Lower - Step [+ 1]
7952     if (TestIsStrictOp)
7953       Diff = SemaRef.BuildBinOp(
7954           S, DefaultLoc, BO_Add, Diff.get(),
7955           SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7956     if (!Diff.isUsable())
7957       return nullptr;
7958 
7959     Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7960     if (!Diff.isUsable())
7961       return nullptr;
7962 
7963     // Upper - (Lower - Step [+ 1]).
7964     Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get());
7965     if (!Diff.isUsable())
7966       return nullptr;
7967   } else {
7968     Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
7969 
7970     if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) {
7971       // BuildBinOp already emitted error, this one is to point user to upper
7972       // and lower bound, and to tell what is passed to 'operator-'.
7973       SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
7974           << Upper->getSourceRange() << Lower->getSourceRange();
7975       return nullptr;
7976     }
7977 
7978     if (!Diff.isUsable())
7979       return nullptr;
7980 
7981     // Upper - Lower [- 1]
7982     if (TestIsStrictOp)
7983       Diff = SemaRef.BuildBinOp(
7984           S, DefaultLoc, BO_Sub, Diff.get(),
7985           SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7986     if (!Diff.isUsable())
7987       return nullptr;
7988 
7989     if (RoundToStep) {
7990       // Upper - Lower [- 1] + Step
7991       Diff =
7992           SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
7993       if (!Diff.isUsable())
7994         return nullptr;
7995     }
7996   }
7997 
7998   // Parentheses (for dumping/debugging purposes only).
7999   Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8000   if (!Diff.isUsable())
8001     return nullptr;
8002 
8003   // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step
8004   Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
8005   if (!Diff.isUsable())
8006     return nullptr;
8007 
8008   return Diff.get();
8009 }
8010 
8011 /// Build the expression to calculate the number of iterations.
buildNumIterations(Scope * S,ArrayRef<LoopIterationSpace> ResultIterSpaces,bool LimitedType,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures) const8012 Expr *OpenMPIterationSpaceChecker::buildNumIterations(
8013     Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
8014     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8015   QualType VarType = LCDecl->getType().getNonReferenceType();
8016   if (!VarType->isIntegerType() && !VarType->isPointerType() &&
8017       !SemaRef.getLangOpts().CPlusPlus)
8018     return nullptr;
8019   Expr *LBVal = LB;
8020   Expr *UBVal = UB;
8021   // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
8022   // max(LB(MinVal), LB(MaxVal))
8023   if (InitDependOnLC) {
8024     const LoopIterationSpace &IS = ResultIterSpaces[*InitDependOnLC - 1];
8025     if (!IS.MinValue || !IS.MaxValue)
8026       return nullptr;
8027     // OuterVar = Min
8028     ExprResult MinValue =
8029         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8030     if (!MinValue.isUsable())
8031       return nullptr;
8032 
8033     ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8034                                              IS.CounterVar, MinValue.get());
8035     if (!LBMinVal.isUsable())
8036       return nullptr;
8037     // OuterVar = Min, LBVal
8038     LBMinVal =
8039         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal);
8040     if (!LBMinVal.isUsable())
8041       return nullptr;
8042     // (OuterVar = Min, LBVal)
8043     LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get());
8044     if (!LBMinVal.isUsable())
8045       return nullptr;
8046 
8047     // OuterVar = Max
8048     ExprResult MaxValue =
8049         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8050     if (!MaxValue.isUsable())
8051       return nullptr;
8052 
8053     ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8054                                              IS.CounterVar, MaxValue.get());
8055     if (!LBMaxVal.isUsable())
8056       return nullptr;
8057     // OuterVar = Max, LBVal
8058     LBMaxVal =
8059         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal);
8060     if (!LBMaxVal.isUsable())
8061       return nullptr;
8062     // (OuterVar = Max, LBVal)
8063     LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get());
8064     if (!LBMaxVal.isUsable())
8065       return nullptr;
8066 
8067     Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get();
8068     Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get();
8069     if (!LBMin || !LBMax)
8070       return nullptr;
8071     // LB(MinVal) < LB(MaxVal)
8072     ExprResult MinLessMaxRes =
8073         SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
8074     if (!MinLessMaxRes.isUsable())
8075       return nullptr;
8076     Expr *MinLessMax =
8077         tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get();
8078     if (!MinLessMax)
8079       return nullptr;
8080     if (TestIsLessOp.getValue()) {
8081       // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
8082       // LB(MaxVal))
8083       ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8084                                                     MinLessMax, LBMin, LBMax);
8085       if (!MinLB.isUsable())
8086         return nullptr;
8087       LBVal = MinLB.get();
8088     } else {
8089       // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
8090       // LB(MaxVal))
8091       ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8092                                                     MinLessMax, LBMax, LBMin);
8093       if (!MaxLB.isUsable())
8094         return nullptr;
8095       LBVal = MaxLB.get();
8096     }
8097   }
8098   // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
8099   // min(UB(MinVal), UB(MaxVal))
8100   if (CondDependOnLC) {
8101     const LoopIterationSpace &IS = ResultIterSpaces[*CondDependOnLC - 1];
8102     if (!IS.MinValue || !IS.MaxValue)
8103       return nullptr;
8104     // OuterVar = Min
8105     ExprResult MinValue =
8106         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8107     if (!MinValue.isUsable())
8108       return nullptr;
8109 
8110     ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8111                                              IS.CounterVar, MinValue.get());
8112     if (!UBMinVal.isUsable())
8113       return nullptr;
8114     // OuterVar = Min, UBVal
8115     UBMinVal =
8116         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal);
8117     if (!UBMinVal.isUsable())
8118       return nullptr;
8119     // (OuterVar = Min, UBVal)
8120     UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get());
8121     if (!UBMinVal.isUsable())
8122       return nullptr;
8123 
8124     // OuterVar = Max
8125     ExprResult MaxValue =
8126         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8127     if (!MaxValue.isUsable())
8128       return nullptr;
8129 
8130     ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8131                                              IS.CounterVar, MaxValue.get());
8132     if (!UBMaxVal.isUsable())
8133       return nullptr;
8134     // OuterVar = Max, UBVal
8135     UBMaxVal =
8136         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal);
8137     if (!UBMaxVal.isUsable())
8138       return nullptr;
8139     // (OuterVar = Max, UBVal)
8140     UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get());
8141     if (!UBMaxVal.isUsable())
8142       return nullptr;
8143 
8144     Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get();
8145     Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get();
8146     if (!UBMin || !UBMax)
8147       return nullptr;
8148     // UB(MinVal) > UB(MaxVal)
8149     ExprResult MinGreaterMaxRes =
8150         SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
8151     if (!MinGreaterMaxRes.isUsable())
8152       return nullptr;
8153     Expr *MinGreaterMax =
8154         tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get();
8155     if (!MinGreaterMax)
8156       return nullptr;
8157     if (TestIsLessOp.getValue()) {
8158       // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
8159       // UB(MaxVal))
8160       ExprResult MaxUB = SemaRef.ActOnConditionalOp(
8161           DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
8162       if (!MaxUB.isUsable())
8163         return nullptr;
8164       UBVal = MaxUB.get();
8165     } else {
8166       // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
8167       // UB(MaxVal))
8168       ExprResult MinUB = SemaRef.ActOnConditionalOp(
8169           DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
8170       if (!MinUB.isUsable())
8171         return nullptr;
8172       UBVal = MinUB.get();
8173     }
8174   }
8175   Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal;
8176   Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal;
8177   Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
8178   Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
8179   if (!Upper || !Lower)
8180     return nullptr;
8181 
8182   ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8183                                       Step, VarType, TestIsStrictOp,
8184                                       /*RoundToStep=*/true, Captures);
8185   if (!Diff.isUsable())
8186     return nullptr;
8187 
8188   // OpenMP runtime requires 32-bit or 64-bit loop variables.
8189   QualType Type = Diff.get()->getType();
8190   ASTContext &C = SemaRef.Context;
8191   bool UseVarType = VarType->hasIntegerRepresentation() &&
8192                     C.getTypeSize(Type) > C.getTypeSize(VarType);
8193   if (!Type->isIntegerType() || UseVarType) {
8194     unsigned NewSize =
8195         UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
8196     bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
8197                                : Type->hasSignedIntegerRepresentation();
8198     Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
8199     if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
8200       Diff = SemaRef.PerformImplicitConversion(
8201           Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
8202       if (!Diff.isUsable())
8203         return nullptr;
8204     }
8205   }
8206   if (LimitedType) {
8207     unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
8208     if (NewSize != C.getTypeSize(Type)) {
8209       if (NewSize < C.getTypeSize(Type)) {
8210         assert(NewSize == 64 && "incorrect loop var size");
8211         SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
8212             << InitSrcRange << ConditionSrcRange;
8213       }
8214       QualType NewType = C.getIntTypeForBitwidth(
8215           NewSize, Type->hasSignedIntegerRepresentation() ||
8216                        C.getTypeSize(Type) < NewSize);
8217       if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
8218         Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
8219                                                  Sema::AA_Converting, true);
8220         if (!Diff.isUsable())
8221           return nullptr;
8222       }
8223     }
8224   }
8225 
8226   return Diff.get();
8227 }
8228 
buildMinMaxValues(Scope * S,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures) const8229 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
8230     Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8231   // Do not build for iterators, they cannot be used in non-rectangular loop
8232   // nests.
8233   if (LCDecl->getType()->isRecordType())
8234     return std::make_pair(nullptr, nullptr);
8235   // If we subtract, the min is in the condition, otherwise the min is in the
8236   // init value.
8237   Expr *MinExpr = nullptr;
8238   Expr *MaxExpr = nullptr;
8239   Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB;
8240   Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB;
8241   bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue()
8242                                            : CondDependOnLC.hasValue();
8243   bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue()
8244                                            : InitDependOnLC.hasValue();
8245   Expr *Lower =
8246       LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
8247   Expr *Upper =
8248       UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
8249   if (!Upper || !Lower)
8250     return std::make_pair(nullptr, nullptr);
8251 
8252   if (TestIsLessOp.getValue())
8253     MinExpr = Lower;
8254   else
8255     MaxExpr = Upper;
8256 
8257   // Build minimum/maximum value based on number of iterations.
8258   QualType VarType = LCDecl->getType().getNonReferenceType();
8259 
8260   ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8261                                       Step, VarType, TestIsStrictOp,
8262                                       /*RoundToStep=*/false, Captures);
8263   if (!Diff.isUsable())
8264     return std::make_pair(nullptr, nullptr);
8265 
8266   // ((Upper - Lower [- 1]) / Step) * Step
8267   // Parentheses (for dumping/debugging purposes only).
8268   Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8269   if (!Diff.isUsable())
8270     return std::make_pair(nullptr, nullptr);
8271 
8272   ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
8273   if (!NewStep.isUsable())
8274     return std::make_pair(nullptr, nullptr);
8275   Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get());
8276   if (!Diff.isUsable())
8277     return std::make_pair(nullptr, nullptr);
8278 
8279   // Parentheses (for dumping/debugging purposes only).
8280   Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8281   if (!Diff.isUsable())
8282     return std::make_pair(nullptr, nullptr);
8283 
8284   // Convert to the ptrdiff_t, if original type is pointer.
8285   if (VarType->isAnyPointerType() &&
8286       !SemaRef.Context.hasSameType(
8287           Diff.get()->getType(),
8288           SemaRef.Context.getUnsignedPointerDiffType())) {
8289     Diff = SemaRef.PerformImplicitConversion(
8290         Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(),
8291         Sema::AA_Converting, /*AllowExplicit=*/true);
8292   }
8293   if (!Diff.isUsable())
8294     return std::make_pair(nullptr, nullptr);
8295 
8296   if (TestIsLessOp.getValue()) {
8297     // MinExpr = Lower;
8298     // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
8299     Diff = SemaRef.BuildBinOp(
8300         S, DefaultLoc, BO_Add,
8301         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(),
8302         Diff.get());
8303     if (!Diff.isUsable())
8304       return std::make_pair(nullptr, nullptr);
8305   } else {
8306     // MaxExpr = Upper;
8307     // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
8308     Diff = SemaRef.BuildBinOp(
8309         S, DefaultLoc, BO_Sub,
8310         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
8311         Diff.get());
8312     if (!Diff.isUsable())
8313       return std::make_pair(nullptr, nullptr);
8314   }
8315 
8316   // Convert to the original type.
8317   if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType))
8318     Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType,
8319                                              Sema::AA_Converting,
8320                                              /*AllowExplicit=*/true);
8321   if (!Diff.isUsable())
8322     return std::make_pair(nullptr, nullptr);
8323 
8324   Sema::TentativeAnalysisScope Trap(SemaRef);
8325   Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false);
8326   if (!Diff.isUsable())
8327     return std::make_pair(nullptr, nullptr);
8328 
8329   if (TestIsLessOp.getValue())
8330     MaxExpr = Diff.get();
8331   else
8332     MinExpr = Diff.get();
8333 
8334   return std::make_pair(MinExpr, MaxExpr);
8335 }
8336 
buildFinalCondition(Scope * S) const8337 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const {
8338   if (InitDependOnLC || CondDependOnLC)
8339     return Condition;
8340   return nullptr;
8341 }
8342 
buildPreCond(Scope * S,Expr * Cond,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures) const8343 Expr *OpenMPIterationSpaceChecker::buildPreCond(
8344     Scope *S, Expr *Cond,
8345     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8346   // Do not build a precondition when the condition/initialization is dependent
8347   // to prevent pessimistic early loop exit.
8348   // TODO: this can be improved by calculating min/max values but not sure that
8349   // it will be very effective.
8350   if (CondDependOnLC || InitDependOnLC)
8351     return SemaRef.PerformImplicitConversion(
8352         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(),
8353         SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
8354         /*AllowExplicit=*/true).get();
8355 
8356   // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
8357   Sema::TentativeAnalysisScope Trap(SemaRef);
8358 
8359   ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
8360   ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
8361   if (!NewLB.isUsable() || !NewUB.isUsable())
8362     return nullptr;
8363 
8364   ExprResult CondExpr =
8365       SemaRef.BuildBinOp(S, DefaultLoc,
8366                          TestIsLessOp.getValue() ?
8367                            (TestIsStrictOp ? BO_LT : BO_LE) :
8368                            (TestIsStrictOp ? BO_GT : BO_GE),
8369                          NewLB.get(), NewUB.get());
8370   if (CondExpr.isUsable()) {
8371     if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
8372                                                 SemaRef.Context.BoolTy))
8373       CondExpr = SemaRef.PerformImplicitConversion(
8374           CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
8375           /*AllowExplicit=*/true);
8376   }
8377 
8378   // Otherwise use original loop condition and evaluate it in runtime.
8379   return CondExpr.isUsable() ? CondExpr.get() : Cond;
8380 }
8381 
8382 /// Build reference expression to the counter be used for codegen.
buildCounterVar(llvm::MapVector<const Expr *,DeclRefExpr * > & Captures,DSAStackTy & DSA) const8383 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
8384     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8385     DSAStackTy &DSA) const {
8386   auto *VD = dyn_cast<VarDecl>(LCDecl);
8387   if (!VD) {
8388     VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
8389     DeclRefExpr *Ref = buildDeclRefExpr(
8390         SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
8391     const DSAStackTy::DSAVarData Data =
8392         DSA.getTopDSA(LCDecl, /*FromParent=*/false);
8393     // If the loop control decl is explicitly marked as private, do not mark it
8394     // as captured again.
8395     if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
8396       Captures.insert(std::make_pair(LCRef, Ref));
8397     return Ref;
8398   }
8399   return cast<DeclRefExpr>(LCRef);
8400 }
8401 
buildPrivateCounterVar() const8402 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
8403   if (LCDecl && !LCDecl->isInvalidDecl()) {
8404     QualType Type = LCDecl->getType().getNonReferenceType();
8405     VarDecl *PrivateVar = buildVarDecl(
8406         SemaRef, DefaultLoc, Type, LCDecl->getName(),
8407         LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
8408         isa<VarDecl>(LCDecl)
8409             ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
8410             : nullptr);
8411     if (PrivateVar->isInvalidDecl())
8412       return nullptr;
8413     return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
8414   }
8415   return nullptr;
8416 }
8417 
8418 /// Build initialization of the counter to be used for codegen.
buildCounterInit() const8419 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
8420 
8421 /// Build step of the counter be used for codegen.
buildCounterStep() const8422 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
8423 
buildOrderedLoopData(Scope * S,Expr * Counter,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures,SourceLocation Loc,Expr * Inc,OverloadedOperatorKind OOK)8424 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
8425     Scope *S, Expr *Counter,
8426     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
8427     Expr *Inc, OverloadedOperatorKind OOK) {
8428   Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
8429   if (!Cnt)
8430     return nullptr;
8431   if (Inc) {
8432     assert((OOK == OO_Plus || OOK == OO_Minus) &&
8433            "Expected only + or - operations for depend clauses.");
8434     BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
8435     Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
8436     if (!Cnt)
8437       return nullptr;
8438   }
8439   QualType VarType = LCDecl->getType().getNonReferenceType();
8440   if (!VarType->isIntegerType() && !VarType->isPointerType() &&
8441       !SemaRef.getLangOpts().CPlusPlus)
8442     return nullptr;
8443   // Upper - Lower
8444   Expr *Upper = TestIsLessOp.getValue()
8445                     ? Cnt
8446                     : tryBuildCapture(SemaRef, LB, Captures).get();
8447   Expr *Lower = TestIsLessOp.getValue()
8448                     ? tryBuildCapture(SemaRef, LB, Captures).get()
8449                     : Cnt;
8450   if (!Upper || !Lower)
8451     return nullptr;
8452 
8453   ExprResult Diff = calculateNumIters(
8454       SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
8455       /*TestIsStrictOp=*/false, /*RoundToStep=*/false, Captures);
8456   if (!Diff.isUsable())
8457     return nullptr;
8458 
8459   return Diff.get();
8460 }
8461 } // namespace
8462 
ActOnOpenMPLoopInitialization(SourceLocation ForLoc,Stmt * Init)8463 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
8464   assert(getLangOpts().OpenMP && "OpenMP is not active.");
8465   assert(Init && "Expected loop in canonical form.");
8466   unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
8467   if (AssociatedLoops > 0 &&
8468       isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
8469     DSAStack->loopStart();
8470     OpenMPIterationSpaceChecker ISC(*this, /*SupportsNonRectangular=*/true,
8471                                     *DSAStack, ForLoc);
8472     if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
8473       if (ValueDecl *D = ISC.getLoopDecl()) {
8474         auto *VD = dyn_cast<VarDecl>(D);
8475         DeclRefExpr *PrivateRef = nullptr;
8476         if (!VD) {
8477           if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
8478             VD = Private;
8479           } else {
8480             PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
8481                                       /*WithInit=*/false);
8482             VD = cast<VarDecl>(PrivateRef->getDecl());
8483           }
8484         }
8485         DSAStack->addLoopControlVariable(D, VD);
8486         const Decl *LD = DSAStack->getPossiblyLoopCunter();
8487         if (LD != D->getCanonicalDecl()) {
8488           DSAStack->resetPossibleLoopCounter();
8489           if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
8490             MarkDeclarationsReferencedInExpr(
8491                 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
8492                                  Var->getType().getNonLValueExprType(Context),
8493                                  ForLoc, /*RefersToCapture=*/true));
8494         }
8495         OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
8496         // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
8497         // Referenced in a Construct, C/C++]. The loop iteration variable in the
8498         // associated for-loop of a simd construct with just one associated
8499         // for-loop may be listed in a linear clause with a constant-linear-step
8500         // that is the increment of the associated for-loop. The loop iteration
8501         // variable(s) in the associated for-loop(s) of a for or parallel for
8502         // construct may be listed in a private or lastprivate clause.
8503         DSAStackTy::DSAVarData DVar =
8504             DSAStack->getTopDSA(D, /*FromParent=*/false);
8505         // If LoopVarRefExpr is nullptr it means the corresponding loop variable
8506         // is declared in the loop and it is predetermined as a private.
8507         Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
8508         OpenMPClauseKind PredeterminedCKind =
8509             isOpenMPSimdDirective(DKind)
8510                 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
8511                 : OMPC_private;
8512         if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
8513               DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
8514               (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
8515                                          DVar.CKind != OMPC_private))) ||
8516              ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
8517                DKind == OMPD_master_taskloop ||
8518                DKind == OMPD_parallel_master_taskloop ||
8519                isOpenMPDistributeDirective(DKind)) &&
8520               !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
8521               DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
8522             (DVar.CKind != OMPC_private || DVar.RefExpr)) {
8523           Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
8524               << getOpenMPClauseName(DVar.CKind)
8525               << getOpenMPDirectiveName(DKind)
8526               << getOpenMPClauseName(PredeterminedCKind);
8527           if (DVar.RefExpr == nullptr)
8528             DVar.CKind = PredeterminedCKind;
8529           reportOriginalDsa(*this, DSAStack, D, DVar,
8530                             /*IsLoopIterVar=*/true);
8531         } else if (LoopDeclRefExpr) {
8532           // Make the loop iteration variable private (for worksharing
8533           // constructs), linear (for simd directives with the only one
8534           // associated loop) or lastprivate (for simd directives with several
8535           // collapsed or ordered loops).
8536           if (DVar.CKind == OMPC_unknown)
8537             DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
8538                              PrivateRef);
8539         }
8540       }
8541     }
8542     DSAStack->setAssociatedLoops(AssociatedLoops - 1);
8543   }
8544 }
8545 
8546 /// Called on a for stmt to check and extract its iteration space
8547 /// for further processing (such as collapsing).
checkOpenMPIterationSpace(OpenMPDirectiveKind DKind,Stmt * S,Sema & SemaRef,DSAStackTy & DSA,unsigned CurrentNestedLoopCount,unsigned NestedLoopCount,unsigned TotalNestedLoopCount,Expr * CollapseLoopCountExpr,Expr * OrderedLoopCountExpr,Sema::VarsWithInheritedDSAType & VarsWithImplicitDSA,llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)8548 static bool checkOpenMPIterationSpace(
8549     OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
8550     unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
8551     unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
8552     Expr *OrderedLoopCountExpr,
8553     Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
8554     llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,
8555     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8556   bool SupportsNonRectangular = !isOpenMPLoopTransformationDirective(DKind);
8557   // OpenMP [2.9.1, Canonical Loop Form]
8558   //   for (init-expr; test-expr; incr-expr) structured-block
8559   //   for (range-decl: range-expr) structured-block
8560   if (auto *CanonLoop = dyn_cast_or_null<OMPCanonicalLoop>(S))
8561     S = CanonLoop->getLoopStmt();
8562   auto *For = dyn_cast_or_null<ForStmt>(S);
8563   auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
8564   // Ranged for is supported only in OpenMP 5.0.
8565   if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) {
8566     SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
8567         << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
8568         << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
8569         << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
8570     if (TotalNestedLoopCount > 1) {
8571       if (CollapseLoopCountExpr && OrderedLoopCountExpr)
8572         SemaRef.Diag(DSA.getConstructLoc(),
8573                      diag::note_omp_collapse_ordered_expr)
8574             << 2 << CollapseLoopCountExpr->getSourceRange()
8575             << OrderedLoopCountExpr->getSourceRange();
8576       else if (CollapseLoopCountExpr)
8577         SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
8578                      diag::note_omp_collapse_ordered_expr)
8579             << 0 << CollapseLoopCountExpr->getSourceRange();
8580       else
8581         SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
8582                      diag::note_omp_collapse_ordered_expr)
8583             << 1 << OrderedLoopCountExpr->getSourceRange();
8584     }
8585     return true;
8586   }
8587   assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&
8588          "No loop body.");
8589 
8590   OpenMPIterationSpaceChecker ISC(SemaRef, SupportsNonRectangular, DSA,
8591                                   For ? For->getForLoc() : CXXFor->getForLoc());
8592 
8593   // Check init.
8594   Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt();
8595   if (ISC.checkAndSetInit(Init))
8596     return true;
8597 
8598   bool HasErrors = false;
8599 
8600   // Check loop variable's type.
8601   if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
8602     // OpenMP [2.6, Canonical Loop Form]
8603     // Var is one of the following:
8604     //   A variable of signed or unsigned integer type.
8605     //   For C++, a variable of a random access iterator type.
8606     //   For C, a variable of a pointer type.
8607     QualType VarType = LCDecl->getType().getNonReferenceType();
8608     if (!VarType->isDependentType() && !VarType->isIntegerType() &&
8609         !VarType->isPointerType() &&
8610         !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
8611       SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
8612           << SemaRef.getLangOpts().CPlusPlus;
8613       HasErrors = true;
8614     }
8615 
8616     // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
8617     // a Construct
8618     // The loop iteration variable(s) in the associated for-loop(s) of a for or
8619     // parallel for construct is (are) private.
8620     // The loop iteration variable in the associated for-loop of a simd
8621     // construct with just one associated for-loop is linear with a
8622     // constant-linear-step that is the increment of the associated for-loop.
8623     // Exclude loop var from the list of variables with implicitly defined data
8624     // sharing attributes.
8625     VarsWithImplicitDSA.erase(LCDecl);
8626 
8627     assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
8628 
8629     // Check test-expr.
8630     HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
8631 
8632     // Check incr-expr.
8633     HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
8634   }
8635 
8636   if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
8637     return HasErrors;
8638 
8639   // Build the loop's iteration space representation.
8640   ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
8641       DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
8642   ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
8643       ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
8644                              (isOpenMPWorksharingDirective(DKind) ||
8645                               isOpenMPTaskLoopDirective(DKind) ||
8646                               isOpenMPDistributeDirective(DKind) ||
8647                               isOpenMPLoopTransformationDirective(DKind)),
8648                              Captures);
8649   ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
8650       ISC.buildCounterVar(Captures, DSA);
8651   ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
8652       ISC.buildPrivateCounterVar();
8653   ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
8654   ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
8655   ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
8656   ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
8657       ISC.getConditionSrcRange();
8658   ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
8659       ISC.getIncrementSrcRange();
8660   ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
8661   ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
8662       ISC.isStrictTestOp();
8663   std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
8664            ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
8665       ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
8666   ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
8667       ISC.buildFinalCondition(DSA.getCurScope());
8668   ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
8669       ISC.doesInitDependOnLC();
8670   ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
8671       ISC.doesCondDependOnLC();
8672   ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
8673       ISC.getLoopDependentIdx();
8674 
8675   HasErrors |=
8676       (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr ||
8677        ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr ||
8678        ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr ||
8679        ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr ||
8680        ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr ||
8681        ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr);
8682   if (!HasErrors && DSA.isOrderedRegion()) {
8683     if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
8684       if (CurrentNestedLoopCount <
8685           DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
8686         DSA.getOrderedRegionParam().second->setLoopNumIterations(
8687             CurrentNestedLoopCount,
8688             ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
8689         DSA.getOrderedRegionParam().second->setLoopCounter(
8690             CurrentNestedLoopCount,
8691             ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
8692       }
8693     }
8694     for (auto &Pair : DSA.getDoacrossDependClauses()) {
8695       if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
8696         // Erroneous case - clause has some problems.
8697         continue;
8698       }
8699       if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
8700           Pair.second.size() <= CurrentNestedLoopCount) {
8701         // Erroneous case - clause has some problems.
8702         Pair.first->setLoopData(CurrentNestedLoopCount, nullptr);
8703         continue;
8704       }
8705       Expr *CntValue;
8706       if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
8707         CntValue = ISC.buildOrderedLoopData(
8708             DSA.getCurScope(),
8709             ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
8710             Pair.first->getDependencyLoc());
8711       else
8712         CntValue = ISC.buildOrderedLoopData(
8713             DSA.getCurScope(),
8714             ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
8715             Pair.first->getDependencyLoc(),
8716             Pair.second[CurrentNestedLoopCount].first,
8717             Pair.second[CurrentNestedLoopCount].second);
8718       Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
8719     }
8720   }
8721 
8722   return HasErrors;
8723 }
8724 
8725 /// Build 'VarRef = Start.
8726 static ExprResult
buildCounterInit(Sema & SemaRef,Scope * S,SourceLocation Loc,ExprResult VarRef,ExprResult Start,bool IsNonRectangularLB,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)8727 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
8728                  ExprResult Start, bool IsNonRectangularLB,
8729                  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8730   // Build 'VarRef = Start.
8731   ExprResult NewStart = IsNonRectangularLB
8732                             ? Start.get()
8733                             : tryBuildCapture(SemaRef, Start.get(), Captures);
8734   if (!NewStart.isUsable())
8735     return ExprError();
8736   if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
8737                                    VarRef.get()->getType())) {
8738     NewStart = SemaRef.PerformImplicitConversion(
8739         NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
8740         /*AllowExplicit=*/true);
8741     if (!NewStart.isUsable())
8742       return ExprError();
8743   }
8744 
8745   ExprResult Init =
8746       SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
8747   return Init;
8748 }
8749 
8750 /// Build 'VarRef = Start + Iter * Step'.
buildCounterUpdate(Sema & SemaRef,Scope * S,SourceLocation Loc,ExprResult VarRef,ExprResult Start,ExprResult Iter,ExprResult Step,bool Subtract,bool IsNonRectangularLB,llvm::MapVector<const Expr *,DeclRefExpr * > * Captures=nullptr)8751 static ExprResult buildCounterUpdate(
8752     Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
8753     ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
8754     bool IsNonRectangularLB,
8755     llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
8756   // Add parentheses (for debugging purposes only).
8757   Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
8758   if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
8759       !Step.isUsable())
8760     return ExprError();
8761 
8762   ExprResult NewStep = Step;
8763   if (Captures)
8764     NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
8765   if (NewStep.isInvalid())
8766     return ExprError();
8767   ExprResult Update =
8768       SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
8769   if (!Update.isUsable())
8770     return ExprError();
8771 
8772   // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
8773   // 'VarRef = Start (+|-) Iter * Step'.
8774   if (!Start.isUsable())
8775     return ExprError();
8776   ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get());
8777   if (!NewStart.isUsable())
8778     return ExprError();
8779   if (Captures && !IsNonRectangularLB)
8780     NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
8781   if (NewStart.isInvalid())
8782     return ExprError();
8783 
8784   // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
8785   ExprResult SavedUpdate = Update;
8786   ExprResult UpdateVal;
8787   if (VarRef.get()->getType()->isOverloadableType() ||
8788       NewStart.get()->getType()->isOverloadableType() ||
8789       Update.get()->getType()->isOverloadableType()) {
8790     Sema::TentativeAnalysisScope Trap(SemaRef);
8791 
8792     Update =
8793         SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
8794     if (Update.isUsable()) {
8795       UpdateVal =
8796           SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
8797                              VarRef.get(), SavedUpdate.get());
8798       if (UpdateVal.isUsable()) {
8799         Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
8800                                             UpdateVal.get());
8801       }
8802     }
8803   }
8804 
8805   // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
8806   if (!Update.isUsable() || !UpdateVal.isUsable()) {
8807     Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
8808                                 NewStart.get(), SavedUpdate.get());
8809     if (!Update.isUsable())
8810       return ExprError();
8811 
8812     if (!SemaRef.Context.hasSameType(Update.get()->getType(),
8813                                      VarRef.get()->getType())) {
8814       Update = SemaRef.PerformImplicitConversion(
8815           Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
8816       if (!Update.isUsable())
8817         return ExprError();
8818     }
8819 
8820     Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
8821   }
8822   return Update;
8823 }
8824 
8825 /// Convert integer expression \a E to make it have at least \a Bits
8826 /// bits.
widenIterationCount(unsigned Bits,Expr * E,Sema & SemaRef)8827 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
8828   if (E == nullptr)
8829     return ExprError();
8830   ASTContext &C = SemaRef.Context;
8831   QualType OldType = E->getType();
8832   unsigned HasBits = C.getTypeSize(OldType);
8833   if (HasBits >= Bits)
8834     return ExprResult(E);
8835   // OK to convert to signed, because new type has more bits than old.
8836   QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
8837   return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
8838                                            true);
8839 }
8840 
8841 /// Check if the given expression \a E is a constant integer that fits
8842 /// into \a Bits bits.
fitsInto(unsigned Bits,bool Signed,const Expr * E,Sema & SemaRef)8843 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
8844   if (E == nullptr)
8845     return false;
8846   if (Optional<llvm::APSInt> Result =
8847           E->getIntegerConstantExpr(SemaRef.Context))
8848     return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits);
8849   return false;
8850 }
8851 
8852 /// Build preinits statement for the given declarations.
buildPreInits(ASTContext & Context,MutableArrayRef<Decl * > PreInits)8853 static Stmt *buildPreInits(ASTContext &Context,
8854                            MutableArrayRef<Decl *> PreInits) {
8855   if (!PreInits.empty()) {
8856     return new (Context) DeclStmt(
8857         DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
8858         SourceLocation(), SourceLocation());
8859   }
8860   return nullptr;
8861 }
8862 
8863 /// Build preinits statement for the given declarations.
8864 static Stmt *
buildPreInits(ASTContext & Context,const llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)8865 buildPreInits(ASTContext &Context,
8866               const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8867   if (!Captures.empty()) {
8868     SmallVector<Decl *, 16> PreInits;
8869     for (const auto &Pair : Captures)
8870       PreInits.push_back(Pair.second->getDecl());
8871     return buildPreInits(Context, PreInits);
8872   }
8873   return nullptr;
8874 }
8875 
8876 /// Build postupdate expression for the given list of postupdates expressions.
buildPostUpdate(Sema & S,ArrayRef<Expr * > PostUpdates)8877 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
8878   Expr *PostUpdate = nullptr;
8879   if (!PostUpdates.empty()) {
8880     for (Expr *E : PostUpdates) {
8881       Expr *ConvE = S.BuildCStyleCastExpr(
8882                          E->getExprLoc(),
8883                          S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
8884                          E->getExprLoc(), E)
8885                         .get();
8886       PostUpdate = PostUpdate
8887                        ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
8888                                               PostUpdate, ConvE)
8889                              .get()
8890                        : ConvE;
8891     }
8892   }
8893   return PostUpdate;
8894 }
8895 
8896 /// Called on a for stmt to check itself and nested loops (if any).
8897 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
8898 /// number of collapsed loops otherwise.
8899 static unsigned
checkOpenMPLoop(OpenMPDirectiveKind DKind,Expr * CollapseLoopCountExpr,Expr * OrderedLoopCountExpr,Stmt * AStmt,Sema & SemaRef,DSAStackTy & DSA,Sema::VarsWithInheritedDSAType & VarsWithImplicitDSA,OMPLoopBasedDirective::HelperExprs & Built)8900 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
8901                 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
8902                 DSAStackTy &DSA,
8903                 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
8904                 OMPLoopBasedDirective::HelperExprs &Built) {
8905   unsigned NestedLoopCount = 1;
8906   bool SupportsNonPerfectlyNested = (SemaRef.LangOpts.OpenMP >= 50) &&
8907                                     !isOpenMPLoopTransformationDirective(DKind);
8908 
8909   if (CollapseLoopCountExpr) {
8910     // Found 'collapse' clause - calculate collapse number.
8911     Expr::EvalResult Result;
8912     if (!CollapseLoopCountExpr->isValueDependent() &&
8913         CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
8914       NestedLoopCount = Result.Val.getInt().getLimitedValue();
8915     } else {
8916       Built.clear(/*Size=*/1);
8917       return 1;
8918     }
8919   }
8920   unsigned OrderedLoopCount = 1;
8921   if (OrderedLoopCountExpr) {
8922     // Found 'ordered' clause - calculate collapse number.
8923     Expr::EvalResult EVResult;
8924     if (!OrderedLoopCountExpr->isValueDependent() &&
8925         OrderedLoopCountExpr->EvaluateAsInt(EVResult,
8926                                             SemaRef.getASTContext())) {
8927       llvm::APSInt Result = EVResult.Val.getInt();
8928       if (Result.getLimitedValue() < NestedLoopCount) {
8929         SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
8930                      diag::err_omp_wrong_ordered_loop_count)
8931             << OrderedLoopCountExpr->getSourceRange();
8932         SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
8933                      diag::note_collapse_loop_count)
8934             << CollapseLoopCountExpr->getSourceRange();
8935       }
8936       OrderedLoopCount = Result.getLimitedValue();
8937     } else {
8938       Built.clear(/*Size=*/1);
8939       return 1;
8940     }
8941   }
8942   // This is helper routine for loop directives (e.g., 'for', 'simd',
8943   // 'for simd', etc.).
8944   llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
8945   unsigned NumLoops = std::max(OrderedLoopCount, NestedLoopCount);
8946   SmallVector<LoopIterationSpace, 4> IterSpaces(NumLoops);
8947   if (!OMPLoopBasedDirective::doForAllLoops(
8948           AStmt->IgnoreContainers(!isOpenMPLoopTransformationDirective(DKind)),
8949           SupportsNonPerfectlyNested, NumLoops,
8950           [DKind, &SemaRef, &DSA, NumLoops, NestedLoopCount,
8951            CollapseLoopCountExpr, OrderedLoopCountExpr, &VarsWithImplicitDSA,
8952            &IterSpaces, &Captures](unsigned Cnt, Stmt *CurStmt) {
8953             if (checkOpenMPIterationSpace(
8954                     DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
8955                     NumLoops, CollapseLoopCountExpr, OrderedLoopCountExpr,
8956                     VarsWithImplicitDSA, IterSpaces, Captures))
8957               return true;
8958             if (Cnt > 0 && Cnt >= NestedLoopCount &&
8959                 IterSpaces[Cnt].CounterVar) {
8960               // Handle initialization of captured loop iterator variables.
8961               auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
8962               if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
8963                 Captures[DRE] = DRE;
8964               }
8965             }
8966             return false;
8967           }))
8968     return 0;
8969 
8970   Built.clear(/* size */ NestedLoopCount);
8971 
8972   if (SemaRef.CurContext->isDependentContext())
8973     return NestedLoopCount;
8974 
8975   // An example of what is generated for the following code:
8976   //
8977   //   #pragma omp simd collapse(2) ordered(2)
8978   //   for (i = 0; i < NI; ++i)
8979   //     for (k = 0; k < NK; ++k)
8980   //       for (j = J0; j < NJ; j+=2) {
8981   //         <loop body>
8982   //       }
8983   //
8984   // We generate the code below.
8985   // Note: the loop body may be outlined in CodeGen.
8986   // Note: some counters may be C++ classes, operator- is used to find number of
8987   // iterations and operator+= to calculate counter value.
8988   // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
8989   // or i64 is currently supported).
8990   //
8991   //   #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
8992   //   for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
8993   //     .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
8994   //     .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
8995   //     // similar updates for vars in clauses (e.g. 'linear')
8996   //     <loop body (using local i and j)>
8997   //   }
8998   //   i = NI; // assign final values of counters
8999   //   j = NJ;
9000   //
9001 
9002   // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
9003   // the iteration counts of the collapsed for loops.
9004   // Precondition tests if there is at least one iteration (all conditions are
9005   // true).
9006   auto PreCond = ExprResult(IterSpaces[0].PreCond);
9007   Expr *N0 = IterSpaces[0].NumIterations;
9008   ExprResult LastIteration32 =
9009       widenIterationCount(/*Bits=*/32,
9010                           SemaRef
9011                               .PerformImplicitConversion(
9012                                   N0->IgnoreImpCasts(), N0->getType(),
9013                                   Sema::AA_Converting, /*AllowExplicit=*/true)
9014                               .get(),
9015                           SemaRef);
9016   ExprResult LastIteration64 = widenIterationCount(
9017       /*Bits=*/64,
9018       SemaRef
9019           .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
9020                                      Sema::AA_Converting,
9021                                      /*AllowExplicit=*/true)
9022           .get(),
9023       SemaRef);
9024 
9025   if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
9026     return NestedLoopCount;
9027 
9028   ASTContext &C = SemaRef.Context;
9029   bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
9030 
9031   Scope *CurScope = DSA.getCurScope();
9032   for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
9033     if (PreCond.isUsable()) {
9034       PreCond =
9035           SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
9036                              PreCond.get(), IterSpaces[Cnt].PreCond);
9037     }
9038     Expr *N = IterSpaces[Cnt].NumIterations;
9039     SourceLocation Loc = N->getExprLoc();
9040     AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
9041     if (LastIteration32.isUsable())
9042       LastIteration32 = SemaRef.BuildBinOp(
9043           CurScope, Loc, BO_Mul, LastIteration32.get(),
9044           SemaRef
9045               .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
9046                                          Sema::AA_Converting,
9047                                          /*AllowExplicit=*/true)
9048               .get());
9049     if (LastIteration64.isUsable())
9050       LastIteration64 = SemaRef.BuildBinOp(
9051           CurScope, Loc, BO_Mul, LastIteration64.get(),
9052           SemaRef
9053               .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
9054                                          Sema::AA_Converting,
9055                                          /*AllowExplicit=*/true)
9056               .get());
9057   }
9058 
9059   // Choose either the 32-bit or 64-bit version.
9060   ExprResult LastIteration = LastIteration64;
9061   if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
9062       (LastIteration32.isUsable() &&
9063        C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
9064        (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
9065         fitsInto(
9066             /*Bits=*/32,
9067             LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
9068             LastIteration64.get(), SemaRef))))
9069     LastIteration = LastIteration32;
9070   QualType VType = LastIteration.get()->getType();
9071   QualType RealVType = VType;
9072   QualType StrideVType = VType;
9073   if (isOpenMPTaskLoopDirective(DKind)) {
9074     VType =
9075         SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
9076     StrideVType =
9077         SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
9078   }
9079 
9080   if (!LastIteration.isUsable())
9081     return 0;
9082 
9083   // Save the number of iterations.
9084   ExprResult NumIterations = LastIteration;
9085   {
9086     LastIteration = SemaRef.BuildBinOp(
9087         CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
9088         LastIteration.get(),
9089         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9090     if (!LastIteration.isUsable())
9091       return 0;
9092   }
9093 
9094   // Calculate the last iteration number beforehand instead of doing this on
9095   // each iteration. Do not do this if the number of iterations may be kfold-ed.
9096   bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context);
9097   ExprResult CalcLastIteration;
9098   if (!IsConstant) {
9099     ExprResult SaveRef =
9100         tryBuildCapture(SemaRef, LastIteration.get(), Captures);
9101     LastIteration = SaveRef;
9102 
9103     // Prepare SaveRef + 1.
9104     NumIterations = SemaRef.BuildBinOp(
9105         CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
9106         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9107     if (!NumIterations.isUsable())
9108       return 0;
9109   }
9110 
9111   SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
9112 
9113   // Build variables passed into runtime, necessary for worksharing directives.
9114   ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
9115   if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
9116       isOpenMPDistributeDirective(DKind) ||
9117       isOpenMPLoopTransformationDirective(DKind)) {
9118     // Lower bound variable, initialized with zero.
9119     VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
9120     LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
9121     SemaRef.AddInitializerToDecl(LBDecl,
9122                                  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9123                                  /*DirectInit*/ false);
9124 
9125     // Upper bound variable, initialized with last iteration number.
9126     VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
9127     UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
9128     SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
9129                                  /*DirectInit*/ false);
9130 
9131     // A 32-bit variable-flag where runtime returns 1 for the last iteration.
9132     // This will be used to implement clause 'lastprivate'.
9133     QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
9134     VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
9135     IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
9136     SemaRef.AddInitializerToDecl(ILDecl,
9137                                  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9138                                  /*DirectInit*/ false);
9139 
9140     // Stride variable returned by runtime (we initialize it to 1 by default).
9141     VarDecl *STDecl =
9142         buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
9143     ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
9144     SemaRef.AddInitializerToDecl(STDecl,
9145                                  SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
9146                                  /*DirectInit*/ false);
9147 
9148     // Build expression: UB = min(UB, LastIteration)
9149     // It is necessary for CodeGen of directives with static scheduling.
9150     ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
9151                                                 UB.get(), LastIteration.get());
9152     ExprResult CondOp = SemaRef.ActOnConditionalOp(
9153         LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
9154         LastIteration.get(), UB.get());
9155     EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
9156                              CondOp.get());
9157     EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
9158 
9159     // If we have a combined directive that combines 'distribute', 'for' or
9160     // 'simd' we need to be able to access the bounds of the schedule of the
9161     // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
9162     // by scheduling 'distribute' have to be passed to the schedule of 'for'.
9163     if (isOpenMPLoopBoundSharingDirective(DKind)) {
9164       // Lower bound variable, initialized with zero.
9165       VarDecl *CombLBDecl =
9166           buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
9167       CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
9168       SemaRef.AddInitializerToDecl(
9169           CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9170           /*DirectInit*/ false);
9171 
9172       // Upper bound variable, initialized with last iteration number.
9173       VarDecl *CombUBDecl =
9174           buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
9175       CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
9176       SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
9177                                    /*DirectInit*/ false);
9178 
9179       ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
9180           CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
9181       ExprResult CombCondOp =
9182           SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
9183                                      LastIteration.get(), CombUB.get());
9184       CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
9185                                    CombCondOp.get());
9186       CombEUB =
9187           SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
9188 
9189       const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
9190       // We expect to have at least 2 more parameters than the 'parallel'
9191       // directive does - the lower and upper bounds of the previous schedule.
9192       assert(CD->getNumParams() >= 4 &&
9193              "Unexpected number of parameters in loop combined directive");
9194 
9195       // Set the proper type for the bounds given what we learned from the
9196       // enclosed loops.
9197       ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
9198       ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
9199 
9200       // Previous lower and upper bounds are obtained from the region
9201       // parameters.
9202       PrevLB =
9203           buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
9204       PrevUB =
9205           buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
9206     }
9207   }
9208 
9209   // Build the iteration variable and its initialization before loop.
9210   ExprResult IV;
9211   ExprResult Init, CombInit;
9212   {
9213     VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
9214     IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
9215     Expr *RHS = (isOpenMPWorksharingDirective(DKind) ||
9216                  isOpenMPTaskLoopDirective(DKind) ||
9217                  isOpenMPDistributeDirective(DKind) ||
9218                  isOpenMPLoopTransformationDirective(DKind))
9219                     ? LB.get()
9220                     : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
9221     Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
9222     Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
9223 
9224     if (isOpenMPLoopBoundSharingDirective(DKind)) {
9225       Expr *CombRHS =
9226           (isOpenMPWorksharingDirective(DKind) ||
9227            isOpenMPTaskLoopDirective(DKind) ||
9228            isOpenMPDistributeDirective(DKind))
9229               ? CombLB.get()
9230               : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
9231       CombInit =
9232           SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
9233       CombInit =
9234           SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
9235     }
9236   }
9237 
9238   bool UseStrictCompare =
9239       RealVType->hasUnsignedIntegerRepresentation() &&
9240       llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
9241         return LIS.IsStrictCompare;
9242       });
9243   // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
9244   // unsigned IV)) for worksharing loops.
9245   SourceLocation CondLoc = AStmt->getBeginLoc();
9246   Expr *BoundUB = UB.get();
9247   if (UseStrictCompare) {
9248     BoundUB =
9249         SemaRef
9250             .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
9251                         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9252             .get();
9253     BoundUB =
9254         SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
9255   }
9256   ExprResult Cond =
9257       (isOpenMPWorksharingDirective(DKind) ||
9258        isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind) ||
9259        isOpenMPLoopTransformationDirective(DKind))
9260           ? SemaRef.BuildBinOp(CurScope, CondLoc,
9261                                UseStrictCompare ? BO_LT : BO_LE, IV.get(),
9262                                BoundUB)
9263           : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
9264                                NumIterations.get());
9265   ExprResult CombDistCond;
9266   if (isOpenMPLoopBoundSharingDirective(DKind)) {
9267     CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
9268                                       NumIterations.get());
9269   }
9270 
9271   ExprResult CombCond;
9272   if (isOpenMPLoopBoundSharingDirective(DKind)) {
9273     Expr *BoundCombUB = CombUB.get();
9274     if (UseStrictCompare) {
9275       BoundCombUB =
9276           SemaRef
9277               .BuildBinOp(
9278                   CurScope, CondLoc, BO_Add, BoundCombUB,
9279                   SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9280               .get();
9281       BoundCombUB =
9282           SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
9283               .get();
9284     }
9285     CombCond =
9286         SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
9287                            IV.get(), BoundCombUB);
9288   }
9289   // Loop increment (IV = IV + 1)
9290   SourceLocation IncLoc = AStmt->getBeginLoc();
9291   ExprResult Inc =
9292       SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
9293                          SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
9294   if (!Inc.isUsable())
9295     return 0;
9296   Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
9297   Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
9298   if (!Inc.isUsable())
9299     return 0;
9300 
9301   // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
9302   // Used for directives with static scheduling.
9303   // In combined construct, add combined version that use CombLB and CombUB
9304   // base variables for the update
9305   ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
9306   if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
9307       isOpenMPDistributeDirective(DKind) ||
9308       isOpenMPLoopTransformationDirective(DKind)) {
9309     // LB + ST
9310     NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
9311     if (!NextLB.isUsable())
9312       return 0;
9313     // LB = LB + ST
9314     NextLB =
9315         SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
9316     NextLB =
9317         SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
9318     if (!NextLB.isUsable())
9319       return 0;
9320     // UB + ST
9321     NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
9322     if (!NextUB.isUsable())
9323       return 0;
9324     // UB = UB + ST
9325     NextUB =
9326         SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
9327     NextUB =
9328         SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
9329     if (!NextUB.isUsable())
9330       return 0;
9331     if (isOpenMPLoopBoundSharingDirective(DKind)) {
9332       CombNextLB =
9333           SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
9334       if (!NextLB.isUsable())
9335         return 0;
9336       // LB = LB + ST
9337       CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
9338                                       CombNextLB.get());
9339       CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
9340                                                /*DiscardedValue*/ false);
9341       if (!CombNextLB.isUsable())
9342         return 0;
9343       // UB + ST
9344       CombNextUB =
9345           SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
9346       if (!CombNextUB.isUsable())
9347         return 0;
9348       // UB = UB + ST
9349       CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
9350                                       CombNextUB.get());
9351       CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
9352                                                /*DiscardedValue*/ false);
9353       if (!CombNextUB.isUsable())
9354         return 0;
9355     }
9356   }
9357 
9358   // Create increment expression for distribute loop when combined in a same
9359   // directive with for as IV = IV + ST; ensure upper bound expression based
9360   // on PrevUB instead of NumIterations - used to implement 'for' when found
9361   // in combination with 'distribute', like in 'distribute parallel for'
9362   SourceLocation DistIncLoc = AStmt->getBeginLoc();
9363   ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
9364   if (isOpenMPLoopBoundSharingDirective(DKind)) {
9365     DistCond = SemaRef.BuildBinOp(
9366         CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
9367     assert(DistCond.isUsable() && "distribute cond expr was not built");
9368 
9369     DistInc =
9370         SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
9371     assert(DistInc.isUsable() && "distribute inc expr was not built");
9372     DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
9373                                  DistInc.get());
9374     DistInc =
9375         SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
9376     assert(DistInc.isUsable() && "distribute inc expr was not built");
9377 
9378     // Build expression: UB = min(UB, prevUB) for #for in composite or combined
9379     // construct
9380     SourceLocation DistEUBLoc = AStmt->getBeginLoc();
9381     ExprResult IsUBGreater =
9382         SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get());
9383     ExprResult CondOp = SemaRef.ActOnConditionalOp(
9384         DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get());
9385     PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
9386                                  CondOp.get());
9387     PrevEUB =
9388         SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
9389 
9390     // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
9391     // parallel for is in combination with a distribute directive with
9392     // schedule(static, 1)
9393     Expr *BoundPrevUB = PrevUB.get();
9394     if (UseStrictCompare) {
9395       BoundPrevUB =
9396           SemaRef
9397               .BuildBinOp(
9398                   CurScope, CondLoc, BO_Add, BoundPrevUB,
9399                   SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9400               .get();
9401       BoundPrevUB =
9402           SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
9403               .get();
9404     }
9405     ParForInDistCond =
9406         SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
9407                            IV.get(), BoundPrevUB);
9408   }
9409 
9410   // Build updates and final values of the loop counters.
9411   bool HasErrors = false;
9412   Built.Counters.resize(NestedLoopCount);
9413   Built.Inits.resize(NestedLoopCount);
9414   Built.Updates.resize(NestedLoopCount);
9415   Built.Finals.resize(NestedLoopCount);
9416   Built.DependentCounters.resize(NestedLoopCount);
9417   Built.DependentInits.resize(NestedLoopCount);
9418   Built.FinalsConditions.resize(NestedLoopCount);
9419   {
9420     // We implement the following algorithm for obtaining the
9421     // original loop iteration variable values based on the
9422     // value of the collapsed loop iteration variable IV.
9423     //
9424     // Let n+1 be the number of collapsed loops in the nest.
9425     // Iteration variables (I0, I1, .... In)
9426     // Iteration counts (N0, N1, ... Nn)
9427     //
9428     // Acc = IV;
9429     //
9430     // To compute Ik for loop k, 0 <= k <= n, generate:
9431     //    Prod = N(k+1) * N(k+2) * ... * Nn;
9432     //    Ik = Acc / Prod;
9433     //    Acc -= Ik * Prod;
9434     //
9435     ExprResult Acc = IV;
9436     for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
9437       LoopIterationSpace &IS = IterSpaces[Cnt];
9438       SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
9439       ExprResult Iter;
9440 
9441       // Compute prod
9442       ExprResult Prod =
9443           SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
9444       for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K)
9445         Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
9446                                   IterSpaces[K].NumIterations);
9447 
9448       // Iter = Acc / Prod
9449       // If there is at least one more inner loop to avoid
9450       // multiplication by 1.
9451       if (Cnt + 1 < NestedLoopCount)
9452         Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div,
9453                                   Acc.get(), Prod.get());
9454       else
9455         Iter = Acc;
9456       if (!Iter.isUsable()) {
9457         HasErrors = true;
9458         break;
9459       }
9460 
9461       // Update Acc:
9462       // Acc -= Iter * Prod
9463       // Check if there is at least one more inner loop to avoid
9464       // multiplication by 1.
9465       if (Cnt + 1 < NestedLoopCount)
9466         Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul,
9467                                   Iter.get(), Prod.get());
9468       else
9469         Prod = Iter;
9470       Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub,
9471                                Acc.get(), Prod.get());
9472 
9473       // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
9474       auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
9475       DeclRefExpr *CounterVar = buildDeclRefExpr(
9476           SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
9477           /*RefersToCapture=*/true);
9478       ExprResult Init =
9479           buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
9480                            IS.CounterInit, IS.IsNonRectangularLB, Captures);
9481       if (!Init.isUsable()) {
9482         HasErrors = true;
9483         break;
9484       }
9485       ExprResult Update = buildCounterUpdate(
9486           SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
9487           IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
9488       if (!Update.isUsable()) {
9489         HasErrors = true;
9490         break;
9491       }
9492 
9493       // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
9494       ExprResult Final =
9495           buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
9496                              IS.CounterInit, IS.NumIterations, IS.CounterStep,
9497                              IS.Subtract, IS.IsNonRectangularLB, &Captures);
9498       if (!Final.isUsable()) {
9499         HasErrors = true;
9500         break;
9501       }
9502 
9503       if (!Update.isUsable() || !Final.isUsable()) {
9504         HasErrors = true;
9505         break;
9506       }
9507       // Save results
9508       Built.Counters[Cnt] = IS.CounterVar;
9509       Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
9510       Built.Inits[Cnt] = Init.get();
9511       Built.Updates[Cnt] = Update.get();
9512       Built.Finals[Cnt] = Final.get();
9513       Built.DependentCounters[Cnt] = nullptr;
9514       Built.DependentInits[Cnt] = nullptr;
9515       Built.FinalsConditions[Cnt] = nullptr;
9516       if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
9517         Built.DependentCounters[Cnt] =
9518             Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx];
9519         Built.DependentInits[Cnt] =
9520             Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx];
9521         Built.FinalsConditions[Cnt] = IS.FinalCondition;
9522       }
9523     }
9524   }
9525 
9526   if (HasErrors)
9527     return 0;
9528 
9529   // Save results
9530   Built.IterationVarRef = IV.get();
9531   Built.LastIteration = LastIteration.get();
9532   Built.NumIterations = NumIterations.get();
9533   Built.CalcLastIteration = SemaRef
9534                                 .ActOnFinishFullExpr(CalcLastIteration.get(),
9535                                                      /*DiscardedValue=*/false)
9536                                 .get();
9537   Built.PreCond = PreCond.get();
9538   Built.PreInits = buildPreInits(C, Captures);
9539   Built.Cond = Cond.get();
9540   Built.Init = Init.get();
9541   Built.Inc = Inc.get();
9542   Built.LB = LB.get();
9543   Built.UB = UB.get();
9544   Built.IL = IL.get();
9545   Built.ST = ST.get();
9546   Built.EUB = EUB.get();
9547   Built.NLB = NextLB.get();
9548   Built.NUB = NextUB.get();
9549   Built.PrevLB = PrevLB.get();
9550   Built.PrevUB = PrevUB.get();
9551   Built.DistInc = DistInc.get();
9552   Built.PrevEUB = PrevEUB.get();
9553   Built.DistCombinedFields.LB = CombLB.get();
9554   Built.DistCombinedFields.UB = CombUB.get();
9555   Built.DistCombinedFields.EUB = CombEUB.get();
9556   Built.DistCombinedFields.Init = CombInit.get();
9557   Built.DistCombinedFields.Cond = CombCond.get();
9558   Built.DistCombinedFields.NLB = CombNextLB.get();
9559   Built.DistCombinedFields.NUB = CombNextUB.get();
9560   Built.DistCombinedFields.DistCond = CombDistCond.get();
9561   Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
9562 
9563   return NestedLoopCount;
9564 }
9565 
getCollapseNumberExpr(ArrayRef<OMPClause * > Clauses)9566 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
9567   auto CollapseClauses =
9568       OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
9569   if (CollapseClauses.begin() != CollapseClauses.end())
9570     return (*CollapseClauses.begin())->getNumForLoops();
9571   return nullptr;
9572 }
9573 
getOrderedNumberExpr(ArrayRef<OMPClause * > Clauses)9574 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
9575   auto OrderedClauses =
9576       OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
9577   if (OrderedClauses.begin() != OrderedClauses.end())
9578     return (*OrderedClauses.begin())->getNumForLoops();
9579   return nullptr;
9580 }
9581 
checkSimdlenSafelenSpecified(Sema & S,const ArrayRef<OMPClause * > Clauses)9582 static bool checkSimdlenSafelenSpecified(Sema &S,
9583                                          const ArrayRef<OMPClause *> Clauses) {
9584   const OMPSafelenClause *Safelen = nullptr;
9585   const OMPSimdlenClause *Simdlen = nullptr;
9586 
9587   for (const OMPClause *Clause : Clauses) {
9588     if (Clause->getClauseKind() == OMPC_safelen)
9589       Safelen = cast<OMPSafelenClause>(Clause);
9590     else if (Clause->getClauseKind() == OMPC_simdlen)
9591       Simdlen = cast<OMPSimdlenClause>(Clause);
9592     if (Safelen && Simdlen)
9593       break;
9594   }
9595 
9596   if (Simdlen && Safelen) {
9597     const Expr *SimdlenLength = Simdlen->getSimdlen();
9598     const Expr *SafelenLength = Safelen->getSafelen();
9599     if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
9600         SimdlenLength->isInstantiationDependent() ||
9601         SimdlenLength->containsUnexpandedParameterPack())
9602       return false;
9603     if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
9604         SafelenLength->isInstantiationDependent() ||
9605         SafelenLength->containsUnexpandedParameterPack())
9606       return false;
9607     Expr::EvalResult SimdlenResult, SafelenResult;
9608     SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
9609     SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
9610     llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
9611     llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
9612     // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
9613     // If both simdlen and safelen clauses are specified, the value of the
9614     // simdlen parameter must be less than or equal to the value of the safelen
9615     // parameter.
9616     if (SimdlenRes > SafelenRes) {
9617       S.Diag(SimdlenLength->getExprLoc(),
9618              diag::err_omp_wrong_simdlen_safelen_values)
9619           << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
9620       return true;
9621     }
9622   }
9623   return false;
9624 }
9625 
9626 StmtResult
ActOnOpenMPSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)9627 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
9628                                SourceLocation StartLoc, SourceLocation EndLoc,
9629                                VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9630   if (!AStmt)
9631     return StmtError();
9632 
9633   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9634   OMPLoopBasedDirective::HelperExprs B;
9635   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9636   // define the nested loops number.
9637   unsigned NestedLoopCount = checkOpenMPLoop(
9638       OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
9639       AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
9640   if (NestedLoopCount == 0)
9641     return StmtError();
9642 
9643   assert((CurContext->isDependentContext() || B.builtAll()) &&
9644          "omp simd loop exprs were not built");
9645 
9646   if (!CurContext->isDependentContext()) {
9647     // Finalize the clauses that need pre-built expressions for CodeGen.
9648     for (OMPClause *C : Clauses) {
9649       if (auto *LC = dyn_cast<OMPLinearClause>(C))
9650         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9651                                      B.NumIterations, *this, CurScope,
9652                                      DSAStack))
9653           return StmtError();
9654     }
9655   }
9656 
9657   if (checkSimdlenSafelenSpecified(*this, Clauses))
9658     return StmtError();
9659 
9660   setFunctionHasBranchProtectedScope();
9661   return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
9662                                   Clauses, AStmt, B);
9663 }
9664 
9665 StmtResult
ActOnOpenMPForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)9666 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
9667                               SourceLocation StartLoc, SourceLocation EndLoc,
9668                               VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9669   if (!AStmt)
9670     return StmtError();
9671 
9672   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9673   OMPLoopBasedDirective::HelperExprs B;
9674   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9675   // define the nested loops number.
9676   unsigned NestedLoopCount = checkOpenMPLoop(
9677       OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
9678       AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
9679   if (NestedLoopCount == 0)
9680     return StmtError();
9681 
9682   assert((CurContext->isDependentContext() || B.builtAll()) &&
9683          "omp for loop exprs were not built");
9684 
9685   if (!CurContext->isDependentContext()) {
9686     // Finalize the clauses that need pre-built expressions for CodeGen.
9687     for (OMPClause *C : Clauses) {
9688       if (auto *LC = dyn_cast<OMPLinearClause>(C))
9689         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9690                                      B.NumIterations, *this, CurScope,
9691                                      DSAStack))
9692           return StmtError();
9693     }
9694   }
9695 
9696   setFunctionHasBranchProtectedScope();
9697   return OMPForDirective::Create(
9698       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
9699       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
9700 }
9701 
ActOnOpenMPForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)9702 StmtResult Sema::ActOnOpenMPForSimdDirective(
9703     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9704     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9705   if (!AStmt)
9706     return StmtError();
9707 
9708   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9709   OMPLoopBasedDirective::HelperExprs B;
9710   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9711   // define the nested loops number.
9712   unsigned NestedLoopCount =
9713       checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
9714                       getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
9715                       VarsWithImplicitDSA, B);
9716   if (NestedLoopCount == 0)
9717     return StmtError();
9718 
9719   assert((CurContext->isDependentContext() || B.builtAll()) &&
9720          "omp for simd loop exprs were not built");
9721 
9722   if (!CurContext->isDependentContext()) {
9723     // Finalize the clauses that need pre-built expressions for CodeGen.
9724     for (OMPClause *C : Clauses) {
9725       if (auto *LC = dyn_cast<OMPLinearClause>(C))
9726         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9727                                      B.NumIterations, *this, CurScope,
9728                                      DSAStack))
9729           return StmtError();
9730     }
9731   }
9732 
9733   if (checkSimdlenSafelenSpecified(*this, Clauses))
9734     return StmtError();
9735 
9736   setFunctionHasBranchProtectedScope();
9737   return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
9738                                      Clauses, AStmt, B);
9739 }
9740 
ActOnOpenMPSectionsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9741 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
9742                                               Stmt *AStmt,
9743                                               SourceLocation StartLoc,
9744                                               SourceLocation EndLoc) {
9745   if (!AStmt)
9746     return StmtError();
9747 
9748   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9749   auto BaseStmt = AStmt;
9750   while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
9751     BaseStmt = CS->getCapturedStmt();
9752   if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
9753     auto S = C->children();
9754     if (S.begin() == S.end())
9755       return StmtError();
9756     // All associated statements must be '#pragma omp section' except for
9757     // the first one.
9758     for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
9759       if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
9760         if (SectionStmt)
9761           Diag(SectionStmt->getBeginLoc(),
9762                diag::err_omp_sections_substmt_not_section);
9763         return StmtError();
9764       }
9765       cast<OMPSectionDirective>(SectionStmt)
9766           ->setHasCancel(DSAStack->isCancelRegion());
9767     }
9768   } else {
9769     Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
9770     return StmtError();
9771   }
9772 
9773   setFunctionHasBranchProtectedScope();
9774 
9775   return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
9776                                       DSAStack->getTaskgroupReductionRef(),
9777                                       DSAStack->isCancelRegion());
9778 }
9779 
ActOnOpenMPSectionDirective(Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9780 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
9781                                              SourceLocation StartLoc,
9782                                              SourceLocation EndLoc) {
9783   if (!AStmt)
9784     return StmtError();
9785 
9786   setFunctionHasBranchProtectedScope();
9787   DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
9788 
9789   return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
9790                                      DSAStack->isCancelRegion());
9791 }
9792 
getDirectCallExpr(Expr * E)9793 static Expr *getDirectCallExpr(Expr *E) {
9794   E = E->IgnoreParenCasts()->IgnoreImplicit();
9795   if (auto *CE = dyn_cast<CallExpr>(E))
9796     if (CE->getDirectCallee())
9797       return E;
9798   return nullptr;
9799 }
9800 
ActOnOpenMPDispatchDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9801 StmtResult Sema::ActOnOpenMPDispatchDirective(ArrayRef<OMPClause *> Clauses,
9802                                               Stmt *AStmt,
9803                                               SourceLocation StartLoc,
9804                                               SourceLocation EndLoc) {
9805   if (!AStmt)
9806     return StmtError();
9807 
9808   Stmt *S = cast<CapturedStmt>(AStmt)->getCapturedStmt();
9809 
9810   // 5.1 OpenMP
9811   // expression-stmt : an expression statement with one of the following forms:
9812   //   expression = target-call ( [expression-list] );
9813   //   target-call ( [expression-list] );
9814 
9815   SourceLocation TargetCallLoc;
9816 
9817   if (!CurContext->isDependentContext()) {
9818     Expr *TargetCall = nullptr;
9819 
9820     auto *E = dyn_cast<Expr>(S);
9821     if (!E) {
9822       Diag(S->getBeginLoc(), diag::err_omp_dispatch_statement_call);
9823       return StmtError();
9824     }
9825 
9826     E = E->IgnoreParenCasts()->IgnoreImplicit();
9827 
9828     if (auto *BO = dyn_cast<BinaryOperator>(E)) {
9829       if (BO->getOpcode() == BO_Assign)
9830         TargetCall = getDirectCallExpr(BO->getRHS());
9831     } else {
9832       if (auto *COCE = dyn_cast<CXXOperatorCallExpr>(E))
9833         if (COCE->getOperator() == OO_Equal)
9834           TargetCall = getDirectCallExpr(COCE->getArg(1));
9835       if (!TargetCall)
9836         TargetCall = getDirectCallExpr(E);
9837     }
9838     if (!TargetCall) {
9839       Diag(E->getBeginLoc(), diag::err_omp_dispatch_statement_call);
9840       return StmtError();
9841     }
9842     TargetCallLoc = TargetCall->getExprLoc();
9843   }
9844 
9845   setFunctionHasBranchProtectedScope();
9846 
9847   return OMPDispatchDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
9848                                       TargetCallLoc);
9849 }
9850 
ActOnOpenMPSingleDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9851 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
9852                                             Stmt *AStmt,
9853                                             SourceLocation StartLoc,
9854                                             SourceLocation EndLoc) {
9855   if (!AStmt)
9856     return StmtError();
9857 
9858   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9859 
9860   setFunctionHasBranchProtectedScope();
9861 
9862   // OpenMP [2.7.3, single Construct, Restrictions]
9863   // The copyprivate clause must not be used with the nowait clause.
9864   const OMPClause *Nowait = nullptr;
9865   const OMPClause *Copyprivate = nullptr;
9866   for (const OMPClause *Clause : Clauses) {
9867     if (Clause->getClauseKind() == OMPC_nowait)
9868       Nowait = Clause;
9869     else if (Clause->getClauseKind() == OMPC_copyprivate)
9870       Copyprivate = Clause;
9871     if (Copyprivate && Nowait) {
9872       Diag(Copyprivate->getBeginLoc(),
9873            diag::err_omp_single_copyprivate_with_nowait);
9874       Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
9875       return StmtError();
9876     }
9877   }
9878 
9879   return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9880 }
9881 
ActOnOpenMPMasterDirective(Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9882 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
9883                                             SourceLocation StartLoc,
9884                                             SourceLocation EndLoc) {
9885   if (!AStmt)
9886     return StmtError();
9887 
9888   setFunctionHasBranchProtectedScope();
9889 
9890   return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
9891 }
9892 
ActOnOpenMPMaskedDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9893 StmtResult Sema::ActOnOpenMPMaskedDirective(ArrayRef<OMPClause *> Clauses,
9894                                             Stmt *AStmt,
9895                                             SourceLocation StartLoc,
9896                                             SourceLocation EndLoc) {
9897   if (!AStmt)
9898     return StmtError();
9899 
9900   setFunctionHasBranchProtectedScope();
9901 
9902   return OMPMaskedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9903 }
9904 
ActOnOpenMPCriticalDirective(const DeclarationNameInfo & DirName,ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9905 StmtResult Sema::ActOnOpenMPCriticalDirective(
9906     const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
9907     Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
9908   if (!AStmt)
9909     return StmtError();
9910 
9911   bool ErrorFound = false;
9912   llvm::APSInt Hint;
9913   SourceLocation HintLoc;
9914   bool DependentHint = false;
9915   for (const OMPClause *C : Clauses) {
9916     if (C->getClauseKind() == OMPC_hint) {
9917       if (!DirName.getName()) {
9918         Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
9919         ErrorFound = true;
9920       }
9921       Expr *E = cast<OMPHintClause>(C)->getHint();
9922       if (E->isTypeDependent() || E->isValueDependent() ||
9923           E->isInstantiationDependent()) {
9924         DependentHint = true;
9925       } else {
9926         Hint = E->EvaluateKnownConstInt(Context);
9927         HintLoc = C->getBeginLoc();
9928       }
9929     }
9930   }
9931   if (ErrorFound)
9932     return StmtError();
9933   const auto Pair = DSAStack->getCriticalWithHint(DirName);
9934   if (Pair.first && DirName.getName() && !DependentHint) {
9935     if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
9936       Diag(StartLoc, diag::err_omp_critical_with_hint);
9937       if (HintLoc.isValid())
9938         Diag(HintLoc, diag::note_omp_critical_hint_here)
9939             << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false);
9940       else
9941         Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
9942       if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
9943         Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
9944             << 1
9945             << C->getHint()->EvaluateKnownConstInt(Context).toString(
9946                    /*Radix=*/10, /*Signed=*/false);
9947       } else {
9948         Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
9949       }
9950     }
9951   }
9952 
9953   setFunctionHasBranchProtectedScope();
9954 
9955   auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
9956                                            Clauses, AStmt);
9957   if (!Pair.first && DirName.getName() && !DependentHint)
9958     DSAStack->addCriticalWithHint(Dir, Hint);
9959   return Dir;
9960 }
9961 
ActOnOpenMPParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)9962 StmtResult Sema::ActOnOpenMPParallelForDirective(
9963     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9964     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9965   if (!AStmt)
9966     return StmtError();
9967 
9968   auto *CS = cast<CapturedStmt>(AStmt);
9969   // 1.2.2 OpenMP Language Terminology
9970   // Structured block - An executable statement with a single entry at the
9971   // top and a single exit at the bottom.
9972   // The point of exit cannot be a branch out of the structured block.
9973   // longjmp() and throw() must not violate the entry/exit criteria.
9974   CS->getCapturedDecl()->setNothrow();
9975 
9976   OMPLoopBasedDirective::HelperExprs B;
9977   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9978   // define the nested loops number.
9979   unsigned NestedLoopCount =
9980       checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
9981                       getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
9982                       VarsWithImplicitDSA, B);
9983   if (NestedLoopCount == 0)
9984     return StmtError();
9985 
9986   assert((CurContext->isDependentContext() || B.builtAll()) &&
9987          "omp parallel for loop exprs were not built");
9988 
9989   if (!CurContext->isDependentContext()) {
9990     // Finalize the clauses that need pre-built expressions for CodeGen.
9991     for (OMPClause *C : Clauses) {
9992       if (auto *LC = dyn_cast<OMPLinearClause>(C))
9993         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9994                                      B.NumIterations, *this, CurScope,
9995                                      DSAStack))
9996           return StmtError();
9997     }
9998   }
9999 
10000   setFunctionHasBranchProtectedScope();
10001   return OMPParallelForDirective::Create(
10002       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10003       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10004 }
10005 
ActOnOpenMPParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10006 StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
10007     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10008     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10009   if (!AStmt)
10010     return StmtError();
10011 
10012   auto *CS = cast<CapturedStmt>(AStmt);
10013   // 1.2.2 OpenMP Language Terminology
10014   // Structured block - An executable statement with a single entry at the
10015   // top and a single exit at the bottom.
10016   // The point of exit cannot be a branch out of the structured block.
10017   // longjmp() and throw() must not violate the entry/exit criteria.
10018   CS->getCapturedDecl()->setNothrow();
10019 
10020   OMPLoopBasedDirective::HelperExprs B;
10021   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10022   // define the nested loops number.
10023   unsigned NestedLoopCount =
10024       checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
10025                       getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
10026                       VarsWithImplicitDSA, B);
10027   if (NestedLoopCount == 0)
10028     return StmtError();
10029 
10030   if (!CurContext->isDependentContext()) {
10031     // Finalize the clauses that need pre-built expressions for CodeGen.
10032     for (OMPClause *C : Clauses) {
10033       if (auto *LC = dyn_cast<OMPLinearClause>(C))
10034         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10035                                      B.NumIterations, *this, CurScope,
10036                                      DSAStack))
10037           return StmtError();
10038     }
10039   }
10040 
10041   if (checkSimdlenSafelenSpecified(*this, Clauses))
10042     return StmtError();
10043 
10044   setFunctionHasBranchProtectedScope();
10045   return OMPParallelForSimdDirective::Create(
10046       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10047 }
10048 
10049 StmtResult
ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10050 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses,
10051                                          Stmt *AStmt, SourceLocation StartLoc,
10052                                          SourceLocation EndLoc) {
10053   if (!AStmt)
10054     return StmtError();
10055 
10056   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10057   auto *CS = cast<CapturedStmt>(AStmt);
10058   // 1.2.2 OpenMP Language Terminology
10059   // Structured block - An executable statement with a single entry at the
10060   // top and a single exit at the bottom.
10061   // The point of exit cannot be a branch out of the structured block.
10062   // longjmp() and throw() must not violate the entry/exit criteria.
10063   CS->getCapturedDecl()->setNothrow();
10064 
10065   setFunctionHasBranchProtectedScope();
10066 
10067   return OMPParallelMasterDirective::Create(
10068       Context, StartLoc, EndLoc, Clauses, AStmt,
10069       DSAStack->getTaskgroupReductionRef());
10070 }
10071 
10072 StmtResult
ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10073 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
10074                                            Stmt *AStmt, SourceLocation StartLoc,
10075                                            SourceLocation EndLoc) {
10076   if (!AStmt)
10077     return StmtError();
10078 
10079   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10080   auto BaseStmt = AStmt;
10081   while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
10082     BaseStmt = CS->getCapturedStmt();
10083   if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
10084     auto S = C->children();
10085     if (S.begin() == S.end())
10086       return StmtError();
10087     // All associated statements must be '#pragma omp section' except for
10088     // the first one.
10089     for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
10090       if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
10091         if (SectionStmt)
10092           Diag(SectionStmt->getBeginLoc(),
10093                diag::err_omp_parallel_sections_substmt_not_section);
10094         return StmtError();
10095       }
10096       cast<OMPSectionDirective>(SectionStmt)
10097           ->setHasCancel(DSAStack->isCancelRegion());
10098     }
10099   } else {
10100     Diag(AStmt->getBeginLoc(),
10101          diag::err_omp_parallel_sections_not_compound_stmt);
10102     return StmtError();
10103   }
10104 
10105   setFunctionHasBranchProtectedScope();
10106 
10107   return OMPParallelSectionsDirective::Create(
10108       Context, StartLoc, EndLoc, Clauses, AStmt,
10109       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10110 }
10111 
10112 /// detach and mergeable clauses are mutially exclusive, check for it.
checkDetachMergeableClauses(Sema & S,ArrayRef<OMPClause * > Clauses)10113 static bool checkDetachMergeableClauses(Sema &S,
10114                                         ArrayRef<OMPClause *> Clauses) {
10115   const OMPClause *PrevClause = nullptr;
10116   bool ErrorFound = false;
10117   for (const OMPClause *C : Clauses) {
10118     if (C->getClauseKind() == OMPC_detach ||
10119         C->getClauseKind() == OMPC_mergeable) {
10120       if (!PrevClause) {
10121         PrevClause = C;
10122       } else if (PrevClause->getClauseKind() != C->getClauseKind()) {
10123         S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
10124             << getOpenMPClauseName(C->getClauseKind())
10125             << getOpenMPClauseName(PrevClause->getClauseKind());
10126         S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
10127             << getOpenMPClauseName(PrevClause->getClauseKind());
10128         ErrorFound = true;
10129       }
10130     }
10131   }
10132   return ErrorFound;
10133 }
10134 
ActOnOpenMPTaskDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10135 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
10136                                           Stmt *AStmt, SourceLocation StartLoc,
10137                                           SourceLocation EndLoc) {
10138   if (!AStmt)
10139     return StmtError();
10140 
10141   // OpenMP 5.0, 2.10.1 task Construct
10142   // If a detach clause appears on the directive, then a mergeable clause cannot
10143   // appear on the same directive.
10144   if (checkDetachMergeableClauses(*this, Clauses))
10145     return StmtError();
10146 
10147   auto *CS = cast<CapturedStmt>(AStmt);
10148   // 1.2.2 OpenMP Language Terminology
10149   // Structured block - An executable statement with a single entry at the
10150   // top and a single exit at the bottom.
10151   // The point of exit cannot be a branch out of the structured block.
10152   // longjmp() and throw() must not violate the entry/exit criteria.
10153   CS->getCapturedDecl()->setNothrow();
10154 
10155   setFunctionHasBranchProtectedScope();
10156 
10157   return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10158                                   DSAStack->isCancelRegion());
10159 }
10160 
ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,SourceLocation EndLoc)10161 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
10162                                                SourceLocation EndLoc) {
10163   return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
10164 }
10165 
ActOnOpenMPBarrierDirective(SourceLocation StartLoc,SourceLocation EndLoc)10166 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
10167                                              SourceLocation EndLoc) {
10168   return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
10169 }
10170 
ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,SourceLocation EndLoc)10171 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
10172                                               SourceLocation EndLoc) {
10173   return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
10174 }
10175 
ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10176 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
10177                                                Stmt *AStmt,
10178                                                SourceLocation StartLoc,
10179                                                SourceLocation EndLoc) {
10180   if (!AStmt)
10181     return StmtError();
10182 
10183   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10184 
10185   setFunctionHasBranchProtectedScope();
10186 
10187   return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
10188                                        AStmt,
10189                                        DSAStack->getTaskgroupReductionRef());
10190 }
10191 
ActOnOpenMPFlushDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)10192 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
10193                                            SourceLocation StartLoc,
10194                                            SourceLocation EndLoc) {
10195   OMPFlushClause *FC = nullptr;
10196   OMPClause *OrderClause = nullptr;
10197   for (OMPClause *C : Clauses) {
10198     if (C->getClauseKind() == OMPC_flush)
10199       FC = cast<OMPFlushClause>(C);
10200     else
10201       OrderClause = C;
10202   }
10203   OpenMPClauseKind MemOrderKind = OMPC_unknown;
10204   SourceLocation MemOrderLoc;
10205   for (const OMPClause *C : Clauses) {
10206     if (C->getClauseKind() == OMPC_acq_rel ||
10207         C->getClauseKind() == OMPC_acquire ||
10208         C->getClauseKind() == OMPC_release) {
10209       if (MemOrderKind != OMPC_unknown) {
10210         Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
10211             << getOpenMPDirectiveName(OMPD_flush) << 1
10212             << SourceRange(C->getBeginLoc(), C->getEndLoc());
10213         Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
10214             << getOpenMPClauseName(MemOrderKind);
10215       } else {
10216         MemOrderKind = C->getClauseKind();
10217         MemOrderLoc = C->getBeginLoc();
10218       }
10219     }
10220   }
10221   if (FC && OrderClause) {
10222     Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list)
10223         << getOpenMPClauseName(OrderClause->getClauseKind());
10224     Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here)
10225         << getOpenMPClauseName(OrderClause->getClauseKind());
10226     return StmtError();
10227   }
10228   return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
10229 }
10230 
ActOnOpenMPDepobjDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)10231 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses,
10232                                             SourceLocation StartLoc,
10233                                             SourceLocation EndLoc) {
10234   if (Clauses.empty()) {
10235     Diag(StartLoc, diag::err_omp_depobj_expected);
10236     return StmtError();
10237   } else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
10238     Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
10239     return StmtError();
10240   }
10241   // Only depobj expression and another single clause is allowed.
10242   if (Clauses.size() > 2) {
10243     Diag(Clauses[2]->getBeginLoc(),
10244          diag::err_omp_depobj_single_clause_expected);
10245     return StmtError();
10246   } else if (Clauses.size() < 1) {
10247     Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
10248     return StmtError();
10249   }
10250   return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses);
10251 }
10252 
ActOnOpenMPScanDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)10253 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses,
10254                                           SourceLocation StartLoc,
10255                                           SourceLocation EndLoc) {
10256   // Check that exactly one clause is specified.
10257   if (Clauses.size() != 1) {
10258     Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
10259          diag::err_omp_scan_single_clause_expected);
10260     return StmtError();
10261   }
10262   // Check that scan directive is used in the scopeof the OpenMP loop body.
10263   if (Scope *S = DSAStack->getCurScope()) {
10264     Scope *ParentS = S->getParent();
10265     if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() ||
10266         !ParentS->getBreakParent()->isOpenMPLoopScope())
10267       return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive)
10268                        << getOpenMPDirectiveName(OMPD_scan) << 5);
10269   }
10270   // Check that only one instance of scan directives is used in the same outer
10271   // region.
10272   if (DSAStack->doesParentHasScanDirective()) {
10273     Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan";
10274     Diag(DSAStack->getParentScanDirectiveLoc(),
10275          diag::note_omp_previous_directive)
10276         << "scan";
10277     return StmtError();
10278   }
10279   DSAStack->setParentHasScanDirective(StartLoc);
10280   return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses);
10281 }
10282 
ActOnOpenMPOrderedDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10283 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
10284                                              Stmt *AStmt,
10285                                              SourceLocation StartLoc,
10286                                              SourceLocation EndLoc) {
10287   const OMPClause *DependFound = nullptr;
10288   const OMPClause *DependSourceClause = nullptr;
10289   const OMPClause *DependSinkClause = nullptr;
10290   bool ErrorFound = false;
10291   const OMPThreadsClause *TC = nullptr;
10292   const OMPSIMDClause *SC = nullptr;
10293   for (const OMPClause *C : Clauses) {
10294     if (auto *DC = dyn_cast<OMPDependClause>(C)) {
10295       DependFound = C;
10296       if (DC->getDependencyKind() == OMPC_DEPEND_source) {
10297         if (DependSourceClause) {
10298           Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
10299               << getOpenMPDirectiveName(OMPD_ordered)
10300               << getOpenMPClauseName(OMPC_depend) << 2;
10301           ErrorFound = true;
10302         } else {
10303           DependSourceClause = C;
10304         }
10305         if (DependSinkClause) {
10306           Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
10307               << 0;
10308           ErrorFound = true;
10309         }
10310       } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
10311         if (DependSourceClause) {
10312           Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
10313               << 1;
10314           ErrorFound = true;
10315         }
10316         DependSinkClause = C;
10317       }
10318     } else if (C->getClauseKind() == OMPC_threads) {
10319       TC = cast<OMPThreadsClause>(C);
10320     } else if (C->getClauseKind() == OMPC_simd) {
10321       SC = cast<OMPSIMDClause>(C);
10322     }
10323   }
10324   if (!ErrorFound && !SC &&
10325       isOpenMPSimdDirective(DSAStack->getParentDirective())) {
10326     // OpenMP [2.8.1,simd Construct, Restrictions]
10327     // An ordered construct with the simd clause is the only OpenMP construct
10328     // that can appear in the simd region.
10329     Diag(StartLoc, diag::err_omp_prohibited_region_simd)
10330         << (LangOpts.OpenMP >= 50 ? 1 : 0);
10331     ErrorFound = true;
10332   } else if (DependFound && (TC || SC)) {
10333     Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
10334         << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
10335     ErrorFound = true;
10336   } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) {
10337     Diag(DependFound->getBeginLoc(),
10338          diag::err_omp_ordered_directive_without_param);
10339     ErrorFound = true;
10340   } else if (TC || Clauses.empty()) {
10341     if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) {
10342       SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
10343       Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
10344           << (TC != nullptr);
10345       Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1;
10346       ErrorFound = true;
10347     }
10348   }
10349   if ((!AStmt && !DependFound) || ErrorFound)
10350     return StmtError();
10351 
10352   // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions.
10353   // During execution of an iteration of a worksharing-loop or a loop nest
10354   // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread
10355   // must not execute more than one ordered region corresponding to an ordered
10356   // construct without a depend clause.
10357   if (!DependFound) {
10358     if (DSAStack->doesParentHasOrderedDirective()) {
10359       Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered";
10360       Diag(DSAStack->getParentOrderedDirectiveLoc(),
10361            diag::note_omp_previous_directive)
10362           << "ordered";
10363       return StmtError();
10364     }
10365     DSAStack->setParentHasOrderedDirective(StartLoc);
10366   }
10367 
10368   if (AStmt) {
10369     assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10370 
10371     setFunctionHasBranchProtectedScope();
10372   }
10373 
10374   return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10375 }
10376 
10377 namespace {
10378 /// Helper class for checking expression in 'omp atomic [update]'
10379 /// construct.
10380 class OpenMPAtomicUpdateChecker {
10381   /// Error results for atomic update expressions.
10382   enum ExprAnalysisErrorCode {
10383     /// A statement is not an expression statement.
10384     NotAnExpression,
10385     /// Expression is not builtin binary or unary operation.
10386     NotABinaryOrUnaryExpression,
10387     /// Unary operation is not post-/pre- increment/decrement operation.
10388     NotAnUnaryIncDecExpression,
10389     /// An expression is not of scalar type.
10390     NotAScalarType,
10391     /// A binary operation is not an assignment operation.
10392     NotAnAssignmentOp,
10393     /// RHS part of the binary operation is not a binary expression.
10394     NotABinaryExpression,
10395     /// RHS part is not additive/multiplicative/shift/biwise binary
10396     /// expression.
10397     NotABinaryOperator,
10398     /// RHS binary operation does not have reference to the updated LHS
10399     /// part.
10400     NotAnUpdateExpression,
10401     /// No errors is found.
10402     NoError
10403   };
10404   /// Reference to Sema.
10405   Sema &SemaRef;
10406   /// A location for note diagnostics (when error is found).
10407   SourceLocation NoteLoc;
10408   /// 'x' lvalue part of the source atomic expression.
10409   Expr *X;
10410   /// 'expr' rvalue part of the source atomic expression.
10411   Expr *E;
10412   /// Helper expression of the form
10413   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
10414   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
10415   Expr *UpdateExpr;
10416   /// Is 'x' a LHS in a RHS part of full update expression. It is
10417   /// important for non-associative operations.
10418   bool IsXLHSInRHSPart;
10419   BinaryOperatorKind Op;
10420   SourceLocation OpLoc;
10421   /// true if the source expression is a postfix unary operation, false
10422   /// if it is a prefix unary operation.
10423   bool IsPostfixUpdate;
10424 
10425 public:
OpenMPAtomicUpdateChecker(Sema & SemaRef)10426   OpenMPAtomicUpdateChecker(Sema &SemaRef)
10427       : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
10428         IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
10429   /// Check specified statement that it is suitable for 'atomic update'
10430   /// constructs and extract 'x', 'expr' and Operation from the original
10431   /// expression. If DiagId and NoteId == 0, then only check is performed
10432   /// without error notification.
10433   /// \param DiagId Diagnostic which should be emitted if error is found.
10434   /// \param NoteId Diagnostic note for the main error message.
10435   /// \return true if statement is not an update expression, false otherwise.
10436   bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
10437   /// Return the 'x' lvalue part of the source atomic expression.
getX() const10438   Expr *getX() const { return X; }
10439   /// Return the 'expr' rvalue part of the source atomic expression.
getExpr() const10440   Expr *getExpr() const { return E; }
10441   /// Return the update expression used in calculation of the updated
10442   /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
10443   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
getUpdateExpr() const10444   Expr *getUpdateExpr() const { return UpdateExpr; }
10445   /// Return true if 'x' is LHS in RHS part of full update expression,
10446   /// false otherwise.
isXLHSInRHSPart() const10447   bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
10448 
10449   /// true if the source expression is a postfix unary operation, false
10450   /// if it is a prefix unary operation.
isPostfixUpdate() const10451   bool isPostfixUpdate() const { return IsPostfixUpdate; }
10452 
10453 private:
10454   bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
10455                             unsigned NoteId = 0);
10456 };
10457 } // namespace
10458 
checkBinaryOperation(BinaryOperator * AtomicBinOp,unsigned DiagId,unsigned NoteId)10459 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
10460     BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
10461   ExprAnalysisErrorCode ErrorFound = NoError;
10462   SourceLocation ErrorLoc, NoteLoc;
10463   SourceRange ErrorRange, NoteRange;
10464   // Allowed constructs are:
10465   //  x = x binop expr;
10466   //  x = expr binop x;
10467   if (AtomicBinOp->getOpcode() == BO_Assign) {
10468     X = AtomicBinOp->getLHS();
10469     if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
10470             AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
10471       if (AtomicInnerBinOp->isMultiplicativeOp() ||
10472           AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
10473           AtomicInnerBinOp->isBitwiseOp()) {
10474         Op = AtomicInnerBinOp->getOpcode();
10475         OpLoc = AtomicInnerBinOp->getOperatorLoc();
10476         Expr *LHS = AtomicInnerBinOp->getLHS();
10477         Expr *RHS = AtomicInnerBinOp->getRHS();
10478         llvm::FoldingSetNodeID XId, LHSId, RHSId;
10479         X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
10480                                           /*Canonical=*/true);
10481         LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
10482                                             /*Canonical=*/true);
10483         RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
10484                                             /*Canonical=*/true);
10485         if (XId == LHSId) {
10486           E = RHS;
10487           IsXLHSInRHSPart = true;
10488         } else if (XId == RHSId) {
10489           E = LHS;
10490           IsXLHSInRHSPart = false;
10491         } else {
10492           ErrorLoc = AtomicInnerBinOp->getExprLoc();
10493           ErrorRange = AtomicInnerBinOp->getSourceRange();
10494           NoteLoc = X->getExprLoc();
10495           NoteRange = X->getSourceRange();
10496           ErrorFound = NotAnUpdateExpression;
10497         }
10498       } else {
10499         ErrorLoc = AtomicInnerBinOp->getExprLoc();
10500         ErrorRange = AtomicInnerBinOp->getSourceRange();
10501         NoteLoc = AtomicInnerBinOp->getOperatorLoc();
10502         NoteRange = SourceRange(NoteLoc, NoteLoc);
10503         ErrorFound = NotABinaryOperator;
10504       }
10505     } else {
10506       NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
10507       NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
10508       ErrorFound = NotABinaryExpression;
10509     }
10510   } else {
10511     ErrorLoc = AtomicBinOp->getExprLoc();
10512     ErrorRange = AtomicBinOp->getSourceRange();
10513     NoteLoc = AtomicBinOp->getOperatorLoc();
10514     NoteRange = SourceRange(NoteLoc, NoteLoc);
10515     ErrorFound = NotAnAssignmentOp;
10516   }
10517   if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
10518     SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
10519     SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
10520     return true;
10521   }
10522   if (SemaRef.CurContext->isDependentContext())
10523     E = X = UpdateExpr = nullptr;
10524   return ErrorFound != NoError;
10525 }
10526 
checkStatement(Stmt * S,unsigned DiagId,unsigned NoteId)10527 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
10528                                                unsigned NoteId) {
10529   ExprAnalysisErrorCode ErrorFound = NoError;
10530   SourceLocation ErrorLoc, NoteLoc;
10531   SourceRange ErrorRange, NoteRange;
10532   // Allowed constructs are:
10533   //  x++;
10534   //  x--;
10535   //  ++x;
10536   //  --x;
10537   //  x binop= expr;
10538   //  x = x binop expr;
10539   //  x = expr binop x;
10540   if (auto *AtomicBody = dyn_cast<Expr>(S)) {
10541     AtomicBody = AtomicBody->IgnoreParenImpCasts();
10542     if (AtomicBody->getType()->isScalarType() ||
10543         AtomicBody->isInstantiationDependent()) {
10544       if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
10545               AtomicBody->IgnoreParenImpCasts())) {
10546         // Check for Compound Assignment Operation
10547         Op = BinaryOperator::getOpForCompoundAssignment(
10548             AtomicCompAssignOp->getOpcode());
10549         OpLoc = AtomicCompAssignOp->getOperatorLoc();
10550         E = AtomicCompAssignOp->getRHS();
10551         X = AtomicCompAssignOp->getLHS()->IgnoreParens();
10552         IsXLHSInRHSPart = true;
10553       } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
10554                      AtomicBody->IgnoreParenImpCasts())) {
10555         // Check for Binary Operation
10556         if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
10557           return true;
10558       } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
10559                      AtomicBody->IgnoreParenImpCasts())) {
10560         // Check for Unary Operation
10561         if (AtomicUnaryOp->isIncrementDecrementOp()) {
10562           IsPostfixUpdate = AtomicUnaryOp->isPostfix();
10563           Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
10564           OpLoc = AtomicUnaryOp->getOperatorLoc();
10565           X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
10566           E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
10567           IsXLHSInRHSPart = true;
10568         } else {
10569           ErrorFound = NotAnUnaryIncDecExpression;
10570           ErrorLoc = AtomicUnaryOp->getExprLoc();
10571           ErrorRange = AtomicUnaryOp->getSourceRange();
10572           NoteLoc = AtomicUnaryOp->getOperatorLoc();
10573           NoteRange = SourceRange(NoteLoc, NoteLoc);
10574         }
10575       } else if (!AtomicBody->isInstantiationDependent()) {
10576         ErrorFound = NotABinaryOrUnaryExpression;
10577         NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
10578         NoteRange = ErrorRange = AtomicBody->getSourceRange();
10579       }
10580     } else {
10581       ErrorFound = NotAScalarType;
10582       NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
10583       NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10584     }
10585   } else {
10586     ErrorFound = NotAnExpression;
10587     NoteLoc = ErrorLoc = S->getBeginLoc();
10588     NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10589   }
10590   if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
10591     SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
10592     SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
10593     return true;
10594   }
10595   if (SemaRef.CurContext->isDependentContext())
10596     E = X = UpdateExpr = nullptr;
10597   if (ErrorFound == NoError && E && X) {
10598     // Build an update expression of form 'OpaqueValueExpr(x) binop
10599     // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
10600     // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
10601     auto *OVEX = new (SemaRef.getASTContext())
10602         OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue);
10603     auto *OVEExpr = new (SemaRef.getASTContext())
10604         OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue);
10605     ExprResult Update =
10606         SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
10607                                    IsXLHSInRHSPart ? OVEExpr : OVEX);
10608     if (Update.isInvalid())
10609       return true;
10610     Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
10611                                                Sema::AA_Casting);
10612     if (Update.isInvalid())
10613       return true;
10614     UpdateExpr = Update.get();
10615   }
10616   return ErrorFound != NoError;
10617 }
10618 
ActOnOpenMPAtomicDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10619 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
10620                                             Stmt *AStmt,
10621                                             SourceLocation StartLoc,
10622                                             SourceLocation EndLoc) {
10623   // Register location of the first atomic directive.
10624   DSAStack->addAtomicDirectiveLoc(StartLoc);
10625   if (!AStmt)
10626     return StmtError();
10627 
10628   // 1.2.2 OpenMP Language Terminology
10629   // Structured block - An executable statement with a single entry at the
10630   // top and a single exit at the bottom.
10631   // The point of exit cannot be a branch out of the structured block.
10632   // longjmp() and throw() must not violate the entry/exit criteria.
10633   OpenMPClauseKind AtomicKind = OMPC_unknown;
10634   SourceLocation AtomicKindLoc;
10635   OpenMPClauseKind MemOrderKind = OMPC_unknown;
10636   SourceLocation MemOrderLoc;
10637   for (const OMPClause *C : Clauses) {
10638     if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
10639         C->getClauseKind() == OMPC_update ||
10640         C->getClauseKind() == OMPC_capture) {
10641       if (AtomicKind != OMPC_unknown) {
10642         Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
10643             << SourceRange(C->getBeginLoc(), C->getEndLoc());
10644         Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
10645             << getOpenMPClauseName(AtomicKind);
10646       } else {
10647         AtomicKind = C->getClauseKind();
10648         AtomicKindLoc = C->getBeginLoc();
10649       }
10650     }
10651     if (C->getClauseKind() == OMPC_seq_cst ||
10652         C->getClauseKind() == OMPC_acq_rel ||
10653         C->getClauseKind() == OMPC_acquire ||
10654         C->getClauseKind() == OMPC_release ||
10655         C->getClauseKind() == OMPC_relaxed) {
10656       if (MemOrderKind != OMPC_unknown) {
10657         Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
10658             << getOpenMPDirectiveName(OMPD_atomic) << 0
10659             << SourceRange(C->getBeginLoc(), C->getEndLoc());
10660         Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
10661             << getOpenMPClauseName(MemOrderKind);
10662       } else {
10663         MemOrderKind = C->getClauseKind();
10664         MemOrderLoc = C->getBeginLoc();
10665       }
10666     }
10667   }
10668   // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions
10669   // If atomic-clause is read then memory-order-clause must not be acq_rel or
10670   // release.
10671   // If atomic-clause is write then memory-order-clause must not be acq_rel or
10672   // acquire.
10673   // If atomic-clause is update or not present then memory-order-clause must not
10674   // be acq_rel or acquire.
10675   if ((AtomicKind == OMPC_read &&
10676        (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) ||
10677       ((AtomicKind == OMPC_write || AtomicKind == OMPC_update ||
10678         AtomicKind == OMPC_unknown) &&
10679        (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) {
10680     SourceLocation Loc = AtomicKindLoc;
10681     if (AtomicKind == OMPC_unknown)
10682       Loc = StartLoc;
10683     Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
10684         << getOpenMPClauseName(AtomicKind)
10685         << (AtomicKind == OMPC_unknown ? 1 : 0)
10686         << getOpenMPClauseName(MemOrderKind);
10687     Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
10688         << getOpenMPClauseName(MemOrderKind);
10689   }
10690 
10691   Stmt *Body = AStmt;
10692   if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
10693     Body = EWC->getSubExpr();
10694 
10695   Expr *X = nullptr;
10696   Expr *V = nullptr;
10697   Expr *E = nullptr;
10698   Expr *UE = nullptr;
10699   bool IsXLHSInRHSPart = false;
10700   bool IsPostfixUpdate = false;
10701   // OpenMP [2.12.6, atomic Construct]
10702   // In the next expressions:
10703   // * x and v (as applicable) are both l-value expressions with scalar type.
10704   // * During the execution of an atomic region, multiple syntactic
10705   // occurrences of x must designate the same storage location.
10706   // * Neither of v and expr (as applicable) may access the storage location
10707   // designated by x.
10708   // * Neither of x and expr (as applicable) may access the storage location
10709   // designated by v.
10710   // * expr is an expression with scalar type.
10711   // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
10712   // * binop, binop=, ++, and -- are not overloaded operators.
10713   // * The expression x binop expr must be numerically equivalent to x binop
10714   // (expr). This requirement is satisfied if the operators in expr have
10715   // precedence greater than binop, or by using parentheses around expr or
10716   // subexpressions of expr.
10717   // * The expression expr binop x must be numerically equivalent to (expr)
10718   // binop x. This requirement is satisfied if the operators in expr have
10719   // precedence equal to or greater than binop, or by using parentheses around
10720   // expr or subexpressions of expr.
10721   // * For forms that allow multiple occurrences of x, the number of times
10722   // that x is evaluated is unspecified.
10723   if (AtomicKind == OMPC_read) {
10724     enum {
10725       NotAnExpression,
10726       NotAnAssignmentOp,
10727       NotAScalarType,
10728       NotAnLValue,
10729       NoError
10730     } ErrorFound = NoError;
10731     SourceLocation ErrorLoc, NoteLoc;
10732     SourceRange ErrorRange, NoteRange;
10733     // If clause is read:
10734     //  v = x;
10735     if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10736       const auto *AtomicBinOp =
10737           dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10738       if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10739         X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
10740         V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
10741         if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
10742             (V->isInstantiationDependent() || V->getType()->isScalarType())) {
10743           if (!X->isLValue() || !V->isLValue()) {
10744             const Expr *NotLValueExpr = X->isLValue() ? V : X;
10745             ErrorFound = NotAnLValue;
10746             ErrorLoc = AtomicBinOp->getExprLoc();
10747             ErrorRange = AtomicBinOp->getSourceRange();
10748             NoteLoc = NotLValueExpr->getExprLoc();
10749             NoteRange = NotLValueExpr->getSourceRange();
10750           }
10751         } else if (!X->isInstantiationDependent() ||
10752                    !V->isInstantiationDependent()) {
10753           const Expr *NotScalarExpr =
10754               (X->isInstantiationDependent() || X->getType()->isScalarType())
10755                   ? V
10756                   : X;
10757           ErrorFound = NotAScalarType;
10758           ErrorLoc = AtomicBinOp->getExprLoc();
10759           ErrorRange = AtomicBinOp->getSourceRange();
10760           NoteLoc = NotScalarExpr->getExprLoc();
10761           NoteRange = NotScalarExpr->getSourceRange();
10762         }
10763       } else if (!AtomicBody->isInstantiationDependent()) {
10764         ErrorFound = NotAnAssignmentOp;
10765         ErrorLoc = AtomicBody->getExprLoc();
10766         ErrorRange = AtomicBody->getSourceRange();
10767         NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10768                               : AtomicBody->getExprLoc();
10769         NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10770                                 : AtomicBody->getSourceRange();
10771       }
10772     } else {
10773       ErrorFound = NotAnExpression;
10774       NoteLoc = ErrorLoc = Body->getBeginLoc();
10775       NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10776     }
10777     if (ErrorFound != NoError) {
10778       Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
10779           << ErrorRange;
10780       Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
10781                                                       << NoteRange;
10782       return StmtError();
10783     }
10784     if (CurContext->isDependentContext())
10785       V = X = nullptr;
10786   } else if (AtomicKind == OMPC_write) {
10787     enum {
10788       NotAnExpression,
10789       NotAnAssignmentOp,
10790       NotAScalarType,
10791       NotAnLValue,
10792       NoError
10793     } ErrorFound = NoError;
10794     SourceLocation ErrorLoc, NoteLoc;
10795     SourceRange ErrorRange, NoteRange;
10796     // If clause is write:
10797     //  x = expr;
10798     if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10799       const auto *AtomicBinOp =
10800           dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10801       if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10802         X = AtomicBinOp->getLHS();
10803         E = AtomicBinOp->getRHS();
10804         if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
10805             (E->isInstantiationDependent() || E->getType()->isScalarType())) {
10806           if (!X->isLValue()) {
10807             ErrorFound = NotAnLValue;
10808             ErrorLoc = AtomicBinOp->getExprLoc();
10809             ErrorRange = AtomicBinOp->getSourceRange();
10810             NoteLoc = X->getExprLoc();
10811             NoteRange = X->getSourceRange();
10812           }
10813         } else if (!X->isInstantiationDependent() ||
10814                    !E->isInstantiationDependent()) {
10815           const Expr *NotScalarExpr =
10816               (X->isInstantiationDependent() || X->getType()->isScalarType())
10817                   ? E
10818                   : X;
10819           ErrorFound = NotAScalarType;
10820           ErrorLoc = AtomicBinOp->getExprLoc();
10821           ErrorRange = AtomicBinOp->getSourceRange();
10822           NoteLoc = NotScalarExpr->getExprLoc();
10823           NoteRange = NotScalarExpr->getSourceRange();
10824         }
10825       } else if (!AtomicBody->isInstantiationDependent()) {
10826         ErrorFound = NotAnAssignmentOp;
10827         ErrorLoc = AtomicBody->getExprLoc();
10828         ErrorRange = AtomicBody->getSourceRange();
10829         NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10830                               : AtomicBody->getExprLoc();
10831         NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10832                                 : AtomicBody->getSourceRange();
10833       }
10834     } else {
10835       ErrorFound = NotAnExpression;
10836       NoteLoc = ErrorLoc = Body->getBeginLoc();
10837       NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10838     }
10839     if (ErrorFound != NoError) {
10840       Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
10841           << ErrorRange;
10842       Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
10843                                                       << NoteRange;
10844       return StmtError();
10845     }
10846     if (CurContext->isDependentContext())
10847       E = X = nullptr;
10848   } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
10849     // If clause is update:
10850     //  x++;
10851     //  x--;
10852     //  ++x;
10853     //  --x;
10854     //  x binop= expr;
10855     //  x = x binop expr;
10856     //  x = expr binop x;
10857     OpenMPAtomicUpdateChecker Checker(*this);
10858     if (Checker.checkStatement(
10859             Body, (AtomicKind == OMPC_update)
10860                       ? diag::err_omp_atomic_update_not_expression_statement
10861                       : diag::err_omp_atomic_not_expression_statement,
10862             diag::note_omp_atomic_update))
10863       return StmtError();
10864     if (!CurContext->isDependentContext()) {
10865       E = Checker.getExpr();
10866       X = Checker.getX();
10867       UE = Checker.getUpdateExpr();
10868       IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10869     }
10870   } else if (AtomicKind == OMPC_capture) {
10871     enum {
10872       NotAnAssignmentOp,
10873       NotACompoundStatement,
10874       NotTwoSubstatements,
10875       NotASpecificExpression,
10876       NoError
10877     } ErrorFound = NoError;
10878     SourceLocation ErrorLoc, NoteLoc;
10879     SourceRange ErrorRange, NoteRange;
10880     if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10881       // If clause is a capture:
10882       //  v = x++;
10883       //  v = x--;
10884       //  v = ++x;
10885       //  v = --x;
10886       //  v = x binop= expr;
10887       //  v = x = x binop expr;
10888       //  v = x = expr binop x;
10889       const auto *AtomicBinOp =
10890           dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10891       if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10892         V = AtomicBinOp->getLHS();
10893         Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
10894         OpenMPAtomicUpdateChecker Checker(*this);
10895         if (Checker.checkStatement(
10896                 Body, diag::err_omp_atomic_capture_not_expression_statement,
10897                 diag::note_omp_atomic_update))
10898           return StmtError();
10899         E = Checker.getExpr();
10900         X = Checker.getX();
10901         UE = Checker.getUpdateExpr();
10902         IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10903         IsPostfixUpdate = Checker.isPostfixUpdate();
10904       } else if (!AtomicBody->isInstantiationDependent()) {
10905         ErrorLoc = AtomicBody->getExprLoc();
10906         ErrorRange = AtomicBody->getSourceRange();
10907         NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10908                               : AtomicBody->getExprLoc();
10909         NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10910                                 : AtomicBody->getSourceRange();
10911         ErrorFound = NotAnAssignmentOp;
10912       }
10913       if (ErrorFound != NoError) {
10914         Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
10915             << ErrorRange;
10916         Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
10917         return StmtError();
10918       }
10919       if (CurContext->isDependentContext())
10920         UE = V = E = X = nullptr;
10921     } else {
10922       // If clause is a capture:
10923       //  { v = x; x = expr; }
10924       //  { v = x; x++; }
10925       //  { v = x; x--; }
10926       //  { v = x; ++x; }
10927       //  { v = x; --x; }
10928       //  { v = x; x binop= expr; }
10929       //  { v = x; x = x binop expr; }
10930       //  { v = x; x = expr binop x; }
10931       //  { x++; v = x; }
10932       //  { x--; v = x; }
10933       //  { ++x; v = x; }
10934       //  { --x; v = x; }
10935       //  { x binop= expr; v = x; }
10936       //  { x = x binop expr; v = x; }
10937       //  { x = expr binop x; v = x; }
10938       if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
10939         // Check that this is { expr1; expr2; }
10940         if (CS->size() == 2) {
10941           Stmt *First = CS->body_front();
10942           Stmt *Second = CS->body_back();
10943           if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
10944             First = EWC->getSubExpr()->IgnoreParenImpCasts();
10945           if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
10946             Second = EWC->getSubExpr()->IgnoreParenImpCasts();
10947           // Need to find what subexpression is 'v' and what is 'x'.
10948           OpenMPAtomicUpdateChecker Checker(*this);
10949           bool IsUpdateExprFound = !Checker.checkStatement(Second);
10950           BinaryOperator *BinOp = nullptr;
10951           if (IsUpdateExprFound) {
10952             BinOp = dyn_cast<BinaryOperator>(First);
10953             IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
10954           }
10955           if (IsUpdateExprFound && !CurContext->isDependentContext()) {
10956             //  { v = x; x++; }
10957             //  { v = x; x--; }
10958             //  { v = x; ++x; }
10959             //  { v = x; --x; }
10960             //  { v = x; x binop= expr; }
10961             //  { v = x; x = x binop expr; }
10962             //  { v = x; x = expr binop x; }
10963             // Check that the first expression has form v = x.
10964             Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
10965             llvm::FoldingSetNodeID XId, PossibleXId;
10966             Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
10967             PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
10968             IsUpdateExprFound = XId == PossibleXId;
10969             if (IsUpdateExprFound) {
10970               V = BinOp->getLHS();
10971               X = Checker.getX();
10972               E = Checker.getExpr();
10973               UE = Checker.getUpdateExpr();
10974               IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10975               IsPostfixUpdate = true;
10976             }
10977           }
10978           if (!IsUpdateExprFound) {
10979             IsUpdateExprFound = !Checker.checkStatement(First);
10980             BinOp = nullptr;
10981             if (IsUpdateExprFound) {
10982               BinOp = dyn_cast<BinaryOperator>(Second);
10983               IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
10984             }
10985             if (IsUpdateExprFound && !CurContext->isDependentContext()) {
10986               //  { x++; v = x; }
10987               //  { x--; v = x; }
10988               //  { ++x; v = x; }
10989               //  { --x; v = x; }
10990               //  { x binop= expr; v = x; }
10991               //  { x = x binop expr; v = x; }
10992               //  { x = expr binop x; v = x; }
10993               // Check that the second expression has form v = x.
10994               Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
10995               llvm::FoldingSetNodeID XId, PossibleXId;
10996               Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
10997               PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
10998               IsUpdateExprFound = XId == PossibleXId;
10999               if (IsUpdateExprFound) {
11000                 V = BinOp->getLHS();
11001                 X = Checker.getX();
11002                 E = Checker.getExpr();
11003                 UE = Checker.getUpdateExpr();
11004                 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
11005                 IsPostfixUpdate = false;
11006               }
11007             }
11008           }
11009           if (!IsUpdateExprFound) {
11010             //  { v = x; x = expr; }
11011             auto *FirstExpr = dyn_cast<Expr>(First);
11012             auto *SecondExpr = dyn_cast<Expr>(Second);
11013             if (!FirstExpr || !SecondExpr ||
11014                 !(FirstExpr->isInstantiationDependent() ||
11015                   SecondExpr->isInstantiationDependent())) {
11016               auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
11017               if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
11018                 ErrorFound = NotAnAssignmentOp;
11019                 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
11020                                                 : First->getBeginLoc();
11021                 NoteRange = ErrorRange = FirstBinOp
11022                                              ? FirstBinOp->getSourceRange()
11023                                              : SourceRange(ErrorLoc, ErrorLoc);
11024               } else {
11025                 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
11026                 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
11027                   ErrorFound = NotAnAssignmentOp;
11028                   NoteLoc = ErrorLoc = SecondBinOp
11029                                            ? SecondBinOp->getOperatorLoc()
11030                                            : Second->getBeginLoc();
11031                   NoteRange = ErrorRange =
11032                       SecondBinOp ? SecondBinOp->getSourceRange()
11033                                   : SourceRange(ErrorLoc, ErrorLoc);
11034                 } else {
11035                   Expr *PossibleXRHSInFirst =
11036                       FirstBinOp->getRHS()->IgnoreParenImpCasts();
11037                   Expr *PossibleXLHSInSecond =
11038                       SecondBinOp->getLHS()->IgnoreParenImpCasts();
11039                   llvm::FoldingSetNodeID X1Id, X2Id;
11040                   PossibleXRHSInFirst->Profile(X1Id, Context,
11041                                                /*Canonical=*/true);
11042                   PossibleXLHSInSecond->Profile(X2Id, Context,
11043                                                 /*Canonical=*/true);
11044                   IsUpdateExprFound = X1Id == X2Id;
11045                   if (IsUpdateExprFound) {
11046                     V = FirstBinOp->getLHS();
11047                     X = SecondBinOp->getLHS();
11048                     E = SecondBinOp->getRHS();
11049                     UE = nullptr;
11050                     IsXLHSInRHSPart = false;
11051                     IsPostfixUpdate = true;
11052                   } else {
11053                     ErrorFound = NotASpecificExpression;
11054                     ErrorLoc = FirstBinOp->getExprLoc();
11055                     ErrorRange = FirstBinOp->getSourceRange();
11056                     NoteLoc = SecondBinOp->getLHS()->getExprLoc();
11057                     NoteRange = SecondBinOp->getRHS()->getSourceRange();
11058                   }
11059                 }
11060               }
11061             }
11062           }
11063         } else {
11064           NoteLoc = ErrorLoc = Body->getBeginLoc();
11065           NoteRange = ErrorRange =
11066               SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
11067           ErrorFound = NotTwoSubstatements;
11068         }
11069       } else {
11070         NoteLoc = ErrorLoc = Body->getBeginLoc();
11071         NoteRange = ErrorRange =
11072             SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
11073         ErrorFound = NotACompoundStatement;
11074       }
11075       if (ErrorFound != NoError) {
11076         Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
11077             << ErrorRange;
11078         Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
11079         return StmtError();
11080       }
11081       if (CurContext->isDependentContext())
11082         UE = V = E = X = nullptr;
11083     }
11084   }
11085 
11086   setFunctionHasBranchProtectedScope();
11087 
11088   return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
11089                                     X, V, E, UE, IsXLHSInRHSPart,
11090                                     IsPostfixUpdate);
11091 }
11092 
ActOnOpenMPTargetDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)11093 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
11094                                             Stmt *AStmt,
11095                                             SourceLocation StartLoc,
11096                                             SourceLocation EndLoc) {
11097   if (!AStmt)
11098     return StmtError();
11099 
11100   auto *CS = cast<CapturedStmt>(AStmt);
11101   // 1.2.2 OpenMP Language Terminology
11102   // Structured block - An executable statement with a single entry at the
11103   // top and a single exit at the bottom.
11104   // The point of exit cannot be a branch out of the structured block.
11105   // longjmp() and throw() must not violate the entry/exit criteria.
11106   CS->getCapturedDecl()->setNothrow();
11107   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
11108        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11109     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11110     // 1.2.2 OpenMP Language Terminology
11111     // Structured block - An executable statement with a single entry at the
11112     // top and a single exit at the bottom.
11113     // The point of exit cannot be a branch out of the structured block.
11114     // longjmp() and throw() must not violate the entry/exit criteria.
11115     CS->getCapturedDecl()->setNothrow();
11116   }
11117 
11118   // OpenMP [2.16, Nesting of Regions]
11119   // If specified, a teams construct must be contained within a target
11120   // construct. That target construct must contain no statements or directives
11121   // outside of the teams construct.
11122   if (DSAStack->hasInnerTeamsRegion()) {
11123     const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
11124     bool OMPTeamsFound = true;
11125     if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
11126       auto I = CS->body_begin();
11127       while (I != CS->body_end()) {
11128         const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
11129         if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) ||
11130             OMPTeamsFound) {
11131 
11132           OMPTeamsFound = false;
11133           break;
11134         }
11135         ++I;
11136       }
11137       assert(I != CS->body_end() && "Not found statement");
11138       S = *I;
11139     } else {
11140       const auto *OED = dyn_cast<OMPExecutableDirective>(S);
11141       OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
11142     }
11143     if (!OMPTeamsFound) {
11144       Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
11145       Diag(DSAStack->getInnerTeamsRegionLoc(),
11146            diag::note_omp_nested_teams_construct_here);
11147       Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
11148           << isa<OMPExecutableDirective>(S);
11149       return StmtError();
11150     }
11151   }
11152 
11153   setFunctionHasBranchProtectedScope();
11154 
11155   return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
11156 }
11157 
11158 StmtResult
ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)11159 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
11160                                          Stmt *AStmt, SourceLocation StartLoc,
11161                                          SourceLocation EndLoc) {
11162   if (!AStmt)
11163     return StmtError();
11164 
11165   auto *CS = cast<CapturedStmt>(AStmt);
11166   // 1.2.2 OpenMP Language Terminology
11167   // Structured block - An executable statement with a single entry at the
11168   // top and a single exit at the bottom.
11169   // The point of exit cannot be a branch out of the structured block.
11170   // longjmp() and throw() must not violate the entry/exit criteria.
11171   CS->getCapturedDecl()->setNothrow();
11172   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
11173        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11174     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11175     // 1.2.2 OpenMP Language Terminology
11176     // Structured block - An executable statement with a single entry at the
11177     // top and a single exit at the bottom.
11178     // The point of exit cannot be a branch out of the structured block.
11179     // longjmp() and throw() must not violate the entry/exit criteria.
11180     CS->getCapturedDecl()->setNothrow();
11181   }
11182 
11183   setFunctionHasBranchProtectedScope();
11184 
11185   return OMPTargetParallelDirective::Create(
11186       Context, StartLoc, EndLoc, Clauses, AStmt,
11187       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11188 }
11189 
ActOnOpenMPTargetParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11190 StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
11191     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11192     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11193   if (!AStmt)
11194     return StmtError();
11195 
11196   auto *CS = cast<CapturedStmt>(AStmt);
11197   // 1.2.2 OpenMP Language Terminology
11198   // Structured block - An executable statement with a single entry at the
11199   // top and a single exit at the bottom.
11200   // The point of exit cannot be a branch out of the structured block.
11201   // longjmp() and throw() must not violate the entry/exit criteria.
11202   CS->getCapturedDecl()->setNothrow();
11203   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
11204        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11205     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11206     // 1.2.2 OpenMP Language Terminology
11207     // Structured block - An executable statement with a single entry at the
11208     // top and a single exit at the bottom.
11209     // The point of exit cannot be a branch out of the structured block.
11210     // longjmp() and throw() must not violate the entry/exit criteria.
11211     CS->getCapturedDecl()->setNothrow();
11212   }
11213 
11214   OMPLoopBasedDirective::HelperExprs B;
11215   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11216   // define the nested loops number.
11217   unsigned NestedLoopCount =
11218       checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
11219                       getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
11220                       VarsWithImplicitDSA, B);
11221   if (NestedLoopCount == 0)
11222     return StmtError();
11223 
11224   assert((CurContext->isDependentContext() || B.builtAll()) &&
11225          "omp target parallel for loop exprs were not built");
11226 
11227   if (!CurContext->isDependentContext()) {
11228     // Finalize the clauses that need pre-built expressions for CodeGen.
11229     for (OMPClause *C : Clauses) {
11230       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11231         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11232                                      B.NumIterations, *this, CurScope,
11233                                      DSAStack))
11234           return StmtError();
11235     }
11236   }
11237 
11238   setFunctionHasBranchProtectedScope();
11239   return OMPTargetParallelForDirective::Create(
11240       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11241       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11242 }
11243 
11244 /// Check for existence of a map clause in the list of clauses.
hasClauses(ArrayRef<OMPClause * > Clauses,const OpenMPClauseKind K)11245 static bool hasClauses(ArrayRef<OMPClause *> Clauses,
11246                        const OpenMPClauseKind K) {
11247   return llvm::any_of(
11248       Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
11249 }
11250 
11251 template <typename... Params>
hasClauses(ArrayRef<OMPClause * > Clauses,const OpenMPClauseKind K,const Params...ClauseTypes)11252 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
11253                        const Params... ClauseTypes) {
11254   return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
11255 }
11256 
ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)11257 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
11258                                                 Stmt *AStmt,
11259                                                 SourceLocation StartLoc,
11260                                                 SourceLocation EndLoc) {
11261   if (!AStmt)
11262     return StmtError();
11263 
11264   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11265 
11266   // OpenMP [2.12.2, target data Construct, Restrictions]
11267   // At least one map, use_device_addr or use_device_ptr clause must appear on
11268   // the directive.
11269   if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) &&
11270       (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) {
11271     StringRef Expected;
11272     if (LangOpts.OpenMP < 50)
11273       Expected = "'map' or 'use_device_ptr'";
11274     else
11275       Expected = "'map', 'use_device_ptr', or 'use_device_addr'";
11276     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
11277         << Expected << getOpenMPDirectiveName(OMPD_target_data);
11278     return StmtError();
11279   }
11280 
11281   setFunctionHasBranchProtectedScope();
11282 
11283   return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
11284                                         AStmt);
11285 }
11286 
11287 StmtResult
ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,Stmt * AStmt)11288 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
11289                                           SourceLocation StartLoc,
11290                                           SourceLocation EndLoc, Stmt *AStmt) {
11291   if (!AStmt)
11292     return StmtError();
11293 
11294   auto *CS = cast<CapturedStmt>(AStmt);
11295   // 1.2.2 OpenMP Language Terminology
11296   // Structured block - An executable statement with a single entry at the
11297   // top and a single exit at the bottom.
11298   // The point of exit cannot be a branch out of the structured block.
11299   // longjmp() and throw() must not violate the entry/exit criteria.
11300   CS->getCapturedDecl()->setNothrow();
11301   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
11302        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11303     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11304     // 1.2.2 OpenMP Language Terminology
11305     // Structured block - An executable statement with a single entry at the
11306     // top and a single exit at the bottom.
11307     // The point of exit cannot be a branch out of the structured block.
11308     // longjmp() and throw() must not violate the entry/exit criteria.
11309     CS->getCapturedDecl()->setNothrow();
11310   }
11311 
11312   // OpenMP [2.10.2, Restrictions, p. 99]
11313   // At least one map clause must appear on the directive.
11314   if (!hasClauses(Clauses, OMPC_map)) {
11315     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
11316         << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
11317     return StmtError();
11318   }
11319 
11320   return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
11321                                              AStmt);
11322 }
11323 
11324 StmtResult
ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,Stmt * AStmt)11325 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
11326                                          SourceLocation StartLoc,
11327                                          SourceLocation EndLoc, Stmt *AStmt) {
11328   if (!AStmt)
11329     return StmtError();
11330 
11331   auto *CS = cast<CapturedStmt>(AStmt);
11332   // 1.2.2 OpenMP Language Terminology
11333   // Structured block - An executable statement with a single entry at the
11334   // top and a single exit at the bottom.
11335   // The point of exit cannot be a branch out of the structured block.
11336   // longjmp() and throw() must not violate the entry/exit criteria.
11337   CS->getCapturedDecl()->setNothrow();
11338   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
11339        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11340     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11341     // 1.2.2 OpenMP Language Terminology
11342     // Structured block - An executable statement with a single entry at the
11343     // top and a single exit at the bottom.
11344     // The point of exit cannot be a branch out of the structured block.
11345     // longjmp() and throw() must not violate the entry/exit criteria.
11346     CS->getCapturedDecl()->setNothrow();
11347   }
11348 
11349   // OpenMP [2.10.3, Restrictions, p. 102]
11350   // At least one map clause must appear on the directive.
11351   if (!hasClauses(Clauses, OMPC_map)) {
11352     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
11353         << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
11354     return StmtError();
11355   }
11356 
11357   return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
11358                                             AStmt);
11359 }
11360 
ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,Stmt * AStmt)11361 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
11362                                                   SourceLocation StartLoc,
11363                                                   SourceLocation EndLoc,
11364                                                   Stmt *AStmt) {
11365   if (!AStmt)
11366     return StmtError();
11367 
11368   auto *CS = cast<CapturedStmt>(AStmt);
11369   // 1.2.2 OpenMP Language Terminology
11370   // Structured block - An executable statement with a single entry at the
11371   // top and a single exit at the bottom.
11372   // The point of exit cannot be a branch out of the structured block.
11373   // longjmp() and throw() must not violate the entry/exit criteria.
11374   CS->getCapturedDecl()->setNothrow();
11375   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
11376        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11377     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11378     // 1.2.2 OpenMP Language Terminology
11379     // Structured block - An executable statement with a single entry at the
11380     // top and a single exit at the bottom.
11381     // The point of exit cannot be a branch out of the structured block.
11382     // longjmp() and throw() must not violate the entry/exit criteria.
11383     CS->getCapturedDecl()->setNothrow();
11384   }
11385 
11386   if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
11387     Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
11388     return StmtError();
11389   }
11390   return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
11391                                           AStmt);
11392 }
11393 
ActOnOpenMPTeamsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)11394 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
11395                                            Stmt *AStmt, SourceLocation StartLoc,
11396                                            SourceLocation EndLoc) {
11397   if (!AStmt)
11398     return StmtError();
11399 
11400   auto *CS = cast<CapturedStmt>(AStmt);
11401   // 1.2.2 OpenMP Language Terminology
11402   // Structured block - An executable statement with a single entry at the
11403   // top and a single exit at the bottom.
11404   // The point of exit cannot be a branch out of the structured block.
11405   // longjmp() and throw() must not violate the entry/exit criteria.
11406   CS->getCapturedDecl()->setNothrow();
11407 
11408   setFunctionHasBranchProtectedScope();
11409 
11410   DSAStack->setParentTeamsRegionLoc(StartLoc);
11411 
11412   return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
11413 }
11414 
11415 StmtResult
ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,SourceLocation EndLoc,OpenMPDirectiveKind CancelRegion)11416 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
11417                                             SourceLocation EndLoc,
11418                                             OpenMPDirectiveKind CancelRegion) {
11419   if (DSAStack->isParentNowaitRegion()) {
11420     Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
11421     return StmtError();
11422   }
11423   if (DSAStack->isParentOrderedRegion()) {
11424     Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
11425     return StmtError();
11426   }
11427   return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
11428                                                CancelRegion);
11429 }
11430 
ActOnOpenMPCancelDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,OpenMPDirectiveKind CancelRegion)11431 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
11432                                             SourceLocation StartLoc,
11433                                             SourceLocation EndLoc,
11434                                             OpenMPDirectiveKind CancelRegion) {
11435   if (DSAStack->isParentNowaitRegion()) {
11436     Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
11437     return StmtError();
11438   }
11439   if (DSAStack->isParentOrderedRegion()) {
11440     Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
11441     return StmtError();
11442   }
11443   DSAStack->setParentCancelRegion(/*Cancel=*/true);
11444   return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
11445                                     CancelRegion);
11446 }
11447 
checkGrainsizeNumTasksClauses(Sema & S,ArrayRef<OMPClause * > Clauses)11448 static bool checkGrainsizeNumTasksClauses(Sema &S,
11449                                           ArrayRef<OMPClause *> Clauses) {
11450   const OMPClause *PrevClause = nullptr;
11451   bool ErrorFound = false;
11452   for (const OMPClause *C : Clauses) {
11453     if (C->getClauseKind() == OMPC_grainsize ||
11454         C->getClauseKind() == OMPC_num_tasks) {
11455       if (!PrevClause)
11456         PrevClause = C;
11457       else if (PrevClause->getClauseKind() != C->getClauseKind()) {
11458         S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
11459             << getOpenMPClauseName(C->getClauseKind())
11460             << getOpenMPClauseName(PrevClause->getClauseKind());
11461         S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
11462             << getOpenMPClauseName(PrevClause->getClauseKind());
11463         ErrorFound = true;
11464       }
11465     }
11466   }
11467   return ErrorFound;
11468 }
11469 
checkReductionClauseWithNogroup(Sema & S,ArrayRef<OMPClause * > Clauses)11470 static bool checkReductionClauseWithNogroup(Sema &S,
11471                                             ArrayRef<OMPClause *> Clauses) {
11472   const OMPClause *ReductionClause = nullptr;
11473   const OMPClause *NogroupClause = nullptr;
11474   for (const OMPClause *C : Clauses) {
11475     if (C->getClauseKind() == OMPC_reduction) {
11476       ReductionClause = C;
11477       if (NogroupClause)
11478         break;
11479       continue;
11480     }
11481     if (C->getClauseKind() == OMPC_nogroup) {
11482       NogroupClause = C;
11483       if (ReductionClause)
11484         break;
11485       continue;
11486     }
11487   }
11488   if (ReductionClause && NogroupClause) {
11489     S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
11490         << SourceRange(NogroupClause->getBeginLoc(),
11491                        NogroupClause->getEndLoc());
11492     return true;
11493   }
11494   return false;
11495 }
11496 
ActOnOpenMPTaskLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11497 StmtResult Sema::ActOnOpenMPTaskLoopDirective(
11498     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11499     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11500   if (!AStmt)
11501     return StmtError();
11502 
11503   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11504   OMPLoopBasedDirective::HelperExprs B;
11505   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11506   // define the nested loops number.
11507   unsigned NestedLoopCount =
11508       checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
11509                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
11510                       VarsWithImplicitDSA, B);
11511   if (NestedLoopCount == 0)
11512     return StmtError();
11513 
11514   assert((CurContext->isDependentContext() || B.builtAll()) &&
11515          "omp for loop exprs were not built");
11516 
11517   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11518   // The grainsize clause and num_tasks clause are mutually exclusive and may
11519   // not appear on the same taskloop directive.
11520   if (checkGrainsizeNumTasksClauses(*this, Clauses))
11521     return StmtError();
11522   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11523   // If a reduction clause is present on the taskloop directive, the nogroup
11524   // clause must not be specified.
11525   if (checkReductionClauseWithNogroup(*this, Clauses))
11526     return StmtError();
11527 
11528   setFunctionHasBranchProtectedScope();
11529   return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
11530                                       NestedLoopCount, Clauses, AStmt, B,
11531                                       DSAStack->isCancelRegion());
11532 }
11533 
ActOnOpenMPTaskLoopSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11534 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
11535     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11536     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11537   if (!AStmt)
11538     return StmtError();
11539 
11540   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11541   OMPLoopBasedDirective::HelperExprs B;
11542   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11543   // define the nested loops number.
11544   unsigned NestedLoopCount =
11545       checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
11546                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
11547                       VarsWithImplicitDSA, B);
11548   if (NestedLoopCount == 0)
11549     return StmtError();
11550 
11551   assert((CurContext->isDependentContext() || B.builtAll()) &&
11552          "omp for loop exprs were not built");
11553 
11554   if (!CurContext->isDependentContext()) {
11555     // Finalize the clauses that need pre-built expressions for CodeGen.
11556     for (OMPClause *C : Clauses) {
11557       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11558         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11559                                      B.NumIterations, *this, CurScope,
11560                                      DSAStack))
11561           return StmtError();
11562     }
11563   }
11564 
11565   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11566   // The grainsize clause and num_tasks clause are mutually exclusive and may
11567   // not appear on the same taskloop directive.
11568   if (checkGrainsizeNumTasksClauses(*this, Clauses))
11569     return StmtError();
11570   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11571   // If a reduction clause is present on the taskloop directive, the nogroup
11572   // clause must not be specified.
11573   if (checkReductionClauseWithNogroup(*this, Clauses))
11574     return StmtError();
11575   if (checkSimdlenSafelenSpecified(*this, Clauses))
11576     return StmtError();
11577 
11578   setFunctionHasBranchProtectedScope();
11579   return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
11580                                           NestedLoopCount, Clauses, AStmt, B);
11581 }
11582 
ActOnOpenMPMasterTaskLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11583 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective(
11584     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11585     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11586   if (!AStmt)
11587     return StmtError();
11588 
11589   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11590   OMPLoopBasedDirective::HelperExprs B;
11591   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11592   // define the nested loops number.
11593   unsigned NestedLoopCount =
11594       checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses),
11595                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
11596                       VarsWithImplicitDSA, B);
11597   if (NestedLoopCount == 0)
11598     return StmtError();
11599 
11600   assert((CurContext->isDependentContext() || B.builtAll()) &&
11601          "omp for loop exprs were not built");
11602 
11603   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11604   // The grainsize clause and num_tasks clause are mutually exclusive and may
11605   // not appear on the same taskloop directive.
11606   if (checkGrainsizeNumTasksClauses(*this, Clauses))
11607     return StmtError();
11608   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11609   // If a reduction clause is present on the taskloop directive, the nogroup
11610   // clause must not be specified.
11611   if (checkReductionClauseWithNogroup(*this, Clauses))
11612     return StmtError();
11613 
11614   setFunctionHasBranchProtectedScope();
11615   return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc,
11616                                             NestedLoopCount, Clauses, AStmt, B,
11617                                             DSAStack->isCancelRegion());
11618 }
11619 
ActOnOpenMPMasterTaskLoopSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11620 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective(
11621     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11622     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11623   if (!AStmt)
11624     return StmtError();
11625 
11626   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11627   OMPLoopBasedDirective::HelperExprs B;
11628   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11629   // define the nested loops number.
11630   unsigned NestedLoopCount =
11631       checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses),
11632                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
11633                       VarsWithImplicitDSA, B);
11634   if (NestedLoopCount == 0)
11635     return StmtError();
11636 
11637   assert((CurContext->isDependentContext() || B.builtAll()) &&
11638          "omp for loop exprs were not built");
11639 
11640   if (!CurContext->isDependentContext()) {
11641     // Finalize the clauses that need pre-built expressions for CodeGen.
11642     for (OMPClause *C : Clauses) {
11643       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11644         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11645                                      B.NumIterations, *this, CurScope,
11646                                      DSAStack))
11647           return StmtError();
11648     }
11649   }
11650 
11651   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11652   // The grainsize clause and num_tasks clause are mutually exclusive and may
11653   // not appear on the same taskloop directive.
11654   if (checkGrainsizeNumTasksClauses(*this, Clauses))
11655     return StmtError();
11656   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11657   // If a reduction clause is present on the taskloop directive, the nogroup
11658   // clause must not be specified.
11659   if (checkReductionClauseWithNogroup(*this, Clauses))
11660     return StmtError();
11661   if (checkSimdlenSafelenSpecified(*this, Clauses))
11662     return StmtError();
11663 
11664   setFunctionHasBranchProtectedScope();
11665   return OMPMasterTaskLoopSimdDirective::Create(
11666       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11667 }
11668 
ActOnOpenMPParallelMasterTaskLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11669 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective(
11670     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11671     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11672   if (!AStmt)
11673     return StmtError();
11674 
11675   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11676   auto *CS = cast<CapturedStmt>(AStmt);
11677   // 1.2.2 OpenMP Language Terminology
11678   // Structured block - An executable statement with a single entry at the
11679   // top and a single exit at the bottom.
11680   // The point of exit cannot be a branch out of the structured block.
11681   // longjmp() and throw() must not violate the entry/exit criteria.
11682   CS->getCapturedDecl()->setNothrow();
11683   for (int ThisCaptureLevel =
11684            getOpenMPCaptureLevels(OMPD_parallel_master_taskloop);
11685        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11686     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11687     // 1.2.2 OpenMP Language Terminology
11688     // Structured block - An executable statement with a single entry at the
11689     // top and a single exit at the bottom.
11690     // The point of exit cannot be a branch out of the structured block.
11691     // longjmp() and throw() must not violate the entry/exit criteria.
11692     CS->getCapturedDecl()->setNothrow();
11693   }
11694 
11695   OMPLoopBasedDirective::HelperExprs B;
11696   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11697   // define the nested loops number.
11698   unsigned NestedLoopCount = checkOpenMPLoop(
11699       OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses),
11700       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
11701       VarsWithImplicitDSA, B);
11702   if (NestedLoopCount == 0)
11703     return StmtError();
11704 
11705   assert((CurContext->isDependentContext() || B.builtAll()) &&
11706          "omp for loop exprs were not built");
11707 
11708   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11709   // The grainsize clause and num_tasks clause are mutually exclusive and may
11710   // not appear on the same taskloop directive.
11711   if (checkGrainsizeNumTasksClauses(*this, Clauses))
11712     return StmtError();
11713   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11714   // If a reduction clause is present on the taskloop directive, the nogroup
11715   // clause must not be specified.
11716   if (checkReductionClauseWithNogroup(*this, Clauses))
11717     return StmtError();
11718 
11719   setFunctionHasBranchProtectedScope();
11720   return OMPParallelMasterTaskLoopDirective::Create(
11721       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11722       DSAStack->isCancelRegion());
11723 }
11724 
ActOnOpenMPParallelMasterTaskLoopSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11725 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective(
11726     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11727     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11728   if (!AStmt)
11729     return StmtError();
11730 
11731   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11732   auto *CS = cast<CapturedStmt>(AStmt);
11733   // 1.2.2 OpenMP Language Terminology
11734   // Structured block - An executable statement with a single entry at the
11735   // top and a single exit at the bottom.
11736   // The point of exit cannot be a branch out of the structured block.
11737   // longjmp() and throw() must not violate the entry/exit criteria.
11738   CS->getCapturedDecl()->setNothrow();
11739   for (int ThisCaptureLevel =
11740            getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd);
11741        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11742     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11743     // 1.2.2 OpenMP Language Terminology
11744     // Structured block - An executable statement with a single entry at the
11745     // top and a single exit at the bottom.
11746     // The point of exit cannot be a branch out of the structured block.
11747     // longjmp() and throw() must not violate the entry/exit criteria.
11748     CS->getCapturedDecl()->setNothrow();
11749   }
11750 
11751   OMPLoopBasedDirective::HelperExprs B;
11752   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11753   // define the nested loops number.
11754   unsigned NestedLoopCount = checkOpenMPLoop(
11755       OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses),
11756       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
11757       VarsWithImplicitDSA, B);
11758   if (NestedLoopCount == 0)
11759     return StmtError();
11760 
11761   assert((CurContext->isDependentContext() || B.builtAll()) &&
11762          "omp for loop exprs were not built");
11763 
11764   if (!CurContext->isDependentContext()) {
11765     // Finalize the clauses that need pre-built expressions for CodeGen.
11766     for (OMPClause *C : Clauses) {
11767       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11768         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11769                                      B.NumIterations, *this, CurScope,
11770                                      DSAStack))
11771           return StmtError();
11772     }
11773   }
11774 
11775   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11776   // The grainsize clause and num_tasks clause are mutually exclusive and may
11777   // not appear on the same taskloop directive.
11778   if (checkGrainsizeNumTasksClauses(*this, Clauses))
11779     return StmtError();
11780   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11781   // If a reduction clause is present on the taskloop directive, the nogroup
11782   // clause must not be specified.
11783   if (checkReductionClauseWithNogroup(*this, Clauses))
11784     return StmtError();
11785   if (checkSimdlenSafelenSpecified(*this, Clauses))
11786     return StmtError();
11787 
11788   setFunctionHasBranchProtectedScope();
11789   return OMPParallelMasterTaskLoopSimdDirective::Create(
11790       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11791 }
11792 
ActOnOpenMPDistributeDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11793 StmtResult Sema::ActOnOpenMPDistributeDirective(
11794     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11795     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11796   if (!AStmt)
11797     return StmtError();
11798 
11799   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11800   OMPLoopBasedDirective::HelperExprs B;
11801   // In presence of clause 'collapse' with number of loops, it will
11802   // define the nested loops number.
11803   unsigned NestedLoopCount =
11804       checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
11805                       nullptr /*ordered not a clause on distribute*/, AStmt,
11806                       *this, *DSAStack, VarsWithImplicitDSA, B);
11807   if (NestedLoopCount == 0)
11808     return StmtError();
11809 
11810   assert((CurContext->isDependentContext() || B.builtAll()) &&
11811          "omp for loop exprs were not built");
11812 
11813   setFunctionHasBranchProtectedScope();
11814   return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
11815                                         NestedLoopCount, Clauses, AStmt, B);
11816 }
11817 
ActOnOpenMPDistributeParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11818 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
11819     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11820     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11821   if (!AStmt)
11822     return StmtError();
11823 
11824   auto *CS = cast<CapturedStmt>(AStmt);
11825   // 1.2.2 OpenMP Language Terminology
11826   // Structured block - An executable statement with a single entry at the
11827   // top and a single exit at the bottom.
11828   // The point of exit cannot be a branch out of the structured block.
11829   // longjmp() and throw() must not violate the entry/exit criteria.
11830   CS->getCapturedDecl()->setNothrow();
11831   for (int ThisCaptureLevel =
11832            getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
11833        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11834     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11835     // 1.2.2 OpenMP Language Terminology
11836     // Structured block - An executable statement with a single entry at the
11837     // top and a single exit at the bottom.
11838     // The point of exit cannot be a branch out of the structured block.
11839     // longjmp() and throw() must not violate the entry/exit criteria.
11840     CS->getCapturedDecl()->setNothrow();
11841   }
11842 
11843   OMPLoopBasedDirective::HelperExprs B;
11844   // In presence of clause 'collapse' with number of loops, it will
11845   // define the nested loops number.
11846   unsigned NestedLoopCount = checkOpenMPLoop(
11847       OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
11848       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11849       VarsWithImplicitDSA, B);
11850   if (NestedLoopCount == 0)
11851     return StmtError();
11852 
11853   assert((CurContext->isDependentContext() || B.builtAll()) &&
11854          "omp for loop exprs were not built");
11855 
11856   setFunctionHasBranchProtectedScope();
11857   return OMPDistributeParallelForDirective::Create(
11858       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11859       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11860 }
11861 
ActOnOpenMPDistributeParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11862 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
11863     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11864     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11865   if (!AStmt)
11866     return StmtError();
11867 
11868   auto *CS = cast<CapturedStmt>(AStmt);
11869   // 1.2.2 OpenMP Language Terminology
11870   // Structured block - An executable statement with a single entry at the
11871   // top and a single exit at the bottom.
11872   // The point of exit cannot be a branch out of the structured block.
11873   // longjmp() and throw() must not violate the entry/exit criteria.
11874   CS->getCapturedDecl()->setNothrow();
11875   for (int ThisCaptureLevel =
11876            getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
11877        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11878     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11879     // 1.2.2 OpenMP Language Terminology
11880     // Structured block - An executable statement with a single entry at the
11881     // top and a single exit at the bottom.
11882     // The point of exit cannot be a branch out of the structured block.
11883     // longjmp() and throw() must not violate the entry/exit criteria.
11884     CS->getCapturedDecl()->setNothrow();
11885   }
11886 
11887   OMPLoopBasedDirective::HelperExprs B;
11888   // In presence of clause 'collapse' with number of loops, it will
11889   // define the nested loops number.
11890   unsigned NestedLoopCount = checkOpenMPLoop(
11891       OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
11892       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11893       VarsWithImplicitDSA, B);
11894   if (NestedLoopCount == 0)
11895     return StmtError();
11896 
11897   assert((CurContext->isDependentContext() || B.builtAll()) &&
11898          "omp for loop exprs were not built");
11899 
11900   if (!CurContext->isDependentContext()) {
11901     // Finalize the clauses that need pre-built expressions for CodeGen.
11902     for (OMPClause *C : Clauses) {
11903       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11904         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11905                                      B.NumIterations, *this, CurScope,
11906                                      DSAStack))
11907           return StmtError();
11908     }
11909   }
11910 
11911   if (checkSimdlenSafelenSpecified(*this, Clauses))
11912     return StmtError();
11913 
11914   setFunctionHasBranchProtectedScope();
11915   return OMPDistributeParallelForSimdDirective::Create(
11916       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11917 }
11918 
ActOnOpenMPDistributeSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11919 StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
11920     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11921     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11922   if (!AStmt)
11923     return StmtError();
11924 
11925   auto *CS = cast<CapturedStmt>(AStmt);
11926   // 1.2.2 OpenMP Language Terminology
11927   // Structured block - An executable statement with a single entry at the
11928   // top and a single exit at the bottom.
11929   // The point of exit cannot be a branch out of the structured block.
11930   // longjmp() and throw() must not violate the entry/exit criteria.
11931   CS->getCapturedDecl()->setNothrow();
11932   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
11933        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11934     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11935     // 1.2.2 OpenMP Language Terminology
11936     // Structured block - An executable statement with a single entry at the
11937     // top and a single exit at the bottom.
11938     // The point of exit cannot be a branch out of the structured block.
11939     // longjmp() and throw() must not violate the entry/exit criteria.
11940     CS->getCapturedDecl()->setNothrow();
11941   }
11942 
11943   OMPLoopBasedDirective::HelperExprs B;
11944   // In presence of clause 'collapse' with number of loops, it will
11945   // define the nested loops number.
11946   unsigned NestedLoopCount =
11947       checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
11948                       nullptr /*ordered not a clause on distribute*/, CS, *this,
11949                       *DSAStack, VarsWithImplicitDSA, B);
11950   if (NestedLoopCount == 0)
11951     return StmtError();
11952 
11953   assert((CurContext->isDependentContext() || B.builtAll()) &&
11954          "omp for loop exprs were not built");
11955 
11956   if (!CurContext->isDependentContext()) {
11957     // Finalize the clauses that need pre-built expressions for CodeGen.
11958     for (OMPClause *C : Clauses) {
11959       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11960         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11961                                      B.NumIterations, *this, CurScope,
11962                                      DSAStack))
11963           return StmtError();
11964     }
11965   }
11966 
11967   if (checkSimdlenSafelenSpecified(*this, Clauses))
11968     return StmtError();
11969 
11970   setFunctionHasBranchProtectedScope();
11971   return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
11972                                             NestedLoopCount, Clauses, AStmt, B);
11973 }
11974 
ActOnOpenMPTargetParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11975 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
11976     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11977     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11978   if (!AStmt)
11979     return StmtError();
11980 
11981   auto *CS = cast<CapturedStmt>(AStmt);
11982   // 1.2.2 OpenMP Language Terminology
11983   // Structured block - An executable statement with a single entry at the
11984   // top and a single exit at the bottom.
11985   // The point of exit cannot be a branch out of the structured block.
11986   // longjmp() and throw() must not violate the entry/exit criteria.
11987   CS->getCapturedDecl()->setNothrow();
11988   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
11989        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11990     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11991     // 1.2.2 OpenMP Language Terminology
11992     // Structured block - An executable statement with a single entry at the
11993     // top and a single exit at the bottom.
11994     // The point of exit cannot be a branch out of the structured block.
11995     // longjmp() and throw() must not violate the entry/exit criteria.
11996     CS->getCapturedDecl()->setNothrow();
11997   }
11998 
11999   OMPLoopBasedDirective::HelperExprs B;
12000   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
12001   // define the nested loops number.
12002   unsigned NestedLoopCount = checkOpenMPLoop(
12003       OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
12004       getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
12005       VarsWithImplicitDSA, B);
12006   if (NestedLoopCount == 0)
12007     return StmtError();
12008 
12009   assert((CurContext->isDependentContext() || B.builtAll()) &&
12010          "omp target parallel for simd loop exprs were not built");
12011 
12012   if (!CurContext->isDependentContext()) {
12013     // Finalize the clauses that need pre-built expressions for CodeGen.
12014     for (OMPClause *C : Clauses) {
12015       if (auto *LC = dyn_cast<OMPLinearClause>(C))
12016         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12017                                      B.NumIterations, *this, CurScope,
12018                                      DSAStack))
12019           return StmtError();
12020     }
12021   }
12022   if (checkSimdlenSafelenSpecified(*this, Clauses))
12023     return StmtError();
12024 
12025   setFunctionHasBranchProtectedScope();
12026   return OMPTargetParallelForSimdDirective::Create(
12027       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12028 }
12029 
ActOnOpenMPTargetSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12030 StmtResult Sema::ActOnOpenMPTargetSimdDirective(
12031     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12032     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12033   if (!AStmt)
12034     return StmtError();
12035 
12036   auto *CS = cast<CapturedStmt>(AStmt);
12037   // 1.2.2 OpenMP Language Terminology
12038   // Structured block - An executable statement with a single entry at the
12039   // top and a single exit at the bottom.
12040   // The point of exit cannot be a branch out of the structured block.
12041   // longjmp() and throw() must not violate the entry/exit criteria.
12042   CS->getCapturedDecl()->setNothrow();
12043   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
12044        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12045     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12046     // 1.2.2 OpenMP Language Terminology
12047     // Structured block - An executable statement with a single entry at the
12048     // top and a single exit at the bottom.
12049     // The point of exit cannot be a branch out of the structured block.
12050     // longjmp() and throw() must not violate the entry/exit criteria.
12051     CS->getCapturedDecl()->setNothrow();
12052   }
12053 
12054   OMPLoopBasedDirective::HelperExprs B;
12055   // In presence of clause 'collapse' with number of loops, it will define the
12056   // nested loops number.
12057   unsigned NestedLoopCount =
12058       checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
12059                       getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
12060                       VarsWithImplicitDSA, B);
12061   if (NestedLoopCount == 0)
12062     return StmtError();
12063 
12064   assert((CurContext->isDependentContext() || B.builtAll()) &&
12065          "omp target simd loop exprs were not built");
12066 
12067   if (!CurContext->isDependentContext()) {
12068     // Finalize the clauses that need pre-built expressions for CodeGen.
12069     for (OMPClause *C : Clauses) {
12070       if (auto *LC = dyn_cast<OMPLinearClause>(C))
12071         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12072                                      B.NumIterations, *this, CurScope,
12073                                      DSAStack))
12074           return StmtError();
12075     }
12076   }
12077 
12078   if (checkSimdlenSafelenSpecified(*this, Clauses))
12079     return StmtError();
12080 
12081   setFunctionHasBranchProtectedScope();
12082   return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
12083                                         NestedLoopCount, Clauses, AStmt, B);
12084 }
12085 
ActOnOpenMPTeamsDistributeDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12086 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
12087     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12088     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12089   if (!AStmt)
12090     return StmtError();
12091 
12092   auto *CS = cast<CapturedStmt>(AStmt);
12093   // 1.2.2 OpenMP Language Terminology
12094   // Structured block - An executable statement with a single entry at the
12095   // top and a single exit at the bottom.
12096   // The point of exit cannot be a branch out of the structured block.
12097   // longjmp() and throw() must not violate the entry/exit criteria.
12098   CS->getCapturedDecl()->setNothrow();
12099   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
12100        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12101     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12102     // 1.2.2 OpenMP Language Terminology
12103     // Structured block - An executable statement with a single entry at the
12104     // top and a single exit at the bottom.
12105     // The point of exit cannot be a branch out of the structured block.
12106     // longjmp() and throw() must not violate the entry/exit criteria.
12107     CS->getCapturedDecl()->setNothrow();
12108   }
12109 
12110   OMPLoopBasedDirective::HelperExprs B;
12111   // In presence of clause 'collapse' with number of loops, it will
12112   // define the nested loops number.
12113   unsigned NestedLoopCount =
12114       checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
12115                       nullptr /*ordered not a clause on distribute*/, CS, *this,
12116                       *DSAStack, VarsWithImplicitDSA, B);
12117   if (NestedLoopCount == 0)
12118     return StmtError();
12119 
12120   assert((CurContext->isDependentContext() || B.builtAll()) &&
12121          "omp teams distribute loop exprs were not built");
12122 
12123   setFunctionHasBranchProtectedScope();
12124 
12125   DSAStack->setParentTeamsRegionLoc(StartLoc);
12126 
12127   return OMPTeamsDistributeDirective::Create(
12128       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12129 }
12130 
ActOnOpenMPTeamsDistributeSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12131 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
12132     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12133     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12134   if (!AStmt)
12135     return StmtError();
12136 
12137   auto *CS = cast<CapturedStmt>(AStmt);
12138   // 1.2.2 OpenMP Language Terminology
12139   // Structured block - An executable statement with a single entry at the
12140   // top and a single exit at the bottom.
12141   // The point of exit cannot be a branch out of the structured block.
12142   // longjmp() and throw() must not violate the entry/exit criteria.
12143   CS->getCapturedDecl()->setNothrow();
12144   for (int ThisCaptureLevel =
12145            getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
12146        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12147     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12148     // 1.2.2 OpenMP Language Terminology
12149     // Structured block - An executable statement with a single entry at the
12150     // top and a single exit at the bottom.
12151     // The point of exit cannot be a branch out of the structured block.
12152     // longjmp() and throw() must not violate the entry/exit criteria.
12153     CS->getCapturedDecl()->setNothrow();
12154   }
12155 
12156   OMPLoopBasedDirective::HelperExprs B;
12157   // In presence of clause 'collapse' with number of loops, it will
12158   // define the nested loops number.
12159   unsigned NestedLoopCount = checkOpenMPLoop(
12160       OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
12161       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
12162       VarsWithImplicitDSA, B);
12163 
12164   if (NestedLoopCount == 0)
12165     return StmtError();
12166 
12167   assert((CurContext->isDependentContext() || B.builtAll()) &&
12168          "omp teams distribute simd loop exprs were not built");
12169 
12170   if (!CurContext->isDependentContext()) {
12171     // Finalize the clauses that need pre-built expressions for CodeGen.
12172     for (OMPClause *C : Clauses) {
12173       if (auto *LC = dyn_cast<OMPLinearClause>(C))
12174         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12175                                      B.NumIterations, *this, CurScope,
12176                                      DSAStack))
12177           return StmtError();
12178     }
12179   }
12180 
12181   if (checkSimdlenSafelenSpecified(*this, Clauses))
12182     return StmtError();
12183 
12184   setFunctionHasBranchProtectedScope();
12185 
12186   DSAStack->setParentTeamsRegionLoc(StartLoc);
12187 
12188   return OMPTeamsDistributeSimdDirective::Create(
12189       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12190 }
12191 
ActOnOpenMPTeamsDistributeParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12192 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
12193     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12194     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12195   if (!AStmt)
12196     return StmtError();
12197 
12198   auto *CS = cast<CapturedStmt>(AStmt);
12199   // 1.2.2 OpenMP Language Terminology
12200   // Structured block - An executable statement with a single entry at the
12201   // top and a single exit at the bottom.
12202   // The point of exit cannot be a branch out of the structured block.
12203   // longjmp() and throw() must not violate the entry/exit criteria.
12204   CS->getCapturedDecl()->setNothrow();
12205 
12206   for (int ThisCaptureLevel =
12207            getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
12208        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12209     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12210     // 1.2.2 OpenMP Language Terminology
12211     // Structured block - An executable statement with a single entry at the
12212     // top and a single exit at the bottom.
12213     // The point of exit cannot be a branch out of the structured block.
12214     // longjmp() and throw() must not violate the entry/exit criteria.
12215     CS->getCapturedDecl()->setNothrow();
12216   }
12217 
12218   OMPLoopBasedDirective::HelperExprs B;
12219   // In presence of clause 'collapse' with number of loops, it will
12220   // define the nested loops number.
12221   unsigned NestedLoopCount = checkOpenMPLoop(
12222       OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
12223       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
12224       VarsWithImplicitDSA, B);
12225 
12226   if (NestedLoopCount == 0)
12227     return StmtError();
12228 
12229   assert((CurContext->isDependentContext() || B.builtAll()) &&
12230          "omp for loop exprs were not built");
12231 
12232   if (!CurContext->isDependentContext()) {
12233     // Finalize the clauses that need pre-built expressions for CodeGen.
12234     for (OMPClause *C : Clauses) {
12235       if (auto *LC = dyn_cast<OMPLinearClause>(C))
12236         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12237                                      B.NumIterations, *this, CurScope,
12238                                      DSAStack))
12239           return StmtError();
12240     }
12241   }
12242 
12243   if (checkSimdlenSafelenSpecified(*this, Clauses))
12244     return StmtError();
12245 
12246   setFunctionHasBranchProtectedScope();
12247 
12248   DSAStack->setParentTeamsRegionLoc(StartLoc);
12249 
12250   return OMPTeamsDistributeParallelForSimdDirective::Create(
12251       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12252 }
12253 
ActOnOpenMPTeamsDistributeParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12254 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
12255     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12256     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12257   if (!AStmt)
12258     return StmtError();
12259 
12260   auto *CS = cast<CapturedStmt>(AStmt);
12261   // 1.2.2 OpenMP Language Terminology
12262   // Structured block - An executable statement with a single entry at the
12263   // top and a single exit at the bottom.
12264   // The point of exit cannot be a branch out of the structured block.
12265   // longjmp() and throw() must not violate the entry/exit criteria.
12266   CS->getCapturedDecl()->setNothrow();
12267 
12268   for (int ThisCaptureLevel =
12269            getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
12270        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12271     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12272     // 1.2.2 OpenMP Language Terminology
12273     // Structured block - An executable statement with a single entry at the
12274     // top and a single exit at the bottom.
12275     // The point of exit cannot be a branch out of the structured block.
12276     // longjmp() and throw() must not violate the entry/exit criteria.
12277     CS->getCapturedDecl()->setNothrow();
12278   }
12279 
12280   OMPLoopBasedDirective::HelperExprs B;
12281   // In presence of clause 'collapse' with number of loops, it will
12282   // define the nested loops number.
12283   unsigned NestedLoopCount = checkOpenMPLoop(
12284       OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
12285       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
12286       VarsWithImplicitDSA, B);
12287 
12288   if (NestedLoopCount == 0)
12289     return StmtError();
12290 
12291   assert((CurContext->isDependentContext() || B.builtAll()) &&
12292          "omp for loop exprs were not built");
12293 
12294   setFunctionHasBranchProtectedScope();
12295 
12296   DSAStack->setParentTeamsRegionLoc(StartLoc);
12297 
12298   return OMPTeamsDistributeParallelForDirective::Create(
12299       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
12300       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
12301 }
12302 
ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)12303 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
12304                                                  Stmt *AStmt,
12305                                                  SourceLocation StartLoc,
12306                                                  SourceLocation EndLoc) {
12307   if (!AStmt)
12308     return StmtError();
12309 
12310   auto *CS = cast<CapturedStmt>(AStmt);
12311   // 1.2.2 OpenMP Language Terminology
12312   // Structured block - An executable statement with a single entry at the
12313   // top and a single exit at the bottom.
12314   // The point of exit cannot be a branch out of the structured block.
12315   // longjmp() and throw() must not violate the entry/exit criteria.
12316   CS->getCapturedDecl()->setNothrow();
12317 
12318   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
12319        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12320     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12321     // 1.2.2 OpenMP Language Terminology
12322     // Structured block - An executable statement with a single entry at the
12323     // top and a single exit at the bottom.
12324     // The point of exit cannot be a branch out of the structured block.
12325     // longjmp() and throw() must not violate the entry/exit criteria.
12326     CS->getCapturedDecl()->setNothrow();
12327   }
12328   setFunctionHasBranchProtectedScope();
12329 
12330   return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
12331                                          AStmt);
12332 }
12333 
ActOnOpenMPTargetTeamsDistributeDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12334 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
12335     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12336     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12337   if (!AStmt)
12338     return StmtError();
12339 
12340   auto *CS = cast<CapturedStmt>(AStmt);
12341   // 1.2.2 OpenMP Language Terminology
12342   // Structured block - An executable statement with a single entry at the
12343   // top and a single exit at the bottom.
12344   // The point of exit cannot be a branch out of the structured block.
12345   // longjmp() and throw() must not violate the entry/exit criteria.
12346   CS->getCapturedDecl()->setNothrow();
12347   for (int ThisCaptureLevel =
12348            getOpenMPCaptureLevels(OMPD_target_teams_distribute);
12349        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12350     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12351     // 1.2.2 OpenMP Language Terminology
12352     // Structured block - An executable statement with a single entry at the
12353     // top and a single exit at the bottom.
12354     // The point of exit cannot be a branch out of the structured block.
12355     // longjmp() and throw() must not violate the entry/exit criteria.
12356     CS->getCapturedDecl()->setNothrow();
12357   }
12358 
12359   OMPLoopBasedDirective::HelperExprs B;
12360   // In presence of clause 'collapse' with number of loops, it will
12361   // define the nested loops number.
12362   unsigned NestedLoopCount = checkOpenMPLoop(
12363       OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
12364       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
12365       VarsWithImplicitDSA, B);
12366   if (NestedLoopCount == 0)
12367     return StmtError();
12368 
12369   assert((CurContext->isDependentContext() || B.builtAll()) &&
12370          "omp target teams distribute loop exprs were not built");
12371 
12372   setFunctionHasBranchProtectedScope();
12373   return OMPTargetTeamsDistributeDirective::Create(
12374       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12375 }
12376 
ActOnOpenMPTargetTeamsDistributeParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12377 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
12378     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12379     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12380   if (!AStmt)
12381     return StmtError();
12382 
12383   auto *CS = cast<CapturedStmt>(AStmt);
12384   // 1.2.2 OpenMP Language Terminology
12385   // Structured block - An executable statement with a single entry at the
12386   // top and a single exit at the bottom.
12387   // The point of exit cannot be a branch out of the structured block.
12388   // longjmp() and throw() must not violate the entry/exit criteria.
12389   CS->getCapturedDecl()->setNothrow();
12390   for (int ThisCaptureLevel =
12391            getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
12392        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12393     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12394     // 1.2.2 OpenMP Language Terminology
12395     // Structured block - An executable statement with a single entry at the
12396     // top and a single exit at the bottom.
12397     // The point of exit cannot be a branch out of the structured block.
12398     // longjmp() and throw() must not violate the entry/exit criteria.
12399     CS->getCapturedDecl()->setNothrow();
12400   }
12401 
12402   OMPLoopBasedDirective::HelperExprs B;
12403   // In presence of clause 'collapse' with number of loops, it will
12404   // define the nested loops number.
12405   unsigned NestedLoopCount = checkOpenMPLoop(
12406       OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
12407       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
12408       VarsWithImplicitDSA, B);
12409   if (NestedLoopCount == 0)
12410     return StmtError();
12411 
12412   assert((CurContext->isDependentContext() || B.builtAll()) &&
12413          "omp target teams distribute parallel for loop exprs were not built");
12414 
12415   if (!CurContext->isDependentContext()) {
12416     // Finalize the clauses that need pre-built expressions for CodeGen.
12417     for (OMPClause *C : Clauses) {
12418       if (auto *LC = dyn_cast<OMPLinearClause>(C))
12419         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12420                                      B.NumIterations, *this, CurScope,
12421                                      DSAStack))
12422           return StmtError();
12423     }
12424   }
12425 
12426   setFunctionHasBranchProtectedScope();
12427   return OMPTargetTeamsDistributeParallelForDirective::Create(
12428       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
12429       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
12430 }
12431 
ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12432 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
12433     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12434     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12435   if (!AStmt)
12436     return StmtError();
12437 
12438   auto *CS = cast<CapturedStmt>(AStmt);
12439   // 1.2.2 OpenMP Language Terminology
12440   // Structured block - An executable statement with a single entry at the
12441   // top and a single exit at the bottom.
12442   // The point of exit cannot be a branch out of the structured block.
12443   // longjmp() and throw() must not violate the entry/exit criteria.
12444   CS->getCapturedDecl()->setNothrow();
12445   for (int ThisCaptureLevel = getOpenMPCaptureLevels(
12446            OMPD_target_teams_distribute_parallel_for_simd);
12447        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12448     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12449     // 1.2.2 OpenMP Language Terminology
12450     // Structured block - An executable statement with a single entry at the
12451     // top and a single exit at the bottom.
12452     // The point of exit cannot be a branch out of the structured block.
12453     // longjmp() and throw() must not violate the entry/exit criteria.
12454     CS->getCapturedDecl()->setNothrow();
12455   }
12456 
12457   OMPLoopBasedDirective::HelperExprs B;
12458   // In presence of clause 'collapse' with number of loops, it will
12459   // define the nested loops number.
12460   unsigned NestedLoopCount =
12461       checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
12462                       getCollapseNumberExpr(Clauses),
12463                       nullptr /*ordered not a clause on distribute*/, CS, *this,
12464                       *DSAStack, VarsWithImplicitDSA, B);
12465   if (NestedLoopCount == 0)
12466     return StmtError();
12467 
12468   assert((CurContext->isDependentContext() || B.builtAll()) &&
12469          "omp target teams distribute parallel for simd loop exprs were not "
12470          "built");
12471 
12472   if (!CurContext->isDependentContext()) {
12473     // Finalize the clauses that need pre-built expressions for CodeGen.
12474     for (OMPClause *C : Clauses) {
12475       if (auto *LC = dyn_cast<OMPLinearClause>(C))
12476         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12477                                      B.NumIterations, *this, CurScope,
12478                                      DSAStack))
12479           return StmtError();
12480     }
12481   }
12482 
12483   if (checkSimdlenSafelenSpecified(*this, Clauses))
12484     return StmtError();
12485 
12486   setFunctionHasBranchProtectedScope();
12487   return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
12488       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12489 }
12490 
ActOnOpenMPTargetTeamsDistributeSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12491 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
12492     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12493     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12494   if (!AStmt)
12495     return StmtError();
12496 
12497   auto *CS = cast<CapturedStmt>(AStmt);
12498   // 1.2.2 OpenMP Language Terminology
12499   // Structured block - An executable statement with a single entry at the
12500   // top and a single exit at the bottom.
12501   // The point of exit cannot be a branch out of the structured block.
12502   // longjmp() and throw() must not violate the entry/exit criteria.
12503   CS->getCapturedDecl()->setNothrow();
12504   for (int ThisCaptureLevel =
12505            getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
12506        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12507     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12508     // 1.2.2 OpenMP Language Terminology
12509     // Structured block - An executable statement with a single entry at the
12510     // top and a single exit at the bottom.
12511     // The point of exit cannot be a branch out of the structured block.
12512     // longjmp() and throw() must not violate the entry/exit criteria.
12513     CS->getCapturedDecl()->setNothrow();
12514   }
12515 
12516   OMPLoopBasedDirective::HelperExprs B;
12517   // In presence of clause 'collapse' with number of loops, it will
12518   // define the nested loops number.
12519   unsigned NestedLoopCount = checkOpenMPLoop(
12520       OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
12521       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
12522       VarsWithImplicitDSA, B);
12523   if (NestedLoopCount == 0)
12524     return StmtError();
12525 
12526   assert((CurContext->isDependentContext() || B.builtAll()) &&
12527          "omp target teams distribute simd loop exprs were not built");
12528 
12529   if (!CurContext->isDependentContext()) {
12530     // Finalize the clauses that need pre-built expressions for CodeGen.
12531     for (OMPClause *C : Clauses) {
12532       if (auto *LC = dyn_cast<OMPLinearClause>(C))
12533         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12534                                      B.NumIterations, *this, CurScope,
12535                                      DSAStack))
12536           return StmtError();
12537     }
12538   }
12539 
12540   if (checkSimdlenSafelenSpecified(*this, Clauses))
12541     return StmtError();
12542 
12543   setFunctionHasBranchProtectedScope();
12544   return OMPTargetTeamsDistributeSimdDirective::Create(
12545       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12546 }
12547 
ActOnOpenMPTileDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)12548 StmtResult Sema::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses,
12549                                           Stmt *AStmt, SourceLocation StartLoc,
12550                                           SourceLocation EndLoc) {
12551   auto SizesClauses =
12552       OMPExecutableDirective::getClausesOfKind<OMPSizesClause>(Clauses);
12553   if (SizesClauses.empty()) {
12554     // A missing 'sizes' clause is already reported by the parser.
12555     return StmtError();
12556   }
12557   const OMPSizesClause *SizesClause = *SizesClauses.begin();
12558   unsigned NumLoops = SizesClause->getNumSizes();
12559 
12560   // Empty statement should only be possible if there already was an error.
12561   if (!AStmt)
12562     return StmtError();
12563 
12564   // Verify and diagnose loop nest.
12565   SmallVector<OMPLoopBasedDirective::HelperExprs, 4> LoopHelpers(NumLoops);
12566   Stmt *Body = nullptr;
12567   SmallVector<Stmt *, 4> OriginalInits;
12568   if (!OMPLoopBasedDirective::doForAllLoops(
12569           AStmt->IgnoreContainers(), /*TryImperfectlyNestedLoops=*/false,
12570           NumLoops,
12571           [this, &LoopHelpers, &Body, &OriginalInits](unsigned Cnt,
12572                                                       Stmt *CurStmt) {
12573             VarsWithInheritedDSAType TmpDSA;
12574             unsigned SingleNumLoops =
12575                 checkOpenMPLoop(OMPD_tile, nullptr, nullptr, CurStmt, *this,
12576                                 *DSAStack, TmpDSA, LoopHelpers[Cnt]);
12577             if (SingleNumLoops == 0)
12578               return true;
12579             assert(SingleNumLoops == 1 && "Expect single loop iteration space");
12580             if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
12581               OriginalInits.push_back(For->getInit());
12582               Body = For->getBody();
12583             } else {
12584               assert(isa<CXXForRangeStmt>(CurStmt) &&
12585                      "Expected canonical for or range-based for loops.");
12586               auto *CXXFor = cast<CXXForRangeStmt>(CurStmt);
12587               OriginalInits.push_back(CXXFor->getBeginStmt());
12588               Body = CXXFor->getBody();
12589             }
12590             return false;
12591           }))
12592     return StmtError();
12593 
12594   // Delay tiling to when template is completely instantiated.
12595   if (CurContext->isDependentContext())
12596     return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses,
12597                                     NumLoops, AStmt, nullptr, nullptr);
12598 
12599   // Collection of generated variable declaration.
12600   SmallVector<Decl *, 4> PreInits;
12601 
12602   // Create iteration variables for the generated loops.
12603   SmallVector<VarDecl *, 4> FloorIndVars;
12604   SmallVector<VarDecl *, 4> TileIndVars;
12605   FloorIndVars.resize(NumLoops);
12606   TileIndVars.resize(NumLoops);
12607   for (unsigned I = 0; I < NumLoops; ++I) {
12608     OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
12609     if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
12610       PreInits.append(PI->decl_begin(), PI->decl_end());
12611     assert(LoopHelper.Counters.size() == 1 &&
12612            "Expect single-dimensional loop iteration space");
12613     auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
12614     std::string OrigVarName = OrigCntVar->getNameInfo().getAsString();
12615     DeclRefExpr *IterVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
12616     QualType CntTy = IterVarRef->getType();
12617 
12618     // Iteration variable for the floor (i.e. outer) loop.
12619     {
12620       std::string FloorCntName =
12621           (Twine(".floor_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
12622       VarDecl *FloorCntDecl =
12623           buildVarDecl(*this, {}, CntTy, FloorCntName, nullptr, OrigCntVar);
12624       FloorIndVars[I] = FloorCntDecl;
12625     }
12626 
12627     // Iteration variable for the tile (i.e. inner) loop.
12628     {
12629       std::string TileCntName =
12630           (Twine(".tile_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
12631 
12632       // Reuse the iteration variable created by checkOpenMPLoop. It is also
12633       // used by the expressions to derive the original iteration variable's
12634       // value from the logical iteration number.
12635       auto *TileCntDecl = cast<VarDecl>(IterVarRef->getDecl());
12636       TileCntDecl->setDeclName(&PP.getIdentifierTable().get(TileCntName));
12637       TileIndVars[I] = TileCntDecl;
12638     }
12639     if (auto *PI = dyn_cast_or_null<DeclStmt>(OriginalInits[I]))
12640       PreInits.append(PI->decl_begin(), PI->decl_end());
12641     // Gather declarations for the data members used as counters.
12642     for (Expr *CounterRef : LoopHelper.Counters) {
12643       auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
12644       if (isa<OMPCapturedExprDecl>(CounterDecl))
12645         PreInits.push_back(CounterDecl);
12646     }
12647   }
12648 
12649   // Once the original iteration values are set, append the innermost body.
12650   Stmt *Inner = Body;
12651 
12652   // Create tile loops from the inside to the outside.
12653   for (int I = NumLoops - 1; I >= 0; --I) {
12654     OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
12655     Expr *NumIterations = LoopHelper.NumIterations;
12656     auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
12657     QualType CntTy = OrigCntVar->getType();
12658     Expr *DimTileSize = SizesClause->getSizesRefs()[I];
12659     Scope *CurScope = getCurScope();
12660 
12661     // Commonly used variables.
12662     DeclRefExpr *TileIV = buildDeclRefExpr(*this, TileIndVars[I], CntTy,
12663                                            OrigCntVar->getExprLoc());
12664     DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
12665                                             OrigCntVar->getExprLoc());
12666 
12667     // For init-statement: auto .tile.iv = .floor.iv
12668     AddInitializerToDecl(TileIndVars[I], DefaultLvalueConversion(FloorIV).get(),
12669                          /*DirectInit=*/false);
12670     Decl *CounterDecl = TileIndVars[I];
12671     StmtResult InitStmt = new (Context)
12672         DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
12673                  OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
12674     if (!InitStmt.isUsable())
12675       return StmtError();
12676 
12677     // For cond-expression: .tile.iv < min(.floor.iv + DimTileSize,
12678     // NumIterations)
12679     ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
12680                                       BO_Add, FloorIV, DimTileSize);
12681     if (!EndOfTile.isUsable())
12682       return StmtError();
12683     ExprResult IsPartialTile =
12684         BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT,
12685                    NumIterations, EndOfTile.get());
12686     if (!IsPartialTile.isUsable())
12687       return StmtError();
12688     ExprResult MinTileAndIterSpace = ActOnConditionalOp(
12689         LoopHelper.Cond->getBeginLoc(), LoopHelper.Cond->getEndLoc(),
12690         IsPartialTile.get(), NumIterations, EndOfTile.get());
12691     if (!MinTileAndIterSpace.isUsable())
12692       return StmtError();
12693     ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
12694                                      BO_LT, TileIV, MinTileAndIterSpace.get());
12695     if (!CondExpr.isUsable())
12696       return StmtError();
12697 
12698     // For incr-statement: ++.tile.iv
12699     ExprResult IncrStmt =
12700         BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), UO_PreInc, TileIV);
12701     if (!IncrStmt.isUsable())
12702       return StmtError();
12703 
12704     // Statements to set the original iteration variable's value from the
12705     // logical iteration number.
12706     // Generated for loop is:
12707     // Original_for_init;
12708     // for (auto .tile.iv = .floor.iv; .tile.iv < min(.floor.iv + DimTileSize,
12709     // NumIterations); ++.tile.iv) {
12710     //   Original_Body;
12711     //   Original_counter_update;
12712     // }
12713     // FIXME: If the innermost body is an loop itself, inserting these
12714     // statements stops it being recognized  as a perfectly nested loop (e.g.
12715     // for applying tiling again). If this is the case, sink the expressions
12716     // further into the inner loop.
12717     SmallVector<Stmt *, 4> BodyParts;
12718     BodyParts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
12719     BodyParts.push_back(Inner);
12720     Inner = CompoundStmt::Create(Context, BodyParts, Inner->getBeginLoc(),
12721                                  Inner->getEndLoc());
12722     Inner = new (Context)
12723         ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
12724                 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
12725                 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
12726   }
12727 
12728   // Create floor loops from the inside to the outside.
12729   for (int I = NumLoops - 1; I >= 0; --I) {
12730     auto &LoopHelper = LoopHelpers[I];
12731     Expr *NumIterations = LoopHelper.NumIterations;
12732     DeclRefExpr *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
12733     QualType CntTy = OrigCntVar->getType();
12734     Expr *DimTileSize = SizesClause->getSizesRefs()[I];
12735     Scope *CurScope = getCurScope();
12736 
12737     // Commonly used variables.
12738     DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
12739                                             OrigCntVar->getExprLoc());
12740 
12741     // For init-statement: auto .floor.iv = 0
12742     AddInitializerToDecl(
12743         FloorIndVars[I],
12744         ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
12745         /*DirectInit=*/false);
12746     Decl *CounterDecl = FloorIndVars[I];
12747     StmtResult InitStmt = new (Context)
12748         DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
12749                  OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
12750     if (!InitStmt.isUsable())
12751       return StmtError();
12752 
12753     // For cond-expression: .floor.iv < NumIterations
12754     ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
12755                                      BO_LT, FloorIV, NumIterations);
12756     if (!CondExpr.isUsable())
12757       return StmtError();
12758 
12759     // For incr-statement: .floor.iv += DimTileSize
12760     ExprResult IncrStmt = BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(),
12761                                      BO_AddAssign, FloorIV, DimTileSize);
12762     if (!IncrStmt.isUsable())
12763       return StmtError();
12764 
12765     Inner = new (Context)
12766         ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
12767                 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
12768                 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
12769   }
12770 
12771   return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, NumLoops,
12772                                   AStmt, Inner,
12773                                   buildPreInits(Context, PreInits));
12774 }
12775 
ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,Expr * Expr,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)12776 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
12777                                              SourceLocation StartLoc,
12778                                              SourceLocation LParenLoc,
12779                                              SourceLocation EndLoc) {
12780   OMPClause *Res = nullptr;
12781   switch (Kind) {
12782   case OMPC_final:
12783     Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
12784     break;
12785   case OMPC_num_threads:
12786     Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
12787     break;
12788   case OMPC_safelen:
12789     Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
12790     break;
12791   case OMPC_simdlen:
12792     Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
12793     break;
12794   case OMPC_allocator:
12795     Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
12796     break;
12797   case OMPC_collapse:
12798     Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
12799     break;
12800   case OMPC_ordered:
12801     Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
12802     break;
12803   case OMPC_num_teams:
12804     Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
12805     break;
12806   case OMPC_thread_limit:
12807     Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
12808     break;
12809   case OMPC_priority:
12810     Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
12811     break;
12812   case OMPC_grainsize:
12813     Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
12814     break;
12815   case OMPC_num_tasks:
12816     Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
12817     break;
12818   case OMPC_hint:
12819     Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
12820     break;
12821   case OMPC_depobj:
12822     Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc);
12823     break;
12824   case OMPC_detach:
12825     Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc);
12826     break;
12827   case OMPC_novariants:
12828     Res = ActOnOpenMPNovariantsClause(Expr, StartLoc, LParenLoc, EndLoc);
12829     break;
12830   case OMPC_nocontext:
12831     Res = ActOnOpenMPNocontextClause(Expr, StartLoc, LParenLoc, EndLoc);
12832     break;
12833   case OMPC_filter:
12834     Res = ActOnOpenMPFilterClause(Expr, StartLoc, LParenLoc, EndLoc);
12835     break;
12836   case OMPC_device:
12837   case OMPC_if:
12838   case OMPC_default:
12839   case OMPC_proc_bind:
12840   case OMPC_schedule:
12841   case OMPC_private:
12842   case OMPC_firstprivate:
12843   case OMPC_lastprivate:
12844   case OMPC_shared:
12845   case OMPC_reduction:
12846   case OMPC_task_reduction:
12847   case OMPC_in_reduction:
12848   case OMPC_linear:
12849   case OMPC_aligned:
12850   case OMPC_copyin:
12851   case OMPC_copyprivate:
12852   case OMPC_nowait:
12853   case OMPC_untied:
12854   case OMPC_mergeable:
12855   case OMPC_threadprivate:
12856   case OMPC_sizes:
12857   case OMPC_allocate:
12858   case OMPC_flush:
12859   case OMPC_read:
12860   case OMPC_write:
12861   case OMPC_update:
12862   case OMPC_capture:
12863   case OMPC_seq_cst:
12864   case OMPC_acq_rel:
12865   case OMPC_acquire:
12866   case OMPC_release:
12867   case OMPC_relaxed:
12868   case OMPC_depend:
12869   case OMPC_threads:
12870   case OMPC_simd:
12871   case OMPC_map:
12872   case OMPC_nogroup:
12873   case OMPC_dist_schedule:
12874   case OMPC_defaultmap:
12875   case OMPC_unknown:
12876   case OMPC_uniform:
12877   case OMPC_to:
12878   case OMPC_from:
12879   case OMPC_use_device_ptr:
12880   case OMPC_use_device_addr:
12881   case OMPC_is_device_ptr:
12882   case OMPC_unified_address:
12883   case OMPC_unified_shared_memory:
12884   case OMPC_reverse_offload:
12885   case OMPC_dynamic_allocators:
12886   case OMPC_atomic_default_mem_order:
12887   case OMPC_device_type:
12888   case OMPC_match:
12889   case OMPC_nontemporal:
12890   case OMPC_order:
12891   case OMPC_destroy:
12892   case OMPC_inclusive:
12893   case OMPC_exclusive:
12894   case OMPC_uses_allocators:
12895   case OMPC_affinity:
12896   default:
12897     llvm_unreachable("Clause is not allowed.");
12898   }
12899   return Res;
12900 }
12901 
12902 // An OpenMP directive such as 'target parallel' has two captured regions:
12903 // for the 'target' and 'parallel' respectively.  This function returns
12904 // the region in which to capture expressions associated with a clause.
12905 // A return value of OMPD_unknown signifies that the expression should not
12906 // be captured.
getOpenMPCaptureRegionForClause(OpenMPDirectiveKind DKind,OpenMPClauseKind CKind,unsigned OpenMPVersion,OpenMPDirectiveKind NameModifier=OMPD_unknown)12907 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
12908     OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion,
12909     OpenMPDirectiveKind NameModifier = OMPD_unknown) {
12910   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
12911   switch (CKind) {
12912   case OMPC_if:
12913     switch (DKind) {
12914     case OMPD_target_parallel_for_simd:
12915       if (OpenMPVersion >= 50 &&
12916           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
12917         CaptureRegion = OMPD_parallel;
12918         break;
12919       }
12920       LLVM_FALLTHROUGH;
12921     case OMPD_target_parallel:
12922     case OMPD_target_parallel_for:
12923       // If this clause applies to the nested 'parallel' region, capture within
12924       // the 'target' region, otherwise do not capture.
12925       if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
12926         CaptureRegion = OMPD_target;
12927       break;
12928     case OMPD_target_teams_distribute_parallel_for_simd:
12929       if (OpenMPVersion >= 50 &&
12930           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
12931         CaptureRegion = OMPD_parallel;
12932         break;
12933       }
12934       LLVM_FALLTHROUGH;
12935     case OMPD_target_teams_distribute_parallel_for:
12936       // If this clause applies to the nested 'parallel' region, capture within
12937       // the 'teams' region, otherwise do not capture.
12938       if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
12939         CaptureRegion = OMPD_teams;
12940       break;
12941     case OMPD_teams_distribute_parallel_for_simd:
12942       if (OpenMPVersion >= 50 &&
12943           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
12944         CaptureRegion = OMPD_parallel;
12945         break;
12946       }
12947       LLVM_FALLTHROUGH;
12948     case OMPD_teams_distribute_parallel_for:
12949       CaptureRegion = OMPD_teams;
12950       break;
12951     case OMPD_target_update:
12952     case OMPD_target_enter_data:
12953     case OMPD_target_exit_data:
12954       CaptureRegion = OMPD_task;
12955       break;
12956     case OMPD_parallel_master_taskloop:
12957       if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
12958         CaptureRegion = OMPD_parallel;
12959       break;
12960     case OMPD_parallel_master_taskloop_simd:
12961       if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
12962           NameModifier == OMPD_taskloop) {
12963         CaptureRegion = OMPD_parallel;
12964         break;
12965       }
12966       if (OpenMPVersion <= 45)
12967         break;
12968       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
12969         CaptureRegion = OMPD_taskloop;
12970       break;
12971     case OMPD_parallel_for_simd:
12972       if (OpenMPVersion <= 45)
12973         break;
12974       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
12975         CaptureRegion = OMPD_parallel;
12976       break;
12977     case OMPD_taskloop_simd:
12978     case OMPD_master_taskloop_simd:
12979       if (OpenMPVersion <= 45)
12980         break;
12981       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
12982         CaptureRegion = OMPD_taskloop;
12983       break;
12984     case OMPD_distribute_parallel_for_simd:
12985       if (OpenMPVersion <= 45)
12986         break;
12987       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
12988         CaptureRegion = OMPD_parallel;
12989       break;
12990     case OMPD_target_simd:
12991       if (OpenMPVersion >= 50 &&
12992           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
12993         CaptureRegion = OMPD_target;
12994       break;
12995     case OMPD_teams_distribute_simd:
12996     case OMPD_target_teams_distribute_simd:
12997       if (OpenMPVersion >= 50 &&
12998           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
12999         CaptureRegion = OMPD_teams;
13000       break;
13001     case OMPD_cancel:
13002     case OMPD_parallel:
13003     case OMPD_parallel_master:
13004     case OMPD_parallel_sections:
13005     case OMPD_parallel_for:
13006     case OMPD_target:
13007     case OMPD_target_teams:
13008     case OMPD_target_teams_distribute:
13009     case OMPD_distribute_parallel_for:
13010     case OMPD_task:
13011     case OMPD_taskloop:
13012     case OMPD_master_taskloop:
13013     case OMPD_target_data:
13014     case OMPD_simd:
13015     case OMPD_for_simd:
13016     case OMPD_distribute_simd:
13017       // Do not capture if-clause expressions.
13018       break;
13019     case OMPD_threadprivate:
13020     case OMPD_allocate:
13021     case OMPD_taskyield:
13022     case OMPD_barrier:
13023     case OMPD_taskwait:
13024     case OMPD_cancellation_point:
13025     case OMPD_flush:
13026     case OMPD_depobj:
13027     case OMPD_scan:
13028     case OMPD_declare_reduction:
13029     case OMPD_declare_mapper:
13030     case OMPD_declare_simd:
13031     case OMPD_declare_variant:
13032     case OMPD_begin_declare_variant:
13033     case OMPD_end_declare_variant:
13034     case OMPD_declare_target:
13035     case OMPD_end_declare_target:
13036     case OMPD_teams:
13037     case OMPD_tile:
13038     case OMPD_for:
13039     case OMPD_sections:
13040     case OMPD_section:
13041     case OMPD_single:
13042     case OMPD_master:
13043     case OMPD_masked:
13044     case OMPD_critical:
13045     case OMPD_taskgroup:
13046     case OMPD_distribute:
13047     case OMPD_ordered:
13048     case OMPD_atomic:
13049     case OMPD_teams_distribute:
13050     case OMPD_requires:
13051       llvm_unreachable("Unexpected OpenMP directive with if-clause");
13052     case OMPD_unknown:
13053     default:
13054       llvm_unreachable("Unknown OpenMP directive");
13055     }
13056     break;
13057   case OMPC_num_threads:
13058     switch (DKind) {
13059     case OMPD_target_parallel:
13060     case OMPD_target_parallel_for:
13061     case OMPD_target_parallel_for_simd:
13062       CaptureRegion = OMPD_target;
13063       break;
13064     case OMPD_teams_distribute_parallel_for:
13065     case OMPD_teams_distribute_parallel_for_simd:
13066     case OMPD_target_teams_distribute_parallel_for:
13067     case OMPD_target_teams_distribute_parallel_for_simd:
13068       CaptureRegion = OMPD_teams;
13069       break;
13070     case OMPD_parallel:
13071     case OMPD_parallel_master:
13072     case OMPD_parallel_sections:
13073     case OMPD_parallel_for:
13074     case OMPD_parallel_for_simd:
13075     case OMPD_distribute_parallel_for:
13076     case OMPD_distribute_parallel_for_simd:
13077     case OMPD_parallel_master_taskloop:
13078     case OMPD_parallel_master_taskloop_simd:
13079       // Do not capture num_threads-clause expressions.
13080       break;
13081     case OMPD_target_data:
13082     case OMPD_target_enter_data:
13083     case OMPD_target_exit_data:
13084     case OMPD_target_update:
13085     case OMPD_target:
13086     case OMPD_target_simd:
13087     case OMPD_target_teams:
13088     case OMPD_target_teams_distribute:
13089     case OMPD_target_teams_distribute_simd:
13090     case OMPD_cancel:
13091     case OMPD_task:
13092     case OMPD_taskloop:
13093     case OMPD_taskloop_simd:
13094     case OMPD_master_taskloop:
13095     case OMPD_master_taskloop_simd:
13096     case OMPD_threadprivate:
13097     case OMPD_allocate:
13098     case OMPD_taskyield:
13099     case OMPD_barrier:
13100     case OMPD_taskwait:
13101     case OMPD_cancellation_point:
13102     case OMPD_flush:
13103     case OMPD_depobj:
13104     case OMPD_scan:
13105     case OMPD_declare_reduction:
13106     case OMPD_declare_mapper:
13107     case OMPD_declare_simd:
13108     case OMPD_declare_variant:
13109     case OMPD_begin_declare_variant:
13110     case OMPD_end_declare_variant:
13111     case OMPD_declare_target:
13112     case OMPD_end_declare_target:
13113     case OMPD_teams:
13114     case OMPD_simd:
13115     case OMPD_tile:
13116     case OMPD_for:
13117     case OMPD_for_simd:
13118     case OMPD_sections:
13119     case OMPD_section:
13120     case OMPD_single:
13121     case OMPD_master:
13122     case OMPD_masked:
13123     case OMPD_critical:
13124     case OMPD_taskgroup:
13125     case OMPD_distribute:
13126     case OMPD_ordered:
13127     case OMPD_atomic:
13128     case OMPD_distribute_simd:
13129     case OMPD_teams_distribute:
13130     case OMPD_teams_distribute_simd:
13131     case OMPD_requires:
13132       llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
13133     case OMPD_unknown:
13134     default:
13135       llvm_unreachable("Unknown OpenMP directive");
13136     }
13137     break;
13138   case OMPC_num_teams:
13139     switch (DKind) {
13140     case OMPD_target_teams:
13141     case OMPD_target_teams_distribute:
13142     case OMPD_target_teams_distribute_simd:
13143     case OMPD_target_teams_distribute_parallel_for:
13144     case OMPD_target_teams_distribute_parallel_for_simd:
13145       CaptureRegion = OMPD_target;
13146       break;
13147     case OMPD_teams_distribute_parallel_for:
13148     case OMPD_teams_distribute_parallel_for_simd:
13149     case OMPD_teams:
13150     case OMPD_teams_distribute:
13151     case OMPD_teams_distribute_simd:
13152       // Do not capture num_teams-clause expressions.
13153       break;
13154     case OMPD_distribute_parallel_for:
13155     case OMPD_distribute_parallel_for_simd:
13156     case OMPD_task:
13157     case OMPD_taskloop:
13158     case OMPD_taskloop_simd:
13159     case OMPD_master_taskloop:
13160     case OMPD_master_taskloop_simd:
13161     case OMPD_parallel_master_taskloop:
13162     case OMPD_parallel_master_taskloop_simd:
13163     case OMPD_target_data:
13164     case OMPD_target_enter_data:
13165     case OMPD_target_exit_data:
13166     case OMPD_target_update:
13167     case OMPD_cancel:
13168     case OMPD_parallel:
13169     case OMPD_parallel_master:
13170     case OMPD_parallel_sections:
13171     case OMPD_parallel_for:
13172     case OMPD_parallel_for_simd:
13173     case OMPD_target:
13174     case OMPD_target_simd:
13175     case OMPD_target_parallel:
13176     case OMPD_target_parallel_for:
13177     case OMPD_target_parallel_for_simd:
13178     case OMPD_threadprivate:
13179     case OMPD_allocate:
13180     case OMPD_taskyield:
13181     case OMPD_barrier:
13182     case OMPD_taskwait:
13183     case OMPD_cancellation_point:
13184     case OMPD_flush:
13185     case OMPD_depobj:
13186     case OMPD_scan:
13187     case OMPD_declare_reduction:
13188     case OMPD_declare_mapper:
13189     case OMPD_declare_simd:
13190     case OMPD_declare_variant:
13191     case OMPD_begin_declare_variant:
13192     case OMPD_end_declare_variant:
13193     case OMPD_declare_target:
13194     case OMPD_end_declare_target:
13195     case OMPD_simd:
13196     case OMPD_tile:
13197     case OMPD_for:
13198     case OMPD_for_simd:
13199     case OMPD_sections:
13200     case OMPD_section:
13201     case OMPD_single:
13202     case OMPD_master:
13203     case OMPD_masked:
13204     case OMPD_critical:
13205     case OMPD_taskgroup:
13206     case OMPD_distribute:
13207     case OMPD_ordered:
13208     case OMPD_atomic:
13209     case OMPD_distribute_simd:
13210     case OMPD_requires:
13211       llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
13212     case OMPD_unknown:
13213     default:
13214       llvm_unreachable("Unknown OpenMP directive");
13215     }
13216     break;
13217   case OMPC_thread_limit:
13218     switch (DKind) {
13219     case OMPD_target_teams:
13220     case OMPD_target_teams_distribute:
13221     case OMPD_target_teams_distribute_simd:
13222     case OMPD_target_teams_distribute_parallel_for:
13223     case OMPD_target_teams_distribute_parallel_for_simd:
13224       CaptureRegion = OMPD_target;
13225       break;
13226     case OMPD_teams_distribute_parallel_for:
13227     case OMPD_teams_distribute_parallel_for_simd:
13228     case OMPD_teams:
13229     case OMPD_teams_distribute:
13230     case OMPD_teams_distribute_simd:
13231       // Do not capture thread_limit-clause expressions.
13232       break;
13233     case OMPD_distribute_parallel_for:
13234     case OMPD_distribute_parallel_for_simd:
13235     case OMPD_task:
13236     case OMPD_taskloop:
13237     case OMPD_taskloop_simd:
13238     case OMPD_master_taskloop:
13239     case OMPD_master_taskloop_simd:
13240     case OMPD_parallel_master_taskloop:
13241     case OMPD_parallel_master_taskloop_simd:
13242     case OMPD_target_data:
13243     case OMPD_target_enter_data:
13244     case OMPD_target_exit_data:
13245     case OMPD_target_update:
13246     case OMPD_cancel:
13247     case OMPD_parallel:
13248     case OMPD_parallel_master:
13249     case OMPD_parallel_sections:
13250     case OMPD_parallel_for:
13251     case OMPD_parallel_for_simd:
13252     case OMPD_target:
13253     case OMPD_target_simd:
13254     case OMPD_target_parallel:
13255     case OMPD_target_parallel_for:
13256     case OMPD_target_parallel_for_simd:
13257     case OMPD_threadprivate:
13258     case OMPD_allocate:
13259     case OMPD_taskyield:
13260     case OMPD_barrier:
13261     case OMPD_taskwait:
13262     case OMPD_cancellation_point:
13263     case OMPD_flush:
13264     case OMPD_depobj:
13265     case OMPD_scan:
13266     case OMPD_declare_reduction:
13267     case OMPD_declare_mapper:
13268     case OMPD_declare_simd:
13269     case OMPD_declare_variant:
13270     case OMPD_begin_declare_variant:
13271     case OMPD_end_declare_variant:
13272     case OMPD_declare_target:
13273     case OMPD_end_declare_target:
13274     case OMPD_simd:
13275     case OMPD_tile:
13276     case OMPD_for:
13277     case OMPD_for_simd:
13278     case OMPD_sections:
13279     case OMPD_section:
13280     case OMPD_single:
13281     case OMPD_master:
13282     case OMPD_masked:
13283     case OMPD_critical:
13284     case OMPD_taskgroup:
13285     case OMPD_distribute:
13286     case OMPD_ordered:
13287     case OMPD_atomic:
13288     case OMPD_distribute_simd:
13289     case OMPD_requires:
13290       llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
13291     case OMPD_unknown:
13292     default:
13293       llvm_unreachable("Unknown OpenMP directive");
13294     }
13295     break;
13296   case OMPC_schedule:
13297     switch (DKind) {
13298     case OMPD_parallel_for:
13299     case OMPD_parallel_for_simd:
13300     case OMPD_distribute_parallel_for:
13301     case OMPD_distribute_parallel_for_simd:
13302     case OMPD_teams_distribute_parallel_for:
13303     case OMPD_teams_distribute_parallel_for_simd:
13304     case OMPD_target_parallel_for:
13305     case OMPD_target_parallel_for_simd:
13306     case OMPD_target_teams_distribute_parallel_for:
13307     case OMPD_target_teams_distribute_parallel_for_simd:
13308       CaptureRegion = OMPD_parallel;
13309       break;
13310     case OMPD_for:
13311     case OMPD_for_simd:
13312       // Do not capture schedule-clause expressions.
13313       break;
13314     case OMPD_task:
13315     case OMPD_taskloop:
13316     case OMPD_taskloop_simd:
13317     case OMPD_master_taskloop:
13318     case OMPD_master_taskloop_simd:
13319     case OMPD_parallel_master_taskloop:
13320     case OMPD_parallel_master_taskloop_simd:
13321     case OMPD_target_data:
13322     case OMPD_target_enter_data:
13323     case OMPD_target_exit_data:
13324     case OMPD_target_update:
13325     case OMPD_teams:
13326     case OMPD_teams_distribute:
13327     case OMPD_teams_distribute_simd:
13328     case OMPD_target_teams_distribute:
13329     case OMPD_target_teams_distribute_simd:
13330     case OMPD_target:
13331     case OMPD_target_simd:
13332     case OMPD_target_parallel:
13333     case OMPD_cancel:
13334     case OMPD_parallel:
13335     case OMPD_parallel_master:
13336     case OMPD_parallel_sections:
13337     case OMPD_threadprivate:
13338     case OMPD_allocate:
13339     case OMPD_taskyield:
13340     case OMPD_barrier:
13341     case OMPD_taskwait:
13342     case OMPD_cancellation_point:
13343     case OMPD_flush:
13344     case OMPD_depobj:
13345     case OMPD_scan:
13346     case OMPD_declare_reduction:
13347     case OMPD_declare_mapper:
13348     case OMPD_declare_simd:
13349     case OMPD_declare_variant:
13350     case OMPD_begin_declare_variant:
13351     case OMPD_end_declare_variant:
13352     case OMPD_declare_target:
13353     case OMPD_end_declare_target:
13354     case OMPD_simd:
13355     case OMPD_tile:
13356     case OMPD_sections:
13357     case OMPD_section:
13358     case OMPD_single:
13359     case OMPD_master:
13360     case OMPD_masked:
13361     case OMPD_critical:
13362     case OMPD_taskgroup:
13363     case OMPD_distribute:
13364     case OMPD_ordered:
13365     case OMPD_atomic:
13366     case OMPD_distribute_simd:
13367     case OMPD_target_teams:
13368     case OMPD_requires:
13369       llvm_unreachable("Unexpected OpenMP directive with schedule clause");
13370     case OMPD_unknown:
13371     default:
13372       llvm_unreachable("Unknown OpenMP directive");
13373     }
13374     break;
13375   case OMPC_dist_schedule:
13376     switch (DKind) {
13377     case OMPD_teams_distribute_parallel_for:
13378     case OMPD_teams_distribute_parallel_for_simd:
13379     case OMPD_teams_distribute:
13380     case OMPD_teams_distribute_simd:
13381     case OMPD_target_teams_distribute_parallel_for:
13382     case OMPD_target_teams_distribute_parallel_for_simd:
13383     case OMPD_target_teams_distribute:
13384     case OMPD_target_teams_distribute_simd:
13385       CaptureRegion = OMPD_teams;
13386       break;
13387     case OMPD_distribute_parallel_for:
13388     case OMPD_distribute_parallel_for_simd:
13389     case OMPD_distribute:
13390     case OMPD_distribute_simd:
13391       // Do not capture dist_schedule-clause expressions.
13392       break;
13393     case OMPD_parallel_for:
13394     case OMPD_parallel_for_simd:
13395     case OMPD_target_parallel_for_simd:
13396     case OMPD_target_parallel_for:
13397     case OMPD_task:
13398     case OMPD_taskloop:
13399     case OMPD_taskloop_simd:
13400     case OMPD_master_taskloop:
13401     case OMPD_master_taskloop_simd:
13402     case OMPD_parallel_master_taskloop:
13403     case OMPD_parallel_master_taskloop_simd:
13404     case OMPD_target_data:
13405     case OMPD_target_enter_data:
13406     case OMPD_target_exit_data:
13407     case OMPD_target_update:
13408     case OMPD_teams:
13409     case OMPD_target:
13410     case OMPD_target_simd:
13411     case OMPD_target_parallel:
13412     case OMPD_cancel:
13413     case OMPD_parallel:
13414     case OMPD_parallel_master:
13415     case OMPD_parallel_sections:
13416     case OMPD_threadprivate:
13417     case OMPD_allocate:
13418     case OMPD_taskyield:
13419     case OMPD_barrier:
13420     case OMPD_taskwait:
13421     case OMPD_cancellation_point:
13422     case OMPD_flush:
13423     case OMPD_depobj:
13424     case OMPD_scan:
13425     case OMPD_declare_reduction:
13426     case OMPD_declare_mapper:
13427     case OMPD_declare_simd:
13428     case OMPD_declare_variant:
13429     case OMPD_begin_declare_variant:
13430     case OMPD_end_declare_variant:
13431     case OMPD_declare_target:
13432     case OMPD_end_declare_target:
13433     case OMPD_simd:
13434     case OMPD_tile:
13435     case OMPD_for:
13436     case OMPD_for_simd:
13437     case OMPD_sections:
13438     case OMPD_section:
13439     case OMPD_single:
13440     case OMPD_master:
13441     case OMPD_masked:
13442     case OMPD_critical:
13443     case OMPD_taskgroup:
13444     case OMPD_ordered:
13445     case OMPD_atomic:
13446     case OMPD_target_teams:
13447     case OMPD_requires:
13448       llvm_unreachable("Unexpected OpenMP directive with dist_schedule clause");
13449     case OMPD_unknown:
13450     default:
13451       llvm_unreachable("Unknown OpenMP directive");
13452     }
13453     break;
13454   case OMPC_device:
13455     switch (DKind) {
13456     case OMPD_target_update:
13457     case OMPD_target_enter_data:
13458     case OMPD_target_exit_data:
13459     case OMPD_target:
13460     case OMPD_target_simd:
13461     case OMPD_target_teams:
13462     case OMPD_target_parallel:
13463     case OMPD_target_teams_distribute:
13464     case OMPD_target_teams_distribute_simd:
13465     case OMPD_target_parallel_for:
13466     case OMPD_target_parallel_for_simd:
13467     case OMPD_target_teams_distribute_parallel_for:
13468     case OMPD_target_teams_distribute_parallel_for_simd:
13469     case OMPD_dispatch:
13470       CaptureRegion = OMPD_task;
13471       break;
13472     case OMPD_target_data:
13473     case OMPD_interop:
13474       // Do not capture device-clause expressions.
13475       break;
13476     case OMPD_teams_distribute_parallel_for:
13477     case OMPD_teams_distribute_parallel_for_simd:
13478     case OMPD_teams:
13479     case OMPD_teams_distribute:
13480     case OMPD_teams_distribute_simd:
13481     case OMPD_distribute_parallel_for:
13482     case OMPD_distribute_parallel_for_simd:
13483     case OMPD_task:
13484     case OMPD_taskloop:
13485     case OMPD_taskloop_simd:
13486     case OMPD_master_taskloop:
13487     case OMPD_master_taskloop_simd:
13488     case OMPD_parallel_master_taskloop:
13489     case OMPD_parallel_master_taskloop_simd:
13490     case OMPD_cancel:
13491     case OMPD_parallel:
13492     case OMPD_parallel_master:
13493     case OMPD_parallel_sections:
13494     case OMPD_parallel_for:
13495     case OMPD_parallel_for_simd:
13496     case OMPD_threadprivate:
13497     case OMPD_allocate:
13498     case OMPD_taskyield:
13499     case OMPD_barrier:
13500     case OMPD_taskwait:
13501     case OMPD_cancellation_point:
13502     case OMPD_flush:
13503     case OMPD_depobj:
13504     case OMPD_scan:
13505     case OMPD_declare_reduction:
13506     case OMPD_declare_mapper:
13507     case OMPD_declare_simd:
13508     case OMPD_declare_variant:
13509     case OMPD_begin_declare_variant:
13510     case OMPD_end_declare_variant:
13511     case OMPD_declare_target:
13512     case OMPD_end_declare_target:
13513     case OMPD_simd:
13514     case OMPD_tile:
13515     case OMPD_for:
13516     case OMPD_for_simd:
13517     case OMPD_sections:
13518     case OMPD_section:
13519     case OMPD_single:
13520     case OMPD_master:
13521     case OMPD_masked:
13522     case OMPD_critical:
13523     case OMPD_taskgroup:
13524     case OMPD_distribute:
13525     case OMPD_ordered:
13526     case OMPD_atomic:
13527     case OMPD_distribute_simd:
13528     case OMPD_requires:
13529       llvm_unreachable("Unexpected OpenMP directive with device-clause");
13530     case OMPD_unknown:
13531     default:
13532       llvm_unreachable("Unknown OpenMP directive");
13533     }
13534     break;
13535   case OMPC_grainsize:
13536   case OMPC_num_tasks:
13537   case OMPC_final:
13538   case OMPC_priority:
13539     switch (DKind) {
13540     case OMPD_task:
13541     case OMPD_taskloop:
13542     case OMPD_taskloop_simd:
13543     case OMPD_master_taskloop:
13544     case OMPD_master_taskloop_simd:
13545       break;
13546     case OMPD_parallel_master_taskloop:
13547     case OMPD_parallel_master_taskloop_simd:
13548       CaptureRegion = OMPD_parallel;
13549       break;
13550     case OMPD_target_update:
13551     case OMPD_target_enter_data:
13552     case OMPD_target_exit_data:
13553     case OMPD_target:
13554     case OMPD_target_simd:
13555     case OMPD_target_teams:
13556     case OMPD_target_parallel:
13557     case OMPD_target_teams_distribute:
13558     case OMPD_target_teams_distribute_simd:
13559     case OMPD_target_parallel_for:
13560     case OMPD_target_parallel_for_simd:
13561     case OMPD_target_teams_distribute_parallel_for:
13562     case OMPD_target_teams_distribute_parallel_for_simd:
13563     case OMPD_target_data:
13564     case OMPD_teams_distribute_parallel_for:
13565     case OMPD_teams_distribute_parallel_for_simd:
13566     case OMPD_teams:
13567     case OMPD_teams_distribute:
13568     case OMPD_teams_distribute_simd:
13569     case OMPD_distribute_parallel_for:
13570     case OMPD_distribute_parallel_for_simd:
13571     case OMPD_cancel:
13572     case OMPD_parallel:
13573     case OMPD_parallel_master:
13574     case OMPD_parallel_sections:
13575     case OMPD_parallel_for:
13576     case OMPD_parallel_for_simd:
13577     case OMPD_threadprivate:
13578     case OMPD_allocate:
13579     case OMPD_taskyield:
13580     case OMPD_barrier:
13581     case OMPD_taskwait:
13582     case OMPD_cancellation_point:
13583     case OMPD_flush:
13584     case OMPD_depobj:
13585     case OMPD_scan:
13586     case OMPD_declare_reduction:
13587     case OMPD_declare_mapper:
13588     case OMPD_declare_simd:
13589     case OMPD_declare_variant:
13590     case OMPD_begin_declare_variant:
13591     case OMPD_end_declare_variant:
13592     case OMPD_declare_target:
13593     case OMPD_end_declare_target:
13594     case OMPD_simd:
13595     case OMPD_tile:
13596     case OMPD_for:
13597     case OMPD_for_simd:
13598     case OMPD_sections:
13599     case OMPD_section:
13600     case OMPD_single:
13601     case OMPD_master:
13602     case OMPD_masked:
13603     case OMPD_critical:
13604     case OMPD_taskgroup:
13605     case OMPD_distribute:
13606     case OMPD_ordered:
13607     case OMPD_atomic:
13608     case OMPD_distribute_simd:
13609     case OMPD_requires:
13610       llvm_unreachable("Unexpected OpenMP directive with grainsize-clause");
13611     case OMPD_unknown:
13612     default:
13613       llvm_unreachable("Unknown OpenMP directive");
13614     }
13615     break;
13616   case OMPC_novariants:
13617   case OMPC_nocontext:
13618     switch (DKind) {
13619     case OMPD_dispatch:
13620       CaptureRegion = OMPD_task;
13621       break;
13622     default:
13623       llvm_unreachable("Unexpected OpenMP directive");
13624     }
13625     break;
13626   case OMPC_filter:
13627     // Do not capture filter-clause expressions.
13628     break;
13629   case OMPC_firstprivate:
13630   case OMPC_lastprivate:
13631   case OMPC_reduction:
13632   case OMPC_task_reduction:
13633   case OMPC_in_reduction:
13634   case OMPC_linear:
13635   case OMPC_default:
13636   case OMPC_proc_bind:
13637   case OMPC_safelen:
13638   case OMPC_simdlen:
13639   case OMPC_sizes:
13640   case OMPC_allocator:
13641   case OMPC_collapse:
13642   case OMPC_private:
13643   case OMPC_shared:
13644   case OMPC_aligned:
13645   case OMPC_copyin:
13646   case OMPC_copyprivate:
13647   case OMPC_ordered:
13648   case OMPC_nowait:
13649   case OMPC_untied:
13650   case OMPC_mergeable:
13651   case OMPC_threadprivate:
13652   case OMPC_allocate:
13653   case OMPC_flush:
13654   case OMPC_depobj:
13655   case OMPC_read:
13656   case OMPC_write:
13657   case OMPC_update:
13658   case OMPC_capture:
13659   case OMPC_seq_cst:
13660   case OMPC_acq_rel:
13661   case OMPC_acquire:
13662   case OMPC_release:
13663   case OMPC_relaxed:
13664   case OMPC_depend:
13665   case OMPC_threads:
13666   case OMPC_simd:
13667   case OMPC_map:
13668   case OMPC_nogroup:
13669   case OMPC_hint:
13670   case OMPC_defaultmap:
13671   case OMPC_unknown:
13672   case OMPC_uniform:
13673   case OMPC_to:
13674   case OMPC_from:
13675   case OMPC_use_device_ptr:
13676   case OMPC_use_device_addr:
13677   case OMPC_is_device_ptr:
13678   case OMPC_unified_address:
13679   case OMPC_unified_shared_memory:
13680   case OMPC_reverse_offload:
13681   case OMPC_dynamic_allocators:
13682   case OMPC_atomic_default_mem_order:
13683   case OMPC_device_type:
13684   case OMPC_match:
13685   case OMPC_nontemporal:
13686   case OMPC_order:
13687   case OMPC_destroy:
13688   case OMPC_detach:
13689   case OMPC_inclusive:
13690   case OMPC_exclusive:
13691   case OMPC_uses_allocators:
13692   case OMPC_affinity:
13693   default:
13694     llvm_unreachable("Unexpected OpenMP clause.");
13695   }
13696   return CaptureRegion;
13697 }
13698 
ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation NameModifierLoc,SourceLocation ColonLoc,SourceLocation EndLoc)13699 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
13700                                      Expr *Condition, SourceLocation StartLoc,
13701                                      SourceLocation LParenLoc,
13702                                      SourceLocation NameModifierLoc,
13703                                      SourceLocation ColonLoc,
13704                                      SourceLocation EndLoc) {
13705   Expr *ValExpr = Condition;
13706   Stmt *HelperValStmt = nullptr;
13707   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
13708   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
13709       !Condition->isInstantiationDependent() &&
13710       !Condition->containsUnexpandedParameterPack()) {
13711     ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
13712     if (Val.isInvalid())
13713       return nullptr;
13714 
13715     ValExpr = Val.get();
13716 
13717     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
13718     CaptureRegion = getOpenMPCaptureRegionForClause(
13719         DKind, OMPC_if, LangOpts.OpenMP, NameModifier);
13720     if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
13721       ValExpr = MakeFullExpr(ValExpr).get();
13722       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13723       ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
13724       HelperValStmt = buildPreInits(Context, Captures);
13725     }
13726   }
13727 
13728   return new (Context)
13729       OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
13730                   LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
13731 }
13732 
ActOnOpenMPFinalClause(Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13733 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
13734                                         SourceLocation StartLoc,
13735                                         SourceLocation LParenLoc,
13736                                         SourceLocation EndLoc) {
13737   Expr *ValExpr = Condition;
13738   Stmt *HelperValStmt = nullptr;
13739   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
13740   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
13741       !Condition->isInstantiationDependent() &&
13742       !Condition->containsUnexpandedParameterPack()) {
13743     ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
13744     if (Val.isInvalid())
13745       return nullptr;
13746 
13747     ValExpr = MakeFullExpr(Val.get()).get();
13748 
13749     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
13750     CaptureRegion =
13751         getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP);
13752     if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
13753       ValExpr = MakeFullExpr(ValExpr).get();
13754       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13755       ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
13756       HelperValStmt = buildPreInits(Context, Captures);
13757     }
13758   }
13759 
13760   return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion,
13761                                       StartLoc, LParenLoc, EndLoc);
13762 }
13763 
PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,Expr * Op)13764 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
13765                                                         Expr *Op) {
13766   if (!Op)
13767     return ExprError();
13768 
13769   class IntConvertDiagnoser : public ICEConvertDiagnoser {
13770   public:
13771     IntConvertDiagnoser()
13772         : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
13773     SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
13774                                          QualType T) override {
13775       return S.Diag(Loc, diag::err_omp_not_integral) << T;
13776     }
13777     SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
13778                                              QualType T) override {
13779       return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
13780     }
13781     SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
13782                                                QualType T,
13783                                                QualType ConvTy) override {
13784       return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
13785     }
13786     SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
13787                                            QualType ConvTy) override {
13788       return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
13789              << ConvTy->isEnumeralType() << ConvTy;
13790     }
13791     SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
13792                                             QualType T) override {
13793       return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
13794     }
13795     SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
13796                                         QualType ConvTy) override {
13797       return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
13798              << ConvTy->isEnumeralType() << ConvTy;
13799     }
13800     SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
13801                                              QualType) override {
13802       llvm_unreachable("conversion functions are permitted");
13803     }
13804   } ConvertDiagnoser;
13805   return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
13806 }
13807 
13808 static bool
isNonNegativeIntegerValue(Expr * & ValExpr,Sema & SemaRef,OpenMPClauseKind CKind,bool StrictlyPositive,bool BuildCapture=false,OpenMPDirectiveKind DKind=OMPD_unknown,OpenMPDirectiveKind * CaptureRegion=nullptr,Stmt ** HelperValStmt=nullptr)13809 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind,
13810                           bool StrictlyPositive, bool BuildCapture = false,
13811                           OpenMPDirectiveKind DKind = OMPD_unknown,
13812                           OpenMPDirectiveKind *CaptureRegion = nullptr,
13813                           Stmt **HelperValStmt = nullptr) {
13814   if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
13815       !ValExpr->isInstantiationDependent()) {
13816     SourceLocation Loc = ValExpr->getExprLoc();
13817     ExprResult Value =
13818         SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
13819     if (Value.isInvalid())
13820       return false;
13821 
13822     ValExpr = Value.get();
13823     // The expression must evaluate to a non-negative integer value.
13824     if (Optional<llvm::APSInt> Result =
13825             ValExpr->getIntegerConstantExpr(SemaRef.Context)) {
13826       if (Result->isSigned() &&
13827           !((!StrictlyPositive && Result->isNonNegative()) ||
13828             (StrictlyPositive && Result->isStrictlyPositive()))) {
13829         SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
13830             << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
13831             << ValExpr->getSourceRange();
13832         return false;
13833       }
13834     }
13835     if (!BuildCapture)
13836       return true;
13837     *CaptureRegion =
13838         getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP);
13839     if (*CaptureRegion != OMPD_unknown &&
13840         !SemaRef.CurContext->isDependentContext()) {
13841       ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
13842       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13843       ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
13844       *HelperValStmt = buildPreInits(SemaRef.Context, Captures);
13845     }
13846   }
13847   return true;
13848 }
13849 
ActOnOpenMPNumThreadsClause(Expr * NumThreads,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13850 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
13851                                              SourceLocation StartLoc,
13852                                              SourceLocation LParenLoc,
13853                                              SourceLocation EndLoc) {
13854   Expr *ValExpr = NumThreads;
13855   Stmt *HelperValStmt = nullptr;
13856 
13857   // OpenMP [2.5, Restrictions]
13858   //  The num_threads expression must evaluate to a positive integer value.
13859   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
13860                                  /*StrictlyPositive=*/true))
13861     return nullptr;
13862 
13863   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
13864   OpenMPDirectiveKind CaptureRegion =
13865       getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP);
13866   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
13867     ValExpr = MakeFullExpr(ValExpr).get();
13868     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
13869     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
13870     HelperValStmt = buildPreInits(Context, Captures);
13871   }
13872 
13873   return new (Context) OMPNumThreadsClause(
13874       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
13875 }
13876 
VerifyPositiveIntegerConstantInClause(Expr * E,OpenMPClauseKind CKind,bool StrictlyPositive)13877 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
13878                                                        OpenMPClauseKind CKind,
13879                                                        bool StrictlyPositive) {
13880   if (!E)
13881     return ExprError();
13882   if (E->isValueDependent() || E->isTypeDependent() ||
13883       E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
13884     return E;
13885   llvm::APSInt Result;
13886   ExprResult ICE =
13887       VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold);
13888   if (ICE.isInvalid())
13889     return ExprError();
13890   if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
13891       (!StrictlyPositive && !Result.isNonNegative())) {
13892     Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
13893         << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
13894         << E->getSourceRange();
13895     return ExprError();
13896   }
13897   if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
13898     Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
13899         << E->getSourceRange();
13900     return ExprError();
13901   }
13902   if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
13903     DSAStack->setAssociatedLoops(Result.getExtValue());
13904   else if (CKind == OMPC_ordered)
13905     DSAStack->setAssociatedLoops(Result.getExtValue());
13906   return ICE;
13907 }
13908 
ActOnOpenMPSafelenClause(Expr * Len,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13909 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
13910                                           SourceLocation LParenLoc,
13911                                           SourceLocation EndLoc) {
13912   // OpenMP [2.8.1, simd construct, Description]
13913   // The parameter of the safelen clause must be a constant
13914   // positive integer expression.
13915   ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
13916   if (Safelen.isInvalid())
13917     return nullptr;
13918   return new (Context)
13919       OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
13920 }
13921 
ActOnOpenMPSimdlenClause(Expr * Len,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13922 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
13923                                           SourceLocation LParenLoc,
13924                                           SourceLocation EndLoc) {
13925   // OpenMP [2.8.1, simd construct, Description]
13926   // The parameter of the simdlen clause must be a constant
13927   // positive integer expression.
13928   ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
13929   if (Simdlen.isInvalid())
13930     return nullptr;
13931   return new (Context)
13932       OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
13933 }
13934 
13935 /// Tries to find omp_allocator_handle_t type.
findOMPAllocatorHandleT(Sema & S,SourceLocation Loc,DSAStackTy * Stack)13936 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
13937                                     DSAStackTy *Stack) {
13938   QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
13939   if (!OMPAllocatorHandleT.isNull())
13940     return true;
13941   // Build the predefined allocator expressions.
13942   bool ErrorFound = false;
13943   for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
13944     auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
13945     StringRef Allocator =
13946         OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
13947     DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
13948     auto *VD = dyn_cast_or_null<ValueDecl>(
13949         S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
13950     if (!VD) {
13951       ErrorFound = true;
13952       break;
13953     }
13954     QualType AllocatorType =
13955         VD->getType().getNonLValueExprType(S.getASTContext());
13956     ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
13957     if (!Res.isUsable()) {
13958       ErrorFound = true;
13959       break;
13960     }
13961     if (OMPAllocatorHandleT.isNull())
13962       OMPAllocatorHandleT = AllocatorType;
13963     if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) {
13964       ErrorFound = true;
13965       break;
13966     }
13967     Stack->setAllocator(AllocatorKind, Res.get());
13968   }
13969   if (ErrorFound) {
13970     S.Diag(Loc, diag::err_omp_implied_type_not_found)
13971         << "omp_allocator_handle_t";
13972     return false;
13973   }
13974   OMPAllocatorHandleT.addConst();
13975   Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
13976   return true;
13977 }
13978 
ActOnOpenMPAllocatorClause(Expr * A,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13979 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc,
13980                                             SourceLocation LParenLoc,
13981                                             SourceLocation EndLoc) {
13982   // OpenMP [2.11.3, allocate Directive, Description]
13983   // allocator is an expression of omp_allocator_handle_t type.
13984   if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack))
13985     return nullptr;
13986 
13987   ExprResult Allocator = DefaultLvalueConversion(A);
13988   if (Allocator.isInvalid())
13989     return nullptr;
13990   Allocator = PerformImplicitConversion(Allocator.get(),
13991                                         DSAStack->getOMPAllocatorHandleT(),
13992                                         Sema::AA_Initializing,
13993                                         /*AllowExplicit=*/true);
13994   if (Allocator.isInvalid())
13995     return nullptr;
13996   return new (Context)
13997       OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
13998 }
13999 
ActOnOpenMPCollapseClause(Expr * NumForLoops,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14000 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
14001                                            SourceLocation StartLoc,
14002                                            SourceLocation LParenLoc,
14003                                            SourceLocation EndLoc) {
14004   // OpenMP [2.7.1, loop construct, Description]
14005   // OpenMP [2.8.1, simd construct, Description]
14006   // OpenMP [2.9.6, distribute construct, Description]
14007   // The parameter of the collapse clause must be a constant
14008   // positive integer expression.
14009   ExprResult NumForLoopsResult =
14010       VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
14011   if (NumForLoopsResult.isInvalid())
14012     return nullptr;
14013   return new (Context)
14014       OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
14015 }
14016 
ActOnOpenMPOrderedClause(SourceLocation StartLoc,SourceLocation EndLoc,SourceLocation LParenLoc,Expr * NumForLoops)14017 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
14018                                           SourceLocation EndLoc,
14019                                           SourceLocation LParenLoc,
14020                                           Expr *NumForLoops) {
14021   // OpenMP [2.7.1, loop construct, Description]
14022   // OpenMP [2.8.1, simd construct, Description]
14023   // OpenMP [2.9.6, distribute construct, Description]
14024   // The parameter of the ordered clause must be a constant
14025   // positive integer expression if any.
14026   if (NumForLoops && LParenLoc.isValid()) {
14027     ExprResult NumForLoopsResult =
14028         VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
14029     if (NumForLoopsResult.isInvalid())
14030       return nullptr;
14031     NumForLoops = NumForLoopsResult.get();
14032   } else {
14033     NumForLoops = nullptr;
14034   }
14035   auto *Clause = OMPOrderedClause::Create(
14036       Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0,
14037       StartLoc, LParenLoc, EndLoc);
14038   DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
14039   return Clause;
14040 }
14041 
ActOnOpenMPSimpleClause(OpenMPClauseKind Kind,unsigned Argument,SourceLocation ArgumentLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14042 OMPClause *Sema::ActOnOpenMPSimpleClause(
14043     OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
14044     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
14045   OMPClause *Res = nullptr;
14046   switch (Kind) {
14047   case OMPC_default:
14048     Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument),
14049                                    ArgumentLoc, StartLoc, LParenLoc, EndLoc);
14050     break;
14051   case OMPC_proc_bind:
14052     Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument),
14053                                     ArgumentLoc, StartLoc, LParenLoc, EndLoc);
14054     break;
14055   case OMPC_atomic_default_mem_order:
14056     Res = ActOnOpenMPAtomicDefaultMemOrderClause(
14057         static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
14058         ArgumentLoc, StartLoc, LParenLoc, EndLoc);
14059     break;
14060   case OMPC_order:
14061     Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument),
14062                                  ArgumentLoc, StartLoc, LParenLoc, EndLoc);
14063     break;
14064   case OMPC_update:
14065     Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
14066                                   ArgumentLoc, StartLoc, LParenLoc, EndLoc);
14067     break;
14068   case OMPC_if:
14069   case OMPC_final:
14070   case OMPC_num_threads:
14071   case OMPC_safelen:
14072   case OMPC_simdlen:
14073   case OMPC_sizes:
14074   case OMPC_allocator:
14075   case OMPC_collapse:
14076   case OMPC_schedule:
14077   case OMPC_private:
14078   case OMPC_firstprivate:
14079   case OMPC_lastprivate:
14080   case OMPC_shared:
14081   case OMPC_reduction:
14082   case OMPC_task_reduction:
14083   case OMPC_in_reduction:
14084   case OMPC_linear:
14085   case OMPC_aligned:
14086   case OMPC_copyin:
14087   case OMPC_copyprivate:
14088   case OMPC_ordered:
14089   case OMPC_nowait:
14090   case OMPC_untied:
14091   case OMPC_mergeable:
14092   case OMPC_threadprivate:
14093   case OMPC_allocate:
14094   case OMPC_flush:
14095   case OMPC_depobj:
14096   case OMPC_read:
14097   case OMPC_write:
14098   case OMPC_capture:
14099   case OMPC_seq_cst:
14100   case OMPC_acq_rel:
14101   case OMPC_acquire:
14102   case OMPC_release:
14103   case OMPC_relaxed:
14104   case OMPC_depend:
14105   case OMPC_device:
14106   case OMPC_threads:
14107   case OMPC_simd:
14108   case OMPC_map:
14109   case OMPC_num_teams:
14110   case OMPC_thread_limit:
14111   case OMPC_priority:
14112   case OMPC_grainsize:
14113   case OMPC_nogroup:
14114   case OMPC_num_tasks:
14115   case OMPC_hint:
14116   case OMPC_dist_schedule:
14117   case OMPC_defaultmap:
14118   case OMPC_unknown:
14119   case OMPC_uniform:
14120   case OMPC_to:
14121   case OMPC_from:
14122   case OMPC_use_device_ptr:
14123   case OMPC_use_device_addr:
14124   case OMPC_is_device_ptr:
14125   case OMPC_unified_address:
14126   case OMPC_unified_shared_memory:
14127   case OMPC_reverse_offload:
14128   case OMPC_dynamic_allocators:
14129   case OMPC_device_type:
14130   case OMPC_match:
14131   case OMPC_nontemporal:
14132   case OMPC_destroy:
14133   case OMPC_novariants:
14134   case OMPC_nocontext:
14135   case OMPC_detach:
14136   case OMPC_inclusive:
14137   case OMPC_exclusive:
14138   case OMPC_uses_allocators:
14139   case OMPC_affinity:
14140   default:
14141     llvm_unreachable("Clause is not allowed.");
14142   }
14143   return Res;
14144 }
14145 
14146 static std::string
getListOfPossibleValues(OpenMPClauseKind K,unsigned First,unsigned Last,ArrayRef<unsigned> Exclude=llvm::None)14147 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
14148                         ArrayRef<unsigned> Exclude = llvm::None) {
14149   SmallString<256> Buffer;
14150   llvm::raw_svector_ostream Out(Buffer);
14151   unsigned Skipped = Exclude.size();
14152   auto S = Exclude.begin(), E = Exclude.end();
14153   for (unsigned I = First; I < Last; ++I) {
14154     if (std::find(S, E, I) != E) {
14155       --Skipped;
14156       continue;
14157     }
14158     Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
14159     if (I + Skipped + 2 == Last)
14160       Out << " or ";
14161     else if (I + Skipped + 1 != Last)
14162       Out << ", ";
14163   }
14164   return std::string(Out.str());
14165 }
14166 
ActOnOpenMPDefaultClause(DefaultKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14167 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind,
14168                                           SourceLocation KindKwLoc,
14169                                           SourceLocation StartLoc,
14170                                           SourceLocation LParenLoc,
14171                                           SourceLocation EndLoc) {
14172   if (Kind == OMP_DEFAULT_unknown) {
14173     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14174         << getListOfPossibleValues(OMPC_default, /*First=*/0,
14175                                    /*Last=*/unsigned(OMP_DEFAULT_unknown))
14176         << getOpenMPClauseName(OMPC_default);
14177     return nullptr;
14178   }
14179 
14180   switch (Kind) {
14181   case OMP_DEFAULT_none:
14182     DSAStack->setDefaultDSANone(KindKwLoc);
14183     break;
14184   case OMP_DEFAULT_shared:
14185     DSAStack->setDefaultDSAShared(KindKwLoc);
14186     break;
14187   case OMP_DEFAULT_firstprivate:
14188     DSAStack->setDefaultDSAFirstPrivate(KindKwLoc);
14189     break;
14190   default:
14191     llvm_unreachable("DSA unexpected in OpenMP default clause");
14192   }
14193 
14194   return new (Context)
14195       OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
14196 }
14197 
ActOnOpenMPProcBindClause(ProcBindKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14198 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind,
14199                                            SourceLocation KindKwLoc,
14200                                            SourceLocation StartLoc,
14201                                            SourceLocation LParenLoc,
14202                                            SourceLocation EndLoc) {
14203   if (Kind == OMP_PROC_BIND_unknown) {
14204     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14205         << getListOfPossibleValues(OMPC_proc_bind,
14206                                    /*First=*/unsigned(OMP_PROC_BIND_master),
14207                                    /*Last=*/
14208                                    unsigned(LangOpts.OpenMP > 50
14209                                                 ? OMP_PROC_BIND_primary
14210                                                 : OMP_PROC_BIND_spread) +
14211                                        1)
14212         << getOpenMPClauseName(OMPC_proc_bind);
14213     return nullptr;
14214   }
14215   if (Kind == OMP_PROC_BIND_primary && LangOpts.OpenMP < 51)
14216     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14217         << getListOfPossibleValues(OMPC_proc_bind,
14218                                    /*First=*/unsigned(OMP_PROC_BIND_master),
14219                                    /*Last=*/
14220                                    unsigned(OMP_PROC_BIND_spread) + 1)
14221         << getOpenMPClauseName(OMPC_proc_bind);
14222   return new (Context)
14223       OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
14224 }
14225 
ActOnOpenMPAtomicDefaultMemOrderClause(OpenMPAtomicDefaultMemOrderClauseKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14226 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause(
14227     OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc,
14228     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
14229   if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) {
14230     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14231         << getListOfPossibleValues(
14232                OMPC_atomic_default_mem_order, /*First=*/0,
14233                /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown)
14234         << getOpenMPClauseName(OMPC_atomic_default_mem_order);
14235     return nullptr;
14236   }
14237   return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
14238                                                       LParenLoc, EndLoc);
14239 }
14240 
ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14241 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,
14242                                         SourceLocation KindKwLoc,
14243                                         SourceLocation StartLoc,
14244                                         SourceLocation LParenLoc,
14245                                         SourceLocation EndLoc) {
14246   if (Kind == OMPC_ORDER_unknown) {
14247     static_assert(OMPC_ORDER_unknown > 0,
14248                   "OMPC_ORDER_unknown not greater than 0");
14249     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14250         << getListOfPossibleValues(OMPC_order, /*First=*/0,
14251                                    /*Last=*/OMPC_ORDER_unknown)
14252         << getOpenMPClauseName(OMPC_order);
14253     return nullptr;
14254   }
14255   return new (Context)
14256       OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
14257 }
14258 
ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14259 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,
14260                                          SourceLocation KindKwLoc,
14261                                          SourceLocation StartLoc,
14262                                          SourceLocation LParenLoc,
14263                                          SourceLocation EndLoc) {
14264   if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source ||
14265       Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) {
14266     unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink,
14267                          OMPC_DEPEND_depobj};
14268     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14269         << getListOfPossibleValues(OMPC_depend, /*First=*/0,
14270                                    /*Last=*/OMPC_DEPEND_unknown, Except)
14271         << getOpenMPClauseName(OMPC_update);
14272     return nullptr;
14273   }
14274   return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind,
14275                                  EndLoc);
14276 }
14277 
ActOnOpenMPSizesClause(ArrayRef<Expr * > SizeExprs,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14278 OMPClause *Sema::ActOnOpenMPSizesClause(ArrayRef<Expr *> SizeExprs,
14279                                         SourceLocation StartLoc,
14280                                         SourceLocation LParenLoc,
14281                                         SourceLocation EndLoc) {
14282   for (Expr *SizeExpr : SizeExprs) {
14283     ExprResult NumForLoopsResult = VerifyPositiveIntegerConstantInClause(
14284         SizeExpr, OMPC_sizes, /*StrictlyPositive=*/true);
14285     if (!NumForLoopsResult.isUsable())
14286       return nullptr;
14287   }
14288 
14289   DSAStack->setAssociatedLoops(SizeExprs.size());
14290   return OMPSizesClause::Create(Context, StartLoc, LParenLoc, EndLoc,
14291                                 SizeExprs);
14292 }
14293 
ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind,ArrayRef<unsigned> Argument,Expr * Expr,SourceLocation StartLoc,SourceLocation LParenLoc,ArrayRef<SourceLocation> ArgumentLoc,SourceLocation DelimLoc,SourceLocation EndLoc)14294 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
14295     OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
14296     SourceLocation StartLoc, SourceLocation LParenLoc,
14297     ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
14298     SourceLocation EndLoc) {
14299   OMPClause *Res = nullptr;
14300   switch (Kind) {
14301   case OMPC_schedule:
14302     enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
14303     assert(Argument.size() == NumberOfElements &&
14304            ArgumentLoc.size() == NumberOfElements);
14305     Res = ActOnOpenMPScheduleClause(
14306         static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
14307         static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
14308         static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
14309         StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
14310         ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
14311     break;
14312   case OMPC_if:
14313     assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
14314     Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
14315                               Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
14316                               DelimLoc, EndLoc);
14317     break;
14318   case OMPC_dist_schedule:
14319     Res = ActOnOpenMPDistScheduleClause(
14320         static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
14321         StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
14322     break;
14323   case OMPC_defaultmap:
14324     enum { Modifier, DefaultmapKind };
14325     Res = ActOnOpenMPDefaultmapClause(
14326         static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
14327         static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
14328         StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
14329         EndLoc);
14330     break;
14331   case OMPC_device:
14332     assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
14333     Res = ActOnOpenMPDeviceClause(
14334         static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr,
14335         StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
14336     break;
14337   case OMPC_final:
14338   case OMPC_num_threads:
14339   case OMPC_safelen:
14340   case OMPC_simdlen:
14341   case OMPC_sizes:
14342   case OMPC_allocator:
14343   case OMPC_collapse:
14344   case OMPC_default:
14345   case OMPC_proc_bind:
14346   case OMPC_private:
14347   case OMPC_firstprivate:
14348   case OMPC_lastprivate:
14349   case OMPC_shared:
14350   case OMPC_reduction:
14351   case OMPC_task_reduction:
14352   case OMPC_in_reduction:
14353   case OMPC_linear:
14354   case OMPC_aligned:
14355   case OMPC_copyin:
14356   case OMPC_copyprivate:
14357   case OMPC_ordered:
14358   case OMPC_nowait:
14359   case OMPC_untied:
14360   case OMPC_mergeable:
14361   case OMPC_threadprivate:
14362   case OMPC_allocate:
14363   case OMPC_flush:
14364   case OMPC_depobj:
14365   case OMPC_read:
14366   case OMPC_write:
14367   case OMPC_update:
14368   case OMPC_capture:
14369   case OMPC_seq_cst:
14370   case OMPC_acq_rel:
14371   case OMPC_acquire:
14372   case OMPC_release:
14373   case OMPC_relaxed:
14374   case OMPC_depend:
14375   case OMPC_threads:
14376   case OMPC_simd:
14377   case OMPC_map:
14378   case OMPC_num_teams:
14379   case OMPC_thread_limit:
14380   case OMPC_priority:
14381   case OMPC_grainsize:
14382   case OMPC_nogroup:
14383   case OMPC_num_tasks:
14384   case OMPC_hint:
14385   case OMPC_unknown:
14386   case OMPC_uniform:
14387   case OMPC_to:
14388   case OMPC_from:
14389   case OMPC_use_device_ptr:
14390   case OMPC_use_device_addr:
14391   case OMPC_is_device_ptr:
14392   case OMPC_unified_address:
14393   case OMPC_unified_shared_memory:
14394   case OMPC_reverse_offload:
14395   case OMPC_dynamic_allocators:
14396   case OMPC_atomic_default_mem_order:
14397   case OMPC_device_type:
14398   case OMPC_match:
14399   case OMPC_nontemporal:
14400   case OMPC_order:
14401   case OMPC_destroy:
14402   case OMPC_novariants:
14403   case OMPC_nocontext:
14404   case OMPC_detach:
14405   case OMPC_inclusive:
14406   case OMPC_exclusive:
14407   case OMPC_uses_allocators:
14408   case OMPC_affinity:
14409   default:
14410     llvm_unreachable("Clause is not allowed.");
14411   }
14412   return Res;
14413 }
14414 
checkScheduleModifiers(Sema & S,OpenMPScheduleClauseModifier M1,OpenMPScheduleClauseModifier M2,SourceLocation M1Loc,SourceLocation M2Loc)14415 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
14416                                    OpenMPScheduleClauseModifier M2,
14417                                    SourceLocation M1Loc, SourceLocation M2Loc) {
14418   if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
14419     SmallVector<unsigned, 2> Excluded;
14420     if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
14421       Excluded.push_back(M2);
14422     if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
14423       Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
14424     if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
14425       Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
14426     S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
14427         << getListOfPossibleValues(OMPC_schedule,
14428                                    /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
14429                                    /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
14430                                    Excluded)
14431         << getOpenMPClauseName(OMPC_schedule);
14432     return true;
14433   }
14434   return false;
14435 }
14436 
ActOnOpenMPScheduleClause(OpenMPScheduleClauseModifier M1,OpenMPScheduleClauseModifier M2,OpenMPScheduleClauseKind Kind,Expr * ChunkSize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation M1Loc,SourceLocation M2Loc,SourceLocation KindLoc,SourceLocation CommaLoc,SourceLocation EndLoc)14437 OMPClause *Sema::ActOnOpenMPScheduleClause(
14438     OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
14439     OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
14440     SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
14441     SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
14442   if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
14443       checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
14444     return nullptr;
14445   // OpenMP, 2.7.1, Loop Construct, Restrictions
14446   // Either the monotonic modifier or the nonmonotonic modifier can be specified
14447   // but not both.
14448   if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
14449       (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
14450        M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
14451       (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
14452        M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
14453     Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
14454         << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
14455         << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
14456     return nullptr;
14457   }
14458   if (Kind == OMPC_SCHEDULE_unknown) {
14459     std::string Values;
14460     if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
14461       unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
14462       Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
14463                                        /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
14464                                        Exclude);
14465     } else {
14466       Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
14467                                        /*Last=*/OMPC_SCHEDULE_unknown);
14468     }
14469     Diag(KindLoc, diag::err_omp_unexpected_clause_value)
14470         << Values << getOpenMPClauseName(OMPC_schedule);
14471     return nullptr;
14472   }
14473   // OpenMP, 2.7.1, Loop Construct, Restrictions
14474   // The nonmonotonic modifier can only be specified with schedule(dynamic) or
14475   // schedule(guided).
14476   // OpenMP 5.0 does not have this restriction.
14477   if (LangOpts.OpenMP < 50 &&
14478       (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
14479        M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
14480       Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
14481     Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
14482          diag::err_omp_schedule_nonmonotonic_static);
14483     return nullptr;
14484   }
14485   Expr *ValExpr = ChunkSize;
14486   Stmt *HelperValStmt = nullptr;
14487   if (ChunkSize) {
14488     if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
14489         !ChunkSize->isInstantiationDependent() &&
14490         !ChunkSize->containsUnexpandedParameterPack()) {
14491       SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
14492       ExprResult Val =
14493           PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
14494       if (Val.isInvalid())
14495         return nullptr;
14496 
14497       ValExpr = Val.get();
14498 
14499       // OpenMP [2.7.1, Restrictions]
14500       //  chunk_size must be a loop invariant integer expression with a positive
14501       //  value.
14502       if (Optional<llvm::APSInt> Result =
14503               ValExpr->getIntegerConstantExpr(Context)) {
14504         if (Result->isSigned() && !Result->isStrictlyPositive()) {
14505           Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
14506               << "schedule" << 1 << ChunkSize->getSourceRange();
14507           return nullptr;
14508         }
14509       } else if (getOpenMPCaptureRegionForClause(
14510                      DSAStack->getCurrentDirective(), OMPC_schedule,
14511                      LangOpts.OpenMP) != OMPD_unknown &&
14512                  !CurContext->isDependentContext()) {
14513         ValExpr = MakeFullExpr(ValExpr).get();
14514         llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14515         ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
14516         HelperValStmt = buildPreInits(Context, Captures);
14517       }
14518     }
14519   }
14520 
14521   return new (Context)
14522       OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
14523                         ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
14524 }
14525 
ActOnOpenMPClause(OpenMPClauseKind Kind,SourceLocation StartLoc,SourceLocation EndLoc)14526 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
14527                                    SourceLocation StartLoc,
14528                                    SourceLocation EndLoc) {
14529   OMPClause *Res = nullptr;
14530   switch (Kind) {
14531   case OMPC_ordered:
14532     Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
14533     break;
14534   case OMPC_nowait:
14535     Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
14536     break;
14537   case OMPC_untied:
14538     Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
14539     break;
14540   case OMPC_mergeable:
14541     Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
14542     break;
14543   case OMPC_read:
14544     Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
14545     break;
14546   case OMPC_write:
14547     Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
14548     break;
14549   case OMPC_update:
14550     Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
14551     break;
14552   case OMPC_capture:
14553     Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
14554     break;
14555   case OMPC_seq_cst:
14556     Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
14557     break;
14558   case OMPC_acq_rel:
14559     Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc);
14560     break;
14561   case OMPC_acquire:
14562     Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc);
14563     break;
14564   case OMPC_release:
14565     Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc);
14566     break;
14567   case OMPC_relaxed:
14568     Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc);
14569     break;
14570   case OMPC_threads:
14571     Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
14572     break;
14573   case OMPC_simd:
14574     Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
14575     break;
14576   case OMPC_nogroup:
14577     Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
14578     break;
14579   case OMPC_unified_address:
14580     Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
14581     break;
14582   case OMPC_unified_shared_memory:
14583     Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
14584     break;
14585   case OMPC_reverse_offload:
14586     Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
14587     break;
14588   case OMPC_dynamic_allocators:
14589     Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
14590     break;
14591   case OMPC_destroy:
14592     Res = ActOnOpenMPDestroyClause(/*InteropVar=*/nullptr, StartLoc,
14593                                    /*LParenLoc=*/SourceLocation(),
14594                                    /*VarLoc=*/SourceLocation(), EndLoc);
14595     break;
14596   case OMPC_if:
14597   case OMPC_final:
14598   case OMPC_num_threads:
14599   case OMPC_safelen:
14600   case OMPC_simdlen:
14601   case OMPC_sizes:
14602   case OMPC_allocator:
14603   case OMPC_collapse:
14604   case OMPC_schedule:
14605   case OMPC_private:
14606   case OMPC_firstprivate:
14607   case OMPC_lastprivate:
14608   case OMPC_shared:
14609   case OMPC_reduction:
14610   case OMPC_task_reduction:
14611   case OMPC_in_reduction:
14612   case OMPC_linear:
14613   case OMPC_aligned:
14614   case OMPC_copyin:
14615   case OMPC_copyprivate:
14616   case OMPC_default:
14617   case OMPC_proc_bind:
14618   case OMPC_threadprivate:
14619   case OMPC_allocate:
14620   case OMPC_flush:
14621   case OMPC_depobj:
14622   case OMPC_depend:
14623   case OMPC_device:
14624   case OMPC_map:
14625   case OMPC_num_teams:
14626   case OMPC_thread_limit:
14627   case OMPC_priority:
14628   case OMPC_grainsize:
14629   case OMPC_num_tasks:
14630   case OMPC_hint:
14631   case OMPC_dist_schedule:
14632   case OMPC_defaultmap:
14633   case OMPC_unknown:
14634   case OMPC_uniform:
14635   case OMPC_to:
14636   case OMPC_from:
14637   case OMPC_use_device_ptr:
14638   case OMPC_use_device_addr:
14639   case OMPC_is_device_ptr:
14640   case OMPC_atomic_default_mem_order:
14641   case OMPC_device_type:
14642   case OMPC_match:
14643   case OMPC_nontemporal:
14644   case OMPC_order:
14645   case OMPC_novariants:
14646   case OMPC_nocontext:
14647   case OMPC_detach:
14648   case OMPC_inclusive:
14649   case OMPC_exclusive:
14650   case OMPC_uses_allocators:
14651   case OMPC_affinity:
14652   default:
14653     llvm_unreachable("Clause is not allowed.");
14654   }
14655   return Res;
14656 }
14657 
ActOnOpenMPNowaitClause(SourceLocation StartLoc,SourceLocation EndLoc)14658 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
14659                                          SourceLocation EndLoc) {
14660   DSAStack->setNowaitRegion();
14661   return new (Context) OMPNowaitClause(StartLoc, EndLoc);
14662 }
14663 
ActOnOpenMPUntiedClause(SourceLocation StartLoc,SourceLocation EndLoc)14664 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
14665                                          SourceLocation EndLoc) {
14666   return new (Context) OMPUntiedClause(StartLoc, EndLoc);
14667 }
14668 
ActOnOpenMPMergeableClause(SourceLocation StartLoc,SourceLocation EndLoc)14669 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
14670                                             SourceLocation EndLoc) {
14671   return new (Context) OMPMergeableClause(StartLoc, EndLoc);
14672 }
14673 
ActOnOpenMPReadClause(SourceLocation StartLoc,SourceLocation EndLoc)14674 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
14675                                        SourceLocation EndLoc) {
14676   return new (Context) OMPReadClause(StartLoc, EndLoc);
14677 }
14678 
ActOnOpenMPWriteClause(SourceLocation StartLoc,SourceLocation EndLoc)14679 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
14680                                         SourceLocation EndLoc) {
14681   return new (Context) OMPWriteClause(StartLoc, EndLoc);
14682 }
14683 
ActOnOpenMPUpdateClause(SourceLocation StartLoc,SourceLocation EndLoc)14684 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
14685                                          SourceLocation EndLoc) {
14686   return OMPUpdateClause::Create(Context, StartLoc, EndLoc);
14687 }
14688 
ActOnOpenMPCaptureClause(SourceLocation StartLoc,SourceLocation EndLoc)14689 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
14690                                           SourceLocation EndLoc) {
14691   return new (Context) OMPCaptureClause(StartLoc, EndLoc);
14692 }
14693 
ActOnOpenMPSeqCstClause(SourceLocation StartLoc,SourceLocation EndLoc)14694 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
14695                                          SourceLocation EndLoc) {
14696   return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
14697 }
14698 
ActOnOpenMPAcqRelClause(SourceLocation StartLoc,SourceLocation EndLoc)14699 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc,
14700                                          SourceLocation EndLoc) {
14701   return new (Context) OMPAcqRelClause(StartLoc, EndLoc);
14702 }
14703 
ActOnOpenMPAcquireClause(SourceLocation StartLoc,SourceLocation EndLoc)14704 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc,
14705                                           SourceLocation EndLoc) {
14706   return new (Context) OMPAcquireClause(StartLoc, EndLoc);
14707 }
14708 
ActOnOpenMPReleaseClause(SourceLocation StartLoc,SourceLocation EndLoc)14709 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc,
14710                                           SourceLocation EndLoc) {
14711   return new (Context) OMPReleaseClause(StartLoc, EndLoc);
14712 }
14713 
ActOnOpenMPRelaxedClause(SourceLocation StartLoc,SourceLocation EndLoc)14714 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc,
14715                                           SourceLocation EndLoc) {
14716   return new (Context) OMPRelaxedClause(StartLoc, EndLoc);
14717 }
14718 
ActOnOpenMPThreadsClause(SourceLocation StartLoc,SourceLocation EndLoc)14719 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
14720                                           SourceLocation EndLoc) {
14721   return new (Context) OMPThreadsClause(StartLoc, EndLoc);
14722 }
14723 
ActOnOpenMPSIMDClause(SourceLocation StartLoc,SourceLocation EndLoc)14724 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
14725                                        SourceLocation EndLoc) {
14726   return new (Context) OMPSIMDClause(StartLoc, EndLoc);
14727 }
14728 
ActOnOpenMPNogroupClause(SourceLocation StartLoc,SourceLocation EndLoc)14729 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
14730                                           SourceLocation EndLoc) {
14731   return new (Context) OMPNogroupClause(StartLoc, EndLoc);
14732 }
14733 
ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,SourceLocation EndLoc)14734 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
14735                                                  SourceLocation EndLoc) {
14736   return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
14737 }
14738 
ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,SourceLocation EndLoc)14739 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
14740                                                       SourceLocation EndLoc) {
14741   return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
14742 }
14743 
ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,SourceLocation EndLoc)14744 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
14745                                                  SourceLocation EndLoc) {
14746   return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
14747 }
14748 
ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,SourceLocation EndLoc)14749 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
14750                                                     SourceLocation EndLoc) {
14751   return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
14752 }
14753 
ActOnOpenMPInteropDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)14754 StmtResult Sema::ActOnOpenMPInteropDirective(ArrayRef<OMPClause *> Clauses,
14755                                              SourceLocation StartLoc,
14756                                              SourceLocation EndLoc) {
14757 
14758   // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
14759   // At least one action-clause must appear on a directive.
14760   if (!hasClauses(Clauses, OMPC_init, OMPC_use, OMPC_destroy, OMPC_nowait)) {
14761     StringRef Expected = "'init', 'use', 'destroy', or 'nowait'";
14762     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
14763         << Expected << getOpenMPDirectiveName(OMPD_interop);
14764     return StmtError();
14765   }
14766 
14767   // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
14768   // A depend clause can only appear on the directive if a targetsync
14769   // interop-type is present or the interop-var was initialized with
14770   // the targetsync interop-type.
14771 
14772   // If there is any 'init' clause diagnose if there is no 'init' clause with
14773   // interop-type of 'targetsync'. Cases involving other directives cannot be
14774   // diagnosed.
14775   const OMPDependClause *DependClause = nullptr;
14776   bool HasInitClause = false;
14777   bool IsTargetSync = false;
14778   for (const OMPClause *C : Clauses) {
14779     if (IsTargetSync)
14780       break;
14781     if (const auto *InitClause = dyn_cast<OMPInitClause>(C)) {
14782       HasInitClause = true;
14783       if (InitClause->getIsTargetSync())
14784         IsTargetSync = true;
14785     } else if (const auto *DC = dyn_cast<OMPDependClause>(C)) {
14786       DependClause = DC;
14787     }
14788   }
14789   if (DependClause && HasInitClause && !IsTargetSync) {
14790     Diag(DependClause->getBeginLoc(), diag::err_omp_interop_bad_depend_clause);
14791     return StmtError();
14792   }
14793 
14794   // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
14795   // Each interop-var may be specified for at most one action-clause of each
14796   // interop construct.
14797   llvm::SmallPtrSet<const VarDecl *, 4> InteropVars;
14798   for (const OMPClause *C : Clauses) {
14799     OpenMPClauseKind ClauseKind = C->getClauseKind();
14800     const DeclRefExpr *DRE = nullptr;
14801     SourceLocation VarLoc;
14802 
14803     if (ClauseKind == OMPC_init) {
14804       const auto *IC = cast<OMPInitClause>(C);
14805       VarLoc = IC->getVarLoc();
14806       DRE = dyn_cast_or_null<DeclRefExpr>(IC->getInteropVar());
14807     } else if (ClauseKind == OMPC_use) {
14808       const auto *UC = cast<OMPUseClause>(C);
14809       VarLoc = UC->getVarLoc();
14810       DRE = dyn_cast_or_null<DeclRefExpr>(UC->getInteropVar());
14811     } else if (ClauseKind == OMPC_destroy) {
14812       const auto *DC = cast<OMPDestroyClause>(C);
14813       VarLoc = DC->getVarLoc();
14814       DRE = dyn_cast_or_null<DeclRefExpr>(DC->getInteropVar());
14815     }
14816 
14817     if (!DRE)
14818       continue;
14819 
14820     if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
14821       if (!InteropVars.insert(VD->getCanonicalDecl()).second) {
14822         Diag(VarLoc, diag::err_omp_interop_var_multiple_actions) << VD;
14823         return StmtError();
14824       }
14825     }
14826   }
14827 
14828   return OMPInteropDirective::Create(Context, StartLoc, EndLoc, Clauses);
14829 }
14830 
isValidInteropVariable(Sema & SemaRef,Expr * InteropVarExpr,SourceLocation VarLoc,OpenMPClauseKind Kind)14831 static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr,
14832                                    SourceLocation VarLoc,
14833                                    OpenMPClauseKind Kind) {
14834   if (InteropVarExpr->isValueDependent() || InteropVarExpr->isTypeDependent() ||
14835       InteropVarExpr->isInstantiationDependent() ||
14836       InteropVarExpr->containsUnexpandedParameterPack())
14837     return true;
14838 
14839   const auto *DRE = dyn_cast<DeclRefExpr>(InteropVarExpr);
14840   if (!DRE || !isa<VarDecl>(DRE->getDecl())) {
14841     SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected) << 0;
14842     return false;
14843   }
14844 
14845   // Interop variable should be of type omp_interop_t.
14846   bool HasError = false;
14847   QualType InteropType;
14848   LookupResult Result(SemaRef, &SemaRef.Context.Idents.get("omp_interop_t"),
14849                       VarLoc, Sema::LookupOrdinaryName);
14850   if (SemaRef.LookupName(Result, SemaRef.getCurScope())) {
14851     NamedDecl *ND = Result.getFoundDecl();
14852     if (const auto *TD = dyn_cast<TypeDecl>(ND)) {
14853       InteropType = QualType(TD->getTypeForDecl(), 0);
14854     } else {
14855       HasError = true;
14856     }
14857   } else {
14858     HasError = true;
14859   }
14860 
14861   if (HasError) {
14862     SemaRef.Diag(VarLoc, diag::err_omp_implied_type_not_found)
14863         << "omp_interop_t";
14864     return false;
14865   }
14866 
14867   QualType VarType = InteropVarExpr->getType().getUnqualifiedType();
14868   if (!SemaRef.Context.hasSameType(InteropType, VarType)) {
14869     SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_wrong_type);
14870     return false;
14871   }
14872 
14873   // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
14874   // The interop-var passed to init or destroy must be non-const.
14875   if ((Kind == OMPC_init || Kind == OMPC_destroy) &&
14876       isConstNotMutableType(SemaRef, InteropVarExpr->getType())) {
14877     SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected)
14878         << /*non-const*/ 1;
14879     return false;
14880   }
14881   return true;
14882 }
14883 
14884 OMPClause *
ActOnOpenMPInitClause(Expr * InteropVar,ArrayRef<Expr * > PrefExprs,bool IsTarget,bool IsTargetSync,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation VarLoc,SourceLocation EndLoc)14885 Sema::ActOnOpenMPInitClause(Expr *InteropVar, ArrayRef<Expr *> PrefExprs,
14886                             bool IsTarget, bool IsTargetSync,
14887                             SourceLocation StartLoc, SourceLocation LParenLoc,
14888                             SourceLocation VarLoc, SourceLocation EndLoc) {
14889 
14890   if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_init))
14891     return nullptr;
14892 
14893   // Check prefer_type values.  These foreign-runtime-id values are either
14894   // string literals or constant integral expressions.
14895   for (const Expr *E : PrefExprs) {
14896     if (E->isValueDependent() || E->isTypeDependent() ||
14897         E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
14898       continue;
14899     if (E->isIntegerConstantExpr(Context))
14900       continue;
14901     if (isa<StringLiteral>(E))
14902       continue;
14903     Diag(E->getExprLoc(), diag::err_omp_interop_prefer_type);
14904     return nullptr;
14905   }
14906 
14907   return OMPInitClause::Create(Context, InteropVar, PrefExprs, IsTarget,
14908                                IsTargetSync, StartLoc, LParenLoc, VarLoc,
14909                                EndLoc);
14910 }
14911 
ActOnOpenMPUseClause(Expr * InteropVar,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation VarLoc,SourceLocation EndLoc)14912 OMPClause *Sema::ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
14913                                       SourceLocation LParenLoc,
14914                                       SourceLocation VarLoc,
14915                                       SourceLocation EndLoc) {
14916 
14917   if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_use))
14918     return nullptr;
14919 
14920   return new (Context)
14921       OMPUseClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
14922 }
14923 
ActOnOpenMPDestroyClause(Expr * InteropVar,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation VarLoc,SourceLocation EndLoc)14924 OMPClause *Sema::ActOnOpenMPDestroyClause(Expr *InteropVar,
14925                                           SourceLocation StartLoc,
14926                                           SourceLocation LParenLoc,
14927                                           SourceLocation VarLoc,
14928                                           SourceLocation EndLoc) {
14929   if (InteropVar &&
14930       !isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_destroy))
14931     return nullptr;
14932 
14933   return new (Context)
14934       OMPDestroyClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
14935 }
14936 
ActOnOpenMPNovariantsClause(Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14937 OMPClause *Sema::ActOnOpenMPNovariantsClause(Expr *Condition,
14938                                              SourceLocation StartLoc,
14939                                              SourceLocation LParenLoc,
14940                                              SourceLocation EndLoc) {
14941   Expr *ValExpr = Condition;
14942   Stmt *HelperValStmt = nullptr;
14943   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
14944   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
14945       !Condition->isInstantiationDependent() &&
14946       !Condition->containsUnexpandedParameterPack()) {
14947     ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
14948     if (Val.isInvalid())
14949       return nullptr;
14950 
14951     ValExpr = MakeFullExpr(Val.get()).get();
14952 
14953     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
14954     CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_novariants,
14955                                                     LangOpts.OpenMP);
14956     if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
14957       ValExpr = MakeFullExpr(ValExpr).get();
14958       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14959       ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
14960       HelperValStmt = buildPreInits(Context, Captures);
14961     }
14962   }
14963 
14964   return new (Context) OMPNovariantsClause(
14965       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
14966 }
14967 
ActOnOpenMPNocontextClause(Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14968 OMPClause *Sema::ActOnOpenMPNocontextClause(Expr *Condition,
14969                                             SourceLocation StartLoc,
14970                                             SourceLocation LParenLoc,
14971                                             SourceLocation EndLoc) {
14972   Expr *ValExpr = Condition;
14973   Stmt *HelperValStmt = nullptr;
14974   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
14975   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
14976       !Condition->isInstantiationDependent() &&
14977       !Condition->containsUnexpandedParameterPack()) {
14978     ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
14979     if (Val.isInvalid())
14980       return nullptr;
14981 
14982     ValExpr = MakeFullExpr(Val.get()).get();
14983 
14984     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
14985     CaptureRegion =
14986         getOpenMPCaptureRegionForClause(DKind, OMPC_nocontext, LangOpts.OpenMP);
14987     if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
14988       ValExpr = MakeFullExpr(ValExpr).get();
14989       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14990       ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
14991       HelperValStmt = buildPreInits(Context, Captures);
14992     }
14993   }
14994 
14995   return new (Context) OMPNocontextClause(ValExpr, HelperValStmt, CaptureRegion,
14996                                           StartLoc, LParenLoc, EndLoc);
14997 }
14998 
ActOnOpenMPFilterClause(Expr * ThreadID,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14999 OMPClause *Sema::ActOnOpenMPFilterClause(Expr *ThreadID,
15000                                          SourceLocation StartLoc,
15001                                          SourceLocation LParenLoc,
15002                                          SourceLocation EndLoc) {
15003   Expr *ValExpr = ThreadID;
15004   Stmt *HelperValStmt = nullptr;
15005 
15006   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
15007   OpenMPDirectiveKind CaptureRegion =
15008       getOpenMPCaptureRegionForClause(DKind, OMPC_filter, LangOpts.OpenMP);
15009   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
15010     ValExpr = MakeFullExpr(ValExpr).get();
15011     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15012     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
15013     HelperValStmt = buildPreInits(Context, Captures);
15014   }
15015 
15016   return new (Context) OMPFilterClause(ValExpr, HelperValStmt, CaptureRegion,
15017                                        StartLoc, LParenLoc, EndLoc);
15018 }
15019 
ActOnOpenMPVarListClause(OpenMPClauseKind Kind,ArrayRef<Expr * > VarList,Expr * DepModOrTailExpr,const OMPVarListLocTy & Locs,SourceLocation ColonLoc,CXXScopeSpec & ReductionOrMapperIdScopeSpec,DeclarationNameInfo & ReductionOrMapperId,int ExtraModifier,ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,ArrayRef<SourceLocation> MapTypeModifiersLoc,bool IsMapTypeImplicit,SourceLocation ExtraModifierLoc,ArrayRef<OpenMPMotionModifierKind> MotionModifiers,ArrayRef<SourceLocation> MotionModifiersLoc)15020 OMPClause *Sema::ActOnOpenMPVarListClause(
15021     OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr,
15022     const OMPVarListLocTy &Locs, SourceLocation ColonLoc,
15023     CXXScopeSpec &ReductionOrMapperIdScopeSpec,
15024     DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier,
15025     ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
15026     ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit,
15027     SourceLocation ExtraModifierLoc,
15028     ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
15029     ArrayRef<SourceLocation> MotionModifiersLoc) {
15030   SourceLocation StartLoc = Locs.StartLoc;
15031   SourceLocation LParenLoc = Locs.LParenLoc;
15032   SourceLocation EndLoc = Locs.EndLoc;
15033   OMPClause *Res = nullptr;
15034   switch (Kind) {
15035   case OMPC_private:
15036     Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
15037     break;
15038   case OMPC_firstprivate:
15039     Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
15040     break;
15041   case OMPC_lastprivate:
15042     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown &&
15043            "Unexpected lastprivate modifier.");
15044     Res = ActOnOpenMPLastprivateClause(
15045         VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier),
15046         ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
15047     break;
15048   case OMPC_shared:
15049     Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
15050     break;
15051   case OMPC_reduction:
15052     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown &&
15053            "Unexpected lastprivate modifier.");
15054     Res = ActOnOpenMPReductionClause(
15055         VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier),
15056         StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
15057         ReductionOrMapperIdScopeSpec, ReductionOrMapperId);
15058     break;
15059   case OMPC_task_reduction:
15060     Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
15061                                          EndLoc, ReductionOrMapperIdScopeSpec,
15062                                          ReductionOrMapperId);
15063     break;
15064   case OMPC_in_reduction:
15065     Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
15066                                        EndLoc, ReductionOrMapperIdScopeSpec,
15067                                        ReductionOrMapperId);
15068     break;
15069   case OMPC_linear:
15070     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown &&
15071            "Unexpected linear modifier.");
15072     Res = ActOnOpenMPLinearClause(
15073         VarList, DepModOrTailExpr, StartLoc, LParenLoc,
15074         static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc,
15075         ColonLoc, EndLoc);
15076     break;
15077   case OMPC_aligned:
15078     Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc,
15079                                    LParenLoc, ColonLoc, EndLoc);
15080     break;
15081   case OMPC_copyin:
15082     Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
15083     break;
15084   case OMPC_copyprivate:
15085     Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
15086     break;
15087   case OMPC_flush:
15088     Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
15089     break;
15090   case OMPC_depend:
15091     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown &&
15092            "Unexpected depend modifier.");
15093     Res = ActOnOpenMPDependClause(
15094         DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier),
15095         ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
15096     break;
15097   case OMPC_map:
15098     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown &&
15099            "Unexpected map modifier.");
15100     Res = ActOnOpenMPMapClause(
15101         MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec,
15102         ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier),
15103         IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs);
15104     break;
15105   case OMPC_to:
15106     Res = ActOnOpenMPToClause(MotionModifiers, MotionModifiersLoc,
15107                               ReductionOrMapperIdScopeSpec, ReductionOrMapperId,
15108                               ColonLoc, VarList, Locs);
15109     break;
15110   case OMPC_from:
15111     Res = ActOnOpenMPFromClause(MotionModifiers, MotionModifiersLoc,
15112                                 ReductionOrMapperIdScopeSpec,
15113                                 ReductionOrMapperId, ColonLoc, VarList, Locs);
15114     break;
15115   case OMPC_use_device_ptr:
15116     Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
15117     break;
15118   case OMPC_use_device_addr:
15119     Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
15120     break;
15121   case OMPC_is_device_ptr:
15122     Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
15123     break;
15124   case OMPC_allocate:
15125     Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc,
15126                                     LParenLoc, ColonLoc, EndLoc);
15127     break;
15128   case OMPC_nontemporal:
15129     Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc);
15130     break;
15131   case OMPC_inclusive:
15132     Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
15133     break;
15134   case OMPC_exclusive:
15135     Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
15136     break;
15137   case OMPC_affinity:
15138     Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc,
15139                                     DepModOrTailExpr, VarList);
15140     break;
15141   case OMPC_if:
15142   case OMPC_depobj:
15143   case OMPC_final:
15144   case OMPC_num_threads:
15145   case OMPC_safelen:
15146   case OMPC_simdlen:
15147   case OMPC_sizes:
15148   case OMPC_allocator:
15149   case OMPC_collapse:
15150   case OMPC_default:
15151   case OMPC_proc_bind:
15152   case OMPC_schedule:
15153   case OMPC_ordered:
15154   case OMPC_nowait:
15155   case OMPC_untied:
15156   case OMPC_mergeable:
15157   case OMPC_threadprivate:
15158   case OMPC_read:
15159   case OMPC_write:
15160   case OMPC_update:
15161   case OMPC_capture:
15162   case OMPC_seq_cst:
15163   case OMPC_acq_rel:
15164   case OMPC_acquire:
15165   case OMPC_release:
15166   case OMPC_relaxed:
15167   case OMPC_device:
15168   case OMPC_threads:
15169   case OMPC_simd:
15170   case OMPC_num_teams:
15171   case OMPC_thread_limit:
15172   case OMPC_priority:
15173   case OMPC_grainsize:
15174   case OMPC_nogroup:
15175   case OMPC_num_tasks:
15176   case OMPC_hint:
15177   case OMPC_dist_schedule:
15178   case OMPC_defaultmap:
15179   case OMPC_unknown:
15180   case OMPC_uniform:
15181   case OMPC_unified_address:
15182   case OMPC_unified_shared_memory:
15183   case OMPC_reverse_offload:
15184   case OMPC_dynamic_allocators:
15185   case OMPC_atomic_default_mem_order:
15186   case OMPC_device_type:
15187   case OMPC_match:
15188   case OMPC_order:
15189   case OMPC_destroy:
15190   case OMPC_novariants:
15191   case OMPC_nocontext:
15192   case OMPC_detach:
15193   case OMPC_uses_allocators:
15194   default:
15195     llvm_unreachable("Clause is not allowed.");
15196   }
15197   return Res;
15198 }
15199 
getOpenMPCapturedExpr(VarDecl * Capture,ExprValueKind VK,ExprObjectKind OK,SourceLocation Loc)15200 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
15201                                        ExprObjectKind OK, SourceLocation Loc) {
15202   ExprResult Res = BuildDeclRefExpr(
15203       Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
15204   if (!Res.isUsable())
15205     return ExprError();
15206   if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
15207     Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
15208     if (!Res.isUsable())
15209       return ExprError();
15210   }
15211   if (VK != VK_LValue && Res.get()->isGLValue()) {
15212     Res = DefaultLvalueConversion(Res.get());
15213     if (!Res.isUsable())
15214       return ExprError();
15215   }
15216   return Res;
15217 }
15218 
ActOnOpenMPPrivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)15219 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
15220                                           SourceLocation StartLoc,
15221                                           SourceLocation LParenLoc,
15222                                           SourceLocation EndLoc) {
15223   SmallVector<Expr *, 8> Vars;
15224   SmallVector<Expr *, 8> PrivateCopies;
15225   for (Expr *RefExpr : VarList) {
15226     assert(RefExpr && "NULL expr in OpenMP private clause.");
15227     SourceLocation ELoc;
15228     SourceRange ERange;
15229     Expr *SimpleRefExpr = RefExpr;
15230     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15231     if (Res.second) {
15232       // It will be analyzed later.
15233       Vars.push_back(RefExpr);
15234       PrivateCopies.push_back(nullptr);
15235     }
15236     ValueDecl *D = Res.first;
15237     if (!D)
15238       continue;
15239 
15240     QualType Type = D->getType();
15241     auto *VD = dyn_cast<VarDecl>(D);
15242 
15243     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
15244     //  A variable that appears in a private clause must not have an incomplete
15245     //  type or a reference type.
15246     if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
15247       continue;
15248     Type = Type.getNonReferenceType();
15249 
15250     // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
15251     // A variable that is privatized must not have a const-qualified type
15252     // unless it is of class type with a mutable member. This restriction does
15253     // not apply to the firstprivate clause.
15254     //
15255     // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
15256     // A variable that appears in a private clause must not have a
15257     // const-qualified type unless it is of class type with a mutable member.
15258     if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
15259       continue;
15260 
15261     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
15262     // in a Construct]
15263     //  Variables with the predetermined data-sharing attributes may not be
15264     //  listed in data-sharing attributes clauses, except for the cases
15265     //  listed below. For these exceptions only, listing a predetermined
15266     //  variable in a data-sharing attribute clause is allowed and overrides
15267     //  the variable's predetermined data-sharing attributes.
15268     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
15269     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
15270       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
15271                                           << getOpenMPClauseName(OMPC_private);
15272       reportOriginalDsa(*this, DSAStack, D, DVar);
15273       continue;
15274     }
15275 
15276     OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
15277     // Variably modified types are not supported for tasks.
15278     if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
15279         isOpenMPTaskingDirective(CurrDir)) {
15280       Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
15281           << getOpenMPClauseName(OMPC_private) << Type
15282           << getOpenMPDirectiveName(CurrDir);
15283       bool IsDecl =
15284           !VD ||
15285           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
15286       Diag(D->getLocation(),
15287            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15288           << D;
15289       continue;
15290     }
15291 
15292     // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
15293     // A list item cannot appear in both a map clause and a data-sharing
15294     // attribute clause on the same construct
15295     //
15296     // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
15297     // A list item cannot appear in both a map clause and a data-sharing
15298     // attribute clause on the same construct unless the construct is a
15299     // combined construct.
15300     if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) ||
15301         CurrDir == OMPD_target) {
15302       OpenMPClauseKind ConflictKind;
15303       if (DSAStack->checkMappableExprComponentListsForDecl(
15304               VD, /*CurrentRegionOnly=*/true,
15305               [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
15306                   OpenMPClauseKind WhereFoundClauseKind) -> bool {
15307                 ConflictKind = WhereFoundClauseKind;
15308                 return true;
15309               })) {
15310         Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
15311             << getOpenMPClauseName(OMPC_private)
15312             << getOpenMPClauseName(ConflictKind)
15313             << getOpenMPDirectiveName(CurrDir);
15314         reportOriginalDsa(*this, DSAStack, D, DVar);
15315         continue;
15316       }
15317     }
15318 
15319     // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
15320     //  A variable of class type (or array thereof) that appears in a private
15321     //  clause requires an accessible, unambiguous default constructor for the
15322     //  class type.
15323     // Generate helper private variable and initialize it with the default
15324     // value. The address of the original variable is replaced by the address of
15325     // the new private variable in CodeGen. This new variable is not added to
15326     // IdResolver, so the code in the OpenMP region uses original variable for
15327     // proper diagnostics.
15328     Type = Type.getUnqualifiedType();
15329     VarDecl *VDPrivate =
15330         buildVarDecl(*this, ELoc, Type, D->getName(),
15331                      D->hasAttrs() ? &D->getAttrs() : nullptr,
15332                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
15333     ActOnUninitializedDecl(VDPrivate);
15334     if (VDPrivate->isInvalidDecl())
15335       continue;
15336     DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
15337         *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
15338 
15339     DeclRefExpr *Ref = nullptr;
15340     if (!VD && !CurContext->isDependentContext())
15341       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
15342     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
15343     Vars.push_back((VD || CurContext->isDependentContext())
15344                        ? RefExpr->IgnoreParens()
15345                        : Ref);
15346     PrivateCopies.push_back(VDPrivateRefExpr);
15347   }
15348 
15349   if (Vars.empty())
15350     return nullptr;
15351 
15352   return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
15353                                   PrivateCopies);
15354 }
15355 
15356 namespace {
15357 class DiagsUninitializedSeveretyRAII {
15358 private:
15359   DiagnosticsEngine &Diags;
15360   SourceLocation SavedLoc;
15361   bool IsIgnored = false;
15362 
15363 public:
DiagsUninitializedSeveretyRAII(DiagnosticsEngine & Diags,SourceLocation Loc,bool IsIgnored)15364   DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
15365                                  bool IsIgnored)
15366       : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
15367     if (!IsIgnored) {
15368       Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
15369                         /*Map*/ diag::Severity::Ignored, Loc);
15370     }
15371   }
~DiagsUninitializedSeveretyRAII()15372   ~DiagsUninitializedSeveretyRAII() {
15373     if (!IsIgnored)
15374       Diags.popMappings(SavedLoc);
15375   }
15376 };
15377 }
15378 
ActOnOpenMPFirstprivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)15379 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
15380                                                SourceLocation StartLoc,
15381                                                SourceLocation LParenLoc,
15382                                                SourceLocation EndLoc) {
15383   SmallVector<Expr *, 8> Vars;
15384   SmallVector<Expr *, 8> PrivateCopies;
15385   SmallVector<Expr *, 8> Inits;
15386   SmallVector<Decl *, 4> ExprCaptures;
15387   bool IsImplicitClause =
15388       StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
15389   SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc();
15390 
15391   for (Expr *RefExpr : VarList) {
15392     assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
15393     SourceLocation ELoc;
15394     SourceRange ERange;
15395     Expr *SimpleRefExpr = RefExpr;
15396     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15397     if (Res.second) {
15398       // It will be analyzed later.
15399       Vars.push_back(RefExpr);
15400       PrivateCopies.push_back(nullptr);
15401       Inits.push_back(nullptr);
15402     }
15403     ValueDecl *D = Res.first;
15404     if (!D)
15405       continue;
15406 
15407     ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
15408     QualType Type = D->getType();
15409     auto *VD = dyn_cast<VarDecl>(D);
15410 
15411     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
15412     //  A variable that appears in a private clause must not have an incomplete
15413     //  type or a reference type.
15414     if (RequireCompleteType(ELoc, Type,
15415                             diag::err_omp_firstprivate_incomplete_type))
15416       continue;
15417     Type = Type.getNonReferenceType();
15418 
15419     // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
15420     //  A variable of class type (or array thereof) that appears in a private
15421     //  clause requires an accessible, unambiguous copy constructor for the
15422     //  class type.
15423     QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
15424 
15425     // If an implicit firstprivate variable found it was checked already.
15426     DSAStackTy::DSAVarData TopDVar;
15427     if (!IsImplicitClause) {
15428       DSAStackTy::DSAVarData DVar =
15429           DSAStack->getTopDSA(D, /*FromParent=*/false);
15430       TopDVar = DVar;
15431       OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
15432       bool IsConstant = ElemType.isConstant(Context);
15433       // OpenMP [2.4.13, Data-sharing Attribute Clauses]
15434       //  A list item that specifies a given variable may not appear in more
15435       // than one clause on the same directive, except that a variable may be
15436       //  specified in both firstprivate and lastprivate clauses.
15437       // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
15438       // A list item may appear in a firstprivate or lastprivate clause but not
15439       // both.
15440       if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
15441           (isOpenMPDistributeDirective(CurrDir) ||
15442            DVar.CKind != OMPC_lastprivate) &&
15443           DVar.RefExpr) {
15444         Diag(ELoc, diag::err_omp_wrong_dsa)
15445             << getOpenMPClauseName(DVar.CKind)
15446             << getOpenMPClauseName(OMPC_firstprivate);
15447         reportOriginalDsa(*this, DSAStack, D, DVar);
15448         continue;
15449       }
15450 
15451       // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
15452       // in a Construct]
15453       //  Variables with the predetermined data-sharing attributes may not be
15454       //  listed in data-sharing attributes clauses, except for the cases
15455       //  listed below. For these exceptions only, listing a predetermined
15456       //  variable in a data-sharing attribute clause is allowed and overrides
15457       //  the variable's predetermined data-sharing attributes.
15458       // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
15459       // in a Construct, C/C++, p.2]
15460       //  Variables with const-qualified type having no mutable member may be
15461       //  listed in a firstprivate clause, even if they are static data members.
15462       if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
15463           DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
15464         Diag(ELoc, diag::err_omp_wrong_dsa)
15465             << getOpenMPClauseName(DVar.CKind)
15466             << getOpenMPClauseName(OMPC_firstprivate);
15467         reportOriginalDsa(*this, DSAStack, D, DVar);
15468         continue;
15469       }
15470 
15471       // OpenMP [2.9.3.4, Restrictions, p.2]
15472       //  A list item that is private within a parallel region must not appear
15473       //  in a firstprivate clause on a worksharing construct if any of the
15474       //  worksharing regions arising from the worksharing construct ever bind
15475       //  to any of the parallel regions arising from the parallel construct.
15476       // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
15477       // A list item that is private within a teams region must not appear in a
15478       // firstprivate clause on a distribute construct if any of the distribute
15479       // regions arising from the distribute construct ever bind to any of the
15480       // teams regions arising from the teams construct.
15481       // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
15482       // A list item that appears in a reduction clause of a teams construct
15483       // must not appear in a firstprivate clause on a distribute construct if
15484       // any of the distribute regions arising from the distribute construct
15485       // ever bind to any of the teams regions arising from the teams construct.
15486       if ((isOpenMPWorksharingDirective(CurrDir) ||
15487            isOpenMPDistributeDirective(CurrDir)) &&
15488           !isOpenMPParallelDirective(CurrDir) &&
15489           !isOpenMPTeamsDirective(CurrDir)) {
15490         DVar = DSAStack->getImplicitDSA(D, true);
15491         if (DVar.CKind != OMPC_shared &&
15492             (isOpenMPParallelDirective(DVar.DKind) ||
15493              isOpenMPTeamsDirective(DVar.DKind) ||
15494              DVar.DKind == OMPD_unknown)) {
15495           Diag(ELoc, diag::err_omp_required_access)
15496               << getOpenMPClauseName(OMPC_firstprivate)
15497               << getOpenMPClauseName(OMPC_shared);
15498           reportOriginalDsa(*this, DSAStack, D, DVar);
15499           continue;
15500         }
15501       }
15502       // OpenMP [2.9.3.4, Restrictions, p.3]
15503       //  A list item that appears in a reduction clause of a parallel construct
15504       //  must not appear in a firstprivate clause on a worksharing or task
15505       //  construct if any of the worksharing or task regions arising from the
15506       //  worksharing or task construct ever bind to any of the parallel regions
15507       //  arising from the parallel construct.
15508       // OpenMP [2.9.3.4, Restrictions, p.4]
15509       //  A list item that appears in a reduction clause in worksharing
15510       //  construct must not appear in a firstprivate clause in a task construct
15511       //  encountered during execution of any of the worksharing regions arising
15512       //  from the worksharing construct.
15513       if (isOpenMPTaskingDirective(CurrDir)) {
15514         DVar = DSAStack->hasInnermostDSA(
15515             D,
15516             [](OpenMPClauseKind C, bool AppliedToPointee) {
15517               return C == OMPC_reduction && !AppliedToPointee;
15518             },
15519             [](OpenMPDirectiveKind K) {
15520               return isOpenMPParallelDirective(K) ||
15521                      isOpenMPWorksharingDirective(K) ||
15522                      isOpenMPTeamsDirective(K);
15523             },
15524             /*FromParent=*/true);
15525         if (DVar.CKind == OMPC_reduction &&
15526             (isOpenMPParallelDirective(DVar.DKind) ||
15527              isOpenMPWorksharingDirective(DVar.DKind) ||
15528              isOpenMPTeamsDirective(DVar.DKind))) {
15529           Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
15530               << getOpenMPDirectiveName(DVar.DKind);
15531           reportOriginalDsa(*this, DSAStack, D, DVar);
15532           continue;
15533         }
15534       }
15535 
15536       // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
15537       // A list item cannot appear in both a map clause and a data-sharing
15538       // attribute clause on the same construct
15539       //
15540       // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
15541       // A list item cannot appear in both a map clause and a data-sharing
15542       // attribute clause on the same construct unless the construct is a
15543       // combined construct.
15544       if ((LangOpts.OpenMP <= 45 &&
15545            isOpenMPTargetExecutionDirective(CurrDir)) ||
15546           CurrDir == OMPD_target) {
15547         OpenMPClauseKind ConflictKind;
15548         if (DSAStack->checkMappableExprComponentListsForDecl(
15549                 VD, /*CurrentRegionOnly=*/true,
15550                 [&ConflictKind](
15551                     OMPClauseMappableExprCommon::MappableExprComponentListRef,
15552                     OpenMPClauseKind WhereFoundClauseKind) {
15553                   ConflictKind = WhereFoundClauseKind;
15554                   return true;
15555                 })) {
15556           Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
15557               << getOpenMPClauseName(OMPC_firstprivate)
15558               << getOpenMPClauseName(ConflictKind)
15559               << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
15560           reportOriginalDsa(*this, DSAStack, D, DVar);
15561           continue;
15562         }
15563       }
15564     }
15565 
15566     // Variably modified types are not supported for tasks.
15567     if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
15568         isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
15569       Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
15570           << getOpenMPClauseName(OMPC_firstprivate) << Type
15571           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
15572       bool IsDecl =
15573           !VD ||
15574           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
15575       Diag(D->getLocation(),
15576            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15577           << D;
15578       continue;
15579     }
15580 
15581     Type = Type.getUnqualifiedType();
15582     VarDecl *VDPrivate =
15583         buildVarDecl(*this, ELoc, Type, D->getName(),
15584                      D->hasAttrs() ? &D->getAttrs() : nullptr,
15585                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
15586     // Generate helper private variable and initialize it with the value of the
15587     // original variable. The address of the original variable is replaced by
15588     // the address of the new private variable in the CodeGen. This new variable
15589     // is not added to IdResolver, so the code in the OpenMP region uses
15590     // original variable for proper diagnostics and variable capturing.
15591     Expr *VDInitRefExpr = nullptr;
15592     // For arrays generate initializer for single element and replace it by the
15593     // original array element in CodeGen.
15594     if (Type->isArrayType()) {
15595       VarDecl *VDInit =
15596           buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
15597       VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
15598       Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
15599       ElemType = ElemType.getUnqualifiedType();
15600       VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
15601                                          ".firstprivate.temp");
15602       InitializedEntity Entity =
15603           InitializedEntity::InitializeVariable(VDInitTemp);
15604       InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
15605 
15606       InitializationSequence InitSeq(*this, Entity, Kind, Init);
15607       ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
15608       if (Result.isInvalid())
15609         VDPrivate->setInvalidDecl();
15610       else
15611         VDPrivate->setInit(Result.getAs<Expr>());
15612       // Remove temp variable declaration.
15613       Context.Deallocate(VDInitTemp);
15614     } else {
15615       VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
15616                                      ".firstprivate.temp");
15617       VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
15618                                        RefExpr->getExprLoc());
15619       AddInitializerToDecl(VDPrivate,
15620                            DefaultLvalueConversion(VDInitRefExpr).get(),
15621                            /*DirectInit=*/false);
15622     }
15623     if (VDPrivate->isInvalidDecl()) {
15624       if (IsImplicitClause) {
15625         Diag(RefExpr->getExprLoc(),
15626              diag::note_omp_task_predetermined_firstprivate_here);
15627       }
15628       continue;
15629     }
15630     CurContext->addDecl(VDPrivate);
15631     DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
15632         *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
15633         RefExpr->getExprLoc());
15634     DeclRefExpr *Ref = nullptr;
15635     if (!VD && !CurContext->isDependentContext()) {
15636       if (TopDVar.CKind == OMPC_lastprivate) {
15637         Ref = TopDVar.PrivateCopy;
15638       } else {
15639         Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
15640         if (!isOpenMPCapturedDecl(D))
15641           ExprCaptures.push_back(Ref->getDecl());
15642       }
15643     }
15644     if (!IsImplicitClause)
15645       DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
15646     Vars.push_back((VD || CurContext->isDependentContext())
15647                        ? RefExpr->IgnoreParens()
15648                        : Ref);
15649     PrivateCopies.push_back(VDPrivateRefExpr);
15650     Inits.push_back(VDInitRefExpr);
15651   }
15652 
15653   if (Vars.empty())
15654     return nullptr;
15655 
15656   return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
15657                                        Vars, PrivateCopies, Inits,
15658                                        buildPreInits(Context, ExprCaptures));
15659 }
15660 
ActOnOpenMPLastprivateClause(ArrayRef<Expr * > VarList,OpenMPLastprivateModifier LPKind,SourceLocation LPKindLoc,SourceLocation ColonLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)15661 OMPClause *Sema::ActOnOpenMPLastprivateClause(
15662     ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind,
15663     SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc,
15664     SourceLocation LParenLoc, SourceLocation EndLoc) {
15665   if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) {
15666     assert(ColonLoc.isValid() && "Colon location must be valid.");
15667     Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
15668         << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0,
15669                                    /*Last=*/OMPC_LASTPRIVATE_unknown)
15670         << getOpenMPClauseName(OMPC_lastprivate);
15671     return nullptr;
15672   }
15673 
15674   SmallVector<Expr *, 8> Vars;
15675   SmallVector<Expr *, 8> SrcExprs;
15676   SmallVector<Expr *, 8> DstExprs;
15677   SmallVector<Expr *, 8> AssignmentOps;
15678   SmallVector<Decl *, 4> ExprCaptures;
15679   SmallVector<Expr *, 4> ExprPostUpdates;
15680   for (Expr *RefExpr : VarList) {
15681     assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
15682     SourceLocation ELoc;
15683     SourceRange ERange;
15684     Expr *SimpleRefExpr = RefExpr;
15685     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15686     if (Res.second) {
15687       // It will be analyzed later.
15688       Vars.push_back(RefExpr);
15689       SrcExprs.push_back(nullptr);
15690       DstExprs.push_back(nullptr);
15691       AssignmentOps.push_back(nullptr);
15692     }
15693     ValueDecl *D = Res.first;
15694     if (!D)
15695       continue;
15696 
15697     QualType Type = D->getType();
15698     auto *VD = dyn_cast<VarDecl>(D);
15699 
15700     // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
15701     //  A variable that appears in a lastprivate clause must not have an
15702     //  incomplete type or a reference type.
15703     if (RequireCompleteType(ELoc, Type,
15704                             diag::err_omp_lastprivate_incomplete_type))
15705       continue;
15706     Type = Type.getNonReferenceType();
15707 
15708     // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
15709     // A variable that is privatized must not have a const-qualified type
15710     // unless it is of class type with a mutable member. This restriction does
15711     // not apply to the firstprivate clause.
15712     //
15713     // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
15714     // A variable that appears in a lastprivate clause must not have a
15715     // const-qualified type unless it is of class type with a mutable member.
15716     if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
15717       continue;
15718 
15719     // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions]
15720     // A list item that appears in a lastprivate clause with the conditional
15721     // modifier must be a scalar variable.
15722     if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) {
15723       Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
15724       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
15725                                VarDecl::DeclarationOnly;
15726       Diag(D->getLocation(),
15727            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15728           << D;
15729       continue;
15730     }
15731 
15732     OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
15733     // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
15734     // in a Construct]
15735     //  Variables with the predetermined data-sharing attributes may not be
15736     //  listed in data-sharing attributes clauses, except for the cases
15737     //  listed below.
15738     // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
15739     // A list item may appear in a firstprivate or lastprivate clause but not
15740     // both.
15741     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
15742     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
15743         (isOpenMPDistributeDirective(CurrDir) ||
15744          DVar.CKind != OMPC_firstprivate) &&
15745         (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
15746       Diag(ELoc, diag::err_omp_wrong_dsa)
15747           << getOpenMPClauseName(DVar.CKind)
15748           << getOpenMPClauseName(OMPC_lastprivate);
15749       reportOriginalDsa(*this, DSAStack, D, DVar);
15750       continue;
15751     }
15752 
15753     // OpenMP [2.14.3.5, Restrictions, p.2]
15754     // A list item that is private within a parallel region, or that appears in
15755     // the reduction clause of a parallel construct, must not appear in a
15756     // lastprivate clause on a worksharing construct if any of the corresponding
15757     // worksharing regions ever binds to any of the corresponding parallel
15758     // regions.
15759     DSAStackTy::DSAVarData TopDVar = DVar;
15760     if (isOpenMPWorksharingDirective(CurrDir) &&
15761         !isOpenMPParallelDirective(CurrDir) &&
15762         !isOpenMPTeamsDirective(CurrDir)) {
15763       DVar = DSAStack->getImplicitDSA(D, true);
15764       if (DVar.CKind != OMPC_shared) {
15765         Diag(ELoc, diag::err_omp_required_access)
15766             << getOpenMPClauseName(OMPC_lastprivate)
15767             << getOpenMPClauseName(OMPC_shared);
15768         reportOriginalDsa(*this, DSAStack, D, DVar);
15769         continue;
15770       }
15771     }
15772 
15773     // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
15774     //  A variable of class type (or array thereof) that appears in a
15775     //  lastprivate clause requires an accessible, unambiguous default
15776     //  constructor for the class type, unless the list item is also specified
15777     //  in a firstprivate clause.
15778     //  A variable of class type (or array thereof) that appears in a
15779     //  lastprivate clause requires an accessible, unambiguous copy assignment
15780     //  operator for the class type.
15781     Type = Context.getBaseElementType(Type).getNonReferenceType();
15782     VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
15783                                   Type.getUnqualifiedType(), ".lastprivate.src",
15784                                   D->hasAttrs() ? &D->getAttrs() : nullptr);
15785     DeclRefExpr *PseudoSrcExpr =
15786         buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
15787     VarDecl *DstVD =
15788         buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
15789                      D->hasAttrs() ? &D->getAttrs() : nullptr);
15790     DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
15791     // For arrays generate assignment operation for single element and replace
15792     // it by the original array element in CodeGen.
15793     ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
15794                                          PseudoDstExpr, PseudoSrcExpr);
15795     if (AssignmentOp.isInvalid())
15796       continue;
15797     AssignmentOp =
15798         ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
15799     if (AssignmentOp.isInvalid())
15800       continue;
15801 
15802     DeclRefExpr *Ref = nullptr;
15803     if (!VD && !CurContext->isDependentContext()) {
15804       if (TopDVar.CKind == OMPC_firstprivate) {
15805         Ref = TopDVar.PrivateCopy;
15806       } else {
15807         Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
15808         if (!isOpenMPCapturedDecl(D))
15809           ExprCaptures.push_back(Ref->getDecl());
15810       }
15811       if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) ||
15812           (!isOpenMPCapturedDecl(D) &&
15813            Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
15814         ExprResult RefRes = DefaultLvalueConversion(Ref);
15815         if (!RefRes.isUsable())
15816           continue;
15817         ExprResult PostUpdateRes =
15818             BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
15819                        RefRes.get());
15820         if (!PostUpdateRes.isUsable())
15821           continue;
15822         ExprPostUpdates.push_back(
15823             IgnoredValueConversions(PostUpdateRes.get()).get());
15824       }
15825     }
15826     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
15827     Vars.push_back((VD || CurContext->isDependentContext())
15828                        ? RefExpr->IgnoreParens()
15829                        : Ref);
15830     SrcExprs.push_back(PseudoSrcExpr);
15831     DstExprs.push_back(PseudoDstExpr);
15832     AssignmentOps.push_back(AssignmentOp.get());
15833   }
15834 
15835   if (Vars.empty())
15836     return nullptr;
15837 
15838   return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
15839                                       Vars, SrcExprs, DstExprs, AssignmentOps,
15840                                       LPKind, LPKindLoc, ColonLoc,
15841                                       buildPreInits(Context, ExprCaptures),
15842                                       buildPostUpdate(*this, ExprPostUpdates));
15843 }
15844 
ActOnOpenMPSharedClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)15845 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
15846                                          SourceLocation StartLoc,
15847                                          SourceLocation LParenLoc,
15848                                          SourceLocation EndLoc) {
15849   SmallVector<Expr *, 8> Vars;
15850   for (Expr *RefExpr : VarList) {
15851     assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
15852     SourceLocation ELoc;
15853     SourceRange ERange;
15854     Expr *SimpleRefExpr = RefExpr;
15855     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15856     if (Res.second) {
15857       // It will be analyzed later.
15858       Vars.push_back(RefExpr);
15859     }
15860     ValueDecl *D = Res.first;
15861     if (!D)
15862       continue;
15863 
15864     auto *VD = dyn_cast<VarDecl>(D);
15865     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
15866     // in a Construct]
15867     //  Variables with the predetermined data-sharing attributes may not be
15868     //  listed in data-sharing attributes clauses, except for the cases
15869     //  listed below. For these exceptions only, listing a predetermined
15870     //  variable in a data-sharing attribute clause is allowed and overrides
15871     //  the variable's predetermined data-sharing attributes.
15872     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
15873     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
15874         DVar.RefExpr) {
15875       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
15876                                           << getOpenMPClauseName(OMPC_shared);
15877       reportOriginalDsa(*this, DSAStack, D, DVar);
15878       continue;
15879     }
15880 
15881     DeclRefExpr *Ref = nullptr;
15882     if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
15883       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
15884     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
15885     Vars.push_back((VD || !Ref || CurContext->isDependentContext())
15886                        ? RefExpr->IgnoreParens()
15887                        : Ref);
15888   }
15889 
15890   if (Vars.empty())
15891     return nullptr;
15892 
15893   return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
15894 }
15895 
15896 namespace {
15897 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
15898   DSAStackTy *Stack;
15899 
15900 public:
VisitDeclRefExpr(DeclRefExpr * E)15901   bool VisitDeclRefExpr(DeclRefExpr *E) {
15902     if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
15903       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
15904       if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
15905         return false;
15906       if (DVar.CKind != OMPC_unknown)
15907         return true;
15908       DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
15909           VD,
15910           [](OpenMPClauseKind C, bool AppliedToPointee) {
15911             return isOpenMPPrivate(C) && !AppliedToPointee;
15912           },
15913           [](OpenMPDirectiveKind) { return true; },
15914           /*FromParent=*/true);
15915       return DVarPrivate.CKind != OMPC_unknown;
15916     }
15917     return false;
15918   }
VisitStmt(Stmt * S)15919   bool VisitStmt(Stmt *S) {
15920     for (Stmt *Child : S->children()) {
15921       if (Child && Visit(Child))
15922         return true;
15923     }
15924     return false;
15925   }
DSARefChecker(DSAStackTy * S)15926   explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
15927 };
15928 } // namespace
15929 
15930 namespace {
15931 // Transform MemberExpression for specified FieldDecl of current class to
15932 // DeclRefExpr to specified OMPCapturedExprDecl.
15933 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
15934   typedef TreeTransform<TransformExprToCaptures> BaseTransform;
15935   ValueDecl *Field = nullptr;
15936   DeclRefExpr *CapturedExpr = nullptr;
15937 
15938 public:
TransformExprToCaptures(Sema & SemaRef,ValueDecl * FieldDecl)15939   TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
15940       : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
15941 
TransformMemberExpr(MemberExpr * E)15942   ExprResult TransformMemberExpr(MemberExpr *E) {
15943     if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
15944         E->getMemberDecl() == Field) {
15945       CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
15946       return CapturedExpr;
15947     }
15948     return BaseTransform::TransformMemberExpr(E);
15949   }
getCapturedExpr()15950   DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
15951 };
15952 } // namespace
15953 
15954 template <typename T, typename U>
filterLookupForUDReductionAndMapper(SmallVectorImpl<U> & Lookups,const llvm::function_ref<T (ValueDecl *)> Gen)15955 static T filterLookupForUDReductionAndMapper(
15956     SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
15957   for (U &Set : Lookups) {
15958     for (auto *D : Set) {
15959       if (T Res = Gen(cast<ValueDecl>(D)))
15960         return Res;
15961     }
15962   }
15963   return T();
15964 }
15965 
findAcceptableDecl(Sema & SemaRef,NamedDecl * D)15966 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
15967   assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case");
15968 
15969   for (auto RD : D->redecls()) {
15970     // Don't bother with extra checks if we already know this one isn't visible.
15971     if (RD == D)
15972       continue;
15973 
15974     auto ND = cast<NamedDecl>(RD);
15975     if (LookupResult::isVisible(SemaRef, ND))
15976       return ND;
15977   }
15978 
15979   return nullptr;
15980 }
15981 
15982 static void
argumentDependentLookup(Sema & SemaRef,const DeclarationNameInfo & Id,SourceLocation Loc,QualType Ty,SmallVectorImpl<UnresolvedSet<8>> & Lookups)15983 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id,
15984                         SourceLocation Loc, QualType Ty,
15985                         SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
15986   // Find all of the associated namespaces and classes based on the
15987   // arguments we have.
15988   Sema::AssociatedNamespaceSet AssociatedNamespaces;
15989   Sema::AssociatedClassSet AssociatedClasses;
15990   OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
15991   SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
15992                                              AssociatedClasses);
15993 
15994   // C++ [basic.lookup.argdep]p3:
15995   //   Let X be the lookup set produced by unqualified lookup (3.4.1)
15996   //   and let Y be the lookup set produced by argument dependent
15997   //   lookup (defined as follows). If X contains [...] then Y is
15998   //   empty. Otherwise Y is the set of declarations found in the
15999   //   namespaces associated with the argument types as described
16000   //   below. The set of declarations found by the lookup of the name
16001   //   is the union of X and Y.
16002   //
16003   // Here, we compute Y and add its members to the overloaded
16004   // candidate set.
16005   for (auto *NS : AssociatedNamespaces) {
16006     //   When considering an associated namespace, the lookup is the
16007     //   same as the lookup performed when the associated namespace is
16008     //   used as a qualifier (3.4.3.2) except that:
16009     //
16010     //     -- Any using-directives in the associated namespace are
16011     //        ignored.
16012     //
16013     //     -- Any namespace-scope friend functions declared in
16014     //        associated classes are visible within their respective
16015     //        namespaces even if they are not visible during an ordinary
16016     //        lookup (11.4).
16017     DeclContext::lookup_result R = NS->lookup(Id.getName());
16018     for (auto *D : R) {
16019       auto *Underlying = D;
16020       if (auto *USD = dyn_cast<UsingShadowDecl>(D))
16021         Underlying = USD->getTargetDecl();
16022 
16023       if (!isa<OMPDeclareReductionDecl>(Underlying) &&
16024           !isa<OMPDeclareMapperDecl>(Underlying))
16025         continue;
16026 
16027       if (!SemaRef.isVisible(D)) {
16028         D = findAcceptableDecl(SemaRef, D);
16029         if (!D)
16030           continue;
16031         if (auto *USD = dyn_cast<UsingShadowDecl>(D))
16032           Underlying = USD->getTargetDecl();
16033       }
16034       Lookups.emplace_back();
16035       Lookups.back().addDecl(Underlying);
16036     }
16037   }
16038 }
16039 
16040 static ExprResult
buildDeclareReductionRef(Sema & SemaRef,SourceLocation Loc,SourceRange Range,Scope * S,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,QualType Ty,CXXCastPath & BasePath,Expr * UnresolvedReduction)16041 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
16042                          Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
16043                          const DeclarationNameInfo &ReductionId, QualType Ty,
16044                          CXXCastPath &BasePath, Expr *UnresolvedReduction) {
16045   if (ReductionIdScopeSpec.isInvalid())
16046     return ExprError();
16047   SmallVector<UnresolvedSet<8>, 4> Lookups;
16048   if (S) {
16049     LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
16050     Lookup.suppressDiagnostics();
16051     while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
16052       NamedDecl *D = Lookup.getRepresentativeDecl();
16053       do {
16054         S = S->getParent();
16055       } while (S && !S->isDeclScope(D));
16056       if (S)
16057         S = S->getParent();
16058       Lookups.emplace_back();
16059       Lookups.back().append(Lookup.begin(), Lookup.end());
16060       Lookup.clear();
16061     }
16062   } else if (auto *ULE =
16063                  cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
16064     Lookups.push_back(UnresolvedSet<8>());
16065     Decl *PrevD = nullptr;
16066     for (NamedDecl *D : ULE->decls()) {
16067       if (D == PrevD)
16068         Lookups.push_back(UnresolvedSet<8>());
16069       else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
16070         Lookups.back().addDecl(DRD);
16071       PrevD = D;
16072     }
16073   }
16074   if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
16075       Ty->isInstantiationDependentType() ||
16076       Ty->containsUnexpandedParameterPack() ||
16077       filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
16078         return !D->isInvalidDecl() &&
16079                (D->getType()->isDependentType() ||
16080                 D->getType()->isInstantiationDependentType() ||
16081                 D->getType()->containsUnexpandedParameterPack());
16082       })) {
16083     UnresolvedSet<8> ResSet;
16084     for (const UnresolvedSet<8> &Set : Lookups) {
16085       if (Set.empty())
16086         continue;
16087       ResSet.append(Set.begin(), Set.end());
16088       // The last item marks the end of all declarations at the specified scope.
16089       ResSet.addDecl(Set[Set.size() - 1]);
16090     }
16091     return UnresolvedLookupExpr::Create(
16092         SemaRef.Context, /*NamingClass=*/nullptr,
16093         ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
16094         /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
16095   }
16096   // Lookup inside the classes.
16097   // C++ [over.match.oper]p3:
16098   //   For a unary operator @ with an operand of a type whose
16099   //   cv-unqualified version is T1, and for a binary operator @ with
16100   //   a left operand of a type whose cv-unqualified version is T1 and
16101   //   a right operand of a type whose cv-unqualified version is T2,
16102   //   three sets of candidate functions, designated member
16103   //   candidates, non-member candidates and built-in candidates, are
16104   //   constructed as follows:
16105   //     -- If T1 is a complete class type or a class currently being
16106   //        defined, the set of member candidates is the result of the
16107   //        qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
16108   //        the set of member candidates is empty.
16109   LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
16110   Lookup.suppressDiagnostics();
16111   if (const auto *TyRec = Ty->getAs<RecordType>()) {
16112     // Complete the type if it can be completed.
16113     // If the type is neither complete nor being defined, bail out now.
16114     if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
16115         TyRec->getDecl()->getDefinition()) {
16116       Lookup.clear();
16117       SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
16118       if (Lookup.empty()) {
16119         Lookups.emplace_back();
16120         Lookups.back().append(Lookup.begin(), Lookup.end());
16121       }
16122     }
16123   }
16124   // Perform ADL.
16125   if (SemaRef.getLangOpts().CPlusPlus)
16126     argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
16127   if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
16128           Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
16129             if (!D->isInvalidDecl() &&
16130                 SemaRef.Context.hasSameType(D->getType(), Ty))
16131               return D;
16132             return nullptr;
16133           }))
16134     return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
16135                                     VK_LValue, Loc);
16136   if (SemaRef.getLangOpts().CPlusPlus) {
16137     if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
16138             Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
16139               if (!D->isInvalidDecl() &&
16140                   SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
16141                   !Ty.isMoreQualifiedThan(D->getType()))
16142                 return D;
16143               return nullptr;
16144             })) {
16145       CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
16146                          /*DetectVirtual=*/false);
16147       if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
16148         if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
16149                 VD->getType().getUnqualifiedType()))) {
16150           if (SemaRef.CheckBaseClassAccess(
16151                   Loc, VD->getType(), Ty, Paths.front(),
16152                   /*DiagID=*/0) != Sema::AR_inaccessible) {
16153             SemaRef.BuildBasePathArray(Paths, BasePath);
16154             return SemaRef.BuildDeclRefExpr(
16155                 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
16156           }
16157         }
16158       }
16159     }
16160   }
16161   if (ReductionIdScopeSpec.isSet()) {
16162     SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
16163         << Ty << Range;
16164     return ExprError();
16165   }
16166   return ExprEmpty();
16167 }
16168 
16169 namespace {
16170 /// Data for the reduction-based clauses.
16171 struct ReductionData {
16172   /// List of original reduction items.
16173   SmallVector<Expr *, 8> Vars;
16174   /// List of private copies of the reduction items.
16175   SmallVector<Expr *, 8> Privates;
16176   /// LHS expressions for the reduction_op expressions.
16177   SmallVector<Expr *, 8> LHSs;
16178   /// RHS expressions for the reduction_op expressions.
16179   SmallVector<Expr *, 8> RHSs;
16180   /// Reduction operation expression.
16181   SmallVector<Expr *, 8> ReductionOps;
16182   /// inscan copy operation expressions.
16183   SmallVector<Expr *, 8> InscanCopyOps;
16184   /// inscan copy temp array expressions for prefix sums.
16185   SmallVector<Expr *, 8> InscanCopyArrayTemps;
16186   /// inscan copy temp array element expressions for prefix sums.
16187   SmallVector<Expr *, 8> InscanCopyArrayElems;
16188   /// Taskgroup descriptors for the corresponding reduction items in
16189   /// in_reduction clauses.
16190   SmallVector<Expr *, 8> TaskgroupDescriptors;
16191   /// List of captures for clause.
16192   SmallVector<Decl *, 4> ExprCaptures;
16193   /// List of postupdate expressions.
16194   SmallVector<Expr *, 4> ExprPostUpdates;
16195   /// Reduction modifier.
16196   unsigned RedModifier = 0;
16197   ReductionData() = delete;
16198   /// Reserves required memory for the reduction data.
ReductionData__anon022d4e254c11::ReductionData16199   ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) {
16200     Vars.reserve(Size);
16201     Privates.reserve(Size);
16202     LHSs.reserve(Size);
16203     RHSs.reserve(Size);
16204     ReductionOps.reserve(Size);
16205     if (RedModifier == OMPC_REDUCTION_inscan) {
16206       InscanCopyOps.reserve(Size);
16207       InscanCopyArrayTemps.reserve(Size);
16208       InscanCopyArrayElems.reserve(Size);
16209     }
16210     TaskgroupDescriptors.reserve(Size);
16211     ExprCaptures.reserve(Size);
16212     ExprPostUpdates.reserve(Size);
16213   }
16214   /// Stores reduction item and reduction operation only (required for dependent
16215   /// reduction item).
push__anon022d4e254c11::ReductionData16216   void push(Expr *Item, Expr *ReductionOp) {
16217     Vars.emplace_back(Item);
16218     Privates.emplace_back(nullptr);
16219     LHSs.emplace_back(nullptr);
16220     RHSs.emplace_back(nullptr);
16221     ReductionOps.emplace_back(ReductionOp);
16222     TaskgroupDescriptors.emplace_back(nullptr);
16223     if (RedModifier == OMPC_REDUCTION_inscan) {
16224       InscanCopyOps.push_back(nullptr);
16225       InscanCopyArrayTemps.push_back(nullptr);
16226       InscanCopyArrayElems.push_back(nullptr);
16227     }
16228   }
16229   /// Stores reduction data.
push__anon022d4e254c11::ReductionData16230   void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
16231             Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp,
16232             Expr *CopyArrayElem) {
16233     Vars.emplace_back(Item);
16234     Privates.emplace_back(Private);
16235     LHSs.emplace_back(LHS);
16236     RHSs.emplace_back(RHS);
16237     ReductionOps.emplace_back(ReductionOp);
16238     TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
16239     if (RedModifier == OMPC_REDUCTION_inscan) {
16240       InscanCopyOps.push_back(CopyOp);
16241       InscanCopyArrayTemps.push_back(CopyArrayTemp);
16242       InscanCopyArrayElems.push_back(CopyArrayElem);
16243     } else {
16244       assert(CopyOp == nullptr && CopyArrayTemp == nullptr &&
16245              CopyArrayElem == nullptr &&
16246              "Copy operation must be used for inscan reductions only.");
16247     }
16248   }
16249 };
16250 } // namespace
16251 
checkOMPArraySectionConstantForReduction(ASTContext & Context,const OMPArraySectionExpr * OASE,bool & SingleElement,SmallVectorImpl<llvm::APSInt> & ArraySizes)16252 static bool checkOMPArraySectionConstantForReduction(
16253     ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
16254     SmallVectorImpl<llvm::APSInt> &ArraySizes) {
16255   const Expr *Length = OASE->getLength();
16256   if (Length == nullptr) {
16257     // For array sections of the form [1:] or [:], we would need to analyze
16258     // the lower bound...
16259     if (OASE->getColonLocFirst().isValid())
16260       return false;
16261 
16262     // This is an array subscript which has implicit length 1!
16263     SingleElement = true;
16264     ArraySizes.push_back(llvm::APSInt::get(1));
16265   } else {
16266     Expr::EvalResult Result;
16267     if (!Length->EvaluateAsInt(Result, Context))
16268       return false;
16269 
16270     llvm::APSInt ConstantLengthValue = Result.Val.getInt();
16271     SingleElement = (ConstantLengthValue.getSExtValue() == 1);
16272     ArraySizes.push_back(ConstantLengthValue);
16273   }
16274 
16275   // Get the base of this array section and walk up from there.
16276   const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
16277 
16278   // We require length = 1 for all array sections except the right-most to
16279   // guarantee that the memory region is contiguous and has no holes in it.
16280   while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
16281     Length = TempOASE->getLength();
16282     if (Length == nullptr) {
16283       // For array sections of the form [1:] or [:], we would need to analyze
16284       // the lower bound...
16285       if (OASE->getColonLocFirst().isValid())
16286         return false;
16287 
16288       // This is an array subscript which has implicit length 1!
16289       ArraySizes.push_back(llvm::APSInt::get(1));
16290     } else {
16291       Expr::EvalResult Result;
16292       if (!Length->EvaluateAsInt(Result, Context))
16293         return false;
16294 
16295       llvm::APSInt ConstantLengthValue = Result.Val.getInt();
16296       if (ConstantLengthValue.getSExtValue() != 1)
16297         return false;
16298 
16299       ArraySizes.push_back(ConstantLengthValue);
16300     }
16301     Base = TempOASE->getBase()->IgnoreParenImpCasts();
16302   }
16303 
16304   // If we have a single element, we don't need to add the implicit lengths.
16305   if (!SingleElement) {
16306     while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
16307       // Has implicit length 1!
16308       ArraySizes.push_back(llvm::APSInt::get(1));
16309       Base = TempASE->getBase()->IgnoreParenImpCasts();
16310     }
16311   }
16312 
16313   // This array section can be privatized as a single value or as a constant
16314   // sized array.
16315   return true;
16316 }
16317 
16318 static BinaryOperatorKind
getRelatedCompoundReductionOp(BinaryOperatorKind BOK)16319 getRelatedCompoundReductionOp(BinaryOperatorKind BOK) {
16320   if (BOK == BO_Add)
16321     return BO_AddAssign;
16322   if (BOK == BO_Mul)
16323     return BO_MulAssign;
16324   if (BOK == BO_And)
16325     return BO_AndAssign;
16326   if (BOK == BO_Or)
16327     return BO_OrAssign;
16328   if (BOK == BO_Xor)
16329     return BO_XorAssign;
16330   return BOK;
16331 }
16332 
actOnOMPReductionKindClause(Sema & S,DSAStackTy * Stack,OpenMPClauseKind ClauseKind,ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions,ReductionData & RD)16333 static bool actOnOMPReductionKindClause(
16334     Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
16335     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
16336     SourceLocation ColonLoc, SourceLocation EndLoc,
16337     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
16338     ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
16339   DeclarationName DN = ReductionId.getName();
16340   OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator();
16341   BinaryOperatorKind BOK = BO_Comma;
16342 
16343   ASTContext &Context = S.Context;
16344   // OpenMP [2.14.3.6, reduction clause]
16345   // C
16346   // reduction-identifier is either an identifier or one of the following
16347   // operators: +, -, *,  &, |, ^, && and ||
16348   // C++
16349   // reduction-identifier is either an id-expression or one of the following
16350   // operators: +, -, *, &, |, ^, && and ||
16351   switch (OOK) {
16352   case OO_Plus:
16353   case OO_Minus:
16354     BOK = BO_Add;
16355     break;
16356   case OO_Star:
16357     BOK = BO_Mul;
16358     break;
16359   case OO_Amp:
16360     BOK = BO_And;
16361     break;
16362   case OO_Pipe:
16363     BOK = BO_Or;
16364     break;
16365   case OO_Caret:
16366     BOK = BO_Xor;
16367     break;
16368   case OO_AmpAmp:
16369     BOK = BO_LAnd;
16370     break;
16371   case OO_PipePipe:
16372     BOK = BO_LOr;
16373     break;
16374   case OO_New:
16375   case OO_Delete:
16376   case OO_Array_New:
16377   case OO_Array_Delete:
16378   case OO_Slash:
16379   case OO_Percent:
16380   case OO_Tilde:
16381   case OO_Exclaim:
16382   case OO_Equal:
16383   case OO_Less:
16384   case OO_Greater:
16385   case OO_LessEqual:
16386   case OO_GreaterEqual:
16387   case OO_PlusEqual:
16388   case OO_MinusEqual:
16389   case OO_StarEqual:
16390   case OO_SlashEqual:
16391   case OO_PercentEqual:
16392   case OO_CaretEqual:
16393   case OO_AmpEqual:
16394   case OO_PipeEqual:
16395   case OO_LessLess:
16396   case OO_GreaterGreater:
16397   case OO_LessLessEqual:
16398   case OO_GreaterGreaterEqual:
16399   case OO_EqualEqual:
16400   case OO_ExclaimEqual:
16401   case OO_Spaceship:
16402   case OO_PlusPlus:
16403   case OO_MinusMinus:
16404   case OO_Comma:
16405   case OO_ArrowStar:
16406   case OO_Arrow:
16407   case OO_Call:
16408   case OO_Subscript:
16409   case OO_Conditional:
16410   case OO_Coawait:
16411   case NUM_OVERLOADED_OPERATORS:
16412     llvm_unreachable("Unexpected reduction identifier");
16413   case OO_None:
16414     if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
16415       if (II->isStr("max"))
16416         BOK = BO_GT;
16417       else if (II->isStr("min"))
16418         BOK = BO_LT;
16419     }
16420     break;
16421   }
16422   SourceRange ReductionIdRange;
16423   if (ReductionIdScopeSpec.isValid())
16424     ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
16425   else
16426     ReductionIdRange.setBegin(ReductionId.getBeginLoc());
16427   ReductionIdRange.setEnd(ReductionId.getEndLoc());
16428 
16429   auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
16430   bool FirstIter = true;
16431   for (Expr *RefExpr : VarList) {
16432     assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
16433     // OpenMP [2.1, C/C++]
16434     //  A list item is a variable or array section, subject to the restrictions
16435     //  specified in Section 2.4 on page 42 and in each of the sections
16436     // describing clauses and directives for which a list appears.
16437     // OpenMP  [2.14.3.3, Restrictions, p.1]
16438     //  A variable that is part of another variable (as an array or
16439     //  structure element) cannot appear in a private clause.
16440     if (!FirstIter && IR != ER)
16441       ++IR;
16442     FirstIter = false;
16443     SourceLocation ELoc;
16444     SourceRange ERange;
16445     Expr *SimpleRefExpr = RefExpr;
16446     auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
16447                               /*AllowArraySection=*/true);
16448     if (Res.second) {
16449       // Try to find 'declare reduction' corresponding construct before using
16450       // builtin/overloaded operators.
16451       QualType Type = Context.DependentTy;
16452       CXXCastPath BasePath;
16453       ExprResult DeclareReductionRef = buildDeclareReductionRef(
16454           S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
16455           ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
16456       Expr *ReductionOp = nullptr;
16457       if (S.CurContext->isDependentContext() &&
16458           (DeclareReductionRef.isUnset() ||
16459            isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
16460         ReductionOp = DeclareReductionRef.get();
16461       // It will be analyzed later.
16462       RD.push(RefExpr, ReductionOp);
16463     }
16464     ValueDecl *D = Res.first;
16465     if (!D)
16466       continue;
16467 
16468     Expr *TaskgroupDescriptor = nullptr;
16469     QualType Type;
16470     auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
16471     auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
16472     if (ASE) {
16473       Type = ASE->getType().getNonReferenceType();
16474     } else if (OASE) {
16475       QualType BaseType =
16476           OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
16477       if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
16478         Type = ATy->getElementType();
16479       else
16480         Type = BaseType->getPointeeType();
16481       Type = Type.getNonReferenceType();
16482     } else {
16483       Type = Context.getBaseElementType(D->getType().getNonReferenceType());
16484     }
16485     auto *VD = dyn_cast<VarDecl>(D);
16486 
16487     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
16488     //  A variable that appears in a private clause must not have an incomplete
16489     //  type or a reference type.
16490     if (S.RequireCompleteType(ELoc, D->getType(),
16491                               diag::err_omp_reduction_incomplete_type))
16492       continue;
16493     // OpenMP [2.14.3.6, reduction clause, Restrictions]
16494     // A list item that appears in a reduction clause must not be
16495     // const-qualified.
16496     if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
16497                                   /*AcceptIfMutable*/ false, ASE || OASE))
16498       continue;
16499 
16500     OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
16501     // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
16502     //  If a list-item is a reference type then it must bind to the same object
16503     //  for all threads of the team.
16504     if (!ASE && !OASE) {
16505       if (VD) {
16506         VarDecl *VDDef = VD->getDefinition();
16507         if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
16508           DSARefChecker Check(Stack);
16509           if (Check.Visit(VDDef->getInit())) {
16510             S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
16511                 << getOpenMPClauseName(ClauseKind) << ERange;
16512             S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
16513             continue;
16514           }
16515         }
16516       }
16517 
16518       // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
16519       // in a Construct]
16520       //  Variables with the predetermined data-sharing attributes may not be
16521       //  listed in data-sharing attributes clauses, except for the cases
16522       //  listed below. For these exceptions only, listing a predetermined
16523       //  variable in a data-sharing attribute clause is allowed and overrides
16524       //  the variable's predetermined data-sharing attributes.
16525       // OpenMP [2.14.3.6, Restrictions, p.3]
16526       //  Any number of reduction clauses can be specified on the directive,
16527       //  but a list item can appear only once in the reduction clauses for that
16528       //  directive.
16529       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
16530       if (DVar.CKind == OMPC_reduction) {
16531         S.Diag(ELoc, diag::err_omp_once_referenced)
16532             << getOpenMPClauseName(ClauseKind);
16533         if (DVar.RefExpr)
16534           S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
16535         continue;
16536       }
16537       if (DVar.CKind != OMPC_unknown) {
16538         S.Diag(ELoc, diag::err_omp_wrong_dsa)
16539             << getOpenMPClauseName(DVar.CKind)
16540             << getOpenMPClauseName(OMPC_reduction);
16541         reportOriginalDsa(S, Stack, D, DVar);
16542         continue;
16543       }
16544 
16545       // OpenMP [2.14.3.6, Restrictions, p.1]
16546       //  A list item that appears in a reduction clause of a worksharing
16547       //  construct must be shared in the parallel regions to which any of the
16548       //  worksharing regions arising from the worksharing construct bind.
16549       if (isOpenMPWorksharingDirective(CurrDir) &&
16550           !isOpenMPParallelDirective(CurrDir) &&
16551           !isOpenMPTeamsDirective(CurrDir)) {
16552         DVar = Stack->getImplicitDSA(D, true);
16553         if (DVar.CKind != OMPC_shared) {
16554           S.Diag(ELoc, diag::err_omp_required_access)
16555               << getOpenMPClauseName(OMPC_reduction)
16556               << getOpenMPClauseName(OMPC_shared);
16557           reportOriginalDsa(S, Stack, D, DVar);
16558           continue;
16559         }
16560       }
16561     } else {
16562       // Threadprivates cannot be shared between threads, so dignose if the base
16563       // is a threadprivate variable.
16564       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
16565       if (DVar.CKind == OMPC_threadprivate) {
16566         S.Diag(ELoc, diag::err_omp_wrong_dsa)
16567             << getOpenMPClauseName(DVar.CKind)
16568             << getOpenMPClauseName(OMPC_reduction);
16569         reportOriginalDsa(S, Stack, D, DVar);
16570         continue;
16571       }
16572     }
16573 
16574     // Try to find 'declare reduction' corresponding construct before using
16575     // builtin/overloaded operators.
16576     CXXCastPath BasePath;
16577     ExprResult DeclareReductionRef = buildDeclareReductionRef(
16578         S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
16579         ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
16580     if (DeclareReductionRef.isInvalid())
16581       continue;
16582     if (S.CurContext->isDependentContext() &&
16583         (DeclareReductionRef.isUnset() ||
16584          isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
16585       RD.push(RefExpr, DeclareReductionRef.get());
16586       continue;
16587     }
16588     if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
16589       // Not allowed reduction identifier is found.
16590       S.Diag(ReductionId.getBeginLoc(),
16591              diag::err_omp_unknown_reduction_identifier)
16592           << Type << ReductionIdRange;
16593       continue;
16594     }
16595 
16596     // OpenMP [2.14.3.6, reduction clause, Restrictions]
16597     // The type of a list item that appears in a reduction clause must be valid
16598     // for the reduction-identifier. For a max or min reduction in C, the type
16599     // of the list item must be an allowed arithmetic data type: char, int,
16600     // float, double, or _Bool, possibly modified with long, short, signed, or
16601     // unsigned. For a max or min reduction in C++, the type of the list item
16602     // must be an allowed arithmetic data type: char, wchar_t, int, float,
16603     // double, or bool, possibly modified with long, short, signed, or unsigned.
16604     if (DeclareReductionRef.isUnset()) {
16605       if ((BOK == BO_GT || BOK == BO_LT) &&
16606           !(Type->isScalarType() ||
16607             (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
16608         S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
16609             << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
16610         if (!ASE && !OASE) {
16611           bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
16612                                    VarDecl::DeclarationOnly;
16613           S.Diag(D->getLocation(),
16614                  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16615               << D;
16616         }
16617         continue;
16618       }
16619       if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
16620           !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
16621         S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
16622             << getOpenMPClauseName(ClauseKind);
16623         if (!ASE && !OASE) {
16624           bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
16625                                    VarDecl::DeclarationOnly;
16626           S.Diag(D->getLocation(),
16627                  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16628               << D;
16629         }
16630         continue;
16631       }
16632     }
16633 
16634     Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
16635     VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
16636                                   D->hasAttrs() ? &D->getAttrs() : nullptr);
16637     VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
16638                                   D->hasAttrs() ? &D->getAttrs() : nullptr);
16639     QualType PrivateTy = Type;
16640 
16641     // Try if we can determine constant lengths for all array sections and avoid
16642     // the VLA.
16643     bool ConstantLengthOASE = false;
16644     if (OASE) {
16645       bool SingleElement;
16646       llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
16647       ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
16648           Context, OASE, SingleElement, ArraySizes);
16649 
16650       // If we don't have a single element, we must emit a constant array type.
16651       if (ConstantLengthOASE && !SingleElement) {
16652         for (llvm::APSInt &Size : ArraySizes)
16653           PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr,
16654                                                    ArrayType::Normal,
16655                                                    /*IndexTypeQuals=*/0);
16656       }
16657     }
16658 
16659     if ((OASE && !ConstantLengthOASE) ||
16660         (!OASE && !ASE &&
16661          D->getType().getNonReferenceType()->isVariablyModifiedType())) {
16662       if (!Context.getTargetInfo().isVLASupported()) {
16663         if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) {
16664           S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
16665           S.Diag(ELoc, diag::note_vla_unsupported);
16666           continue;
16667         } else {
16668           S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
16669           S.targetDiag(ELoc, diag::note_vla_unsupported);
16670         }
16671       }
16672       // For arrays/array sections only:
16673       // Create pseudo array type for private copy. The size for this array will
16674       // be generated during codegen.
16675       // For array subscripts or single variables Private Ty is the same as Type
16676       // (type of the variable or single array element).
16677       PrivateTy = Context.getVariableArrayType(
16678           Type,
16679           new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue),
16680           ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
16681     } else if (!ASE && !OASE &&
16682                Context.getAsArrayType(D->getType().getNonReferenceType())) {
16683       PrivateTy = D->getType().getNonReferenceType();
16684     }
16685     // Private copy.
16686     VarDecl *PrivateVD =
16687         buildVarDecl(S, ELoc, PrivateTy, D->getName(),
16688                      D->hasAttrs() ? &D->getAttrs() : nullptr,
16689                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
16690     // Add initializer for private variable.
16691     Expr *Init = nullptr;
16692     DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
16693     DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
16694     if (DeclareReductionRef.isUsable()) {
16695       auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
16696       auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
16697       if (DRD->getInitializer()) {
16698         S.ActOnUninitializedDecl(PrivateVD);
16699         Init = DRDRef;
16700         RHSVD->setInit(DRDRef);
16701         RHSVD->setInitStyle(VarDecl::CallInit);
16702       }
16703     } else {
16704       switch (BOK) {
16705       case BO_Add:
16706       case BO_Xor:
16707       case BO_Or:
16708       case BO_LOr:
16709         // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
16710         if (Type->isScalarType() || Type->isAnyComplexType())
16711           Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
16712         break;
16713       case BO_Mul:
16714       case BO_LAnd:
16715         if (Type->isScalarType() || Type->isAnyComplexType()) {
16716           // '*' and '&&' reduction ops - initializer is '1'.
16717           Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
16718         }
16719         break;
16720       case BO_And: {
16721         // '&' reduction op - initializer is '~0'.
16722         QualType OrigType = Type;
16723         if (auto *ComplexTy = OrigType->getAs<ComplexType>())
16724           Type = ComplexTy->getElementType();
16725         if (Type->isRealFloatingType()) {
16726           llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue(
16727               Context.getFloatTypeSemantics(Type),
16728               Context.getTypeSize(Type));
16729           Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
16730                                          Type, ELoc);
16731         } else if (Type->isScalarType()) {
16732           uint64_t Size = Context.getTypeSize(Type);
16733           QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
16734           llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
16735           Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
16736         }
16737         if (Init && OrigType->isAnyComplexType()) {
16738           // Init = 0xFFFF + 0xFFFFi;
16739           auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
16740           Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
16741         }
16742         Type = OrigType;
16743         break;
16744       }
16745       case BO_LT:
16746       case BO_GT: {
16747         // 'min' reduction op - initializer is 'Largest representable number in
16748         // the reduction list item type'.
16749         // 'max' reduction op - initializer is 'Least representable number in
16750         // the reduction list item type'.
16751         if (Type->isIntegerType() || Type->isPointerType()) {
16752           bool IsSigned = Type->hasSignedIntegerRepresentation();
16753           uint64_t Size = Context.getTypeSize(Type);
16754           QualType IntTy =
16755               Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
16756           llvm::APInt InitValue =
16757               (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
16758                                         : llvm::APInt::getMinValue(Size)
16759                              : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
16760                                         : llvm::APInt::getMaxValue(Size);
16761           Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
16762           if (Type->isPointerType()) {
16763             // Cast to pointer type.
16764             ExprResult CastExpr = S.BuildCStyleCastExpr(
16765                 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
16766             if (CastExpr.isInvalid())
16767               continue;
16768             Init = CastExpr.get();
16769           }
16770         } else if (Type->isRealFloatingType()) {
16771           llvm::APFloat InitValue = llvm::APFloat::getLargest(
16772               Context.getFloatTypeSemantics(Type), BOK != BO_LT);
16773           Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
16774                                          Type, ELoc);
16775         }
16776         break;
16777       }
16778       case BO_PtrMemD:
16779       case BO_PtrMemI:
16780       case BO_MulAssign:
16781       case BO_Div:
16782       case BO_Rem:
16783       case BO_Sub:
16784       case BO_Shl:
16785       case BO_Shr:
16786       case BO_LE:
16787       case BO_GE:
16788       case BO_EQ:
16789       case BO_NE:
16790       case BO_Cmp:
16791       case BO_AndAssign:
16792       case BO_XorAssign:
16793       case BO_OrAssign:
16794       case BO_Assign:
16795       case BO_AddAssign:
16796       case BO_SubAssign:
16797       case BO_DivAssign:
16798       case BO_RemAssign:
16799       case BO_ShlAssign:
16800       case BO_ShrAssign:
16801       case BO_Comma:
16802         llvm_unreachable("Unexpected reduction operation");
16803       }
16804     }
16805     if (Init && DeclareReductionRef.isUnset()) {
16806       S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
16807       // Store initializer for single element in private copy. Will be used
16808       // during codegen.
16809       PrivateVD->setInit(RHSVD->getInit());
16810       PrivateVD->setInitStyle(RHSVD->getInitStyle());
16811     } else if (!Init) {
16812       S.ActOnUninitializedDecl(RHSVD);
16813       // Store initializer for single element in private copy. Will be used
16814       // during codegen.
16815       PrivateVD->setInit(RHSVD->getInit());
16816       PrivateVD->setInitStyle(RHSVD->getInitStyle());
16817     }
16818     if (RHSVD->isInvalidDecl())
16819       continue;
16820     if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) {
16821       S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
16822           << Type << ReductionIdRange;
16823       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
16824                                VarDecl::DeclarationOnly;
16825       S.Diag(D->getLocation(),
16826              IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16827           << D;
16828       continue;
16829     }
16830     DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
16831     ExprResult ReductionOp;
16832     if (DeclareReductionRef.isUsable()) {
16833       QualType RedTy = DeclareReductionRef.get()->getType();
16834       QualType PtrRedTy = Context.getPointerType(RedTy);
16835       ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
16836       ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
16837       if (!BasePath.empty()) {
16838         LHS = S.DefaultLvalueConversion(LHS.get());
16839         RHS = S.DefaultLvalueConversion(RHS.get());
16840         LHS = ImplicitCastExpr::Create(
16841             Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath,
16842             LHS.get()->getValueKind(), FPOptionsOverride());
16843         RHS = ImplicitCastExpr::Create(
16844             Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath,
16845             RHS.get()->getValueKind(), FPOptionsOverride());
16846       }
16847       FunctionProtoType::ExtProtoInfo EPI;
16848       QualType Params[] = {PtrRedTy, PtrRedTy};
16849       QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
16850       auto *OVE = new (Context) OpaqueValueExpr(
16851           ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary,
16852           S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
16853       Expr *Args[] = {LHS.get(), RHS.get()};
16854       ReductionOp =
16855           CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc,
16856                            S.CurFPFeatureOverrides());
16857     } else {
16858       BinaryOperatorKind CombBOK = getRelatedCompoundReductionOp(BOK);
16859       if (Type->isRecordType() && CombBOK != BOK) {
16860         Sema::TentativeAnalysisScope Trap(S);
16861         ReductionOp =
16862             S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
16863                          CombBOK, LHSDRE, RHSDRE);
16864       }
16865       if (!ReductionOp.isUsable()) {
16866         ReductionOp =
16867             S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), BOK,
16868                          LHSDRE, RHSDRE);
16869         if (ReductionOp.isUsable()) {
16870           if (BOK != BO_LT && BOK != BO_GT) {
16871             ReductionOp =
16872                 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
16873                              BO_Assign, LHSDRE, ReductionOp.get());
16874           } else {
16875             auto *ConditionalOp = new (Context)
16876                 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc,
16877                                     RHSDRE, Type, VK_LValue, OK_Ordinary);
16878             ReductionOp =
16879                 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
16880                              BO_Assign, LHSDRE, ConditionalOp);
16881           }
16882         }
16883       }
16884       if (ReductionOp.isUsable())
16885         ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
16886                                             /*DiscardedValue*/ false);
16887       if (!ReductionOp.isUsable())
16888         continue;
16889     }
16890 
16891     // Add copy operations for inscan reductions.
16892     // LHS = RHS;
16893     ExprResult CopyOpRes, TempArrayRes, TempArrayElem;
16894     if (ClauseKind == OMPC_reduction &&
16895         RD.RedModifier == OMPC_REDUCTION_inscan) {
16896       ExprResult RHS = S.DefaultLvalueConversion(RHSDRE);
16897       CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE,
16898                                RHS.get());
16899       if (!CopyOpRes.isUsable())
16900         continue;
16901       CopyOpRes =
16902           S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true);
16903       if (!CopyOpRes.isUsable())
16904         continue;
16905       // For simd directive and simd-based directives in simd mode no need to
16906       // construct temp array, need just a single temp element.
16907       if (Stack->getCurrentDirective() == OMPD_simd ||
16908           (S.getLangOpts().OpenMPSimd &&
16909            isOpenMPSimdDirective(Stack->getCurrentDirective()))) {
16910         VarDecl *TempArrayVD =
16911             buildVarDecl(S, ELoc, PrivateTy, D->getName(),
16912                          D->hasAttrs() ? &D->getAttrs() : nullptr);
16913         // Add a constructor to the temp decl.
16914         S.ActOnUninitializedDecl(TempArrayVD);
16915         TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc);
16916       } else {
16917         // Build temp array for prefix sum.
16918         auto *Dim = new (S.Context)
16919             OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue);
16920         QualType ArrayTy =
16921             S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal,
16922                                            /*IndexTypeQuals=*/0, {ELoc, ELoc});
16923         VarDecl *TempArrayVD =
16924             buildVarDecl(S, ELoc, ArrayTy, D->getName(),
16925                          D->hasAttrs() ? &D->getAttrs() : nullptr);
16926         // Add a constructor to the temp decl.
16927         S.ActOnUninitializedDecl(TempArrayVD);
16928         TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc);
16929         TempArrayElem =
16930             S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get());
16931         auto *Idx = new (S.Context)
16932             OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue);
16933         TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(),
16934                                                           ELoc, Idx, ELoc);
16935       }
16936     }
16937 
16938     // OpenMP [2.15.4.6, Restrictions, p.2]
16939     // A list item that appears in an in_reduction clause of a task construct
16940     // must appear in a task_reduction clause of a construct associated with a
16941     // taskgroup region that includes the participating task in its taskgroup
16942     // set. The construct associated with the innermost region that meets this
16943     // condition must specify the same reduction-identifier as the in_reduction
16944     // clause.
16945     if (ClauseKind == OMPC_in_reduction) {
16946       SourceRange ParentSR;
16947       BinaryOperatorKind ParentBOK;
16948       const Expr *ParentReductionOp = nullptr;
16949       Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr;
16950       DSAStackTy::DSAVarData ParentBOKDSA =
16951           Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
16952                                                   ParentBOKTD);
16953       DSAStackTy::DSAVarData ParentReductionOpDSA =
16954           Stack->getTopMostTaskgroupReductionData(
16955               D, ParentSR, ParentReductionOp, ParentReductionOpTD);
16956       bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
16957       bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
16958       if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
16959           (DeclareReductionRef.isUsable() && IsParentBOK) ||
16960           (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) {
16961         bool EmitError = true;
16962         if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
16963           llvm::FoldingSetNodeID RedId, ParentRedId;
16964           ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
16965           DeclareReductionRef.get()->Profile(RedId, Context,
16966                                              /*Canonical=*/true);
16967           EmitError = RedId != ParentRedId;
16968         }
16969         if (EmitError) {
16970           S.Diag(ReductionId.getBeginLoc(),
16971                  diag::err_omp_reduction_identifier_mismatch)
16972               << ReductionIdRange << RefExpr->getSourceRange();
16973           S.Diag(ParentSR.getBegin(),
16974                  diag::note_omp_previous_reduction_identifier)
16975               << ParentSR
16976               << (IsParentBOK ? ParentBOKDSA.RefExpr
16977                               : ParentReductionOpDSA.RefExpr)
16978                      ->getSourceRange();
16979           continue;
16980         }
16981       }
16982       TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
16983     }
16984 
16985     DeclRefExpr *Ref = nullptr;
16986     Expr *VarsExpr = RefExpr->IgnoreParens();
16987     if (!VD && !S.CurContext->isDependentContext()) {
16988       if (ASE || OASE) {
16989         TransformExprToCaptures RebuildToCapture(S, D);
16990         VarsExpr =
16991             RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
16992         Ref = RebuildToCapture.getCapturedExpr();
16993       } else {
16994         VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
16995       }
16996       if (!S.isOpenMPCapturedDecl(D)) {
16997         RD.ExprCaptures.emplace_back(Ref->getDecl());
16998         if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
16999           ExprResult RefRes = S.DefaultLvalueConversion(Ref);
17000           if (!RefRes.isUsable())
17001             continue;
17002           ExprResult PostUpdateRes =
17003               S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
17004                            RefRes.get());
17005           if (!PostUpdateRes.isUsable())
17006             continue;
17007           if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
17008               Stack->getCurrentDirective() == OMPD_taskgroup) {
17009             S.Diag(RefExpr->getExprLoc(),
17010                    diag::err_omp_reduction_non_addressable_expression)
17011                 << RefExpr->getSourceRange();
17012             continue;
17013           }
17014           RD.ExprPostUpdates.emplace_back(
17015               S.IgnoredValueConversions(PostUpdateRes.get()).get());
17016         }
17017       }
17018     }
17019     // All reduction items are still marked as reduction (to do not increase
17020     // code base size).
17021     unsigned Modifier = RD.RedModifier;
17022     // Consider task_reductions as reductions with task modifier. Required for
17023     // correct analysis of in_reduction clauses.
17024     if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction)
17025       Modifier = OMPC_REDUCTION_task;
17026     Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier,
17027                   ASE || OASE);
17028     if (Modifier == OMPC_REDUCTION_task &&
17029         (CurrDir == OMPD_taskgroup ||
17030          ((isOpenMPParallelDirective(CurrDir) ||
17031            isOpenMPWorksharingDirective(CurrDir)) &&
17032           !isOpenMPSimdDirective(CurrDir)))) {
17033       if (DeclareReductionRef.isUsable())
17034         Stack->addTaskgroupReductionData(D, ReductionIdRange,
17035                                          DeclareReductionRef.get());
17036       else
17037         Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
17038     }
17039     RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
17040             TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(),
17041             TempArrayElem.get());
17042   }
17043   return RD.Vars.empty();
17044 }
17045 
ActOnOpenMPReductionClause(ArrayRef<Expr * > VarList,OpenMPReductionClauseModifier Modifier,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ModifierLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)17046 OMPClause *Sema::ActOnOpenMPReductionClause(
17047     ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
17048     SourceLocation StartLoc, SourceLocation LParenLoc,
17049     SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
17050     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
17051     ArrayRef<Expr *> UnresolvedReductions) {
17052   if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) {
17053     Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
17054         << getListOfPossibleValues(OMPC_reduction, /*First=*/0,
17055                                    /*Last=*/OMPC_REDUCTION_unknown)
17056         << getOpenMPClauseName(OMPC_reduction);
17057     return nullptr;
17058   }
17059   // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions
17060   // A reduction clause with the inscan reduction-modifier may only appear on a
17061   // worksharing-loop construct, a worksharing-loop SIMD construct, a simd
17062   // construct, a parallel worksharing-loop construct or a parallel
17063   // worksharing-loop SIMD construct.
17064   if (Modifier == OMPC_REDUCTION_inscan &&
17065       (DSAStack->getCurrentDirective() != OMPD_for &&
17066        DSAStack->getCurrentDirective() != OMPD_for_simd &&
17067        DSAStack->getCurrentDirective() != OMPD_simd &&
17068        DSAStack->getCurrentDirective() != OMPD_parallel_for &&
17069        DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) {
17070     Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
17071     return nullptr;
17072   }
17073 
17074   ReductionData RD(VarList.size(), Modifier);
17075   if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList,
17076                                   StartLoc, LParenLoc, ColonLoc, EndLoc,
17077                                   ReductionIdScopeSpec, ReductionId,
17078                                   UnresolvedReductions, RD))
17079     return nullptr;
17080 
17081   return OMPReductionClause::Create(
17082       Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier,
17083       RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
17084       RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps,
17085       RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems,
17086       buildPreInits(Context, RD.ExprCaptures),
17087       buildPostUpdate(*this, RD.ExprPostUpdates));
17088 }
17089 
ActOnOpenMPTaskReductionClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)17090 OMPClause *Sema::ActOnOpenMPTaskReductionClause(
17091     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
17092     SourceLocation ColonLoc, SourceLocation EndLoc,
17093     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
17094     ArrayRef<Expr *> UnresolvedReductions) {
17095   ReductionData RD(VarList.size());
17096   if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList,
17097                                   StartLoc, LParenLoc, ColonLoc, EndLoc,
17098                                   ReductionIdScopeSpec, ReductionId,
17099                                   UnresolvedReductions, RD))
17100     return nullptr;
17101 
17102   return OMPTaskReductionClause::Create(
17103       Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
17104       ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
17105       RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
17106       buildPreInits(Context, RD.ExprCaptures),
17107       buildPostUpdate(*this, RD.ExprPostUpdates));
17108 }
17109 
ActOnOpenMPInReductionClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)17110 OMPClause *Sema::ActOnOpenMPInReductionClause(
17111     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
17112     SourceLocation ColonLoc, SourceLocation EndLoc,
17113     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
17114     ArrayRef<Expr *> UnresolvedReductions) {
17115   ReductionData RD(VarList.size());
17116   if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList,
17117                                   StartLoc, LParenLoc, ColonLoc, EndLoc,
17118                                   ReductionIdScopeSpec, ReductionId,
17119                                   UnresolvedReductions, RD))
17120     return nullptr;
17121 
17122   return OMPInReductionClause::Create(
17123       Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
17124       ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
17125       RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
17126       buildPreInits(Context, RD.ExprCaptures),
17127       buildPostUpdate(*this, RD.ExprPostUpdates));
17128 }
17129 
CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,SourceLocation LinLoc)17130 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
17131                                      SourceLocation LinLoc) {
17132   if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
17133       LinKind == OMPC_LINEAR_unknown) {
17134     Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
17135     return true;
17136   }
17137   return false;
17138 }
17139 
CheckOpenMPLinearDecl(const ValueDecl * D,SourceLocation ELoc,OpenMPLinearClauseKind LinKind,QualType Type,bool IsDeclareSimd)17140 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
17141                                  OpenMPLinearClauseKind LinKind, QualType Type,
17142                                  bool IsDeclareSimd) {
17143   const auto *VD = dyn_cast_or_null<VarDecl>(D);
17144   // A variable must not have an incomplete type or a reference type.
17145   if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
17146     return true;
17147   if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
17148       !Type->isReferenceType()) {
17149     Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
17150         << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
17151     return true;
17152   }
17153   Type = Type.getNonReferenceType();
17154 
17155   // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
17156   // A variable that is privatized must not have a const-qualified type
17157   // unless it is of class type with a mutable member. This restriction does
17158   // not apply to the firstprivate clause, nor to the linear clause on
17159   // declarative directives (like declare simd).
17160   if (!IsDeclareSimd &&
17161       rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
17162     return true;
17163 
17164   // A list item must be of integral or pointer type.
17165   Type = Type.getUnqualifiedType().getCanonicalType();
17166   const auto *Ty = Type.getTypePtrOrNull();
17167   if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
17168               !Ty->isIntegralType(Context) && !Ty->isPointerType())) {
17169     Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
17170     if (D) {
17171       bool IsDecl =
17172           !VD ||
17173           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
17174       Diag(D->getLocation(),
17175            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17176           << D;
17177     }
17178     return true;
17179   }
17180   return false;
17181 }
17182 
ActOnOpenMPLinearClause(ArrayRef<Expr * > VarList,Expr * Step,SourceLocation StartLoc,SourceLocation LParenLoc,OpenMPLinearClauseKind LinKind,SourceLocation LinLoc,SourceLocation ColonLoc,SourceLocation EndLoc)17183 OMPClause *Sema::ActOnOpenMPLinearClause(
17184     ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
17185     SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
17186     SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
17187   SmallVector<Expr *, 8> Vars;
17188   SmallVector<Expr *, 8> Privates;
17189   SmallVector<Expr *, 8> Inits;
17190   SmallVector<Decl *, 4> ExprCaptures;
17191   SmallVector<Expr *, 4> ExprPostUpdates;
17192   if (CheckOpenMPLinearModifier(LinKind, LinLoc))
17193     LinKind = OMPC_LINEAR_val;
17194   for (Expr *RefExpr : VarList) {
17195     assert(RefExpr && "NULL expr in OpenMP linear clause.");
17196     SourceLocation ELoc;
17197     SourceRange ERange;
17198     Expr *SimpleRefExpr = RefExpr;
17199     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17200     if (Res.second) {
17201       // It will be analyzed later.
17202       Vars.push_back(RefExpr);
17203       Privates.push_back(nullptr);
17204       Inits.push_back(nullptr);
17205     }
17206     ValueDecl *D = Res.first;
17207     if (!D)
17208       continue;
17209 
17210     QualType Type = D->getType();
17211     auto *VD = dyn_cast<VarDecl>(D);
17212 
17213     // OpenMP [2.14.3.7, linear clause]
17214     //  A list-item cannot appear in more than one linear clause.
17215     //  A list-item that appears in a linear clause cannot appear in any
17216     //  other data-sharing attribute clause.
17217     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
17218     if (DVar.RefExpr) {
17219       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
17220                                           << getOpenMPClauseName(OMPC_linear);
17221       reportOriginalDsa(*this, DSAStack, D, DVar);
17222       continue;
17223     }
17224 
17225     if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
17226       continue;
17227     Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
17228 
17229     // Build private copy of original var.
17230     VarDecl *Private =
17231         buildVarDecl(*this, ELoc, Type, D->getName(),
17232                      D->hasAttrs() ? &D->getAttrs() : nullptr,
17233                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
17234     DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
17235     // Build var to save initial value.
17236     VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
17237     Expr *InitExpr;
17238     DeclRefExpr *Ref = nullptr;
17239     if (!VD && !CurContext->isDependentContext()) {
17240       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
17241       if (!isOpenMPCapturedDecl(D)) {
17242         ExprCaptures.push_back(Ref->getDecl());
17243         if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
17244           ExprResult RefRes = DefaultLvalueConversion(Ref);
17245           if (!RefRes.isUsable())
17246             continue;
17247           ExprResult PostUpdateRes =
17248               BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
17249                          SimpleRefExpr, RefRes.get());
17250           if (!PostUpdateRes.isUsable())
17251             continue;
17252           ExprPostUpdates.push_back(
17253               IgnoredValueConversions(PostUpdateRes.get()).get());
17254         }
17255       }
17256     }
17257     if (LinKind == OMPC_LINEAR_uval)
17258       InitExpr = VD ? VD->getInit() : SimpleRefExpr;
17259     else
17260       InitExpr = VD ? SimpleRefExpr : Ref;
17261     AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
17262                          /*DirectInit=*/false);
17263     DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
17264 
17265     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
17266     Vars.push_back((VD || CurContext->isDependentContext())
17267                        ? RefExpr->IgnoreParens()
17268                        : Ref);
17269     Privates.push_back(PrivateRef);
17270     Inits.push_back(InitRef);
17271   }
17272 
17273   if (Vars.empty())
17274     return nullptr;
17275 
17276   Expr *StepExpr = Step;
17277   Expr *CalcStepExpr = nullptr;
17278   if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
17279       !Step->isInstantiationDependent() &&
17280       !Step->containsUnexpandedParameterPack()) {
17281     SourceLocation StepLoc = Step->getBeginLoc();
17282     ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
17283     if (Val.isInvalid())
17284       return nullptr;
17285     StepExpr = Val.get();
17286 
17287     // Build var to save the step value.
17288     VarDecl *SaveVar =
17289         buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
17290     ExprResult SaveRef =
17291         buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
17292     ExprResult CalcStep =
17293         BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
17294     CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
17295 
17296     // Warn about zero linear step (it would be probably better specified as
17297     // making corresponding variables 'const').
17298     if (Optional<llvm::APSInt> Result =
17299             StepExpr->getIntegerConstantExpr(Context)) {
17300       if (!Result->isNegative() && !Result->isStrictlyPositive())
17301         Diag(StepLoc, diag::warn_omp_linear_step_zero)
17302             << Vars[0] << (Vars.size() > 1);
17303     } else if (CalcStep.isUsable()) {
17304       // Calculate the step beforehand instead of doing this on each iteration.
17305       // (This is not used if the number of iterations may be kfold-ed).
17306       CalcStepExpr = CalcStep.get();
17307     }
17308   }
17309 
17310   return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
17311                                  ColonLoc, EndLoc, Vars, Privates, Inits,
17312                                  StepExpr, CalcStepExpr,
17313                                  buildPreInits(Context, ExprCaptures),
17314                                  buildPostUpdate(*this, ExprPostUpdates));
17315 }
17316 
FinishOpenMPLinearClause(OMPLinearClause & Clause,DeclRefExpr * IV,Expr * NumIterations,Sema & SemaRef,Scope * S,DSAStackTy * Stack)17317 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
17318                                      Expr *NumIterations, Sema &SemaRef,
17319                                      Scope *S, DSAStackTy *Stack) {
17320   // Walk the vars and build update/final expressions for the CodeGen.
17321   SmallVector<Expr *, 8> Updates;
17322   SmallVector<Expr *, 8> Finals;
17323   SmallVector<Expr *, 8> UsedExprs;
17324   Expr *Step = Clause.getStep();
17325   Expr *CalcStep = Clause.getCalcStep();
17326   // OpenMP [2.14.3.7, linear clause]
17327   // If linear-step is not specified it is assumed to be 1.
17328   if (!Step)
17329     Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
17330   else if (CalcStep)
17331     Step = cast<BinaryOperator>(CalcStep)->getLHS();
17332   bool HasErrors = false;
17333   auto CurInit = Clause.inits().begin();
17334   auto CurPrivate = Clause.privates().begin();
17335   OpenMPLinearClauseKind LinKind = Clause.getModifier();
17336   for (Expr *RefExpr : Clause.varlists()) {
17337     SourceLocation ELoc;
17338     SourceRange ERange;
17339     Expr *SimpleRefExpr = RefExpr;
17340     auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
17341     ValueDecl *D = Res.first;
17342     if (Res.second || !D) {
17343       Updates.push_back(nullptr);
17344       Finals.push_back(nullptr);
17345       HasErrors = true;
17346       continue;
17347     }
17348     auto &&Info = Stack->isLoopControlVariable(D);
17349     // OpenMP [2.15.11, distribute simd Construct]
17350     // A list item may not appear in a linear clause, unless it is the loop
17351     // iteration variable.
17352     if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
17353         isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
17354       SemaRef.Diag(ELoc,
17355                    diag::err_omp_linear_distribute_var_non_loop_iteration);
17356       Updates.push_back(nullptr);
17357       Finals.push_back(nullptr);
17358       HasErrors = true;
17359       continue;
17360     }
17361     Expr *InitExpr = *CurInit;
17362 
17363     // Build privatized reference to the current linear var.
17364     auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
17365     Expr *CapturedRef;
17366     if (LinKind == OMPC_LINEAR_uval)
17367       CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
17368     else
17369       CapturedRef =
17370           buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
17371                            DE->getType().getUnqualifiedType(), DE->getExprLoc(),
17372                            /*RefersToCapture=*/true);
17373 
17374     // Build update: Var = InitExpr + IV * Step
17375     ExprResult Update;
17376     if (!Info.first)
17377       Update = buildCounterUpdate(
17378           SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
17379           /*Subtract=*/false, /*IsNonRectangularLB=*/false);
17380     else
17381       Update = *CurPrivate;
17382     Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
17383                                          /*DiscardedValue*/ false);
17384 
17385     // Build final: Var = InitExpr + NumIterations * Step
17386     ExprResult Final;
17387     if (!Info.first)
17388       Final =
17389           buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
17390                              InitExpr, NumIterations, Step, /*Subtract=*/false,
17391                              /*IsNonRectangularLB=*/false);
17392     else
17393       Final = *CurPrivate;
17394     Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
17395                                         /*DiscardedValue*/ false);
17396 
17397     if (!Update.isUsable() || !Final.isUsable()) {
17398       Updates.push_back(nullptr);
17399       Finals.push_back(nullptr);
17400       UsedExprs.push_back(nullptr);
17401       HasErrors = true;
17402     } else {
17403       Updates.push_back(Update.get());
17404       Finals.push_back(Final.get());
17405       if (!Info.first)
17406         UsedExprs.push_back(SimpleRefExpr);
17407     }
17408     ++CurInit;
17409     ++CurPrivate;
17410   }
17411   if (Expr *S = Clause.getStep())
17412     UsedExprs.push_back(S);
17413   // Fill the remaining part with the nullptr.
17414   UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr);
17415   Clause.setUpdates(Updates);
17416   Clause.setFinals(Finals);
17417   Clause.setUsedExprs(UsedExprs);
17418   return HasErrors;
17419 }
17420 
ActOnOpenMPAlignedClause(ArrayRef<Expr * > VarList,Expr * Alignment,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc)17421 OMPClause *Sema::ActOnOpenMPAlignedClause(
17422     ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
17423     SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
17424   SmallVector<Expr *, 8> Vars;
17425   for (Expr *RefExpr : VarList) {
17426     assert(RefExpr && "NULL expr in OpenMP linear clause.");
17427     SourceLocation ELoc;
17428     SourceRange ERange;
17429     Expr *SimpleRefExpr = RefExpr;
17430     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17431     if (Res.second) {
17432       // It will be analyzed later.
17433       Vars.push_back(RefExpr);
17434     }
17435     ValueDecl *D = Res.first;
17436     if (!D)
17437       continue;
17438 
17439     QualType QType = D->getType();
17440     auto *VD = dyn_cast<VarDecl>(D);
17441 
17442     // OpenMP  [2.8.1, simd construct, Restrictions]
17443     // The type of list items appearing in the aligned clause must be
17444     // array, pointer, reference to array, or reference to pointer.
17445     QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
17446     const Type *Ty = QType.getTypePtrOrNull();
17447     if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
17448       Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
17449           << QType << getLangOpts().CPlusPlus << ERange;
17450       bool IsDecl =
17451           !VD ||
17452           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
17453       Diag(D->getLocation(),
17454            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17455           << D;
17456       continue;
17457     }
17458 
17459     // OpenMP  [2.8.1, simd construct, Restrictions]
17460     // A list-item cannot appear in more than one aligned clause.
17461     if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
17462       Diag(ELoc, diag::err_omp_used_in_clause_twice)
17463           << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
17464       Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
17465           << getOpenMPClauseName(OMPC_aligned);
17466       continue;
17467     }
17468 
17469     DeclRefExpr *Ref = nullptr;
17470     if (!VD && isOpenMPCapturedDecl(D))
17471       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
17472     Vars.push_back(DefaultFunctionArrayConversion(
17473                        (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
17474                        .get());
17475   }
17476 
17477   // OpenMP [2.8.1, simd construct, Description]
17478   // The parameter of the aligned clause, alignment, must be a constant
17479   // positive integer expression.
17480   // If no optional parameter is specified, implementation-defined default
17481   // alignments for SIMD instructions on the target platforms are assumed.
17482   if (Alignment != nullptr) {
17483     ExprResult AlignResult =
17484         VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
17485     if (AlignResult.isInvalid())
17486       return nullptr;
17487     Alignment = AlignResult.get();
17488   }
17489   if (Vars.empty())
17490     return nullptr;
17491 
17492   return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
17493                                   EndLoc, Vars, Alignment);
17494 }
17495 
ActOnOpenMPCopyinClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)17496 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
17497                                          SourceLocation StartLoc,
17498                                          SourceLocation LParenLoc,
17499                                          SourceLocation EndLoc) {
17500   SmallVector<Expr *, 8> Vars;
17501   SmallVector<Expr *, 8> SrcExprs;
17502   SmallVector<Expr *, 8> DstExprs;
17503   SmallVector<Expr *, 8> AssignmentOps;
17504   for (Expr *RefExpr : VarList) {
17505     assert(RefExpr && "NULL expr in OpenMP copyin clause.");
17506     if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
17507       // It will be analyzed later.
17508       Vars.push_back(RefExpr);
17509       SrcExprs.push_back(nullptr);
17510       DstExprs.push_back(nullptr);
17511       AssignmentOps.push_back(nullptr);
17512       continue;
17513     }
17514 
17515     SourceLocation ELoc = RefExpr->getExprLoc();
17516     // OpenMP [2.1, C/C++]
17517     //  A list item is a variable name.
17518     // OpenMP  [2.14.4.1, Restrictions, p.1]
17519     //  A list item that appears in a copyin clause must be threadprivate.
17520     auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
17521     if (!DE || !isa<VarDecl>(DE->getDecl())) {
17522       Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
17523           << 0 << RefExpr->getSourceRange();
17524       continue;
17525     }
17526 
17527     Decl *D = DE->getDecl();
17528     auto *VD = cast<VarDecl>(D);
17529 
17530     QualType Type = VD->getType();
17531     if (Type->isDependentType() || Type->isInstantiationDependentType()) {
17532       // It will be analyzed later.
17533       Vars.push_back(DE);
17534       SrcExprs.push_back(nullptr);
17535       DstExprs.push_back(nullptr);
17536       AssignmentOps.push_back(nullptr);
17537       continue;
17538     }
17539 
17540     // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
17541     //  A list item that appears in a copyin clause must be threadprivate.
17542     if (!DSAStack->isThreadPrivate(VD)) {
17543       Diag(ELoc, diag::err_omp_required_access)
17544           << getOpenMPClauseName(OMPC_copyin)
17545           << getOpenMPDirectiveName(OMPD_threadprivate);
17546       continue;
17547     }
17548 
17549     // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
17550     //  A variable of class type (or array thereof) that appears in a
17551     //  copyin clause requires an accessible, unambiguous copy assignment
17552     //  operator for the class type.
17553     QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
17554     VarDecl *SrcVD =
17555         buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
17556                      ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
17557     DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
17558         *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
17559     VarDecl *DstVD =
17560         buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
17561                      VD->hasAttrs() ? &VD->getAttrs() : nullptr);
17562     DeclRefExpr *PseudoDstExpr =
17563         buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
17564     // For arrays generate assignment operation for single element and replace
17565     // it by the original array element in CodeGen.
17566     ExprResult AssignmentOp =
17567         BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
17568                    PseudoSrcExpr);
17569     if (AssignmentOp.isInvalid())
17570       continue;
17571     AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
17572                                        /*DiscardedValue*/ false);
17573     if (AssignmentOp.isInvalid())
17574       continue;
17575 
17576     DSAStack->addDSA(VD, DE, OMPC_copyin);
17577     Vars.push_back(DE);
17578     SrcExprs.push_back(PseudoSrcExpr);
17579     DstExprs.push_back(PseudoDstExpr);
17580     AssignmentOps.push_back(AssignmentOp.get());
17581   }
17582 
17583   if (Vars.empty())
17584     return nullptr;
17585 
17586   return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
17587                                  SrcExprs, DstExprs, AssignmentOps);
17588 }
17589 
ActOnOpenMPCopyprivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)17590 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
17591                                               SourceLocation StartLoc,
17592                                               SourceLocation LParenLoc,
17593                                               SourceLocation EndLoc) {
17594   SmallVector<Expr *, 8> Vars;
17595   SmallVector<Expr *, 8> SrcExprs;
17596   SmallVector<Expr *, 8> DstExprs;
17597   SmallVector<Expr *, 8> AssignmentOps;
17598   for (Expr *RefExpr : VarList) {
17599     assert(RefExpr && "NULL expr in OpenMP linear clause.");
17600     SourceLocation ELoc;
17601     SourceRange ERange;
17602     Expr *SimpleRefExpr = RefExpr;
17603     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17604     if (Res.second) {
17605       // It will be analyzed later.
17606       Vars.push_back(RefExpr);
17607       SrcExprs.push_back(nullptr);
17608       DstExprs.push_back(nullptr);
17609       AssignmentOps.push_back(nullptr);
17610     }
17611     ValueDecl *D = Res.first;
17612     if (!D)
17613       continue;
17614 
17615     QualType Type = D->getType();
17616     auto *VD = dyn_cast<VarDecl>(D);
17617 
17618     // OpenMP [2.14.4.2, Restrictions, p.2]
17619     //  A list item that appears in a copyprivate clause may not appear in a
17620     //  private or firstprivate clause on the single construct.
17621     if (!VD || !DSAStack->isThreadPrivate(VD)) {
17622       DSAStackTy::DSAVarData DVar =
17623           DSAStack->getTopDSA(D, /*FromParent=*/false);
17624       if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
17625           DVar.RefExpr) {
17626         Diag(ELoc, diag::err_omp_wrong_dsa)
17627             << getOpenMPClauseName(DVar.CKind)
17628             << getOpenMPClauseName(OMPC_copyprivate);
17629         reportOriginalDsa(*this, DSAStack, D, DVar);
17630         continue;
17631       }
17632 
17633       // OpenMP [2.11.4.2, Restrictions, p.1]
17634       //  All list items that appear in a copyprivate clause must be either
17635       //  threadprivate or private in the enclosing context.
17636       if (DVar.CKind == OMPC_unknown) {
17637         DVar = DSAStack->getImplicitDSA(D, false);
17638         if (DVar.CKind == OMPC_shared) {
17639           Diag(ELoc, diag::err_omp_required_access)
17640               << getOpenMPClauseName(OMPC_copyprivate)
17641               << "threadprivate or private in the enclosing context";
17642           reportOriginalDsa(*this, DSAStack, D, DVar);
17643           continue;
17644         }
17645       }
17646     }
17647 
17648     // Variably modified types are not supported.
17649     if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
17650       Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
17651           << getOpenMPClauseName(OMPC_copyprivate) << Type
17652           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
17653       bool IsDecl =
17654           !VD ||
17655           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
17656       Diag(D->getLocation(),
17657            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17658           << D;
17659       continue;
17660     }
17661 
17662     // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
17663     //  A variable of class type (or array thereof) that appears in a
17664     //  copyin clause requires an accessible, unambiguous copy assignment
17665     //  operator for the class type.
17666     Type = Context.getBaseElementType(Type.getNonReferenceType())
17667                .getUnqualifiedType();
17668     VarDecl *SrcVD =
17669         buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
17670                      D->hasAttrs() ? &D->getAttrs() : nullptr);
17671     DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
17672     VarDecl *DstVD =
17673         buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
17674                      D->hasAttrs() ? &D->getAttrs() : nullptr);
17675     DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
17676     ExprResult AssignmentOp = BuildBinOp(
17677         DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
17678     if (AssignmentOp.isInvalid())
17679       continue;
17680     AssignmentOp =
17681         ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
17682     if (AssignmentOp.isInvalid())
17683       continue;
17684 
17685     // No need to mark vars as copyprivate, they are already threadprivate or
17686     // implicitly private.
17687     assert(VD || isOpenMPCapturedDecl(D));
17688     Vars.push_back(
17689         VD ? RefExpr->IgnoreParens()
17690            : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
17691     SrcExprs.push_back(PseudoSrcExpr);
17692     DstExprs.push_back(PseudoDstExpr);
17693     AssignmentOps.push_back(AssignmentOp.get());
17694   }
17695 
17696   if (Vars.empty())
17697     return nullptr;
17698 
17699   return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
17700                                       Vars, SrcExprs, DstExprs, AssignmentOps);
17701 }
17702 
ActOnOpenMPFlushClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)17703 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
17704                                         SourceLocation StartLoc,
17705                                         SourceLocation LParenLoc,
17706                                         SourceLocation EndLoc) {
17707   if (VarList.empty())
17708     return nullptr;
17709 
17710   return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
17711 }
17712 
17713 /// Tries to find omp_depend_t. type.
findOMPDependT(Sema & S,SourceLocation Loc,DSAStackTy * Stack,bool Diagnose=true)17714 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack,
17715                            bool Diagnose = true) {
17716   QualType OMPDependT = Stack->getOMPDependT();
17717   if (!OMPDependT.isNull())
17718     return true;
17719   IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t");
17720   ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
17721   if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
17722     if (Diagnose)
17723       S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t";
17724     return false;
17725   }
17726   Stack->setOMPDependT(PT.get());
17727   return true;
17728 }
17729 
ActOnOpenMPDepobjClause(Expr * Depobj,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)17730 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
17731                                          SourceLocation LParenLoc,
17732                                          SourceLocation EndLoc) {
17733   if (!Depobj)
17734     return nullptr;
17735 
17736   bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack);
17737 
17738   // OpenMP 5.0, 2.17.10.1 depobj Construct
17739   // depobj is an lvalue expression of type omp_depend_t.
17740   if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() &&
17741       !Depobj->isInstantiationDependent() &&
17742       !Depobj->containsUnexpandedParameterPack() &&
17743       (OMPDependTFound &&
17744        !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(),
17745                                    /*CompareUnqualified=*/true))) {
17746     Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
17747         << 0 << Depobj->getType() << Depobj->getSourceRange();
17748   }
17749 
17750   if (!Depobj->isLValue()) {
17751     Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
17752         << 1 << Depobj->getSourceRange();
17753   }
17754 
17755   return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj);
17756 }
17757 
17758 OMPClause *
ActOnOpenMPDependClause(Expr * DepModifier,OpenMPDependClauseKind DepKind,SourceLocation DepLoc,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)17759 Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind,
17760                               SourceLocation DepLoc, SourceLocation ColonLoc,
17761                               ArrayRef<Expr *> VarList, SourceLocation StartLoc,
17762                               SourceLocation LParenLoc, SourceLocation EndLoc) {
17763   if (DSAStack->getCurrentDirective() == OMPD_ordered &&
17764       DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
17765     Diag(DepLoc, diag::err_omp_unexpected_clause_value)
17766         << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
17767     return nullptr;
17768   }
17769   if ((DSAStack->getCurrentDirective() != OMPD_ordered ||
17770        DSAStack->getCurrentDirective() == OMPD_depobj) &&
17771       (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
17772        DepKind == OMPC_DEPEND_sink ||
17773        ((LangOpts.OpenMP < 50 ||
17774          DSAStack->getCurrentDirective() == OMPD_depobj) &&
17775         DepKind == OMPC_DEPEND_depobj))) {
17776     SmallVector<unsigned, 3> Except;
17777     Except.push_back(OMPC_DEPEND_source);
17778     Except.push_back(OMPC_DEPEND_sink);
17779     if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj)
17780       Except.push_back(OMPC_DEPEND_depobj);
17781     std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier)
17782                                ? "depend modifier(iterator) or "
17783                                : "";
17784     Diag(DepLoc, diag::err_omp_unexpected_clause_value)
17785         << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0,
17786                                               /*Last=*/OMPC_DEPEND_unknown,
17787                                               Except)
17788         << getOpenMPClauseName(OMPC_depend);
17789     return nullptr;
17790   }
17791   if (DepModifier &&
17792       (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) {
17793     Diag(DepModifier->getExprLoc(),
17794          diag::err_omp_depend_sink_source_with_modifier);
17795     return nullptr;
17796   }
17797   if (DepModifier &&
17798       !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator))
17799     Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator);
17800 
17801   SmallVector<Expr *, 8> Vars;
17802   DSAStackTy::OperatorOffsetTy OpsOffs;
17803   llvm::APSInt DepCounter(/*BitWidth=*/32);
17804   llvm::APSInt TotalDepCount(/*BitWidth=*/32);
17805   if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
17806     if (const Expr *OrderedCountExpr =
17807             DSAStack->getParentOrderedRegionParam().first) {
17808       TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
17809       TotalDepCount.setIsUnsigned(/*Val=*/true);
17810     }
17811   }
17812   for (Expr *RefExpr : VarList) {
17813     assert(RefExpr && "NULL expr in OpenMP shared clause.");
17814     if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
17815       // It will be analyzed later.
17816       Vars.push_back(RefExpr);
17817       continue;
17818     }
17819 
17820     SourceLocation ELoc = RefExpr->getExprLoc();
17821     Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
17822     if (DepKind == OMPC_DEPEND_sink) {
17823       if (DSAStack->getParentOrderedRegionParam().first &&
17824           DepCounter >= TotalDepCount) {
17825         Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
17826         continue;
17827       }
17828       ++DepCounter;
17829       // OpenMP  [2.13.9, Summary]
17830       // depend(dependence-type : vec), where dependence-type is:
17831       // 'sink' and where vec is the iteration vector, which has the form:
17832       //  x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
17833       // where n is the value specified by the ordered clause in the loop
17834       // directive, xi denotes the loop iteration variable of the i-th nested
17835       // loop associated with the loop directive, and di is a constant
17836       // non-negative integer.
17837       if (CurContext->isDependentContext()) {
17838         // It will be analyzed later.
17839         Vars.push_back(RefExpr);
17840         continue;
17841       }
17842       SimpleExpr = SimpleExpr->IgnoreImplicit();
17843       OverloadedOperatorKind OOK = OO_None;
17844       SourceLocation OOLoc;
17845       Expr *LHS = SimpleExpr;
17846       Expr *RHS = nullptr;
17847       if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
17848         OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
17849         OOLoc = BO->getOperatorLoc();
17850         LHS = BO->getLHS()->IgnoreParenImpCasts();
17851         RHS = BO->getRHS()->IgnoreParenImpCasts();
17852       } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
17853         OOK = OCE->getOperator();
17854         OOLoc = OCE->getOperatorLoc();
17855         LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
17856         RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
17857       } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
17858         OOK = MCE->getMethodDecl()
17859                   ->getNameInfo()
17860                   .getName()
17861                   .getCXXOverloadedOperator();
17862         OOLoc = MCE->getCallee()->getExprLoc();
17863         LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
17864         RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
17865       }
17866       SourceLocation ELoc;
17867       SourceRange ERange;
17868       auto Res = getPrivateItem(*this, LHS, ELoc, ERange);
17869       if (Res.second) {
17870         // It will be analyzed later.
17871         Vars.push_back(RefExpr);
17872       }
17873       ValueDecl *D = Res.first;
17874       if (!D)
17875         continue;
17876 
17877       if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
17878         Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
17879         continue;
17880       }
17881       if (RHS) {
17882         ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
17883             RHS, OMPC_depend, /*StrictlyPositive=*/false);
17884         if (RHSRes.isInvalid())
17885           continue;
17886       }
17887       if (!CurContext->isDependentContext() &&
17888           DSAStack->getParentOrderedRegionParam().first &&
17889           DepCounter != DSAStack->isParentLoopControlVariable(D).first) {
17890         const ValueDecl *VD =
17891             DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue());
17892         if (VD)
17893           Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
17894               << 1 << VD;
17895         else
17896           Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
17897         continue;
17898       }
17899       OpsOffs.emplace_back(RHS, OOK);
17900     } else {
17901       bool OMPDependTFound = LangOpts.OpenMP >= 50;
17902       if (OMPDependTFound)
17903         OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack,
17904                                          DepKind == OMPC_DEPEND_depobj);
17905       if (DepKind == OMPC_DEPEND_depobj) {
17906         // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
17907         // List items used in depend clauses with the depobj dependence type
17908         // must be expressions of the omp_depend_t type.
17909         if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
17910             !RefExpr->isInstantiationDependent() &&
17911             !RefExpr->containsUnexpandedParameterPack() &&
17912             (OMPDependTFound &&
17913              !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(),
17914                                              RefExpr->getType()))) {
17915           Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
17916               << 0 << RefExpr->getType() << RefExpr->getSourceRange();
17917           continue;
17918         }
17919         if (!RefExpr->isLValue()) {
17920           Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
17921               << 1 << RefExpr->getType() << RefExpr->getSourceRange();
17922           continue;
17923         }
17924       } else {
17925         // OpenMP 5.0 [2.17.11, Restrictions]
17926         // List items used in depend clauses cannot be zero-length array
17927         // sections.
17928         QualType ExprTy = RefExpr->getType().getNonReferenceType();
17929         const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
17930         if (OASE) {
17931           QualType BaseType =
17932               OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
17933           if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
17934             ExprTy = ATy->getElementType();
17935           else
17936             ExprTy = BaseType->getPointeeType();
17937           ExprTy = ExprTy.getNonReferenceType();
17938           const Expr *Length = OASE->getLength();
17939           Expr::EvalResult Result;
17940           if (Length && !Length->isValueDependent() &&
17941               Length->EvaluateAsInt(Result, Context) &&
17942               Result.Val.getInt().isNullValue()) {
17943             Diag(ELoc,
17944                  diag::err_omp_depend_zero_length_array_section_not_allowed)
17945                 << SimpleExpr->getSourceRange();
17946             continue;
17947           }
17948         }
17949 
17950         // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
17951         // List items used in depend clauses with the in, out, inout or
17952         // mutexinoutset dependence types cannot be expressions of the
17953         // omp_depend_t type.
17954         if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
17955             !RefExpr->isInstantiationDependent() &&
17956             !RefExpr->containsUnexpandedParameterPack() &&
17957             (OMPDependTFound &&
17958              DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) {
17959           Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
17960               << (LangOpts.OpenMP >= 50 ? 1 : 0) << 1
17961               << RefExpr->getSourceRange();
17962           continue;
17963         }
17964 
17965         auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
17966         if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
17967             (ASE && !ASE->getBase()->isTypeDependent() &&
17968              !ASE->getBase()
17969                   ->getType()
17970                   .getNonReferenceType()
17971                   ->isPointerType() &&
17972              !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
17973           Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
17974               << (LangOpts.OpenMP >= 50 ? 1 : 0)
17975               << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
17976           continue;
17977         }
17978 
17979         ExprResult Res;
17980         {
17981           Sema::TentativeAnalysisScope Trap(*this);
17982           Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
17983                                      RefExpr->IgnoreParenImpCasts());
17984         }
17985         if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
17986             !isa<OMPArrayShapingExpr>(SimpleExpr)) {
17987           Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
17988               << (LangOpts.OpenMP >= 50 ? 1 : 0)
17989               << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
17990           continue;
17991         }
17992       }
17993     }
17994     Vars.push_back(RefExpr->IgnoreParenImpCasts());
17995   }
17996 
17997   if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
17998       TotalDepCount > VarList.size() &&
17999       DSAStack->getParentOrderedRegionParam().first &&
18000       DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
18001     Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
18002         << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1);
18003   }
18004   if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
18005       Vars.empty())
18006     return nullptr;
18007 
18008   auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
18009                                     DepModifier, DepKind, DepLoc, ColonLoc,
18010                                     Vars, TotalDepCount.getZExtValue());
18011   if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
18012       DSAStack->isParentOrderedRegion())
18013     DSAStack->addDoacrossDependClause(C, OpsOffs);
18014   return C;
18015 }
18016 
ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,Expr * Device,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ModifierLoc,SourceLocation EndLoc)18017 OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
18018                                          Expr *Device, SourceLocation StartLoc,
18019                                          SourceLocation LParenLoc,
18020                                          SourceLocation ModifierLoc,
18021                                          SourceLocation EndLoc) {
18022   assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) &&
18023          "Unexpected device modifier in OpenMP < 50.");
18024 
18025   bool ErrorFound = false;
18026   if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) {
18027     std::string Values =
18028         getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown);
18029     Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
18030         << Values << getOpenMPClauseName(OMPC_device);
18031     ErrorFound = true;
18032   }
18033 
18034   Expr *ValExpr = Device;
18035   Stmt *HelperValStmt = nullptr;
18036 
18037   // OpenMP [2.9.1, Restrictions]
18038   // The device expression must evaluate to a non-negative integer value.
18039   ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
18040                                           /*StrictlyPositive=*/false) ||
18041                ErrorFound;
18042   if (ErrorFound)
18043     return nullptr;
18044 
18045   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
18046   OpenMPDirectiveKind CaptureRegion =
18047       getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP);
18048   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18049     ValExpr = MakeFullExpr(ValExpr).get();
18050     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18051     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18052     HelperValStmt = buildPreInits(Context, Captures);
18053   }
18054 
18055   return new (Context)
18056       OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
18057                       LParenLoc, ModifierLoc, EndLoc);
18058 }
18059 
checkTypeMappable(SourceLocation SL,SourceRange SR,Sema & SemaRef,DSAStackTy * Stack,QualType QTy,bool FullCheck=true)18060 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
18061                               DSAStackTy *Stack, QualType QTy,
18062                               bool FullCheck = true) {
18063   NamedDecl *ND;
18064   if (QTy->isIncompleteType(&ND)) {
18065     SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR;
18066     return false;
18067   }
18068   if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
18069       !QTy.isTriviallyCopyableType(SemaRef.Context))
18070     SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
18071   return true;
18072 }
18073 
18074 /// Return true if it can be proven that the provided array expression
18075 /// (array section or array subscript) does NOT specify the whole size of the
18076 /// array whose base type is \a BaseQTy.
checkArrayExpressionDoesNotReferToWholeSize(Sema & SemaRef,const Expr * E,QualType BaseQTy)18077 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
18078                                                         const Expr *E,
18079                                                         QualType BaseQTy) {
18080   const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
18081 
18082   // If this is an array subscript, it refers to the whole size if the size of
18083   // the dimension is constant and equals 1. Also, an array section assumes the
18084   // format of an array subscript if no colon is used.
18085   if (isa<ArraySubscriptExpr>(E) ||
18086       (OASE && OASE->getColonLocFirst().isInvalid())) {
18087     if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
18088       return ATy->getSize().getSExtValue() != 1;
18089     // Size can't be evaluated statically.
18090     return false;
18091   }
18092 
18093   assert(OASE && "Expecting array section if not an array subscript.");
18094   const Expr *LowerBound = OASE->getLowerBound();
18095   const Expr *Length = OASE->getLength();
18096 
18097   // If there is a lower bound that does not evaluates to zero, we are not
18098   // covering the whole dimension.
18099   if (LowerBound) {
18100     Expr::EvalResult Result;
18101     if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
18102       return false; // Can't get the integer value as a constant.
18103 
18104     llvm::APSInt ConstLowerBound = Result.Val.getInt();
18105     if (ConstLowerBound.getSExtValue())
18106       return true;
18107   }
18108 
18109   // If we don't have a length we covering the whole dimension.
18110   if (!Length)
18111     return false;
18112 
18113   // If the base is a pointer, we don't have a way to get the size of the
18114   // pointee.
18115   if (BaseQTy->isPointerType())
18116     return false;
18117 
18118   // We can only check if the length is the same as the size of the dimension
18119   // if we have a constant array.
18120   const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
18121   if (!CATy)
18122     return false;
18123 
18124   Expr::EvalResult Result;
18125   if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
18126     return false; // Can't get the integer value as a constant.
18127 
18128   llvm::APSInt ConstLength = Result.Val.getInt();
18129   return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
18130 }
18131 
18132 // Return true if it can be proven that the provided array expression (array
18133 // section or array subscript) does NOT specify a single element of the array
18134 // whose base type is \a BaseQTy.
checkArrayExpressionDoesNotReferToUnitySize(Sema & SemaRef,const Expr * E,QualType BaseQTy)18135 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
18136                                                         const Expr *E,
18137                                                         QualType BaseQTy) {
18138   const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
18139 
18140   // An array subscript always refer to a single element. Also, an array section
18141   // assumes the format of an array subscript if no colon is used.
18142   if (isa<ArraySubscriptExpr>(E) ||
18143       (OASE && OASE->getColonLocFirst().isInvalid()))
18144     return false;
18145 
18146   assert(OASE && "Expecting array section if not an array subscript.");
18147   const Expr *Length = OASE->getLength();
18148 
18149   // If we don't have a length we have to check if the array has unitary size
18150   // for this dimension. Also, we should always expect a length if the base type
18151   // is pointer.
18152   if (!Length) {
18153     if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
18154       return ATy->getSize().getSExtValue() != 1;
18155     // We cannot assume anything.
18156     return false;
18157   }
18158 
18159   // Check if the length evaluates to 1.
18160   Expr::EvalResult Result;
18161   if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
18162     return false; // Can't get the integer value as a constant.
18163 
18164   llvm::APSInt ConstLength = Result.Val.getInt();
18165   return ConstLength.getSExtValue() != 1;
18166 }
18167 
18168 // The base of elements of list in a map clause have to be either:
18169 //  - a reference to variable or field.
18170 //  - a member expression.
18171 //  - an array expression.
18172 //
18173 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
18174 // reference to 'r'.
18175 //
18176 // If we have:
18177 //
18178 // struct SS {
18179 //   Bla S;
18180 //   foo() {
18181 //     #pragma omp target map (S.Arr[:12]);
18182 //   }
18183 // }
18184 //
18185 // We want to retrieve the member expression 'this->S';
18186 
18187 // OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2]
18188 //  If a list item is an array section, it must specify contiguous storage.
18189 //
18190 // For this restriction it is sufficient that we make sure only references
18191 // to variables or fields and array expressions, and that no array sections
18192 // exist except in the rightmost expression (unless they cover the whole
18193 // dimension of the array). E.g. these would be invalid:
18194 //
18195 //   r.ArrS[3:5].Arr[6:7]
18196 //
18197 //   r.ArrS[3:5].x
18198 //
18199 // but these would be valid:
18200 //   r.ArrS[3].Arr[6:7]
18201 //
18202 //   r.ArrS[3].x
18203 namespace {
18204 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> {
18205   Sema &SemaRef;
18206   OpenMPClauseKind CKind = OMPC_unknown;
18207   OpenMPDirectiveKind DKind = OMPD_unknown;
18208   OMPClauseMappableExprCommon::MappableExprComponentList &Components;
18209   bool IsNonContiguous = false;
18210   bool NoDiagnose = false;
18211   const Expr *RelevantExpr = nullptr;
18212   bool AllowUnitySizeArraySection = true;
18213   bool AllowWholeSizeArraySection = true;
18214   bool AllowAnotherPtr = true;
18215   SourceLocation ELoc;
18216   SourceRange ERange;
18217 
emitErrorMsg()18218   void emitErrorMsg() {
18219     // If nothing else worked, this is not a valid map clause expression.
18220     if (SemaRef.getLangOpts().OpenMP < 50) {
18221       SemaRef.Diag(ELoc,
18222                    diag::err_omp_expected_named_var_member_or_array_expression)
18223           << ERange;
18224     } else {
18225       SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
18226           << getOpenMPClauseName(CKind) << ERange;
18227     }
18228   }
18229 
18230 public:
VisitDeclRefExpr(DeclRefExpr * DRE)18231   bool VisitDeclRefExpr(DeclRefExpr *DRE) {
18232     if (!isa<VarDecl>(DRE->getDecl())) {
18233       emitErrorMsg();
18234       return false;
18235     }
18236     assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
18237     RelevantExpr = DRE;
18238     // Record the component.
18239     Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous);
18240     return true;
18241   }
18242 
VisitMemberExpr(MemberExpr * ME)18243   bool VisitMemberExpr(MemberExpr *ME) {
18244     Expr *E = ME;
18245     Expr *BaseE = ME->getBase()->IgnoreParenCasts();
18246 
18247     if (isa<CXXThisExpr>(BaseE)) {
18248       assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
18249       // We found a base expression: this->Val.
18250       RelevantExpr = ME;
18251     } else {
18252       E = BaseE;
18253     }
18254 
18255     if (!isa<FieldDecl>(ME->getMemberDecl())) {
18256       if (!NoDiagnose) {
18257         SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
18258           << ME->getSourceRange();
18259         return false;
18260       }
18261       if (RelevantExpr)
18262         return false;
18263       return Visit(E);
18264     }
18265 
18266     auto *FD = cast<FieldDecl>(ME->getMemberDecl());
18267 
18268     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
18269     //  A bit-field cannot appear in a map clause.
18270     //
18271     if (FD->isBitField()) {
18272       if (!NoDiagnose) {
18273         SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
18274           << ME->getSourceRange() << getOpenMPClauseName(CKind);
18275         return false;
18276       }
18277       if (RelevantExpr)
18278         return false;
18279       return Visit(E);
18280     }
18281 
18282     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
18283     //  If the type of a list item is a reference to a type T then the type
18284     //  will be considered to be T for all purposes of this clause.
18285     QualType CurType = BaseE->getType().getNonReferenceType();
18286 
18287     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
18288     //  A list item cannot be a variable that is a member of a structure with
18289     //  a union type.
18290     //
18291     if (CurType->isUnionType()) {
18292       if (!NoDiagnose) {
18293         SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
18294           << ME->getSourceRange();
18295         return false;
18296       }
18297       return RelevantExpr || Visit(E);
18298     }
18299 
18300     // If we got a member expression, we should not expect any array section
18301     // before that:
18302     //
18303     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
18304     //  If a list item is an element of a structure, only the rightmost symbol
18305     //  of the variable reference can be an array section.
18306     //
18307     AllowUnitySizeArraySection = false;
18308     AllowWholeSizeArraySection = false;
18309 
18310     // Record the component.
18311     Components.emplace_back(ME, FD, IsNonContiguous);
18312     return RelevantExpr || Visit(E);
18313   }
18314 
VisitArraySubscriptExpr(ArraySubscriptExpr * AE)18315   bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) {
18316     Expr *E = AE->getBase()->IgnoreParenImpCasts();
18317 
18318     if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
18319       if (!NoDiagnose) {
18320         SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
18321           << 0 << AE->getSourceRange();
18322         return false;
18323       }
18324       return RelevantExpr || Visit(E);
18325     }
18326 
18327     // If we got an array subscript that express the whole dimension we
18328     // can have any array expressions before. If it only expressing part of
18329     // the dimension, we can only have unitary-size array expressions.
18330     if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE,
18331                                                     E->getType()))
18332       AllowWholeSizeArraySection = false;
18333 
18334     if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) {
18335       Expr::EvalResult Result;
18336       if (!AE->getIdx()->isValueDependent() &&
18337           AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) &&
18338           !Result.Val.getInt().isNullValue()) {
18339         SemaRef.Diag(AE->getIdx()->getExprLoc(),
18340                      diag::err_omp_invalid_map_this_expr);
18341         SemaRef.Diag(AE->getIdx()->getExprLoc(),
18342                      diag::note_omp_invalid_subscript_on_this_ptr_map);
18343       }
18344       assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
18345       RelevantExpr = TE;
18346     }
18347 
18348     // Record the component - we don't have any declaration associated.
18349     Components.emplace_back(AE, nullptr, IsNonContiguous);
18350 
18351     return RelevantExpr || Visit(E);
18352   }
18353 
VisitOMPArraySectionExpr(OMPArraySectionExpr * OASE)18354   bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) {
18355     assert(!NoDiagnose && "Array sections cannot be implicitly mapped.");
18356     Expr *E = OASE->getBase()->IgnoreParenImpCasts();
18357     QualType CurType =
18358       OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
18359 
18360     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
18361     //  If the type of a list item is a reference to a type T then the type
18362     //  will be considered to be T for all purposes of this clause.
18363     if (CurType->isReferenceType())
18364       CurType = CurType->getPointeeType();
18365 
18366     bool IsPointer = CurType->isAnyPointerType();
18367 
18368     if (!IsPointer && !CurType->isArrayType()) {
18369       SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
18370         << 0 << OASE->getSourceRange();
18371       return false;
18372     }
18373 
18374     bool NotWhole =
18375       checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType);
18376     bool NotUnity =
18377       checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType);
18378 
18379     if (AllowWholeSizeArraySection) {
18380       // Any array section is currently allowed. Allowing a whole size array
18381       // section implies allowing a unity array section as well.
18382       //
18383       // If this array section refers to the whole dimension we can still
18384       // accept other array sections before this one, except if the base is a
18385       // pointer. Otherwise, only unitary sections are accepted.
18386       if (NotWhole || IsPointer)
18387         AllowWholeSizeArraySection = false;
18388     } else if (DKind == OMPD_target_update &&
18389                SemaRef.getLangOpts().OpenMP >= 50) {
18390       if (IsPointer && !AllowAnotherPtr)
18391         SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined)
18392             << /*array of unknown bound */ 1;
18393       else
18394         IsNonContiguous = true;
18395     } else if (AllowUnitySizeArraySection && NotUnity) {
18396       // A unity or whole array section is not allowed and that is not
18397       // compatible with the properties of the current array section.
18398       SemaRef.Diag(
18399         ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
18400         << OASE->getSourceRange();
18401       return false;
18402     }
18403 
18404     if (IsPointer)
18405       AllowAnotherPtr = false;
18406 
18407     if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
18408       Expr::EvalResult ResultR;
18409       Expr::EvalResult ResultL;
18410       if (!OASE->getLength()->isValueDependent() &&
18411           OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) &&
18412           !ResultR.Val.getInt().isOneValue()) {
18413         SemaRef.Diag(OASE->getLength()->getExprLoc(),
18414                      diag::err_omp_invalid_map_this_expr);
18415         SemaRef.Diag(OASE->getLength()->getExprLoc(),
18416                      diag::note_omp_invalid_length_on_this_ptr_mapping);
18417       }
18418       if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() &&
18419           OASE->getLowerBound()->EvaluateAsInt(ResultL,
18420                                                SemaRef.getASTContext()) &&
18421           !ResultL.Val.getInt().isNullValue()) {
18422         SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
18423                      diag::err_omp_invalid_map_this_expr);
18424         SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
18425                      diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
18426       }
18427       assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
18428       RelevantExpr = TE;
18429     }
18430 
18431     // Record the component - we don't have any declaration associated.
18432     Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false);
18433     return RelevantExpr || Visit(E);
18434   }
VisitOMPArrayShapingExpr(OMPArrayShapingExpr * E)18435   bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
18436     Expr *Base = E->getBase();
18437 
18438     // Record the component - we don't have any declaration associated.
18439     Components.emplace_back(E, nullptr, IsNonContiguous);
18440 
18441     return Visit(Base->IgnoreParenImpCasts());
18442   }
18443 
VisitUnaryOperator(UnaryOperator * UO)18444   bool VisitUnaryOperator(UnaryOperator *UO) {
18445     if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() ||
18446         UO->getOpcode() != UO_Deref) {
18447       emitErrorMsg();
18448       return false;
18449     }
18450     if (!RelevantExpr) {
18451       // Record the component if haven't found base decl.
18452       Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false);
18453     }
18454     return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts());
18455   }
VisitBinaryOperator(BinaryOperator * BO)18456   bool VisitBinaryOperator(BinaryOperator *BO) {
18457     if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) {
18458       emitErrorMsg();
18459       return false;
18460     }
18461 
18462     // Pointer arithmetic is the only thing we expect to happen here so after we
18463     // make sure the binary operator is a pointer type, the we only thing need
18464     // to to is to visit the subtree that has the same type as root (so that we
18465     // know the other subtree is just an offset)
18466     Expr *LE = BO->getLHS()->IgnoreParenImpCasts();
18467     Expr *RE = BO->getRHS()->IgnoreParenImpCasts();
18468     Components.emplace_back(BO, nullptr, false);
18469     assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() ||
18470             RE->getType().getTypePtr() == BO->getType().getTypePtr()) &&
18471            "Either LHS or RHS have base decl inside");
18472     if (BO->getType().getTypePtr() == LE->getType().getTypePtr())
18473       return RelevantExpr || Visit(LE);
18474     return RelevantExpr || Visit(RE);
18475   }
VisitCXXThisExpr(CXXThisExpr * CTE)18476   bool VisitCXXThisExpr(CXXThisExpr *CTE) {
18477     assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
18478     RelevantExpr = CTE;
18479     Components.emplace_back(CTE, nullptr, IsNonContiguous);
18480     return true;
18481   }
VisitCXXOperatorCallExpr(CXXOperatorCallExpr * COCE)18482   bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) {
18483     assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
18484     Components.emplace_back(COCE, nullptr, IsNonContiguous);
18485     return true;
18486   }
VisitOpaqueValueExpr(OpaqueValueExpr * E)18487   bool VisitOpaqueValueExpr(OpaqueValueExpr *E) {
18488     Expr *Source = E->getSourceExpr();
18489     if (!Source) {
18490       emitErrorMsg();
18491       return false;
18492     }
18493     return Visit(Source);
18494   }
VisitStmt(Stmt *)18495   bool VisitStmt(Stmt *) {
18496     emitErrorMsg();
18497     return false;
18498   }
getFoundBase() const18499   const Expr *getFoundBase() const {
18500     return RelevantExpr;
18501   }
MapBaseChecker(Sema & SemaRef,OpenMPClauseKind CKind,OpenMPDirectiveKind DKind,OMPClauseMappableExprCommon::MappableExprComponentList & Components,bool NoDiagnose,SourceLocation & ELoc,SourceRange & ERange)18502   explicit MapBaseChecker(
18503       Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind,
18504       OMPClauseMappableExprCommon::MappableExprComponentList &Components,
18505       bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange)
18506       : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components),
18507         NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
18508 };
18509 } // namespace
18510 
18511 /// Return the expression of the base of the mappable expression or null if it
18512 /// cannot be determined and do all the necessary checks to see if the expression
18513 /// is valid as a standalone mappable expression. In the process, record all the
18514 /// components of the expression.
checkMapClauseExpressionBase(Sema & SemaRef,Expr * E,OMPClauseMappableExprCommon::MappableExprComponentList & CurComponents,OpenMPClauseKind CKind,OpenMPDirectiveKind DKind,bool NoDiagnose)18515 static const Expr *checkMapClauseExpressionBase(
18516     Sema &SemaRef, Expr *E,
18517     OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
18518     OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) {
18519   SourceLocation ELoc = E->getExprLoc();
18520   SourceRange ERange = E->getSourceRange();
18521   MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc,
18522                          ERange);
18523   if (Checker.Visit(E->IgnoreParens())) {
18524     // Check if the highest dimension array section has length specified
18525     if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() &&
18526         (CKind == OMPC_to || CKind == OMPC_from)) {
18527       auto CI = CurComponents.rbegin();
18528       auto CE = CurComponents.rend();
18529       for (; CI != CE; ++CI) {
18530         const auto *OASE =
18531             dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression());
18532         if (!OASE)
18533           continue;
18534         if (OASE && OASE->getLength())
18535           break;
18536         SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length)
18537             << ERange;
18538       }
18539     }
18540     return Checker.getFoundBase();
18541   }
18542   return nullptr;
18543 }
18544 
18545 // Return true if expression E associated with value VD has conflicts with other
18546 // map information.
checkMapConflicts(Sema & SemaRef,DSAStackTy * DSAS,const ValueDecl * VD,const Expr * E,bool CurrentRegionOnly,OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,OpenMPClauseKind CKind)18547 static bool checkMapConflicts(
18548     Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
18549     bool CurrentRegionOnly,
18550     OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
18551     OpenMPClauseKind CKind) {
18552   assert(VD && E);
18553   SourceLocation ELoc = E->getExprLoc();
18554   SourceRange ERange = E->getSourceRange();
18555 
18556   // In order to easily check the conflicts we need to match each component of
18557   // the expression under test with the components of the expressions that are
18558   // already in the stack.
18559 
18560   assert(!CurComponents.empty() && "Map clause expression with no components!");
18561   assert(CurComponents.back().getAssociatedDeclaration() == VD &&
18562          "Map clause expression with unexpected base!");
18563 
18564   // Variables to help detecting enclosing problems in data environment nests.
18565   bool IsEnclosedByDataEnvironmentExpr = false;
18566   const Expr *EnclosingExpr = nullptr;
18567 
18568   bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
18569       VD, CurrentRegionOnly,
18570       [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
18571        ERange, CKind, &EnclosingExpr,
18572        CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef
18573                           StackComponents,
18574                       OpenMPClauseKind Kind) {
18575         if (CKind == Kind && SemaRef.LangOpts.OpenMP >= 50)
18576           return false;
18577         assert(!StackComponents.empty() &&
18578                "Map clause expression with no components!");
18579         assert(StackComponents.back().getAssociatedDeclaration() == VD &&
18580                "Map clause expression with unexpected base!");
18581         (void)VD;
18582 
18583         // The whole expression in the stack.
18584         const Expr *RE = StackComponents.front().getAssociatedExpression();
18585 
18586         // Expressions must start from the same base. Here we detect at which
18587         // point both expressions diverge from each other and see if we can
18588         // detect if the memory referred to both expressions is contiguous and
18589         // do not overlap.
18590         auto CI = CurComponents.rbegin();
18591         auto CE = CurComponents.rend();
18592         auto SI = StackComponents.rbegin();
18593         auto SE = StackComponents.rend();
18594         for (; CI != CE && SI != SE; ++CI, ++SI) {
18595 
18596           // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
18597           //  At most one list item can be an array item derived from a given
18598           //  variable in map clauses of the same construct.
18599           if (CurrentRegionOnly &&
18600               (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
18601                isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) ||
18602                isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) &&
18603               (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
18604                isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) ||
18605                isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) {
18606             SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
18607                          diag::err_omp_multiple_array_items_in_map_clause)
18608                 << CI->getAssociatedExpression()->getSourceRange();
18609             SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
18610                          diag::note_used_here)
18611                 << SI->getAssociatedExpression()->getSourceRange();
18612             return true;
18613           }
18614 
18615           // Do both expressions have the same kind?
18616           if (CI->getAssociatedExpression()->getStmtClass() !=
18617               SI->getAssociatedExpression()->getStmtClass())
18618             break;
18619 
18620           // Are we dealing with different variables/fields?
18621           if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
18622             break;
18623         }
18624         // Check if the extra components of the expressions in the enclosing
18625         // data environment are redundant for the current base declaration.
18626         // If they are, the maps completely overlap, which is legal.
18627         for (; SI != SE; ++SI) {
18628           QualType Type;
18629           if (const auto *ASE =
18630                   dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
18631             Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
18632           } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
18633                          SI->getAssociatedExpression())) {
18634             const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
18635             Type =
18636                 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
18637           } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>(
18638                          SI->getAssociatedExpression())) {
18639             Type = OASE->getBase()->getType()->getPointeeType();
18640           }
18641           if (Type.isNull() || Type->isAnyPointerType() ||
18642               checkArrayExpressionDoesNotReferToWholeSize(
18643                   SemaRef, SI->getAssociatedExpression(), Type))
18644             break;
18645         }
18646 
18647         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
18648         //  List items of map clauses in the same construct must not share
18649         //  original storage.
18650         //
18651         // If the expressions are exactly the same or one is a subset of the
18652         // other, it means they are sharing storage.
18653         if (CI == CE && SI == SE) {
18654           if (CurrentRegionOnly) {
18655             if (CKind == OMPC_map) {
18656               SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
18657             } else {
18658               assert(CKind == OMPC_to || CKind == OMPC_from);
18659               SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
18660                   << ERange;
18661             }
18662             SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
18663                 << RE->getSourceRange();
18664             return true;
18665           }
18666           // If we find the same expression in the enclosing data environment,
18667           // that is legal.
18668           IsEnclosedByDataEnvironmentExpr = true;
18669           return false;
18670         }
18671 
18672         QualType DerivedType =
18673             std::prev(CI)->getAssociatedDeclaration()->getType();
18674         SourceLocation DerivedLoc =
18675             std::prev(CI)->getAssociatedExpression()->getExprLoc();
18676 
18677         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
18678         //  If the type of a list item is a reference to a type T then the type
18679         //  will be considered to be T for all purposes of this clause.
18680         DerivedType = DerivedType.getNonReferenceType();
18681 
18682         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
18683         //  A variable for which the type is pointer and an array section
18684         //  derived from that variable must not appear as list items of map
18685         //  clauses of the same construct.
18686         //
18687         // Also, cover one of the cases in:
18688         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
18689         //  If any part of the original storage of a list item has corresponding
18690         //  storage in the device data environment, all of the original storage
18691         //  must have corresponding storage in the device data environment.
18692         //
18693         if (DerivedType->isAnyPointerType()) {
18694           if (CI == CE || SI == SE) {
18695             SemaRef.Diag(
18696                 DerivedLoc,
18697                 diag::err_omp_pointer_mapped_along_with_derived_section)
18698                 << DerivedLoc;
18699             SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
18700                 << RE->getSourceRange();
18701             return true;
18702           }
18703           if (CI->getAssociatedExpression()->getStmtClass() !=
18704                          SI->getAssociatedExpression()->getStmtClass() ||
18705                      CI->getAssociatedDeclaration()->getCanonicalDecl() ==
18706                          SI->getAssociatedDeclaration()->getCanonicalDecl()) {
18707             assert(CI != CE && SI != SE);
18708             SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
18709                 << DerivedLoc;
18710             SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
18711                 << RE->getSourceRange();
18712             return true;
18713           }
18714         }
18715 
18716         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
18717         //  List items of map clauses in the same construct must not share
18718         //  original storage.
18719         //
18720         // An expression is a subset of the other.
18721         if (CurrentRegionOnly && (CI == CE || SI == SE)) {
18722           if (CKind == OMPC_map) {
18723             if (CI != CE || SI != SE) {
18724               // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
18725               // a pointer.
18726               auto Begin =
18727                   CI != CE ? CurComponents.begin() : StackComponents.begin();
18728               auto End = CI != CE ? CurComponents.end() : StackComponents.end();
18729               auto It = Begin;
18730               while (It != End && !It->getAssociatedDeclaration())
18731                 std::advance(It, 1);
18732               assert(It != End &&
18733                      "Expected at least one component with the declaration.");
18734               if (It != Begin && It->getAssociatedDeclaration()
18735                                      ->getType()
18736                                      .getCanonicalType()
18737                                      ->isAnyPointerType()) {
18738                 IsEnclosedByDataEnvironmentExpr = false;
18739                 EnclosingExpr = nullptr;
18740                 return false;
18741               }
18742             }
18743             SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
18744           } else {
18745             assert(CKind == OMPC_to || CKind == OMPC_from);
18746             SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
18747                 << ERange;
18748           }
18749           SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
18750               << RE->getSourceRange();
18751           return true;
18752         }
18753 
18754         // The current expression uses the same base as other expression in the
18755         // data environment but does not contain it completely.
18756         if (!CurrentRegionOnly && SI != SE)
18757           EnclosingExpr = RE;
18758 
18759         // The current expression is a subset of the expression in the data
18760         // environment.
18761         IsEnclosedByDataEnvironmentExpr |=
18762             (!CurrentRegionOnly && CI != CE && SI == SE);
18763 
18764         return false;
18765       });
18766 
18767   if (CurrentRegionOnly)
18768     return FoundError;
18769 
18770   // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
18771   //  If any part of the original storage of a list item has corresponding
18772   //  storage in the device data environment, all of the original storage must
18773   //  have corresponding storage in the device data environment.
18774   // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
18775   //  If a list item is an element of a structure, and a different element of
18776   //  the structure has a corresponding list item in the device data environment
18777   //  prior to a task encountering the construct associated with the map clause,
18778   //  then the list item must also have a corresponding list item in the device
18779   //  data environment prior to the task encountering the construct.
18780   //
18781   if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
18782     SemaRef.Diag(ELoc,
18783                  diag::err_omp_original_storage_is_shared_and_does_not_contain)
18784         << ERange;
18785     SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
18786         << EnclosingExpr->getSourceRange();
18787     return true;
18788   }
18789 
18790   return FoundError;
18791 }
18792 
18793 // Look up the user-defined mapper given the mapper name and mapped type, and
18794 // build a reference to it.
buildUserDefinedMapperRef(Sema & SemaRef,Scope * S,CXXScopeSpec & MapperIdScopeSpec,const DeclarationNameInfo & MapperId,QualType Type,Expr * UnresolvedMapper)18795 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
18796                                             CXXScopeSpec &MapperIdScopeSpec,
18797                                             const DeclarationNameInfo &MapperId,
18798                                             QualType Type,
18799                                             Expr *UnresolvedMapper) {
18800   if (MapperIdScopeSpec.isInvalid())
18801     return ExprError();
18802   // Get the actual type for the array type.
18803   if (Type->isArrayType()) {
18804     assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type");
18805     Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType();
18806   }
18807   // Find all user-defined mappers with the given MapperId.
18808   SmallVector<UnresolvedSet<8>, 4> Lookups;
18809   LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
18810   Lookup.suppressDiagnostics();
18811   if (S) {
18812     while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) {
18813       NamedDecl *D = Lookup.getRepresentativeDecl();
18814       while (S && !S->isDeclScope(D))
18815         S = S->getParent();
18816       if (S)
18817         S = S->getParent();
18818       Lookups.emplace_back();
18819       Lookups.back().append(Lookup.begin(), Lookup.end());
18820       Lookup.clear();
18821     }
18822   } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
18823     // Extract the user-defined mappers with the given MapperId.
18824     Lookups.push_back(UnresolvedSet<8>());
18825     for (NamedDecl *D : ULE->decls()) {
18826       auto *DMD = cast<OMPDeclareMapperDecl>(D);
18827       assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation.");
18828       Lookups.back().addDecl(DMD);
18829     }
18830   }
18831   // Defer the lookup for dependent types. The results will be passed through
18832   // UnresolvedMapper on instantiation.
18833   if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
18834       Type->isInstantiationDependentType() ||
18835       Type->containsUnexpandedParameterPack() ||
18836       filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
18837         return !D->isInvalidDecl() &&
18838                (D->getType()->isDependentType() ||
18839                 D->getType()->isInstantiationDependentType() ||
18840                 D->getType()->containsUnexpandedParameterPack());
18841       })) {
18842     UnresolvedSet<8> URS;
18843     for (const UnresolvedSet<8> &Set : Lookups) {
18844       if (Set.empty())
18845         continue;
18846       URS.append(Set.begin(), Set.end());
18847     }
18848     return UnresolvedLookupExpr::Create(
18849         SemaRef.Context, /*NamingClass=*/nullptr,
18850         MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
18851         /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end());
18852   }
18853   SourceLocation Loc = MapperId.getLoc();
18854   // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
18855   //  The type must be of struct, union or class type in C and C++
18856   if (!Type->isStructureOrClassType() && !Type->isUnionType() &&
18857       (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) {
18858     SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type);
18859     return ExprError();
18860   }
18861   // Perform argument dependent lookup.
18862   if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
18863     argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
18864   // Return the first user-defined mapper with the desired type.
18865   if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
18866           Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
18867             if (!D->isInvalidDecl() &&
18868                 SemaRef.Context.hasSameType(D->getType(), Type))
18869               return D;
18870             return nullptr;
18871           }))
18872     return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
18873   // Find the first user-defined mapper with a type derived from the desired
18874   // type.
18875   if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
18876           Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
18877             if (!D->isInvalidDecl() &&
18878                 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
18879                 !Type.isMoreQualifiedThan(D->getType()))
18880               return D;
18881             return nullptr;
18882           })) {
18883     CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
18884                        /*DetectVirtual=*/false);
18885     if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
18886       if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
18887               VD->getType().getUnqualifiedType()))) {
18888         if (SemaRef.CheckBaseClassAccess(
18889                 Loc, VD->getType(), Type, Paths.front(),
18890                 /*DiagID=*/0) != Sema::AR_inaccessible) {
18891           return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
18892         }
18893       }
18894     }
18895   }
18896   // Report error if a mapper is specified, but cannot be found.
18897   if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
18898     SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
18899         << Type << MapperId.getName();
18900     return ExprError();
18901   }
18902   return ExprEmpty();
18903 }
18904 
18905 namespace {
18906 // Utility struct that gathers all the related lists associated with a mappable
18907 // expression.
18908 struct MappableVarListInfo {
18909   // The list of expressions.
18910   ArrayRef<Expr *> VarList;
18911   // The list of processed expressions.
18912   SmallVector<Expr *, 16> ProcessedVarList;
18913   // The mappble components for each expression.
18914   OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
18915   // The base declaration of the variable.
18916   SmallVector<ValueDecl *, 16> VarBaseDeclarations;
18917   // The reference to the user-defined mapper associated with every expression.
18918   SmallVector<Expr *, 16> UDMapperList;
18919 
MappableVarListInfo__anon022d4e255211::MappableVarListInfo18920   MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
18921     // We have a list of components and base declarations for each entry in the
18922     // variable list.
18923     VarComponents.reserve(VarList.size());
18924     VarBaseDeclarations.reserve(VarList.size());
18925   }
18926 };
18927 }
18928 
18929 // Check the validity of the provided variable list for the provided clause kind
18930 // \a CKind. In the check process the valid expressions, mappable expression
18931 // components, variables, and user-defined mappers are extracted and used to
18932 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
18933 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
18934 // and \a MapperId are expected to be valid if the clause kind is 'map'.
checkMappableExpressionList(Sema & SemaRef,DSAStackTy * DSAS,OpenMPClauseKind CKind,MappableVarListInfo & MVLI,SourceLocation StartLoc,CXXScopeSpec & MapperIdScopeSpec,DeclarationNameInfo MapperId,ArrayRef<Expr * > UnresolvedMappers,OpenMPMapClauseKind MapType=OMPC_MAP_unknown,bool IsMapTypeImplicit=false)18935 static void checkMappableExpressionList(
18936     Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
18937     MappableVarListInfo &MVLI, SourceLocation StartLoc,
18938     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
18939     ArrayRef<Expr *> UnresolvedMappers,
18940     OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
18941     bool IsMapTypeImplicit = false) {
18942   // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
18943   assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
18944          "Unexpected clause kind with mappable expressions!");
18945 
18946   // If the identifier of user-defined mapper is not specified, it is "default".
18947   // We do not change the actual name in this clause to distinguish whether a
18948   // mapper is specified explicitly, i.e., it is not explicitly specified when
18949   // MapperId.getName() is empty.
18950   if (!MapperId.getName() || MapperId.getName().isEmpty()) {
18951     auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
18952     MapperId.setName(DeclNames.getIdentifier(
18953         &SemaRef.getASTContext().Idents.get("default")));
18954     MapperId.setLoc(StartLoc);
18955   }
18956 
18957   // Iterators to find the current unresolved mapper expression.
18958   auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
18959   bool UpdateUMIt = false;
18960   Expr *UnresolvedMapper = nullptr;
18961 
18962   // Keep track of the mappable components and base declarations in this clause.
18963   // Each entry in the list is going to have a list of components associated. We
18964   // record each set of the components so that we can build the clause later on.
18965   // In the end we should have the same amount of declarations and component
18966   // lists.
18967 
18968   for (Expr *RE : MVLI.VarList) {
18969     assert(RE && "Null expr in omp to/from/map clause");
18970     SourceLocation ELoc = RE->getExprLoc();
18971 
18972     // Find the current unresolved mapper expression.
18973     if (UpdateUMIt && UMIt != UMEnd) {
18974       UMIt++;
18975       assert(
18976           UMIt != UMEnd &&
18977           "Expect the size of UnresolvedMappers to match with that of VarList");
18978     }
18979     UpdateUMIt = true;
18980     if (UMIt != UMEnd)
18981       UnresolvedMapper = *UMIt;
18982 
18983     const Expr *VE = RE->IgnoreParenLValueCasts();
18984 
18985     if (VE->isValueDependent() || VE->isTypeDependent() ||
18986         VE->isInstantiationDependent() ||
18987         VE->containsUnexpandedParameterPack()) {
18988       // Try to find the associated user-defined mapper.
18989       ExprResult ER = buildUserDefinedMapperRef(
18990           SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
18991           VE->getType().getCanonicalType(), UnresolvedMapper);
18992       if (ER.isInvalid())
18993         continue;
18994       MVLI.UDMapperList.push_back(ER.get());
18995       // We can only analyze this information once the missing information is
18996       // resolved.
18997       MVLI.ProcessedVarList.push_back(RE);
18998       continue;
18999     }
19000 
19001     Expr *SimpleExpr = RE->IgnoreParenCasts();
19002 
19003     if (!RE->isLValue()) {
19004       if (SemaRef.getLangOpts().OpenMP < 50) {
19005         SemaRef.Diag(
19006             ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
19007             << RE->getSourceRange();
19008       } else {
19009         SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
19010             << getOpenMPClauseName(CKind) << RE->getSourceRange();
19011       }
19012       continue;
19013     }
19014 
19015     OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
19016     ValueDecl *CurDeclaration = nullptr;
19017 
19018     // Obtain the array or member expression bases if required. Also, fill the
19019     // components array with all the components identified in the process.
19020     const Expr *BE = checkMapClauseExpressionBase(
19021         SemaRef, SimpleExpr, CurComponents, CKind, DSAS->getCurrentDirective(),
19022         /*NoDiagnose=*/false);
19023     if (!BE)
19024       continue;
19025 
19026     assert(!CurComponents.empty() &&
19027            "Invalid mappable expression information.");
19028 
19029     if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
19030       // Add store "this" pointer to class in DSAStackTy for future checking
19031       DSAS->addMappedClassesQualTypes(TE->getType());
19032       // Try to find the associated user-defined mapper.
19033       ExprResult ER = buildUserDefinedMapperRef(
19034           SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
19035           VE->getType().getCanonicalType(), UnresolvedMapper);
19036       if (ER.isInvalid())
19037         continue;
19038       MVLI.UDMapperList.push_back(ER.get());
19039       // Skip restriction checking for variable or field declarations
19040       MVLI.ProcessedVarList.push_back(RE);
19041       MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
19042       MVLI.VarComponents.back().append(CurComponents.begin(),
19043                                        CurComponents.end());
19044       MVLI.VarBaseDeclarations.push_back(nullptr);
19045       continue;
19046     }
19047 
19048     // For the following checks, we rely on the base declaration which is
19049     // expected to be associated with the last component. The declaration is
19050     // expected to be a variable or a field (if 'this' is being mapped).
19051     CurDeclaration = CurComponents.back().getAssociatedDeclaration();
19052     assert(CurDeclaration && "Null decl on map clause.");
19053     assert(
19054         CurDeclaration->isCanonicalDecl() &&
19055         "Expecting components to have associated only canonical declarations.");
19056 
19057     auto *VD = dyn_cast<VarDecl>(CurDeclaration);
19058     const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
19059 
19060     assert((VD || FD) && "Only variables or fields are expected here!");
19061     (void)FD;
19062 
19063     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
19064     // threadprivate variables cannot appear in a map clause.
19065     // OpenMP 4.5 [2.10.5, target update Construct]
19066     // threadprivate variables cannot appear in a from clause.
19067     if (VD && DSAS->isThreadPrivate(VD)) {
19068       DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
19069       SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
19070           << getOpenMPClauseName(CKind);
19071       reportOriginalDsa(SemaRef, DSAS, VD, DVar);
19072       continue;
19073     }
19074 
19075     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
19076     //  A list item cannot appear in both a map clause and a data-sharing
19077     //  attribute clause on the same construct.
19078 
19079     // Check conflicts with other map clause expressions. We check the conflicts
19080     // with the current construct separately from the enclosing data
19081     // environment, because the restrictions are different. We only have to
19082     // check conflicts across regions for the map clauses.
19083     if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
19084                           /*CurrentRegionOnly=*/true, CurComponents, CKind))
19085       break;
19086     if (CKind == OMPC_map &&
19087         (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) &&
19088         checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
19089                           /*CurrentRegionOnly=*/false, CurComponents, CKind))
19090       break;
19091 
19092     // OpenMP 4.5 [2.10.5, target update Construct]
19093     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
19094     //  If the type of a list item is a reference to a type T then the type will
19095     //  be considered to be T for all purposes of this clause.
19096     auto I = llvm::find_if(
19097         CurComponents,
19098         [](const OMPClauseMappableExprCommon::MappableComponent &MC) {
19099           return MC.getAssociatedDeclaration();
19100         });
19101     assert(I != CurComponents.end() && "Null decl on map clause.");
19102     (void)I;
19103     QualType Type;
19104     auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens());
19105     auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens());
19106     auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens());
19107     if (ASE) {
19108       Type = ASE->getType().getNonReferenceType();
19109     } else if (OASE) {
19110       QualType BaseType =
19111           OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
19112       if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
19113         Type = ATy->getElementType();
19114       else
19115         Type = BaseType->getPointeeType();
19116       Type = Type.getNonReferenceType();
19117     } else if (OAShE) {
19118       Type = OAShE->getBase()->getType()->getPointeeType();
19119     } else {
19120       Type = VE->getType();
19121     }
19122 
19123     // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
19124     // A list item in a to or from clause must have a mappable type.
19125     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
19126     //  A list item must have a mappable type.
19127     if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
19128                            DSAS, Type))
19129       continue;
19130 
19131     if (CKind == OMPC_map) {
19132       // target enter data
19133       // OpenMP [2.10.2, Restrictions, p. 99]
19134       // A map-type must be specified in all map clauses and must be either
19135       // to or alloc.
19136       OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
19137       if (DKind == OMPD_target_enter_data &&
19138           !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
19139         SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
19140             << (IsMapTypeImplicit ? 1 : 0)
19141             << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
19142             << getOpenMPDirectiveName(DKind);
19143         continue;
19144       }
19145 
19146       // target exit_data
19147       // OpenMP [2.10.3, Restrictions, p. 102]
19148       // A map-type must be specified in all map clauses and must be either
19149       // from, release, or delete.
19150       if (DKind == OMPD_target_exit_data &&
19151           !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
19152             MapType == OMPC_MAP_delete)) {
19153         SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
19154             << (IsMapTypeImplicit ? 1 : 0)
19155             << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
19156             << getOpenMPDirectiveName(DKind);
19157         continue;
19158       }
19159 
19160       // target, target data
19161       // OpenMP 5.0 [2.12.2, Restrictions, p. 163]
19162       // OpenMP 5.0 [2.12.5, Restrictions, p. 174]
19163       // A map-type in a map clause must be to, from, tofrom or alloc
19164       if ((DKind == OMPD_target_data ||
19165            isOpenMPTargetExecutionDirective(DKind)) &&
19166           !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
19167             MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) {
19168         SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
19169             << (IsMapTypeImplicit ? 1 : 0)
19170             << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
19171             << getOpenMPDirectiveName(DKind);
19172         continue;
19173       }
19174 
19175       // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
19176       // A list item cannot appear in both a map clause and a data-sharing
19177       // attribute clause on the same construct
19178       //
19179       // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
19180       // A list item cannot appear in both a map clause and a data-sharing
19181       // attribute clause on the same construct unless the construct is a
19182       // combined construct.
19183       if (VD && ((SemaRef.LangOpts.OpenMP <= 45 &&
19184                   isOpenMPTargetExecutionDirective(DKind)) ||
19185                  DKind == OMPD_target)) {
19186         DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
19187         if (isOpenMPPrivate(DVar.CKind)) {
19188           SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
19189               << getOpenMPClauseName(DVar.CKind)
19190               << getOpenMPClauseName(OMPC_map)
19191               << getOpenMPDirectiveName(DSAS->getCurrentDirective());
19192           reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
19193           continue;
19194         }
19195       }
19196     }
19197 
19198     // Try to find the associated user-defined mapper.
19199     ExprResult ER = buildUserDefinedMapperRef(
19200         SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
19201         Type.getCanonicalType(), UnresolvedMapper);
19202     if (ER.isInvalid())
19203       continue;
19204     MVLI.UDMapperList.push_back(ER.get());
19205 
19206     // Save the current expression.
19207     MVLI.ProcessedVarList.push_back(RE);
19208 
19209     // Store the components in the stack so that they can be used to check
19210     // against other clauses later on.
19211     DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
19212                                           /*WhereFoundClauseKind=*/OMPC_map);
19213 
19214     // Save the components and declaration to create the clause. For purposes of
19215     // the clause creation, any component list that has has base 'this' uses
19216     // null as base declaration.
19217     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
19218     MVLI.VarComponents.back().append(CurComponents.begin(),
19219                                      CurComponents.end());
19220     MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
19221                                                            : CurDeclaration);
19222   }
19223 }
19224 
ActOnOpenMPMapClause(ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,ArrayRef<SourceLocation> MapTypeModifiersLoc,CXXScopeSpec & MapperIdScopeSpec,DeclarationNameInfo & MapperId,OpenMPMapClauseKind MapType,bool IsMapTypeImplicit,SourceLocation MapLoc,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs,ArrayRef<Expr * > UnresolvedMappers)19225 OMPClause *Sema::ActOnOpenMPMapClause(
19226     ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
19227     ArrayRef<SourceLocation> MapTypeModifiersLoc,
19228     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
19229     OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
19230     SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
19231     const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
19232   OpenMPMapModifierKind Modifiers[] = {
19233       OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
19234       OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown};
19235   SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers];
19236 
19237   // Process map-type-modifiers, flag errors for duplicate modifiers.
19238   unsigned Count = 0;
19239   for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
19240     if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
19241         llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) {
19242       Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
19243       continue;
19244     }
19245     assert(Count < NumberOfOMPMapClauseModifiers &&
19246            "Modifiers exceed the allowed number of map type modifiers");
19247     Modifiers[Count] = MapTypeModifiers[I];
19248     ModifiersLoc[Count] = MapTypeModifiersLoc[I];
19249     ++Count;
19250   }
19251 
19252   MappableVarListInfo MVLI(VarList);
19253   checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc,
19254                               MapperIdScopeSpec, MapperId, UnresolvedMappers,
19255                               MapType, IsMapTypeImplicit);
19256 
19257   // We need to produce a map clause even if we don't have variables so that
19258   // other diagnostics related with non-existing map clauses are accurate.
19259   return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList,
19260                               MVLI.VarBaseDeclarations, MVLI.VarComponents,
19261                               MVLI.UDMapperList, Modifiers, ModifiersLoc,
19262                               MapperIdScopeSpec.getWithLocInContext(Context),
19263                               MapperId, MapType, IsMapTypeImplicit, MapLoc);
19264 }
19265 
ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,TypeResult ParsedType)19266 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
19267                                                TypeResult ParsedType) {
19268   assert(ParsedType.isUsable());
19269 
19270   QualType ReductionType = GetTypeFromParser(ParsedType.get());
19271   if (ReductionType.isNull())
19272     return QualType();
19273 
19274   // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
19275   // A type name in a declare reduction directive cannot be a function type, an
19276   // array type, a reference type, or a type qualified with const, volatile or
19277   // restrict.
19278   if (ReductionType.hasQualifiers()) {
19279     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
19280     return QualType();
19281   }
19282 
19283   if (ReductionType->isFunctionType()) {
19284     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
19285     return QualType();
19286   }
19287   if (ReductionType->isReferenceType()) {
19288     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
19289     return QualType();
19290   }
19291   if (ReductionType->isArrayType()) {
19292     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
19293     return QualType();
19294   }
19295   return ReductionType;
19296 }
19297 
ActOnOpenMPDeclareReductionDirectiveStart(Scope * S,DeclContext * DC,DeclarationName Name,ArrayRef<std::pair<QualType,SourceLocation>> ReductionTypes,AccessSpecifier AS,Decl * PrevDeclInScope)19298 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
19299     Scope *S, DeclContext *DC, DeclarationName Name,
19300     ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
19301     AccessSpecifier AS, Decl *PrevDeclInScope) {
19302   SmallVector<Decl *, 8> Decls;
19303   Decls.reserve(ReductionTypes.size());
19304 
19305   LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
19306                       forRedeclarationInCurContext());
19307   // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
19308   // A reduction-identifier may not be re-declared in the current scope for the
19309   // same type or for a type that is compatible according to the base language
19310   // rules.
19311   llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
19312   OMPDeclareReductionDecl *PrevDRD = nullptr;
19313   bool InCompoundScope = true;
19314   if (S != nullptr) {
19315     // Find previous declaration with the same name not referenced in other
19316     // declarations.
19317     FunctionScopeInfo *ParentFn = getEnclosingFunction();
19318     InCompoundScope =
19319         (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
19320     LookupName(Lookup, S);
19321     FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
19322                          /*AllowInlineNamespace=*/false);
19323     llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
19324     LookupResult::Filter Filter = Lookup.makeFilter();
19325     while (Filter.hasNext()) {
19326       auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
19327       if (InCompoundScope) {
19328         auto I = UsedAsPrevious.find(PrevDecl);
19329         if (I == UsedAsPrevious.end())
19330           UsedAsPrevious[PrevDecl] = false;
19331         if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
19332           UsedAsPrevious[D] = true;
19333       }
19334       PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
19335           PrevDecl->getLocation();
19336     }
19337     Filter.done();
19338     if (InCompoundScope) {
19339       for (const auto &PrevData : UsedAsPrevious) {
19340         if (!PrevData.second) {
19341           PrevDRD = PrevData.first;
19342           break;
19343         }
19344       }
19345     }
19346   } else if (PrevDeclInScope != nullptr) {
19347     auto *PrevDRDInScope = PrevDRD =
19348         cast<OMPDeclareReductionDecl>(PrevDeclInScope);
19349     do {
19350       PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
19351           PrevDRDInScope->getLocation();
19352       PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
19353     } while (PrevDRDInScope != nullptr);
19354   }
19355   for (const auto &TyData : ReductionTypes) {
19356     const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
19357     bool Invalid = false;
19358     if (I != PreviousRedeclTypes.end()) {
19359       Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
19360           << TyData.first;
19361       Diag(I->second, diag::note_previous_definition);
19362       Invalid = true;
19363     }
19364     PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
19365     auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
19366                                                 Name, TyData.first, PrevDRD);
19367     DC->addDecl(DRD);
19368     DRD->setAccess(AS);
19369     Decls.push_back(DRD);
19370     if (Invalid)
19371       DRD->setInvalidDecl();
19372     else
19373       PrevDRD = DRD;
19374   }
19375 
19376   return DeclGroupPtrTy::make(
19377       DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
19378 }
19379 
ActOnOpenMPDeclareReductionCombinerStart(Scope * S,Decl * D)19380 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
19381   auto *DRD = cast<OMPDeclareReductionDecl>(D);
19382 
19383   // Enter new function scope.
19384   PushFunctionScope();
19385   setFunctionHasBranchProtectedScope();
19386   getCurFunction()->setHasOMPDeclareReductionCombiner();
19387 
19388   if (S != nullptr)
19389     PushDeclContext(S, DRD);
19390   else
19391     CurContext = DRD;
19392 
19393   PushExpressionEvaluationContext(
19394       ExpressionEvaluationContext::PotentiallyEvaluated);
19395 
19396   QualType ReductionType = DRD->getType();
19397   // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
19398   // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
19399   // uses semantics of argument handles by value, but it should be passed by
19400   // reference. C lang does not support references, so pass all parameters as
19401   // pointers.
19402   // Create 'T omp_in;' variable.
19403   VarDecl *OmpInParm =
19404       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
19405   // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
19406   // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
19407   // uses semantics of argument handles by value, but it should be passed by
19408   // reference. C lang does not support references, so pass all parameters as
19409   // pointers.
19410   // Create 'T omp_out;' variable.
19411   VarDecl *OmpOutParm =
19412       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
19413   if (S != nullptr) {
19414     PushOnScopeChains(OmpInParm, S);
19415     PushOnScopeChains(OmpOutParm, S);
19416   } else {
19417     DRD->addDecl(OmpInParm);
19418     DRD->addDecl(OmpOutParm);
19419   }
19420   Expr *InE =
19421       ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
19422   Expr *OutE =
19423       ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
19424   DRD->setCombinerData(InE, OutE);
19425 }
19426 
ActOnOpenMPDeclareReductionCombinerEnd(Decl * D,Expr * Combiner)19427 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
19428   auto *DRD = cast<OMPDeclareReductionDecl>(D);
19429   DiscardCleanupsInEvaluationContext();
19430   PopExpressionEvaluationContext();
19431 
19432   PopDeclContext();
19433   PopFunctionScopeInfo();
19434 
19435   if (Combiner != nullptr)
19436     DRD->setCombiner(Combiner);
19437   else
19438     DRD->setInvalidDecl();
19439 }
19440 
ActOnOpenMPDeclareReductionInitializerStart(Scope * S,Decl * D)19441 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
19442   auto *DRD = cast<OMPDeclareReductionDecl>(D);
19443 
19444   // Enter new function scope.
19445   PushFunctionScope();
19446   setFunctionHasBranchProtectedScope();
19447 
19448   if (S != nullptr)
19449     PushDeclContext(S, DRD);
19450   else
19451     CurContext = DRD;
19452 
19453   PushExpressionEvaluationContext(
19454       ExpressionEvaluationContext::PotentiallyEvaluated);
19455 
19456   QualType ReductionType = DRD->getType();
19457   // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
19458   // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
19459   // uses semantics of argument handles by value, but it should be passed by
19460   // reference. C lang does not support references, so pass all parameters as
19461   // pointers.
19462   // Create 'T omp_priv;' variable.
19463   VarDecl *OmpPrivParm =
19464       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
19465   // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
19466   // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
19467   // uses semantics of argument handles by value, but it should be passed by
19468   // reference. C lang does not support references, so pass all parameters as
19469   // pointers.
19470   // Create 'T omp_orig;' variable.
19471   VarDecl *OmpOrigParm =
19472       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
19473   if (S != nullptr) {
19474     PushOnScopeChains(OmpPrivParm, S);
19475     PushOnScopeChains(OmpOrigParm, S);
19476   } else {
19477     DRD->addDecl(OmpPrivParm);
19478     DRD->addDecl(OmpOrigParm);
19479   }
19480   Expr *OrigE =
19481       ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
19482   Expr *PrivE =
19483       ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
19484   DRD->setInitializerData(OrigE, PrivE);
19485   return OmpPrivParm;
19486 }
19487 
ActOnOpenMPDeclareReductionInitializerEnd(Decl * D,Expr * Initializer,VarDecl * OmpPrivParm)19488 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
19489                                                      VarDecl *OmpPrivParm) {
19490   auto *DRD = cast<OMPDeclareReductionDecl>(D);
19491   DiscardCleanupsInEvaluationContext();
19492   PopExpressionEvaluationContext();
19493 
19494   PopDeclContext();
19495   PopFunctionScopeInfo();
19496 
19497   if (Initializer != nullptr) {
19498     DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
19499   } else if (OmpPrivParm->hasInit()) {
19500     DRD->setInitializer(OmpPrivParm->getInit(),
19501                         OmpPrivParm->isDirectInit()
19502                             ? OMPDeclareReductionDecl::DirectInit
19503                             : OMPDeclareReductionDecl::CopyInit);
19504   } else {
19505     DRD->setInvalidDecl();
19506   }
19507 }
19508 
ActOnOpenMPDeclareReductionDirectiveEnd(Scope * S,DeclGroupPtrTy DeclReductions,bool IsValid)19509 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
19510     Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
19511   for (Decl *D : DeclReductions.get()) {
19512     if (IsValid) {
19513       if (S)
19514         PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
19515                           /*AddToContext=*/false);
19516     } else {
19517       D->setInvalidDecl();
19518     }
19519   }
19520   return DeclReductions;
19521 }
19522 
ActOnOpenMPDeclareMapperVarDecl(Scope * S,Declarator & D)19523 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) {
19524   TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
19525   QualType T = TInfo->getType();
19526   if (D.isInvalidType())
19527     return true;
19528 
19529   if (getLangOpts().CPlusPlus) {
19530     // Check that there are no default arguments (C++ only).
19531     CheckExtraCXXDefaultArguments(D);
19532   }
19533 
19534   return CreateParsedType(T, TInfo);
19535 }
19536 
ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,TypeResult ParsedType)19537 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
19538                                             TypeResult ParsedType) {
19539   assert(ParsedType.isUsable() && "Expect usable parsed mapper type");
19540 
19541   QualType MapperType = GetTypeFromParser(ParsedType.get());
19542   assert(!MapperType.isNull() && "Expect valid mapper type");
19543 
19544   // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
19545   //  The type must be of struct, union or class type in C and C++
19546   if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
19547     Diag(TyLoc, diag::err_omp_mapper_wrong_type);
19548     return QualType();
19549   }
19550   return MapperType;
19551 }
19552 
ActOnOpenMPDeclareMapperDirective(Scope * S,DeclContext * DC,DeclarationName Name,QualType MapperType,SourceLocation StartLoc,DeclarationName VN,AccessSpecifier AS,Expr * MapperVarRef,ArrayRef<OMPClause * > Clauses,Decl * PrevDeclInScope)19553 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective(
19554     Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
19555     SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
19556     Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) {
19557   LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
19558                       forRedeclarationInCurContext());
19559   // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
19560   //  A mapper-identifier may not be redeclared in the current scope for the
19561   //  same type or for a type that is compatible according to the base language
19562   //  rules.
19563   llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
19564   OMPDeclareMapperDecl *PrevDMD = nullptr;
19565   bool InCompoundScope = true;
19566   if (S != nullptr) {
19567     // Find previous declaration with the same name not referenced in other
19568     // declarations.
19569     FunctionScopeInfo *ParentFn = getEnclosingFunction();
19570     InCompoundScope =
19571         (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
19572     LookupName(Lookup, S);
19573     FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
19574                          /*AllowInlineNamespace=*/false);
19575     llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
19576     LookupResult::Filter Filter = Lookup.makeFilter();
19577     while (Filter.hasNext()) {
19578       auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
19579       if (InCompoundScope) {
19580         auto I = UsedAsPrevious.find(PrevDecl);
19581         if (I == UsedAsPrevious.end())
19582           UsedAsPrevious[PrevDecl] = false;
19583         if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
19584           UsedAsPrevious[D] = true;
19585       }
19586       PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
19587           PrevDecl->getLocation();
19588     }
19589     Filter.done();
19590     if (InCompoundScope) {
19591       for (const auto &PrevData : UsedAsPrevious) {
19592         if (!PrevData.second) {
19593           PrevDMD = PrevData.first;
19594           break;
19595         }
19596       }
19597     }
19598   } else if (PrevDeclInScope) {
19599     auto *PrevDMDInScope = PrevDMD =
19600         cast<OMPDeclareMapperDecl>(PrevDeclInScope);
19601     do {
19602       PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
19603           PrevDMDInScope->getLocation();
19604       PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
19605     } while (PrevDMDInScope != nullptr);
19606   }
19607   const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
19608   bool Invalid = false;
19609   if (I != PreviousRedeclTypes.end()) {
19610     Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
19611         << MapperType << Name;
19612     Diag(I->second, diag::note_previous_definition);
19613     Invalid = true;
19614   }
19615   // Build expressions for implicit maps of data members with 'default'
19616   // mappers.
19617   SmallVector<OMPClause *, 4> ClausesWithImplicit(Clauses.begin(),
19618                                                   Clauses.end());
19619   if (LangOpts.OpenMP >= 50)
19620     processImplicitMapsWithDefaultMappers(*this, DSAStack, ClausesWithImplicit);
19621   auto *DMD =
19622       OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, MapperType, VN,
19623                                    ClausesWithImplicit, PrevDMD);
19624   if (S)
19625     PushOnScopeChains(DMD, S);
19626   else
19627     DC->addDecl(DMD);
19628   DMD->setAccess(AS);
19629   if (Invalid)
19630     DMD->setInvalidDecl();
19631 
19632   auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl();
19633   VD->setDeclContext(DMD);
19634   VD->setLexicalDeclContext(DMD);
19635   DMD->addDecl(VD);
19636   DMD->setMapperVarRef(MapperVarRef);
19637 
19638   return DeclGroupPtrTy::make(DeclGroupRef(DMD));
19639 }
19640 
19641 ExprResult
ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope * S,QualType MapperType,SourceLocation StartLoc,DeclarationName VN)19642 Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType,
19643                                                SourceLocation StartLoc,
19644                                                DeclarationName VN) {
19645   TypeSourceInfo *TInfo =
19646       Context.getTrivialTypeSourceInfo(MapperType, StartLoc);
19647   auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(),
19648                              StartLoc, StartLoc, VN.getAsIdentifierInfo(),
19649                              MapperType, TInfo, SC_None);
19650   if (S)
19651     PushOnScopeChains(VD, S, /*AddToContext=*/false);
19652   Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
19653   DSAStack->addDeclareMapperVarRef(E);
19654   return E;
19655 }
19656 
isOpenMPDeclareMapperVarDeclAllowed(const VarDecl * VD) const19657 bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const {
19658   assert(LangOpts.OpenMP && "Expected OpenMP mode.");
19659   const Expr *Ref = DSAStack->getDeclareMapperVarRef();
19660   if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref))
19661     return VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl();
19662   return true;
19663 }
19664 
getOpenMPDeclareMapperVarName() const19665 const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const {
19666   assert(LangOpts.OpenMP && "Expected OpenMP mode.");
19667   return cast<DeclRefExpr>(DSAStack->getDeclareMapperVarRef())->getDecl();
19668 }
19669 
ActOnOpenMPNumTeamsClause(Expr * NumTeams,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)19670 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
19671                                            SourceLocation StartLoc,
19672                                            SourceLocation LParenLoc,
19673                                            SourceLocation EndLoc) {
19674   Expr *ValExpr = NumTeams;
19675   Stmt *HelperValStmt = nullptr;
19676 
19677   // OpenMP [teams Constrcut, Restrictions]
19678   // The num_teams expression must evaluate to a positive integer value.
19679   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
19680                                  /*StrictlyPositive=*/true))
19681     return nullptr;
19682 
19683   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
19684   OpenMPDirectiveKind CaptureRegion =
19685       getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP);
19686   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
19687     ValExpr = MakeFullExpr(ValExpr).get();
19688     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
19689     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
19690     HelperValStmt = buildPreInits(Context, Captures);
19691   }
19692 
19693   return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
19694                                          StartLoc, LParenLoc, EndLoc);
19695 }
19696 
ActOnOpenMPThreadLimitClause(Expr * ThreadLimit,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)19697 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
19698                                               SourceLocation StartLoc,
19699                                               SourceLocation LParenLoc,
19700                                               SourceLocation EndLoc) {
19701   Expr *ValExpr = ThreadLimit;
19702   Stmt *HelperValStmt = nullptr;
19703 
19704   // OpenMP [teams Constrcut, Restrictions]
19705   // The thread_limit expression must evaluate to a positive integer value.
19706   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
19707                                  /*StrictlyPositive=*/true))
19708     return nullptr;
19709 
19710   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
19711   OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
19712       DKind, OMPC_thread_limit, LangOpts.OpenMP);
19713   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
19714     ValExpr = MakeFullExpr(ValExpr).get();
19715     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
19716     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
19717     HelperValStmt = buildPreInits(Context, Captures);
19718   }
19719 
19720   return new (Context) OMPThreadLimitClause(
19721       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
19722 }
19723 
ActOnOpenMPPriorityClause(Expr * Priority,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)19724 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
19725                                            SourceLocation StartLoc,
19726                                            SourceLocation LParenLoc,
19727                                            SourceLocation EndLoc) {
19728   Expr *ValExpr = Priority;
19729   Stmt *HelperValStmt = nullptr;
19730   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
19731 
19732   // OpenMP [2.9.1, task Constrcut]
19733   // The priority-value is a non-negative numerical scalar expression.
19734   if (!isNonNegativeIntegerValue(
19735           ValExpr, *this, OMPC_priority,
19736           /*StrictlyPositive=*/false, /*BuildCapture=*/true,
19737           DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
19738     return nullptr;
19739 
19740   return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion,
19741                                          StartLoc, LParenLoc, EndLoc);
19742 }
19743 
ActOnOpenMPGrainsizeClause(Expr * Grainsize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)19744 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize,
19745                                             SourceLocation StartLoc,
19746                                             SourceLocation LParenLoc,
19747                                             SourceLocation EndLoc) {
19748   Expr *ValExpr = Grainsize;
19749   Stmt *HelperValStmt = nullptr;
19750   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
19751 
19752   // OpenMP [2.9.2, taskloop Constrcut]
19753   // The parameter of the grainsize clause must be a positive integer
19754   // expression.
19755   if (!isNonNegativeIntegerValue(
19756           ValExpr, *this, OMPC_grainsize,
19757           /*StrictlyPositive=*/true, /*BuildCapture=*/true,
19758           DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
19759     return nullptr;
19760 
19761   return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion,
19762                                           StartLoc, LParenLoc, EndLoc);
19763 }
19764 
ActOnOpenMPNumTasksClause(Expr * NumTasks,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)19765 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
19766                                            SourceLocation StartLoc,
19767                                            SourceLocation LParenLoc,
19768                                            SourceLocation EndLoc) {
19769   Expr *ValExpr = NumTasks;
19770   Stmt *HelperValStmt = nullptr;
19771   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
19772 
19773   // OpenMP [2.9.2, taskloop Constrcut]
19774   // The parameter of the num_tasks clause must be a positive integer
19775   // expression.
19776   if (!isNonNegativeIntegerValue(
19777           ValExpr, *this, OMPC_num_tasks,
19778           /*StrictlyPositive=*/true, /*BuildCapture=*/true,
19779           DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
19780     return nullptr;
19781 
19782   return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion,
19783                                          StartLoc, LParenLoc, EndLoc);
19784 }
19785 
ActOnOpenMPHintClause(Expr * Hint,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)19786 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
19787                                        SourceLocation LParenLoc,
19788                                        SourceLocation EndLoc) {
19789   // OpenMP [2.13.2, critical construct, Description]
19790   // ... where hint-expression is an integer constant expression that evaluates
19791   // to a valid lock hint.
19792   ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
19793   if (HintExpr.isInvalid())
19794     return nullptr;
19795   return new (Context)
19796       OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
19797 }
19798 
19799 /// Tries to find omp_event_handle_t type.
findOMPEventHandleT(Sema & S,SourceLocation Loc,DSAStackTy * Stack)19800 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc,
19801                                 DSAStackTy *Stack) {
19802   QualType OMPEventHandleT = Stack->getOMPEventHandleT();
19803   if (!OMPEventHandleT.isNull())
19804     return true;
19805   IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t");
19806   ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
19807   if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
19808     S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t";
19809     return false;
19810   }
19811   Stack->setOMPEventHandleT(PT.get());
19812   return true;
19813 }
19814 
ActOnOpenMPDetachClause(Expr * Evt,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)19815 OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc,
19816                                          SourceLocation LParenLoc,
19817                                          SourceLocation EndLoc) {
19818   if (!Evt->isValueDependent() && !Evt->isTypeDependent() &&
19819       !Evt->isInstantiationDependent() &&
19820       !Evt->containsUnexpandedParameterPack()) {
19821     if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack))
19822       return nullptr;
19823     // OpenMP 5.0, 2.10.1 task Construct.
19824     // event-handle is a variable of the omp_event_handle_t type.
19825     auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts());
19826     if (!Ref) {
19827       Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
19828           << "omp_event_handle_t" << 0 << Evt->getSourceRange();
19829       return nullptr;
19830     }
19831     auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl());
19832     if (!VD) {
19833       Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
19834           << "omp_event_handle_t" << 0 << Evt->getSourceRange();
19835       return nullptr;
19836     }
19837     if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(),
19838                                         VD->getType()) ||
19839         VD->getType().isConstant(Context)) {
19840       Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
19841           << "omp_event_handle_t" << 1 << VD->getType()
19842           << Evt->getSourceRange();
19843       return nullptr;
19844     }
19845     // OpenMP 5.0, 2.10.1 task Construct
19846     // [detach clause]... The event-handle will be considered as if it was
19847     // specified on a firstprivate clause.
19848     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false);
19849     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
19850         DVar.RefExpr) {
19851       Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa)
19852           << getOpenMPClauseName(DVar.CKind)
19853           << getOpenMPClauseName(OMPC_firstprivate);
19854       reportOriginalDsa(*this, DSAStack, VD, DVar);
19855       return nullptr;
19856     }
19857   }
19858 
19859   return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc);
19860 }
19861 
ActOnOpenMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind,Expr * ChunkSize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation KindLoc,SourceLocation CommaLoc,SourceLocation EndLoc)19862 OMPClause *Sema::ActOnOpenMPDistScheduleClause(
19863     OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
19864     SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
19865     SourceLocation EndLoc) {
19866   if (Kind == OMPC_DIST_SCHEDULE_unknown) {
19867     std::string Values;
19868     Values += "'";
19869     Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
19870     Values += "'";
19871     Diag(KindLoc, diag::err_omp_unexpected_clause_value)
19872         << Values << getOpenMPClauseName(OMPC_dist_schedule);
19873     return nullptr;
19874   }
19875   Expr *ValExpr = ChunkSize;
19876   Stmt *HelperValStmt = nullptr;
19877   if (ChunkSize) {
19878     if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
19879         !ChunkSize->isInstantiationDependent() &&
19880         !ChunkSize->containsUnexpandedParameterPack()) {
19881       SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
19882       ExprResult Val =
19883           PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
19884       if (Val.isInvalid())
19885         return nullptr;
19886 
19887       ValExpr = Val.get();
19888 
19889       // OpenMP [2.7.1, Restrictions]
19890       //  chunk_size must be a loop invariant integer expression with a positive
19891       //  value.
19892       if (Optional<llvm::APSInt> Result =
19893               ValExpr->getIntegerConstantExpr(Context)) {
19894         if (Result->isSigned() && !Result->isStrictlyPositive()) {
19895           Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
19896               << "dist_schedule" << ChunkSize->getSourceRange();
19897           return nullptr;
19898         }
19899       } else if (getOpenMPCaptureRegionForClause(
19900                      DSAStack->getCurrentDirective(), OMPC_dist_schedule,
19901                      LangOpts.OpenMP) != OMPD_unknown &&
19902                  !CurContext->isDependentContext()) {
19903         ValExpr = MakeFullExpr(ValExpr).get();
19904         llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
19905         ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
19906         HelperValStmt = buildPreInits(Context, Captures);
19907       }
19908     }
19909   }
19910 
19911   return new (Context)
19912       OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
19913                             Kind, ValExpr, HelperValStmt);
19914 }
19915 
ActOnOpenMPDefaultmapClause(OpenMPDefaultmapClauseModifier M,OpenMPDefaultmapClauseKind Kind,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation MLoc,SourceLocation KindLoc,SourceLocation EndLoc)19916 OMPClause *Sema::ActOnOpenMPDefaultmapClause(
19917     OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
19918     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
19919     SourceLocation KindLoc, SourceLocation EndLoc) {
19920   if (getLangOpts().OpenMP < 50) {
19921     if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
19922         Kind != OMPC_DEFAULTMAP_scalar) {
19923       std::string Value;
19924       SourceLocation Loc;
19925       Value += "'";
19926       if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
19927         Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
19928                                                OMPC_DEFAULTMAP_MODIFIER_tofrom);
19929         Loc = MLoc;
19930       } else {
19931         Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
19932                                                OMPC_DEFAULTMAP_scalar);
19933         Loc = KindLoc;
19934       }
19935       Value += "'";
19936       Diag(Loc, diag::err_omp_unexpected_clause_value)
19937           << Value << getOpenMPClauseName(OMPC_defaultmap);
19938       return nullptr;
19939     }
19940   } else {
19941     bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown);
19942     bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) ||
19943                             (LangOpts.OpenMP >= 50 && KindLoc.isInvalid());
19944     if (!isDefaultmapKind || !isDefaultmapModifier) {
19945       StringRef KindValue = "'scalar', 'aggregate', 'pointer'";
19946       if (LangOpts.OpenMP == 50) {
19947         StringRef ModifierValue = "'alloc', 'from', 'to', 'tofrom', "
19948                                   "'firstprivate', 'none', 'default'";
19949         if (!isDefaultmapKind && isDefaultmapModifier) {
19950           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
19951               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
19952         } else if (isDefaultmapKind && !isDefaultmapModifier) {
19953           Diag(MLoc, diag::err_omp_unexpected_clause_value)
19954               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
19955         } else {
19956           Diag(MLoc, diag::err_omp_unexpected_clause_value)
19957               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
19958           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
19959               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
19960         }
19961       } else {
19962         StringRef ModifierValue =
19963             "'alloc', 'from', 'to', 'tofrom', "
19964             "'firstprivate', 'none', 'default', 'present'";
19965         if (!isDefaultmapKind && isDefaultmapModifier) {
19966           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
19967               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
19968         } else if (isDefaultmapKind && !isDefaultmapModifier) {
19969           Diag(MLoc, diag::err_omp_unexpected_clause_value)
19970               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
19971         } else {
19972           Diag(MLoc, diag::err_omp_unexpected_clause_value)
19973               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
19974           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
19975               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
19976         }
19977       }
19978       return nullptr;
19979     }
19980 
19981     // OpenMP [5.0, 2.12.5, Restrictions, p. 174]
19982     //  At most one defaultmap clause for each category can appear on the
19983     //  directive.
19984     if (DSAStack->checkDefaultmapCategory(Kind)) {
19985       Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
19986       return nullptr;
19987     }
19988   }
19989   if (Kind == OMPC_DEFAULTMAP_unknown) {
19990     // Variable category is not specified - mark all categories.
19991     DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc);
19992     DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc);
19993     DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc);
19994   } else {
19995     DSAStack->setDefaultDMAAttr(M, Kind, StartLoc);
19996   }
19997 
19998   return new (Context)
19999       OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
20000 }
20001 
ActOnStartOpenMPDeclareTargetContext(DeclareTargetContextInfo & DTCI)20002 bool Sema::ActOnStartOpenMPDeclareTargetContext(
20003     DeclareTargetContextInfo &DTCI) {
20004   DeclContext *CurLexicalContext = getCurLexicalContext();
20005   if (!CurLexicalContext->isFileContext() &&
20006       !CurLexicalContext->isExternCContext() &&
20007       !CurLexicalContext->isExternCXXContext() &&
20008       !isa<CXXRecordDecl>(CurLexicalContext) &&
20009       !isa<ClassTemplateDecl>(CurLexicalContext) &&
20010       !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
20011       !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
20012     Diag(DTCI.Loc, diag::err_omp_region_not_file_context);
20013     return false;
20014   }
20015   DeclareTargetNesting.push_back(DTCI);
20016   return true;
20017 }
20018 
20019 const Sema::DeclareTargetContextInfo
ActOnOpenMPEndDeclareTargetDirective()20020 Sema::ActOnOpenMPEndDeclareTargetDirective() {
20021   assert(!DeclareTargetNesting.empty() &&
20022          "check isInOpenMPDeclareTargetContext() first!");
20023   return DeclareTargetNesting.pop_back_val();
20024 }
20025 
ActOnFinishedOpenMPDeclareTargetContext(DeclareTargetContextInfo & DTCI)20026 void Sema::ActOnFinishedOpenMPDeclareTargetContext(
20027     DeclareTargetContextInfo &DTCI) {
20028   for (auto &It : DTCI.ExplicitlyMapped)
20029     ActOnOpenMPDeclareTargetName(It.first, It.second.Loc, It.second.MT,
20030                                  DTCI.DT);
20031 }
20032 
lookupOpenMPDeclareTargetName(Scope * CurScope,CXXScopeSpec & ScopeSpec,const DeclarationNameInfo & Id)20033 NamedDecl *Sema::lookupOpenMPDeclareTargetName(Scope *CurScope,
20034                                                CXXScopeSpec &ScopeSpec,
20035                                                const DeclarationNameInfo &Id) {
20036   LookupResult Lookup(*this, Id, LookupOrdinaryName);
20037   LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
20038 
20039   if (Lookup.isAmbiguous())
20040     return nullptr;
20041   Lookup.suppressDiagnostics();
20042 
20043   if (!Lookup.isSingleResult()) {
20044     VarOrFuncDeclFilterCCC CCC(*this);
20045     if (TypoCorrection Corrected =
20046             CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
20047                         CTK_ErrorRecovery)) {
20048       diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
20049                                   << Id.getName());
20050       checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
20051       return nullptr;
20052     }
20053 
20054     Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
20055     return nullptr;
20056   }
20057 
20058   NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
20059   if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
20060       !isa<FunctionTemplateDecl>(ND)) {
20061     Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
20062     return nullptr;
20063   }
20064   return ND;
20065 }
20066 
ActOnOpenMPDeclareTargetName(NamedDecl * ND,SourceLocation Loc,OMPDeclareTargetDeclAttr::MapTypeTy MT,OMPDeclareTargetDeclAttr::DevTypeTy DT)20067 void Sema::ActOnOpenMPDeclareTargetName(
20068     NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT,
20069     OMPDeclareTargetDeclAttr::DevTypeTy DT) {
20070   assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
20071           isa<FunctionTemplateDecl>(ND)) &&
20072          "Expected variable, function or function template.");
20073 
20074   // Diagnose marking after use as it may lead to incorrect diagnosis and
20075   // codegen.
20076   if (LangOpts.OpenMP >= 50 &&
20077       (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced()))
20078     Diag(Loc, diag::warn_omp_declare_target_after_first_use);
20079 
20080   // Explicit declare target lists have precedence.
20081   const unsigned Level = -1;
20082 
20083   auto *VD = cast<ValueDecl>(ND);
20084   llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
20085       OMPDeclareTargetDeclAttr::getActiveAttr(VD);
20086   if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getDevType() != DT &&
20087       ActiveAttr.getValue()->getLevel() == Level) {
20088     Diag(Loc, diag::err_omp_device_type_mismatch)
20089         << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT)
20090         << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(
20091                ActiveAttr.getValue()->getDevType());
20092     return;
20093   }
20094   if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getMapType() != MT &&
20095       ActiveAttr.getValue()->getLevel() == Level) {
20096     Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
20097     return;
20098   }
20099 
20100   if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getLevel() == Level)
20101     return;
20102 
20103   auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, Level,
20104                                                      SourceRange(Loc, Loc));
20105   ND->addAttr(A);
20106   if (ASTMutationListener *ML = Context.getASTMutationListener())
20107     ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
20108   checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc);
20109 }
20110 
checkDeclInTargetContext(SourceLocation SL,SourceRange SR,Sema & SemaRef,Decl * D)20111 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
20112                                      Sema &SemaRef, Decl *D) {
20113   if (!D || !isa<VarDecl>(D))
20114     return;
20115   auto *VD = cast<VarDecl>(D);
20116   Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
20117       OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
20118   if (SemaRef.LangOpts.OpenMP >= 50 &&
20119       (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) ||
20120        SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) &&
20121       VD->hasGlobalStorage()) {
20122     if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) {
20123       // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
20124       // If a lambda declaration and definition appears between a
20125       // declare target directive and the matching end declare target
20126       // directive, all variables that are captured by the lambda
20127       // expression must also appear in a to clause.
20128       SemaRef.Diag(VD->getLocation(),
20129                    diag::err_omp_lambda_capture_in_declare_target_not_to);
20130       SemaRef.Diag(SL, diag::note_var_explicitly_captured_here)
20131           << VD << 0 << SR;
20132       return;
20133     }
20134   }
20135   if (MapTy.hasValue())
20136     return;
20137   SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
20138   SemaRef.Diag(SL, diag::note_used_here) << SR;
20139 }
20140 
checkValueDeclInTarget(SourceLocation SL,SourceRange SR,Sema & SemaRef,DSAStackTy * Stack,ValueDecl * VD)20141 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
20142                                    Sema &SemaRef, DSAStackTy *Stack,
20143                                    ValueDecl *VD) {
20144   return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
20145          checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
20146                            /*FullCheck=*/false);
20147 }
20148 
checkDeclIsAllowedInOpenMPTarget(Expr * E,Decl * D,SourceLocation IdLoc)20149 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
20150                                             SourceLocation IdLoc) {
20151   if (!D || D->isInvalidDecl())
20152     return;
20153   SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
20154   SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
20155   if (auto *VD = dyn_cast<VarDecl>(D)) {
20156     // Only global variables can be marked as declare target.
20157     if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
20158         !VD->isStaticDataMember())
20159       return;
20160     // 2.10.6: threadprivate variable cannot appear in a declare target
20161     // directive.
20162     if (DSAStack->isThreadPrivate(VD)) {
20163       Diag(SL, diag::err_omp_threadprivate_in_target);
20164       reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false));
20165       return;
20166     }
20167   }
20168   if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
20169     D = FTD->getTemplatedDecl();
20170   if (auto *FD = dyn_cast<FunctionDecl>(D)) {
20171     llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
20172         OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
20173     if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
20174       Diag(IdLoc, diag::err_omp_function_in_link_clause);
20175       Diag(FD->getLocation(), diag::note_defined_here) << FD;
20176       return;
20177     }
20178   }
20179   if (auto *VD = dyn_cast<ValueDecl>(D)) {
20180     // Problem if any with var declared with incomplete type will be reported
20181     // as normal, so no need to check it here.
20182     if ((E || !VD->getType()->isIncompleteType()) &&
20183         !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD))
20184       return;
20185     if (!E && isInOpenMPDeclareTargetContext()) {
20186       // Checking declaration inside declare target region.
20187       if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
20188           isa<FunctionTemplateDecl>(D)) {
20189         llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
20190             OMPDeclareTargetDeclAttr::getActiveAttr(VD);
20191         unsigned Level = DeclareTargetNesting.size();
20192         if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getLevel() >= Level)
20193           return;
20194         DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back();
20195         auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
20196             Context, OMPDeclareTargetDeclAttr::MT_To, DTCI.DT, Level,
20197             SourceRange(DTCI.Loc, DTCI.Loc));
20198         D->addAttr(A);
20199         if (ASTMutationListener *ML = Context.getASTMutationListener())
20200           ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
20201       }
20202       return;
20203     }
20204   }
20205   if (!E)
20206     return;
20207   checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
20208 }
20209 
ActOnOpenMPToClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,ArrayRef<SourceLocation> MotionModifiersLoc,CXXScopeSpec & MapperIdScopeSpec,DeclarationNameInfo & MapperId,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs,ArrayRef<Expr * > UnresolvedMappers)20210 OMPClause *Sema::ActOnOpenMPToClause(
20211     ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
20212     ArrayRef<SourceLocation> MotionModifiersLoc,
20213     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
20214     SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
20215     const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
20216   OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
20217                                           OMPC_MOTION_MODIFIER_unknown};
20218   SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
20219 
20220   // Process motion-modifiers, flag errors for duplicate modifiers.
20221   unsigned Count = 0;
20222   for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
20223     if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
20224         llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) {
20225       Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
20226       continue;
20227     }
20228     assert(Count < NumberOfOMPMotionModifiers &&
20229            "Modifiers exceed the allowed number of motion modifiers");
20230     Modifiers[Count] = MotionModifiers[I];
20231     ModifiersLoc[Count] = MotionModifiersLoc[I];
20232     ++Count;
20233   }
20234 
20235   MappableVarListInfo MVLI(VarList);
20236   checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc,
20237                               MapperIdScopeSpec, MapperId, UnresolvedMappers);
20238   if (MVLI.ProcessedVarList.empty())
20239     return nullptr;
20240 
20241   return OMPToClause::Create(
20242       Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
20243       MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
20244       MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
20245 }
20246 
ActOnOpenMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,ArrayRef<SourceLocation> MotionModifiersLoc,CXXScopeSpec & MapperIdScopeSpec,DeclarationNameInfo & MapperId,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs,ArrayRef<Expr * > UnresolvedMappers)20247 OMPClause *Sema::ActOnOpenMPFromClause(
20248     ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
20249     ArrayRef<SourceLocation> MotionModifiersLoc,
20250     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
20251     SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
20252     const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
20253   OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
20254                                           OMPC_MOTION_MODIFIER_unknown};
20255   SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
20256 
20257   // Process motion-modifiers, flag errors for duplicate modifiers.
20258   unsigned Count = 0;
20259   for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
20260     if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
20261         llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) {
20262       Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
20263       continue;
20264     }
20265     assert(Count < NumberOfOMPMotionModifiers &&
20266            "Modifiers exceed the allowed number of motion modifiers");
20267     Modifiers[Count] = MotionModifiers[I];
20268     ModifiersLoc[Count] = MotionModifiersLoc[I];
20269     ++Count;
20270   }
20271 
20272   MappableVarListInfo MVLI(VarList);
20273   checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc,
20274                               MapperIdScopeSpec, MapperId, UnresolvedMappers);
20275   if (MVLI.ProcessedVarList.empty())
20276     return nullptr;
20277 
20278   return OMPFromClause::Create(
20279       Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
20280       MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
20281       MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
20282 }
20283 
ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs)20284 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
20285                                                const OMPVarListLocTy &Locs) {
20286   MappableVarListInfo MVLI(VarList);
20287   SmallVector<Expr *, 8> PrivateCopies;
20288   SmallVector<Expr *, 8> Inits;
20289 
20290   for (Expr *RefExpr : VarList) {
20291     assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
20292     SourceLocation ELoc;
20293     SourceRange ERange;
20294     Expr *SimpleRefExpr = RefExpr;
20295     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20296     if (Res.second) {
20297       // It will be analyzed later.
20298       MVLI.ProcessedVarList.push_back(RefExpr);
20299       PrivateCopies.push_back(nullptr);
20300       Inits.push_back(nullptr);
20301     }
20302     ValueDecl *D = Res.first;
20303     if (!D)
20304       continue;
20305 
20306     QualType Type = D->getType();
20307     Type = Type.getNonReferenceType().getUnqualifiedType();
20308 
20309     auto *VD = dyn_cast<VarDecl>(D);
20310 
20311     // Item should be a pointer or reference to pointer.
20312     if (!Type->isPointerType()) {
20313       Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
20314           << 0 << RefExpr->getSourceRange();
20315       continue;
20316     }
20317 
20318     // Build the private variable and the expression that refers to it.
20319     auto VDPrivate =
20320         buildVarDecl(*this, ELoc, Type, D->getName(),
20321                      D->hasAttrs() ? &D->getAttrs() : nullptr,
20322                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
20323     if (VDPrivate->isInvalidDecl())
20324       continue;
20325 
20326     CurContext->addDecl(VDPrivate);
20327     DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
20328         *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
20329 
20330     // Add temporary variable to initialize the private copy of the pointer.
20331     VarDecl *VDInit =
20332         buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
20333     DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
20334         *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
20335     AddInitializerToDecl(VDPrivate,
20336                          DefaultLvalueConversion(VDInitRefExpr).get(),
20337                          /*DirectInit=*/false);
20338 
20339     // If required, build a capture to implement the privatization initialized
20340     // with the current list item value.
20341     DeclRefExpr *Ref = nullptr;
20342     if (!VD)
20343       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
20344     MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
20345     PrivateCopies.push_back(VDPrivateRefExpr);
20346     Inits.push_back(VDInitRefExpr);
20347 
20348     // We need to add a data sharing attribute for this variable to make sure it
20349     // is correctly captured. A variable that shows up in a use_device_ptr has
20350     // similar properties of a first private variable.
20351     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
20352 
20353     // Create a mappable component for the list item. List items in this clause
20354     // only need a component.
20355     MVLI.VarBaseDeclarations.push_back(D);
20356     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
20357     MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D,
20358                                            /*IsNonContiguous=*/false);
20359   }
20360 
20361   if (MVLI.ProcessedVarList.empty())
20362     return nullptr;
20363 
20364   return OMPUseDevicePtrClause::Create(
20365       Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
20366       MVLI.VarBaseDeclarations, MVLI.VarComponents);
20367 }
20368 
ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs)20369 OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
20370                                                 const OMPVarListLocTy &Locs) {
20371   MappableVarListInfo MVLI(VarList);
20372 
20373   for (Expr *RefExpr : VarList) {
20374     assert(RefExpr && "NULL expr in OpenMP use_device_addr clause.");
20375     SourceLocation ELoc;
20376     SourceRange ERange;
20377     Expr *SimpleRefExpr = RefExpr;
20378     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
20379                               /*AllowArraySection=*/true);
20380     if (Res.second) {
20381       // It will be analyzed later.
20382       MVLI.ProcessedVarList.push_back(RefExpr);
20383     }
20384     ValueDecl *D = Res.first;
20385     if (!D)
20386       continue;
20387     auto *VD = dyn_cast<VarDecl>(D);
20388 
20389     // If required, build a capture to implement the privatization initialized
20390     // with the current list item value.
20391     DeclRefExpr *Ref = nullptr;
20392     if (!VD)
20393       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
20394     MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
20395 
20396     // We need to add a data sharing attribute for this variable to make sure it
20397     // is correctly captured. A variable that shows up in a use_device_addr has
20398     // similar properties of a first private variable.
20399     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
20400 
20401     // Create a mappable component for the list item. List items in this clause
20402     // only need a component.
20403     MVLI.VarBaseDeclarations.push_back(D);
20404     MVLI.VarComponents.emplace_back();
20405     Expr *Component = SimpleRefExpr;
20406     if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
20407                isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
20408       Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
20409     MVLI.VarComponents.back().emplace_back(Component, D,
20410                                            /*IsNonContiguous=*/false);
20411   }
20412 
20413   if (MVLI.ProcessedVarList.empty())
20414     return nullptr;
20415 
20416   return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
20417                                         MVLI.VarBaseDeclarations,
20418                                         MVLI.VarComponents);
20419 }
20420 
ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs)20421 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
20422                                               const OMPVarListLocTy &Locs) {
20423   MappableVarListInfo MVLI(VarList);
20424   for (Expr *RefExpr : VarList) {
20425     assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
20426     SourceLocation ELoc;
20427     SourceRange ERange;
20428     Expr *SimpleRefExpr = RefExpr;
20429     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20430     if (Res.second) {
20431       // It will be analyzed later.
20432       MVLI.ProcessedVarList.push_back(RefExpr);
20433     }
20434     ValueDecl *D = Res.first;
20435     if (!D)
20436       continue;
20437 
20438     QualType Type = D->getType();
20439     // item should be a pointer or array or reference to pointer or array
20440     if (!Type.getNonReferenceType()->isPointerType() &&
20441         !Type.getNonReferenceType()->isArrayType()) {
20442       Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
20443           << 0 << RefExpr->getSourceRange();
20444       continue;
20445     }
20446 
20447     // Check if the declaration in the clause does not show up in any data
20448     // sharing attribute.
20449     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
20450     if (isOpenMPPrivate(DVar.CKind)) {
20451       Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
20452           << getOpenMPClauseName(DVar.CKind)
20453           << getOpenMPClauseName(OMPC_is_device_ptr)
20454           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
20455       reportOriginalDsa(*this, DSAStack, D, DVar);
20456       continue;
20457     }
20458 
20459     const Expr *ConflictExpr;
20460     if (DSAStack->checkMappableExprComponentListsForDecl(
20461             D, /*CurrentRegionOnly=*/true,
20462             [&ConflictExpr](
20463                 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
20464                 OpenMPClauseKind) -> bool {
20465               ConflictExpr = R.front().getAssociatedExpression();
20466               return true;
20467             })) {
20468       Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
20469       Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
20470           << ConflictExpr->getSourceRange();
20471       continue;
20472     }
20473 
20474     // Store the components in the stack so that they can be used to check
20475     // against other clauses later on.
20476     OMPClauseMappableExprCommon::MappableComponent MC(
20477         SimpleRefExpr, D, /*IsNonContiguous=*/false);
20478     DSAStack->addMappableExpressionComponents(
20479         D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
20480 
20481     // Record the expression we've just processed.
20482     MVLI.ProcessedVarList.push_back(SimpleRefExpr);
20483 
20484     // Create a mappable component for the list item. List items in this clause
20485     // only need a component. We use a null declaration to signal fields in
20486     // 'this'.
20487     assert((isa<DeclRefExpr>(SimpleRefExpr) ||
20488             isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
20489            "Unexpected device pointer expression!");
20490     MVLI.VarBaseDeclarations.push_back(
20491         isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
20492     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
20493     MVLI.VarComponents.back().push_back(MC);
20494   }
20495 
20496   if (MVLI.ProcessedVarList.empty())
20497     return nullptr;
20498 
20499   return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
20500                                       MVLI.VarBaseDeclarations,
20501                                       MVLI.VarComponents);
20502 }
20503 
ActOnOpenMPAllocateClause(Expr * Allocator,ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation ColonLoc,SourceLocation LParenLoc,SourceLocation EndLoc)20504 OMPClause *Sema::ActOnOpenMPAllocateClause(
20505     Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
20506     SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
20507   if (Allocator) {
20508     // OpenMP [2.11.4 allocate Clause, Description]
20509     // allocator is an expression of omp_allocator_handle_t type.
20510     if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack))
20511       return nullptr;
20512 
20513     ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
20514     if (AllocatorRes.isInvalid())
20515       return nullptr;
20516     AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
20517                                              DSAStack->getOMPAllocatorHandleT(),
20518                                              Sema::AA_Initializing,
20519                                              /*AllowExplicit=*/true);
20520     if (AllocatorRes.isInvalid())
20521       return nullptr;
20522     Allocator = AllocatorRes.get();
20523   } else {
20524     // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
20525     // allocate clauses that appear on a target construct or on constructs in a
20526     // target region must specify an allocator expression unless a requires
20527     // directive with the dynamic_allocators clause is present in the same
20528     // compilation unit.
20529     if (LangOpts.OpenMPIsDevice &&
20530         !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
20531       targetDiag(StartLoc, diag::err_expected_allocator_expression);
20532   }
20533   // Analyze and build list of variables.
20534   SmallVector<Expr *, 8> Vars;
20535   for (Expr *RefExpr : VarList) {
20536     assert(RefExpr && "NULL expr in OpenMP private clause.");
20537     SourceLocation ELoc;
20538     SourceRange ERange;
20539     Expr *SimpleRefExpr = RefExpr;
20540     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20541     if (Res.second) {
20542       // It will be analyzed later.
20543       Vars.push_back(RefExpr);
20544     }
20545     ValueDecl *D = Res.first;
20546     if (!D)
20547       continue;
20548 
20549     auto *VD = dyn_cast<VarDecl>(D);
20550     DeclRefExpr *Ref = nullptr;
20551     if (!VD && !CurContext->isDependentContext())
20552       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
20553     Vars.push_back((VD || CurContext->isDependentContext())
20554                        ? RefExpr->IgnoreParens()
20555                        : Ref);
20556   }
20557 
20558   if (Vars.empty())
20559     return nullptr;
20560 
20561   if (Allocator)
20562     DSAStack->addInnerAllocatorExpr(Allocator);
20563   return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
20564                                    ColonLoc, EndLoc, Vars);
20565 }
20566 
ActOnOpenMPNontemporalClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)20567 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
20568                                               SourceLocation StartLoc,
20569                                               SourceLocation LParenLoc,
20570                                               SourceLocation EndLoc) {
20571   SmallVector<Expr *, 8> Vars;
20572   for (Expr *RefExpr : VarList) {
20573     assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
20574     SourceLocation ELoc;
20575     SourceRange ERange;
20576     Expr *SimpleRefExpr = RefExpr;
20577     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20578     if (Res.second)
20579       // It will be analyzed later.
20580       Vars.push_back(RefExpr);
20581     ValueDecl *D = Res.first;
20582     if (!D)
20583       continue;
20584 
20585     // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions.
20586     // A list-item cannot appear in more than one nontemporal clause.
20587     if (const Expr *PrevRef =
20588             DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) {
20589       Diag(ELoc, diag::err_omp_used_in_clause_twice)
20590           << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
20591       Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
20592           << getOpenMPClauseName(OMPC_nontemporal);
20593       continue;
20594     }
20595 
20596     Vars.push_back(RefExpr);
20597   }
20598 
20599   if (Vars.empty())
20600     return nullptr;
20601 
20602   return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc,
20603                                       Vars);
20604 }
20605 
ActOnOpenMPInclusiveClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)20606 OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList,
20607                                             SourceLocation StartLoc,
20608                                             SourceLocation LParenLoc,
20609                                             SourceLocation EndLoc) {
20610   SmallVector<Expr *, 8> Vars;
20611   for (Expr *RefExpr : VarList) {
20612     assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
20613     SourceLocation ELoc;
20614     SourceRange ERange;
20615     Expr *SimpleRefExpr = RefExpr;
20616     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
20617                               /*AllowArraySection=*/true);
20618     if (Res.second)
20619       // It will be analyzed later.
20620       Vars.push_back(RefExpr);
20621     ValueDecl *D = Res.first;
20622     if (!D)
20623       continue;
20624 
20625     const DSAStackTy::DSAVarData DVar =
20626         DSAStack->getTopDSA(D, /*FromParent=*/true);
20627     // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
20628     // A list item that appears in the inclusive or exclusive clause must appear
20629     // in a reduction clause with the inscan modifier on the enclosing
20630     // worksharing-loop, worksharing-loop SIMD, or simd construct.
20631     if (DVar.CKind != OMPC_reduction ||
20632         DVar.Modifier != OMPC_REDUCTION_inscan)
20633       Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
20634           << RefExpr->getSourceRange();
20635 
20636     if (DSAStack->getParentDirective() != OMPD_unknown)
20637       DSAStack->markDeclAsUsedInScanDirective(D);
20638     Vars.push_back(RefExpr);
20639   }
20640 
20641   if (Vars.empty())
20642     return nullptr;
20643 
20644   return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
20645 }
20646 
ActOnOpenMPExclusiveClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)20647 OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList,
20648                                             SourceLocation StartLoc,
20649                                             SourceLocation LParenLoc,
20650                                             SourceLocation EndLoc) {
20651   SmallVector<Expr *, 8> Vars;
20652   for (Expr *RefExpr : VarList) {
20653     assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
20654     SourceLocation ELoc;
20655     SourceRange ERange;
20656     Expr *SimpleRefExpr = RefExpr;
20657     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
20658                               /*AllowArraySection=*/true);
20659     if (Res.second)
20660       // It will be analyzed later.
20661       Vars.push_back(RefExpr);
20662     ValueDecl *D = Res.first;
20663     if (!D)
20664       continue;
20665 
20666     OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective();
20667     DSAStackTy::DSAVarData DVar;
20668     if (ParentDirective != OMPD_unknown)
20669       DVar = DSAStack->getTopDSA(D, /*FromParent=*/true);
20670     // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
20671     // A list item that appears in the inclusive or exclusive clause must appear
20672     // in a reduction clause with the inscan modifier on the enclosing
20673     // worksharing-loop, worksharing-loop SIMD, or simd construct.
20674     if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction ||
20675         DVar.Modifier != OMPC_REDUCTION_inscan) {
20676       Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
20677           << RefExpr->getSourceRange();
20678     } else {
20679       DSAStack->markDeclAsUsedInScanDirective(D);
20680     }
20681     Vars.push_back(RefExpr);
20682   }
20683 
20684   if (Vars.empty())
20685     return nullptr;
20686 
20687   return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
20688 }
20689 
20690 /// Tries to find omp_alloctrait_t type.
findOMPAlloctraitT(Sema & S,SourceLocation Loc,DSAStackTy * Stack)20691 static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) {
20692   QualType OMPAlloctraitT = Stack->getOMPAlloctraitT();
20693   if (!OMPAlloctraitT.isNull())
20694     return true;
20695   IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t");
20696   ParsedType PT = S.getTypeName(II, Loc, S.getCurScope());
20697   if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
20698     S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t";
20699     return false;
20700   }
20701   Stack->setOMPAlloctraitT(PT.get());
20702   return true;
20703 }
20704 
ActOnOpenMPUsesAllocatorClause(SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc,ArrayRef<UsesAllocatorsData> Data)20705 OMPClause *Sema::ActOnOpenMPUsesAllocatorClause(
20706     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
20707     ArrayRef<UsesAllocatorsData> Data) {
20708   // OpenMP [2.12.5, target Construct]
20709   // allocator is an identifier of omp_allocator_handle_t type.
20710   if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack))
20711     return nullptr;
20712   // OpenMP [2.12.5, target Construct]
20713   // allocator-traits-array is an identifier of const omp_alloctrait_t * type.
20714   if (llvm::any_of(
20715           Data,
20716           [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) &&
20717       !findOMPAlloctraitT(*this, StartLoc, DSAStack))
20718     return nullptr;
20719   llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators;
20720   for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
20721     auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
20722     StringRef Allocator =
20723         OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
20724     DeclarationName AllocatorName = &Context.Idents.get(Allocator);
20725     PredefinedAllocators.insert(LookupSingleName(
20726         TUScope, AllocatorName, StartLoc, Sema::LookupAnyName));
20727   }
20728 
20729   SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData;
20730   for (const UsesAllocatorsData &D : Data) {
20731     Expr *AllocatorExpr = nullptr;
20732     // Check allocator expression.
20733     if (D.Allocator->isTypeDependent()) {
20734       AllocatorExpr = D.Allocator;
20735     } else {
20736       // Traits were specified - need to assign new allocator to the specified
20737       // allocator, so it must be an lvalue.
20738       AllocatorExpr = D.Allocator->IgnoreParenImpCasts();
20739       auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr);
20740       bool IsPredefinedAllocator = false;
20741       if (DRE)
20742         IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl());
20743       if (!DRE ||
20744           !(Context.hasSameUnqualifiedType(
20745                 AllocatorExpr->getType(), DSAStack->getOMPAllocatorHandleT()) ||
20746             Context.typesAreCompatible(AllocatorExpr->getType(),
20747                                        DSAStack->getOMPAllocatorHandleT(),
20748                                        /*CompareUnqualified=*/true)) ||
20749           (!IsPredefinedAllocator &&
20750            (AllocatorExpr->getType().isConstant(Context) ||
20751             !AllocatorExpr->isLValue()))) {
20752         Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected)
20753             << "omp_allocator_handle_t" << (DRE ? 1 : 0)
20754             << AllocatorExpr->getType() << D.Allocator->getSourceRange();
20755         continue;
20756       }
20757       // OpenMP [2.12.5, target Construct]
20758       // Predefined allocators appearing in a uses_allocators clause cannot have
20759       // traits specified.
20760       if (IsPredefinedAllocator && D.AllocatorTraits) {
20761         Diag(D.AllocatorTraits->getExprLoc(),
20762              diag::err_omp_predefined_allocator_with_traits)
20763             << D.AllocatorTraits->getSourceRange();
20764         Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator)
20765             << cast<NamedDecl>(DRE->getDecl())->getName()
20766             << D.Allocator->getSourceRange();
20767         continue;
20768       }
20769       // OpenMP [2.12.5, target Construct]
20770       // Non-predefined allocators appearing in a uses_allocators clause must
20771       // have traits specified.
20772       if (!IsPredefinedAllocator && !D.AllocatorTraits) {
20773         Diag(D.Allocator->getExprLoc(),
20774              diag::err_omp_nonpredefined_allocator_without_traits);
20775         continue;
20776       }
20777       // No allocator traits - just convert it to rvalue.
20778       if (!D.AllocatorTraits)
20779         AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get();
20780       DSAStack->addUsesAllocatorsDecl(
20781           DRE->getDecl(),
20782           IsPredefinedAllocator
20783               ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator
20784               : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator);
20785     }
20786     Expr *AllocatorTraitsExpr = nullptr;
20787     if (D.AllocatorTraits) {
20788       if (D.AllocatorTraits->isTypeDependent()) {
20789         AllocatorTraitsExpr = D.AllocatorTraits;
20790       } else {
20791         // OpenMP [2.12.5, target Construct]
20792         // Arrays that contain allocator traits that appear in a uses_allocators
20793         // clause must be constant arrays, have constant values and be defined
20794         // in the same scope as the construct in which the clause appears.
20795         AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts();
20796         // Check that traits expr is a constant array.
20797         QualType TraitTy;
20798         if (const ArrayType *Ty =
20799                 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe())
20800           if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty))
20801             TraitTy = ConstArrayTy->getElementType();
20802         if (TraitTy.isNull() ||
20803             !(Context.hasSameUnqualifiedType(TraitTy,
20804                                              DSAStack->getOMPAlloctraitT()) ||
20805               Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(),
20806                                          /*CompareUnqualified=*/true))) {
20807           Diag(D.AllocatorTraits->getExprLoc(),
20808                diag::err_omp_expected_array_alloctraits)
20809               << AllocatorTraitsExpr->getType();
20810           continue;
20811         }
20812         // Do not map by default allocator traits if it is a standalone
20813         // variable.
20814         if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr))
20815           DSAStack->addUsesAllocatorsDecl(
20816               DRE->getDecl(),
20817               DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait);
20818       }
20819     }
20820     OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back();
20821     NewD.Allocator = AllocatorExpr;
20822     NewD.AllocatorTraits = AllocatorTraitsExpr;
20823     NewD.LParenLoc = D.LParenLoc;
20824     NewD.RParenLoc = D.RParenLoc;
20825   }
20826   return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc,
20827                                          NewData);
20828 }
20829 
ActOnOpenMPAffinityClause(SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,Expr * Modifier,ArrayRef<Expr * > Locators)20830 OMPClause *Sema::ActOnOpenMPAffinityClause(
20831     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
20832     SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) {
20833   SmallVector<Expr *, 8> Vars;
20834   for (Expr *RefExpr : Locators) {
20835     assert(RefExpr && "NULL expr in OpenMP shared clause.");
20836     if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) {
20837       // It will be analyzed later.
20838       Vars.push_back(RefExpr);
20839       continue;
20840     }
20841 
20842     SourceLocation ELoc = RefExpr->getExprLoc();
20843     Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts();
20844 
20845     if (!SimpleExpr->isLValue()) {
20846       Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
20847           << 1 << 0 << RefExpr->getSourceRange();
20848       continue;
20849     }
20850 
20851     ExprResult Res;
20852     {
20853       Sema::TentativeAnalysisScope Trap(*this);
20854       Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr);
20855     }
20856     if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
20857         !isa<OMPArrayShapingExpr>(SimpleExpr)) {
20858       Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
20859           << 1 << 0 << RefExpr->getSourceRange();
20860       continue;
20861     }
20862     Vars.push_back(SimpleExpr);
20863   }
20864 
20865   return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
20866                                    EndLoc, Modifier, Vars);
20867 }
20868