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__anondf8189520111::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__anondf8189520111::DSAStackTy::ReductionData130     void set(BinaryOperatorKind BO, SourceRange RR) {
131       ReductionRange = RR;
132       ReductionOp = BO;
133     }
set__anondf8189520111::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__anondf8189520111::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__anondf8189520111::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 
VisitOMPUnrollDirective(OMPUnrollDirective * S)3813   void VisitOMPUnrollDirective(OMPUnrollDirective *S) {
3814     // #pragma omp unroll does not introduce data sharing.
3815     VisitStmt(S);
3816   }
3817 
VisitStmt(Stmt * S)3818   void VisitStmt(Stmt *S) {
3819     for (Stmt *C : S->children()) {
3820       if (C) {
3821         // Check implicitly captured variables in the task-based directives to
3822         // check if they must be firstprivatized.
3823         Visit(C);
3824       }
3825     }
3826   }
3827 
visitSubCaptures(CapturedStmt * S)3828   void visitSubCaptures(CapturedStmt *S) {
3829     for (const CapturedStmt::Capture &Cap : S->captures()) {
3830       if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy())
3831         continue;
3832       VarDecl *VD = Cap.getCapturedVar();
3833       // Do not try to map the variable if it or its sub-component was mapped
3834       // already.
3835       if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
3836           Stack->checkMappableExprComponentListsForDecl(
3837               VD, /*CurrentRegionOnly=*/true,
3838               [](OMPClauseMappableExprCommon::MappableExprComponentListRef,
3839                  OpenMPClauseKind) { return true; }))
3840         continue;
3841       DeclRefExpr *DRE = buildDeclRefExpr(
3842           SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context),
3843           Cap.getLocation(), /*RefersToCapture=*/true);
3844       Visit(DRE);
3845     }
3846   }
isErrorFound() const3847   bool isErrorFound() const { return ErrorFound; }
getImplicitFirstprivate() const3848   ArrayRef<Expr *> getImplicitFirstprivate() const {
3849     return ImplicitFirstprivate;
3850   }
getImplicitMap(OpenMPDefaultmapClauseKind DK,OpenMPMapClauseKind MK) const3851   ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind DK,
3852                                   OpenMPMapClauseKind MK) const {
3853     return ImplicitMap[DK][MK];
3854   }
3855   ArrayRef<OpenMPMapModifierKind>
getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const3856   getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const {
3857     return ImplicitMapModifier[Kind];
3858   }
getVarsWithInheritedDSA() const3859   const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const {
3860     return VarsWithInheritedDSA;
3861   }
3862 
DSAAttrChecker(DSAStackTy * S,Sema & SemaRef,CapturedStmt * CS)3863   DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS)
3864       : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {
3865     // Process declare target link variables for the target directives.
3866     if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) {
3867       for (DeclRefExpr *E : Stack->getLinkGlobals())
3868         Visit(E);
3869     }
3870   }
3871 };
3872 } // namespace
3873 
ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind,Scope * CurScope)3874 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
3875   switch (DKind) {
3876   case OMPD_parallel:
3877   case OMPD_parallel_for:
3878   case OMPD_parallel_for_simd:
3879   case OMPD_parallel_sections:
3880   case OMPD_parallel_master:
3881   case OMPD_teams:
3882   case OMPD_teams_distribute:
3883   case OMPD_teams_distribute_simd: {
3884     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3885     QualType KmpInt32PtrTy =
3886         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3887     Sema::CapturedParamNameType Params[] = {
3888         std::make_pair(".global_tid.", KmpInt32PtrTy),
3889         std::make_pair(".bound_tid.", KmpInt32PtrTy),
3890         std::make_pair(StringRef(), QualType()) // __context with shared vars
3891     };
3892     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3893                              Params);
3894     break;
3895   }
3896   case OMPD_target_teams:
3897   case OMPD_target_parallel:
3898   case OMPD_target_parallel_for:
3899   case OMPD_target_parallel_for_simd:
3900   case OMPD_target_teams_distribute:
3901   case OMPD_target_teams_distribute_simd: {
3902     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3903     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3904     QualType KmpInt32PtrTy =
3905         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3906     QualType Args[] = {VoidPtrTy};
3907     FunctionProtoType::ExtProtoInfo EPI;
3908     EPI.Variadic = true;
3909     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3910     Sema::CapturedParamNameType Params[] = {
3911         std::make_pair(".global_tid.", KmpInt32Ty),
3912         std::make_pair(".part_id.", KmpInt32PtrTy),
3913         std::make_pair(".privates.", VoidPtrTy),
3914         std::make_pair(
3915             ".copy_fn.",
3916             Context.getPointerType(CopyFnType).withConst().withRestrict()),
3917         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3918         std::make_pair(StringRef(), QualType()) // __context with shared vars
3919     };
3920     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3921                              Params, /*OpenMPCaptureLevel=*/0);
3922     // Mark this captured region as inlined, because we don't use outlined
3923     // function directly.
3924     getCurCapturedRegion()->TheCapturedDecl->addAttr(
3925         AlwaysInlineAttr::CreateImplicit(
3926             Context, {}, AttributeCommonInfo::AS_Keyword,
3927             AlwaysInlineAttr::Keyword_forceinline));
3928     Sema::CapturedParamNameType ParamsTarget[] = {
3929         std::make_pair(StringRef(), QualType()) // __context with shared vars
3930     };
3931     // Start a captured region for 'target' with no implicit parameters.
3932     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3933                              ParamsTarget, /*OpenMPCaptureLevel=*/1);
3934     Sema::CapturedParamNameType ParamsTeamsOrParallel[] = {
3935         std::make_pair(".global_tid.", KmpInt32PtrTy),
3936         std::make_pair(".bound_tid.", KmpInt32PtrTy),
3937         std::make_pair(StringRef(), QualType()) // __context with shared vars
3938     };
3939     // Start a captured region for 'teams' or 'parallel'.  Both regions have
3940     // the same implicit parameters.
3941     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3942                              ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2);
3943     break;
3944   }
3945   case OMPD_target:
3946   case OMPD_target_simd: {
3947     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
3948     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
3949     QualType KmpInt32PtrTy =
3950         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
3951     QualType Args[] = {VoidPtrTy};
3952     FunctionProtoType::ExtProtoInfo EPI;
3953     EPI.Variadic = true;
3954     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
3955     Sema::CapturedParamNameType Params[] = {
3956         std::make_pair(".global_tid.", KmpInt32Ty),
3957         std::make_pair(".part_id.", KmpInt32PtrTy),
3958         std::make_pair(".privates.", VoidPtrTy),
3959         std::make_pair(
3960             ".copy_fn.",
3961             Context.getPointerType(CopyFnType).withConst().withRestrict()),
3962         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
3963         std::make_pair(StringRef(), QualType()) // __context with shared vars
3964     };
3965     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3966                              Params, /*OpenMPCaptureLevel=*/0);
3967     // Mark this captured region as inlined, because we don't use outlined
3968     // function directly.
3969     getCurCapturedRegion()->TheCapturedDecl->addAttr(
3970         AlwaysInlineAttr::CreateImplicit(
3971             Context, {}, AttributeCommonInfo::AS_Keyword,
3972             AlwaysInlineAttr::Keyword_forceinline));
3973     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
3974                              std::make_pair(StringRef(), QualType()),
3975                              /*OpenMPCaptureLevel=*/1);
3976     break;
3977   }
3978   case OMPD_atomic:
3979   case OMPD_critical:
3980   case OMPD_section:
3981   case OMPD_master:
3982   case OMPD_masked:
3983   case OMPD_tile:
3984   case OMPD_unroll:
3985     break;
3986   case OMPD_simd:
3987   case OMPD_for:
3988   case OMPD_for_simd:
3989   case OMPD_sections:
3990   case OMPD_single:
3991   case OMPD_taskgroup:
3992   case OMPD_distribute:
3993   case OMPD_distribute_simd:
3994   case OMPD_ordered:
3995   case OMPD_target_data:
3996   case OMPD_dispatch: {
3997     Sema::CapturedParamNameType Params[] = {
3998         std::make_pair(StringRef(), QualType()) // __context with shared vars
3999     };
4000     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4001                              Params);
4002     break;
4003   }
4004   case OMPD_task: {
4005     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4006     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4007     QualType KmpInt32PtrTy =
4008         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4009     QualType Args[] = {VoidPtrTy};
4010     FunctionProtoType::ExtProtoInfo EPI;
4011     EPI.Variadic = true;
4012     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4013     Sema::CapturedParamNameType Params[] = {
4014         std::make_pair(".global_tid.", KmpInt32Ty),
4015         std::make_pair(".part_id.", KmpInt32PtrTy),
4016         std::make_pair(".privates.", VoidPtrTy),
4017         std::make_pair(
4018             ".copy_fn.",
4019             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4020         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4021         std::make_pair(StringRef(), QualType()) // __context with shared vars
4022     };
4023     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4024                              Params);
4025     // Mark this captured region as inlined, because we don't use outlined
4026     // function directly.
4027     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4028         AlwaysInlineAttr::CreateImplicit(
4029             Context, {}, AttributeCommonInfo::AS_Keyword,
4030             AlwaysInlineAttr::Keyword_forceinline));
4031     break;
4032   }
4033   case OMPD_taskloop:
4034   case OMPD_taskloop_simd:
4035   case OMPD_master_taskloop:
4036   case OMPD_master_taskloop_simd: {
4037     QualType KmpInt32Ty =
4038         Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4039             .withConst();
4040     QualType KmpUInt64Ty =
4041         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4042             .withConst();
4043     QualType KmpInt64Ty =
4044         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4045             .withConst();
4046     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4047     QualType KmpInt32PtrTy =
4048         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4049     QualType Args[] = {VoidPtrTy};
4050     FunctionProtoType::ExtProtoInfo EPI;
4051     EPI.Variadic = true;
4052     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4053     Sema::CapturedParamNameType Params[] = {
4054         std::make_pair(".global_tid.", KmpInt32Ty),
4055         std::make_pair(".part_id.", KmpInt32PtrTy),
4056         std::make_pair(".privates.", VoidPtrTy),
4057         std::make_pair(
4058             ".copy_fn.",
4059             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4060         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4061         std::make_pair(".lb.", KmpUInt64Ty),
4062         std::make_pair(".ub.", KmpUInt64Ty),
4063         std::make_pair(".st.", KmpInt64Ty),
4064         std::make_pair(".liter.", KmpInt32Ty),
4065         std::make_pair(".reductions.", VoidPtrTy),
4066         std::make_pair(StringRef(), QualType()) // __context with shared vars
4067     };
4068     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4069                              Params);
4070     // Mark this captured region as inlined, because we don't use outlined
4071     // function directly.
4072     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4073         AlwaysInlineAttr::CreateImplicit(
4074             Context, {}, AttributeCommonInfo::AS_Keyword,
4075             AlwaysInlineAttr::Keyword_forceinline));
4076     break;
4077   }
4078   case OMPD_parallel_master_taskloop:
4079   case OMPD_parallel_master_taskloop_simd: {
4080     QualType KmpInt32Ty =
4081         Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1)
4082             .withConst();
4083     QualType KmpUInt64Ty =
4084         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0)
4085             .withConst();
4086     QualType KmpInt64Ty =
4087         Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1)
4088             .withConst();
4089     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4090     QualType KmpInt32PtrTy =
4091         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4092     Sema::CapturedParamNameType ParamsParallel[] = {
4093         std::make_pair(".global_tid.", KmpInt32PtrTy),
4094         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4095         std::make_pair(StringRef(), QualType()) // __context with shared vars
4096     };
4097     // Start a captured region for 'parallel'.
4098     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4099                              ParamsParallel, /*OpenMPCaptureLevel=*/0);
4100     QualType Args[] = {VoidPtrTy};
4101     FunctionProtoType::ExtProtoInfo EPI;
4102     EPI.Variadic = true;
4103     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4104     Sema::CapturedParamNameType Params[] = {
4105         std::make_pair(".global_tid.", KmpInt32Ty),
4106         std::make_pair(".part_id.", KmpInt32PtrTy),
4107         std::make_pair(".privates.", VoidPtrTy),
4108         std::make_pair(
4109             ".copy_fn.",
4110             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4111         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4112         std::make_pair(".lb.", KmpUInt64Ty),
4113         std::make_pair(".ub.", KmpUInt64Ty),
4114         std::make_pair(".st.", KmpInt64Ty),
4115         std::make_pair(".liter.", KmpInt32Ty),
4116         std::make_pair(".reductions.", VoidPtrTy),
4117         std::make_pair(StringRef(), QualType()) // __context with shared vars
4118     };
4119     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4120                              Params, /*OpenMPCaptureLevel=*/1);
4121     // Mark this captured region as inlined, because we don't use outlined
4122     // function directly.
4123     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4124         AlwaysInlineAttr::CreateImplicit(
4125             Context, {}, AttributeCommonInfo::AS_Keyword,
4126             AlwaysInlineAttr::Keyword_forceinline));
4127     break;
4128   }
4129   case OMPD_distribute_parallel_for_simd:
4130   case OMPD_distribute_parallel_for: {
4131     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4132     QualType KmpInt32PtrTy =
4133         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4134     Sema::CapturedParamNameType Params[] = {
4135         std::make_pair(".global_tid.", KmpInt32PtrTy),
4136         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4137         std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4138         std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4139         std::make_pair(StringRef(), QualType()) // __context with shared vars
4140     };
4141     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4142                              Params);
4143     break;
4144   }
4145   case OMPD_target_teams_distribute_parallel_for:
4146   case OMPD_target_teams_distribute_parallel_for_simd: {
4147     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4148     QualType KmpInt32PtrTy =
4149         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4150     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4151 
4152     QualType Args[] = {VoidPtrTy};
4153     FunctionProtoType::ExtProtoInfo EPI;
4154     EPI.Variadic = true;
4155     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4156     Sema::CapturedParamNameType Params[] = {
4157         std::make_pair(".global_tid.", KmpInt32Ty),
4158         std::make_pair(".part_id.", KmpInt32PtrTy),
4159         std::make_pair(".privates.", VoidPtrTy),
4160         std::make_pair(
4161             ".copy_fn.",
4162             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4163         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4164         std::make_pair(StringRef(), QualType()) // __context with shared vars
4165     };
4166     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4167                              Params, /*OpenMPCaptureLevel=*/0);
4168     // Mark this captured region as inlined, because we don't use outlined
4169     // function directly.
4170     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4171         AlwaysInlineAttr::CreateImplicit(
4172             Context, {}, AttributeCommonInfo::AS_Keyword,
4173             AlwaysInlineAttr::Keyword_forceinline));
4174     Sema::CapturedParamNameType ParamsTarget[] = {
4175         std::make_pair(StringRef(), QualType()) // __context with shared vars
4176     };
4177     // Start a captured region for 'target' with no implicit parameters.
4178     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4179                              ParamsTarget, /*OpenMPCaptureLevel=*/1);
4180 
4181     Sema::CapturedParamNameType ParamsTeams[] = {
4182         std::make_pair(".global_tid.", KmpInt32PtrTy),
4183         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4184         std::make_pair(StringRef(), QualType()) // __context with shared vars
4185     };
4186     // Start a captured region for 'target' with no implicit parameters.
4187     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4188                              ParamsTeams, /*OpenMPCaptureLevel=*/2);
4189 
4190     Sema::CapturedParamNameType ParamsParallel[] = {
4191         std::make_pair(".global_tid.", KmpInt32PtrTy),
4192         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4193         std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4194         std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4195         std::make_pair(StringRef(), QualType()) // __context with shared vars
4196     };
4197     // Start a captured region for 'teams' or 'parallel'.  Both regions have
4198     // the same implicit parameters.
4199     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4200                              ParamsParallel, /*OpenMPCaptureLevel=*/3);
4201     break;
4202   }
4203 
4204   case OMPD_teams_distribute_parallel_for:
4205   case OMPD_teams_distribute_parallel_for_simd: {
4206     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4207     QualType KmpInt32PtrTy =
4208         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4209 
4210     Sema::CapturedParamNameType ParamsTeams[] = {
4211         std::make_pair(".global_tid.", KmpInt32PtrTy),
4212         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4213         std::make_pair(StringRef(), QualType()) // __context with shared vars
4214     };
4215     // Start a captured region for 'target' with no implicit parameters.
4216     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4217                              ParamsTeams, /*OpenMPCaptureLevel=*/0);
4218 
4219     Sema::CapturedParamNameType ParamsParallel[] = {
4220         std::make_pair(".global_tid.", KmpInt32PtrTy),
4221         std::make_pair(".bound_tid.", KmpInt32PtrTy),
4222         std::make_pair(".previous.lb.", Context.getSizeType().withConst()),
4223         std::make_pair(".previous.ub.", Context.getSizeType().withConst()),
4224         std::make_pair(StringRef(), QualType()) // __context with shared vars
4225     };
4226     // Start a captured region for 'teams' or 'parallel'.  Both regions have
4227     // the same implicit parameters.
4228     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4229                              ParamsParallel, /*OpenMPCaptureLevel=*/1);
4230     break;
4231   }
4232   case OMPD_target_update:
4233   case OMPD_target_enter_data:
4234   case OMPD_target_exit_data: {
4235     QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst();
4236     QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict();
4237     QualType KmpInt32PtrTy =
4238         Context.getPointerType(KmpInt32Ty).withConst().withRestrict();
4239     QualType Args[] = {VoidPtrTy};
4240     FunctionProtoType::ExtProtoInfo EPI;
4241     EPI.Variadic = true;
4242     QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI);
4243     Sema::CapturedParamNameType Params[] = {
4244         std::make_pair(".global_tid.", KmpInt32Ty),
4245         std::make_pair(".part_id.", KmpInt32PtrTy),
4246         std::make_pair(".privates.", VoidPtrTy),
4247         std::make_pair(
4248             ".copy_fn.",
4249             Context.getPointerType(CopyFnType).withConst().withRestrict()),
4250         std::make_pair(".task_t.", Context.VoidPtrTy.withConst()),
4251         std::make_pair(StringRef(), QualType()) // __context with shared vars
4252     };
4253     ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
4254                              Params);
4255     // Mark this captured region as inlined, because we don't use outlined
4256     // function directly.
4257     getCurCapturedRegion()->TheCapturedDecl->addAttr(
4258         AlwaysInlineAttr::CreateImplicit(
4259             Context, {}, AttributeCommonInfo::AS_Keyword,
4260             AlwaysInlineAttr::Keyword_forceinline));
4261     break;
4262   }
4263   case OMPD_threadprivate:
4264   case OMPD_allocate:
4265   case OMPD_taskyield:
4266   case OMPD_barrier:
4267   case OMPD_taskwait:
4268   case OMPD_cancellation_point:
4269   case OMPD_cancel:
4270   case OMPD_flush:
4271   case OMPD_depobj:
4272   case OMPD_scan:
4273   case OMPD_declare_reduction:
4274   case OMPD_declare_mapper:
4275   case OMPD_declare_simd:
4276   case OMPD_declare_target:
4277   case OMPD_end_declare_target:
4278   case OMPD_requires:
4279   case OMPD_declare_variant:
4280   case OMPD_begin_declare_variant:
4281   case OMPD_end_declare_variant:
4282     llvm_unreachable("OpenMP Directive is not allowed");
4283   case OMPD_unknown:
4284   default:
4285     llvm_unreachable("Unknown OpenMP directive");
4286   }
4287   DSAStack->setContext(CurContext);
4288 }
4289 
getNumberOfConstructScopes(unsigned Level) const4290 int Sema::getNumberOfConstructScopes(unsigned Level) const {
4291   return getOpenMPCaptureLevels(DSAStack->getDirective(Level));
4292 }
4293 
getOpenMPCaptureLevels(OpenMPDirectiveKind DKind)4294 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) {
4295   SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4296   getOpenMPCaptureRegions(CaptureRegions, DKind);
4297   return CaptureRegions.size();
4298 }
4299 
buildCaptureDecl(Sema & S,IdentifierInfo * Id,Expr * CaptureExpr,bool WithInit,bool AsExpression)4300 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id,
4301                                              Expr *CaptureExpr, bool WithInit,
4302                                              bool AsExpression) {
4303   assert(CaptureExpr);
4304   ASTContext &C = S.getASTContext();
4305   Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts();
4306   QualType Ty = Init->getType();
4307   if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) {
4308     if (S.getLangOpts().CPlusPlus) {
4309       Ty = C.getLValueReferenceType(Ty);
4310     } else {
4311       Ty = C.getPointerType(Ty);
4312       ExprResult Res =
4313           S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init);
4314       if (!Res.isUsable())
4315         return nullptr;
4316       Init = Res.get();
4317     }
4318     WithInit = true;
4319   }
4320   auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty,
4321                                           CaptureExpr->getBeginLoc());
4322   if (!WithInit)
4323     CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C));
4324   S.CurContext->addHiddenDecl(CED);
4325   Sema::TentativeAnalysisScope Trap(S);
4326   S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false);
4327   return CED;
4328 }
4329 
buildCapture(Sema & S,ValueDecl * D,Expr * CaptureExpr,bool WithInit)4330 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr,
4331                                  bool WithInit) {
4332   OMPCapturedExprDecl *CD;
4333   if (VarDecl *VD = S.isOpenMPCapturedDecl(D))
4334     CD = cast<OMPCapturedExprDecl>(VD);
4335   else
4336     CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit,
4337                           /*AsExpression=*/false);
4338   return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4339                           CaptureExpr->getExprLoc());
4340 }
4341 
buildCapture(Sema & S,Expr * CaptureExpr,DeclRefExpr * & Ref)4342 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) {
4343   CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get();
4344   if (!Ref) {
4345     OMPCapturedExprDecl *CD = buildCaptureDecl(
4346         S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr,
4347         /*WithInit=*/true, /*AsExpression=*/true);
4348     Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(),
4349                            CaptureExpr->getExprLoc());
4350   }
4351   ExprResult Res = Ref;
4352   if (!S.getLangOpts().CPlusPlus &&
4353       CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() &&
4354       Ref->getType()->isPointerType()) {
4355     Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref);
4356     if (!Res.isUsable())
4357       return ExprError();
4358   }
4359   return S.DefaultLvalueConversion(Res.get());
4360 }
4361 
4362 namespace {
4363 // OpenMP directives parsed in this section are represented as a
4364 // CapturedStatement with an associated statement.  If a syntax error
4365 // is detected during the parsing of the associated statement, the
4366 // compiler must abort processing and close the CapturedStatement.
4367 //
4368 // Combined directives such as 'target parallel' have more than one
4369 // nested CapturedStatements.  This RAII ensures that we unwind out
4370 // of all the nested CapturedStatements when an error is found.
4371 class CaptureRegionUnwinderRAII {
4372 private:
4373   Sema &S;
4374   bool &ErrorFound;
4375   OpenMPDirectiveKind DKind = OMPD_unknown;
4376 
4377 public:
CaptureRegionUnwinderRAII(Sema & S,bool & ErrorFound,OpenMPDirectiveKind DKind)4378   CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound,
4379                             OpenMPDirectiveKind DKind)
4380       : S(S), ErrorFound(ErrorFound), DKind(DKind) {}
~CaptureRegionUnwinderRAII()4381   ~CaptureRegionUnwinderRAII() {
4382     if (ErrorFound) {
4383       int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind);
4384       while (--ThisCaptureLevel >= 0)
4385         S.ActOnCapturedRegionError();
4386     }
4387   }
4388 };
4389 } // namespace
4390 
tryCaptureOpenMPLambdas(ValueDecl * V)4391 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) {
4392   // Capture variables captured by reference in lambdas for target-based
4393   // directives.
4394   if (!CurContext->isDependentContext() &&
4395       (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) ||
4396        isOpenMPTargetDataManagementDirective(
4397            DSAStack->getCurrentDirective()))) {
4398     QualType Type = V->getType();
4399     if (const auto *RD = Type.getCanonicalType()
4400                              .getNonReferenceType()
4401                              ->getAsCXXRecordDecl()) {
4402       bool SavedForceCaptureByReferenceInTargetExecutable =
4403           DSAStack->isForceCaptureByReferenceInTargetExecutable();
4404       DSAStack->setForceCaptureByReferenceInTargetExecutable(
4405           /*V=*/true);
4406       if (RD->isLambda()) {
4407         llvm::DenseMap<const VarDecl *, FieldDecl *> Captures;
4408         FieldDecl *ThisCapture;
4409         RD->getCaptureFields(Captures, ThisCapture);
4410         for (const LambdaCapture &LC : RD->captures()) {
4411           if (LC.getCaptureKind() == LCK_ByRef) {
4412             VarDecl *VD = LC.getCapturedVar();
4413             DeclContext *VDC = VD->getDeclContext();
4414             if (!VDC->Encloses(CurContext))
4415               continue;
4416             MarkVariableReferenced(LC.getLocation(), VD);
4417           } else if (LC.getCaptureKind() == LCK_This) {
4418             QualType ThisTy = getCurrentThisType();
4419             if (!ThisTy.isNull() &&
4420                 Context.typesAreCompatible(ThisTy, ThisCapture->getType()))
4421               CheckCXXThisCapture(LC.getLocation());
4422           }
4423         }
4424       }
4425       DSAStack->setForceCaptureByReferenceInTargetExecutable(
4426           SavedForceCaptureByReferenceInTargetExecutable);
4427     }
4428   }
4429 }
4430 
checkOrderedOrderSpecified(Sema & S,const ArrayRef<OMPClause * > Clauses)4431 static bool checkOrderedOrderSpecified(Sema &S,
4432                                        const ArrayRef<OMPClause *> Clauses) {
4433   const OMPOrderedClause *Ordered = nullptr;
4434   const OMPOrderClause *Order = nullptr;
4435 
4436   for (const OMPClause *Clause : Clauses) {
4437     if (Clause->getClauseKind() == OMPC_ordered)
4438       Ordered = cast<OMPOrderedClause>(Clause);
4439     else if (Clause->getClauseKind() == OMPC_order) {
4440       Order = cast<OMPOrderClause>(Clause);
4441       if (Order->getKind() != OMPC_ORDER_concurrent)
4442         Order = nullptr;
4443     }
4444     if (Ordered && Order)
4445       break;
4446   }
4447 
4448   if (Ordered && Order) {
4449     S.Diag(Order->getKindKwLoc(),
4450            diag::err_omp_simple_clause_incompatible_with_ordered)
4451         << getOpenMPClauseName(OMPC_order)
4452         << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent)
4453         << SourceRange(Order->getBeginLoc(), Order->getEndLoc());
4454     S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param)
4455         << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc());
4456     return true;
4457   }
4458   return false;
4459 }
4460 
ActOnOpenMPRegionEnd(StmtResult S,ArrayRef<OMPClause * > Clauses)4461 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S,
4462                                       ArrayRef<OMPClause *> Clauses) {
4463   if (DSAStack->getCurrentDirective() == OMPD_atomic ||
4464       DSAStack->getCurrentDirective() == OMPD_critical ||
4465       DSAStack->getCurrentDirective() == OMPD_section ||
4466       DSAStack->getCurrentDirective() == OMPD_master ||
4467       DSAStack->getCurrentDirective() == OMPD_masked)
4468     return S;
4469 
4470   bool ErrorFound = false;
4471   CaptureRegionUnwinderRAII CaptureRegionUnwinder(
4472       *this, ErrorFound, DSAStack->getCurrentDirective());
4473   if (!S.isUsable()) {
4474     ErrorFound = true;
4475     return StmtError();
4476   }
4477 
4478   SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
4479   getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective());
4480   OMPOrderedClause *OC = nullptr;
4481   OMPScheduleClause *SC = nullptr;
4482   SmallVector<const OMPLinearClause *, 4> LCs;
4483   SmallVector<const OMPClauseWithPreInit *, 4> PICs;
4484   // This is required for proper codegen.
4485   for (OMPClause *Clause : Clauses) {
4486     if (!LangOpts.OpenMPSimd &&
4487         isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) &&
4488         Clause->getClauseKind() == OMPC_in_reduction) {
4489       // Capture taskgroup task_reduction descriptors inside the tasking regions
4490       // with the corresponding in_reduction items.
4491       auto *IRC = cast<OMPInReductionClause>(Clause);
4492       for (Expr *E : IRC->taskgroup_descriptors())
4493         if (E)
4494           MarkDeclarationsReferencedInExpr(E);
4495     }
4496     if (isOpenMPPrivate(Clause->getClauseKind()) ||
4497         Clause->getClauseKind() == OMPC_copyprivate ||
4498         (getLangOpts().OpenMPUseTLS &&
4499          getASTContext().getTargetInfo().isTLSSupported() &&
4500          Clause->getClauseKind() == OMPC_copyin)) {
4501       DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin);
4502       // Mark all variables in private list clauses as used in inner region.
4503       for (Stmt *VarRef : Clause->children()) {
4504         if (auto *E = cast_or_null<Expr>(VarRef)) {
4505           MarkDeclarationsReferencedInExpr(E);
4506         }
4507       }
4508       DSAStack->setForceVarCapturing(/*V=*/false);
4509     } else if (isOpenMPLoopTransformationDirective(
4510                    DSAStack->getCurrentDirective())) {
4511       assert(CaptureRegions.empty() &&
4512              "No captured regions in loop transformation directives.");
4513     } else if (CaptureRegions.size() > 1 ||
4514                CaptureRegions.back() != OMPD_unknown) {
4515       if (auto *C = OMPClauseWithPreInit::get(Clause))
4516         PICs.push_back(C);
4517       if (auto *C = OMPClauseWithPostUpdate::get(Clause)) {
4518         if (Expr *E = C->getPostUpdateExpr())
4519           MarkDeclarationsReferencedInExpr(E);
4520       }
4521     }
4522     if (Clause->getClauseKind() == OMPC_schedule)
4523       SC = cast<OMPScheduleClause>(Clause);
4524     else if (Clause->getClauseKind() == OMPC_ordered)
4525       OC = cast<OMPOrderedClause>(Clause);
4526     else if (Clause->getClauseKind() == OMPC_linear)
4527       LCs.push_back(cast<OMPLinearClause>(Clause));
4528   }
4529   // Capture allocator expressions if used.
4530   for (Expr *E : DSAStack->getInnerAllocators())
4531     MarkDeclarationsReferencedInExpr(E);
4532   // OpenMP, 2.7.1 Loop Construct, Restrictions
4533   // The nonmonotonic modifier cannot be specified if an ordered clause is
4534   // specified.
4535   if (SC &&
4536       (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
4537        SC->getSecondScheduleModifier() ==
4538            OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
4539       OC) {
4540     Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic
4541              ? SC->getFirstScheduleModifierLoc()
4542              : SC->getSecondScheduleModifierLoc(),
4543          diag::err_omp_simple_clause_incompatible_with_ordered)
4544         << getOpenMPClauseName(OMPC_schedule)
4545         << getOpenMPSimpleClauseTypeName(OMPC_schedule,
4546                                          OMPC_SCHEDULE_MODIFIER_nonmonotonic)
4547         << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4548     ErrorFound = true;
4549   }
4550   // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions.
4551   // If an order(concurrent) clause is present, an ordered clause may not appear
4552   // on the same directive.
4553   if (checkOrderedOrderSpecified(*this, Clauses))
4554     ErrorFound = true;
4555   if (!LCs.empty() && OC && OC->getNumForLoops()) {
4556     for (const OMPLinearClause *C : LCs) {
4557       Diag(C->getBeginLoc(), diag::err_omp_linear_ordered)
4558           << SourceRange(OC->getBeginLoc(), OC->getEndLoc());
4559     }
4560     ErrorFound = true;
4561   }
4562   if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) &&
4563       isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC &&
4564       OC->getNumForLoops()) {
4565     Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd)
4566         << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
4567     ErrorFound = true;
4568   }
4569   if (ErrorFound) {
4570     return StmtError();
4571   }
4572   StmtResult SR = S;
4573   unsigned CompletedRegions = 0;
4574   for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) {
4575     // Mark all variables in private list clauses as used in inner region.
4576     // Required for proper codegen of combined directives.
4577     // TODO: add processing for other clauses.
4578     if (ThisCaptureRegion != OMPD_unknown) {
4579       for (const clang::OMPClauseWithPreInit *C : PICs) {
4580         OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion();
4581         // Find the particular capture region for the clause if the
4582         // directive is a combined one with multiple capture regions.
4583         // If the directive is not a combined one, the capture region
4584         // associated with the clause is OMPD_unknown and is generated
4585         // only once.
4586         if (CaptureRegion == ThisCaptureRegion ||
4587             CaptureRegion == OMPD_unknown) {
4588           if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) {
4589             for (Decl *D : DS->decls())
4590               MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D));
4591           }
4592         }
4593       }
4594     }
4595     if (ThisCaptureRegion == OMPD_target) {
4596       // Capture allocator traits in the target region. They are used implicitly
4597       // and, thus, are not captured by default.
4598       for (OMPClause *C : Clauses) {
4599         if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) {
4600           for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End;
4601                ++I) {
4602             OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I);
4603             if (Expr *E = D.AllocatorTraits)
4604               MarkDeclarationsReferencedInExpr(E);
4605           }
4606           continue;
4607         }
4608       }
4609     }
4610     if (ThisCaptureRegion == OMPD_parallel) {
4611       // Capture temp arrays for inscan reductions and locals in aligned
4612       // clauses.
4613       for (OMPClause *C : Clauses) {
4614         if (auto *RC = dyn_cast<OMPReductionClause>(C)) {
4615           if (RC->getModifier() != OMPC_REDUCTION_inscan)
4616             continue;
4617           for (Expr *E : RC->copy_array_temps())
4618             MarkDeclarationsReferencedInExpr(E);
4619         }
4620         if (auto *AC = dyn_cast<OMPAlignedClause>(C)) {
4621           for (Expr *E : AC->varlists())
4622             MarkDeclarationsReferencedInExpr(E);
4623         }
4624       }
4625     }
4626     if (++CompletedRegions == CaptureRegions.size())
4627       DSAStack->setBodyComplete();
4628     SR = ActOnCapturedRegionEnd(SR.get());
4629   }
4630   return SR;
4631 }
4632 
checkCancelRegion(Sema & SemaRef,OpenMPDirectiveKind CurrentRegion,OpenMPDirectiveKind CancelRegion,SourceLocation StartLoc)4633 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion,
4634                               OpenMPDirectiveKind CancelRegion,
4635                               SourceLocation StartLoc) {
4636   // CancelRegion is only needed for cancel and cancellation_point.
4637   if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point)
4638     return false;
4639 
4640   if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for ||
4641       CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup)
4642     return false;
4643 
4644   SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region)
4645       << getOpenMPDirectiveName(CancelRegion);
4646   return true;
4647 }
4648 
checkNestingOfRegions(Sema & SemaRef,const DSAStackTy * Stack,OpenMPDirectiveKind CurrentRegion,const DeclarationNameInfo & CurrentName,OpenMPDirectiveKind CancelRegion,SourceLocation StartLoc)4649 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack,
4650                                   OpenMPDirectiveKind CurrentRegion,
4651                                   const DeclarationNameInfo &CurrentName,
4652                                   OpenMPDirectiveKind CancelRegion,
4653                                   SourceLocation StartLoc) {
4654   if (Stack->getCurScope()) {
4655     OpenMPDirectiveKind ParentRegion = Stack->getParentDirective();
4656     OpenMPDirectiveKind OffendingRegion = ParentRegion;
4657     bool NestingProhibited = false;
4658     bool CloseNesting = true;
4659     bool OrphanSeen = false;
4660     enum {
4661       NoRecommend,
4662       ShouldBeInParallelRegion,
4663       ShouldBeInOrderedRegion,
4664       ShouldBeInTargetRegion,
4665       ShouldBeInTeamsRegion,
4666       ShouldBeInLoopSimdRegion,
4667     } Recommend = NoRecommend;
4668     if (isOpenMPSimdDirective(ParentRegion) &&
4669         ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) ||
4670          (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered &&
4671           CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic &&
4672           CurrentRegion != OMPD_scan))) {
4673       // OpenMP [2.16, Nesting of Regions]
4674       // OpenMP constructs may not be nested inside a simd region.
4675       // OpenMP [2.8.1,simd Construct, Restrictions]
4676       // An ordered construct with the simd clause is the only OpenMP
4677       // construct that can appear in the simd region.
4678       // Allowing a SIMD construct nested in another SIMD construct is an
4679       // extension. The OpenMP 4.5 spec does not allow it. Issue a warning
4680       // message.
4681       // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions]
4682       // The only OpenMP constructs that can be encountered during execution of
4683       // a simd region are the atomic construct, the loop construct, the simd
4684       // construct and the ordered construct with the simd clause.
4685       SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd)
4686                                  ? diag::err_omp_prohibited_region_simd
4687                                  : diag::warn_omp_nesting_simd)
4688           << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0);
4689       return CurrentRegion != OMPD_simd;
4690     }
4691     if (ParentRegion == OMPD_atomic) {
4692       // OpenMP [2.16, Nesting of Regions]
4693       // OpenMP constructs may not be nested inside an atomic region.
4694       SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic);
4695       return true;
4696     }
4697     if (CurrentRegion == OMPD_section) {
4698       // OpenMP [2.7.2, sections Construct, Restrictions]
4699       // Orphaned section directives are prohibited. That is, the section
4700       // directives must appear within the sections construct and must not be
4701       // encountered elsewhere in the sections region.
4702       if (ParentRegion != OMPD_sections &&
4703           ParentRegion != OMPD_parallel_sections) {
4704         SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive)
4705             << (ParentRegion != OMPD_unknown)
4706             << getOpenMPDirectiveName(ParentRegion);
4707         return true;
4708       }
4709       return false;
4710     }
4711     // Allow some constructs (except teams and cancellation constructs) to be
4712     // orphaned (they could be used in functions, called from OpenMP regions
4713     // with the required preconditions).
4714     if (ParentRegion == OMPD_unknown &&
4715         !isOpenMPNestingTeamsDirective(CurrentRegion) &&
4716         CurrentRegion != OMPD_cancellation_point &&
4717         CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan)
4718       return false;
4719     if (CurrentRegion == OMPD_cancellation_point ||
4720         CurrentRegion == OMPD_cancel) {
4721       // OpenMP [2.16, Nesting of Regions]
4722       // A cancellation point construct for which construct-type-clause is
4723       // taskgroup must be nested inside a task construct. A cancellation
4724       // point construct for which construct-type-clause is not taskgroup must
4725       // be closely nested inside an OpenMP construct that matches the type
4726       // specified in construct-type-clause.
4727       // A cancel construct for which construct-type-clause is taskgroup must be
4728       // nested inside a task construct. A cancel construct for which
4729       // construct-type-clause is not taskgroup must be closely nested inside an
4730       // OpenMP construct that matches the type specified in
4731       // construct-type-clause.
4732       NestingProhibited =
4733           !((CancelRegion == OMPD_parallel &&
4734              (ParentRegion == OMPD_parallel ||
4735               ParentRegion == OMPD_target_parallel)) ||
4736             (CancelRegion == OMPD_for &&
4737              (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for ||
4738               ParentRegion == OMPD_target_parallel_for ||
4739               ParentRegion == OMPD_distribute_parallel_for ||
4740               ParentRegion == OMPD_teams_distribute_parallel_for ||
4741               ParentRegion == OMPD_target_teams_distribute_parallel_for)) ||
4742             (CancelRegion == OMPD_taskgroup &&
4743              (ParentRegion == OMPD_task ||
4744               (SemaRef.getLangOpts().OpenMP >= 50 &&
4745                (ParentRegion == OMPD_taskloop ||
4746                 ParentRegion == OMPD_master_taskloop ||
4747                 ParentRegion == OMPD_parallel_master_taskloop)))) ||
4748             (CancelRegion == OMPD_sections &&
4749              (ParentRegion == OMPD_section || ParentRegion == OMPD_sections ||
4750               ParentRegion == OMPD_parallel_sections)));
4751       OrphanSeen = ParentRegion == OMPD_unknown;
4752     } else if (CurrentRegion == OMPD_master || CurrentRegion == OMPD_masked) {
4753       // OpenMP 5.1 [2.22, Nesting of Regions]
4754       // A masked region may not be closely nested inside a worksharing, loop,
4755       // atomic, task, or taskloop region.
4756       NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) ||
4757                           isOpenMPTaskingDirective(ParentRegion);
4758     } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) {
4759       // OpenMP [2.16, Nesting of Regions]
4760       // A critical region may not be nested (closely or otherwise) inside a
4761       // critical region with the same name. Note that this restriction is not
4762       // sufficient to prevent deadlock.
4763       SourceLocation PreviousCriticalLoc;
4764       bool DeadLock = Stack->hasDirective(
4765           [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K,
4766                                               const DeclarationNameInfo &DNI,
4767                                               SourceLocation Loc) {
4768             if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) {
4769               PreviousCriticalLoc = Loc;
4770               return true;
4771             }
4772             return false;
4773           },
4774           false /* skip top directive */);
4775       if (DeadLock) {
4776         SemaRef.Diag(StartLoc,
4777                      diag::err_omp_prohibited_region_critical_same_name)
4778             << CurrentName.getName();
4779         if (PreviousCriticalLoc.isValid())
4780           SemaRef.Diag(PreviousCriticalLoc,
4781                        diag::note_omp_previous_critical_region);
4782         return true;
4783       }
4784     } else if (CurrentRegion == OMPD_barrier) {
4785       // OpenMP 5.1 [2.22, Nesting of Regions]
4786       // A barrier region may not be closely nested inside a worksharing, loop,
4787       // task, taskloop, critical, ordered, atomic, or masked region.
4788       NestingProhibited =
4789           isOpenMPWorksharingDirective(ParentRegion) ||
4790           isOpenMPTaskingDirective(ParentRegion) ||
4791           ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
4792           ParentRegion == OMPD_parallel_master ||
4793           ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
4794     } else if (isOpenMPWorksharingDirective(CurrentRegion) &&
4795                !isOpenMPParallelDirective(CurrentRegion) &&
4796                !isOpenMPTeamsDirective(CurrentRegion)) {
4797       // OpenMP 5.1 [2.22, Nesting of Regions]
4798       // A loop region that binds to a parallel region or a worksharing region
4799       // may not be closely nested inside a worksharing, loop, task, taskloop,
4800       // critical, ordered, atomic, or masked region.
4801       NestingProhibited =
4802           isOpenMPWorksharingDirective(ParentRegion) ||
4803           isOpenMPTaskingDirective(ParentRegion) ||
4804           ParentRegion == OMPD_master || ParentRegion == OMPD_masked ||
4805           ParentRegion == OMPD_parallel_master ||
4806           ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered;
4807       Recommend = ShouldBeInParallelRegion;
4808     } else if (CurrentRegion == OMPD_ordered) {
4809       // OpenMP [2.16, Nesting of Regions]
4810       // An ordered region may not be closely nested inside a critical,
4811       // atomic, or explicit task region.
4812       // An ordered region must be closely nested inside a loop region (or
4813       // parallel loop region) with an ordered clause.
4814       // OpenMP [2.8.1,simd Construct, Restrictions]
4815       // An ordered construct with the simd clause is the only OpenMP construct
4816       // that can appear in the simd region.
4817       NestingProhibited = ParentRegion == OMPD_critical ||
4818                           isOpenMPTaskingDirective(ParentRegion) ||
4819                           !(isOpenMPSimdDirective(ParentRegion) ||
4820                             Stack->isParentOrderedRegion());
4821       Recommend = ShouldBeInOrderedRegion;
4822     } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) {
4823       // OpenMP [2.16, Nesting of Regions]
4824       // If specified, a teams construct must be contained within a target
4825       // construct.
4826       NestingProhibited =
4827           (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) ||
4828           (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown &&
4829            ParentRegion != OMPD_target);
4830       OrphanSeen = ParentRegion == OMPD_unknown;
4831       Recommend = ShouldBeInTargetRegion;
4832     } else if (CurrentRegion == OMPD_scan) {
4833       // OpenMP [2.16, Nesting of Regions]
4834       // If specified, a teams construct must be contained within a target
4835       // construct.
4836       NestingProhibited =
4837           SemaRef.LangOpts.OpenMP < 50 ||
4838           (ParentRegion != OMPD_simd && ParentRegion != OMPD_for &&
4839            ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for &&
4840            ParentRegion != OMPD_parallel_for_simd);
4841       OrphanSeen = ParentRegion == OMPD_unknown;
4842       Recommend = ShouldBeInLoopSimdRegion;
4843     }
4844     if (!NestingProhibited &&
4845         !isOpenMPTargetExecutionDirective(CurrentRegion) &&
4846         !isOpenMPTargetDataManagementDirective(CurrentRegion) &&
4847         (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) {
4848       // OpenMP [2.16, Nesting of Regions]
4849       // distribute, parallel, parallel sections, parallel workshare, and the
4850       // parallel loop and parallel loop SIMD constructs are the only OpenMP
4851       // constructs that can be closely nested in the teams region.
4852       NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) &&
4853                           !isOpenMPDistributeDirective(CurrentRegion);
4854       Recommend = ShouldBeInParallelRegion;
4855     }
4856     if (!NestingProhibited &&
4857         isOpenMPNestingDistributeDirective(CurrentRegion)) {
4858       // OpenMP 4.5 [2.17 Nesting of Regions]
4859       // The region associated with the distribute construct must be strictly
4860       // nested inside a teams region
4861       NestingProhibited =
4862           (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams);
4863       Recommend = ShouldBeInTeamsRegion;
4864     }
4865     if (!NestingProhibited &&
4866         (isOpenMPTargetExecutionDirective(CurrentRegion) ||
4867          isOpenMPTargetDataManagementDirective(CurrentRegion))) {
4868       // OpenMP 4.5 [2.17 Nesting of Regions]
4869       // If a target, target update, target data, target enter data, or
4870       // target exit data construct is encountered during execution of a
4871       // target region, the behavior is unspecified.
4872       NestingProhibited = Stack->hasDirective(
4873           [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &,
4874                              SourceLocation) {
4875             if (isOpenMPTargetExecutionDirective(K)) {
4876               OffendingRegion = K;
4877               return true;
4878             }
4879             return false;
4880           },
4881           false /* don't skip top directive */);
4882       CloseNesting = false;
4883     }
4884     if (NestingProhibited) {
4885       if (OrphanSeen) {
4886         SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive)
4887             << getOpenMPDirectiveName(CurrentRegion) << Recommend;
4888       } else {
4889         SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region)
4890             << CloseNesting << getOpenMPDirectiveName(OffendingRegion)
4891             << Recommend << getOpenMPDirectiveName(CurrentRegion);
4892       }
4893       return true;
4894     }
4895   }
4896   return false;
4897 }
4898 
4899 struct Kind2Unsigned {
4900   using argument_type = OpenMPDirectiveKind;
operator ()Kind2Unsigned4901   unsigned operator()(argument_type DK) { return unsigned(DK); }
4902 };
checkIfClauses(Sema & S,OpenMPDirectiveKind Kind,ArrayRef<OMPClause * > Clauses,ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers)4903 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind,
4904                            ArrayRef<OMPClause *> Clauses,
4905                            ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) {
4906   bool ErrorFound = false;
4907   unsigned NamedModifiersNumber = 0;
4908   llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers;
4909   FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1);
4910   SmallVector<SourceLocation, 4> NameModifierLoc;
4911   for (const OMPClause *C : Clauses) {
4912     if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) {
4913       // At most one if clause without a directive-name-modifier can appear on
4914       // the directive.
4915       OpenMPDirectiveKind CurNM = IC->getNameModifier();
4916       if (FoundNameModifiers[CurNM]) {
4917         S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
4918             << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if)
4919             << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM);
4920         ErrorFound = true;
4921       } else if (CurNM != OMPD_unknown) {
4922         NameModifierLoc.push_back(IC->getNameModifierLoc());
4923         ++NamedModifiersNumber;
4924       }
4925       FoundNameModifiers[CurNM] = IC;
4926       if (CurNM == OMPD_unknown)
4927         continue;
4928       // Check if the specified name modifier is allowed for the current
4929       // directive.
4930       // At most one if clause with the particular directive-name-modifier can
4931       // appear on the directive.
4932       bool MatchFound = false;
4933       for (auto NM : AllowedNameModifiers) {
4934         if (CurNM == NM) {
4935           MatchFound = true;
4936           break;
4937         }
4938       }
4939       if (!MatchFound) {
4940         S.Diag(IC->getNameModifierLoc(),
4941                diag::err_omp_wrong_if_directive_name_modifier)
4942             << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind);
4943         ErrorFound = true;
4944       }
4945     }
4946   }
4947   // If any if clause on the directive includes a directive-name-modifier then
4948   // all if clauses on the directive must include a directive-name-modifier.
4949   if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) {
4950     if (NamedModifiersNumber == AllowedNameModifiers.size()) {
4951       S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(),
4952              diag::err_omp_no_more_if_clause);
4953     } else {
4954       std::string Values;
4955       std::string Sep(", ");
4956       unsigned AllowedCnt = 0;
4957       unsigned TotalAllowedNum =
4958           AllowedNameModifiers.size() - NamedModifiersNumber;
4959       for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End;
4960            ++Cnt) {
4961         OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt];
4962         if (!FoundNameModifiers[NM]) {
4963           Values += "'";
4964           Values += getOpenMPDirectiveName(NM);
4965           Values += "'";
4966           if (AllowedCnt + 2 == TotalAllowedNum)
4967             Values += " or ";
4968           else if (AllowedCnt + 1 != TotalAllowedNum)
4969             Values += Sep;
4970           ++AllowedCnt;
4971         }
4972       }
4973       S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(),
4974              diag::err_omp_unnamed_if_clause)
4975           << (TotalAllowedNum > 1) << Values;
4976     }
4977     for (SourceLocation Loc : NameModifierLoc) {
4978       S.Diag(Loc, diag::note_omp_previous_named_if_clause);
4979     }
4980     ErrorFound = true;
4981   }
4982   return ErrorFound;
4983 }
4984 
getPrivateItem(Sema & S,Expr * & RefExpr,SourceLocation & ELoc,SourceRange & ERange,bool AllowArraySection)4985 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr,
4986                                                    SourceLocation &ELoc,
4987                                                    SourceRange &ERange,
4988                                                    bool AllowArraySection) {
4989   if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() ||
4990       RefExpr->containsUnexpandedParameterPack())
4991     return std::make_pair(nullptr, true);
4992 
4993   // OpenMP [3.1, C/C++]
4994   //  A list item is a variable name.
4995   // OpenMP  [2.9.3.3, Restrictions, p.1]
4996   //  A variable that is part of another variable (as an array or
4997   //  structure element) cannot appear in a private clause.
4998   RefExpr = RefExpr->IgnoreParens();
4999   enum {
5000     NoArrayExpr = -1,
5001     ArraySubscript = 0,
5002     OMPArraySection = 1
5003   } IsArrayExpr = NoArrayExpr;
5004   if (AllowArraySection) {
5005     if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) {
5006       Expr *Base = ASE->getBase()->IgnoreParenImpCasts();
5007       while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
5008         Base = TempASE->getBase()->IgnoreParenImpCasts();
5009       RefExpr = Base;
5010       IsArrayExpr = ArraySubscript;
5011     } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) {
5012       Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
5013       while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
5014         Base = TempOASE->getBase()->IgnoreParenImpCasts();
5015       while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
5016         Base = TempASE->getBase()->IgnoreParenImpCasts();
5017       RefExpr = Base;
5018       IsArrayExpr = OMPArraySection;
5019     }
5020   }
5021   ELoc = RefExpr->getExprLoc();
5022   ERange = RefExpr->getSourceRange();
5023   RefExpr = RefExpr->IgnoreParenImpCasts();
5024   auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr);
5025   auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr);
5026   if ((!DE || !isa<VarDecl>(DE->getDecl())) &&
5027       (S.getCurrentThisType().isNull() || !ME ||
5028        !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) ||
5029        !isa<FieldDecl>(ME->getMemberDecl()))) {
5030     if (IsArrayExpr != NoArrayExpr) {
5031       S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr
5032                                                          << ERange;
5033     } else {
5034       S.Diag(ELoc,
5035              AllowArraySection
5036                  ? diag::err_omp_expected_var_name_member_expr_or_array_item
5037                  : diag::err_omp_expected_var_name_member_expr)
5038           << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange;
5039     }
5040     return std::make_pair(nullptr, false);
5041   }
5042   return std::make_pair(
5043       getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false);
5044 }
5045 
5046 namespace {
5047 /// Checks if the allocator is used in uses_allocators clause to be allowed in
5048 /// target regions.
5049 class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> {
5050   DSAStackTy *S = nullptr;
5051 
5052 public:
VisitDeclRefExpr(const DeclRefExpr * E)5053   bool VisitDeclRefExpr(const DeclRefExpr *E) {
5054     return S->isUsesAllocatorsDecl(E->getDecl())
5055                .getValueOr(
5056                    DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) ==
5057            DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait;
5058   }
VisitStmt(const Stmt * S)5059   bool VisitStmt(const Stmt *S) {
5060     for (const Stmt *Child : S->children()) {
5061       if (Child && Visit(Child))
5062         return true;
5063     }
5064     return false;
5065   }
AllocatorChecker(DSAStackTy * S)5066   explicit AllocatorChecker(DSAStackTy *S) : S(S) {}
5067 };
5068 } // namespace
5069 
checkAllocateClauses(Sema & S,DSAStackTy * Stack,ArrayRef<OMPClause * > Clauses)5070 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack,
5071                                  ArrayRef<OMPClause *> Clauses) {
5072   assert(!S.CurContext->isDependentContext() &&
5073          "Expected non-dependent context.");
5074   auto AllocateRange =
5075       llvm::make_filter_range(Clauses, OMPAllocateClause::classof);
5076   llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>>
5077       DeclToCopy;
5078   auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) {
5079     return isOpenMPPrivate(C->getClauseKind());
5080   });
5081   for (OMPClause *Cl : PrivateRange) {
5082     MutableArrayRef<Expr *>::iterator I, It, Et;
5083     if (Cl->getClauseKind() == OMPC_private) {
5084       auto *PC = cast<OMPPrivateClause>(Cl);
5085       I = PC->private_copies().begin();
5086       It = PC->varlist_begin();
5087       Et = PC->varlist_end();
5088     } else if (Cl->getClauseKind() == OMPC_firstprivate) {
5089       auto *PC = cast<OMPFirstprivateClause>(Cl);
5090       I = PC->private_copies().begin();
5091       It = PC->varlist_begin();
5092       Et = PC->varlist_end();
5093     } else if (Cl->getClauseKind() == OMPC_lastprivate) {
5094       auto *PC = cast<OMPLastprivateClause>(Cl);
5095       I = PC->private_copies().begin();
5096       It = PC->varlist_begin();
5097       Et = PC->varlist_end();
5098     } else if (Cl->getClauseKind() == OMPC_linear) {
5099       auto *PC = cast<OMPLinearClause>(Cl);
5100       I = PC->privates().begin();
5101       It = PC->varlist_begin();
5102       Et = PC->varlist_end();
5103     } else if (Cl->getClauseKind() == OMPC_reduction) {
5104       auto *PC = cast<OMPReductionClause>(Cl);
5105       I = PC->privates().begin();
5106       It = PC->varlist_begin();
5107       Et = PC->varlist_end();
5108     } else if (Cl->getClauseKind() == OMPC_task_reduction) {
5109       auto *PC = cast<OMPTaskReductionClause>(Cl);
5110       I = PC->privates().begin();
5111       It = PC->varlist_begin();
5112       Et = PC->varlist_end();
5113     } else if (Cl->getClauseKind() == OMPC_in_reduction) {
5114       auto *PC = cast<OMPInReductionClause>(Cl);
5115       I = PC->privates().begin();
5116       It = PC->varlist_begin();
5117       Et = PC->varlist_end();
5118     } else {
5119       llvm_unreachable("Expected private clause.");
5120     }
5121     for (Expr *E : llvm::make_range(It, Et)) {
5122       if (!*I) {
5123         ++I;
5124         continue;
5125       }
5126       SourceLocation ELoc;
5127       SourceRange ERange;
5128       Expr *SimpleRefExpr = E;
5129       auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
5130                                 /*AllowArraySection=*/true);
5131       DeclToCopy.try_emplace(Res.first,
5132                              cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl()));
5133       ++I;
5134     }
5135   }
5136   for (OMPClause *C : AllocateRange) {
5137     auto *AC = cast<OMPAllocateClause>(C);
5138     if (S.getLangOpts().OpenMP >= 50 &&
5139         !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() &&
5140         isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) &&
5141         AC->getAllocator()) {
5142       Expr *Allocator = AC->getAllocator();
5143       // OpenMP, 2.12.5 target Construct
5144       // Memory allocators that do not appear in a uses_allocators clause cannot
5145       // appear as an allocator in an allocate clause or be used in the target
5146       // region unless a requires directive with the dynamic_allocators clause
5147       // is present in the same compilation unit.
5148       AllocatorChecker Checker(Stack);
5149       if (Checker.Visit(Allocator))
5150         S.Diag(Allocator->getExprLoc(),
5151                diag::err_omp_allocator_not_in_uses_allocators)
5152             << Allocator->getSourceRange();
5153     }
5154     OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind =
5155         getAllocatorKind(S, Stack, AC->getAllocator());
5156     // OpenMP, 2.11.4 allocate Clause, Restrictions.
5157     // For task, taskloop or target directives, allocation requests to memory
5158     // allocators with the trait access set to thread result in unspecified
5159     // behavior.
5160     if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc &&
5161         (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
5162          isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) {
5163       S.Diag(AC->getAllocator()->getExprLoc(),
5164              diag::warn_omp_allocate_thread_on_task_target_directive)
5165           << getOpenMPDirectiveName(Stack->getCurrentDirective());
5166     }
5167     for (Expr *E : AC->varlists()) {
5168       SourceLocation ELoc;
5169       SourceRange ERange;
5170       Expr *SimpleRefExpr = E;
5171       auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange);
5172       ValueDecl *VD = Res.first;
5173       DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false);
5174       if (!isOpenMPPrivate(Data.CKind)) {
5175         S.Diag(E->getExprLoc(),
5176                diag::err_omp_expected_private_copy_for_allocate);
5177         continue;
5178       }
5179       VarDecl *PrivateVD = DeclToCopy[VD];
5180       if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD,
5181                                             AllocatorKind, AC->getAllocator()))
5182         continue;
5183       applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(),
5184                                 E->getSourceRange());
5185     }
5186   }
5187 }
5188 
5189 namespace {
5190 /// Rewrite statements and expressions for Sema \p Actions CurContext.
5191 ///
5192 /// Used to wrap already parsed statements/expressions into a new CapturedStmt
5193 /// context. DeclRefExpr used inside the new context are changed to refer to the
5194 /// captured variable instead.
5195 class CaptureVars : public TreeTransform<CaptureVars> {
5196   using BaseTransform = TreeTransform<CaptureVars>;
5197 
5198 public:
CaptureVars(Sema & Actions)5199   CaptureVars(Sema &Actions) : BaseTransform(Actions) {}
5200 
AlwaysRebuild()5201   bool AlwaysRebuild() { return true; }
5202 };
5203 } // namespace
5204 
precomputeExpr(Sema & Actions,SmallVectorImpl<Stmt * > & BodyStmts,Expr * E,StringRef Name)5205 static VarDecl *precomputeExpr(Sema &Actions,
5206                                SmallVectorImpl<Stmt *> &BodyStmts, Expr *E,
5207                                StringRef Name) {
5208   Expr *NewE = AssertSuccess(CaptureVars(Actions).TransformExpr(E));
5209   VarDecl *NewVar = buildVarDecl(Actions, {}, NewE->getType(), Name, nullptr,
5210                                  dyn_cast<DeclRefExpr>(E->IgnoreImplicit()));
5211   auto *NewDeclStmt = cast<DeclStmt>(AssertSuccess(
5212       Actions.ActOnDeclStmt(Actions.ConvertDeclToDeclGroup(NewVar), {}, {})));
5213   Actions.AddInitializerToDecl(NewDeclStmt->getSingleDecl(), NewE, false);
5214   BodyStmts.push_back(NewDeclStmt);
5215   return NewVar;
5216 }
5217 
5218 /// Create a closure that computes the number of iterations of a loop.
5219 ///
5220 /// \param Actions   The Sema object.
5221 /// \param LogicalTy Type for the logical iteration number.
5222 /// \param Rel       Comparison operator of the loop condition.
5223 /// \param StartExpr Value of the loop counter at the first iteration.
5224 /// \param StopExpr  Expression the loop counter is compared against in the loop
5225 /// condition. \param StepExpr      Amount of increment after each iteration.
5226 ///
5227 /// \return Closure (CapturedStmt) of the distance calculation.
buildDistanceFunc(Sema & Actions,QualType LogicalTy,BinaryOperator::Opcode Rel,Expr * StartExpr,Expr * StopExpr,Expr * StepExpr)5228 static CapturedStmt *buildDistanceFunc(Sema &Actions, QualType LogicalTy,
5229                                        BinaryOperator::Opcode Rel,
5230                                        Expr *StartExpr, Expr *StopExpr,
5231                                        Expr *StepExpr) {
5232   ASTContext &Ctx = Actions.getASTContext();
5233   TypeSourceInfo *LogicalTSI = Ctx.getTrivialTypeSourceInfo(LogicalTy);
5234 
5235   // Captured regions currently don't support return values, we use an
5236   // out-parameter instead. All inputs are implicit captures.
5237   // TODO: Instead of capturing each DeclRefExpr occurring in
5238   // StartExpr/StopExpr/Step, these could also be passed as a value capture.
5239   QualType ResultTy = Ctx.getLValueReferenceType(LogicalTy);
5240   Sema::CapturedParamNameType Params[] = {{"Distance", ResultTy},
5241                                           {StringRef(), QualType()}};
5242   Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5243 
5244   Stmt *Body;
5245   {
5246     Sema::CompoundScopeRAII CompoundScope(Actions);
5247     CapturedDecl *CS = cast<CapturedDecl>(Actions.CurContext);
5248 
5249     // Get the LValue expression for the result.
5250     ImplicitParamDecl *DistParam = CS->getParam(0);
5251     DeclRefExpr *DistRef = Actions.BuildDeclRefExpr(
5252         DistParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5253 
5254     SmallVector<Stmt *, 4> BodyStmts;
5255 
5256     // Capture all referenced variable references.
5257     // TODO: Instead of computing NewStart/NewStop/NewStep inside the
5258     // CapturedStmt, we could compute them before and capture the result, to be
5259     // used jointly with the LoopVar function.
5260     VarDecl *NewStart = precomputeExpr(Actions, BodyStmts, StartExpr, ".start");
5261     VarDecl *NewStop = precomputeExpr(Actions, BodyStmts, StopExpr, ".stop");
5262     VarDecl *NewStep = precomputeExpr(Actions, BodyStmts, StepExpr, ".step");
5263     auto BuildVarRef = [&](VarDecl *VD) {
5264       return buildDeclRefExpr(Actions, VD, VD->getType(), {});
5265     };
5266 
5267     IntegerLiteral *Zero = IntegerLiteral::Create(
5268         Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 0), LogicalTy, {});
5269     Expr *Dist;
5270     if (Rel == BO_NE) {
5271       // When using a != comparison, the increment can be +1 or -1. This can be
5272       // dynamic at runtime, so we need to check for the direction.
5273       Expr *IsNegStep = AssertSuccess(
5274           Actions.BuildBinOp(nullptr, {}, BO_LT, BuildVarRef(NewStep), Zero));
5275 
5276       // Positive increment.
5277       Expr *ForwardRange = AssertSuccess(Actions.BuildBinOp(
5278           nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5279       ForwardRange = AssertSuccess(
5280           Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, ForwardRange));
5281       Expr *ForwardDist = AssertSuccess(Actions.BuildBinOp(
5282           nullptr, {}, BO_Div, ForwardRange, BuildVarRef(NewStep)));
5283 
5284       // Negative increment.
5285       Expr *BackwardRange = AssertSuccess(Actions.BuildBinOp(
5286           nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5287       BackwardRange = AssertSuccess(
5288           Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, BackwardRange));
5289       Expr *NegIncAmount = AssertSuccess(
5290           Actions.BuildUnaryOp(nullptr, {}, UO_Minus, BuildVarRef(NewStep)));
5291       Expr *BackwardDist = AssertSuccess(
5292           Actions.BuildBinOp(nullptr, {}, BO_Div, BackwardRange, NegIncAmount));
5293 
5294       // Use the appropriate case.
5295       Dist = AssertSuccess(Actions.ActOnConditionalOp(
5296           {}, {}, IsNegStep, BackwardDist, ForwardDist));
5297     } else {
5298       assert((Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT) &&
5299              "Expected one of these relational operators");
5300 
5301       // We can derive the direction from any other comparison operator. It is
5302       // non well-formed OpenMP if Step increments/decrements in the other
5303       // directions. Whether at least the first iteration passes the loop
5304       // condition.
5305       Expr *HasAnyIteration = AssertSuccess(Actions.BuildBinOp(
5306           nullptr, {}, Rel, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5307 
5308       // Compute the range between first and last counter value.
5309       Expr *Range;
5310       if (Rel == BO_GE || Rel == BO_GT)
5311         Range = AssertSuccess(Actions.BuildBinOp(
5312             nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop)));
5313       else
5314         Range = AssertSuccess(Actions.BuildBinOp(
5315             nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart)));
5316 
5317       // Ensure unsigned range space.
5318       Range =
5319           AssertSuccess(Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, Range));
5320 
5321       if (Rel == BO_LE || Rel == BO_GE) {
5322         // Add one to the range if the relational operator is inclusive.
5323         Range =
5324             AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_PreInc, Range));
5325       }
5326 
5327       // Divide by the absolute step amount.
5328       Expr *Divisor = BuildVarRef(NewStep);
5329       if (Rel == BO_GE || Rel == BO_GT)
5330         Divisor =
5331             AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Minus, Divisor));
5332       Dist = AssertSuccess(
5333           Actions.BuildBinOp(nullptr, {}, BO_Div, Range, Divisor));
5334 
5335       // If there is not at least one iteration, the range contains garbage. Fix
5336       // to zero in this case.
5337       Dist = AssertSuccess(
5338           Actions.ActOnConditionalOp({}, {}, HasAnyIteration, Dist, Zero));
5339     }
5340 
5341     // Assign the result to the out-parameter.
5342     Stmt *ResultAssign = AssertSuccess(Actions.BuildBinOp(
5343         Actions.getCurScope(), {}, BO_Assign, DistRef, Dist));
5344     BodyStmts.push_back(ResultAssign);
5345 
5346     Body = AssertSuccess(Actions.ActOnCompoundStmt({}, {}, BodyStmts, false));
5347   }
5348 
5349   return cast<CapturedStmt>(
5350       AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5351 }
5352 
5353 /// Create a closure that computes the loop variable from the logical iteration
5354 /// number.
5355 ///
5356 /// \param Actions   The Sema object.
5357 /// \param LoopVarTy Type for the loop variable used for result value.
5358 /// \param LogicalTy Type for the logical iteration number.
5359 /// \param StartExpr Value of the loop counter at the first iteration.
5360 /// \param Step      Amount of increment after each iteration.
5361 /// \param Deref     Whether the loop variable is a dereference of the loop
5362 /// counter variable.
5363 ///
5364 /// \return Closure (CapturedStmt) of the loop value calculation.
buildLoopVarFunc(Sema & Actions,QualType LoopVarTy,QualType LogicalTy,DeclRefExpr * StartExpr,Expr * Step,bool Deref)5365 static CapturedStmt *buildLoopVarFunc(Sema &Actions, QualType LoopVarTy,
5366                                       QualType LogicalTy,
5367                                       DeclRefExpr *StartExpr, Expr *Step,
5368                                       bool Deref) {
5369   ASTContext &Ctx = Actions.getASTContext();
5370 
5371   // Pass the result as an out-parameter. Passing as return value would require
5372   // the OpenMPIRBuilder to know additional C/C++ semantics, such as how to
5373   // invoke a copy constructor.
5374   QualType TargetParamTy = Ctx.getLValueReferenceType(LoopVarTy);
5375   Sema::CapturedParamNameType Params[] = {{"LoopVar", TargetParamTy},
5376                                           {"Logical", LogicalTy},
5377                                           {StringRef(), QualType()}};
5378   Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params);
5379 
5380   // Capture the initial iterator which represents the LoopVar value at the
5381   // zero's logical iteration. Since the original ForStmt/CXXForRangeStmt update
5382   // it in every iteration, capture it by value before it is modified.
5383   VarDecl *StartVar = cast<VarDecl>(StartExpr->getDecl());
5384   bool Invalid = Actions.tryCaptureVariable(StartVar, {},
5385                                             Sema::TryCapture_ExplicitByVal, {});
5386   (void)Invalid;
5387   assert(!Invalid && "Expecting capture-by-value to work.");
5388 
5389   Expr *Body;
5390   {
5391     Sema::CompoundScopeRAII CompoundScope(Actions);
5392     auto *CS = cast<CapturedDecl>(Actions.CurContext);
5393 
5394     ImplicitParamDecl *TargetParam = CS->getParam(0);
5395     DeclRefExpr *TargetRef = Actions.BuildDeclRefExpr(
5396         TargetParam, LoopVarTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5397     ImplicitParamDecl *IndvarParam = CS->getParam(1);
5398     DeclRefExpr *LogicalRef = Actions.BuildDeclRefExpr(
5399         IndvarParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr);
5400 
5401     // Capture the Start expression.
5402     CaptureVars Recap(Actions);
5403     Expr *NewStart = AssertSuccess(Recap.TransformExpr(StartExpr));
5404     Expr *NewStep = AssertSuccess(Recap.TransformExpr(Step));
5405 
5406     Expr *Skip = AssertSuccess(
5407         Actions.BuildBinOp(nullptr, {}, BO_Mul, NewStep, LogicalRef));
5408     // TODO: Explicitly cast to the iterator's difference_type instead of
5409     // relying on implicit conversion.
5410     Expr *Advanced =
5411         AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, NewStart, Skip));
5412 
5413     if (Deref) {
5414       // For range-based for-loops convert the loop counter value to a concrete
5415       // loop variable value by dereferencing the iterator.
5416       Advanced =
5417           AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Deref, Advanced));
5418     }
5419 
5420     // Assign the result to the output parameter.
5421     Body = AssertSuccess(Actions.BuildBinOp(Actions.getCurScope(), {},
5422                                             BO_Assign, TargetRef, Advanced));
5423   }
5424   return cast<CapturedStmt>(
5425       AssertSuccess(Actions.ActOnCapturedRegionEnd(Body)));
5426 }
5427 
ActOnOpenMPCanonicalLoop(Stmt * AStmt)5428 StmtResult Sema::ActOnOpenMPCanonicalLoop(Stmt *AStmt) {
5429   ASTContext &Ctx = getASTContext();
5430 
5431   // Extract the common elements of ForStmt and CXXForRangeStmt:
5432   // Loop variable, repeat condition, increment
5433   Expr *Cond, *Inc;
5434   VarDecl *LIVDecl, *LUVDecl;
5435   if (auto *For = dyn_cast<ForStmt>(AStmt)) {
5436     Stmt *Init = For->getInit();
5437     if (auto *LCVarDeclStmt = dyn_cast<DeclStmt>(Init)) {
5438       // For statement declares loop variable.
5439       LIVDecl = cast<VarDecl>(LCVarDeclStmt->getSingleDecl());
5440     } else if (auto *LCAssign = dyn_cast<BinaryOperator>(Init)) {
5441       // For statement reuses variable.
5442       assert(LCAssign->getOpcode() == BO_Assign &&
5443              "init part must be a loop variable assignment");
5444       auto *CounterRef = cast<DeclRefExpr>(LCAssign->getLHS());
5445       LIVDecl = cast<VarDecl>(CounterRef->getDecl());
5446     } else
5447       llvm_unreachable("Cannot determine loop variable");
5448     LUVDecl = LIVDecl;
5449 
5450     Cond = For->getCond();
5451     Inc = For->getInc();
5452   } else if (auto *RangeFor = dyn_cast<CXXForRangeStmt>(AStmt)) {
5453     DeclStmt *BeginStmt = RangeFor->getBeginStmt();
5454     LIVDecl = cast<VarDecl>(BeginStmt->getSingleDecl());
5455     LUVDecl = RangeFor->getLoopVariable();
5456 
5457     Cond = RangeFor->getCond();
5458     Inc = RangeFor->getInc();
5459   } else
5460     llvm_unreachable("unhandled kind of loop");
5461 
5462   QualType CounterTy = LIVDecl->getType();
5463   QualType LVTy = LUVDecl->getType();
5464 
5465   // Analyze the loop condition.
5466   Expr *LHS, *RHS;
5467   BinaryOperator::Opcode CondRel;
5468   Cond = Cond->IgnoreImplicit();
5469   if (auto *CondBinExpr = dyn_cast<BinaryOperator>(Cond)) {
5470     LHS = CondBinExpr->getLHS();
5471     RHS = CondBinExpr->getRHS();
5472     CondRel = CondBinExpr->getOpcode();
5473   } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Cond)) {
5474     assert(CondCXXOp->getNumArgs() == 2 && "Comparison should have 2 operands");
5475     LHS = CondCXXOp->getArg(0);
5476     RHS = CondCXXOp->getArg(1);
5477     switch (CondCXXOp->getOperator()) {
5478     case OO_ExclaimEqual:
5479       CondRel = BO_NE;
5480       break;
5481     case OO_Less:
5482       CondRel = BO_LT;
5483       break;
5484     case OO_LessEqual:
5485       CondRel = BO_LE;
5486       break;
5487     case OO_Greater:
5488       CondRel = BO_GT;
5489       break;
5490     case OO_GreaterEqual:
5491       CondRel = BO_GE;
5492       break;
5493     default:
5494       llvm_unreachable("unexpected iterator operator");
5495     }
5496   } else
5497     llvm_unreachable("unexpected loop condition");
5498 
5499   // Normalize such that the loop counter is on the LHS.
5500   if (!isa<DeclRefExpr>(LHS->IgnoreImplicit()) ||
5501       cast<DeclRefExpr>(LHS->IgnoreImplicit())->getDecl() != LIVDecl) {
5502     std::swap(LHS, RHS);
5503     CondRel = BinaryOperator::reverseComparisonOp(CondRel);
5504   }
5505   auto *CounterRef = cast<DeclRefExpr>(LHS->IgnoreImplicit());
5506 
5507   // Decide the bit width for the logical iteration counter. By default use the
5508   // unsigned ptrdiff_t integer size (for iterators and pointers).
5509   // TODO: For iterators, use iterator::difference_type,
5510   // std::iterator_traits<>::difference_type or decltype(it - end).
5511   QualType LogicalTy = Ctx.getUnsignedPointerDiffType();
5512   if (CounterTy->isIntegerType()) {
5513     unsigned BitWidth = Ctx.getIntWidth(CounterTy);
5514     LogicalTy = Ctx.getIntTypeForBitwidth(BitWidth, false);
5515   }
5516 
5517   // Analyze the loop increment.
5518   Expr *Step;
5519   if (auto *IncUn = dyn_cast<UnaryOperator>(Inc)) {
5520     int Direction;
5521     switch (IncUn->getOpcode()) {
5522     case UO_PreInc:
5523     case UO_PostInc:
5524       Direction = 1;
5525       break;
5526     case UO_PreDec:
5527     case UO_PostDec:
5528       Direction = -1;
5529       break;
5530     default:
5531       llvm_unreachable("unhandled unary increment operator");
5532     }
5533     Step = IntegerLiteral::Create(
5534         Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), Direction), LogicalTy, {});
5535   } else if (auto *IncBin = dyn_cast<BinaryOperator>(Inc)) {
5536     if (IncBin->getOpcode() == BO_AddAssign) {
5537       Step = IncBin->getRHS();
5538     } else if (IncBin->getOpcode() == BO_SubAssign) {
5539       Step =
5540           AssertSuccess(BuildUnaryOp(nullptr, {}, UO_Minus, IncBin->getRHS()));
5541     } else
5542       llvm_unreachable("unhandled binary increment operator");
5543   } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Inc)) {
5544     switch (CondCXXOp->getOperator()) {
5545     case OO_PlusPlus:
5546       Step = IntegerLiteral::Create(
5547           Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {});
5548       break;
5549     case OO_MinusMinus:
5550       Step = IntegerLiteral::Create(
5551           Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), -1), LogicalTy, {});
5552       break;
5553     case OO_PlusEqual:
5554       Step = CondCXXOp->getArg(1);
5555       break;
5556     case OO_MinusEqual:
5557       Step = AssertSuccess(
5558           BuildUnaryOp(nullptr, {}, UO_Minus, CondCXXOp->getArg(1)));
5559       break;
5560     default:
5561       llvm_unreachable("unhandled overloaded increment operator");
5562     }
5563   } else
5564     llvm_unreachable("unknown increment expression");
5565 
5566   CapturedStmt *DistanceFunc =
5567       buildDistanceFunc(*this, LogicalTy, CondRel, LHS, RHS, Step);
5568   CapturedStmt *LoopVarFunc = buildLoopVarFunc(
5569       *this, LVTy, LogicalTy, CounterRef, Step, isa<CXXForRangeStmt>(AStmt));
5570   DeclRefExpr *LVRef = BuildDeclRefExpr(LUVDecl, LUVDecl->getType(), VK_LValue,
5571                                         {}, nullptr, nullptr, {}, nullptr);
5572   return OMPCanonicalLoop::create(getASTContext(), AStmt, DistanceFunc,
5573                                   LoopVarFunc, LVRef);
5574 }
5575 
5576 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
5577                                             CXXScopeSpec &MapperIdScopeSpec,
5578                                             const DeclarationNameInfo &MapperId,
5579                                             QualType Type,
5580                                             Expr *UnresolvedMapper);
5581 
5582 /// Perform DFS through the structure/class data members trying to find
5583 /// member(s) with user-defined 'default' mapper and generate implicit map
5584 /// clauses for such members with the found 'default' mapper.
5585 static void
processImplicitMapsWithDefaultMappers(Sema & S,DSAStackTy * Stack,SmallVectorImpl<OMPClause * > & Clauses)5586 processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack,
5587                                       SmallVectorImpl<OMPClause *> &Clauses) {
5588   // Check for the deault mapper for data members.
5589   if (S.getLangOpts().OpenMP < 50)
5590     return;
5591   SmallVector<OMPClause *, 4> ImplicitMaps;
5592   for (int Cnt = 0, EndCnt = Clauses.size(); Cnt < EndCnt; ++Cnt) {
5593     auto *C = dyn_cast<OMPMapClause>(Clauses[Cnt]);
5594     if (!C)
5595       continue;
5596     SmallVector<Expr *, 4> SubExprs;
5597     auto *MI = C->mapperlist_begin();
5598     for (auto I = C->varlist_begin(), End = C->varlist_end(); I != End;
5599          ++I, ++MI) {
5600       // Expression is mapped using mapper - skip it.
5601       if (*MI)
5602         continue;
5603       Expr *E = *I;
5604       // Expression is dependent - skip it, build the mapper when it gets
5605       // instantiated.
5606       if (E->isTypeDependent() || E->isValueDependent() ||
5607           E->containsUnexpandedParameterPack())
5608         continue;
5609       // Array section - need to check for the mapping of the array section
5610       // element.
5611       QualType CanonType = E->getType().getCanonicalType();
5612       if (CanonType->isSpecificBuiltinType(BuiltinType::OMPArraySection)) {
5613         const auto *OASE = cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts());
5614         QualType BaseType =
5615             OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
5616         QualType ElemType;
5617         if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
5618           ElemType = ATy->getElementType();
5619         else
5620           ElemType = BaseType->getPointeeType();
5621         CanonType = ElemType;
5622       }
5623 
5624       // DFS over data members in structures/classes.
5625       SmallVector<std::pair<QualType, FieldDecl *>, 4> Types(
5626           1, {CanonType, nullptr});
5627       llvm::DenseMap<const Type *, Expr *> Visited;
5628       SmallVector<std::pair<FieldDecl *, unsigned>, 4> ParentChain(
5629           1, {nullptr, 1});
5630       while (!Types.empty()) {
5631         QualType BaseType;
5632         FieldDecl *CurFD;
5633         std::tie(BaseType, CurFD) = Types.pop_back_val();
5634         while (ParentChain.back().second == 0)
5635           ParentChain.pop_back();
5636         --ParentChain.back().second;
5637         if (BaseType.isNull())
5638           continue;
5639         // Only structs/classes are allowed to have mappers.
5640         const RecordDecl *RD = BaseType.getCanonicalType()->getAsRecordDecl();
5641         if (!RD)
5642           continue;
5643         auto It = Visited.find(BaseType.getTypePtr());
5644         if (It == Visited.end()) {
5645           // Try to find the associated user-defined mapper.
5646           CXXScopeSpec MapperIdScopeSpec;
5647           DeclarationNameInfo DefaultMapperId;
5648           DefaultMapperId.setName(S.Context.DeclarationNames.getIdentifier(
5649               &S.Context.Idents.get("default")));
5650           DefaultMapperId.setLoc(E->getExprLoc());
5651           ExprResult ER = buildUserDefinedMapperRef(
5652               S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId,
5653               BaseType, /*UnresolvedMapper=*/nullptr);
5654           if (ER.isInvalid())
5655             continue;
5656           It = Visited.try_emplace(BaseType.getTypePtr(), ER.get()).first;
5657         }
5658         // Found default mapper.
5659         if (It->second) {
5660           auto *OE = new (S.Context) OpaqueValueExpr(E->getExprLoc(), CanonType,
5661                                                      VK_LValue, OK_Ordinary, E);
5662           OE->setIsUnique(/*V=*/true);
5663           Expr *BaseExpr = OE;
5664           for (const auto &P : ParentChain) {
5665             if (P.first) {
5666               BaseExpr = S.BuildMemberExpr(
5667                   BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
5668                   NestedNameSpecifierLoc(), SourceLocation(), P.first,
5669                   DeclAccessPair::make(P.first, P.first->getAccess()),
5670                   /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
5671                   P.first->getType(), VK_LValue, OK_Ordinary);
5672               BaseExpr = S.DefaultLvalueConversion(BaseExpr).get();
5673             }
5674           }
5675           if (CurFD)
5676             BaseExpr = S.BuildMemberExpr(
5677                 BaseExpr, /*IsArrow=*/false, E->getExprLoc(),
5678                 NestedNameSpecifierLoc(), SourceLocation(), CurFD,
5679                 DeclAccessPair::make(CurFD, CurFD->getAccess()),
5680                 /*HadMultipleCandidates=*/false, DeclarationNameInfo(),
5681                 CurFD->getType(), VK_LValue, OK_Ordinary);
5682           SubExprs.push_back(BaseExpr);
5683           continue;
5684         }
5685         // Check for the "default" mapper for data memebers.
5686         bool FirstIter = true;
5687         for (FieldDecl *FD : RD->fields()) {
5688           if (!FD)
5689             continue;
5690           QualType FieldTy = FD->getType();
5691           if (FieldTy.isNull() ||
5692               !(FieldTy->isStructureOrClassType() || FieldTy->isUnionType()))
5693             continue;
5694           if (FirstIter) {
5695             FirstIter = false;
5696             ParentChain.emplace_back(CurFD, 1);
5697           } else {
5698             ++ParentChain.back().second;
5699           }
5700           Types.emplace_back(FieldTy, FD);
5701         }
5702       }
5703     }
5704     if (SubExprs.empty())
5705       continue;
5706     CXXScopeSpec MapperIdScopeSpec;
5707     DeclarationNameInfo MapperId;
5708     if (OMPClause *NewClause = S.ActOnOpenMPMapClause(
5709             C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(),
5710             MapperIdScopeSpec, MapperId, C->getMapType(),
5711             /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(),
5712             SubExprs, OMPVarListLocTy()))
5713       Clauses.push_back(NewClause);
5714   }
5715 }
5716 
ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind,const DeclarationNameInfo & DirName,OpenMPDirectiveKind CancelRegion,ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)5717 StmtResult Sema::ActOnOpenMPExecutableDirective(
5718     OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName,
5719     OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses,
5720     Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
5721   StmtResult Res = StmtError();
5722   // First check CancelRegion which is then used in checkNestingOfRegions.
5723   if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) ||
5724       checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion,
5725                             StartLoc))
5726     return StmtError();
5727 
5728   llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit;
5729   VarsWithInheritedDSAType VarsWithInheritedDSA;
5730   bool ErrorFound = false;
5731   ClausesWithImplicit.append(Clauses.begin(), Clauses.end());
5732   if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic &&
5733       Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master &&
5734       Kind != OMPD_masked && !isOpenMPLoopTransformationDirective(Kind)) {
5735     assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
5736 
5737     // Check default data sharing attributes for referenced variables.
5738     DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt));
5739     int ThisCaptureLevel = getOpenMPCaptureLevels(Kind);
5740     Stmt *S = AStmt;
5741     while (--ThisCaptureLevel >= 0)
5742       S = cast<CapturedStmt>(S)->getCapturedStmt();
5743     DSAChecker.Visit(S);
5744     if (!isOpenMPTargetDataManagementDirective(Kind) &&
5745         !isOpenMPTaskingDirective(Kind)) {
5746       // Visit subcaptures to generate implicit clauses for captured vars.
5747       auto *CS = cast<CapturedStmt>(AStmt);
5748       SmallVector<OpenMPDirectiveKind, 4> CaptureRegions;
5749       getOpenMPCaptureRegions(CaptureRegions, Kind);
5750       // Ignore outer tasking regions for target directives.
5751       if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task)
5752         CS = cast<CapturedStmt>(CS->getCapturedStmt());
5753       DSAChecker.visitSubCaptures(CS);
5754     }
5755     if (DSAChecker.isErrorFound())
5756       return StmtError();
5757     // Generate list of implicitly defined firstprivate variables.
5758     VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA();
5759 
5760     SmallVector<Expr *, 4> ImplicitFirstprivates(
5761         DSAChecker.getImplicitFirstprivate().begin(),
5762         DSAChecker.getImplicitFirstprivate().end());
5763     const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1;
5764     SmallVector<Expr *, 4> ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete];
5765     SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers>
5766         ImplicitMapModifiers[DefaultmapKindNum];
5767     SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers>
5768         ImplicitMapModifiersLoc[DefaultmapKindNum];
5769     // Get the original location of present modifier from Defaultmap clause.
5770     SourceLocation PresentModifierLocs[DefaultmapKindNum];
5771     for (OMPClause *C : Clauses) {
5772       if (auto *DMC = dyn_cast<OMPDefaultmapClause>(C))
5773         if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present)
5774           PresentModifierLocs[DMC->getDefaultmapKind()] =
5775               DMC->getDefaultmapModifierLoc();
5776     }
5777     for (unsigned VC = 0; VC < DefaultmapKindNum; ++VC) {
5778       auto Kind = static_cast<OpenMPDefaultmapClauseKind>(VC);
5779       for (unsigned I = 0; I < OMPC_MAP_delete; ++I) {
5780         ArrayRef<Expr *> ImplicitMap = DSAChecker.getImplicitMap(
5781             Kind, static_cast<OpenMPMapClauseKind>(I));
5782         ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end());
5783       }
5784       ArrayRef<OpenMPMapModifierKind> ImplicitModifier =
5785           DSAChecker.getImplicitMapModifier(Kind);
5786       ImplicitMapModifiers[VC].append(ImplicitModifier.begin(),
5787                                       ImplicitModifier.end());
5788       std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]),
5789                   ImplicitModifier.size(), PresentModifierLocs[VC]);
5790     }
5791     // Mark taskgroup task_reduction descriptors as implicitly firstprivate.
5792     for (OMPClause *C : Clauses) {
5793       if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) {
5794         for (Expr *E : IRC->taskgroup_descriptors())
5795           if (E)
5796             ImplicitFirstprivates.emplace_back(E);
5797       }
5798       // OpenMP 5.0, 2.10.1 task Construct
5799       // [detach clause]... The event-handle will be considered as if it was
5800       // specified on a firstprivate clause.
5801       if (auto *DC = dyn_cast<OMPDetachClause>(C))
5802         ImplicitFirstprivates.push_back(DC->getEventHandler());
5803     }
5804     if (!ImplicitFirstprivates.empty()) {
5805       if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause(
5806               ImplicitFirstprivates, SourceLocation(), SourceLocation(),
5807               SourceLocation())) {
5808         ClausesWithImplicit.push_back(Implicit);
5809         ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() !=
5810                      ImplicitFirstprivates.size();
5811       } else {
5812         ErrorFound = true;
5813       }
5814     }
5815     for (unsigned I = 0, E = DefaultmapKindNum; I < E; ++I) {
5816       int ClauseKindCnt = -1;
5817       for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps[I]) {
5818         ++ClauseKindCnt;
5819         if (ImplicitMap.empty())
5820           continue;
5821         CXXScopeSpec MapperIdScopeSpec;
5822         DeclarationNameInfo MapperId;
5823         auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt);
5824         if (OMPClause *Implicit = ActOnOpenMPMapClause(
5825                 ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I],
5826                 MapperIdScopeSpec, MapperId, Kind, /*IsMapTypeImplicit=*/true,
5827                 SourceLocation(), SourceLocation(), ImplicitMap,
5828                 OMPVarListLocTy())) {
5829           ClausesWithImplicit.emplace_back(Implicit);
5830           ErrorFound |= cast<OMPMapClause>(Implicit)->varlist_size() !=
5831                         ImplicitMap.size();
5832         } else {
5833           ErrorFound = true;
5834         }
5835       }
5836     }
5837     // Build expressions for implicit maps of data members with 'default'
5838     // mappers.
5839     if (LangOpts.OpenMP >= 50)
5840       processImplicitMapsWithDefaultMappers(*this, DSAStack,
5841                                             ClausesWithImplicit);
5842   }
5843 
5844   llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers;
5845   switch (Kind) {
5846   case OMPD_parallel:
5847     Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc,
5848                                        EndLoc);
5849     AllowedNameModifiers.push_back(OMPD_parallel);
5850     break;
5851   case OMPD_simd:
5852     Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5853                                    VarsWithInheritedDSA);
5854     if (LangOpts.OpenMP >= 50)
5855       AllowedNameModifiers.push_back(OMPD_simd);
5856     break;
5857   case OMPD_tile:
5858     Res =
5859         ActOnOpenMPTileDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5860     break;
5861   case OMPD_unroll:
5862     Res = ActOnOpenMPUnrollDirective(ClausesWithImplicit, AStmt, StartLoc,
5863                                      EndLoc);
5864     break;
5865   case OMPD_for:
5866     Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc,
5867                                   VarsWithInheritedDSA);
5868     break;
5869   case OMPD_for_simd:
5870     Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
5871                                       EndLoc, VarsWithInheritedDSA);
5872     if (LangOpts.OpenMP >= 50)
5873       AllowedNameModifiers.push_back(OMPD_simd);
5874     break;
5875   case OMPD_sections:
5876     Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc,
5877                                        EndLoc);
5878     break;
5879   case OMPD_section:
5880     assert(ClausesWithImplicit.empty() &&
5881            "No clauses are allowed for 'omp section' directive");
5882     Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc);
5883     break;
5884   case OMPD_single:
5885     Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc,
5886                                      EndLoc);
5887     break;
5888   case OMPD_master:
5889     assert(ClausesWithImplicit.empty() &&
5890            "No clauses are allowed for 'omp master' directive");
5891     Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc);
5892     break;
5893   case OMPD_masked:
5894     Res = ActOnOpenMPMaskedDirective(ClausesWithImplicit, AStmt, StartLoc,
5895                                      EndLoc);
5896     break;
5897   case OMPD_critical:
5898     Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt,
5899                                        StartLoc, EndLoc);
5900     break;
5901   case OMPD_parallel_for:
5902     Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc,
5903                                           EndLoc, VarsWithInheritedDSA);
5904     AllowedNameModifiers.push_back(OMPD_parallel);
5905     break;
5906   case OMPD_parallel_for_simd:
5907     Res = ActOnOpenMPParallelForSimdDirective(
5908         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5909     AllowedNameModifiers.push_back(OMPD_parallel);
5910     if (LangOpts.OpenMP >= 50)
5911       AllowedNameModifiers.push_back(OMPD_simd);
5912     break;
5913   case OMPD_parallel_master:
5914     Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt,
5915                                                StartLoc, EndLoc);
5916     AllowedNameModifiers.push_back(OMPD_parallel);
5917     break;
5918   case OMPD_parallel_sections:
5919     Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt,
5920                                                StartLoc, EndLoc);
5921     AllowedNameModifiers.push_back(OMPD_parallel);
5922     break;
5923   case OMPD_task:
5924     Res =
5925         ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5926     AllowedNameModifiers.push_back(OMPD_task);
5927     break;
5928   case OMPD_taskyield:
5929     assert(ClausesWithImplicit.empty() &&
5930            "No clauses are allowed for 'omp taskyield' directive");
5931     assert(AStmt == nullptr &&
5932            "No associated statement allowed for 'omp taskyield' directive");
5933     Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc);
5934     break;
5935   case OMPD_barrier:
5936     assert(ClausesWithImplicit.empty() &&
5937            "No clauses are allowed for 'omp barrier' directive");
5938     assert(AStmt == nullptr &&
5939            "No associated statement allowed for 'omp barrier' directive");
5940     Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc);
5941     break;
5942   case OMPD_taskwait:
5943     assert(ClausesWithImplicit.empty() &&
5944            "No clauses are allowed for 'omp taskwait' directive");
5945     assert(AStmt == nullptr &&
5946            "No associated statement allowed for 'omp taskwait' directive");
5947     Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
5948     break;
5949   case OMPD_taskgroup:
5950     Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
5951                                         EndLoc);
5952     break;
5953   case OMPD_flush:
5954     assert(AStmt == nullptr &&
5955            "No associated statement allowed for 'omp flush' directive");
5956     Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc);
5957     break;
5958   case OMPD_depobj:
5959     assert(AStmt == nullptr &&
5960            "No associated statement allowed for 'omp depobj' directive");
5961     Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc);
5962     break;
5963   case OMPD_scan:
5964     assert(AStmt == nullptr &&
5965            "No associated statement allowed for 'omp scan' directive");
5966     Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc);
5967     break;
5968   case OMPD_ordered:
5969     Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc,
5970                                       EndLoc);
5971     break;
5972   case OMPD_atomic:
5973     Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc,
5974                                      EndLoc);
5975     break;
5976   case OMPD_teams:
5977     Res =
5978         ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc);
5979     break;
5980   case OMPD_target:
5981     Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc,
5982                                      EndLoc);
5983     AllowedNameModifiers.push_back(OMPD_target);
5984     break;
5985   case OMPD_target_parallel:
5986     Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt,
5987                                              StartLoc, EndLoc);
5988     AllowedNameModifiers.push_back(OMPD_target);
5989     AllowedNameModifiers.push_back(OMPD_parallel);
5990     break;
5991   case OMPD_target_parallel_for:
5992     Res = ActOnOpenMPTargetParallelForDirective(
5993         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
5994     AllowedNameModifiers.push_back(OMPD_target);
5995     AllowedNameModifiers.push_back(OMPD_parallel);
5996     break;
5997   case OMPD_cancellation_point:
5998     assert(ClausesWithImplicit.empty() &&
5999            "No clauses are allowed for 'omp cancellation point' directive");
6000     assert(AStmt == nullptr && "No associated statement allowed for 'omp "
6001                                "cancellation point' directive");
6002     Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion);
6003     break;
6004   case OMPD_cancel:
6005     assert(AStmt == nullptr &&
6006            "No associated statement allowed for 'omp cancel' directive");
6007     Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc,
6008                                      CancelRegion);
6009     AllowedNameModifiers.push_back(OMPD_cancel);
6010     break;
6011   case OMPD_target_data:
6012     Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc,
6013                                          EndLoc);
6014     AllowedNameModifiers.push_back(OMPD_target_data);
6015     break;
6016   case OMPD_target_enter_data:
6017     Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc,
6018                                               EndLoc, AStmt);
6019     AllowedNameModifiers.push_back(OMPD_target_enter_data);
6020     break;
6021   case OMPD_target_exit_data:
6022     Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc,
6023                                              EndLoc, AStmt);
6024     AllowedNameModifiers.push_back(OMPD_target_exit_data);
6025     break;
6026   case OMPD_taskloop:
6027     Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc,
6028                                        EndLoc, VarsWithInheritedDSA);
6029     AllowedNameModifiers.push_back(OMPD_taskloop);
6030     break;
6031   case OMPD_taskloop_simd:
6032     Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6033                                            EndLoc, VarsWithInheritedDSA);
6034     AllowedNameModifiers.push_back(OMPD_taskloop);
6035     if (LangOpts.OpenMP >= 50)
6036       AllowedNameModifiers.push_back(OMPD_simd);
6037     break;
6038   case OMPD_master_taskloop:
6039     Res = ActOnOpenMPMasterTaskLoopDirective(
6040         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6041     AllowedNameModifiers.push_back(OMPD_taskloop);
6042     break;
6043   case OMPD_master_taskloop_simd:
6044     Res = ActOnOpenMPMasterTaskLoopSimdDirective(
6045         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6046     AllowedNameModifiers.push_back(OMPD_taskloop);
6047     if (LangOpts.OpenMP >= 50)
6048       AllowedNameModifiers.push_back(OMPD_simd);
6049     break;
6050   case OMPD_parallel_master_taskloop:
6051     Res = ActOnOpenMPParallelMasterTaskLoopDirective(
6052         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6053     AllowedNameModifiers.push_back(OMPD_taskloop);
6054     AllowedNameModifiers.push_back(OMPD_parallel);
6055     break;
6056   case OMPD_parallel_master_taskloop_simd:
6057     Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective(
6058         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6059     AllowedNameModifiers.push_back(OMPD_taskloop);
6060     AllowedNameModifiers.push_back(OMPD_parallel);
6061     if (LangOpts.OpenMP >= 50)
6062       AllowedNameModifiers.push_back(OMPD_simd);
6063     break;
6064   case OMPD_distribute:
6065     Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc,
6066                                          EndLoc, VarsWithInheritedDSA);
6067     break;
6068   case OMPD_target_update:
6069     Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc,
6070                                            EndLoc, AStmt);
6071     AllowedNameModifiers.push_back(OMPD_target_update);
6072     break;
6073   case OMPD_distribute_parallel_for:
6074     Res = ActOnOpenMPDistributeParallelForDirective(
6075         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6076     AllowedNameModifiers.push_back(OMPD_parallel);
6077     break;
6078   case OMPD_distribute_parallel_for_simd:
6079     Res = ActOnOpenMPDistributeParallelForSimdDirective(
6080         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6081     AllowedNameModifiers.push_back(OMPD_parallel);
6082     if (LangOpts.OpenMP >= 50)
6083       AllowedNameModifiers.push_back(OMPD_simd);
6084     break;
6085   case OMPD_distribute_simd:
6086     Res = ActOnOpenMPDistributeSimdDirective(
6087         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6088     if (LangOpts.OpenMP >= 50)
6089       AllowedNameModifiers.push_back(OMPD_simd);
6090     break;
6091   case OMPD_target_parallel_for_simd:
6092     Res = ActOnOpenMPTargetParallelForSimdDirective(
6093         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6094     AllowedNameModifiers.push_back(OMPD_target);
6095     AllowedNameModifiers.push_back(OMPD_parallel);
6096     if (LangOpts.OpenMP >= 50)
6097       AllowedNameModifiers.push_back(OMPD_simd);
6098     break;
6099   case OMPD_target_simd:
6100     Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc,
6101                                          EndLoc, VarsWithInheritedDSA);
6102     AllowedNameModifiers.push_back(OMPD_target);
6103     if (LangOpts.OpenMP >= 50)
6104       AllowedNameModifiers.push_back(OMPD_simd);
6105     break;
6106   case OMPD_teams_distribute:
6107     Res = ActOnOpenMPTeamsDistributeDirective(
6108         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6109     break;
6110   case OMPD_teams_distribute_simd:
6111     Res = ActOnOpenMPTeamsDistributeSimdDirective(
6112         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6113     if (LangOpts.OpenMP >= 50)
6114       AllowedNameModifiers.push_back(OMPD_simd);
6115     break;
6116   case OMPD_teams_distribute_parallel_for_simd:
6117     Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective(
6118         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6119     AllowedNameModifiers.push_back(OMPD_parallel);
6120     if (LangOpts.OpenMP >= 50)
6121       AllowedNameModifiers.push_back(OMPD_simd);
6122     break;
6123   case OMPD_teams_distribute_parallel_for:
6124     Res = ActOnOpenMPTeamsDistributeParallelForDirective(
6125         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6126     AllowedNameModifiers.push_back(OMPD_parallel);
6127     break;
6128   case OMPD_target_teams:
6129     Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc,
6130                                           EndLoc);
6131     AllowedNameModifiers.push_back(OMPD_target);
6132     break;
6133   case OMPD_target_teams_distribute:
6134     Res = ActOnOpenMPTargetTeamsDistributeDirective(
6135         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6136     AllowedNameModifiers.push_back(OMPD_target);
6137     break;
6138   case OMPD_target_teams_distribute_parallel_for:
6139     Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective(
6140         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6141     AllowedNameModifiers.push_back(OMPD_target);
6142     AllowedNameModifiers.push_back(OMPD_parallel);
6143     break;
6144   case OMPD_target_teams_distribute_parallel_for_simd:
6145     Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
6146         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6147     AllowedNameModifiers.push_back(OMPD_target);
6148     AllowedNameModifiers.push_back(OMPD_parallel);
6149     if (LangOpts.OpenMP >= 50)
6150       AllowedNameModifiers.push_back(OMPD_simd);
6151     break;
6152   case OMPD_target_teams_distribute_simd:
6153     Res = ActOnOpenMPTargetTeamsDistributeSimdDirective(
6154         ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA);
6155     AllowedNameModifiers.push_back(OMPD_target);
6156     if (LangOpts.OpenMP >= 50)
6157       AllowedNameModifiers.push_back(OMPD_simd);
6158     break;
6159   case OMPD_interop:
6160     assert(AStmt == nullptr &&
6161            "No associated statement allowed for 'omp interop' directive");
6162     Res = ActOnOpenMPInteropDirective(ClausesWithImplicit, StartLoc, EndLoc);
6163     break;
6164   case OMPD_dispatch:
6165     Res = ActOnOpenMPDispatchDirective(ClausesWithImplicit, AStmt, StartLoc,
6166                                        EndLoc);
6167     break;
6168   case OMPD_declare_target:
6169   case OMPD_end_declare_target:
6170   case OMPD_threadprivate:
6171   case OMPD_allocate:
6172   case OMPD_declare_reduction:
6173   case OMPD_declare_mapper:
6174   case OMPD_declare_simd:
6175   case OMPD_requires:
6176   case OMPD_declare_variant:
6177   case OMPD_begin_declare_variant:
6178   case OMPD_end_declare_variant:
6179     llvm_unreachable("OpenMP Directive is not allowed");
6180   case OMPD_unknown:
6181   default:
6182     llvm_unreachable("Unknown OpenMP directive");
6183   }
6184 
6185   ErrorFound = Res.isInvalid() || ErrorFound;
6186 
6187   // Check variables in the clauses if default(none) or
6188   // default(firstprivate) was specified.
6189   if (DSAStack->getDefaultDSA() == DSA_none ||
6190       DSAStack->getDefaultDSA() == DSA_firstprivate) {
6191     DSAAttrChecker DSAChecker(DSAStack, *this, nullptr);
6192     for (OMPClause *C : Clauses) {
6193       switch (C->getClauseKind()) {
6194       case OMPC_num_threads:
6195       case OMPC_dist_schedule:
6196         // Do not analyse if no parent teams directive.
6197         if (isOpenMPTeamsDirective(Kind))
6198           break;
6199         continue;
6200       case OMPC_if:
6201         if (isOpenMPTeamsDirective(Kind) &&
6202             cast<OMPIfClause>(C)->getNameModifier() != OMPD_target)
6203           break;
6204         if (isOpenMPParallelDirective(Kind) &&
6205             isOpenMPTaskLoopDirective(Kind) &&
6206             cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel)
6207           break;
6208         continue;
6209       case OMPC_schedule:
6210       case OMPC_detach:
6211         break;
6212       case OMPC_grainsize:
6213       case OMPC_num_tasks:
6214       case OMPC_final:
6215       case OMPC_priority:
6216       case OMPC_novariants:
6217       case OMPC_nocontext:
6218         // Do not analyze if no parent parallel directive.
6219         if (isOpenMPParallelDirective(Kind))
6220           break;
6221         continue;
6222       case OMPC_ordered:
6223       case OMPC_device:
6224       case OMPC_num_teams:
6225       case OMPC_thread_limit:
6226       case OMPC_hint:
6227       case OMPC_collapse:
6228       case OMPC_safelen:
6229       case OMPC_simdlen:
6230       case OMPC_sizes:
6231       case OMPC_default:
6232       case OMPC_proc_bind:
6233       case OMPC_private:
6234       case OMPC_firstprivate:
6235       case OMPC_lastprivate:
6236       case OMPC_shared:
6237       case OMPC_reduction:
6238       case OMPC_task_reduction:
6239       case OMPC_in_reduction:
6240       case OMPC_linear:
6241       case OMPC_aligned:
6242       case OMPC_copyin:
6243       case OMPC_copyprivate:
6244       case OMPC_nowait:
6245       case OMPC_untied:
6246       case OMPC_mergeable:
6247       case OMPC_allocate:
6248       case OMPC_read:
6249       case OMPC_write:
6250       case OMPC_update:
6251       case OMPC_capture:
6252       case OMPC_seq_cst:
6253       case OMPC_acq_rel:
6254       case OMPC_acquire:
6255       case OMPC_release:
6256       case OMPC_relaxed:
6257       case OMPC_depend:
6258       case OMPC_threads:
6259       case OMPC_simd:
6260       case OMPC_map:
6261       case OMPC_nogroup:
6262       case OMPC_defaultmap:
6263       case OMPC_to:
6264       case OMPC_from:
6265       case OMPC_use_device_ptr:
6266       case OMPC_use_device_addr:
6267       case OMPC_is_device_ptr:
6268       case OMPC_nontemporal:
6269       case OMPC_order:
6270       case OMPC_destroy:
6271       case OMPC_inclusive:
6272       case OMPC_exclusive:
6273       case OMPC_uses_allocators:
6274       case OMPC_affinity:
6275         continue;
6276       case OMPC_allocator:
6277       case OMPC_flush:
6278       case OMPC_depobj:
6279       case OMPC_threadprivate:
6280       case OMPC_uniform:
6281       case OMPC_unknown:
6282       case OMPC_unified_address:
6283       case OMPC_unified_shared_memory:
6284       case OMPC_reverse_offload:
6285       case OMPC_dynamic_allocators:
6286       case OMPC_atomic_default_mem_order:
6287       case OMPC_device_type:
6288       case OMPC_match:
6289       default:
6290         llvm_unreachable("Unexpected clause");
6291       }
6292       for (Stmt *CC : C->children()) {
6293         if (CC)
6294           DSAChecker.Visit(CC);
6295       }
6296     }
6297     for (const auto &P : DSAChecker.getVarsWithInheritedDSA())
6298       VarsWithInheritedDSA[P.getFirst()] = P.getSecond();
6299   }
6300   for (const auto &P : VarsWithInheritedDSA) {
6301     if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst()))
6302       continue;
6303     ErrorFound = true;
6304     if (DSAStack->getDefaultDSA() == DSA_none ||
6305         DSAStack->getDefaultDSA() == DSA_firstprivate) {
6306       Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable)
6307           << P.first << P.second->getSourceRange();
6308       Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none);
6309     } else if (getLangOpts().OpenMP >= 50) {
6310       Diag(P.second->getExprLoc(),
6311            diag::err_omp_defaultmap_no_attr_for_variable)
6312           << P.first << P.second->getSourceRange();
6313       Diag(DSAStack->getDefaultDSALocation(),
6314            diag::note_omp_defaultmap_attr_none);
6315     }
6316   }
6317 
6318   if (!AllowedNameModifiers.empty())
6319     ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) ||
6320                  ErrorFound;
6321 
6322   if (ErrorFound)
6323     return StmtError();
6324 
6325   if (!CurContext->isDependentContext() &&
6326       isOpenMPTargetExecutionDirective(Kind) &&
6327       !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() ||
6328         DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() ||
6329         DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() ||
6330         DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) {
6331     // Register target to DSA Stack.
6332     DSAStack->addTargetDirLocation(StartLoc);
6333   }
6334 
6335   return Res;
6336 }
6337 
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)6338 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective(
6339     DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen,
6340     ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds,
6341     ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears,
6342     ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) {
6343   assert(Aligneds.size() == Alignments.size());
6344   assert(Linears.size() == LinModifiers.size());
6345   assert(Linears.size() == Steps.size());
6346   if (!DG || DG.get().isNull())
6347     return DeclGroupPtrTy();
6348 
6349   const int SimdId = 0;
6350   if (!DG.get().isSingleDecl()) {
6351     Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
6352         << SimdId;
6353     return DG;
6354   }
6355   Decl *ADecl = DG.get().getSingleDecl();
6356   if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
6357     ADecl = FTD->getTemplatedDecl();
6358 
6359   auto *FD = dyn_cast<FunctionDecl>(ADecl);
6360   if (!FD) {
6361     Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId;
6362     return DeclGroupPtrTy();
6363   }
6364 
6365   // OpenMP [2.8.2, declare simd construct, Description]
6366   // The parameter of the simdlen clause must be a constant positive integer
6367   // expression.
6368   ExprResult SL;
6369   if (Simdlen)
6370     SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen);
6371   // OpenMP [2.8.2, declare simd construct, Description]
6372   // The special this pointer can be used as if was one of the arguments to the
6373   // function in any of the linear, aligned, or uniform clauses.
6374   // The uniform clause declares one or more arguments to have an invariant
6375   // value for all concurrent invocations of the function in the execution of a
6376   // single SIMD loop.
6377   llvm::DenseMap<const Decl *, const Expr *> UniformedArgs;
6378   const Expr *UniformedLinearThis = nullptr;
6379   for (const Expr *E : Uniforms) {
6380     E = E->IgnoreParenImpCasts();
6381     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6382       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl()))
6383         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6384             FD->getParamDecl(PVD->getFunctionScopeIndex())
6385                     ->getCanonicalDecl() == PVD->getCanonicalDecl()) {
6386           UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E);
6387           continue;
6388         }
6389     if (isa<CXXThisExpr>(E)) {
6390       UniformedLinearThis = E;
6391       continue;
6392     }
6393     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6394         << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6395   }
6396   // OpenMP [2.8.2, declare simd construct, Description]
6397   // The aligned clause declares that the object to which each list item points
6398   // is aligned to the number of bytes expressed in the optional parameter of
6399   // the aligned clause.
6400   // The special this pointer can be used as if was one of the arguments to the
6401   // function in any of the linear, aligned, or uniform clauses.
6402   // The type of list items appearing in the aligned clause must be array,
6403   // pointer, reference to array, or reference to pointer.
6404   llvm::DenseMap<const Decl *, const Expr *> AlignedArgs;
6405   const Expr *AlignedThis = nullptr;
6406   for (const Expr *E : Aligneds) {
6407     E = E->IgnoreParenImpCasts();
6408     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6409       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6410         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6411         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6412             FD->getParamDecl(PVD->getFunctionScopeIndex())
6413                     ->getCanonicalDecl() == CanonPVD) {
6414           // OpenMP  [2.8.1, simd construct, Restrictions]
6415           // A list-item cannot appear in more than one aligned clause.
6416           if (AlignedArgs.count(CanonPVD) > 0) {
6417             Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
6418                 << 1 << getOpenMPClauseName(OMPC_aligned)
6419                 << E->getSourceRange();
6420             Diag(AlignedArgs[CanonPVD]->getExprLoc(),
6421                  diag::note_omp_explicit_dsa)
6422                 << getOpenMPClauseName(OMPC_aligned);
6423             continue;
6424           }
6425           AlignedArgs[CanonPVD] = E;
6426           QualType QTy = PVD->getType()
6427                              .getNonReferenceType()
6428                              .getUnqualifiedType()
6429                              .getCanonicalType();
6430           const Type *Ty = QTy.getTypePtrOrNull();
6431           if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
6432             Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr)
6433                 << QTy << getLangOpts().CPlusPlus << E->getSourceRange();
6434             Diag(PVD->getLocation(), diag::note_previous_decl) << PVD;
6435           }
6436           continue;
6437         }
6438       }
6439     if (isa<CXXThisExpr>(E)) {
6440       if (AlignedThis) {
6441         Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice)
6442             << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange();
6443         Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa)
6444             << getOpenMPClauseName(OMPC_aligned);
6445       }
6446       AlignedThis = E;
6447       continue;
6448     }
6449     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6450         << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6451   }
6452   // The optional parameter of the aligned clause, alignment, must be a constant
6453   // positive integer expression. If no optional parameter is specified,
6454   // implementation-defined default alignments for SIMD instructions on the
6455   // target platforms are assumed.
6456   SmallVector<const Expr *, 4> NewAligns;
6457   for (Expr *E : Alignments) {
6458     ExprResult Align;
6459     if (E)
6460       Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned);
6461     NewAligns.push_back(Align.get());
6462   }
6463   // OpenMP [2.8.2, declare simd construct, Description]
6464   // The linear clause declares one or more list items to be private to a SIMD
6465   // lane and to have a linear relationship with respect to the iteration space
6466   // of a loop.
6467   // The special this pointer can be used as if was one of the arguments to the
6468   // function in any of the linear, aligned, or uniform clauses.
6469   // When a linear-step expression is specified in a linear clause it must be
6470   // either a constant integer expression or an integer-typed parameter that is
6471   // specified in a uniform clause on the directive.
6472   llvm::DenseMap<const Decl *, const Expr *> LinearArgs;
6473   const bool IsUniformedThis = UniformedLinearThis != nullptr;
6474   auto MI = LinModifiers.begin();
6475   for (const Expr *E : Linears) {
6476     auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI);
6477     ++MI;
6478     E = E->IgnoreParenImpCasts();
6479     if (const auto *DRE = dyn_cast<DeclRefExpr>(E))
6480       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6481         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6482         if (FD->getNumParams() > PVD->getFunctionScopeIndex() &&
6483             FD->getParamDecl(PVD->getFunctionScopeIndex())
6484                     ->getCanonicalDecl() == CanonPVD) {
6485           // OpenMP  [2.15.3.7, linear Clause, Restrictions]
6486           // A list-item cannot appear in more than one linear clause.
6487           if (LinearArgs.count(CanonPVD) > 0) {
6488             Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6489                 << getOpenMPClauseName(OMPC_linear)
6490                 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange();
6491             Diag(LinearArgs[CanonPVD]->getExprLoc(),
6492                  diag::note_omp_explicit_dsa)
6493                 << getOpenMPClauseName(OMPC_linear);
6494             continue;
6495           }
6496           // Each argument can appear in at most one uniform or linear clause.
6497           if (UniformedArgs.count(CanonPVD) > 0) {
6498             Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6499                 << getOpenMPClauseName(OMPC_linear)
6500                 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange();
6501             Diag(UniformedArgs[CanonPVD]->getExprLoc(),
6502                  diag::note_omp_explicit_dsa)
6503                 << getOpenMPClauseName(OMPC_uniform);
6504             continue;
6505           }
6506           LinearArgs[CanonPVD] = E;
6507           if (E->isValueDependent() || E->isTypeDependent() ||
6508               E->isInstantiationDependent() ||
6509               E->containsUnexpandedParameterPack())
6510             continue;
6511           (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind,
6512                                       PVD->getOriginalType(),
6513                                       /*IsDeclareSimd=*/true);
6514           continue;
6515         }
6516       }
6517     if (isa<CXXThisExpr>(E)) {
6518       if (UniformedLinearThis) {
6519         Diag(E->getExprLoc(), diag::err_omp_wrong_dsa)
6520             << getOpenMPClauseName(OMPC_linear)
6521             << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear)
6522             << E->getSourceRange();
6523         Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa)
6524             << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform
6525                                                    : OMPC_linear);
6526         continue;
6527       }
6528       UniformedLinearThis = E;
6529       if (E->isValueDependent() || E->isTypeDependent() ||
6530           E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
6531         continue;
6532       (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind,
6533                                   E->getType(), /*IsDeclareSimd=*/true);
6534       continue;
6535     }
6536     Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause)
6537         << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0);
6538   }
6539   Expr *Step = nullptr;
6540   Expr *NewStep = nullptr;
6541   SmallVector<Expr *, 4> NewSteps;
6542   for (Expr *E : Steps) {
6543     // Skip the same step expression, it was checked already.
6544     if (Step == E || !E) {
6545       NewSteps.push_back(E ? NewStep : nullptr);
6546       continue;
6547     }
6548     Step = E;
6549     if (const auto *DRE = dyn_cast<DeclRefExpr>(Step))
6550       if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) {
6551         const VarDecl *CanonPVD = PVD->getCanonicalDecl();
6552         if (UniformedArgs.count(CanonPVD) == 0) {
6553           Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param)
6554               << Step->getSourceRange();
6555         } else if (E->isValueDependent() || E->isTypeDependent() ||
6556                    E->isInstantiationDependent() ||
6557                    E->containsUnexpandedParameterPack() ||
6558                    CanonPVD->getType()->hasIntegerRepresentation()) {
6559           NewSteps.push_back(Step);
6560         } else {
6561           Diag(Step->getExprLoc(), diag::err_omp_expected_int_param)
6562               << Step->getSourceRange();
6563         }
6564         continue;
6565       }
6566     NewStep = Step;
6567     if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
6568         !Step->isInstantiationDependent() &&
6569         !Step->containsUnexpandedParameterPack()) {
6570       NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step)
6571                     .get();
6572       if (NewStep)
6573         NewStep =
6574             VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get();
6575     }
6576     NewSteps.push_back(NewStep);
6577   }
6578   auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(
6579       Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()),
6580       Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(),
6581       const_cast<Expr **>(NewAligns.data()), NewAligns.size(),
6582       const_cast<Expr **>(Linears.data()), Linears.size(),
6583       const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(),
6584       NewSteps.data(), NewSteps.size(), SR);
6585   ADecl->addAttr(NewAttr);
6586   return DG;
6587 }
6588 
setPrototype(Sema & S,FunctionDecl * FD,FunctionDecl * FDWithProto,QualType NewType)6589 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto,
6590                          QualType NewType) {
6591   assert(NewType->isFunctionProtoType() &&
6592          "Expected function type with prototype.");
6593   assert(FD->getType()->isFunctionNoProtoType() &&
6594          "Expected function with type with no prototype.");
6595   assert(FDWithProto->getType()->isFunctionProtoType() &&
6596          "Expected function with prototype.");
6597   // Synthesize parameters with the same types.
6598   FD->setType(NewType);
6599   SmallVector<ParmVarDecl *, 16> Params;
6600   for (const ParmVarDecl *P : FDWithProto->parameters()) {
6601     auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(),
6602                                       SourceLocation(), nullptr, P->getType(),
6603                                       /*TInfo=*/nullptr, SC_None, nullptr);
6604     Param->setScopeInfo(0, Params.size());
6605     Param->setImplicit();
6606     Params.push_back(Param);
6607   }
6608 
6609   FD->setParams(Params);
6610 }
6611 
ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl * D)6612 void Sema::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D) {
6613   if (D->isInvalidDecl())
6614     return;
6615   FunctionDecl *FD = nullptr;
6616   if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
6617     FD = UTemplDecl->getTemplatedDecl();
6618   else
6619     FD = cast<FunctionDecl>(D);
6620   assert(FD && "Expected a function declaration!");
6621 
6622   // If we are intantiating templates we do *not* apply scoped assumptions but
6623   // only global ones. We apply scoped assumption to the template definition
6624   // though.
6625   if (!inTemplateInstantiation()) {
6626     for (AssumptionAttr *AA : OMPAssumeScoped)
6627       FD->addAttr(AA);
6628   }
6629   for (AssumptionAttr *AA : OMPAssumeGlobal)
6630     FD->addAttr(AA);
6631 }
6632 
OMPDeclareVariantScope(OMPTraitInfo & TI)6633 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI)
6634     : TI(&TI), NameSuffix(TI.getMangledName()) {}
6635 
ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope * S,Declarator & D,MultiTemplateParamsArg TemplateParamLists,SmallVectorImpl<FunctionDecl * > & Bases)6636 void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(
6637     Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists,
6638     SmallVectorImpl<FunctionDecl *> &Bases) {
6639   if (!D.getIdentifier())
6640     return;
6641 
6642   OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
6643 
6644   // Template specialization is an extension, check if we do it.
6645   bool IsTemplated = !TemplateParamLists.empty();
6646   if (IsTemplated &
6647       !DVScope.TI->isExtensionActive(
6648           llvm::omp::TraitProperty::implementation_extension_allow_templates))
6649     return;
6650 
6651   IdentifierInfo *BaseII = D.getIdentifier();
6652   LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(),
6653                       LookupOrdinaryName);
6654   LookupParsedName(Lookup, S, &D.getCXXScopeSpec());
6655 
6656   TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
6657   QualType FType = TInfo->getType();
6658 
6659   bool IsConstexpr =
6660       D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr;
6661   bool IsConsteval =
6662       D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Consteval;
6663 
6664   for (auto *Candidate : Lookup) {
6665     auto *CandidateDecl = Candidate->getUnderlyingDecl();
6666     FunctionDecl *UDecl = nullptr;
6667     if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl))
6668       UDecl = cast<FunctionTemplateDecl>(CandidateDecl)->getTemplatedDecl();
6669     else if (!IsTemplated)
6670       UDecl = dyn_cast<FunctionDecl>(CandidateDecl);
6671     if (!UDecl)
6672       continue;
6673 
6674     // Don't specialize constexpr/consteval functions with
6675     // non-constexpr/consteval functions.
6676     if (UDecl->isConstexpr() && !IsConstexpr)
6677       continue;
6678     if (UDecl->isConsteval() && !IsConsteval)
6679       continue;
6680 
6681     QualType UDeclTy = UDecl->getType();
6682     if (!UDeclTy->isDependentType()) {
6683       QualType NewType = Context.mergeFunctionTypes(
6684           FType, UDeclTy, /* OfBlockPointer */ false,
6685           /* Unqualified */ false, /* AllowCXX */ true);
6686       if (NewType.isNull())
6687         continue;
6688     }
6689 
6690     // Found a base!
6691     Bases.push_back(UDecl);
6692   }
6693 
6694   bool UseImplicitBase = !DVScope.TI->isExtensionActive(
6695       llvm::omp::TraitProperty::implementation_extension_disable_implicit_base);
6696   // If no base was found we create a declaration that we use as base.
6697   if (Bases.empty() && UseImplicitBase) {
6698     D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration);
6699     Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists);
6700     BaseD->setImplicit(true);
6701     if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD))
6702       Bases.push_back(BaseTemplD->getTemplatedDecl());
6703     else
6704       Bases.push_back(cast<FunctionDecl>(BaseD));
6705   }
6706 
6707   std::string MangledName;
6708   MangledName += D.getIdentifier()->getName();
6709   MangledName += getOpenMPVariantManglingSeparatorStr();
6710   MangledName += DVScope.NameSuffix;
6711   IdentifierInfo &VariantII = Context.Idents.get(MangledName);
6712 
6713   VariantII.setMangledOpenMPVariantName(true);
6714   D.SetIdentifier(&VariantII, D.getBeginLoc());
6715 }
6716 
ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(Decl * D,SmallVectorImpl<FunctionDecl * > & Bases)6717 void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope(
6718     Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) {
6719   // Do not mark function as is used to prevent its emission if this is the
6720   // only place where it is used.
6721   EnterExpressionEvaluationContext Unevaluated(
6722       *this, Sema::ExpressionEvaluationContext::Unevaluated);
6723 
6724   FunctionDecl *FD = nullptr;
6725   if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D))
6726     FD = UTemplDecl->getTemplatedDecl();
6727   else
6728     FD = cast<FunctionDecl>(D);
6729   auto *VariantFuncRef = DeclRefExpr::Create(
6730       Context, NestedNameSpecifierLoc(), SourceLocation(), FD,
6731       /* RefersToEnclosingVariableOrCapture */ false,
6732       /* NameLoc */ FD->getLocation(), FD->getType(),
6733       ExprValueKind::VK_PRValue);
6734 
6735   OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back();
6736   auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit(
6737       Context, VariantFuncRef, DVScope.TI);
6738   for (FunctionDecl *BaseFD : Bases)
6739     BaseFD->addAttr(OMPDeclareVariantA);
6740 }
6741 
ActOnOpenMPCall(ExprResult Call,Scope * Scope,SourceLocation LParenLoc,MultiExprArg ArgExprs,SourceLocation RParenLoc,Expr * ExecConfig)6742 ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope,
6743                                  SourceLocation LParenLoc,
6744                                  MultiExprArg ArgExprs,
6745                                  SourceLocation RParenLoc, Expr *ExecConfig) {
6746   // The common case is a regular call we do not want to specialize at all. Try
6747   // to make that case fast by bailing early.
6748   CallExpr *CE = dyn_cast<CallExpr>(Call.get());
6749   if (!CE)
6750     return Call;
6751 
6752   FunctionDecl *CalleeFnDecl = CE->getDirectCallee();
6753   if (!CalleeFnDecl)
6754     return Call;
6755 
6756   if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>())
6757     return Call;
6758 
6759   ASTContext &Context = getASTContext();
6760   std::function<void(StringRef)> DiagUnknownTrait = [this,
6761                                                      CE](StringRef ISATrait) {
6762     // TODO Track the selector locations in a way that is accessible here to
6763     // improve the diagnostic location.
6764     Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait)
6765         << ISATrait;
6766   };
6767   TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait),
6768                           getCurFunctionDecl());
6769 
6770   QualType CalleeFnType = CalleeFnDecl->getType();
6771 
6772   SmallVector<Expr *, 4> Exprs;
6773   SmallVector<VariantMatchInfo, 4> VMIs;
6774   while (CalleeFnDecl) {
6775     for (OMPDeclareVariantAttr *A :
6776          CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) {
6777       Expr *VariantRef = A->getVariantFuncRef();
6778 
6779       VariantMatchInfo VMI;
6780       OMPTraitInfo &TI = A->getTraitInfo();
6781       TI.getAsVariantMatchInfo(Context, VMI);
6782       if (!isVariantApplicableInContext(VMI, OMPCtx,
6783                                         /* DeviceSetOnly */ false))
6784         continue;
6785 
6786       VMIs.push_back(VMI);
6787       Exprs.push_back(VariantRef);
6788     }
6789 
6790     CalleeFnDecl = CalleeFnDecl->getPreviousDecl();
6791   }
6792 
6793   ExprResult NewCall;
6794   do {
6795     int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx);
6796     if (BestIdx < 0)
6797       return Call;
6798     Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]);
6799     Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl();
6800 
6801     {
6802       // Try to build a (member) call expression for the current best applicable
6803       // variant expression. We allow this to fail in which case we continue
6804       // with the next best variant expression. The fail case is part of the
6805       // implementation defined behavior in the OpenMP standard when it talks
6806       // about what differences in the function prototypes: "Any differences
6807       // that the specific OpenMP context requires in the prototype of the
6808       // variant from the base function prototype are implementation defined."
6809       // This wording is there to allow the specialized variant to have a
6810       // different type than the base function. This is intended and OK but if
6811       // we cannot create a call the difference is not in the "implementation
6812       // defined range" we allow.
6813       Sema::TentativeAnalysisScope Trap(*this);
6814 
6815       if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) {
6816         auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE);
6817         BestExpr = MemberExpr::CreateImplicit(
6818             Context, MemberCall->getImplicitObjectArgument(),
6819             /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy,
6820             MemberCall->getValueKind(), MemberCall->getObjectKind());
6821       }
6822       NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc,
6823                               ExecConfig);
6824       if (NewCall.isUsable()) {
6825         if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) {
6826           FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee();
6827           QualType NewType = Context.mergeFunctionTypes(
6828               CalleeFnType, NewCalleeFnDecl->getType(),
6829               /* OfBlockPointer */ false,
6830               /* Unqualified */ false, /* AllowCXX */ true);
6831           if (!NewType.isNull())
6832             break;
6833           // Don't use the call if the function type was not compatible.
6834           NewCall = nullptr;
6835         }
6836       }
6837     }
6838 
6839     VMIs.erase(VMIs.begin() + BestIdx);
6840     Exprs.erase(Exprs.begin() + BestIdx);
6841   } while (!VMIs.empty());
6842 
6843   if (!NewCall.isUsable())
6844     return Call;
6845   return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0);
6846 }
6847 
6848 Optional<std::pair<FunctionDecl *, Expr *>>
checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,Expr * VariantRef,OMPTraitInfo & TI,SourceRange SR)6849 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG,
6850                                         Expr *VariantRef, OMPTraitInfo &TI,
6851                                         SourceRange SR) {
6852   if (!DG || DG.get().isNull())
6853     return None;
6854 
6855   const int VariantId = 1;
6856   // Must be applied only to single decl.
6857   if (!DG.get().isSingleDecl()) {
6858     Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant)
6859         << VariantId << SR;
6860     return None;
6861   }
6862   Decl *ADecl = DG.get().getSingleDecl();
6863   if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl))
6864     ADecl = FTD->getTemplatedDecl();
6865 
6866   // Decl must be a function.
6867   auto *FD = dyn_cast<FunctionDecl>(ADecl);
6868   if (!FD) {
6869     Diag(ADecl->getLocation(), diag::err_omp_function_expected)
6870         << VariantId << SR;
6871     return None;
6872   }
6873 
6874   auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) {
6875     return FD->hasAttrs() &&
6876            (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() ||
6877             FD->hasAttr<TargetAttr>());
6878   };
6879   // OpenMP is not compatible with CPU-specific attributes.
6880   if (HasMultiVersionAttributes(FD)) {
6881     Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes)
6882         << SR;
6883     return None;
6884   }
6885 
6886   // Allow #pragma omp declare variant only if the function is not used.
6887   if (FD->isUsed(false))
6888     Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used)
6889         << FD->getLocation();
6890 
6891   // Check if the function was emitted already.
6892   const FunctionDecl *Definition;
6893   if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) &&
6894       (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition)))
6895     Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted)
6896         << FD->getLocation();
6897 
6898   // The VariantRef must point to function.
6899   if (!VariantRef) {
6900     Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId;
6901     return None;
6902   }
6903 
6904   auto ShouldDelayChecks = [](Expr *&E, bool) {
6905     return E && (E->isTypeDependent() || E->isValueDependent() ||
6906                  E->containsUnexpandedParameterPack() ||
6907                  E->isInstantiationDependent());
6908   };
6909   // Do not check templates, wait until instantiation.
6910   if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) ||
6911       TI.anyScoreOrCondition(ShouldDelayChecks))
6912     return std::make_pair(FD, VariantRef);
6913 
6914   // Deal with non-constant score and user condition expressions.
6915   auto HandleNonConstantScoresAndConditions = [this](Expr *&E,
6916                                                      bool IsScore) -> bool {
6917     if (!E || E->isIntegerConstantExpr(Context))
6918       return false;
6919 
6920     if (IsScore) {
6921       // We warn on non-constant scores and pretend they were not present.
6922       Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant)
6923           << E;
6924       E = nullptr;
6925     } else {
6926       // We could replace a non-constant user condition with "false" but we
6927       // will soon need to handle these anyway for the dynamic version of
6928       // OpenMP context selectors.
6929       Diag(E->getExprLoc(),
6930            diag::err_omp_declare_variant_user_condition_not_constant)
6931           << E;
6932     }
6933     return true;
6934   };
6935   if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions))
6936     return None;
6937 
6938   // Convert VariantRef expression to the type of the original function to
6939   // resolve possible conflicts.
6940   ExprResult VariantRefCast = VariantRef;
6941   if (LangOpts.CPlusPlus) {
6942     QualType FnPtrType;
6943     auto *Method = dyn_cast<CXXMethodDecl>(FD);
6944     if (Method && !Method->isStatic()) {
6945       const Type *ClassType =
6946           Context.getTypeDeclType(Method->getParent()).getTypePtr();
6947       FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType);
6948       ExprResult ER;
6949       {
6950         // Build adrr_of unary op to correctly handle type checks for member
6951         // functions.
6952         Sema::TentativeAnalysisScope Trap(*this);
6953         ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf,
6954                                   VariantRef);
6955       }
6956       if (!ER.isUsable()) {
6957         Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6958             << VariantId << VariantRef->getSourceRange();
6959         return None;
6960       }
6961       VariantRef = ER.get();
6962     } else {
6963       FnPtrType = Context.getPointerType(FD->getType());
6964     }
6965     QualType VarianPtrType = Context.getPointerType(VariantRef->getType());
6966     if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) {
6967       ImplicitConversionSequence ICS = TryImplicitConversion(
6968           VariantRef, FnPtrType.getUnqualifiedType(),
6969           /*SuppressUserConversions=*/false, AllowedExplicit::None,
6970           /*InOverloadResolution=*/false,
6971           /*CStyle=*/false,
6972           /*AllowObjCWritebackConversion=*/false);
6973       if (ICS.isFailure()) {
6974         Diag(VariantRef->getExprLoc(),
6975              diag::err_omp_declare_variant_incompat_types)
6976             << VariantRef->getType()
6977             << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType())
6978             << VariantRef->getSourceRange();
6979         return None;
6980       }
6981       VariantRefCast = PerformImplicitConversion(
6982           VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting);
6983       if (!VariantRefCast.isUsable())
6984         return None;
6985     }
6986     // Drop previously built artificial addr_of unary op for member functions.
6987     if (Method && !Method->isStatic()) {
6988       Expr *PossibleAddrOfVariantRef = VariantRefCast.get();
6989       if (auto *UO = dyn_cast<UnaryOperator>(
6990               PossibleAddrOfVariantRef->IgnoreImplicit()))
6991         VariantRefCast = UO->getSubExpr();
6992     }
6993   }
6994 
6995   ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get());
6996   if (!ER.isUsable() ||
6997       !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) {
6998     Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
6999         << VariantId << VariantRef->getSourceRange();
7000     return None;
7001   }
7002 
7003   // The VariantRef must point to function.
7004   auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts());
7005   if (!DRE) {
7006     Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7007         << VariantId << VariantRef->getSourceRange();
7008     return None;
7009   }
7010   auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl());
7011   if (!NewFD) {
7012     Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected)
7013         << VariantId << VariantRef->getSourceRange();
7014     return None;
7015   }
7016 
7017   // Check if function types are compatible in C.
7018   if (!LangOpts.CPlusPlus) {
7019     QualType NewType =
7020         Context.mergeFunctionTypes(FD->getType(), NewFD->getType());
7021     if (NewType.isNull()) {
7022       Diag(VariantRef->getExprLoc(),
7023            diag::err_omp_declare_variant_incompat_types)
7024           << NewFD->getType() << FD->getType() << VariantRef->getSourceRange();
7025       return None;
7026     }
7027     if (NewType->isFunctionProtoType()) {
7028       if (FD->getType()->isFunctionNoProtoType())
7029         setPrototype(*this, FD, NewFD, NewType);
7030       else if (NewFD->getType()->isFunctionNoProtoType())
7031         setPrototype(*this, NewFD, FD, NewType);
7032     }
7033   }
7034 
7035   // Check if variant function is not marked with declare variant directive.
7036   if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) {
7037     Diag(VariantRef->getExprLoc(),
7038          diag::warn_omp_declare_variant_marked_as_declare_variant)
7039         << VariantRef->getSourceRange();
7040     SourceRange SR =
7041         NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange();
7042     Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR;
7043     return None;
7044   }
7045 
7046   enum DoesntSupport {
7047     VirtFuncs = 1,
7048     Constructors = 3,
7049     Destructors = 4,
7050     DeletedFuncs = 5,
7051     DefaultedFuncs = 6,
7052     ConstexprFuncs = 7,
7053     ConstevalFuncs = 8,
7054   };
7055   if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) {
7056     if (CXXFD->isVirtual()) {
7057       Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7058           << VirtFuncs;
7059       return None;
7060     }
7061 
7062     if (isa<CXXConstructorDecl>(FD)) {
7063       Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7064           << Constructors;
7065       return None;
7066     }
7067 
7068     if (isa<CXXDestructorDecl>(FD)) {
7069       Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7070           << Destructors;
7071       return None;
7072     }
7073   }
7074 
7075   if (FD->isDeleted()) {
7076     Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7077         << DeletedFuncs;
7078     return None;
7079   }
7080 
7081   if (FD->isDefaulted()) {
7082     Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7083         << DefaultedFuncs;
7084     return None;
7085   }
7086 
7087   if (FD->isConstexpr()) {
7088     Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support)
7089         << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs);
7090     return None;
7091   }
7092 
7093   // Check general compatibility.
7094   if (areMultiversionVariantFunctionsCompatible(
7095           FD, NewFD, PartialDiagnostic::NullDiagnostic(),
7096           PartialDiagnosticAt(SourceLocation(),
7097                               PartialDiagnostic::NullDiagnostic()),
7098           PartialDiagnosticAt(
7099               VariantRef->getExprLoc(),
7100               PDiag(diag::err_omp_declare_variant_doesnt_support)),
7101           PartialDiagnosticAt(VariantRef->getExprLoc(),
7102                               PDiag(diag::err_omp_declare_variant_diff)
7103                                   << FD->getLocation()),
7104           /*TemplatesSupported=*/true, /*ConstexprSupported=*/false,
7105           /*CLinkageMayDiffer=*/true))
7106     return None;
7107   return std::make_pair(FD, cast<Expr>(DRE));
7108 }
7109 
ActOnOpenMPDeclareVariantDirective(FunctionDecl * FD,Expr * VariantRef,OMPTraitInfo & TI,SourceRange SR)7110 void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD,
7111                                               Expr *VariantRef,
7112                                               OMPTraitInfo &TI,
7113                                               SourceRange SR) {
7114   auto *NewAttr =
7115       OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, &TI, SR);
7116   FD->addAttr(NewAttr);
7117 }
7118 
ActOnOpenMPParallelDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)7119 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses,
7120                                               Stmt *AStmt,
7121                                               SourceLocation StartLoc,
7122                                               SourceLocation EndLoc) {
7123   if (!AStmt)
7124     return StmtError();
7125 
7126   auto *CS = cast<CapturedStmt>(AStmt);
7127   // 1.2.2 OpenMP Language Terminology
7128   // Structured block - An executable statement with a single entry at the
7129   // top and a single exit at the bottom.
7130   // The point of exit cannot be a branch out of the structured block.
7131   // longjmp() and throw() must not violate the entry/exit criteria.
7132   CS->getCapturedDecl()->setNothrow();
7133 
7134   setFunctionHasBranchProtectedScope();
7135 
7136   return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
7137                                       DSAStack->getTaskgroupReductionRef(),
7138                                       DSAStack->isCancelRegion());
7139 }
7140 
7141 namespace {
7142 /// Iteration space of a single for loop.
7143 struct LoopIterationSpace final {
7144   /// True if the condition operator is the strict compare operator (<, > or
7145   /// !=).
7146   bool IsStrictCompare = false;
7147   /// Condition of the loop.
7148   Expr *PreCond = nullptr;
7149   /// This expression calculates the number of iterations in the loop.
7150   /// It is always possible to calculate it before starting the loop.
7151   Expr *NumIterations = nullptr;
7152   /// The loop counter variable.
7153   Expr *CounterVar = nullptr;
7154   /// Private loop counter variable.
7155   Expr *PrivateCounterVar = nullptr;
7156   /// This is initializer for the initial value of #CounterVar.
7157   Expr *CounterInit = nullptr;
7158   /// This is step for the #CounterVar used to generate its update:
7159   /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration.
7160   Expr *CounterStep = nullptr;
7161   /// Should step be subtracted?
7162   bool Subtract = false;
7163   /// Source range of the loop init.
7164   SourceRange InitSrcRange;
7165   /// Source range of the loop condition.
7166   SourceRange CondSrcRange;
7167   /// Source range of the loop increment.
7168   SourceRange IncSrcRange;
7169   /// Minimum value that can have the loop control variable. Used to support
7170   /// non-rectangular loops. Applied only for LCV with the non-iterator types,
7171   /// since only such variables can be used in non-loop invariant expressions.
7172   Expr *MinValue = nullptr;
7173   /// Maximum value that can have the loop control variable. Used to support
7174   /// non-rectangular loops. Applied only for LCV with the non-iterator type,
7175   /// since only such variables can be used in non-loop invariant expressions.
7176   Expr *MaxValue = nullptr;
7177   /// true, if the lower bound depends on the outer loop control var.
7178   bool IsNonRectangularLB = false;
7179   /// true, if the upper bound depends on the outer loop control var.
7180   bool IsNonRectangularUB = false;
7181   /// Index of the loop this loop depends on and forms non-rectangular loop
7182   /// nest.
7183   unsigned LoopDependentIdx = 0;
7184   /// Final condition for the non-rectangular loop nest support. It is used to
7185   /// check that the number of iterations for this particular counter must be
7186   /// finished.
7187   Expr *FinalCondition = nullptr;
7188 };
7189 
7190 /// Helper class for checking canonical form of the OpenMP loops and
7191 /// extracting iteration space of each loop in the loop nest, that will be used
7192 /// for IR generation.
7193 class OpenMPIterationSpaceChecker {
7194   /// Reference to Sema.
7195   Sema &SemaRef;
7196   /// Does the loop associated directive support non-rectangular loops?
7197   bool SupportsNonRectangular;
7198   /// Data-sharing stack.
7199   DSAStackTy &Stack;
7200   /// A location for diagnostics (when there is no some better location).
7201   SourceLocation DefaultLoc;
7202   /// A location for diagnostics (when increment is not compatible).
7203   SourceLocation ConditionLoc;
7204   /// A source location for referring to loop init later.
7205   SourceRange InitSrcRange;
7206   /// A source location for referring to condition later.
7207   SourceRange ConditionSrcRange;
7208   /// A source location for referring to increment later.
7209   SourceRange IncrementSrcRange;
7210   /// Loop variable.
7211   ValueDecl *LCDecl = nullptr;
7212   /// Reference to loop variable.
7213   Expr *LCRef = nullptr;
7214   /// Lower bound (initializer for the var).
7215   Expr *LB = nullptr;
7216   /// Upper bound.
7217   Expr *UB = nullptr;
7218   /// Loop step (increment).
7219   Expr *Step = nullptr;
7220   /// This flag is true when condition is one of:
7221   ///   Var <  UB
7222   ///   Var <= UB
7223   ///   UB  >  Var
7224   ///   UB  >= Var
7225   /// This will have no value when the condition is !=
7226   llvm::Optional<bool> TestIsLessOp;
7227   /// This flag is true when condition is strict ( < or > ).
7228   bool TestIsStrictOp = false;
7229   /// This flag is true when step is subtracted on each iteration.
7230   bool SubtractStep = false;
7231   /// The outer loop counter this loop depends on (if any).
7232   const ValueDecl *DepDecl = nullptr;
7233   /// Contains number of loop (starts from 1) on which loop counter init
7234   /// expression of this loop depends on.
7235   Optional<unsigned> InitDependOnLC;
7236   /// Contains number of loop (starts from 1) on which loop counter condition
7237   /// expression of this loop depends on.
7238   Optional<unsigned> CondDependOnLC;
7239   /// Checks if the provide statement depends on the loop counter.
7240   Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer);
7241   /// Original condition required for checking of the exit condition for
7242   /// non-rectangular loop.
7243   Expr *Condition = nullptr;
7244 
7245 public:
OpenMPIterationSpaceChecker(Sema & SemaRef,bool SupportsNonRectangular,DSAStackTy & Stack,SourceLocation DefaultLoc)7246   OpenMPIterationSpaceChecker(Sema &SemaRef, bool SupportsNonRectangular,
7247                               DSAStackTy &Stack, SourceLocation DefaultLoc)
7248       : SemaRef(SemaRef), SupportsNonRectangular(SupportsNonRectangular),
7249         Stack(Stack), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {}
7250   /// Check init-expr for canonical loop form and save loop counter
7251   /// variable - #Var and its initialization value - #LB.
7252   bool checkAndSetInit(Stmt *S, bool EmitDiags = true);
7253   /// Check test-expr for canonical form, save upper-bound (#UB), flags
7254   /// for less/greater and for strict/non-strict comparison.
7255   bool checkAndSetCond(Expr *S);
7256   /// Check incr-expr for canonical loop form and return true if it
7257   /// does not conform, otherwise save loop step (#Step).
7258   bool checkAndSetInc(Expr *S);
7259   /// Return the loop counter variable.
getLoopDecl() const7260   ValueDecl *getLoopDecl() const { return LCDecl; }
7261   /// Return the reference expression to loop counter variable.
getLoopDeclRefExpr() const7262   Expr *getLoopDeclRefExpr() const { return LCRef; }
7263   /// Source range of the loop init.
getInitSrcRange() const7264   SourceRange getInitSrcRange() const { return InitSrcRange; }
7265   /// Source range of the loop condition.
getConditionSrcRange() const7266   SourceRange getConditionSrcRange() const { return ConditionSrcRange; }
7267   /// Source range of the loop increment.
getIncrementSrcRange() const7268   SourceRange getIncrementSrcRange() const { return IncrementSrcRange; }
7269   /// True if the step should be subtracted.
shouldSubtractStep() const7270   bool shouldSubtractStep() const { return SubtractStep; }
7271   /// True, if the compare operator is strict (<, > or !=).
isStrictTestOp() const7272   bool isStrictTestOp() const { return TestIsStrictOp; }
7273   /// Build the expression to calculate the number of iterations.
7274   Expr *buildNumIterations(
7275       Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
7276       llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7277   /// Build the precondition expression for the loops.
7278   Expr *
7279   buildPreCond(Scope *S, Expr *Cond,
7280                llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7281   /// Build reference expression to the counter be used for codegen.
7282   DeclRefExpr *
7283   buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7284                   DSAStackTy &DSA) const;
7285   /// Build reference expression to the private counter be used for
7286   /// codegen.
7287   Expr *buildPrivateCounterVar() const;
7288   /// Build initialization of the counter be used for codegen.
7289   Expr *buildCounterInit() const;
7290   /// Build step of the counter be used for codegen.
7291   Expr *buildCounterStep() const;
7292   /// Build loop data with counter value for depend clauses in ordered
7293   /// directives.
7294   Expr *
7295   buildOrderedLoopData(Scope *S, Expr *Counter,
7296                        llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
7297                        SourceLocation Loc, Expr *Inc = nullptr,
7298                        OverloadedOperatorKind OOK = OO_Amp);
7299   /// Builds the minimum value for the loop counter.
7300   std::pair<Expr *, Expr *> buildMinMaxValues(
7301       Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const;
7302   /// Builds final condition for the non-rectangular loops.
7303   Expr *buildFinalCondition(Scope *S) const;
7304   /// Return true if any expression is dependent.
7305   bool dependent() const;
7306   /// Returns true if the initializer forms non-rectangular loop.
doesInitDependOnLC() const7307   bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); }
7308   /// Returns true if the condition forms non-rectangular loop.
doesCondDependOnLC() const7309   bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); }
7310   /// Returns index of the loop we depend on (starting from 1), or 0 otherwise.
getLoopDependentIdx() const7311   unsigned getLoopDependentIdx() const {
7312     return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0));
7313   }
7314 
7315 private:
7316   /// Check the right-hand side of an assignment in the increment
7317   /// expression.
7318   bool checkAndSetIncRHS(Expr *RHS);
7319   /// Helper to set loop counter variable and its initializer.
7320   bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB,
7321                       bool EmitDiags);
7322   /// Helper to set upper bound.
7323   bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp,
7324              SourceRange SR, SourceLocation SL);
7325   /// Helper to set loop increment.
7326   bool setStep(Expr *NewStep, bool Subtract);
7327 };
7328 
dependent() const7329 bool OpenMPIterationSpaceChecker::dependent() const {
7330   if (!LCDecl) {
7331     assert(!LB && !UB && !Step);
7332     return false;
7333   }
7334   return LCDecl->getType()->isDependentType() ||
7335          (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) ||
7336          (Step && Step->isValueDependent());
7337 }
7338 
setLCDeclAndLB(ValueDecl * NewLCDecl,Expr * NewLCRefExpr,Expr * NewLB,bool EmitDiags)7339 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl,
7340                                                  Expr *NewLCRefExpr,
7341                                                  Expr *NewLB, bool EmitDiags) {
7342   // State consistency checking to ensure correct usage.
7343   assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr &&
7344          UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
7345   if (!NewLCDecl || !NewLB)
7346     return true;
7347   LCDecl = getCanonicalDecl(NewLCDecl);
7348   LCRef = NewLCRefExpr;
7349   if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB))
7350     if (const CXXConstructorDecl *Ctor = CE->getConstructor())
7351       if ((Ctor->isCopyOrMoveConstructor() ||
7352            Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
7353           CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
7354         NewLB = CE->getArg(0)->IgnoreParenImpCasts();
7355   LB = NewLB;
7356   if (EmitDiags)
7357     InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true);
7358   return false;
7359 }
7360 
setUB(Expr * NewUB,llvm::Optional<bool> LessOp,bool StrictOp,SourceRange SR,SourceLocation SL)7361 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB,
7362                                         llvm::Optional<bool> LessOp,
7363                                         bool StrictOp, SourceRange SR,
7364                                         SourceLocation SL) {
7365   // State consistency checking to ensure correct usage.
7366   assert(LCDecl != nullptr && LB != nullptr && UB == nullptr &&
7367          Step == nullptr && !TestIsLessOp && !TestIsStrictOp);
7368   if (!NewUB)
7369     return true;
7370   UB = NewUB;
7371   if (LessOp)
7372     TestIsLessOp = LessOp;
7373   TestIsStrictOp = StrictOp;
7374   ConditionSrcRange = SR;
7375   ConditionLoc = SL;
7376   CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false);
7377   return false;
7378 }
7379 
setStep(Expr * NewStep,bool Subtract)7380 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) {
7381   // State consistency checking to ensure correct usage.
7382   assert(LCDecl != nullptr && LB != nullptr && Step == nullptr);
7383   if (!NewStep)
7384     return true;
7385   if (!NewStep->isValueDependent()) {
7386     // Check that the step is integer expression.
7387     SourceLocation StepLoc = NewStep->getBeginLoc();
7388     ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion(
7389         StepLoc, getExprAsWritten(NewStep));
7390     if (Val.isInvalid())
7391       return true;
7392     NewStep = Val.get();
7393 
7394     // OpenMP [2.6, Canonical Loop Form, Restrictions]
7395     //  If test-expr is of form var relational-op b and relational-op is < or
7396     //  <= then incr-expr must cause var to increase on each iteration of the
7397     //  loop. If test-expr is of form var relational-op b and relational-op is
7398     //  > or >= then incr-expr must cause var to decrease on each iteration of
7399     //  the loop.
7400     //  If test-expr is of form b relational-op var and relational-op is < or
7401     //  <= then incr-expr must cause var to decrease on each iteration of the
7402     //  loop. If test-expr is of form b relational-op var and relational-op is
7403     //  > or >= then incr-expr must cause var to increase on each iteration of
7404     //  the loop.
7405     Optional<llvm::APSInt> Result =
7406         NewStep->getIntegerConstantExpr(SemaRef.Context);
7407     bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation();
7408     bool IsConstNeg =
7409         Result && Result->isSigned() && (Subtract != Result->isNegative());
7410     bool IsConstPos =
7411         Result && Result->isSigned() && (Subtract == Result->isNegative());
7412     bool IsConstZero = Result && !Result->getBoolValue();
7413 
7414     // != with increment is treated as <; != with decrement is treated as >
7415     if (!TestIsLessOp.hasValue())
7416       TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract);
7417     if (UB && (IsConstZero ||
7418                (TestIsLessOp.getValue() ?
7419                   (IsConstNeg || (IsUnsigned && Subtract)) :
7420                   (IsConstPos || (IsUnsigned && !Subtract))))) {
7421       SemaRef.Diag(NewStep->getExprLoc(),
7422                    diag::err_omp_loop_incr_not_compatible)
7423           << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange();
7424       SemaRef.Diag(ConditionLoc,
7425                    diag::note_omp_loop_cond_requres_compatible_incr)
7426           << TestIsLessOp.getValue() << ConditionSrcRange;
7427       return true;
7428     }
7429     if (TestIsLessOp.getValue() == Subtract) {
7430       NewStep =
7431           SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep)
7432               .get();
7433       Subtract = !Subtract;
7434     }
7435   }
7436 
7437   Step = NewStep;
7438   SubtractStep = Subtract;
7439   return false;
7440 }
7441 
7442 namespace {
7443 /// Checker for the non-rectangular loops. Checks if the initializer or
7444 /// condition expression references loop counter variable.
7445 class LoopCounterRefChecker final
7446     : public ConstStmtVisitor<LoopCounterRefChecker, bool> {
7447   Sema &SemaRef;
7448   DSAStackTy &Stack;
7449   const ValueDecl *CurLCDecl = nullptr;
7450   const ValueDecl *DepDecl = nullptr;
7451   const ValueDecl *PrevDepDecl = nullptr;
7452   bool IsInitializer = true;
7453   bool SupportsNonRectangular;
7454   unsigned BaseLoopId = 0;
checkDecl(const Expr * E,const ValueDecl * VD)7455   bool checkDecl(const Expr *E, const ValueDecl *VD) {
7456     if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) {
7457       SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter)
7458           << (IsInitializer ? 0 : 1);
7459       return false;
7460     }
7461     const auto &&Data = Stack.isLoopControlVariable(VD);
7462     // OpenMP, 2.9.1 Canonical Loop Form, Restrictions.
7463     // The type of the loop iterator on which we depend may not have a random
7464     // access iterator type.
7465     if (Data.first && VD->getType()->isRecordType()) {
7466       SmallString<128> Name;
7467       llvm::raw_svector_ostream OS(Name);
7468       VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
7469                                /*Qualified=*/true);
7470       SemaRef.Diag(E->getExprLoc(),
7471                    diag::err_omp_wrong_dependency_iterator_type)
7472           << OS.str();
7473       SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD;
7474       return false;
7475     }
7476     if (Data.first && !SupportsNonRectangular) {
7477       SemaRef.Diag(E->getExprLoc(), diag::err_omp_invariant_dependency);
7478       return false;
7479     }
7480     if (Data.first &&
7481         (DepDecl || (PrevDepDecl &&
7482                      getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) {
7483       if (!DepDecl && PrevDepDecl)
7484         DepDecl = PrevDepDecl;
7485       SmallString<128> Name;
7486       llvm::raw_svector_ostream OS(Name);
7487       DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(),
7488                                     /*Qualified=*/true);
7489       SemaRef.Diag(E->getExprLoc(),
7490                    diag::err_omp_invariant_or_linear_dependency)
7491           << OS.str();
7492       return false;
7493     }
7494     if (Data.first) {
7495       DepDecl = VD;
7496       BaseLoopId = Data.first;
7497     }
7498     return Data.first;
7499   }
7500 
7501 public:
VisitDeclRefExpr(const DeclRefExpr * E)7502   bool VisitDeclRefExpr(const DeclRefExpr *E) {
7503     const ValueDecl *VD = E->getDecl();
7504     if (isa<VarDecl>(VD))
7505       return checkDecl(E, VD);
7506     return false;
7507   }
VisitMemberExpr(const MemberExpr * E)7508   bool VisitMemberExpr(const MemberExpr *E) {
7509     if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) {
7510       const ValueDecl *VD = E->getMemberDecl();
7511       if (isa<VarDecl>(VD) || isa<FieldDecl>(VD))
7512         return checkDecl(E, VD);
7513     }
7514     return false;
7515   }
VisitStmt(const Stmt * S)7516   bool VisitStmt(const Stmt *S) {
7517     bool Res = false;
7518     for (const Stmt *Child : S->children())
7519       Res = (Child && Visit(Child)) || Res;
7520     return Res;
7521   }
LoopCounterRefChecker(Sema & SemaRef,DSAStackTy & Stack,const ValueDecl * CurLCDecl,bool IsInitializer,const ValueDecl * PrevDepDecl=nullptr,bool SupportsNonRectangular=true)7522   explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack,
7523                                  const ValueDecl *CurLCDecl, bool IsInitializer,
7524                                  const ValueDecl *PrevDepDecl = nullptr,
7525                                  bool SupportsNonRectangular = true)
7526       : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl),
7527         PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer),
7528         SupportsNonRectangular(SupportsNonRectangular) {}
getBaseLoopId() const7529   unsigned getBaseLoopId() const {
7530     assert(CurLCDecl && "Expected loop dependency.");
7531     return BaseLoopId;
7532   }
getDepDecl() const7533   const ValueDecl *getDepDecl() const {
7534     assert(CurLCDecl && "Expected loop dependency.");
7535     return DepDecl;
7536   }
7537 };
7538 } // namespace
7539 
7540 Optional<unsigned>
doesDependOnLoopCounter(const Stmt * S,bool IsInitializer)7541 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S,
7542                                                      bool IsInitializer) {
7543   // Check for the non-rectangular loops.
7544   LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer,
7545                                         DepDecl, SupportsNonRectangular);
7546   if (LoopStmtChecker.Visit(S)) {
7547     DepDecl = LoopStmtChecker.getDepDecl();
7548     return LoopStmtChecker.getBaseLoopId();
7549   }
7550   return llvm::None;
7551 }
7552 
checkAndSetInit(Stmt * S,bool EmitDiags)7553 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) {
7554   // Check init-expr for canonical loop form and save loop counter
7555   // variable - #Var and its initialization value - #LB.
7556   // OpenMP [2.6] Canonical loop form. init-expr may be one of the following:
7557   //   var = lb
7558   //   integer-type var = lb
7559   //   random-access-iterator-type var = lb
7560   //   pointer-type var = lb
7561   //
7562   if (!S) {
7563     if (EmitDiags) {
7564       SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init);
7565     }
7566     return true;
7567   }
7568   if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
7569     if (!ExprTemp->cleanupsHaveSideEffects())
7570       S = ExprTemp->getSubExpr();
7571 
7572   InitSrcRange = S->getSourceRange();
7573   if (Expr *E = dyn_cast<Expr>(S))
7574     S = E->IgnoreParens();
7575   if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7576     if (BO->getOpcode() == BO_Assign) {
7577       Expr *LHS = BO->getLHS()->IgnoreParens();
7578       if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
7579         if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
7580           if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
7581             return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7582                                   EmitDiags);
7583         return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags);
7584       }
7585       if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
7586         if (ME->isArrow() &&
7587             isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7588           return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7589                                 EmitDiags);
7590       }
7591     }
7592   } else if (auto *DS = dyn_cast<DeclStmt>(S)) {
7593     if (DS->isSingleDecl()) {
7594       if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) {
7595         if (Var->hasInit() && !Var->getType()->isReferenceType()) {
7596           // Accept non-canonical init form here but emit ext. warning.
7597           if (Var->getInitStyle() != VarDecl::CInit && EmitDiags)
7598             SemaRef.Diag(S->getBeginLoc(),
7599                          diag::ext_omp_loop_not_canonical_init)
7600                 << S->getSourceRange();
7601           return setLCDeclAndLB(
7602               Var,
7603               buildDeclRefExpr(SemaRef, Var,
7604                                Var->getType().getNonReferenceType(),
7605                                DS->getBeginLoc()),
7606               Var->getInit(), EmitDiags);
7607         }
7608       }
7609     }
7610   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7611     if (CE->getOperator() == OO_Equal) {
7612       Expr *LHS = CE->getArg(0);
7613       if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) {
7614         if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl()))
7615           if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit())))
7616             return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7617                                   EmitDiags);
7618         return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags);
7619       }
7620       if (auto *ME = dyn_cast<MemberExpr>(LHS)) {
7621         if (ME->isArrow() &&
7622             isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7623           return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(),
7624                                 EmitDiags);
7625       }
7626     }
7627   }
7628 
7629   if (dependent() || SemaRef.CurContext->isDependentContext())
7630     return false;
7631   if (EmitDiags) {
7632     SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init)
7633         << S->getSourceRange();
7634   }
7635   return true;
7636 }
7637 
7638 /// Ignore parenthesizes, implicit casts, copy constructor and return the
7639 /// variable (which may be the loop variable) if possible.
getInitLCDecl(const Expr * E)7640 static const ValueDecl *getInitLCDecl(const Expr *E) {
7641   if (!E)
7642     return nullptr;
7643   E = getExprAsWritten(E);
7644   if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E))
7645     if (const CXXConstructorDecl *Ctor = CE->getConstructor())
7646       if ((Ctor->isCopyOrMoveConstructor() ||
7647            Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) &&
7648           CE->getNumArgs() > 0 && CE->getArg(0) != nullptr)
7649         E = CE->getArg(0)->IgnoreParenImpCasts();
7650   if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) {
7651     if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
7652       return getCanonicalDecl(VD);
7653   }
7654   if (const auto *ME = dyn_cast_or_null<MemberExpr>(E))
7655     if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()))
7656       return getCanonicalDecl(ME->getMemberDecl());
7657   return nullptr;
7658 }
7659 
checkAndSetCond(Expr * S)7660 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) {
7661   // Check test-expr for canonical form, save upper-bound UB, flags for
7662   // less/greater and for strict/non-strict comparison.
7663   // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following:
7664   //   var relational-op b
7665   //   b relational-op var
7666   //
7667   bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50;
7668   if (!S) {
7669     SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond)
7670         << (IneqCondIsCanonical ? 1 : 0) << LCDecl;
7671     return true;
7672   }
7673   Condition = S;
7674   S = getExprAsWritten(S);
7675   SourceLocation CondLoc = S->getBeginLoc();
7676   auto &&CheckAndSetCond = [this, IneqCondIsCanonical](
7677                                BinaryOperatorKind Opcode, const Expr *LHS,
7678                                const Expr *RHS, SourceRange SR,
7679                                SourceLocation OpLoc) -> llvm::Optional<bool> {
7680     if (BinaryOperator::isRelationalOp(Opcode)) {
7681       if (getInitLCDecl(LHS) == LCDecl)
7682         return setUB(const_cast<Expr *>(RHS),
7683                      (Opcode == BO_LT || Opcode == BO_LE),
7684                      (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
7685       if (getInitLCDecl(RHS) == LCDecl)
7686         return setUB(const_cast<Expr *>(LHS),
7687                      (Opcode == BO_GT || Opcode == BO_GE),
7688                      (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc);
7689     } else if (IneqCondIsCanonical && Opcode == BO_NE) {
7690       return setUB(const_cast<Expr *>(getInitLCDecl(LHS) == LCDecl ? RHS : LHS),
7691                    /*LessOp=*/llvm::None,
7692                    /*StrictOp=*/true, SR, OpLoc);
7693     }
7694     return llvm::None;
7695   };
7696   llvm::Optional<bool> Res;
7697   if (auto *RBO = dyn_cast<CXXRewrittenBinaryOperator>(S)) {
7698     CXXRewrittenBinaryOperator::DecomposedForm DF = RBO->getDecomposedForm();
7699     Res = CheckAndSetCond(DF.Opcode, DF.LHS, DF.RHS, RBO->getSourceRange(),
7700                           RBO->getOperatorLoc());
7701   } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7702     Res = CheckAndSetCond(BO->getOpcode(), BO->getLHS(), BO->getRHS(),
7703                           BO->getSourceRange(), BO->getOperatorLoc());
7704   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7705     if (CE->getNumArgs() == 2) {
7706       Res = CheckAndSetCond(
7707           BinaryOperator::getOverloadedOpcode(CE->getOperator()), CE->getArg(0),
7708           CE->getArg(1), CE->getSourceRange(), CE->getOperatorLoc());
7709     }
7710   }
7711   if (Res.hasValue())
7712     return *Res;
7713   if (dependent() || SemaRef.CurContext->isDependentContext())
7714     return false;
7715   SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond)
7716       << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl;
7717   return true;
7718 }
7719 
checkAndSetIncRHS(Expr * RHS)7720 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) {
7721   // RHS of canonical loop form increment can be:
7722   //   var + incr
7723   //   incr + var
7724   //   var - incr
7725   //
7726   RHS = RHS->IgnoreParenImpCasts();
7727   if (auto *BO = dyn_cast<BinaryOperator>(RHS)) {
7728     if (BO->isAdditiveOp()) {
7729       bool IsAdd = BO->getOpcode() == BO_Add;
7730       if (getInitLCDecl(BO->getLHS()) == LCDecl)
7731         return setStep(BO->getRHS(), !IsAdd);
7732       if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl)
7733         return setStep(BO->getLHS(), /*Subtract=*/false);
7734     }
7735   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) {
7736     bool IsAdd = CE->getOperator() == OO_Plus;
7737     if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) {
7738       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7739         return setStep(CE->getArg(1), !IsAdd);
7740       if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl)
7741         return setStep(CE->getArg(0), /*Subtract=*/false);
7742     }
7743   }
7744   if (dependent() || SemaRef.CurContext->isDependentContext())
7745     return false;
7746   SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
7747       << RHS->getSourceRange() << LCDecl;
7748   return true;
7749 }
7750 
checkAndSetInc(Expr * S)7751 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) {
7752   // Check incr-expr for canonical loop form and return true if it
7753   // does not conform.
7754   // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following:
7755   //   ++var
7756   //   var++
7757   //   --var
7758   //   var--
7759   //   var += incr
7760   //   var -= incr
7761   //   var = var + incr
7762   //   var = incr + var
7763   //   var = var - incr
7764   //
7765   if (!S) {
7766     SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl;
7767     return true;
7768   }
7769   if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S))
7770     if (!ExprTemp->cleanupsHaveSideEffects())
7771       S = ExprTemp->getSubExpr();
7772 
7773   IncrementSrcRange = S->getSourceRange();
7774   S = S->IgnoreParens();
7775   if (auto *UO = dyn_cast<UnaryOperator>(S)) {
7776     if (UO->isIncrementDecrementOp() &&
7777         getInitLCDecl(UO->getSubExpr()) == LCDecl)
7778       return setStep(SemaRef
7779                          .ActOnIntegerConstant(UO->getBeginLoc(),
7780                                                (UO->isDecrementOp() ? -1 : 1))
7781                          .get(),
7782                      /*Subtract=*/false);
7783   } else if (auto *BO = dyn_cast<BinaryOperator>(S)) {
7784     switch (BO->getOpcode()) {
7785     case BO_AddAssign:
7786     case BO_SubAssign:
7787       if (getInitLCDecl(BO->getLHS()) == LCDecl)
7788         return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign);
7789       break;
7790     case BO_Assign:
7791       if (getInitLCDecl(BO->getLHS()) == LCDecl)
7792         return checkAndSetIncRHS(BO->getRHS());
7793       break;
7794     default:
7795       break;
7796     }
7797   } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) {
7798     switch (CE->getOperator()) {
7799     case OO_PlusPlus:
7800     case OO_MinusMinus:
7801       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7802         return setStep(SemaRef
7803                            .ActOnIntegerConstant(
7804                                CE->getBeginLoc(),
7805                                ((CE->getOperator() == OO_MinusMinus) ? -1 : 1))
7806                            .get(),
7807                        /*Subtract=*/false);
7808       break;
7809     case OO_PlusEqual:
7810     case OO_MinusEqual:
7811       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7812         return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual);
7813       break;
7814     case OO_Equal:
7815       if (getInitLCDecl(CE->getArg(0)) == LCDecl)
7816         return checkAndSetIncRHS(CE->getArg(1));
7817       break;
7818     default:
7819       break;
7820     }
7821   }
7822   if (dependent() || SemaRef.CurContext->isDependentContext())
7823     return false;
7824   SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr)
7825       << S->getSourceRange() << LCDecl;
7826   return true;
7827 }
7828 
7829 static ExprResult
tryBuildCapture(Sema & SemaRef,Expr * Capture,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)7830 tryBuildCapture(Sema &SemaRef, Expr *Capture,
7831                 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7832   if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors())
7833     return Capture;
7834   if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects))
7835     return SemaRef.PerformImplicitConversion(
7836         Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting,
7837         /*AllowExplicit=*/true);
7838   auto I = Captures.find(Capture);
7839   if (I != Captures.end())
7840     return buildCapture(SemaRef, Capture, I->second);
7841   DeclRefExpr *Ref = nullptr;
7842   ExprResult Res = buildCapture(SemaRef, Capture, Ref);
7843   Captures[Capture] = Ref;
7844   return Res;
7845 }
7846 
7847 /// Calculate number of iterations, transforming to unsigned, if number of
7848 /// iterations may be larger than the original type.
7849 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)7850 calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc,
7851                   Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy,
7852                   bool TestIsStrictOp, bool RoundToStep,
7853                   llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
7854   ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
7855   if (!NewStep.isUsable())
7856     return nullptr;
7857   llvm::APSInt LRes, SRes;
7858   bool IsLowerConst = false, IsStepConst = false;
7859   if (Optional<llvm::APSInt> Res = Lower->getIntegerConstantExpr(SemaRef.Context)) {
7860     LRes = *Res;
7861     IsLowerConst = true;
7862   }
7863   if (Optional<llvm::APSInt> Res = Step->getIntegerConstantExpr(SemaRef.Context)) {
7864     SRes = *Res;
7865     IsStepConst = true;
7866   }
7867   bool NoNeedToConvert = IsLowerConst && !RoundToStep &&
7868                          ((!TestIsStrictOp && LRes.isNonNegative()) ||
7869                           (TestIsStrictOp && LRes.isStrictlyPositive()));
7870   bool NeedToReorganize = false;
7871   // Check if any subexpressions in Lower -Step [+ 1] lead to overflow.
7872   if (!NoNeedToConvert && IsLowerConst &&
7873       (TestIsStrictOp || (RoundToStep && IsStepConst))) {
7874     NoNeedToConvert = true;
7875     if (RoundToStep) {
7876       unsigned BW = LRes.getBitWidth() > SRes.getBitWidth()
7877                         ? LRes.getBitWidth()
7878                         : SRes.getBitWidth();
7879       LRes = LRes.extend(BW + 1);
7880       LRes.setIsSigned(true);
7881       SRes = SRes.extend(BW + 1);
7882       SRes.setIsSigned(true);
7883       LRes -= SRes;
7884       NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes;
7885       LRes = LRes.trunc(BW);
7886     }
7887     if (TestIsStrictOp) {
7888       unsigned BW = LRes.getBitWidth();
7889       LRes = LRes.extend(BW + 1);
7890       LRes.setIsSigned(true);
7891       ++LRes;
7892       NoNeedToConvert =
7893           NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes;
7894       // truncate to the original bitwidth.
7895       LRes = LRes.trunc(BW);
7896     }
7897     NeedToReorganize = NoNeedToConvert;
7898   }
7899   llvm::APSInt URes;
7900   bool IsUpperConst = false;
7901   if (Optional<llvm::APSInt> Res = Upper->getIntegerConstantExpr(SemaRef.Context)) {
7902     URes = *Res;
7903     IsUpperConst = true;
7904   }
7905   if (NoNeedToConvert && IsLowerConst && IsUpperConst &&
7906       (!RoundToStep || IsStepConst)) {
7907     unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth()
7908                                                           : URes.getBitWidth();
7909     LRes = LRes.extend(BW + 1);
7910     LRes.setIsSigned(true);
7911     URes = URes.extend(BW + 1);
7912     URes.setIsSigned(true);
7913     URes -= LRes;
7914     NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes;
7915     NeedToReorganize = NoNeedToConvert;
7916   }
7917   // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant
7918   // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to
7919   // unsigned.
7920   if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) &&
7921       !LCTy->isDependentType() && LCTy->isIntegerType()) {
7922     QualType LowerTy = Lower->getType();
7923     QualType UpperTy = Upper->getType();
7924     uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy);
7925     uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy);
7926     if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) ||
7927         (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) {
7928       QualType CastType = SemaRef.Context.getIntTypeForBitwidth(
7929           LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0);
7930       Upper =
7931           SemaRef
7932               .PerformImplicitConversion(
7933                   SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
7934                   CastType, Sema::AA_Converting)
7935               .get();
7936       Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get();
7937       NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get());
7938     }
7939   }
7940   if (!Lower || !Upper || NewStep.isInvalid())
7941     return nullptr;
7942 
7943   ExprResult Diff;
7944   // If need to reorganize, then calculate the form as Upper - (Lower - Step [+
7945   // 1]).
7946   if (NeedToReorganize) {
7947     Diff = Lower;
7948 
7949     if (RoundToStep) {
7950       // Lower - Step
7951       Diff =
7952           SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get());
7953       if (!Diff.isUsable())
7954         return nullptr;
7955     }
7956 
7957     // Lower - Step [+ 1]
7958     if (TestIsStrictOp)
7959       Diff = SemaRef.BuildBinOp(
7960           S, DefaultLoc, BO_Add, Diff.get(),
7961           SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7962     if (!Diff.isUsable())
7963       return nullptr;
7964 
7965     Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
7966     if (!Diff.isUsable())
7967       return nullptr;
7968 
7969     // Upper - (Lower - Step [+ 1]).
7970     Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get());
7971     if (!Diff.isUsable())
7972       return nullptr;
7973   } else {
7974     Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower);
7975 
7976     if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) {
7977       // BuildBinOp already emitted error, this one is to point user to upper
7978       // and lower bound, and to tell what is passed to 'operator-'.
7979       SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx)
7980           << Upper->getSourceRange() << Lower->getSourceRange();
7981       return nullptr;
7982     }
7983 
7984     if (!Diff.isUsable())
7985       return nullptr;
7986 
7987     // Upper - Lower [- 1]
7988     if (TestIsStrictOp)
7989       Diff = SemaRef.BuildBinOp(
7990           S, DefaultLoc, BO_Sub, Diff.get(),
7991           SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
7992     if (!Diff.isUsable())
7993       return nullptr;
7994 
7995     if (RoundToStep) {
7996       // Upper - Lower [- 1] + Step
7997       Diff =
7998           SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get());
7999       if (!Diff.isUsable())
8000         return nullptr;
8001     }
8002   }
8003 
8004   // Parentheses (for dumping/debugging purposes only).
8005   Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8006   if (!Diff.isUsable())
8007     return nullptr;
8008 
8009   // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step
8010   Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get());
8011   if (!Diff.isUsable())
8012     return nullptr;
8013 
8014   return Diff.get();
8015 }
8016 
8017 /// Build the expression to calculate the number of iterations.
buildNumIterations(Scope * S,ArrayRef<LoopIterationSpace> ResultIterSpaces,bool LimitedType,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures) const8018 Expr *OpenMPIterationSpaceChecker::buildNumIterations(
8019     Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType,
8020     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8021   QualType VarType = LCDecl->getType().getNonReferenceType();
8022   if (!VarType->isIntegerType() && !VarType->isPointerType() &&
8023       !SemaRef.getLangOpts().CPlusPlus)
8024     return nullptr;
8025   Expr *LBVal = LB;
8026   Expr *UBVal = UB;
8027   // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) :
8028   // max(LB(MinVal), LB(MaxVal))
8029   if (InitDependOnLC) {
8030     const LoopIterationSpace &IS = ResultIterSpaces[*InitDependOnLC - 1];
8031     if (!IS.MinValue || !IS.MaxValue)
8032       return nullptr;
8033     // OuterVar = Min
8034     ExprResult MinValue =
8035         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8036     if (!MinValue.isUsable())
8037       return nullptr;
8038 
8039     ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8040                                              IS.CounterVar, MinValue.get());
8041     if (!LBMinVal.isUsable())
8042       return nullptr;
8043     // OuterVar = Min, LBVal
8044     LBMinVal =
8045         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal);
8046     if (!LBMinVal.isUsable())
8047       return nullptr;
8048     // (OuterVar = Min, LBVal)
8049     LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get());
8050     if (!LBMinVal.isUsable())
8051       return nullptr;
8052 
8053     // OuterVar = Max
8054     ExprResult MaxValue =
8055         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8056     if (!MaxValue.isUsable())
8057       return nullptr;
8058 
8059     ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8060                                              IS.CounterVar, MaxValue.get());
8061     if (!LBMaxVal.isUsable())
8062       return nullptr;
8063     // OuterVar = Max, LBVal
8064     LBMaxVal =
8065         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal);
8066     if (!LBMaxVal.isUsable())
8067       return nullptr;
8068     // (OuterVar = Max, LBVal)
8069     LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get());
8070     if (!LBMaxVal.isUsable())
8071       return nullptr;
8072 
8073     Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get();
8074     Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get();
8075     if (!LBMin || !LBMax)
8076       return nullptr;
8077     // LB(MinVal) < LB(MaxVal)
8078     ExprResult MinLessMaxRes =
8079         SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax);
8080     if (!MinLessMaxRes.isUsable())
8081       return nullptr;
8082     Expr *MinLessMax =
8083         tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get();
8084     if (!MinLessMax)
8085       return nullptr;
8086     if (TestIsLessOp.getValue()) {
8087       // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal),
8088       // LB(MaxVal))
8089       ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8090                                                     MinLessMax, LBMin, LBMax);
8091       if (!MinLB.isUsable())
8092         return nullptr;
8093       LBVal = MinLB.get();
8094     } else {
8095       // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal),
8096       // LB(MaxVal))
8097       ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc,
8098                                                     MinLessMax, LBMax, LBMin);
8099       if (!MaxLB.isUsable())
8100         return nullptr;
8101       LBVal = MaxLB.get();
8102     }
8103   }
8104   // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) :
8105   // min(UB(MinVal), UB(MaxVal))
8106   if (CondDependOnLC) {
8107     const LoopIterationSpace &IS = ResultIterSpaces[*CondDependOnLC - 1];
8108     if (!IS.MinValue || !IS.MaxValue)
8109       return nullptr;
8110     // OuterVar = Min
8111     ExprResult MinValue =
8112         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue);
8113     if (!MinValue.isUsable())
8114       return nullptr;
8115 
8116     ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8117                                              IS.CounterVar, MinValue.get());
8118     if (!UBMinVal.isUsable())
8119       return nullptr;
8120     // OuterVar = Min, UBVal
8121     UBMinVal =
8122         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal);
8123     if (!UBMinVal.isUsable())
8124       return nullptr;
8125     // (OuterVar = Min, UBVal)
8126     UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get());
8127     if (!UBMinVal.isUsable())
8128       return nullptr;
8129 
8130     // OuterVar = Max
8131     ExprResult MaxValue =
8132         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue);
8133     if (!MaxValue.isUsable())
8134       return nullptr;
8135 
8136     ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign,
8137                                              IS.CounterVar, MaxValue.get());
8138     if (!UBMaxVal.isUsable())
8139       return nullptr;
8140     // OuterVar = Max, UBVal
8141     UBMaxVal =
8142         SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal);
8143     if (!UBMaxVal.isUsable())
8144       return nullptr;
8145     // (OuterVar = Max, UBVal)
8146     UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get());
8147     if (!UBMaxVal.isUsable())
8148       return nullptr;
8149 
8150     Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get();
8151     Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get();
8152     if (!UBMin || !UBMax)
8153       return nullptr;
8154     // UB(MinVal) > UB(MaxVal)
8155     ExprResult MinGreaterMaxRes =
8156         SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax);
8157     if (!MinGreaterMaxRes.isUsable())
8158       return nullptr;
8159     Expr *MinGreaterMax =
8160         tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get();
8161     if (!MinGreaterMax)
8162       return nullptr;
8163     if (TestIsLessOp.getValue()) {
8164       // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal),
8165       // UB(MaxVal))
8166       ExprResult MaxUB = SemaRef.ActOnConditionalOp(
8167           DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax);
8168       if (!MaxUB.isUsable())
8169         return nullptr;
8170       UBVal = MaxUB.get();
8171     } else {
8172       // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal),
8173       // UB(MaxVal))
8174       ExprResult MinUB = SemaRef.ActOnConditionalOp(
8175           DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin);
8176       if (!MinUB.isUsable())
8177         return nullptr;
8178       UBVal = MinUB.get();
8179     }
8180   }
8181   Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal;
8182   Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal;
8183   Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get();
8184   Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get();
8185   if (!Upper || !Lower)
8186     return nullptr;
8187 
8188   ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8189                                       Step, VarType, TestIsStrictOp,
8190                                       /*RoundToStep=*/true, Captures);
8191   if (!Diff.isUsable())
8192     return nullptr;
8193 
8194   // OpenMP runtime requires 32-bit or 64-bit loop variables.
8195   QualType Type = Diff.get()->getType();
8196   ASTContext &C = SemaRef.Context;
8197   bool UseVarType = VarType->hasIntegerRepresentation() &&
8198                     C.getTypeSize(Type) > C.getTypeSize(VarType);
8199   if (!Type->isIntegerType() || UseVarType) {
8200     unsigned NewSize =
8201         UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type);
8202     bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation()
8203                                : Type->hasSignedIntegerRepresentation();
8204     Type = C.getIntTypeForBitwidth(NewSize, IsSigned);
8205     if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) {
8206       Diff = SemaRef.PerformImplicitConversion(
8207           Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true);
8208       if (!Diff.isUsable())
8209         return nullptr;
8210     }
8211   }
8212   if (LimitedType) {
8213     unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32;
8214     if (NewSize != C.getTypeSize(Type)) {
8215       if (NewSize < C.getTypeSize(Type)) {
8216         assert(NewSize == 64 && "incorrect loop var size");
8217         SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var)
8218             << InitSrcRange << ConditionSrcRange;
8219       }
8220       QualType NewType = C.getIntTypeForBitwidth(
8221           NewSize, Type->hasSignedIntegerRepresentation() ||
8222                        C.getTypeSize(Type) < NewSize);
8223       if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) {
8224         Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType,
8225                                                  Sema::AA_Converting, true);
8226         if (!Diff.isUsable())
8227           return nullptr;
8228       }
8229     }
8230   }
8231 
8232   return Diff.get();
8233 }
8234 
buildMinMaxValues(Scope * S,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures) const8235 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues(
8236     Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8237   // Do not build for iterators, they cannot be used in non-rectangular loop
8238   // nests.
8239   if (LCDecl->getType()->isRecordType())
8240     return std::make_pair(nullptr, nullptr);
8241   // If we subtract, the min is in the condition, otherwise the min is in the
8242   // init value.
8243   Expr *MinExpr = nullptr;
8244   Expr *MaxExpr = nullptr;
8245   Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB;
8246   Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB;
8247   bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue()
8248                                            : CondDependOnLC.hasValue();
8249   bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue()
8250                                            : InitDependOnLC.hasValue();
8251   Expr *Lower =
8252       LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get();
8253   Expr *Upper =
8254       UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get();
8255   if (!Upper || !Lower)
8256     return std::make_pair(nullptr, nullptr);
8257 
8258   if (TestIsLessOp.getValue())
8259     MinExpr = Lower;
8260   else
8261     MaxExpr = Upper;
8262 
8263   // Build minimum/maximum value based on number of iterations.
8264   QualType VarType = LCDecl->getType().getNonReferenceType();
8265 
8266   ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper,
8267                                       Step, VarType, TestIsStrictOp,
8268                                       /*RoundToStep=*/false, Captures);
8269   if (!Diff.isUsable())
8270     return std::make_pair(nullptr, nullptr);
8271 
8272   // ((Upper - Lower [- 1]) / Step) * Step
8273   // Parentheses (for dumping/debugging purposes only).
8274   Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8275   if (!Diff.isUsable())
8276     return std::make_pair(nullptr, nullptr);
8277 
8278   ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures);
8279   if (!NewStep.isUsable())
8280     return std::make_pair(nullptr, nullptr);
8281   Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get());
8282   if (!Diff.isUsable())
8283     return std::make_pair(nullptr, nullptr);
8284 
8285   // Parentheses (for dumping/debugging purposes only).
8286   Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get());
8287   if (!Diff.isUsable())
8288     return std::make_pair(nullptr, nullptr);
8289 
8290   // Convert to the ptrdiff_t, if original type is pointer.
8291   if (VarType->isAnyPointerType() &&
8292       !SemaRef.Context.hasSameType(
8293           Diff.get()->getType(),
8294           SemaRef.Context.getUnsignedPointerDiffType())) {
8295     Diff = SemaRef.PerformImplicitConversion(
8296         Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(),
8297         Sema::AA_Converting, /*AllowExplicit=*/true);
8298   }
8299   if (!Diff.isUsable())
8300     return std::make_pair(nullptr, nullptr);
8301 
8302   if (TestIsLessOp.getValue()) {
8303     // MinExpr = Lower;
8304     // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step)
8305     Diff = SemaRef.BuildBinOp(
8306         S, DefaultLoc, BO_Add,
8307         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(),
8308         Diff.get());
8309     if (!Diff.isUsable())
8310       return std::make_pair(nullptr, nullptr);
8311   } else {
8312     // MaxExpr = Upper;
8313     // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step)
8314     Diff = SemaRef.BuildBinOp(
8315         S, DefaultLoc, BO_Sub,
8316         SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(),
8317         Diff.get());
8318     if (!Diff.isUsable())
8319       return std::make_pair(nullptr, nullptr);
8320   }
8321 
8322   // Convert to the original type.
8323   if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType))
8324     Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType,
8325                                              Sema::AA_Converting,
8326                                              /*AllowExplicit=*/true);
8327   if (!Diff.isUsable())
8328     return std::make_pair(nullptr, nullptr);
8329 
8330   Sema::TentativeAnalysisScope Trap(SemaRef);
8331   Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false);
8332   if (!Diff.isUsable())
8333     return std::make_pair(nullptr, nullptr);
8334 
8335   if (TestIsLessOp.getValue())
8336     MaxExpr = Diff.get();
8337   else
8338     MinExpr = Diff.get();
8339 
8340   return std::make_pair(MinExpr, MaxExpr);
8341 }
8342 
buildFinalCondition(Scope * S) const8343 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const {
8344   if (InitDependOnLC || CondDependOnLC)
8345     return Condition;
8346   return nullptr;
8347 }
8348 
buildPreCond(Scope * S,Expr * Cond,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures) const8349 Expr *OpenMPIterationSpaceChecker::buildPreCond(
8350     Scope *S, Expr *Cond,
8351     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const {
8352   // Do not build a precondition when the condition/initialization is dependent
8353   // to prevent pessimistic early loop exit.
8354   // TODO: this can be improved by calculating min/max values but not sure that
8355   // it will be very effective.
8356   if (CondDependOnLC || InitDependOnLC)
8357     return SemaRef.PerformImplicitConversion(
8358         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(),
8359         SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
8360         /*AllowExplicit=*/true).get();
8361 
8362   // Try to build LB <op> UB, where <op> is <, >, <=, or >=.
8363   Sema::TentativeAnalysisScope Trap(SemaRef);
8364 
8365   ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures);
8366   ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures);
8367   if (!NewLB.isUsable() || !NewUB.isUsable())
8368     return nullptr;
8369 
8370   ExprResult CondExpr =
8371       SemaRef.BuildBinOp(S, DefaultLoc,
8372                          TestIsLessOp.getValue() ?
8373                            (TestIsStrictOp ? BO_LT : BO_LE) :
8374                            (TestIsStrictOp ? BO_GT : BO_GE),
8375                          NewLB.get(), NewUB.get());
8376   if (CondExpr.isUsable()) {
8377     if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(),
8378                                                 SemaRef.Context.BoolTy))
8379       CondExpr = SemaRef.PerformImplicitConversion(
8380           CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting,
8381           /*AllowExplicit=*/true);
8382   }
8383 
8384   // Otherwise use original loop condition and evaluate it in runtime.
8385   return CondExpr.isUsable() ? CondExpr.get() : Cond;
8386 }
8387 
8388 /// Build reference expression to the counter be used for codegen.
buildCounterVar(llvm::MapVector<const Expr *,DeclRefExpr * > & Captures,DSAStackTy & DSA) const8389 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar(
8390     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures,
8391     DSAStackTy &DSA) const {
8392   auto *VD = dyn_cast<VarDecl>(LCDecl);
8393   if (!VD) {
8394     VD = SemaRef.isOpenMPCapturedDecl(LCDecl);
8395     DeclRefExpr *Ref = buildDeclRefExpr(
8396         SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc);
8397     const DSAStackTy::DSAVarData Data =
8398         DSA.getTopDSA(LCDecl, /*FromParent=*/false);
8399     // If the loop control decl is explicitly marked as private, do not mark it
8400     // as captured again.
8401     if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr)
8402       Captures.insert(std::make_pair(LCRef, Ref));
8403     return Ref;
8404   }
8405   return cast<DeclRefExpr>(LCRef);
8406 }
8407 
buildPrivateCounterVar() const8408 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const {
8409   if (LCDecl && !LCDecl->isInvalidDecl()) {
8410     QualType Type = LCDecl->getType().getNonReferenceType();
8411     VarDecl *PrivateVar = buildVarDecl(
8412         SemaRef, DefaultLoc, Type, LCDecl->getName(),
8413         LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr,
8414         isa<VarDecl>(LCDecl)
8415             ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc)
8416             : nullptr);
8417     if (PrivateVar->isInvalidDecl())
8418       return nullptr;
8419     return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc);
8420   }
8421   return nullptr;
8422 }
8423 
8424 /// Build initialization of the counter to be used for codegen.
buildCounterInit() const8425 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; }
8426 
8427 /// Build step of the counter be used for codegen.
buildCounterStep() const8428 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; }
8429 
buildOrderedLoopData(Scope * S,Expr * Counter,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures,SourceLocation Loc,Expr * Inc,OverloadedOperatorKind OOK)8430 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData(
8431     Scope *S, Expr *Counter,
8432     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc,
8433     Expr *Inc, OverloadedOperatorKind OOK) {
8434   Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get();
8435   if (!Cnt)
8436     return nullptr;
8437   if (Inc) {
8438     assert((OOK == OO_Plus || OOK == OO_Minus) &&
8439            "Expected only + or - operations for depend clauses.");
8440     BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub;
8441     Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get();
8442     if (!Cnt)
8443       return nullptr;
8444   }
8445   QualType VarType = LCDecl->getType().getNonReferenceType();
8446   if (!VarType->isIntegerType() && !VarType->isPointerType() &&
8447       !SemaRef.getLangOpts().CPlusPlus)
8448     return nullptr;
8449   // Upper - Lower
8450   Expr *Upper = TestIsLessOp.getValue()
8451                     ? Cnt
8452                     : tryBuildCapture(SemaRef, LB, Captures).get();
8453   Expr *Lower = TestIsLessOp.getValue()
8454                     ? tryBuildCapture(SemaRef, LB, Captures).get()
8455                     : Cnt;
8456   if (!Upper || !Lower)
8457     return nullptr;
8458 
8459   ExprResult Diff = calculateNumIters(
8460       SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType,
8461       /*TestIsStrictOp=*/false, /*RoundToStep=*/false, Captures);
8462   if (!Diff.isUsable())
8463     return nullptr;
8464 
8465   return Diff.get();
8466 }
8467 } // namespace
8468 
ActOnOpenMPLoopInitialization(SourceLocation ForLoc,Stmt * Init)8469 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) {
8470   assert(getLangOpts().OpenMP && "OpenMP is not active.");
8471   assert(Init && "Expected loop in canonical form.");
8472   unsigned AssociatedLoops = DSAStack->getAssociatedLoops();
8473   if (AssociatedLoops > 0 &&
8474       isOpenMPLoopDirective(DSAStack->getCurrentDirective())) {
8475     DSAStack->loopStart();
8476     OpenMPIterationSpaceChecker ISC(*this, /*SupportsNonRectangular=*/true,
8477                                     *DSAStack, ForLoc);
8478     if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) {
8479       if (ValueDecl *D = ISC.getLoopDecl()) {
8480         auto *VD = dyn_cast<VarDecl>(D);
8481         DeclRefExpr *PrivateRef = nullptr;
8482         if (!VD) {
8483           if (VarDecl *Private = isOpenMPCapturedDecl(D)) {
8484             VD = Private;
8485           } else {
8486             PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(),
8487                                       /*WithInit=*/false);
8488             VD = cast<VarDecl>(PrivateRef->getDecl());
8489           }
8490         }
8491         DSAStack->addLoopControlVariable(D, VD);
8492         const Decl *LD = DSAStack->getPossiblyLoopCunter();
8493         if (LD != D->getCanonicalDecl()) {
8494           DSAStack->resetPossibleLoopCounter();
8495           if (auto *Var = dyn_cast_or_null<VarDecl>(LD))
8496             MarkDeclarationsReferencedInExpr(
8497                 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var),
8498                                  Var->getType().getNonLValueExprType(Context),
8499                                  ForLoc, /*RefersToCapture=*/true));
8500         }
8501         OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
8502         // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables
8503         // Referenced in a Construct, C/C++]. The loop iteration variable in the
8504         // associated for-loop of a simd construct with just one associated
8505         // for-loop may be listed in a linear clause with a constant-linear-step
8506         // that is the increment of the associated for-loop. The loop iteration
8507         // variable(s) in the associated for-loop(s) of a for or parallel for
8508         // construct may be listed in a private or lastprivate clause.
8509         DSAStackTy::DSAVarData DVar =
8510             DSAStack->getTopDSA(D, /*FromParent=*/false);
8511         // If LoopVarRefExpr is nullptr it means the corresponding loop variable
8512         // is declared in the loop and it is predetermined as a private.
8513         Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr();
8514         OpenMPClauseKind PredeterminedCKind =
8515             isOpenMPSimdDirective(DKind)
8516                 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear)
8517                 : OMPC_private;
8518         if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
8519               DVar.CKind != PredeterminedCKind && DVar.RefExpr &&
8520               (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate &&
8521                                          DVar.CKind != OMPC_private))) ||
8522              ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop ||
8523                DKind == OMPD_master_taskloop ||
8524                DKind == OMPD_parallel_master_taskloop ||
8525                isOpenMPDistributeDirective(DKind)) &&
8526               !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown &&
8527               DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) &&
8528             (DVar.CKind != OMPC_private || DVar.RefExpr)) {
8529           Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa)
8530               << getOpenMPClauseName(DVar.CKind)
8531               << getOpenMPDirectiveName(DKind)
8532               << getOpenMPClauseName(PredeterminedCKind);
8533           if (DVar.RefExpr == nullptr)
8534             DVar.CKind = PredeterminedCKind;
8535           reportOriginalDsa(*this, DSAStack, D, DVar,
8536                             /*IsLoopIterVar=*/true);
8537         } else if (LoopDeclRefExpr) {
8538           // Make the loop iteration variable private (for worksharing
8539           // constructs), linear (for simd directives with the only one
8540           // associated loop) or lastprivate (for simd directives with several
8541           // collapsed or ordered loops).
8542           if (DVar.CKind == OMPC_unknown)
8543             DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind,
8544                              PrivateRef);
8545         }
8546       }
8547     }
8548     DSAStack->setAssociatedLoops(AssociatedLoops - 1);
8549   }
8550 }
8551 
8552 /// Called on a for stmt to check and extract its iteration space
8553 /// 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)8554 static bool checkOpenMPIterationSpace(
8555     OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA,
8556     unsigned CurrentNestedLoopCount, unsigned NestedLoopCount,
8557     unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr,
8558     Expr *OrderedLoopCountExpr,
8559     Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
8560     llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces,
8561     llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8562   bool SupportsNonRectangular = !isOpenMPLoopTransformationDirective(DKind);
8563   // OpenMP [2.9.1, Canonical Loop Form]
8564   //   for (init-expr; test-expr; incr-expr) structured-block
8565   //   for (range-decl: range-expr) structured-block
8566   if (auto *CanonLoop = dyn_cast_or_null<OMPCanonicalLoop>(S))
8567     S = CanonLoop->getLoopStmt();
8568   auto *For = dyn_cast_or_null<ForStmt>(S);
8569   auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S);
8570   // Ranged for is supported only in OpenMP 5.0.
8571   if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) {
8572     SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for)
8573         << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr)
8574         << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount
8575         << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount;
8576     if (TotalNestedLoopCount > 1) {
8577       if (CollapseLoopCountExpr && OrderedLoopCountExpr)
8578         SemaRef.Diag(DSA.getConstructLoc(),
8579                      diag::note_omp_collapse_ordered_expr)
8580             << 2 << CollapseLoopCountExpr->getSourceRange()
8581             << OrderedLoopCountExpr->getSourceRange();
8582       else if (CollapseLoopCountExpr)
8583         SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
8584                      diag::note_omp_collapse_ordered_expr)
8585             << 0 << CollapseLoopCountExpr->getSourceRange();
8586       else
8587         SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
8588                      diag::note_omp_collapse_ordered_expr)
8589             << 1 << OrderedLoopCountExpr->getSourceRange();
8590     }
8591     return true;
8592   }
8593   assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) &&
8594          "No loop body.");
8595 
8596   OpenMPIterationSpaceChecker ISC(SemaRef, SupportsNonRectangular, DSA,
8597                                   For ? For->getForLoc() : CXXFor->getForLoc());
8598 
8599   // Check init.
8600   Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt();
8601   if (ISC.checkAndSetInit(Init))
8602     return true;
8603 
8604   bool HasErrors = false;
8605 
8606   // Check loop variable's type.
8607   if (ValueDecl *LCDecl = ISC.getLoopDecl()) {
8608     // OpenMP [2.6, Canonical Loop Form]
8609     // Var is one of the following:
8610     //   A variable of signed or unsigned integer type.
8611     //   For C++, a variable of a random access iterator type.
8612     //   For C, a variable of a pointer type.
8613     QualType VarType = LCDecl->getType().getNonReferenceType();
8614     if (!VarType->isDependentType() && !VarType->isIntegerType() &&
8615         !VarType->isPointerType() &&
8616         !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) {
8617       SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type)
8618           << SemaRef.getLangOpts().CPlusPlus;
8619       HasErrors = true;
8620     }
8621 
8622     // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in
8623     // a Construct
8624     // The loop iteration variable(s) in the associated for-loop(s) of a for or
8625     // parallel for construct is (are) private.
8626     // The loop iteration variable in the associated for-loop of a simd
8627     // construct with just one associated for-loop is linear with a
8628     // constant-linear-step that is the increment of the associated for-loop.
8629     // Exclude loop var from the list of variables with implicitly defined data
8630     // sharing attributes.
8631     VarsWithImplicitDSA.erase(LCDecl);
8632 
8633     assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars");
8634 
8635     // Check test-expr.
8636     HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond());
8637 
8638     // Check incr-expr.
8639     HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc());
8640   }
8641 
8642   if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors)
8643     return HasErrors;
8644 
8645   // Build the loop's iteration space representation.
8646   ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond(
8647       DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures);
8648   ResultIterSpaces[CurrentNestedLoopCount].NumIterations =
8649       ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces,
8650                              (isOpenMPWorksharingDirective(DKind) ||
8651                               isOpenMPTaskLoopDirective(DKind) ||
8652                               isOpenMPDistributeDirective(DKind) ||
8653                               isOpenMPLoopTransformationDirective(DKind)),
8654                              Captures);
8655   ResultIterSpaces[CurrentNestedLoopCount].CounterVar =
8656       ISC.buildCounterVar(Captures, DSA);
8657   ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar =
8658       ISC.buildPrivateCounterVar();
8659   ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit();
8660   ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep();
8661   ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange();
8662   ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange =
8663       ISC.getConditionSrcRange();
8664   ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange =
8665       ISC.getIncrementSrcRange();
8666   ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep();
8667   ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare =
8668       ISC.isStrictTestOp();
8669   std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue,
8670            ResultIterSpaces[CurrentNestedLoopCount].MaxValue) =
8671       ISC.buildMinMaxValues(DSA.getCurScope(), Captures);
8672   ResultIterSpaces[CurrentNestedLoopCount].FinalCondition =
8673       ISC.buildFinalCondition(DSA.getCurScope());
8674   ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB =
8675       ISC.doesInitDependOnLC();
8676   ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB =
8677       ISC.doesCondDependOnLC();
8678   ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx =
8679       ISC.getLoopDependentIdx();
8680 
8681   HasErrors |=
8682       (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr ||
8683        ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr ||
8684        ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr ||
8685        ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr ||
8686        ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr ||
8687        ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr);
8688   if (!HasErrors && DSA.isOrderedRegion()) {
8689     if (DSA.getOrderedRegionParam().second->getNumForLoops()) {
8690       if (CurrentNestedLoopCount <
8691           DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) {
8692         DSA.getOrderedRegionParam().second->setLoopNumIterations(
8693             CurrentNestedLoopCount,
8694             ResultIterSpaces[CurrentNestedLoopCount].NumIterations);
8695         DSA.getOrderedRegionParam().second->setLoopCounter(
8696             CurrentNestedLoopCount,
8697             ResultIterSpaces[CurrentNestedLoopCount].CounterVar);
8698       }
8699     }
8700     for (auto &Pair : DSA.getDoacrossDependClauses()) {
8701       if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) {
8702         // Erroneous case - clause has some problems.
8703         continue;
8704       }
8705       if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink &&
8706           Pair.second.size() <= CurrentNestedLoopCount) {
8707         // Erroneous case - clause has some problems.
8708         Pair.first->setLoopData(CurrentNestedLoopCount, nullptr);
8709         continue;
8710       }
8711       Expr *CntValue;
8712       if (Pair.first->getDependencyKind() == OMPC_DEPEND_source)
8713         CntValue = ISC.buildOrderedLoopData(
8714             DSA.getCurScope(),
8715             ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
8716             Pair.first->getDependencyLoc());
8717       else
8718         CntValue = ISC.buildOrderedLoopData(
8719             DSA.getCurScope(),
8720             ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures,
8721             Pair.first->getDependencyLoc(),
8722             Pair.second[CurrentNestedLoopCount].first,
8723             Pair.second[CurrentNestedLoopCount].second);
8724       Pair.first->setLoopData(CurrentNestedLoopCount, CntValue);
8725     }
8726   }
8727 
8728   return HasErrors;
8729 }
8730 
8731 /// Build 'VarRef = Start.
8732 static ExprResult
buildCounterInit(Sema & SemaRef,Scope * S,SourceLocation Loc,ExprResult VarRef,ExprResult Start,bool IsNonRectangularLB,llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)8733 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
8734                  ExprResult Start, bool IsNonRectangularLB,
8735                  llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8736   // Build 'VarRef = Start.
8737   ExprResult NewStart = IsNonRectangularLB
8738                             ? Start.get()
8739                             : tryBuildCapture(SemaRef, Start.get(), Captures);
8740   if (!NewStart.isUsable())
8741     return ExprError();
8742   if (!SemaRef.Context.hasSameType(NewStart.get()->getType(),
8743                                    VarRef.get()->getType())) {
8744     NewStart = SemaRef.PerformImplicitConversion(
8745         NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting,
8746         /*AllowExplicit=*/true);
8747     if (!NewStart.isUsable())
8748       return ExprError();
8749   }
8750 
8751   ExprResult Init =
8752       SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
8753   return Init;
8754 }
8755 
8756 /// 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)8757 static ExprResult buildCounterUpdate(
8758     Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef,
8759     ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract,
8760     bool IsNonRectangularLB,
8761     llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) {
8762   // Add parentheses (for debugging purposes only).
8763   Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get());
8764   if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() ||
8765       !Step.isUsable())
8766     return ExprError();
8767 
8768   ExprResult NewStep = Step;
8769   if (Captures)
8770     NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures);
8771   if (NewStep.isInvalid())
8772     return ExprError();
8773   ExprResult Update =
8774       SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get());
8775   if (!Update.isUsable())
8776     return ExprError();
8777 
8778   // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or
8779   // 'VarRef = Start (+|-) Iter * Step'.
8780   if (!Start.isUsable())
8781     return ExprError();
8782   ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get());
8783   if (!NewStart.isUsable())
8784     return ExprError();
8785   if (Captures && !IsNonRectangularLB)
8786     NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures);
8787   if (NewStart.isInvalid())
8788     return ExprError();
8789 
8790   // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'.
8791   ExprResult SavedUpdate = Update;
8792   ExprResult UpdateVal;
8793   if (VarRef.get()->getType()->isOverloadableType() ||
8794       NewStart.get()->getType()->isOverloadableType() ||
8795       Update.get()->getType()->isOverloadableType()) {
8796     Sema::TentativeAnalysisScope Trap(SemaRef);
8797 
8798     Update =
8799         SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get());
8800     if (Update.isUsable()) {
8801       UpdateVal =
8802           SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign,
8803                              VarRef.get(), SavedUpdate.get());
8804       if (UpdateVal.isUsable()) {
8805         Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(),
8806                                             UpdateVal.get());
8807       }
8808     }
8809   }
8810 
8811   // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'.
8812   if (!Update.isUsable() || !UpdateVal.isUsable()) {
8813     Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add,
8814                                 NewStart.get(), SavedUpdate.get());
8815     if (!Update.isUsable())
8816       return ExprError();
8817 
8818     if (!SemaRef.Context.hasSameType(Update.get()->getType(),
8819                                      VarRef.get()->getType())) {
8820       Update = SemaRef.PerformImplicitConversion(
8821           Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true);
8822       if (!Update.isUsable())
8823         return ExprError();
8824     }
8825 
8826     Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get());
8827   }
8828   return Update;
8829 }
8830 
8831 /// Convert integer expression \a E to make it have at least \a Bits
8832 /// bits.
widenIterationCount(unsigned Bits,Expr * E,Sema & SemaRef)8833 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) {
8834   if (E == nullptr)
8835     return ExprError();
8836   ASTContext &C = SemaRef.Context;
8837   QualType OldType = E->getType();
8838   unsigned HasBits = C.getTypeSize(OldType);
8839   if (HasBits >= Bits)
8840     return ExprResult(E);
8841   // OK to convert to signed, because new type has more bits than old.
8842   QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true);
8843   return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting,
8844                                            true);
8845 }
8846 
8847 /// Check if the given expression \a E is a constant integer that fits
8848 /// into \a Bits bits.
fitsInto(unsigned Bits,bool Signed,const Expr * E,Sema & SemaRef)8849 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) {
8850   if (E == nullptr)
8851     return false;
8852   if (Optional<llvm::APSInt> Result =
8853           E->getIntegerConstantExpr(SemaRef.Context))
8854     return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits);
8855   return false;
8856 }
8857 
8858 /// Build preinits statement for the given declarations.
buildPreInits(ASTContext & Context,MutableArrayRef<Decl * > PreInits)8859 static Stmt *buildPreInits(ASTContext &Context,
8860                            MutableArrayRef<Decl *> PreInits) {
8861   if (!PreInits.empty()) {
8862     return new (Context) DeclStmt(
8863         DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()),
8864         SourceLocation(), SourceLocation());
8865   }
8866   return nullptr;
8867 }
8868 
8869 /// Build preinits statement for the given declarations.
8870 static Stmt *
buildPreInits(ASTContext & Context,const llvm::MapVector<const Expr *,DeclRefExpr * > & Captures)8871 buildPreInits(ASTContext &Context,
8872               const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) {
8873   if (!Captures.empty()) {
8874     SmallVector<Decl *, 16> PreInits;
8875     for (const auto &Pair : Captures)
8876       PreInits.push_back(Pair.second->getDecl());
8877     return buildPreInits(Context, PreInits);
8878   }
8879   return nullptr;
8880 }
8881 
8882 /// Build postupdate expression for the given list of postupdates expressions.
buildPostUpdate(Sema & S,ArrayRef<Expr * > PostUpdates)8883 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) {
8884   Expr *PostUpdate = nullptr;
8885   if (!PostUpdates.empty()) {
8886     for (Expr *E : PostUpdates) {
8887       Expr *ConvE = S.BuildCStyleCastExpr(
8888                          E->getExprLoc(),
8889                          S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy),
8890                          E->getExprLoc(), E)
8891                         .get();
8892       PostUpdate = PostUpdate
8893                        ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma,
8894                                               PostUpdate, ConvE)
8895                              .get()
8896                        : ConvE;
8897     }
8898   }
8899   return PostUpdate;
8900 }
8901 
8902 /// Called on a for stmt to check itself and nested loops (if any).
8903 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop,
8904 /// number of collapsed loops otherwise.
8905 static unsigned
checkOpenMPLoop(OpenMPDirectiveKind DKind,Expr * CollapseLoopCountExpr,Expr * OrderedLoopCountExpr,Stmt * AStmt,Sema & SemaRef,DSAStackTy & DSA,Sema::VarsWithInheritedDSAType & VarsWithImplicitDSA,OMPLoopBasedDirective::HelperExprs & Built)8906 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr,
8907                 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef,
8908                 DSAStackTy &DSA,
8909                 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA,
8910                 OMPLoopBasedDirective::HelperExprs &Built) {
8911   unsigned NestedLoopCount = 1;
8912   bool SupportsNonPerfectlyNested = (SemaRef.LangOpts.OpenMP >= 50) &&
8913                                     !isOpenMPLoopTransformationDirective(DKind);
8914 
8915   if (CollapseLoopCountExpr) {
8916     // Found 'collapse' clause - calculate collapse number.
8917     Expr::EvalResult Result;
8918     if (!CollapseLoopCountExpr->isValueDependent() &&
8919         CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) {
8920       NestedLoopCount = Result.Val.getInt().getLimitedValue();
8921     } else {
8922       Built.clear(/*Size=*/1);
8923       return 1;
8924     }
8925   }
8926   unsigned OrderedLoopCount = 1;
8927   if (OrderedLoopCountExpr) {
8928     // Found 'ordered' clause - calculate collapse number.
8929     Expr::EvalResult EVResult;
8930     if (!OrderedLoopCountExpr->isValueDependent() &&
8931         OrderedLoopCountExpr->EvaluateAsInt(EVResult,
8932                                             SemaRef.getASTContext())) {
8933       llvm::APSInt Result = EVResult.Val.getInt();
8934       if (Result.getLimitedValue() < NestedLoopCount) {
8935         SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(),
8936                      diag::err_omp_wrong_ordered_loop_count)
8937             << OrderedLoopCountExpr->getSourceRange();
8938         SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(),
8939                      diag::note_collapse_loop_count)
8940             << CollapseLoopCountExpr->getSourceRange();
8941       }
8942       OrderedLoopCount = Result.getLimitedValue();
8943     } else {
8944       Built.clear(/*Size=*/1);
8945       return 1;
8946     }
8947   }
8948   // This is helper routine for loop directives (e.g., 'for', 'simd',
8949   // 'for simd', etc.).
8950   llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
8951   unsigned NumLoops = std::max(OrderedLoopCount, NestedLoopCount);
8952   SmallVector<LoopIterationSpace, 4> IterSpaces(NumLoops);
8953   if (!OMPLoopBasedDirective::doForAllLoops(
8954           AStmt->IgnoreContainers(!isOpenMPLoopTransformationDirective(DKind)),
8955           SupportsNonPerfectlyNested, NumLoops,
8956           [DKind, &SemaRef, &DSA, NumLoops, NestedLoopCount,
8957            CollapseLoopCountExpr, OrderedLoopCountExpr, &VarsWithImplicitDSA,
8958            &IterSpaces, &Captures](unsigned Cnt, Stmt *CurStmt) {
8959             if (checkOpenMPIterationSpace(
8960                     DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount,
8961                     NumLoops, CollapseLoopCountExpr, OrderedLoopCountExpr,
8962                     VarsWithImplicitDSA, IterSpaces, Captures))
8963               return true;
8964             if (Cnt > 0 && Cnt >= NestedLoopCount &&
8965                 IterSpaces[Cnt].CounterVar) {
8966               // Handle initialization of captured loop iterator variables.
8967               auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar);
8968               if (isa<OMPCapturedExprDecl>(DRE->getDecl())) {
8969                 Captures[DRE] = DRE;
8970               }
8971             }
8972             return false;
8973           },
8974           [&SemaRef, &Captures](OMPLoopBasedDirective *Transform) {
8975             Stmt *DependentPreInits;
8976             if (auto *Dir = dyn_cast<OMPTileDirective>(Transform)) {
8977               DependentPreInits = Dir->getPreInits();
8978             } else if (auto *Dir = dyn_cast<OMPUnrollDirective>(Transform)) {
8979               DependentPreInits = Dir->getPreInits();
8980             } else {
8981               llvm_unreachable("Unexpected loop transformation");
8982             }
8983             if (!DependentPreInits)
8984               return;
8985             for (Decl *C : cast<DeclStmt>(DependentPreInits)->getDeclGroup()) {
8986               auto *D = cast<VarDecl>(C);
8987               DeclRefExpr *Ref = buildDeclRefExpr(SemaRef, D, D->getType(),
8988                                                   Transform->getBeginLoc());
8989               Captures[Ref] = Ref;
8990             }
8991           }))
8992     return 0;
8993 
8994   Built.clear(/* size */ NestedLoopCount);
8995 
8996   if (SemaRef.CurContext->isDependentContext())
8997     return NestedLoopCount;
8998 
8999   // An example of what is generated for the following code:
9000   //
9001   //   #pragma omp simd collapse(2) ordered(2)
9002   //   for (i = 0; i < NI; ++i)
9003   //     for (k = 0; k < NK; ++k)
9004   //       for (j = J0; j < NJ; j+=2) {
9005   //         <loop body>
9006   //       }
9007   //
9008   // We generate the code below.
9009   // Note: the loop body may be outlined in CodeGen.
9010   // Note: some counters may be C++ classes, operator- is used to find number of
9011   // iterations and operator+= to calculate counter value.
9012   // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32
9013   // or i64 is currently supported).
9014   //
9015   //   #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2))
9016   //   for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) {
9017   //     .local.i = IV / ((NJ - J0 - 1 + 2) / 2);
9018   //     .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2;
9019   //     // similar updates for vars in clauses (e.g. 'linear')
9020   //     <loop body (using local i and j)>
9021   //   }
9022   //   i = NI; // assign final values of counters
9023   //   j = NJ;
9024   //
9025 
9026   // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are
9027   // the iteration counts of the collapsed for loops.
9028   // Precondition tests if there is at least one iteration (all conditions are
9029   // true).
9030   auto PreCond = ExprResult(IterSpaces[0].PreCond);
9031   Expr *N0 = IterSpaces[0].NumIterations;
9032   ExprResult LastIteration32 =
9033       widenIterationCount(/*Bits=*/32,
9034                           SemaRef
9035                               .PerformImplicitConversion(
9036                                   N0->IgnoreImpCasts(), N0->getType(),
9037                                   Sema::AA_Converting, /*AllowExplicit=*/true)
9038                               .get(),
9039                           SemaRef);
9040   ExprResult LastIteration64 = widenIterationCount(
9041       /*Bits=*/64,
9042       SemaRef
9043           .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(),
9044                                      Sema::AA_Converting,
9045                                      /*AllowExplicit=*/true)
9046           .get(),
9047       SemaRef);
9048 
9049   if (!LastIteration32.isUsable() || !LastIteration64.isUsable())
9050     return NestedLoopCount;
9051 
9052   ASTContext &C = SemaRef.Context;
9053   bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32;
9054 
9055   Scope *CurScope = DSA.getCurScope();
9056   for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) {
9057     if (PreCond.isUsable()) {
9058       PreCond =
9059           SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd,
9060                              PreCond.get(), IterSpaces[Cnt].PreCond);
9061     }
9062     Expr *N = IterSpaces[Cnt].NumIterations;
9063     SourceLocation Loc = N->getExprLoc();
9064     AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32;
9065     if (LastIteration32.isUsable())
9066       LastIteration32 = SemaRef.BuildBinOp(
9067           CurScope, Loc, BO_Mul, LastIteration32.get(),
9068           SemaRef
9069               .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
9070                                          Sema::AA_Converting,
9071                                          /*AllowExplicit=*/true)
9072               .get());
9073     if (LastIteration64.isUsable())
9074       LastIteration64 = SemaRef.BuildBinOp(
9075           CurScope, Loc, BO_Mul, LastIteration64.get(),
9076           SemaRef
9077               .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(),
9078                                          Sema::AA_Converting,
9079                                          /*AllowExplicit=*/true)
9080               .get());
9081   }
9082 
9083   // Choose either the 32-bit or 64-bit version.
9084   ExprResult LastIteration = LastIteration64;
9085   if (SemaRef.getLangOpts().OpenMPOptimisticCollapse ||
9086       (LastIteration32.isUsable() &&
9087        C.getTypeSize(LastIteration32.get()->getType()) == 32 &&
9088        (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 ||
9089         fitsInto(
9090             /*Bits=*/32,
9091             LastIteration32.get()->getType()->hasSignedIntegerRepresentation(),
9092             LastIteration64.get(), SemaRef))))
9093     LastIteration = LastIteration32;
9094   QualType VType = LastIteration.get()->getType();
9095   QualType RealVType = VType;
9096   QualType StrideVType = VType;
9097   if (isOpenMPTaskLoopDirective(DKind)) {
9098     VType =
9099         SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0);
9100     StrideVType =
9101         SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1);
9102   }
9103 
9104   if (!LastIteration.isUsable())
9105     return 0;
9106 
9107   // Save the number of iterations.
9108   ExprResult NumIterations = LastIteration;
9109   {
9110     LastIteration = SemaRef.BuildBinOp(
9111         CurScope, LastIteration.get()->getExprLoc(), BO_Sub,
9112         LastIteration.get(),
9113         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9114     if (!LastIteration.isUsable())
9115       return 0;
9116   }
9117 
9118   // Calculate the last iteration number beforehand instead of doing this on
9119   // each iteration. Do not do this if the number of iterations may be kfold-ed.
9120   bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context);
9121   ExprResult CalcLastIteration;
9122   if (!IsConstant) {
9123     ExprResult SaveRef =
9124         tryBuildCapture(SemaRef, LastIteration.get(), Captures);
9125     LastIteration = SaveRef;
9126 
9127     // Prepare SaveRef + 1.
9128     NumIterations = SemaRef.BuildBinOp(
9129         CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(),
9130         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get());
9131     if (!NumIterations.isUsable())
9132       return 0;
9133   }
9134 
9135   SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin();
9136 
9137   // Build variables passed into runtime, necessary for worksharing directives.
9138   ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB;
9139   if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
9140       isOpenMPDistributeDirective(DKind) ||
9141       isOpenMPLoopTransformationDirective(DKind)) {
9142     // Lower bound variable, initialized with zero.
9143     VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb");
9144     LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc);
9145     SemaRef.AddInitializerToDecl(LBDecl,
9146                                  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9147                                  /*DirectInit*/ false);
9148 
9149     // Upper bound variable, initialized with last iteration number.
9150     VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub");
9151     UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc);
9152     SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(),
9153                                  /*DirectInit*/ false);
9154 
9155     // A 32-bit variable-flag where runtime returns 1 for the last iteration.
9156     // This will be used to implement clause 'lastprivate'.
9157     QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true);
9158     VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last");
9159     IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc);
9160     SemaRef.AddInitializerToDecl(ILDecl,
9161                                  SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9162                                  /*DirectInit*/ false);
9163 
9164     // Stride variable returned by runtime (we initialize it to 1 by default).
9165     VarDecl *STDecl =
9166         buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride");
9167     ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc);
9168     SemaRef.AddInitializerToDecl(STDecl,
9169                                  SemaRef.ActOnIntegerConstant(InitLoc, 1).get(),
9170                                  /*DirectInit*/ false);
9171 
9172     // Build expression: UB = min(UB, LastIteration)
9173     // It is necessary for CodeGen of directives with static scheduling.
9174     ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT,
9175                                                 UB.get(), LastIteration.get());
9176     ExprResult CondOp = SemaRef.ActOnConditionalOp(
9177         LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(),
9178         LastIteration.get(), UB.get());
9179     EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(),
9180                              CondOp.get());
9181     EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false);
9182 
9183     // If we have a combined directive that combines 'distribute', 'for' or
9184     // 'simd' we need to be able to access the bounds of the schedule of the
9185     // enclosing region. E.g. in 'distribute parallel for' the bounds obtained
9186     // by scheduling 'distribute' have to be passed to the schedule of 'for'.
9187     if (isOpenMPLoopBoundSharingDirective(DKind)) {
9188       // Lower bound variable, initialized with zero.
9189       VarDecl *CombLBDecl =
9190           buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb");
9191       CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc);
9192       SemaRef.AddInitializerToDecl(
9193           CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(),
9194           /*DirectInit*/ false);
9195 
9196       // Upper bound variable, initialized with last iteration number.
9197       VarDecl *CombUBDecl =
9198           buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub");
9199       CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc);
9200       SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(),
9201                                    /*DirectInit*/ false);
9202 
9203       ExprResult CombIsUBGreater = SemaRef.BuildBinOp(
9204           CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get());
9205       ExprResult CombCondOp =
9206           SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(),
9207                                      LastIteration.get(), CombUB.get());
9208       CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(),
9209                                    CombCondOp.get());
9210       CombEUB =
9211           SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false);
9212 
9213       const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl();
9214       // We expect to have at least 2 more parameters than the 'parallel'
9215       // directive does - the lower and upper bounds of the previous schedule.
9216       assert(CD->getNumParams() >= 4 &&
9217              "Unexpected number of parameters in loop combined directive");
9218 
9219       // Set the proper type for the bounds given what we learned from the
9220       // enclosed loops.
9221       ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2);
9222       ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3);
9223 
9224       // Previous lower and upper bounds are obtained from the region
9225       // parameters.
9226       PrevLB =
9227           buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc);
9228       PrevUB =
9229           buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc);
9230     }
9231   }
9232 
9233   // Build the iteration variable and its initialization before loop.
9234   ExprResult IV;
9235   ExprResult Init, CombInit;
9236   {
9237     VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv");
9238     IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc);
9239     Expr *RHS = (isOpenMPWorksharingDirective(DKind) ||
9240                  isOpenMPTaskLoopDirective(DKind) ||
9241                  isOpenMPDistributeDirective(DKind) ||
9242                  isOpenMPLoopTransformationDirective(DKind))
9243                     ? LB.get()
9244                     : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
9245     Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS);
9246     Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false);
9247 
9248     if (isOpenMPLoopBoundSharingDirective(DKind)) {
9249       Expr *CombRHS =
9250           (isOpenMPWorksharingDirective(DKind) ||
9251            isOpenMPTaskLoopDirective(DKind) ||
9252            isOpenMPDistributeDirective(DKind))
9253               ? CombLB.get()
9254               : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get();
9255       CombInit =
9256           SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS);
9257       CombInit =
9258           SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false);
9259     }
9260   }
9261 
9262   bool UseStrictCompare =
9263       RealVType->hasUnsignedIntegerRepresentation() &&
9264       llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) {
9265         return LIS.IsStrictCompare;
9266       });
9267   // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for
9268   // unsigned IV)) for worksharing loops.
9269   SourceLocation CondLoc = AStmt->getBeginLoc();
9270   Expr *BoundUB = UB.get();
9271   if (UseStrictCompare) {
9272     BoundUB =
9273         SemaRef
9274             .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB,
9275                         SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9276             .get();
9277     BoundUB =
9278         SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get();
9279   }
9280   ExprResult Cond =
9281       (isOpenMPWorksharingDirective(DKind) ||
9282        isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind) ||
9283        isOpenMPLoopTransformationDirective(DKind))
9284           ? SemaRef.BuildBinOp(CurScope, CondLoc,
9285                                UseStrictCompare ? BO_LT : BO_LE, IV.get(),
9286                                BoundUB)
9287           : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
9288                                NumIterations.get());
9289   ExprResult CombDistCond;
9290   if (isOpenMPLoopBoundSharingDirective(DKind)) {
9291     CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(),
9292                                       NumIterations.get());
9293   }
9294 
9295   ExprResult CombCond;
9296   if (isOpenMPLoopBoundSharingDirective(DKind)) {
9297     Expr *BoundCombUB = CombUB.get();
9298     if (UseStrictCompare) {
9299       BoundCombUB =
9300           SemaRef
9301               .BuildBinOp(
9302                   CurScope, CondLoc, BO_Add, BoundCombUB,
9303                   SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9304               .get();
9305       BoundCombUB =
9306           SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false)
9307               .get();
9308     }
9309     CombCond =
9310         SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
9311                            IV.get(), BoundCombUB);
9312   }
9313   // Loop increment (IV = IV + 1)
9314   SourceLocation IncLoc = AStmt->getBeginLoc();
9315   ExprResult Inc =
9316       SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(),
9317                          SemaRef.ActOnIntegerConstant(IncLoc, 1).get());
9318   if (!Inc.isUsable())
9319     return 0;
9320   Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get());
9321   Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false);
9322   if (!Inc.isUsable())
9323     return 0;
9324 
9325   // Increments for worksharing loops (LB = LB + ST; UB = UB + ST).
9326   // Used for directives with static scheduling.
9327   // In combined construct, add combined version that use CombLB and CombUB
9328   // base variables for the update
9329   ExprResult NextLB, NextUB, CombNextLB, CombNextUB;
9330   if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) ||
9331       isOpenMPDistributeDirective(DKind) ||
9332       isOpenMPLoopTransformationDirective(DKind)) {
9333     // LB + ST
9334     NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get());
9335     if (!NextLB.isUsable())
9336       return 0;
9337     // LB = LB + ST
9338     NextLB =
9339         SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get());
9340     NextLB =
9341         SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false);
9342     if (!NextLB.isUsable())
9343       return 0;
9344     // UB + ST
9345     NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get());
9346     if (!NextUB.isUsable())
9347       return 0;
9348     // UB = UB + ST
9349     NextUB =
9350         SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get());
9351     NextUB =
9352         SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false);
9353     if (!NextUB.isUsable())
9354       return 0;
9355     if (isOpenMPLoopBoundSharingDirective(DKind)) {
9356       CombNextLB =
9357           SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get());
9358       if (!NextLB.isUsable())
9359         return 0;
9360       // LB = LB + ST
9361       CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(),
9362                                       CombNextLB.get());
9363       CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(),
9364                                                /*DiscardedValue*/ false);
9365       if (!CombNextLB.isUsable())
9366         return 0;
9367       // UB + ST
9368       CombNextUB =
9369           SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get());
9370       if (!CombNextUB.isUsable())
9371         return 0;
9372       // UB = UB + ST
9373       CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(),
9374                                       CombNextUB.get());
9375       CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(),
9376                                                /*DiscardedValue*/ false);
9377       if (!CombNextUB.isUsable())
9378         return 0;
9379     }
9380   }
9381 
9382   // Create increment expression for distribute loop when combined in a same
9383   // directive with for as IV = IV + ST; ensure upper bound expression based
9384   // on PrevUB instead of NumIterations - used to implement 'for' when found
9385   // in combination with 'distribute', like in 'distribute parallel for'
9386   SourceLocation DistIncLoc = AStmt->getBeginLoc();
9387   ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond;
9388   if (isOpenMPLoopBoundSharingDirective(DKind)) {
9389     DistCond = SemaRef.BuildBinOp(
9390         CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB);
9391     assert(DistCond.isUsable() && "distribute cond expr was not built");
9392 
9393     DistInc =
9394         SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get());
9395     assert(DistInc.isUsable() && "distribute inc expr was not built");
9396     DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(),
9397                                  DistInc.get());
9398     DistInc =
9399         SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false);
9400     assert(DistInc.isUsable() && "distribute inc expr was not built");
9401 
9402     // Build expression: UB = min(UB, prevUB) for #for in composite or combined
9403     // construct
9404     ExprResult NewPrevUB = PrevUB;
9405     SourceLocation DistEUBLoc = AStmt->getBeginLoc();
9406     if (!SemaRef.Context.hasSameType(UB.get()->getType(),
9407                                      PrevUB.get()->getType())) {
9408       NewPrevUB = SemaRef.BuildCStyleCastExpr(
9409           DistEUBLoc,
9410           SemaRef.Context.getTrivialTypeSourceInfo(UB.get()->getType()),
9411           DistEUBLoc, NewPrevUB.get());
9412       if (!NewPrevUB.isUsable())
9413         return 0;
9414     }
9415     ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT,
9416                                                 UB.get(), NewPrevUB.get());
9417     ExprResult CondOp = SemaRef.ActOnConditionalOp(
9418         DistEUBLoc, DistEUBLoc, IsUBGreater.get(), NewPrevUB.get(), UB.get());
9419     PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(),
9420                                  CondOp.get());
9421     PrevEUB =
9422         SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false);
9423 
9424     // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in
9425     // parallel for is in combination with a distribute directive with
9426     // schedule(static, 1)
9427     Expr *BoundPrevUB = PrevUB.get();
9428     if (UseStrictCompare) {
9429       BoundPrevUB =
9430           SemaRef
9431               .BuildBinOp(
9432                   CurScope, CondLoc, BO_Add, BoundPrevUB,
9433                   SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get())
9434               .get();
9435       BoundPrevUB =
9436           SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false)
9437               .get();
9438     }
9439     ParForInDistCond =
9440         SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE,
9441                            IV.get(), BoundPrevUB);
9442   }
9443 
9444   // Build updates and final values of the loop counters.
9445   bool HasErrors = false;
9446   Built.Counters.resize(NestedLoopCount);
9447   Built.Inits.resize(NestedLoopCount);
9448   Built.Updates.resize(NestedLoopCount);
9449   Built.Finals.resize(NestedLoopCount);
9450   Built.DependentCounters.resize(NestedLoopCount);
9451   Built.DependentInits.resize(NestedLoopCount);
9452   Built.FinalsConditions.resize(NestedLoopCount);
9453   {
9454     // We implement the following algorithm for obtaining the
9455     // original loop iteration variable values based on the
9456     // value of the collapsed loop iteration variable IV.
9457     //
9458     // Let n+1 be the number of collapsed loops in the nest.
9459     // Iteration variables (I0, I1, .... In)
9460     // Iteration counts (N0, N1, ... Nn)
9461     //
9462     // Acc = IV;
9463     //
9464     // To compute Ik for loop k, 0 <= k <= n, generate:
9465     //    Prod = N(k+1) * N(k+2) * ... * Nn;
9466     //    Ik = Acc / Prod;
9467     //    Acc -= Ik * Prod;
9468     //
9469     ExprResult Acc = IV;
9470     for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) {
9471       LoopIterationSpace &IS = IterSpaces[Cnt];
9472       SourceLocation UpdLoc = IS.IncSrcRange.getBegin();
9473       ExprResult Iter;
9474 
9475       // Compute prod
9476       ExprResult Prod =
9477           SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
9478       for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K)
9479         Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(),
9480                                   IterSpaces[K].NumIterations);
9481 
9482       // Iter = Acc / Prod
9483       // If there is at least one more inner loop to avoid
9484       // multiplication by 1.
9485       if (Cnt + 1 < NestedLoopCount)
9486         Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div,
9487                                   Acc.get(), Prod.get());
9488       else
9489         Iter = Acc;
9490       if (!Iter.isUsable()) {
9491         HasErrors = true;
9492         break;
9493       }
9494 
9495       // Update Acc:
9496       // Acc -= Iter * Prod
9497       // Check if there is at least one more inner loop to avoid
9498       // multiplication by 1.
9499       if (Cnt + 1 < NestedLoopCount)
9500         Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul,
9501                                   Iter.get(), Prod.get());
9502       else
9503         Prod = Iter;
9504       Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub,
9505                                Acc.get(), Prod.get());
9506 
9507       // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step
9508       auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl());
9509       DeclRefExpr *CounterVar = buildDeclRefExpr(
9510           SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(),
9511           /*RefersToCapture=*/true);
9512       ExprResult Init =
9513           buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar,
9514                            IS.CounterInit, IS.IsNonRectangularLB, Captures);
9515       if (!Init.isUsable()) {
9516         HasErrors = true;
9517         break;
9518       }
9519       ExprResult Update = buildCounterUpdate(
9520           SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter,
9521           IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures);
9522       if (!Update.isUsable()) {
9523         HasErrors = true;
9524         break;
9525       }
9526 
9527       // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step
9528       ExprResult Final =
9529           buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar,
9530                              IS.CounterInit, IS.NumIterations, IS.CounterStep,
9531                              IS.Subtract, IS.IsNonRectangularLB, &Captures);
9532       if (!Final.isUsable()) {
9533         HasErrors = true;
9534         break;
9535       }
9536 
9537       if (!Update.isUsable() || !Final.isUsable()) {
9538         HasErrors = true;
9539         break;
9540       }
9541       // Save results
9542       Built.Counters[Cnt] = IS.CounterVar;
9543       Built.PrivateCounters[Cnt] = IS.PrivateCounterVar;
9544       Built.Inits[Cnt] = Init.get();
9545       Built.Updates[Cnt] = Update.get();
9546       Built.Finals[Cnt] = Final.get();
9547       Built.DependentCounters[Cnt] = nullptr;
9548       Built.DependentInits[Cnt] = nullptr;
9549       Built.FinalsConditions[Cnt] = nullptr;
9550       if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) {
9551         Built.DependentCounters[Cnt] =
9552             Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx];
9553         Built.DependentInits[Cnt] =
9554             Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx];
9555         Built.FinalsConditions[Cnt] = IS.FinalCondition;
9556       }
9557     }
9558   }
9559 
9560   if (HasErrors)
9561     return 0;
9562 
9563   // Save results
9564   Built.IterationVarRef = IV.get();
9565   Built.LastIteration = LastIteration.get();
9566   Built.NumIterations = NumIterations.get();
9567   Built.CalcLastIteration = SemaRef
9568                                 .ActOnFinishFullExpr(CalcLastIteration.get(),
9569                                                      /*DiscardedValue=*/false)
9570                                 .get();
9571   Built.PreCond = PreCond.get();
9572   Built.PreInits = buildPreInits(C, Captures);
9573   Built.Cond = Cond.get();
9574   Built.Init = Init.get();
9575   Built.Inc = Inc.get();
9576   Built.LB = LB.get();
9577   Built.UB = UB.get();
9578   Built.IL = IL.get();
9579   Built.ST = ST.get();
9580   Built.EUB = EUB.get();
9581   Built.NLB = NextLB.get();
9582   Built.NUB = NextUB.get();
9583   Built.PrevLB = PrevLB.get();
9584   Built.PrevUB = PrevUB.get();
9585   Built.DistInc = DistInc.get();
9586   Built.PrevEUB = PrevEUB.get();
9587   Built.DistCombinedFields.LB = CombLB.get();
9588   Built.DistCombinedFields.UB = CombUB.get();
9589   Built.DistCombinedFields.EUB = CombEUB.get();
9590   Built.DistCombinedFields.Init = CombInit.get();
9591   Built.DistCombinedFields.Cond = CombCond.get();
9592   Built.DistCombinedFields.NLB = CombNextLB.get();
9593   Built.DistCombinedFields.NUB = CombNextUB.get();
9594   Built.DistCombinedFields.DistCond = CombDistCond.get();
9595   Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get();
9596 
9597   return NestedLoopCount;
9598 }
9599 
getCollapseNumberExpr(ArrayRef<OMPClause * > Clauses)9600 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) {
9601   auto CollapseClauses =
9602       OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses);
9603   if (CollapseClauses.begin() != CollapseClauses.end())
9604     return (*CollapseClauses.begin())->getNumForLoops();
9605   return nullptr;
9606 }
9607 
getOrderedNumberExpr(ArrayRef<OMPClause * > Clauses)9608 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) {
9609   auto OrderedClauses =
9610       OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses);
9611   if (OrderedClauses.begin() != OrderedClauses.end())
9612     return (*OrderedClauses.begin())->getNumForLoops();
9613   return nullptr;
9614 }
9615 
checkSimdlenSafelenSpecified(Sema & S,const ArrayRef<OMPClause * > Clauses)9616 static bool checkSimdlenSafelenSpecified(Sema &S,
9617                                          const ArrayRef<OMPClause *> Clauses) {
9618   const OMPSafelenClause *Safelen = nullptr;
9619   const OMPSimdlenClause *Simdlen = nullptr;
9620 
9621   for (const OMPClause *Clause : Clauses) {
9622     if (Clause->getClauseKind() == OMPC_safelen)
9623       Safelen = cast<OMPSafelenClause>(Clause);
9624     else if (Clause->getClauseKind() == OMPC_simdlen)
9625       Simdlen = cast<OMPSimdlenClause>(Clause);
9626     if (Safelen && Simdlen)
9627       break;
9628   }
9629 
9630   if (Simdlen && Safelen) {
9631     const Expr *SimdlenLength = Simdlen->getSimdlen();
9632     const Expr *SafelenLength = Safelen->getSafelen();
9633     if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() ||
9634         SimdlenLength->isInstantiationDependent() ||
9635         SimdlenLength->containsUnexpandedParameterPack())
9636       return false;
9637     if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() ||
9638         SafelenLength->isInstantiationDependent() ||
9639         SafelenLength->containsUnexpandedParameterPack())
9640       return false;
9641     Expr::EvalResult SimdlenResult, SafelenResult;
9642     SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context);
9643     SafelenLength->EvaluateAsInt(SafelenResult, S.Context);
9644     llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt();
9645     llvm::APSInt SafelenRes = SafelenResult.Val.getInt();
9646     // OpenMP 4.5 [2.8.1, simd Construct, Restrictions]
9647     // If both simdlen and safelen clauses are specified, the value of the
9648     // simdlen parameter must be less than or equal to the value of the safelen
9649     // parameter.
9650     if (SimdlenRes > SafelenRes) {
9651       S.Diag(SimdlenLength->getExprLoc(),
9652              diag::err_omp_wrong_simdlen_safelen_values)
9653           << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange();
9654       return true;
9655     }
9656   }
9657   return false;
9658 }
9659 
9660 StmtResult
ActOnOpenMPSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)9661 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
9662                                SourceLocation StartLoc, SourceLocation EndLoc,
9663                                VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9664   if (!AStmt)
9665     return StmtError();
9666 
9667   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9668   OMPLoopBasedDirective::HelperExprs B;
9669   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9670   // define the nested loops number.
9671   unsigned NestedLoopCount = checkOpenMPLoop(
9672       OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
9673       AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
9674   if (NestedLoopCount == 0)
9675     return StmtError();
9676 
9677   assert((CurContext->isDependentContext() || B.builtAll()) &&
9678          "omp simd loop exprs were not built");
9679 
9680   if (!CurContext->isDependentContext()) {
9681     // Finalize the clauses that need pre-built expressions for CodeGen.
9682     for (OMPClause *C : Clauses) {
9683       if (auto *LC = dyn_cast<OMPLinearClause>(C))
9684         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9685                                      B.NumIterations, *this, CurScope,
9686                                      DSAStack))
9687           return StmtError();
9688     }
9689   }
9690 
9691   if (checkSimdlenSafelenSpecified(*this, Clauses))
9692     return StmtError();
9693 
9694   setFunctionHasBranchProtectedScope();
9695   return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
9696                                   Clauses, AStmt, B);
9697 }
9698 
9699 StmtResult
ActOnOpenMPForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)9700 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt,
9701                               SourceLocation StartLoc, SourceLocation EndLoc,
9702                               VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9703   if (!AStmt)
9704     return StmtError();
9705 
9706   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9707   OMPLoopBasedDirective::HelperExprs B;
9708   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9709   // define the nested loops number.
9710   unsigned NestedLoopCount = checkOpenMPLoop(
9711       OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses),
9712       AStmt, *this, *DSAStack, VarsWithImplicitDSA, B);
9713   if (NestedLoopCount == 0)
9714     return StmtError();
9715 
9716   assert((CurContext->isDependentContext() || B.builtAll()) &&
9717          "omp for loop exprs were not built");
9718 
9719   if (!CurContext->isDependentContext()) {
9720     // Finalize the clauses that need pre-built expressions for CodeGen.
9721     for (OMPClause *C : Clauses) {
9722       if (auto *LC = dyn_cast<OMPLinearClause>(C))
9723         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9724                                      B.NumIterations, *this, CurScope,
9725                                      DSAStack))
9726           return StmtError();
9727     }
9728   }
9729 
9730   setFunctionHasBranchProtectedScope();
9731   return OMPForDirective::Create(
9732       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
9733       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
9734 }
9735 
ActOnOpenMPForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)9736 StmtResult Sema::ActOnOpenMPForSimdDirective(
9737     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9738     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9739   if (!AStmt)
9740     return StmtError();
9741 
9742   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9743   OMPLoopBasedDirective::HelperExprs B;
9744   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
9745   // define the nested loops number.
9746   unsigned NestedLoopCount =
9747       checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses),
9748                       getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
9749                       VarsWithImplicitDSA, B);
9750   if (NestedLoopCount == 0)
9751     return StmtError();
9752 
9753   assert((CurContext->isDependentContext() || B.builtAll()) &&
9754          "omp for simd loop exprs were not built");
9755 
9756   if (!CurContext->isDependentContext()) {
9757     // Finalize the clauses that need pre-built expressions for CodeGen.
9758     for (OMPClause *C : Clauses) {
9759       if (auto *LC = dyn_cast<OMPLinearClause>(C))
9760         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
9761                                      B.NumIterations, *this, CurScope,
9762                                      DSAStack))
9763           return StmtError();
9764     }
9765   }
9766 
9767   if (checkSimdlenSafelenSpecified(*this, Clauses))
9768     return StmtError();
9769 
9770   setFunctionHasBranchProtectedScope();
9771   return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount,
9772                                      Clauses, AStmt, B);
9773 }
9774 
ActOnOpenMPSectionsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9775 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses,
9776                                               Stmt *AStmt,
9777                                               SourceLocation StartLoc,
9778                                               SourceLocation EndLoc) {
9779   if (!AStmt)
9780     return StmtError();
9781 
9782   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9783   auto BaseStmt = AStmt;
9784   while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
9785     BaseStmt = CS->getCapturedStmt();
9786   if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
9787     auto S = C->children();
9788     if (S.begin() == S.end())
9789       return StmtError();
9790     // All associated statements must be '#pragma omp section' except for
9791     // the first one.
9792     for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
9793       if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
9794         if (SectionStmt)
9795           Diag(SectionStmt->getBeginLoc(),
9796                diag::err_omp_sections_substmt_not_section);
9797         return StmtError();
9798       }
9799       cast<OMPSectionDirective>(SectionStmt)
9800           ->setHasCancel(DSAStack->isCancelRegion());
9801     }
9802   } else {
9803     Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt);
9804     return StmtError();
9805   }
9806 
9807   setFunctionHasBranchProtectedScope();
9808 
9809   return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
9810                                       DSAStack->getTaskgroupReductionRef(),
9811                                       DSAStack->isCancelRegion());
9812 }
9813 
ActOnOpenMPSectionDirective(Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9814 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt,
9815                                              SourceLocation StartLoc,
9816                                              SourceLocation EndLoc) {
9817   if (!AStmt)
9818     return StmtError();
9819 
9820   setFunctionHasBranchProtectedScope();
9821   DSAStack->setParentCancelRegion(DSAStack->isCancelRegion());
9822 
9823   return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt,
9824                                      DSAStack->isCancelRegion());
9825 }
9826 
getDirectCallExpr(Expr * E)9827 static Expr *getDirectCallExpr(Expr *E) {
9828   E = E->IgnoreParenCasts()->IgnoreImplicit();
9829   if (auto *CE = dyn_cast<CallExpr>(E))
9830     if (CE->getDirectCallee())
9831       return E;
9832   return nullptr;
9833 }
9834 
ActOnOpenMPDispatchDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9835 StmtResult Sema::ActOnOpenMPDispatchDirective(ArrayRef<OMPClause *> Clauses,
9836                                               Stmt *AStmt,
9837                                               SourceLocation StartLoc,
9838                                               SourceLocation EndLoc) {
9839   if (!AStmt)
9840     return StmtError();
9841 
9842   Stmt *S = cast<CapturedStmt>(AStmt)->getCapturedStmt();
9843 
9844   // 5.1 OpenMP
9845   // expression-stmt : an expression statement with one of the following forms:
9846   //   expression = target-call ( [expression-list] );
9847   //   target-call ( [expression-list] );
9848 
9849   SourceLocation TargetCallLoc;
9850 
9851   if (!CurContext->isDependentContext()) {
9852     Expr *TargetCall = nullptr;
9853 
9854     auto *E = dyn_cast<Expr>(S);
9855     if (!E) {
9856       Diag(S->getBeginLoc(), diag::err_omp_dispatch_statement_call);
9857       return StmtError();
9858     }
9859 
9860     E = E->IgnoreParenCasts()->IgnoreImplicit();
9861 
9862     if (auto *BO = dyn_cast<BinaryOperator>(E)) {
9863       if (BO->getOpcode() == BO_Assign)
9864         TargetCall = getDirectCallExpr(BO->getRHS());
9865     } else {
9866       if (auto *COCE = dyn_cast<CXXOperatorCallExpr>(E))
9867         if (COCE->getOperator() == OO_Equal)
9868           TargetCall = getDirectCallExpr(COCE->getArg(1));
9869       if (!TargetCall)
9870         TargetCall = getDirectCallExpr(E);
9871     }
9872     if (!TargetCall) {
9873       Diag(E->getBeginLoc(), diag::err_omp_dispatch_statement_call);
9874       return StmtError();
9875     }
9876     TargetCallLoc = TargetCall->getExprLoc();
9877   }
9878 
9879   setFunctionHasBranchProtectedScope();
9880 
9881   return OMPDispatchDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
9882                                       TargetCallLoc);
9883 }
9884 
ActOnOpenMPSingleDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9885 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses,
9886                                             Stmt *AStmt,
9887                                             SourceLocation StartLoc,
9888                                             SourceLocation EndLoc) {
9889   if (!AStmt)
9890     return StmtError();
9891 
9892   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
9893 
9894   setFunctionHasBranchProtectedScope();
9895 
9896   // OpenMP [2.7.3, single Construct, Restrictions]
9897   // The copyprivate clause must not be used with the nowait clause.
9898   const OMPClause *Nowait = nullptr;
9899   const OMPClause *Copyprivate = nullptr;
9900   for (const OMPClause *Clause : Clauses) {
9901     if (Clause->getClauseKind() == OMPC_nowait)
9902       Nowait = Clause;
9903     else if (Clause->getClauseKind() == OMPC_copyprivate)
9904       Copyprivate = Clause;
9905     if (Copyprivate && Nowait) {
9906       Diag(Copyprivate->getBeginLoc(),
9907            diag::err_omp_single_copyprivate_with_nowait);
9908       Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here);
9909       return StmtError();
9910     }
9911   }
9912 
9913   return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9914 }
9915 
ActOnOpenMPMasterDirective(Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9916 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt,
9917                                             SourceLocation StartLoc,
9918                                             SourceLocation EndLoc) {
9919   if (!AStmt)
9920     return StmtError();
9921 
9922   setFunctionHasBranchProtectedScope();
9923 
9924   return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt);
9925 }
9926 
ActOnOpenMPMaskedDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9927 StmtResult Sema::ActOnOpenMPMaskedDirective(ArrayRef<OMPClause *> Clauses,
9928                                             Stmt *AStmt,
9929                                             SourceLocation StartLoc,
9930                                             SourceLocation EndLoc) {
9931   if (!AStmt)
9932     return StmtError();
9933 
9934   setFunctionHasBranchProtectedScope();
9935 
9936   return OMPMaskedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
9937 }
9938 
ActOnOpenMPCriticalDirective(const DeclarationNameInfo & DirName,ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)9939 StmtResult Sema::ActOnOpenMPCriticalDirective(
9940     const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses,
9941     Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) {
9942   if (!AStmt)
9943     return StmtError();
9944 
9945   bool ErrorFound = false;
9946   llvm::APSInt Hint;
9947   SourceLocation HintLoc;
9948   bool DependentHint = false;
9949   for (const OMPClause *C : Clauses) {
9950     if (C->getClauseKind() == OMPC_hint) {
9951       if (!DirName.getName()) {
9952         Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name);
9953         ErrorFound = true;
9954       }
9955       Expr *E = cast<OMPHintClause>(C)->getHint();
9956       if (E->isTypeDependent() || E->isValueDependent() ||
9957           E->isInstantiationDependent()) {
9958         DependentHint = true;
9959       } else {
9960         Hint = E->EvaluateKnownConstInt(Context);
9961         HintLoc = C->getBeginLoc();
9962       }
9963     }
9964   }
9965   if (ErrorFound)
9966     return StmtError();
9967   const auto Pair = DSAStack->getCriticalWithHint(DirName);
9968   if (Pair.first && DirName.getName() && !DependentHint) {
9969     if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) {
9970       Diag(StartLoc, diag::err_omp_critical_with_hint);
9971       if (HintLoc.isValid())
9972         Diag(HintLoc, diag::note_omp_critical_hint_here)
9973             << 0 << toString(Hint, /*Radix=*/10, /*Signed=*/false);
9974       else
9975         Diag(StartLoc, diag::note_omp_critical_no_hint) << 0;
9976       if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) {
9977         Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here)
9978             << 1
9979             << toString(C->getHint()->EvaluateKnownConstInt(Context),
9980                         /*Radix=*/10, /*Signed=*/false);
9981       } else {
9982         Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1;
9983       }
9984     }
9985   }
9986 
9987   setFunctionHasBranchProtectedScope();
9988 
9989   auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc,
9990                                            Clauses, AStmt);
9991   if (!Pair.first && DirName.getName() && !DependentHint)
9992     DSAStack->addCriticalWithHint(Dir, Hint);
9993   return Dir;
9994 }
9995 
ActOnOpenMPParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)9996 StmtResult Sema::ActOnOpenMPParallelForDirective(
9997     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
9998     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
9999   if (!AStmt)
10000     return StmtError();
10001 
10002   auto *CS = cast<CapturedStmt>(AStmt);
10003   // 1.2.2 OpenMP Language Terminology
10004   // Structured block - An executable statement with a single entry at the
10005   // top and a single exit at the bottom.
10006   // The point of exit cannot be a branch out of the structured block.
10007   // longjmp() and throw() must not violate the entry/exit criteria.
10008   CS->getCapturedDecl()->setNothrow();
10009 
10010   OMPLoopBasedDirective::HelperExprs B;
10011   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10012   // define the nested loops number.
10013   unsigned NestedLoopCount =
10014       checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses),
10015                       getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
10016                       VarsWithImplicitDSA, B);
10017   if (NestedLoopCount == 0)
10018     return StmtError();
10019 
10020   assert((CurContext->isDependentContext() || B.builtAll()) &&
10021          "omp parallel for loop exprs were not built");
10022 
10023   if (!CurContext->isDependentContext()) {
10024     // Finalize the clauses that need pre-built expressions for CodeGen.
10025     for (OMPClause *C : Clauses) {
10026       if (auto *LC = dyn_cast<OMPLinearClause>(C))
10027         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10028                                      B.NumIterations, *this, CurScope,
10029                                      DSAStack))
10030           return StmtError();
10031     }
10032   }
10033 
10034   setFunctionHasBranchProtectedScope();
10035   return OMPParallelForDirective::Create(
10036       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
10037       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10038 }
10039 
ActOnOpenMPParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)10040 StmtResult Sema::ActOnOpenMPParallelForSimdDirective(
10041     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
10042     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
10043   if (!AStmt)
10044     return StmtError();
10045 
10046   auto *CS = cast<CapturedStmt>(AStmt);
10047   // 1.2.2 OpenMP Language Terminology
10048   // Structured block - An executable statement with a single entry at the
10049   // top and a single exit at the bottom.
10050   // The point of exit cannot be a branch out of the structured block.
10051   // longjmp() and throw() must not violate the entry/exit criteria.
10052   CS->getCapturedDecl()->setNothrow();
10053 
10054   OMPLoopBasedDirective::HelperExprs B;
10055   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
10056   // define the nested loops number.
10057   unsigned NestedLoopCount =
10058       checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses),
10059                       getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack,
10060                       VarsWithImplicitDSA, B);
10061   if (NestedLoopCount == 0)
10062     return StmtError();
10063 
10064   if (!CurContext->isDependentContext()) {
10065     // Finalize the clauses that need pre-built expressions for CodeGen.
10066     for (OMPClause *C : Clauses) {
10067       if (auto *LC = dyn_cast<OMPLinearClause>(C))
10068         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
10069                                      B.NumIterations, *this, CurScope,
10070                                      DSAStack))
10071           return StmtError();
10072     }
10073   }
10074 
10075   if (checkSimdlenSafelenSpecified(*this, Clauses))
10076     return StmtError();
10077 
10078   setFunctionHasBranchProtectedScope();
10079   return OMPParallelForSimdDirective::Create(
10080       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
10081 }
10082 
10083 StmtResult
ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10084 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses,
10085                                          Stmt *AStmt, SourceLocation StartLoc,
10086                                          SourceLocation EndLoc) {
10087   if (!AStmt)
10088     return StmtError();
10089 
10090   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10091   auto *CS = cast<CapturedStmt>(AStmt);
10092   // 1.2.2 OpenMP Language Terminology
10093   // Structured block - An executable statement with a single entry at the
10094   // top and a single exit at the bottom.
10095   // The point of exit cannot be a branch out of the structured block.
10096   // longjmp() and throw() must not violate the entry/exit criteria.
10097   CS->getCapturedDecl()->setNothrow();
10098 
10099   setFunctionHasBranchProtectedScope();
10100 
10101   return OMPParallelMasterDirective::Create(
10102       Context, StartLoc, EndLoc, Clauses, AStmt,
10103       DSAStack->getTaskgroupReductionRef());
10104 }
10105 
10106 StmtResult
ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10107 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses,
10108                                            Stmt *AStmt, SourceLocation StartLoc,
10109                                            SourceLocation EndLoc) {
10110   if (!AStmt)
10111     return StmtError();
10112 
10113   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10114   auto BaseStmt = AStmt;
10115   while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt))
10116     BaseStmt = CS->getCapturedStmt();
10117   if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) {
10118     auto S = C->children();
10119     if (S.begin() == S.end())
10120       return StmtError();
10121     // All associated statements must be '#pragma omp section' except for
10122     // the first one.
10123     for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) {
10124       if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) {
10125         if (SectionStmt)
10126           Diag(SectionStmt->getBeginLoc(),
10127                diag::err_omp_parallel_sections_substmt_not_section);
10128         return StmtError();
10129       }
10130       cast<OMPSectionDirective>(SectionStmt)
10131           ->setHasCancel(DSAStack->isCancelRegion());
10132     }
10133   } else {
10134     Diag(AStmt->getBeginLoc(),
10135          diag::err_omp_parallel_sections_not_compound_stmt);
10136     return StmtError();
10137   }
10138 
10139   setFunctionHasBranchProtectedScope();
10140 
10141   return OMPParallelSectionsDirective::Create(
10142       Context, StartLoc, EndLoc, Clauses, AStmt,
10143       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
10144 }
10145 
10146 /// Find and diagnose mutually exclusive clause kinds.
checkMutuallyExclusiveClauses(Sema & S,ArrayRef<OMPClause * > Clauses,ArrayRef<OpenMPClauseKind> MutuallyExclusiveClauses)10147 static bool checkMutuallyExclusiveClauses(
10148     Sema &S, ArrayRef<OMPClause *> Clauses,
10149     ArrayRef<OpenMPClauseKind> MutuallyExclusiveClauses) {
10150   const OMPClause *PrevClause = nullptr;
10151   bool ErrorFound = false;
10152   for (const OMPClause *C : Clauses) {
10153     if (llvm::is_contained(MutuallyExclusiveClauses, C->getClauseKind())) {
10154       if (!PrevClause) {
10155         PrevClause = C;
10156       } else if (PrevClause->getClauseKind() != C->getClauseKind()) {
10157         S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive)
10158             << getOpenMPClauseName(C->getClauseKind())
10159             << getOpenMPClauseName(PrevClause->getClauseKind());
10160         S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause)
10161             << getOpenMPClauseName(PrevClause->getClauseKind());
10162         ErrorFound = true;
10163       }
10164     }
10165   }
10166   return ErrorFound;
10167 }
10168 
ActOnOpenMPTaskDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10169 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses,
10170                                           Stmt *AStmt, SourceLocation StartLoc,
10171                                           SourceLocation EndLoc) {
10172   if (!AStmt)
10173     return StmtError();
10174 
10175   // OpenMP 5.0, 2.10.1 task Construct
10176   // If a detach clause appears on the directive, then a mergeable clause cannot
10177   // appear on the same directive.
10178   if (checkMutuallyExclusiveClauses(*this, Clauses,
10179                                     {OMPC_detach, OMPC_mergeable}))
10180     return StmtError();
10181 
10182   auto *CS = cast<CapturedStmt>(AStmt);
10183   // 1.2.2 OpenMP Language Terminology
10184   // Structured block - An executable statement with a single entry at the
10185   // top and a single exit at the bottom.
10186   // The point of exit cannot be a branch out of the structured block.
10187   // longjmp() and throw() must not violate the entry/exit criteria.
10188   CS->getCapturedDecl()->setNothrow();
10189 
10190   setFunctionHasBranchProtectedScope();
10191 
10192   return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
10193                                   DSAStack->isCancelRegion());
10194 }
10195 
ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,SourceLocation EndLoc)10196 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc,
10197                                                SourceLocation EndLoc) {
10198   return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc);
10199 }
10200 
ActOnOpenMPBarrierDirective(SourceLocation StartLoc,SourceLocation EndLoc)10201 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc,
10202                                              SourceLocation EndLoc) {
10203   return OMPBarrierDirective::Create(Context, StartLoc, EndLoc);
10204 }
10205 
ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,SourceLocation EndLoc)10206 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
10207                                               SourceLocation EndLoc) {
10208   return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
10209 }
10210 
ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10211 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
10212                                                Stmt *AStmt,
10213                                                SourceLocation StartLoc,
10214                                                SourceLocation EndLoc) {
10215   if (!AStmt)
10216     return StmtError();
10217 
10218   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10219 
10220   setFunctionHasBranchProtectedScope();
10221 
10222   return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
10223                                        AStmt,
10224                                        DSAStack->getTaskgroupReductionRef());
10225 }
10226 
ActOnOpenMPFlushDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)10227 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
10228                                            SourceLocation StartLoc,
10229                                            SourceLocation EndLoc) {
10230   OMPFlushClause *FC = nullptr;
10231   OMPClause *OrderClause = nullptr;
10232   for (OMPClause *C : Clauses) {
10233     if (C->getClauseKind() == OMPC_flush)
10234       FC = cast<OMPFlushClause>(C);
10235     else
10236       OrderClause = C;
10237   }
10238   OpenMPClauseKind MemOrderKind = OMPC_unknown;
10239   SourceLocation MemOrderLoc;
10240   for (const OMPClause *C : Clauses) {
10241     if (C->getClauseKind() == OMPC_acq_rel ||
10242         C->getClauseKind() == OMPC_acquire ||
10243         C->getClauseKind() == OMPC_release) {
10244       if (MemOrderKind != OMPC_unknown) {
10245         Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
10246             << getOpenMPDirectiveName(OMPD_flush) << 1
10247             << SourceRange(C->getBeginLoc(), C->getEndLoc());
10248         Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
10249             << getOpenMPClauseName(MemOrderKind);
10250       } else {
10251         MemOrderKind = C->getClauseKind();
10252         MemOrderLoc = C->getBeginLoc();
10253       }
10254     }
10255   }
10256   if (FC && OrderClause) {
10257     Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list)
10258         << getOpenMPClauseName(OrderClause->getClauseKind());
10259     Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here)
10260         << getOpenMPClauseName(OrderClause->getClauseKind());
10261     return StmtError();
10262   }
10263   return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses);
10264 }
10265 
ActOnOpenMPDepobjDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)10266 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses,
10267                                             SourceLocation StartLoc,
10268                                             SourceLocation EndLoc) {
10269   if (Clauses.empty()) {
10270     Diag(StartLoc, diag::err_omp_depobj_expected);
10271     return StmtError();
10272   } else if (Clauses[0]->getClauseKind() != OMPC_depobj) {
10273     Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected);
10274     return StmtError();
10275   }
10276   // Only depobj expression and another single clause is allowed.
10277   if (Clauses.size() > 2) {
10278     Diag(Clauses[2]->getBeginLoc(),
10279          diag::err_omp_depobj_single_clause_expected);
10280     return StmtError();
10281   } else if (Clauses.size() < 1) {
10282     Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected);
10283     return StmtError();
10284   }
10285   return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses);
10286 }
10287 
ActOnOpenMPScanDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)10288 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses,
10289                                           SourceLocation StartLoc,
10290                                           SourceLocation EndLoc) {
10291   // Check that exactly one clause is specified.
10292   if (Clauses.size() != 1) {
10293     Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(),
10294          diag::err_omp_scan_single_clause_expected);
10295     return StmtError();
10296   }
10297   // Check that scan directive is used in the scopeof the OpenMP loop body.
10298   if (Scope *S = DSAStack->getCurScope()) {
10299     Scope *ParentS = S->getParent();
10300     if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() ||
10301         !ParentS->getBreakParent()->isOpenMPLoopScope())
10302       return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive)
10303                        << getOpenMPDirectiveName(OMPD_scan) << 5);
10304   }
10305   // Check that only one instance of scan directives is used in the same outer
10306   // region.
10307   if (DSAStack->doesParentHasScanDirective()) {
10308     Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan";
10309     Diag(DSAStack->getParentScanDirectiveLoc(),
10310          diag::note_omp_previous_directive)
10311         << "scan";
10312     return StmtError();
10313   }
10314   DSAStack->setParentHasScanDirective(StartLoc);
10315   return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses);
10316 }
10317 
ActOnOpenMPOrderedDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10318 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses,
10319                                              Stmt *AStmt,
10320                                              SourceLocation StartLoc,
10321                                              SourceLocation EndLoc) {
10322   const OMPClause *DependFound = nullptr;
10323   const OMPClause *DependSourceClause = nullptr;
10324   const OMPClause *DependSinkClause = nullptr;
10325   bool ErrorFound = false;
10326   const OMPThreadsClause *TC = nullptr;
10327   const OMPSIMDClause *SC = nullptr;
10328   for (const OMPClause *C : Clauses) {
10329     if (auto *DC = dyn_cast<OMPDependClause>(C)) {
10330       DependFound = C;
10331       if (DC->getDependencyKind() == OMPC_DEPEND_source) {
10332         if (DependSourceClause) {
10333           Diag(C->getBeginLoc(), diag::err_omp_more_one_clause)
10334               << getOpenMPDirectiveName(OMPD_ordered)
10335               << getOpenMPClauseName(OMPC_depend) << 2;
10336           ErrorFound = true;
10337         } else {
10338           DependSourceClause = C;
10339         }
10340         if (DependSinkClause) {
10341           Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
10342               << 0;
10343           ErrorFound = true;
10344         }
10345       } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) {
10346         if (DependSourceClause) {
10347           Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed)
10348               << 1;
10349           ErrorFound = true;
10350         }
10351         DependSinkClause = C;
10352       }
10353     } else if (C->getClauseKind() == OMPC_threads) {
10354       TC = cast<OMPThreadsClause>(C);
10355     } else if (C->getClauseKind() == OMPC_simd) {
10356       SC = cast<OMPSIMDClause>(C);
10357     }
10358   }
10359   if (!ErrorFound && !SC &&
10360       isOpenMPSimdDirective(DSAStack->getParentDirective())) {
10361     // OpenMP [2.8.1,simd Construct, Restrictions]
10362     // An ordered construct with the simd clause is the only OpenMP construct
10363     // that can appear in the simd region.
10364     Diag(StartLoc, diag::err_omp_prohibited_region_simd)
10365         << (LangOpts.OpenMP >= 50 ? 1 : 0);
10366     ErrorFound = true;
10367   } else if (DependFound && (TC || SC)) {
10368     Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd)
10369         << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind());
10370     ErrorFound = true;
10371   } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) {
10372     Diag(DependFound->getBeginLoc(),
10373          diag::err_omp_ordered_directive_without_param);
10374     ErrorFound = true;
10375   } else if (TC || Clauses.empty()) {
10376     if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) {
10377       SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc;
10378       Diag(ErrLoc, diag::err_omp_ordered_directive_with_param)
10379           << (TC != nullptr);
10380       Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1;
10381       ErrorFound = true;
10382     }
10383   }
10384   if ((!AStmt && !DependFound) || ErrorFound)
10385     return StmtError();
10386 
10387   // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions.
10388   // During execution of an iteration of a worksharing-loop or a loop nest
10389   // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread
10390   // must not execute more than one ordered region corresponding to an ordered
10391   // construct without a depend clause.
10392   if (!DependFound) {
10393     if (DSAStack->doesParentHasOrderedDirective()) {
10394       Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered";
10395       Diag(DSAStack->getParentOrderedDirectiveLoc(),
10396            diag::note_omp_previous_directive)
10397           << "ordered";
10398       return StmtError();
10399     }
10400     DSAStack->setParentHasOrderedDirective(StartLoc);
10401   }
10402 
10403   if (AStmt) {
10404     assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
10405 
10406     setFunctionHasBranchProtectedScope();
10407   }
10408 
10409   return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
10410 }
10411 
10412 namespace {
10413 /// Helper class for checking expression in 'omp atomic [update]'
10414 /// construct.
10415 class OpenMPAtomicUpdateChecker {
10416   /// Error results for atomic update expressions.
10417   enum ExprAnalysisErrorCode {
10418     /// A statement is not an expression statement.
10419     NotAnExpression,
10420     /// Expression is not builtin binary or unary operation.
10421     NotABinaryOrUnaryExpression,
10422     /// Unary operation is not post-/pre- increment/decrement operation.
10423     NotAnUnaryIncDecExpression,
10424     /// An expression is not of scalar type.
10425     NotAScalarType,
10426     /// A binary operation is not an assignment operation.
10427     NotAnAssignmentOp,
10428     /// RHS part of the binary operation is not a binary expression.
10429     NotABinaryExpression,
10430     /// RHS part is not additive/multiplicative/shift/biwise binary
10431     /// expression.
10432     NotABinaryOperator,
10433     /// RHS binary operation does not have reference to the updated LHS
10434     /// part.
10435     NotAnUpdateExpression,
10436     /// No errors is found.
10437     NoError
10438   };
10439   /// Reference to Sema.
10440   Sema &SemaRef;
10441   /// A location for note diagnostics (when error is found).
10442   SourceLocation NoteLoc;
10443   /// 'x' lvalue part of the source atomic expression.
10444   Expr *X;
10445   /// 'expr' rvalue part of the source atomic expression.
10446   Expr *E;
10447   /// Helper expression of the form
10448   /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
10449   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
10450   Expr *UpdateExpr;
10451   /// Is 'x' a LHS in a RHS part of full update expression. It is
10452   /// important for non-associative operations.
10453   bool IsXLHSInRHSPart;
10454   BinaryOperatorKind Op;
10455   SourceLocation OpLoc;
10456   /// true if the source expression is a postfix unary operation, false
10457   /// if it is a prefix unary operation.
10458   bool IsPostfixUpdate;
10459 
10460 public:
OpenMPAtomicUpdateChecker(Sema & SemaRef)10461   OpenMPAtomicUpdateChecker(Sema &SemaRef)
10462       : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr),
10463         IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {}
10464   /// Check specified statement that it is suitable for 'atomic update'
10465   /// constructs and extract 'x', 'expr' and Operation from the original
10466   /// expression. If DiagId and NoteId == 0, then only check is performed
10467   /// without error notification.
10468   /// \param DiagId Diagnostic which should be emitted if error is found.
10469   /// \param NoteId Diagnostic note for the main error message.
10470   /// \return true if statement is not an update expression, false otherwise.
10471   bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0);
10472   /// Return the 'x' lvalue part of the source atomic expression.
getX() const10473   Expr *getX() const { return X; }
10474   /// Return the 'expr' rvalue part of the source atomic expression.
getExpr() const10475   Expr *getExpr() const { return E; }
10476   /// Return the update expression used in calculation of the updated
10477   /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or
10478   /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'.
getUpdateExpr() const10479   Expr *getUpdateExpr() const { return UpdateExpr; }
10480   /// Return true if 'x' is LHS in RHS part of full update expression,
10481   /// false otherwise.
isXLHSInRHSPart() const10482   bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; }
10483 
10484   /// true if the source expression is a postfix unary operation, false
10485   /// if it is a prefix unary operation.
isPostfixUpdate() const10486   bool isPostfixUpdate() const { return IsPostfixUpdate; }
10487 
10488 private:
10489   bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0,
10490                             unsigned NoteId = 0);
10491 };
10492 } // namespace
10493 
checkBinaryOperation(BinaryOperator * AtomicBinOp,unsigned DiagId,unsigned NoteId)10494 bool OpenMPAtomicUpdateChecker::checkBinaryOperation(
10495     BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) {
10496   ExprAnalysisErrorCode ErrorFound = NoError;
10497   SourceLocation ErrorLoc, NoteLoc;
10498   SourceRange ErrorRange, NoteRange;
10499   // Allowed constructs are:
10500   //  x = x binop expr;
10501   //  x = expr binop x;
10502   if (AtomicBinOp->getOpcode() == BO_Assign) {
10503     X = AtomicBinOp->getLHS();
10504     if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>(
10505             AtomicBinOp->getRHS()->IgnoreParenImpCasts())) {
10506       if (AtomicInnerBinOp->isMultiplicativeOp() ||
10507           AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() ||
10508           AtomicInnerBinOp->isBitwiseOp()) {
10509         Op = AtomicInnerBinOp->getOpcode();
10510         OpLoc = AtomicInnerBinOp->getOperatorLoc();
10511         Expr *LHS = AtomicInnerBinOp->getLHS();
10512         Expr *RHS = AtomicInnerBinOp->getRHS();
10513         llvm::FoldingSetNodeID XId, LHSId, RHSId;
10514         X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(),
10515                                           /*Canonical=*/true);
10516         LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(),
10517                                             /*Canonical=*/true);
10518         RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(),
10519                                             /*Canonical=*/true);
10520         if (XId == LHSId) {
10521           E = RHS;
10522           IsXLHSInRHSPart = true;
10523         } else if (XId == RHSId) {
10524           E = LHS;
10525           IsXLHSInRHSPart = false;
10526         } else {
10527           ErrorLoc = AtomicInnerBinOp->getExprLoc();
10528           ErrorRange = AtomicInnerBinOp->getSourceRange();
10529           NoteLoc = X->getExprLoc();
10530           NoteRange = X->getSourceRange();
10531           ErrorFound = NotAnUpdateExpression;
10532         }
10533       } else {
10534         ErrorLoc = AtomicInnerBinOp->getExprLoc();
10535         ErrorRange = AtomicInnerBinOp->getSourceRange();
10536         NoteLoc = AtomicInnerBinOp->getOperatorLoc();
10537         NoteRange = SourceRange(NoteLoc, NoteLoc);
10538         ErrorFound = NotABinaryOperator;
10539       }
10540     } else {
10541       NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc();
10542       NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange();
10543       ErrorFound = NotABinaryExpression;
10544     }
10545   } else {
10546     ErrorLoc = AtomicBinOp->getExprLoc();
10547     ErrorRange = AtomicBinOp->getSourceRange();
10548     NoteLoc = AtomicBinOp->getOperatorLoc();
10549     NoteRange = SourceRange(NoteLoc, NoteLoc);
10550     ErrorFound = NotAnAssignmentOp;
10551   }
10552   if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
10553     SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
10554     SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
10555     return true;
10556   }
10557   if (SemaRef.CurContext->isDependentContext())
10558     E = X = UpdateExpr = nullptr;
10559   return ErrorFound != NoError;
10560 }
10561 
checkStatement(Stmt * S,unsigned DiagId,unsigned NoteId)10562 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId,
10563                                                unsigned NoteId) {
10564   ExprAnalysisErrorCode ErrorFound = NoError;
10565   SourceLocation ErrorLoc, NoteLoc;
10566   SourceRange ErrorRange, NoteRange;
10567   // Allowed constructs are:
10568   //  x++;
10569   //  x--;
10570   //  ++x;
10571   //  --x;
10572   //  x binop= expr;
10573   //  x = x binop expr;
10574   //  x = expr binop x;
10575   if (auto *AtomicBody = dyn_cast<Expr>(S)) {
10576     AtomicBody = AtomicBody->IgnoreParenImpCasts();
10577     if (AtomicBody->getType()->isScalarType() ||
10578         AtomicBody->isInstantiationDependent()) {
10579       if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>(
10580               AtomicBody->IgnoreParenImpCasts())) {
10581         // Check for Compound Assignment Operation
10582         Op = BinaryOperator::getOpForCompoundAssignment(
10583             AtomicCompAssignOp->getOpcode());
10584         OpLoc = AtomicCompAssignOp->getOperatorLoc();
10585         E = AtomicCompAssignOp->getRHS();
10586         X = AtomicCompAssignOp->getLHS()->IgnoreParens();
10587         IsXLHSInRHSPart = true;
10588       } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>(
10589                      AtomicBody->IgnoreParenImpCasts())) {
10590         // Check for Binary Operation
10591         if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId))
10592           return true;
10593       } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>(
10594                      AtomicBody->IgnoreParenImpCasts())) {
10595         // Check for Unary Operation
10596         if (AtomicUnaryOp->isIncrementDecrementOp()) {
10597           IsPostfixUpdate = AtomicUnaryOp->isPostfix();
10598           Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub;
10599           OpLoc = AtomicUnaryOp->getOperatorLoc();
10600           X = AtomicUnaryOp->getSubExpr()->IgnoreParens();
10601           E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get();
10602           IsXLHSInRHSPart = true;
10603         } else {
10604           ErrorFound = NotAnUnaryIncDecExpression;
10605           ErrorLoc = AtomicUnaryOp->getExprLoc();
10606           ErrorRange = AtomicUnaryOp->getSourceRange();
10607           NoteLoc = AtomicUnaryOp->getOperatorLoc();
10608           NoteRange = SourceRange(NoteLoc, NoteLoc);
10609         }
10610       } else if (!AtomicBody->isInstantiationDependent()) {
10611         ErrorFound = NotABinaryOrUnaryExpression;
10612         NoteLoc = ErrorLoc = AtomicBody->getExprLoc();
10613         NoteRange = ErrorRange = AtomicBody->getSourceRange();
10614       }
10615     } else {
10616       ErrorFound = NotAScalarType;
10617       NoteLoc = ErrorLoc = AtomicBody->getBeginLoc();
10618       NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10619     }
10620   } else {
10621     ErrorFound = NotAnExpression;
10622     NoteLoc = ErrorLoc = S->getBeginLoc();
10623     NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10624   }
10625   if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) {
10626     SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange;
10627     SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange;
10628     return true;
10629   }
10630   if (SemaRef.CurContext->isDependentContext())
10631     E = X = UpdateExpr = nullptr;
10632   if (ErrorFound == NoError && E && X) {
10633     // Build an update expression of form 'OpaqueValueExpr(x) binop
10634     // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop
10635     // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression.
10636     auto *OVEX = new (SemaRef.getASTContext())
10637         OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_PRValue);
10638     auto *OVEExpr = new (SemaRef.getASTContext())
10639         OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_PRValue);
10640     ExprResult Update =
10641         SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr,
10642                                    IsXLHSInRHSPart ? OVEExpr : OVEX);
10643     if (Update.isInvalid())
10644       return true;
10645     Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(),
10646                                                Sema::AA_Casting);
10647     if (Update.isInvalid())
10648       return true;
10649     UpdateExpr = Update.get();
10650   }
10651   return ErrorFound != NoError;
10652 }
10653 
ActOnOpenMPAtomicDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)10654 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses,
10655                                             Stmt *AStmt,
10656                                             SourceLocation StartLoc,
10657                                             SourceLocation EndLoc) {
10658   // Register location of the first atomic directive.
10659   DSAStack->addAtomicDirectiveLoc(StartLoc);
10660   if (!AStmt)
10661     return StmtError();
10662 
10663   // 1.2.2 OpenMP Language Terminology
10664   // Structured block - An executable statement with a single entry at the
10665   // top and a single exit at the bottom.
10666   // The point of exit cannot be a branch out of the structured block.
10667   // longjmp() and throw() must not violate the entry/exit criteria.
10668   OpenMPClauseKind AtomicKind = OMPC_unknown;
10669   SourceLocation AtomicKindLoc;
10670   OpenMPClauseKind MemOrderKind = OMPC_unknown;
10671   SourceLocation MemOrderLoc;
10672   for (const OMPClause *C : Clauses) {
10673     if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write ||
10674         C->getClauseKind() == OMPC_update ||
10675         C->getClauseKind() == OMPC_capture) {
10676       if (AtomicKind != OMPC_unknown) {
10677         Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses)
10678             << SourceRange(C->getBeginLoc(), C->getEndLoc());
10679         Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause)
10680             << getOpenMPClauseName(AtomicKind);
10681       } else {
10682         AtomicKind = C->getClauseKind();
10683         AtomicKindLoc = C->getBeginLoc();
10684       }
10685     }
10686     if (C->getClauseKind() == OMPC_seq_cst ||
10687         C->getClauseKind() == OMPC_acq_rel ||
10688         C->getClauseKind() == OMPC_acquire ||
10689         C->getClauseKind() == OMPC_release ||
10690         C->getClauseKind() == OMPC_relaxed) {
10691       if (MemOrderKind != OMPC_unknown) {
10692         Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses)
10693             << getOpenMPDirectiveName(OMPD_atomic) << 0
10694             << SourceRange(C->getBeginLoc(), C->getEndLoc());
10695         Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
10696             << getOpenMPClauseName(MemOrderKind);
10697       } else {
10698         MemOrderKind = C->getClauseKind();
10699         MemOrderLoc = C->getBeginLoc();
10700       }
10701     }
10702   }
10703   // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions
10704   // If atomic-clause is read then memory-order-clause must not be acq_rel or
10705   // release.
10706   // If atomic-clause is write then memory-order-clause must not be acq_rel or
10707   // acquire.
10708   // If atomic-clause is update or not present then memory-order-clause must not
10709   // be acq_rel or acquire.
10710   if ((AtomicKind == OMPC_read &&
10711        (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) ||
10712       ((AtomicKind == OMPC_write || AtomicKind == OMPC_update ||
10713         AtomicKind == OMPC_unknown) &&
10714        (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) {
10715     SourceLocation Loc = AtomicKindLoc;
10716     if (AtomicKind == OMPC_unknown)
10717       Loc = StartLoc;
10718     Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause)
10719         << getOpenMPClauseName(AtomicKind)
10720         << (AtomicKind == OMPC_unknown ? 1 : 0)
10721         << getOpenMPClauseName(MemOrderKind);
10722     Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause)
10723         << getOpenMPClauseName(MemOrderKind);
10724   }
10725 
10726   Stmt *Body = AStmt;
10727   if (auto *EWC = dyn_cast<ExprWithCleanups>(Body))
10728     Body = EWC->getSubExpr();
10729 
10730   Expr *X = nullptr;
10731   Expr *V = nullptr;
10732   Expr *E = nullptr;
10733   Expr *UE = nullptr;
10734   bool IsXLHSInRHSPart = false;
10735   bool IsPostfixUpdate = false;
10736   // OpenMP [2.12.6, atomic Construct]
10737   // In the next expressions:
10738   // * x and v (as applicable) are both l-value expressions with scalar type.
10739   // * During the execution of an atomic region, multiple syntactic
10740   // occurrences of x must designate the same storage location.
10741   // * Neither of v and expr (as applicable) may access the storage location
10742   // designated by x.
10743   // * Neither of x and expr (as applicable) may access the storage location
10744   // designated by v.
10745   // * expr is an expression with scalar type.
10746   // * binop is one of +, *, -, /, &, ^, |, <<, or >>.
10747   // * binop, binop=, ++, and -- are not overloaded operators.
10748   // * The expression x binop expr must be numerically equivalent to x binop
10749   // (expr). This requirement is satisfied if the operators in expr have
10750   // precedence greater than binop, or by using parentheses around expr or
10751   // subexpressions of expr.
10752   // * The expression expr binop x must be numerically equivalent to (expr)
10753   // binop x. This requirement is satisfied if the operators in expr have
10754   // precedence equal to or greater than binop, or by using parentheses around
10755   // expr or subexpressions of expr.
10756   // * For forms that allow multiple occurrences of x, the number of times
10757   // that x is evaluated is unspecified.
10758   if (AtomicKind == OMPC_read) {
10759     enum {
10760       NotAnExpression,
10761       NotAnAssignmentOp,
10762       NotAScalarType,
10763       NotAnLValue,
10764       NoError
10765     } ErrorFound = NoError;
10766     SourceLocation ErrorLoc, NoteLoc;
10767     SourceRange ErrorRange, NoteRange;
10768     // If clause is read:
10769     //  v = x;
10770     if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10771       const auto *AtomicBinOp =
10772           dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10773       if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10774         X = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
10775         V = AtomicBinOp->getLHS()->IgnoreParenImpCasts();
10776         if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
10777             (V->isInstantiationDependent() || V->getType()->isScalarType())) {
10778           if (!X->isLValue() || !V->isLValue()) {
10779             const Expr *NotLValueExpr = X->isLValue() ? V : X;
10780             ErrorFound = NotAnLValue;
10781             ErrorLoc = AtomicBinOp->getExprLoc();
10782             ErrorRange = AtomicBinOp->getSourceRange();
10783             NoteLoc = NotLValueExpr->getExprLoc();
10784             NoteRange = NotLValueExpr->getSourceRange();
10785           }
10786         } else if (!X->isInstantiationDependent() ||
10787                    !V->isInstantiationDependent()) {
10788           const Expr *NotScalarExpr =
10789               (X->isInstantiationDependent() || X->getType()->isScalarType())
10790                   ? V
10791                   : X;
10792           ErrorFound = NotAScalarType;
10793           ErrorLoc = AtomicBinOp->getExprLoc();
10794           ErrorRange = AtomicBinOp->getSourceRange();
10795           NoteLoc = NotScalarExpr->getExprLoc();
10796           NoteRange = NotScalarExpr->getSourceRange();
10797         }
10798       } else if (!AtomicBody->isInstantiationDependent()) {
10799         ErrorFound = NotAnAssignmentOp;
10800         ErrorLoc = AtomicBody->getExprLoc();
10801         ErrorRange = AtomicBody->getSourceRange();
10802         NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10803                               : AtomicBody->getExprLoc();
10804         NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10805                                 : AtomicBody->getSourceRange();
10806       }
10807     } else {
10808       ErrorFound = NotAnExpression;
10809       NoteLoc = ErrorLoc = Body->getBeginLoc();
10810       NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10811     }
10812     if (ErrorFound != NoError) {
10813       Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement)
10814           << ErrorRange;
10815       Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
10816                                                       << NoteRange;
10817       return StmtError();
10818     }
10819     if (CurContext->isDependentContext())
10820       V = X = nullptr;
10821   } else if (AtomicKind == OMPC_write) {
10822     enum {
10823       NotAnExpression,
10824       NotAnAssignmentOp,
10825       NotAScalarType,
10826       NotAnLValue,
10827       NoError
10828     } ErrorFound = NoError;
10829     SourceLocation ErrorLoc, NoteLoc;
10830     SourceRange ErrorRange, NoteRange;
10831     // If clause is write:
10832     //  x = expr;
10833     if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10834       const auto *AtomicBinOp =
10835           dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10836       if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10837         X = AtomicBinOp->getLHS();
10838         E = AtomicBinOp->getRHS();
10839         if ((X->isInstantiationDependent() || X->getType()->isScalarType()) &&
10840             (E->isInstantiationDependent() || E->getType()->isScalarType())) {
10841           if (!X->isLValue()) {
10842             ErrorFound = NotAnLValue;
10843             ErrorLoc = AtomicBinOp->getExprLoc();
10844             ErrorRange = AtomicBinOp->getSourceRange();
10845             NoteLoc = X->getExprLoc();
10846             NoteRange = X->getSourceRange();
10847           }
10848         } else if (!X->isInstantiationDependent() ||
10849                    !E->isInstantiationDependent()) {
10850           const Expr *NotScalarExpr =
10851               (X->isInstantiationDependent() || X->getType()->isScalarType())
10852                   ? E
10853                   : X;
10854           ErrorFound = NotAScalarType;
10855           ErrorLoc = AtomicBinOp->getExprLoc();
10856           ErrorRange = AtomicBinOp->getSourceRange();
10857           NoteLoc = NotScalarExpr->getExprLoc();
10858           NoteRange = NotScalarExpr->getSourceRange();
10859         }
10860       } else if (!AtomicBody->isInstantiationDependent()) {
10861         ErrorFound = NotAnAssignmentOp;
10862         ErrorLoc = AtomicBody->getExprLoc();
10863         ErrorRange = AtomicBody->getSourceRange();
10864         NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10865                               : AtomicBody->getExprLoc();
10866         NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10867                                 : AtomicBody->getSourceRange();
10868       }
10869     } else {
10870       ErrorFound = NotAnExpression;
10871       NoteLoc = ErrorLoc = Body->getBeginLoc();
10872       NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc);
10873     }
10874     if (ErrorFound != NoError) {
10875       Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement)
10876           << ErrorRange;
10877       Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound
10878                                                       << NoteRange;
10879       return StmtError();
10880     }
10881     if (CurContext->isDependentContext())
10882       E = X = nullptr;
10883   } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) {
10884     // If clause is update:
10885     //  x++;
10886     //  x--;
10887     //  ++x;
10888     //  --x;
10889     //  x binop= expr;
10890     //  x = x binop expr;
10891     //  x = expr binop x;
10892     OpenMPAtomicUpdateChecker Checker(*this);
10893     if (Checker.checkStatement(
10894             Body, (AtomicKind == OMPC_update)
10895                       ? diag::err_omp_atomic_update_not_expression_statement
10896                       : diag::err_omp_atomic_not_expression_statement,
10897             diag::note_omp_atomic_update))
10898       return StmtError();
10899     if (!CurContext->isDependentContext()) {
10900       E = Checker.getExpr();
10901       X = Checker.getX();
10902       UE = Checker.getUpdateExpr();
10903       IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10904     }
10905   } else if (AtomicKind == OMPC_capture) {
10906     enum {
10907       NotAnAssignmentOp,
10908       NotACompoundStatement,
10909       NotTwoSubstatements,
10910       NotASpecificExpression,
10911       NoError
10912     } ErrorFound = NoError;
10913     SourceLocation ErrorLoc, NoteLoc;
10914     SourceRange ErrorRange, NoteRange;
10915     if (const auto *AtomicBody = dyn_cast<Expr>(Body)) {
10916       // If clause is a capture:
10917       //  v = x++;
10918       //  v = x--;
10919       //  v = ++x;
10920       //  v = --x;
10921       //  v = x binop= expr;
10922       //  v = x = x binop expr;
10923       //  v = x = expr binop x;
10924       const auto *AtomicBinOp =
10925           dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts());
10926       if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) {
10927         V = AtomicBinOp->getLHS();
10928         Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts();
10929         OpenMPAtomicUpdateChecker Checker(*this);
10930         if (Checker.checkStatement(
10931                 Body, diag::err_omp_atomic_capture_not_expression_statement,
10932                 diag::note_omp_atomic_update))
10933           return StmtError();
10934         E = Checker.getExpr();
10935         X = Checker.getX();
10936         UE = Checker.getUpdateExpr();
10937         IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
10938         IsPostfixUpdate = Checker.isPostfixUpdate();
10939       } else if (!AtomicBody->isInstantiationDependent()) {
10940         ErrorLoc = AtomicBody->getExprLoc();
10941         ErrorRange = AtomicBody->getSourceRange();
10942         NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc()
10943                               : AtomicBody->getExprLoc();
10944         NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange()
10945                                 : AtomicBody->getSourceRange();
10946         ErrorFound = NotAnAssignmentOp;
10947       }
10948       if (ErrorFound != NoError) {
10949         Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement)
10950             << ErrorRange;
10951         Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
10952         return StmtError();
10953       }
10954       if (CurContext->isDependentContext())
10955         UE = V = E = X = nullptr;
10956     } else {
10957       // If clause is a capture:
10958       //  { v = x; x = expr; }
10959       //  { v = x; x++; }
10960       //  { v = x; x--; }
10961       //  { v = x; ++x; }
10962       //  { v = x; --x; }
10963       //  { v = x; x binop= expr; }
10964       //  { v = x; x = x binop expr; }
10965       //  { v = x; x = expr binop x; }
10966       //  { x++; v = x; }
10967       //  { x--; v = x; }
10968       //  { ++x; v = x; }
10969       //  { --x; v = x; }
10970       //  { x binop= expr; v = x; }
10971       //  { x = x binop expr; v = x; }
10972       //  { x = expr binop x; v = x; }
10973       if (auto *CS = dyn_cast<CompoundStmt>(Body)) {
10974         // Check that this is { expr1; expr2; }
10975         if (CS->size() == 2) {
10976           Stmt *First = CS->body_front();
10977           Stmt *Second = CS->body_back();
10978           if (auto *EWC = dyn_cast<ExprWithCleanups>(First))
10979             First = EWC->getSubExpr()->IgnoreParenImpCasts();
10980           if (auto *EWC = dyn_cast<ExprWithCleanups>(Second))
10981             Second = EWC->getSubExpr()->IgnoreParenImpCasts();
10982           // Need to find what subexpression is 'v' and what is 'x'.
10983           OpenMPAtomicUpdateChecker Checker(*this);
10984           bool IsUpdateExprFound = !Checker.checkStatement(Second);
10985           BinaryOperator *BinOp = nullptr;
10986           if (IsUpdateExprFound) {
10987             BinOp = dyn_cast<BinaryOperator>(First);
10988             IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
10989           }
10990           if (IsUpdateExprFound && !CurContext->isDependentContext()) {
10991             //  { v = x; x++; }
10992             //  { v = x; x--; }
10993             //  { v = x; ++x; }
10994             //  { v = x; --x; }
10995             //  { v = x; x binop= expr; }
10996             //  { v = x; x = x binop expr; }
10997             //  { v = x; x = expr binop x; }
10998             // Check that the first expression has form v = x.
10999             Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
11000             llvm::FoldingSetNodeID XId, PossibleXId;
11001             Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
11002             PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
11003             IsUpdateExprFound = XId == PossibleXId;
11004             if (IsUpdateExprFound) {
11005               V = BinOp->getLHS();
11006               X = Checker.getX();
11007               E = Checker.getExpr();
11008               UE = Checker.getUpdateExpr();
11009               IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
11010               IsPostfixUpdate = true;
11011             }
11012           }
11013           if (!IsUpdateExprFound) {
11014             IsUpdateExprFound = !Checker.checkStatement(First);
11015             BinOp = nullptr;
11016             if (IsUpdateExprFound) {
11017               BinOp = dyn_cast<BinaryOperator>(Second);
11018               IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign;
11019             }
11020             if (IsUpdateExprFound && !CurContext->isDependentContext()) {
11021               //  { x++; v = x; }
11022               //  { x--; v = x; }
11023               //  { ++x; v = x; }
11024               //  { --x; v = x; }
11025               //  { x binop= expr; v = x; }
11026               //  { x = x binop expr; v = x; }
11027               //  { x = expr binop x; v = x; }
11028               // Check that the second expression has form v = x.
11029               Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts();
11030               llvm::FoldingSetNodeID XId, PossibleXId;
11031               Checker.getX()->Profile(XId, Context, /*Canonical=*/true);
11032               PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true);
11033               IsUpdateExprFound = XId == PossibleXId;
11034               if (IsUpdateExprFound) {
11035                 V = BinOp->getLHS();
11036                 X = Checker.getX();
11037                 E = Checker.getExpr();
11038                 UE = Checker.getUpdateExpr();
11039                 IsXLHSInRHSPart = Checker.isXLHSInRHSPart();
11040                 IsPostfixUpdate = false;
11041               }
11042             }
11043           }
11044           if (!IsUpdateExprFound) {
11045             //  { v = x; x = expr; }
11046             auto *FirstExpr = dyn_cast<Expr>(First);
11047             auto *SecondExpr = dyn_cast<Expr>(Second);
11048             if (!FirstExpr || !SecondExpr ||
11049                 !(FirstExpr->isInstantiationDependent() ||
11050                   SecondExpr->isInstantiationDependent())) {
11051               auto *FirstBinOp = dyn_cast<BinaryOperator>(First);
11052               if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) {
11053                 ErrorFound = NotAnAssignmentOp;
11054                 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc()
11055                                                 : First->getBeginLoc();
11056                 NoteRange = ErrorRange = FirstBinOp
11057                                              ? FirstBinOp->getSourceRange()
11058                                              : SourceRange(ErrorLoc, ErrorLoc);
11059               } else {
11060                 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second);
11061                 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) {
11062                   ErrorFound = NotAnAssignmentOp;
11063                   NoteLoc = ErrorLoc = SecondBinOp
11064                                            ? SecondBinOp->getOperatorLoc()
11065                                            : Second->getBeginLoc();
11066                   NoteRange = ErrorRange =
11067                       SecondBinOp ? SecondBinOp->getSourceRange()
11068                                   : SourceRange(ErrorLoc, ErrorLoc);
11069                 } else {
11070                   Expr *PossibleXRHSInFirst =
11071                       FirstBinOp->getRHS()->IgnoreParenImpCasts();
11072                   Expr *PossibleXLHSInSecond =
11073                       SecondBinOp->getLHS()->IgnoreParenImpCasts();
11074                   llvm::FoldingSetNodeID X1Id, X2Id;
11075                   PossibleXRHSInFirst->Profile(X1Id, Context,
11076                                                /*Canonical=*/true);
11077                   PossibleXLHSInSecond->Profile(X2Id, Context,
11078                                                 /*Canonical=*/true);
11079                   IsUpdateExprFound = X1Id == X2Id;
11080                   if (IsUpdateExprFound) {
11081                     V = FirstBinOp->getLHS();
11082                     X = SecondBinOp->getLHS();
11083                     E = SecondBinOp->getRHS();
11084                     UE = nullptr;
11085                     IsXLHSInRHSPart = false;
11086                     IsPostfixUpdate = true;
11087                   } else {
11088                     ErrorFound = NotASpecificExpression;
11089                     ErrorLoc = FirstBinOp->getExprLoc();
11090                     ErrorRange = FirstBinOp->getSourceRange();
11091                     NoteLoc = SecondBinOp->getLHS()->getExprLoc();
11092                     NoteRange = SecondBinOp->getRHS()->getSourceRange();
11093                   }
11094                 }
11095               }
11096             }
11097           }
11098         } else {
11099           NoteLoc = ErrorLoc = Body->getBeginLoc();
11100           NoteRange = ErrorRange =
11101               SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
11102           ErrorFound = NotTwoSubstatements;
11103         }
11104       } else {
11105         NoteLoc = ErrorLoc = Body->getBeginLoc();
11106         NoteRange = ErrorRange =
11107             SourceRange(Body->getBeginLoc(), Body->getBeginLoc());
11108         ErrorFound = NotACompoundStatement;
11109       }
11110       if (ErrorFound != NoError) {
11111         Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement)
11112             << ErrorRange;
11113         Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange;
11114         return StmtError();
11115       }
11116       if (CurContext->isDependentContext())
11117         UE = V = E = X = nullptr;
11118     }
11119   }
11120 
11121   setFunctionHasBranchProtectedScope();
11122 
11123   return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
11124                                     X, V, E, UE, IsXLHSInRHSPart,
11125                                     IsPostfixUpdate);
11126 }
11127 
ActOnOpenMPTargetDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)11128 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses,
11129                                             Stmt *AStmt,
11130                                             SourceLocation StartLoc,
11131                                             SourceLocation EndLoc) {
11132   if (!AStmt)
11133     return StmtError();
11134 
11135   auto *CS = cast<CapturedStmt>(AStmt);
11136   // 1.2.2 OpenMP Language Terminology
11137   // Structured block - An executable statement with a single entry at the
11138   // top and a single exit at the bottom.
11139   // The point of exit cannot be a branch out of the structured block.
11140   // longjmp() and throw() must not violate the entry/exit criteria.
11141   CS->getCapturedDecl()->setNothrow();
11142   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target);
11143        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11144     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11145     // 1.2.2 OpenMP Language Terminology
11146     // Structured block - An executable statement with a single entry at the
11147     // top and a single exit at the bottom.
11148     // The point of exit cannot be a branch out of the structured block.
11149     // longjmp() and throw() must not violate the entry/exit criteria.
11150     CS->getCapturedDecl()->setNothrow();
11151   }
11152 
11153   // OpenMP [2.16, Nesting of Regions]
11154   // If specified, a teams construct must be contained within a target
11155   // construct. That target construct must contain no statements or directives
11156   // outside of the teams construct.
11157   if (DSAStack->hasInnerTeamsRegion()) {
11158     const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true);
11159     bool OMPTeamsFound = true;
11160     if (const auto *CS = dyn_cast<CompoundStmt>(S)) {
11161       auto I = CS->body_begin();
11162       while (I != CS->body_end()) {
11163         const auto *OED = dyn_cast<OMPExecutableDirective>(*I);
11164         if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) ||
11165             OMPTeamsFound) {
11166 
11167           OMPTeamsFound = false;
11168           break;
11169         }
11170         ++I;
11171       }
11172       assert(I != CS->body_end() && "Not found statement");
11173       S = *I;
11174     } else {
11175       const auto *OED = dyn_cast<OMPExecutableDirective>(S);
11176       OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind());
11177     }
11178     if (!OMPTeamsFound) {
11179       Diag(StartLoc, diag::err_omp_target_contains_not_only_teams);
11180       Diag(DSAStack->getInnerTeamsRegionLoc(),
11181            diag::note_omp_nested_teams_construct_here);
11182       Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here)
11183           << isa<OMPExecutableDirective>(S);
11184       return StmtError();
11185     }
11186   }
11187 
11188   setFunctionHasBranchProtectedScope();
11189 
11190   return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
11191 }
11192 
11193 StmtResult
ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)11194 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses,
11195                                          Stmt *AStmt, SourceLocation StartLoc,
11196                                          SourceLocation EndLoc) {
11197   if (!AStmt)
11198     return StmtError();
11199 
11200   auto *CS = cast<CapturedStmt>(AStmt);
11201   // 1.2.2 OpenMP Language Terminology
11202   // Structured block - An executable statement with a single entry at the
11203   // top and a single exit at the bottom.
11204   // The point of exit cannot be a branch out of the structured block.
11205   // longjmp() and throw() must not violate the entry/exit criteria.
11206   CS->getCapturedDecl()->setNothrow();
11207   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel);
11208        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11209     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11210     // 1.2.2 OpenMP Language Terminology
11211     // Structured block - An executable statement with a single entry at the
11212     // top and a single exit at the bottom.
11213     // The point of exit cannot be a branch out of the structured block.
11214     // longjmp() and throw() must not violate the entry/exit criteria.
11215     CS->getCapturedDecl()->setNothrow();
11216   }
11217 
11218   setFunctionHasBranchProtectedScope();
11219 
11220   return OMPTargetParallelDirective::Create(
11221       Context, StartLoc, EndLoc, Clauses, AStmt,
11222       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11223 }
11224 
ActOnOpenMPTargetParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11225 StmtResult Sema::ActOnOpenMPTargetParallelForDirective(
11226     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11227     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11228   if (!AStmt)
11229     return StmtError();
11230 
11231   auto *CS = cast<CapturedStmt>(AStmt);
11232   // 1.2.2 OpenMP Language Terminology
11233   // Structured block - An executable statement with a single entry at the
11234   // top and a single exit at the bottom.
11235   // The point of exit cannot be a branch out of the structured block.
11236   // longjmp() and throw() must not violate the entry/exit criteria.
11237   CS->getCapturedDecl()->setNothrow();
11238   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
11239        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11240     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11241     // 1.2.2 OpenMP Language Terminology
11242     // Structured block - An executable statement with a single entry at the
11243     // top and a single exit at the bottom.
11244     // The point of exit cannot be a branch out of the structured block.
11245     // longjmp() and throw() must not violate the entry/exit criteria.
11246     CS->getCapturedDecl()->setNothrow();
11247   }
11248 
11249   OMPLoopBasedDirective::HelperExprs B;
11250   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11251   // define the nested loops number.
11252   unsigned NestedLoopCount =
11253       checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses),
11254                       getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
11255                       VarsWithImplicitDSA, B);
11256   if (NestedLoopCount == 0)
11257     return StmtError();
11258 
11259   assert((CurContext->isDependentContext() || B.builtAll()) &&
11260          "omp target parallel for loop exprs were not built");
11261 
11262   if (!CurContext->isDependentContext()) {
11263     // Finalize the clauses that need pre-built expressions for CodeGen.
11264     for (OMPClause *C : Clauses) {
11265       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11266         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11267                                      B.NumIterations, *this, CurScope,
11268                                      DSAStack))
11269           return StmtError();
11270     }
11271   }
11272 
11273   setFunctionHasBranchProtectedScope();
11274   return OMPTargetParallelForDirective::Create(
11275       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11276       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11277 }
11278 
11279 /// Check for existence of a map clause in the list of clauses.
hasClauses(ArrayRef<OMPClause * > Clauses,const OpenMPClauseKind K)11280 static bool hasClauses(ArrayRef<OMPClause *> Clauses,
11281                        const OpenMPClauseKind K) {
11282   return llvm::any_of(
11283       Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; });
11284 }
11285 
11286 template <typename... Params>
hasClauses(ArrayRef<OMPClause * > Clauses,const OpenMPClauseKind K,const Params...ClauseTypes)11287 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K,
11288                        const Params... ClauseTypes) {
11289   return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...);
11290 }
11291 
ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)11292 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses,
11293                                                 Stmt *AStmt,
11294                                                 SourceLocation StartLoc,
11295                                                 SourceLocation EndLoc) {
11296   if (!AStmt)
11297     return StmtError();
11298 
11299   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11300 
11301   // OpenMP [2.12.2, target data Construct, Restrictions]
11302   // At least one map, use_device_addr or use_device_ptr clause must appear on
11303   // the directive.
11304   if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) &&
11305       (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) {
11306     StringRef Expected;
11307     if (LangOpts.OpenMP < 50)
11308       Expected = "'map' or 'use_device_ptr'";
11309     else
11310       Expected = "'map', 'use_device_ptr', or 'use_device_addr'";
11311     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
11312         << Expected << getOpenMPDirectiveName(OMPD_target_data);
11313     return StmtError();
11314   }
11315 
11316   setFunctionHasBranchProtectedScope();
11317 
11318   return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
11319                                         AStmt);
11320 }
11321 
11322 StmtResult
ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,Stmt * AStmt)11323 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses,
11324                                           SourceLocation StartLoc,
11325                                           SourceLocation EndLoc, Stmt *AStmt) {
11326   if (!AStmt)
11327     return StmtError();
11328 
11329   auto *CS = cast<CapturedStmt>(AStmt);
11330   // 1.2.2 OpenMP Language Terminology
11331   // Structured block - An executable statement with a single entry at the
11332   // top and a single exit at the bottom.
11333   // The point of exit cannot be a branch out of the structured block.
11334   // longjmp() and throw() must not violate the entry/exit criteria.
11335   CS->getCapturedDecl()->setNothrow();
11336   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data);
11337        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11338     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11339     // 1.2.2 OpenMP Language Terminology
11340     // Structured block - An executable statement with a single entry at the
11341     // top and a single exit at the bottom.
11342     // The point of exit cannot be a branch out of the structured block.
11343     // longjmp() and throw() must not violate the entry/exit criteria.
11344     CS->getCapturedDecl()->setNothrow();
11345   }
11346 
11347   // OpenMP [2.10.2, Restrictions, p. 99]
11348   // At least one map clause must appear on the directive.
11349   if (!hasClauses(Clauses, OMPC_map)) {
11350     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
11351         << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data);
11352     return StmtError();
11353   }
11354 
11355   return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
11356                                              AStmt);
11357 }
11358 
11359 StmtResult
ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,Stmt * AStmt)11360 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses,
11361                                          SourceLocation StartLoc,
11362                                          SourceLocation EndLoc, Stmt *AStmt) {
11363   if (!AStmt)
11364     return StmtError();
11365 
11366   auto *CS = cast<CapturedStmt>(AStmt);
11367   // 1.2.2 OpenMP Language Terminology
11368   // Structured block - An executable statement with a single entry at the
11369   // top and a single exit at the bottom.
11370   // The point of exit cannot be a branch out of the structured block.
11371   // longjmp() and throw() must not violate the entry/exit criteria.
11372   CS->getCapturedDecl()->setNothrow();
11373   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data);
11374        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11375     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11376     // 1.2.2 OpenMP Language Terminology
11377     // Structured block - An executable statement with a single entry at the
11378     // top and a single exit at the bottom.
11379     // The point of exit cannot be a branch out of the structured block.
11380     // longjmp() and throw() must not violate the entry/exit criteria.
11381     CS->getCapturedDecl()->setNothrow();
11382   }
11383 
11384   // OpenMP [2.10.3, Restrictions, p. 102]
11385   // At least one map clause must appear on the directive.
11386   if (!hasClauses(Clauses, OMPC_map)) {
11387     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
11388         << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data);
11389     return StmtError();
11390   }
11391 
11392   return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses,
11393                                             AStmt);
11394 }
11395 
ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,Stmt * AStmt)11396 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses,
11397                                                   SourceLocation StartLoc,
11398                                                   SourceLocation EndLoc,
11399                                                   Stmt *AStmt) {
11400   if (!AStmt)
11401     return StmtError();
11402 
11403   auto *CS = cast<CapturedStmt>(AStmt);
11404   // 1.2.2 OpenMP Language Terminology
11405   // Structured block - An executable statement with a single entry at the
11406   // top and a single exit at the bottom.
11407   // The point of exit cannot be a branch out of the structured block.
11408   // longjmp() and throw() must not violate the entry/exit criteria.
11409   CS->getCapturedDecl()->setNothrow();
11410   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update);
11411        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11412     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11413     // 1.2.2 OpenMP Language Terminology
11414     // Structured block - An executable statement with a single entry at the
11415     // top and a single exit at the bottom.
11416     // The point of exit cannot be a branch out of the structured block.
11417     // longjmp() and throw() must not violate the entry/exit criteria.
11418     CS->getCapturedDecl()->setNothrow();
11419   }
11420 
11421   if (!hasClauses(Clauses, OMPC_to, OMPC_from)) {
11422     Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required);
11423     return StmtError();
11424   }
11425   return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses,
11426                                           AStmt);
11427 }
11428 
ActOnOpenMPTeamsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)11429 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses,
11430                                            Stmt *AStmt, SourceLocation StartLoc,
11431                                            SourceLocation EndLoc) {
11432   if (!AStmt)
11433     return StmtError();
11434 
11435   auto *CS = cast<CapturedStmt>(AStmt);
11436   // 1.2.2 OpenMP Language Terminology
11437   // Structured block - An executable statement with a single entry at the
11438   // top and a single exit at the bottom.
11439   // The point of exit cannot be a branch out of the structured block.
11440   // longjmp() and throw() must not violate the entry/exit criteria.
11441   CS->getCapturedDecl()->setNothrow();
11442 
11443   setFunctionHasBranchProtectedScope();
11444 
11445   DSAStack->setParentTeamsRegionLoc(StartLoc);
11446 
11447   return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt);
11448 }
11449 
11450 StmtResult
ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,SourceLocation EndLoc,OpenMPDirectiveKind CancelRegion)11451 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc,
11452                                             SourceLocation EndLoc,
11453                                             OpenMPDirectiveKind CancelRegion) {
11454   if (DSAStack->isParentNowaitRegion()) {
11455     Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0;
11456     return StmtError();
11457   }
11458   if (DSAStack->isParentOrderedRegion()) {
11459     Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0;
11460     return StmtError();
11461   }
11462   return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc,
11463                                                CancelRegion);
11464 }
11465 
ActOnOpenMPCancelDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc,OpenMPDirectiveKind CancelRegion)11466 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses,
11467                                             SourceLocation StartLoc,
11468                                             SourceLocation EndLoc,
11469                                             OpenMPDirectiveKind CancelRegion) {
11470   if (DSAStack->isParentNowaitRegion()) {
11471     Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1;
11472     return StmtError();
11473   }
11474   if (DSAStack->isParentOrderedRegion()) {
11475     Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1;
11476     return StmtError();
11477   }
11478   DSAStack->setParentCancelRegion(/*Cancel=*/true);
11479   return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses,
11480                                     CancelRegion);
11481 }
11482 
checkReductionClauseWithNogroup(Sema & S,ArrayRef<OMPClause * > Clauses)11483 static bool checkReductionClauseWithNogroup(Sema &S,
11484                                             ArrayRef<OMPClause *> Clauses) {
11485   const OMPClause *ReductionClause = nullptr;
11486   const OMPClause *NogroupClause = nullptr;
11487   for (const OMPClause *C : Clauses) {
11488     if (C->getClauseKind() == OMPC_reduction) {
11489       ReductionClause = C;
11490       if (NogroupClause)
11491         break;
11492       continue;
11493     }
11494     if (C->getClauseKind() == OMPC_nogroup) {
11495       NogroupClause = C;
11496       if (ReductionClause)
11497         break;
11498       continue;
11499     }
11500   }
11501   if (ReductionClause && NogroupClause) {
11502     S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup)
11503         << SourceRange(NogroupClause->getBeginLoc(),
11504                        NogroupClause->getEndLoc());
11505     return true;
11506   }
11507   return false;
11508 }
11509 
ActOnOpenMPTaskLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11510 StmtResult Sema::ActOnOpenMPTaskLoopDirective(
11511     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11512     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11513   if (!AStmt)
11514     return StmtError();
11515 
11516   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11517   OMPLoopBasedDirective::HelperExprs B;
11518   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11519   // define the nested loops number.
11520   unsigned NestedLoopCount =
11521       checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses),
11522                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
11523                       VarsWithImplicitDSA, B);
11524   if (NestedLoopCount == 0)
11525     return StmtError();
11526 
11527   assert((CurContext->isDependentContext() || B.builtAll()) &&
11528          "omp for loop exprs were not built");
11529 
11530   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11531   // The grainsize clause and num_tasks clause are mutually exclusive and may
11532   // not appear on the same taskloop directive.
11533   if (checkMutuallyExclusiveClauses(*this, Clauses,
11534                                     {OMPC_grainsize, OMPC_num_tasks}))
11535     return StmtError();
11536   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11537   // If a reduction clause is present on the taskloop directive, the nogroup
11538   // clause must not be specified.
11539   if (checkReductionClauseWithNogroup(*this, Clauses))
11540     return StmtError();
11541 
11542   setFunctionHasBranchProtectedScope();
11543   return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc,
11544                                       NestedLoopCount, Clauses, AStmt, B,
11545                                       DSAStack->isCancelRegion());
11546 }
11547 
ActOnOpenMPTaskLoopSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11548 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective(
11549     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11550     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11551   if (!AStmt)
11552     return StmtError();
11553 
11554   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11555   OMPLoopBasedDirective::HelperExprs B;
11556   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11557   // define the nested loops number.
11558   unsigned NestedLoopCount =
11559       checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses),
11560                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
11561                       VarsWithImplicitDSA, B);
11562   if (NestedLoopCount == 0)
11563     return StmtError();
11564 
11565   assert((CurContext->isDependentContext() || B.builtAll()) &&
11566          "omp for loop exprs were not built");
11567 
11568   if (!CurContext->isDependentContext()) {
11569     // Finalize the clauses that need pre-built expressions for CodeGen.
11570     for (OMPClause *C : Clauses) {
11571       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11572         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11573                                      B.NumIterations, *this, CurScope,
11574                                      DSAStack))
11575           return StmtError();
11576     }
11577   }
11578 
11579   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11580   // The grainsize clause and num_tasks clause are mutually exclusive and may
11581   // not appear on the same taskloop directive.
11582   if (checkMutuallyExclusiveClauses(*this, Clauses,
11583                                     {OMPC_grainsize, OMPC_num_tasks}))
11584     return StmtError();
11585   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11586   // If a reduction clause is present on the taskloop directive, the nogroup
11587   // clause must not be specified.
11588   if (checkReductionClauseWithNogroup(*this, Clauses))
11589     return StmtError();
11590   if (checkSimdlenSafelenSpecified(*this, Clauses))
11591     return StmtError();
11592 
11593   setFunctionHasBranchProtectedScope();
11594   return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc,
11595                                           NestedLoopCount, Clauses, AStmt, B);
11596 }
11597 
ActOnOpenMPMasterTaskLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11598 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective(
11599     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11600     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11601   if (!AStmt)
11602     return StmtError();
11603 
11604   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11605   OMPLoopBasedDirective::HelperExprs B;
11606   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11607   // define the nested loops number.
11608   unsigned NestedLoopCount =
11609       checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses),
11610                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
11611                       VarsWithImplicitDSA, B);
11612   if (NestedLoopCount == 0)
11613     return StmtError();
11614 
11615   assert((CurContext->isDependentContext() || B.builtAll()) &&
11616          "omp for loop exprs were not built");
11617 
11618   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11619   // The grainsize clause and num_tasks clause are mutually exclusive and may
11620   // not appear on the same taskloop directive.
11621   if (checkMutuallyExclusiveClauses(*this, Clauses,
11622                                     {OMPC_grainsize, OMPC_num_tasks}))
11623     return StmtError();
11624   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11625   // If a reduction clause is present on the taskloop directive, the nogroup
11626   // clause must not be specified.
11627   if (checkReductionClauseWithNogroup(*this, Clauses))
11628     return StmtError();
11629 
11630   setFunctionHasBranchProtectedScope();
11631   return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc,
11632                                             NestedLoopCount, Clauses, AStmt, B,
11633                                             DSAStack->isCancelRegion());
11634 }
11635 
ActOnOpenMPMasterTaskLoopSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11636 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective(
11637     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11638     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11639   if (!AStmt)
11640     return StmtError();
11641 
11642   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11643   OMPLoopBasedDirective::HelperExprs B;
11644   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11645   // define the nested loops number.
11646   unsigned NestedLoopCount =
11647       checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses),
11648                       /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack,
11649                       VarsWithImplicitDSA, B);
11650   if (NestedLoopCount == 0)
11651     return StmtError();
11652 
11653   assert((CurContext->isDependentContext() || B.builtAll()) &&
11654          "omp for loop exprs were not built");
11655 
11656   if (!CurContext->isDependentContext()) {
11657     // Finalize the clauses that need pre-built expressions for CodeGen.
11658     for (OMPClause *C : Clauses) {
11659       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11660         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11661                                      B.NumIterations, *this, CurScope,
11662                                      DSAStack))
11663           return StmtError();
11664     }
11665   }
11666 
11667   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11668   // The grainsize clause and num_tasks clause are mutually exclusive and may
11669   // not appear on the same taskloop directive.
11670   if (checkMutuallyExclusiveClauses(*this, Clauses,
11671                                     {OMPC_grainsize, OMPC_num_tasks}))
11672     return StmtError();
11673   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11674   // If a reduction clause is present on the taskloop directive, the nogroup
11675   // clause must not be specified.
11676   if (checkReductionClauseWithNogroup(*this, Clauses))
11677     return StmtError();
11678   if (checkSimdlenSafelenSpecified(*this, Clauses))
11679     return StmtError();
11680 
11681   setFunctionHasBranchProtectedScope();
11682   return OMPMasterTaskLoopSimdDirective::Create(
11683       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11684 }
11685 
ActOnOpenMPParallelMasterTaskLoopDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11686 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective(
11687     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11688     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11689   if (!AStmt)
11690     return StmtError();
11691 
11692   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11693   auto *CS = cast<CapturedStmt>(AStmt);
11694   // 1.2.2 OpenMP Language Terminology
11695   // Structured block - An executable statement with a single entry at the
11696   // top and a single exit at the bottom.
11697   // The point of exit cannot be a branch out of the structured block.
11698   // longjmp() and throw() must not violate the entry/exit criteria.
11699   CS->getCapturedDecl()->setNothrow();
11700   for (int ThisCaptureLevel =
11701            getOpenMPCaptureLevels(OMPD_parallel_master_taskloop);
11702        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11703     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11704     // 1.2.2 OpenMP Language Terminology
11705     // Structured block - An executable statement with a single entry at the
11706     // top and a single exit at the bottom.
11707     // The point of exit cannot be a branch out of the structured block.
11708     // longjmp() and throw() must not violate the entry/exit criteria.
11709     CS->getCapturedDecl()->setNothrow();
11710   }
11711 
11712   OMPLoopBasedDirective::HelperExprs B;
11713   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11714   // define the nested loops number.
11715   unsigned NestedLoopCount = checkOpenMPLoop(
11716       OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses),
11717       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
11718       VarsWithImplicitDSA, B);
11719   if (NestedLoopCount == 0)
11720     return StmtError();
11721 
11722   assert((CurContext->isDependentContext() || B.builtAll()) &&
11723          "omp for loop exprs were not built");
11724 
11725   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11726   // The grainsize clause and num_tasks clause are mutually exclusive and may
11727   // not appear on the same taskloop directive.
11728   if (checkMutuallyExclusiveClauses(*this, Clauses,
11729                                     {OMPC_grainsize, OMPC_num_tasks}))
11730     return StmtError();
11731   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11732   // If a reduction clause is present on the taskloop directive, the nogroup
11733   // clause must not be specified.
11734   if (checkReductionClauseWithNogroup(*this, Clauses))
11735     return StmtError();
11736 
11737   setFunctionHasBranchProtectedScope();
11738   return OMPParallelMasterTaskLoopDirective::Create(
11739       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11740       DSAStack->isCancelRegion());
11741 }
11742 
ActOnOpenMPParallelMasterTaskLoopSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11743 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective(
11744     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11745     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11746   if (!AStmt)
11747     return StmtError();
11748 
11749   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11750   auto *CS = cast<CapturedStmt>(AStmt);
11751   // 1.2.2 OpenMP Language Terminology
11752   // Structured block - An executable statement with a single entry at the
11753   // top and a single exit at the bottom.
11754   // The point of exit cannot be a branch out of the structured block.
11755   // longjmp() and throw() must not violate the entry/exit criteria.
11756   CS->getCapturedDecl()->setNothrow();
11757   for (int ThisCaptureLevel =
11758            getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd);
11759        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11760     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11761     // 1.2.2 OpenMP Language Terminology
11762     // Structured block - An executable statement with a single entry at the
11763     // top and a single exit at the bottom.
11764     // The point of exit cannot be a branch out of the structured block.
11765     // longjmp() and throw() must not violate the entry/exit criteria.
11766     CS->getCapturedDecl()->setNothrow();
11767   }
11768 
11769   OMPLoopBasedDirective::HelperExprs B;
11770   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
11771   // define the nested loops number.
11772   unsigned NestedLoopCount = checkOpenMPLoop(
11773       OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses),
11774       /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack,
11775       VarsWithImplicitDSA, B);
11776   if (NestedLoopCount == 0)
11777     return StmtError();
11778 
11779   assert((CurContext->isDependentContext() || B.builtAll()) &&
11780          "omp for loop exprs were not built");
11781 
11782   if (!CurContext->isDependentContext()) {
11783     // Finalize the clauses that need pre-built expressions for CodeGen.
11784     for (OMPClause *C : Clauses) {
11785       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11786         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11787                                      B.NumIterations, *this, CurScope,
11788                                      DSAStack))
11789           return StmtError();
11790     }
11791   }
11792 
11793   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11794   // The grainsize clause and num_tasks clause are mutually exclusive and may
11795   // not appear on the same taskloop directive.
11796   if (checkMutuallyExclusiveClauses(*this, Clauses,
11797                                     {OMPC_grainsize, OMPC_num_tasks}))
11798     return StmtError();
11799   // OpenMP, [2.9.2 taskloop Construct, Restrictions]
11800   // If a reduction clause is present on the taskloop directive, the nogroup
11801   // clause must not be specified.
11802   if (checkReductionClauseWithNogroup(*this, Clauses))
11803     return StmtError();
11804   if (checkSimdlenSafelenSpecified(*this, Clauses))
11805     return StmtError();
11806 
11807   setFunctionHasBranchProtectedScope();
11808   return OMPParallelMasterTaskLoopSimdDirective::Create(
11809       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11810 }
11811 
ActOnOpenMPDistributeDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11812 StmtResult Sema::ActOnOpenMPDistributeDirective(
11813     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11814     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11815   if (!AStmt)
11816     return StmtError();
11817 
11818   assert(isa<CapturedStmt>(AStmt) && "Captured statement expected");
11819   OMPLoopBasedDirective::HelperExprs B;
11820   // In presence of clause 'collapse' with number of loops, it will
11821   // define the nested loops number.
11822   unsigned NestedLoopCount =
11823       checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses),
11824                       nullptr /*ordered not a clause on distribute*/, AStmt,
11825                       *this, *DSAStack, VarsWithImplicitDSA, B);
11826   if (NestedLoopCount == 0)
11827     return StmtError();
11828 
11829   assert((CurContext->isDependentContext() || B.builtAll()) &&
11830          "omp for loop exprs were not built");
11831 
11832   setFunctionHasBranchProtectedScope();
11833   return OMPDistributeDirective::Create(Context, StartLoc, EndLoc,
11834                                         NestedLoopCount, Clauses, AStmt, B);
11835 }
11836 
ActOnOpenMPDistributeParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11837 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective(
11838     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11839     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11840   if (!AStmt)
11841     return StmtError();
11842 
11843   auto *CS = cast<CapturedStmt>(AStmt);
11844   // 1.2.2 OpenMP Language Terminology
11845   // Structured block - An executable statement with a single entry at the
11846   // top and a single exit at the bottom.
11847   // The point of exit cannot be a branch out of the structured block.
11848   // longjmp() and throw() must not violate the entry/exit criteria.
11849   CS->getCapturedDecl()->setNothrow();
11850   for (int ThisCaptureLevel =
11851            getOpenMPCaptureLevels(OMPD_distribute_parallel_for);
11852        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11853     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11854     // 1.2.2 OpenMP Language Terminology
11855     // Structured block - An executable statement with a single entry at the
11856     // top and a single exit at the bottom.
11857     // The point of exit cannot be a branch out of the structured block.
11858     // longjmp() and throw() must not violate the entry/exit criteria.
11859     CS->getCapturedDecl()->setNothrow();
11860   }
11861 
11862   OMPLoopBasedDirective::HelperExprs B;
11863   // In presence of clause 'collapse' with number of loops, it will
11864   // define the nested loops number.
11865   unsigned NestedLoopCount = checkOpenMPLoop(
11866       OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses),
11867       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11868       VarsWithImplicitDSA, B);
11869   if (NestedLoopCount == 0)
11870     return StmtError();
11871 
11872   assert((CurContext->isDependentContext() || B.builtAll()) &&
11873          "omp for loop exprs were not built");
11874 
11875   setFunctionHasBranchProtectedScope();
11876   return OMPDistributeParallelForDirective::Create(
11877       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
11878       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
11879 }
11880 
ActOnOpenMPDistributeParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11881 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective(
11882     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11883     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11884   if (!AStmt)
11885     return StmtError();
11886 
11887   auto *CS = cast<CapturedStmt>(AStmt);
11888   // 1.2.2 OpenMP Language Terminology
11889   // Structured block - An executable statement with a single entry at the
11890   // top and a single exit at the bottom.
11891   // The point of exit cannot be a branch out of the structured block.
11892   // longjmp() and throw() must not violate the entry/exit criteria.
11893   CS->getCapturedDecl()->setNothrow();
11894   for (int ThisCaptureLevel =
11895            getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd);
11896        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11897     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11898     // 1.2.2 OpenMP Language Terminology
11899     // Structured block - An executable statement with a single entry at the
11900     // top and a single exit at the bottom.
11901     // The point of exit cannot be a branch out of the structured block.
11902     // longjmp() and throw() must not violate the entry/exit criteria.
11903     CS->getCapturedDecl()->setNothrow();
11904   }
11905 
11906   OMPLoopBasedDirective::HelperExprs B;
11907   // In presence of clause 'collapse' with number of loops, it will
11908   // define the nested loops number.
11909   unsigned NestedLoopCount = checkOpenMPLoop(
11910       OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
11911       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
11912       VarsWithImplicitDSA, B);
11913   if (NestedLoopCount == 0)
11914     return StmtError();
11915 
11916   assert((CurContext->isDependentContext() || B.builtAll()) &&
11917          "omp for loop exprs were not built");
11918 
11919   if (!CurContext->isDependentContext()) {
11920     // Finalize the clauses that need pre-built expressions for CodeGen.
11921     for (OMPClause *C : Clauses) {
11922       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11923         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11924                                      B.NumIterations, *this, CurScope,
11925                                      DSAStack))
11926           return StmtError();
11927     }
11928   }
11929 
11930   if (checkSimdlenSafelenSpecified(*this, Clauses))
11931     return StmtError();
11932 
11933   setFunctionHasBranchProtectedScope();
11934   return OMPDistributeParallelForSimdDirective::Create(
11935       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
11936 }
11937 
ActOnOpenMPDistributeSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11938 StmtResult Sema::ActOnOpenMPDistributeSimdDirective(
11939     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11940     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11941   if (!AStmt)
11942     return StmtError();
11943 
11944   auto *CS = cast<CapturedStmt>(AStmt);
11945   // 1.2.2 OpenMP Language Terminology
11946   // Structured block - An executable statement with a single entry at the
11947   // top and a single exit at the bottom.
11948   // The point of exit cannot be a branch out of the structured block.
11949   // longjmp() and throw() must not violate the entry/exit criteria.
11950   CS->getCapturedDecl()->setNothrow();
11951   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd);
11952        ThisCaptureLevel > 1; --ThisCaptureLevel) {
11953     CS = cast<CapturedStmt>(CS->getCapturedStmt());
11954     // 1.2.2 OpenMP Language Terminology
11955     // Structured block - An executable statement with a single entry at the
11956     // top and a single exit at the bottom.
11957     // The point of exit cannot be a branch out of the structured block.
11958     // longjmp() and throw() must not violate the entry/exit criteria.
11959     CS->getCapturedDecl()->setNothrow();
11960   }
11961 
11962   OMPLoopBasedDirective::HelperExprs B;
11963   // In presence of clause 'collapse' with number of loops, it will
11964   // define the nested loops number.
11965   unsigned NestedLoopCount =
11966       checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses),
11967                       nullptr /*ordered not a clause on distribute*/, CS, *this,
11968                       *DSAStack, VarsWithImplicitDSA, B);
11969   if (NestedLoopCount == 0)
11970     return StmtError();
11971 
11972   assert((CurContext->isDependentContext() || B.builtAll()) &&
11973          "omp for loop exprs were not built");
11974 
11975   if (!CurContext->isDependentContext()) {
11976     // Finalize the clauses that need pre-built expressions for CodeGen.
11977     for (OMPClause *C : Clauses) {
11978       if (auto *LC = dyn_cast<OMPLinearClause>(C))
11979         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
11980                                      B.NumIterations, *this, CurScope,
11981                                      DSAStack))
11982           return StmtError();
11983     }
11984   }
11985 
11986   if (checkSimdlenSafelenSpecified(*this, Clauses))
11987     return StmtError();
11988 
11989   setFunctionHasBranchProtectedScope();
11990   return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc,
11991                                             NestedLoopCount, Clauses, AStmt, B);
11992 }
11993 
ActOnOpenMPTargetParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)11994 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective(
11995     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
11996     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
11997   if (!AStmt)
11998     return StmtError();
11999 
12000   auto *CS = cast<CapturedStmt>(AStmt);
12001   // 1.2.2 OpenMP Language Terminology
12002   // Structured block - An executable statement with a single entry at the
12003   // top and a single exit at the bottom.
12004   // The point of exit cannot be a branch out of the structured block.
12005   // longjmp() and throw() must not violate the entry/exit criteria.
12006   CS->getCapturedDecl()->setNothrow();
12007   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for);
12008        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12009     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12010     // 1.2.2 OpenMP Language Terminology
12011     // Structured block - An executable statement with a single entry at the
12012     // top and a single exit at the bottom.
12013     // The point of exit cannot be a branch out of the structured block.
12014     // longjmp() and throw() must not violate the entry/exit criteria.
12015     CS->getCapturedDecl()->setNothrow();
12016   }
12017 
12018   OMPLoopBasedDirective::HelperExprs B;
12019   // In presence of clause 'collapse' or 'ordered' with number of loops, it will
12020   // define the nested loops number.
12021   unsigned NestedLoopCount = checkOpenMPLoop(
12022       OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses),
12023       getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
12024       VarsWithImplicitDSA, B);
12025   if (NestedLoopCount == 0)
12026     return StmtError();
12027 
12028   assert((CurContext->isDependentContext() || B.builtAll()) &&
12029          "omp target parallel for simd loop exprs were not built");
12030 
12031   if (!CurContext->isDependentContext()) {
12032     // Finalize the clauses that need pre-built expressions for CodeGen.
12033     for (OMPClause *C : Clauses) {
12034       if (auto *LC = dyn_cast<OMPLinearClause>(C))
12035         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12036                                      B.NumIterations, *this, CurScope,
12037                                      DSAStack))
12038           return StmtError();
12039     }
12040   }
12041   if (checkSimdlenSafelenSpecified(*this, Clauses))
12042     return StmtError();
12043 
12044   setFunctionHasBranchProtectedScope();
12045   return OMPTargetParallelForSimdDirective::Create(
12046       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12047 }
12048 
ActOnOpenMPTargetSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12049 StmtResult Sema::ActOnOpenMPTargetSimdDirective(
12050     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12051     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12052   if (!AStmt)
12053     return StmtError();
12054 
12055   auto *CS = cast<CapturedStmt>(AStmt);
12056   // 1.2.2 OpenMP Language Terminology
12057   // Structured block - An executable statement with a single entry at the
12058   // top and a single exit at the bottom.
12059   // The point of exit cannot be a branch out of the structured block.
12060   // longjmp() and throw() must not violate the entry/exit criteria.
12061   CS->getCapturedDecl()->setNothrow();
12062   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd);
12063        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12064     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12065     // 1.2.2 OpenMP Language Terminology
12066     // Structured block - An executable statement with a single entry at the
12067     // top and a single exit at the bottom.
12068     // The point of exit cannot be a branch out of the structured block.
12069     // longjmp() and throw() must not violate the entry/exit criteria.
12070     CS->getCapturedDecl()->setNothrow();
12071   }
12072 
12073   OMPLoopBasedDirective::HelperExprs B;
12074   // In presence of clause 'collapse' with number of loops, it will define the
12075   // nested loops number.
12076   unsigned NestedLoopCount =
12077       checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses),
12078                       getOrderedNumberExpr(Clauses), CS, *this, *DSAStack,
12079                       VarsWithImplicitDSA, B);
12080   if (NestedLoopCount == 0)
12081     return StmtError();
12082 
12083   assert((CurContext->isDependentContext() || B.builtAll()) &&
12084          "omp target simd loop exprs were not built");
12085 
12086   if (!CurContext->isDependentContext()) {
12087     // Finalize the clauses that need pre-built expressions for CodeGen.
12088     for (OMPClause *C : Clauses) {
12089       if (auto *LC = dyn_cast<OMPLinearClause>(C))
12090         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12091                                      B.NumIterations, *this, CurScope,
12092                                      DSAStack))
12093           return StmtError();
12094     }
12095   }
12096 
12097   if (checkSimdlenSafelenSpecified(*this, Clauses))
12098     return StmtError();
12099 
12100   setFunctionHasBranchProtectedScope();
12101   return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc,
12102                                         NestedLoopCount, Clauses, AStmt, B);
12103 }
12104 
ActOnOpenMPTeamsDistributeDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12105 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective(
12106     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12107     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12108   if (!AStmt)
12109     return StmtError();
12110 
12111   auto *CS = cast<CapturedStmt>(AStmt);
12112   // 1.2.2 OpenMP Language Terminology
12113   // Structured block - An executable statement with a single entry at the
12114   // top and a single exit at the bottom.
12115   // The point of exit cannot be a branch out of the structured block.
12116   // longjmp() and throw() must not violate the entry/exit criteria.
12117   CS->getCapturedDecl()->setNothrow();
12118   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute);
12119        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12120     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12121     // 1.2.2 OpenMP Language Terminology
12122     // Structured block - An executable statement with a single entry at the
12123     // top and a single exit at the bottom.
12124     // The point of exit cannot be a branch out of the structured block.
12125     // longjmp() and throw() must not violate the entry/exit criteria.
12126     CS->getCapturedDecl()->setNothrow();
12127   }
12128 
12129   OMPLoopBasedDirective::HelperExprs B;
12130   // In presence of clause 'collapse' with number of loops, it will
12131   // define the nested loops number.
12132   unsigned NestedLoopCount =
12133       checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses),
12134                       nullptr /*ordered not a clause on distribute*/, CS, *this,
12135                       *DSAStack, VarsWithImplicitDSA, B);
12136   if (NestedLoopCount == 0)
12137     return StmtError();
12138 
12139   assert((CurContext->isDependentContext() || B.builtAll()) &&
12140          "omp teams distribute loop exprs were not built");
12141 
12142   setFunctionHasBranchProtectedScope();
12143 
12144   DSAStack->setParentTeamsRegionLoc(StartLoc);
12145 
12146   return OMPTeamsDistributeDirective::Create(
12147       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12148 }
12149 
ActOnOpenMPTeamsDistributeSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12150 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective(
12151     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12152     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12153   if (!AStmt)
12154     return StmtError();
12155 
12156   auto *CS = cast<CapturedStmt>(AStmt);
12157   // 1.2.2 OpenMP Language Terminology
12158   // Structured block - An executable statement with a single entry at the
12159   // top and a single exit at the bottom.
12160   // The point of exit cannot be a branch out of the structured block.
12161   // longjmp() and throw() must not violate the entry/exit criteria.
12162   CS->getCapturedDecl()->setNothrow();
12163   for (int ThisCaptureLevel =
12164            getOpenMPCaptureLevels(OMPD_teams_distribute_simd);
12165        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12166     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12167     // 1.2.2 OpenMP Language Terminology
12168     // Structured block - An executable statement with a single entry at the
12169     // top and a single exit at the bottom.
12170     // The point of exit cannot be a branch out of the structured block.
12171     // longjmp() and throw() must not violate the entry/exit criteria.
12172     CS->getCapturedDecl()->setNothrow();
12173   }
12174 
12175   OMPLoopBasedDirective::HelperExprs B;
12176   // In presence of clause 'collapse' with number of loops, it will
12177   // define the nested loops number.
12178   unsigned NestedLoopCount = checkOpenMPLoop(
12179       OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses),
12180       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
12181       VarsWithImplicitDSA, B);
12182 
12183   if (NestedLoopCount == 0)
12184     return StmtError();
12185 
12186   assert((CurContext->isDependentContext() || B.builtAll()) &&
12187          "omp teams distribute simd loop exprs were not built");
12188 
12189   if (!CurContext->isDependentContext()) {
12190     // Finalize the clauses that need pre-built expressions for CodeGen.
12191     for (OMPClause *C : Clauses) {
12192       if (auto *LC = dyn_cast<OMPLinearClause>(C))
12193         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12194                                      B.NumIterations, *this, CurScope,
12195                                      DSAStack))
12196           return StmtError();
12197     }
12198   }
12199 
12200   if (checkSimdlenSafelenSpecified(*this, Clauses))
12201     return StmtError();
12202 
12203   setFunctionHasBranchProtectedScope();
12204 
12205   DSAStack->setParentTeamsRegionLoc(StartLoc);
12206 
12207   return OMPTeamsDistributeSimdDirective::Create(
12208       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12209 }
12210 
ActOnOpenMPTeamsDistributeParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12211 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective(
12212     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12213     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12214   if (!AStmt)
12215     return StmtError();
12216 
12217   auto *CS = cast<CapturedStmt>(AStmt);
12218   // 1.2.2 OpenMP Language Terminology
12219   // Structured block - An executable statement with a single entry at the
12220   // top and a single exit at the bottom.
12221   // The point of exit cannot be a branch out of the structured block.
12222   // longjmp() and throw() must not violate the entry/exit criteria.
12223   CS->getCapturedDecl()->setNothrow();
12224 
12225   for (int ThisCaptureLevel =
12226            getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd);
12227        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12228     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12229     // 1.2.2 OpenMP Language Terminology
12230     // Structured block - An executable statement with a single entry at the
12231     // top and a single exit at the bottom.
12232     // The point of exit cannot be a branch out of the structured block.
12233     // longjmp() and throw() must not violate the entry/exit criteria.
12234     CS->getCapturedDecl()->setNothrow();
12235   }
12236 
12237   OMPLoopBasedDirective::HelperExprs B;
12238   // In presence of clause 'collapse' with number of loops, it will
12239   // define the nested loops number.
12240   unsigned NestedLoopCount = checkOpenMPLoop(
12241       OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses),
12242       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
12243       VarsWithImplicitDSA, B);
12244 
12245   if (NestedLoopCount == 0)
12246     return StmtError();
12247 
12248   assert((CurContext->isDependentContext() || B.builtAll()) &&
12249          "omp for loop exprs were not built");
12250 
12251   if (!CurContext->isDependentContext()) {
12252     // Finalize the clauses that need pre-built expressions for CodeGen.
12253     for (OMPClause *C : Clauses) {
12254       if (auto *LC = dyn_cast<OMPLinearClause>(C))
12255         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12256                                      B.NumIterations, *this, CurScope,
12257                                      DSAStack))
12258           return StmtError();
12259     }
12260   }
12261 
12262   if (checkSimdlenSafelenSpecified(*this, Clauses))
12263     return StmtError();
12264 
12265   setFunctionHasBranchProtectedScope();
12266 
12267   DSAStack->setParentTeamsRegionLoc(StartLoc);
12268 
12269   return OMPTeamsDistributeParallelForSimdDirective::Create(
12270       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12271 }
12272 
ActOnOpenMPTeamsDistributeParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12273 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective(
12274     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12275     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12276   if (!AStmt)
12277     return StmtError();
12278 
12279   auto *CS = cast<CapturedStmt>(AStmt);
12280   // 1.2.2 OpenMP Language Terminology
12281   // Structured block - An executable statement with a single entry at the
12282   // top and a single exit at the bottom.
12283   // The point of exit cannot be a branch out of the structured block.
12284   // longjmp() and throw() must not violate the entry/exit criteria.
12285   CS->getCapturedDecl()->setNothrow();
12286 
12287   for (int ThisCaptureLevel =
12288            getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for);
12289        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12290     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12291     // 1.2.2 OpenMP Language Terminology
12292     // Structured block - An executable statement with a single entry at the
12293     // top and a single exit at the bottom.
12294     // The point of exit cannot be a branch out of the structured block.
12295     // longjmp() and throw() must not violate the entry/exit criteria.
12296     CS->getCapturedDecl()->setNothrow();
12297   }
12298 
12299   OMPLoopBasedDirective::HelperExprs B;
12300   // In presence of clause 'collapse' with number of loops, it will
12301   // define the nested loops number.
12302   unsigned NestedLoopCount = checkOpenMPLoop(
12303       OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
12304       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
12305       VarsWithImplicitDSA, B);
12306 
12307   if (NestedLoopCount == 0)
12308     return StmtError();
12309 
12310   assert((CurContext->isDependentContext() || B.builtAll()) &&
12311          "omp for loop exprs were not built");
12312 
12313   setFunctionHasBranchProtectedScope();
12314 
12315   DSAStack->setParentTeamsRegionLoc(StartLoc);
12316 
12317   return OMPTeamsDistributeParallelForDirective::Create(
12318       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
12319       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
12320 }
12321 
ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)12322 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses,
12323                                                  Stmt *AStmt,
12324                                                  SourceLocation StartLoc,
12325                                                  SourceLocation EndLoc) {
12326   if (!AStmt)
12327     return StmtError();
12328 
12329   auto *CS = cast<CapturedStmt>(AStmt);
12330   // 1.2.2 OpenMP Language Terminology
12331   // Structured block - An executable statement with a single entry at the
12332   // top and a single exit at the bottom.
12333   // The point of exit cannot be a branch out of the structured block.
12334   // longjmp() and throw() must not violate the entry/exit criteria.
12335   CS->getCapturedDecl()->setNothrow();
12336 
12337   for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams);
12338        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12339     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12340     // 1.2.2 OpenMP Language Terminology
12341     // Structured block - An executable statement with a single entry at the
12342     // top and a single exit at the bottom.
12343     // The point of exit cannot be a branch out of the structured block.
12344     // longjmp() and throw() must not violate the entry/exit criteria.
12345     CS->getCapturedDecl()->setNothrow();
12346   }
12347   setFunctionHasBranchProtectedScope();
12348 
12349   return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses,
12350                                          AStmt);
12351 }
12352 
ActOnOpenMPTargetTeamsDistributeDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12353 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective(
12354     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12355     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12356   if (!AStmt)
12357     return StmtError();
12358 
12359   auto *CS = cast<CapturedStmt>(AStmt);
12360   // 1.2.2 OpenMP Language Terminology
12361   // Structured block - An executable statement with a single entry at the
12362   // top and a single exit at the bottom.
12363   // The point of exit cannot be a branch out of the structured block.
12364   // longjmp() and throw() must not violate the entry/exit criteria.
12365   CS->getCapturedDecl()->setNothrow();
12366   for (int ThisCaptureLevel =
12367            getOpenMPCaptureLevels(OMPD_target_teams_distribute);
12368        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12369     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12370     // 1.2.2 OpenMP Language Terminology
12371     // Structured block - An executable statement with a single entry at the
12372     // top and a single exit at the bottom.
12373     // The point of exit cannot be a branch out of the structured block.
12374     // longjmp() and throw() must not violate the entry/exit criteria.
12375     CS->getCapturedDecl()->setNothrow();
12376   }
12377 
12378   OMPLoopBasedDirective::HelperExprs B;
12379   // In presence of clause 'collapse' with number of loops, it will
12380   // define the nested loops number.
12381   unsigned NestedLoopCount = checkOpenMPLoop(
12382       OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses),
12383       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
12384       VarsWithImplicitDSA, B);
12385   if (NestedLoopCount == 0)
12386     return StmtError();
12387 
12388   assert((CurContext->isDependentContext() || B.builtAll()) &&
12389          "omp target teams distribute loop exprs were not built");
12390 
12391   setFunctionHasBranchProtectedScope();
12392   return OMPTargetTeamsDistributeDirective::Create(
12393       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12394 }
12395 
ActOnOpenMPTargetTeamsDistributeParallelForDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12396 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective(
12397     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12398     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12399   if (!AStmt)
12400     return StmtError();
12401 
12402   auto *CS = cast<CapturedStmt>(AStmt);
12403   // 1.2.2 OpenMP Language Terminology
12404   // Structured block - An executable statement with a single entry at the
12405   // top and a single exit at the bottom.
12406   // The point of exit cannot be a branch out of the structured block.
12407   // longjmp() and throw() must not violate the entry/exit criteria.
12408   CS->getCapturedDecl()->setNothrow();
12409   for (int ThisCaptureLevel =
12410            getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for);
12411        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12412     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12413     // 1.2.2 OpenMP Language Terminology
12414     // Structured block - An executable statement with a single entry at the
12415     // top and a single exit at the bottom.
12416     // The point of exit cannot be a branch out of the structured block.
12417     // longjmp() and throw() must not violate the entry/exit criteria.
12418     CS->getCapturedDecl()->setNothrow();
12419   }
12420 
12421   OMPLoopBasedDirective::HelperExprs B;
12422   // In presence of clause 'collapse' with number of loops, it will
12423   // define the nested loops number.
12424   unsigned NestedLoopCount = checkOpenMPLoop(
12425       OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses),
12426       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
12427       VarsWithImplicitDSA, B);
12428   if (NestedLoopCount == 0)
12429     return StmtError();
12430 
12431   assert((CurContext->isDependentContext() || B.builtAll()) &&
12432          "omp target teams distribute parallel for loop exprs were not built");
12433 
12434   if (!CurContext->isDependentContext()) {
12435     // Finalize the clauses that need pre-built expressions for CodeGen.
12436     for (OMPClause *C : Clauses) {
12437       if (auto *LC = dyn_cast<OMPLinearClause>(C))
12438         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12439                                      B.NumIterations, *this, CurScope,
12440                                      DSAStack))
12441           return StmtError();
12442     }
12443   }
12444 
12445   setFunctionHasBranchProtectedScope();
12446   return OMPTargetTeamsDistributeParallelForDirective::Create(
12447       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B,
12448       DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion());
12449 }
12450 
ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12451 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective(
12452     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12453     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12454   if (!AStmt)
12455     return StmtError();
12456 
12457   auto *CS = cast<CapturedStmt>(AStmt);
12458   // 1.2.2 OpenMP Language Terminology
12459   // Structured block - An executable statement with a single entry at the
12460   // top and a single exit at the bottom.
12461   // The point of exit cannot be a branch out of the structured block.
12462   // longjmp() and throw() must not violate the entry/exit criteria.
12463   CS->getCapturedDecl()->setNothrow();
12464   for (int ThisCaptureLevel = getOpenMPCaptureLevels(
12465            OMPD_target_teams_distribute_parallel_for_simd);
12466        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12467     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12468     // 1.2.2 OpenMP Language Terminology
12469     // Structured block - An executable statement with a single entry at the
12470     // top and a single exit at the bottom.
12471     // The point of exit cannot be a branch out of the structured block.
12472     // longjmp() and throw() must not violate the entry/exit criteria.
12473     CS->getCapturedDecl()->setNothrow();
12474   }
12475 
12476   OMPLoopBasedDirective::HelperExprs B;
12477   // In presence of clause 'collapse' with number of loops, it will
12478   // define the nested loops number.
12479   unsigned NestedLoopCount =
12480       checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd,
12481                       getCollapseNumberExpr(Clauses),
12482                       nullptr /*ordered not a clause on distribute*/, CS, *this,
12483                       *DSAStack, VarsWithImplicitDSA, B);
12484   if (NestedLoopCount == 0)
12485     return StmtError();
12486 
12487   assert((CurContext->isDependentContext() || B.builtAll()) &&
12488          "omp target teams distribute parallel for simd loop exprs were not "
12489          "built");
12490 
12491   if (!CurContext->isDependentContext()) {
12492     // Finalize the clauses that need pre-built expressions for CodeGen.
12493     for (OMPClause *C : Clauses) {
12494       if (auto *LC = dyn_cast<OMPLinearClause>(C))
12495         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12496                                      B.NumIterations, *this, CurScope,
12497                                      DSAStack))
12498           return StmtError();
12499     }
12500   }
12501 
12502   if (checkSimdlenSafelenSpecified(*this, Clauses))
12503     return StmtError();
12504 
12505   setFunctionHasBranchProtectedScope();
12506   return OMPTargetTeamsDistributeParallelForSimdDirective::Create(
12507       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12508 }
12509 
ActOnOpenMPTargetTeamsDistributeSimdDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc,VarsWithInheritedDSAType & VarsWithImplicitDSA)12510 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective(
12511     ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc,
12512     SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) {
12513   if (!AStmt)
12514     return StmtError();
12515 
12516   auto *CS = cast<CapturedStmt>(AStmt);
12517   // 1.2.2 OpenMP Language Terminology
12518   // Structured block - An executable statement with a single entry at the
12519   // top and a single exit at the bottom.
12520   // The point of exit cannot be a branch out of the structured block.
12521   // longjmp() and throw() must not violate the entry/exit criteria.
12522   CS->getCapturedDecl()->setNothrow();
12523   for (int ThisCaptureLevel =
12524            getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd);
12525        ThisCaptureLevel > 1; --ThisCaptureLevel) {
12526     CS = cast<CapturedStmt>(CS->getCapturedStmt());
12527     // 1.2.2 OpenMP Language Terminology
12528     // Structured block - An executable statement with a single entry at the
12529     // top and a single exit at the bottom.
12530     // The point of exit cannot be a branch out of the structured block.
12531     // longjmp() and throw() must not violate the entry/exit criteria.
12532     CS->getCapturedDecl()->setNothrow();
12533   }
12534 
12535   OMPLoopBasedDirective::HelperExprs B;
12536   // In presence of clause 'collapse' with number of loops, it will
12537   // define the nested loops number.
12538   unsigned NestedLoopCount = checkOpenMPLoop(
12539       OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses),
12540       nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack,
12541       VarsWithImplicitDSA, B);
12542   if (NestedLoopCount == 0)
12543     return StmtError();
12544 
12545   assert((CurContext->isDependentContext() || B.builtAll()) &&
12546          "omp target teams distribute simd loop exprs were not built");
12547 
12548   if (!CurContext->isDependentContext()) {
12549     // Finalize the clauses that need pre-built expressions for CodeGen.
12550     for (OMPClause *C : Clauses) {
12551       if (auto *LC = dyn_cast<OMPLinearClause>(C))
12552         if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef),
12553                                      B.NumIterations, *this, CurScope,
12554                                      DSAStack))
12555           return StmtError();
12556     }
12557   }
12558 
12559   if (checkSimdlenSafelenSpecified(*this, Clauses))
12560     return StmtError();
12561 
12562   setFunctionHasBranchProtectedScope();
12563   return OMPTargetTeamsDistributeSimdDirective::Create(
12564       Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B);
12565 }
12566 
checkTransformableLoopNest(OpenMPDirectiveKind Kind,Stmt * AStmt,int NumLoops,SmallVectorImpl<OMPLoopBasedDirective::HelperExprs> & LoopHelpers,Stmt * & Body,SmallVectorImpl<SmallVector<llvm::PointerUnion<Stmt *,Decl * >,0>> & OriginalInits)12567 bool Sema::checkTransformableLoopNest(
12568     OpenMPDirectiveKind Kind, Stmt *AStmt, int NumLoops,
12569     SmallVectorImpl<OMPLoopBasedDirective::HelperExprs> &LoopHelpers,
12570     Stmt *&Body,
12571     SmallVectorImpl<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>>
12572         &OriginalInits) {
12573   OriginalInits.emplace_back();
12574   bool Result = OMPLoopBasedDirective::doForAllLoops(
12575       AStmt->IgnoreContainers(), /*TryImperfectlyNestedLoops=*/false, NumLoops,
12576       [this, &LoopHelpers, &Body, &OriginalInits, Kind](unsigned Cnt,
12577                                                         Stmt *CurStmt) {
12578         VarsWithInheritedDSAType TmpDSA;
12579         unsigned SingleNumLoops =
12580             checkOpenMPLoop(Kind, nullptr, nullptr, CurStmt, *this, *DSAStack,
12581                             TmpDSA, LoopHelpers[Cnt]);
12582         if (SingleNumLoops == 0)
12583           return true;
12584         assert(SingleNumLoops == 1 && "Expect single loop iteration space");
12585         if (auto *For = dyn_cast<ForStmt>(CurStmt)) {
12586           OriginalInits.back().push_back(For->getInit());
12587           Body = For->getBody();
12588         } else {
12589           assert(isa<CXXForRangeStmt>(CurStmt) &&
12590                  "Expected canonical for or range-based for loops.");
12591           auto *CXXFor = cast<CXXForRangeStmt>(CurStmt);
12592           OriginalInits.back().push_back(CXXFor->getBeginStmt());
12593           Body = CXXFor->getBody();
12594         }
12595         OriginalInits.emplace_back();
12596         return false;
12597       },
12598       [&OriginalInits](OMPLoopBasedDirective *Transform) {
12599         Stmt *DependentPreInits;
12600         if (auto *Dir = dyn_cast<OMPTileDirective>(Transform))
12601           DependentPreInits = Dir->getPreInits();
12602         else if (auto *Dir = dyn_cast<OMPUnrollDirective>(Transform))
12603           DependentPreInits = Dir->getPreInits();
12604         else
12605           llvm_unreachable("Unhandled loop transformation");
12606         if (!DependentPreInits)
12607           return;
12608         for (Decl *C : cast<DeclStmt>(DependentPreInits)->getDeclGroup())
12609           OriginalInits.back().push_back(C);
12610       });
12611   assert(OriginalInits.back().empty() && "No preinit after innermost loop");
12612   OriginalInits.pop_back();
12613   return Result;
12614 }
12615 
ActOnOpenMPTileDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)12616 StmtResult Sema::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses,
12617                                           Stmt *AStmt, SourceLocation StartLoc,
12618                                           SourceLocation EndLoc) {
12619   auto SizesClauses =
12620       OMPExecutableDirective::getClausesOfKind<OMPSizesClause>(Clauses);
12621   if (SizesClauses.empty()) {
12622     // A missing 'sizes' clause is already reported by the parser.
12623     return StmtError();
12624   }
12625   const OMPSizesClause *SizesClause = *SizesClauses.begin();
12626   unsigned NumLoops = SizesClause->getNumSizes();
12627 
12628   // Empty statement should only be possible if there already was an error.
12629   if (!AStmt)
12630     return StmtError();
12631 
12632   // Verify and diagnose loop nest.
12633   SmallVector<OMPLoopBasedDirective::HelperExprs, 4> LoopHelpers(NumLoops);
12634   Stmt *Body = nullptr;
12635   SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, 4>
12636       OriginalInits;
12637   if (!checkTransformableLoopNest(OMPD_tile, AStmt, NumLoops, LoopHelpers, Body,
12638                                   OriginalInits))
12639     return StmtError();
12640 
12641   // Delay tiling to when template is completely instantiated.
12642   if (CurContext->isDependentContext())
12643     return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses,
12644                                     NumLoops, AStmt, nullptr, nullptr);
12645 
12646   SmallVector<Decl *, 4> PreInits;
12647 
12648   // Create iteration variables for the generated loops.
12649   SmallVector<VarDecl *, 4> FloorIndVars;
12650   SmallVector<VarDecl *, 4> TileIndVars;
12651   FloorIndVars.resize(NumLoops);
12652   TileIndVars.resize(NumLoops);
12653   for (unsigned I = 0; I < NumLoops; ++I) {
12654     OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
12655 
12656     assert(LoopHelper.Counters.size() == 1 &&
12657            "Expect single-dimensional loop iteration space");
12658     auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
12659     std::string OrigVarName = OrigCntVar->getNameInfo().getAsString();
12660     DeclRefExpr *IterVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
12661     QualType CntTy = IterVarRef->getType();
12662 
12663     // Iteration variable for the floor (i.e. outer) loop.
12664     {
12665       std::string FloorCntName =
12666           (Twine(".floor_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
12667       VarDecl *FloorCntDecl =
12668           buildVarDecl(*this, {}, CntTy, FloorCntName, nullptr, OrigCntVar);
12669       FloorIndVars[I] = FloorCntDecl;
12670     }
12671 
12672     // Iteration variable for the tile (i.e. inner) loop.
12673     {
12674       std::string TileCntName =
12675           (Twine(".tile_") + llvm::utostr(I) + ".iv." + OrigVarName).str();
12676 
12677       // Reuse the iteration variable created by checkOpenMPLoop. It is also
12678       // used by the expressions to derive the original iteration variable's
12679       // value from the logical iteration number.
12680       auto *TileCntDecl = cast<VarDecl>(IterVarRef->getDecl());
12681       TileCntDecl->setDeclName(&PP.getIdentifierTable().get(TileCntName));
12682       TileIndVars[I] = TileCntDecl;
12683     }
12684     for (auto &P : OriginalInits[I]) {
12685       if (auto *D = P.dyn_cast<Decl *>())
12686         PreInits.push_back(D);
12687       else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>()))
12688         PreInits.append(PI->decl_begin(), PI->decl_end());
12689     }
12690     if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
12691       PreInits.append(PI->decl_begin(), PI->decl_end());
12692     // Gather declarations for the data members used as counters.
12693     for (Expr *CounterRef : LoopHelper.Counters) {
12694       auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
12695       if (isa<OMPCapturedExprDecl>(CounterDecl))
12696         PreInits.push_back(CounterDecl);
12697     }
12698   }
12699 
12700   // Once the original iteration values are set, append the innermost body.
12701   Stmt *Inner = Body;
12702 
12703   // Create tile loops from the inside to the outside.
12704   for (int I = NumLoops - 1; I >= 0; --I) {
12705     OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I];
12706     Expr *NumIterations = LoopHelper.NumIterations;
12707     auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
12708     QualType CntTy = OrigCntVar->getType();
12709     Expr *DimTileSize = SizesClause->getSizesRefs()[I];
12710     Scope *CurScope = getCurScope();
12711 
12712     // Commonly used variables.
12713     DeclRefExpr *TileIV = buildDeclRefExpr(*this, TileIndVars[I], CntTy,
12714                                            OrigCntVar->getExprLoc());
12715     DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
12716                                             OrigCntVar->getExprLoc());
12717 
12718     // For init-statement: auto .tile.iv = .floor.iv
12719     AddInitializerToDecl(TileIndVars[I], DefaultLvalueConversion(FloorIV).get(),
12720                          /*DirectInit=*/false);
12721     Decl *CounterDecl = TileIndVars[I];
12722     StmtResult InitStmt = new (Context)
12723         DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
12724                  OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
12725     if (!InitStmt.isUsable())
12726       return StmtError();
12727 
12728     // For cond-expression: .tile.iv < min(.floor.iv + DimTileSize,
12729     // NumIterations)
12730     ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
12731                                       BO_Add, FloorIV, DimTileSize);
12732     if (!EndOfTile.isUsable())
12733       return StmtError();
12734     ExprResult IsPartialTile =
12735         BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT,
12736                    NumIterations, EndOfTile.get());
12737     if (!IsPartialTile.isUsable())
12738       return StmtError();
12739     ExprResult MinTileAndIterSpace = ActOnConditionalOp(
12740         LoopHelper.Cond->getBeginLoc(), LoopHelper.Cond->getEndLoc(),
12741         IsPartialTile.get(), NumIterations, EndOfTile.get());
12742     if (!MinTileAndIterSpace.isUsable())
12743       return StmtError();
12744     ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
12745                                      BO_LT, TileIV, MinTileAndIterSpace.get());
12746     if (!CondExpr.isUsable())
12747       return StmtError();
12748 
12749     // For incr-statement: ++.tile.iv
12750     ExprResult IncrStmt =
12751         BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), UO_PreInc, TileIV);
12752     if (!IncrStmt.isUsable())
12753       return StmtError();
12754 
12755     // Statements to set the original iteration variable's value from the
12756     // logical iteration number.
12757     // Generated for loop is:
12758     // Original_for_init;
12759     // for (auto .tile.iv = .floor.iv; .tile.iv < min(.floor.iv + DimTileSize,
12760     // NumIterations); ++.tile.iv) {
12761     //   Original_Body;
12762     //   Original_counter_update;
12763     // }
12764     // FIXME: If the innermost body is an loop itself, inserting these
12765     // statements stops it being recognized  as a perfectly nested loop (e.g.
12766     // for applying tiling again). If this is the case, sink the expressions
12767     // further into the inner loop.
12768     SmallVector<Stmt *, 4> BodyParts;
12769     BodyParts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
12770     BodyParts.push_back(Inner);
12771     Inner = CompoundStmt::Create(Context, BodyParts, Inner->getBeginLoc(),
12772                                  Inner->getEndLoc());
12773     Inner = new (Context)
12774         ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
12775                 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
12776                 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
12777   }
12778 
12779   // Create floor loops from the inside to the outside.
12780   for (int I = NumLoops - 1; I >= 0; --I) {
12781     auto &LoopHelper = LoopHelpers[I];
12782     Expr *NumIterations = LoopHelper.NumIterations;
12783     DeclRefExpr *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]);
12784     QualType CntTy = OrigCntVar->getType();
12785     Expr *DimTileSize = SizesClause->getSizesRefs()[I];
12786     Scope *CurScope = getCurScope();
12787 
12788     // Commonly used variables.
12789     DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy,
12790                                             OrigCntVar->getExprLoc());
12791 
12792     // For init-statement: auto .floor.iv = 0
12793     AddInitializerToDecl(
12794         FloorIndVars[I],
12795         ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
12796         /*DirectInit=*/false);
12797     Decl *CounterDecl = FloorIndVars[I];
12798     StmtResult InitStmt = new (Context)
12799         DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1),
12800                  OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc());
12801     if (!InitStmt.isUsable())
12802       return StmtError();
12803 
12804     // For cond-expression: .floor.iv < NumIterations
12805     ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
12806                                      BO_LT, FloorIV, NumIterations);
12807     if (!CondExpr.isUsable())
12808       return StmtError();
12809 
12810     // For incr-statement: .floor.iv += DimTileSize
12811     ExprResult IncrStmt = BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(),
12812                                      BO_AddAssign, FloorIV, DimTileSize);
12813     if (!IncrStmt.isUsable())
12814       return StmtError();
12815 
12816     Inner = new (Context)
12817         ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr,
12818                 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(),
12819                 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
12820   }
12821 
12822   return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, NumLoops,
12823                                   AStmt, Inner,
12824                                   buildPreInits(Context, PreInits));
12825 }
12826 
ActOnOpenMPUnrollDirective(ArrayRef<OMPClause * > Clauses,Stmt * AStmt,SourceLocation StartLoc,SourceLocation EndLoc)12827 StmtResult Sema::ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses,
12828                                             Stmt *AStmt,
12829                                             SourceLocation StartLoc,
12830                                             SourceLocation EndLoc) {
12831   // Empty statement should only be possible if there already was an error.
12832   if (!AStmt)
12833     return StmtError();
12834 
12835   if (checkMutuallyExclusiveClauses(*this, Clauses, {OMPC_partial, OMPC_full}))
12836     return StmtError();
12837 
12838   const OMPFullClause *FullClause =
12839       OMPExecutableDirective::getSingleClause<OMPFullClause>(Clauses);
12840   const OMPPartialClause *PartialClause =
12841       OMPExecutableDirective::getSingleClause<OMPPartialClause>(Clauses);
12842   assert(!(FullClause && PartialClause) &&
12843          "mutual exclusivity must have been checked before");
12844 
12845   constexpr unsigned NumLoops = 1;
12846   Stmt *Body = nullptr;
12847   SmallVector<OMPLoopBasedDirective::HelperExprs, NumLoops> LoopHelpers(
12848       NumLoops);
12849   SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, NumLoops + 1>
12850       OriginalInits;
12851   if (!checkTransformableLoopNest(OMPD_unroll, AStmt, NumLoops, LoopHelpers,
12852                                   Body, OriginalInits))
12853     return StmtError();
12854 
12855   // Delay unrolling to when template is completely instantiated.
12856   if (CurContext->isDependentContext())
12857     return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
12858                                       nullptr, nullptr);
12859 
12860   OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front();
12861 
12862   if (FullClause) {
12863     if (!VerifyPositiveIntegerConstantInClause(
12864              LoopHelper.NumIterations, OMPC_full, /*StrictlyPositive=*/false,
12865              /*SuppressExprDigs=*/true)
12866              .isUsable()) {
12867       Diag(AStmt->getBeginLoc(), diag::err_omp_unroll_full_variable_trip_count);
12868       Diag(FullClause->getBeginLoc(), diag::note_omp_directive_here)
12869           << "#pragma omp unroll full";
12870       return StmtError();
12871     }
12872   }
12873 
12874   // The generated loop may only be passed to other loop-associated directive
12875   // when a partial clause is specified. Without the requirement it is
12876   // sufficient to generate loop unroll metadata at code-generation.
12877   if (!PartialClause)
12878     return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
12879                                       nullptr, nullptr);
12880 
12881   // Otherwise, we need to provide a de-sugared/transformed AST that can be
12882   // associated with another loop directive.
12883   //
12884   // The canonical loop analysis return by checkTransformableLoopNest assumes
12885   // the following structure to be the same loop without transformations or
12886   // directives applied: \code OriginalInits; LoopHelper.PreInits;
12887   // LoopHelper.Counters;
12888   // for (; IV < LoopHelper.NumIterations; ++IV) {
12889   //   LoopHelper.Updates;
12890   //   Body;
12891   // }
12892   // \endcode
12893   // where IV is a variable declared and initialized to 0 in LoopHelper.PreInits
12894   // and referenced by LoopHelper.IterationVarRef.
12895   //
12896   // The unrolling directive transforms this into the following loop:
12897   // \code
12898   // OriginalInits;         \
12899   // LoopHelper.PreInits;    > NewPreInits
12900   // LoopHelper.Counters;   /
12901   // for (auto UIV = 0; UIV < LoopHelper.NumIterations; UIV+=Factor) {
12902   //   #pragma clang loop unroll_count(Factor)
12903   //   for (IV = UIV; IV < UIV + Factor && UIV < LoopHelper.NumIterations; ++IV)
12904   //   {
12905   //     LoopHelper.Updates;
12906   //     Body;
12907   //   }
12908   // }
12909   // \endcode
12910   // where UIV is a new logical iteration counter. IV must be the same VarDecl
12911   // as the original LoopHelper.IterationVarRef because LoopHelper.Updates
12912   // references it. If the partially unrolled loop is associated with another
12913   // loop directive (like an OMPForDirective), it will use checkOpenMPLoop to
12914   // analyze this loop, i.e. the outer loop must fulfill the constraints of an
12915   // OpenMP canonical loop. The inner loop is not an associable canonical loop
12916   // and only exists to defer its unrolling to LLVM's LoopUnroll instead of
12917   // doing it in the frontend (by adding loop metadata). NewPreInits becomes a
12918   // property of the OMPLoopBasedDirective instead of statements in
12919   // CompoundStatement. This is to allow the loop to become a non-outermost loop
12920   // of a canonical loop nest where these PreInits are emitted before the
12921   // outermost directive.
12922 
12923   // Determine the PreInit declarations.
12924   SmallVector<Decl *, 4> PreInits;
12925   assert(OriginalInits.size() == 1 &&
12926          "Expecting a single-dimensional loop iteration space");
12927   for (auto &P : OriginalInits[0]) {
12928     if (auto *D = P.dyn_cast<Decl *>())
12929       PreInits.push_back(D);
12930     else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>()))
12931       PreInits.append(PI->decl_begin(), PI->decl_end());
12932   }
12933   if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits))
12934     PreInits.append(PI->decl_begin(), PI->decl_end());
12935   // Gather declarations for the data members used as counters.
12936   for (Expr *CounterRef : LoopHelper.Counters) {
12937     auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl();
12938     if (isa<OMPCapturedExprDecl>(CounterDecl))
12939       PreInits.push_back(CounterDecl);
12940   }
12941 
12942   auto *IterationVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef);
12943   QualType IVTy = IterationVarRef->getType();
12944   assert(LoopHelper.Counters.size() == 1 &&
12945          "Expecting a single-dimensional loop iteration space");
12946   auto *OrigVar = cast<DeclRefExpr>(LoopHelper.Counters.front());
12947 
12948   // Determine the unroll factor.
12949   uint64_t Factor;
12950   SourceLocation FactorLoc;
12951   if (Expr *FactorVal = PartialClause->getFactor()) {
12952     Factor =
12953         FactorVal->getIntegerConstantExpr(Context).getValue().getZExtValue();
12954     FactorLoc = FactorVal->getExprLoc();
12955   } else {
12956     // TODO: Use a better profitability model.
12957     Factor = 2;
12958   }
12959   assert(Factor > 0 && "Expected positive unroll factor");
12960   auto MakeFactorExpr = [this, Factor, IVTy, FactorLoc]() {
12961     return IntegerLiteral::Create(
12962         Context, llvm::APInt(Context.getIntWidth(IVTy), Factor), IVTy,
12963         FactorLoc);
12964   };
12965 
12966   // Iteration variable SourceLocations.
12967   SourceLocation OrigVarLoc = OrigVar->getExprLoc();
12968   SourceLocation OrigVarLocBegin = OrigVar->getBeginLoc();
12969   SourceLocation OrigVarLocEnd = OrigVar->getEndLoc();
12970 
12971   // Internal variable names.
12972   std::string OrigVarName = OrigVar->getNameInfo().getAsString();
12973   std::string OuterIVName = (Twine(".unrolled.iv.") + OrigVarName).str();
12974   std::string InnerIVName = (Twine(".unroll_inner.iv.") + OrigVarName).str();
12975   std::string InnerTripCountName =
12976       (Twine(".unroll_inner.tripcount.") + OrigVarName).str();
12977 
12978   // Create the iteration variable for the unrolled loop.
12979   VarDecl *OuterIVDecl =
12980       buildVarDecl(*this, {}, IVTy, OuterIVName, nullptr, OrigVar);
12981   auto MakeOuterRef = [this, OuterIVDecl, IVTy, OrigVarLoc]() {
12982     return buildDeclRefExpr(*this, OuterIVDecl, IVTy, OrigVarLoc);
12983   };
12984 
12985   // Iteration variable for the inner loop: Reuse the iteration variable created
12986   // by checkOpenMPLoop.
12987   auto *InnerIVDecl = cast<VarDecl>(IterationVarRef->getDecl());
12988   InnerIVDecl->setDeclName(&PP.getIdentifierTable().get(InnerIVName));
12989   auto MakeInnerRef = [this, InnerIVDecl, IVTy, OrigVarLoc]() {
12990     return buildDeclRefExpr(*this, InnerIVDecl, IVTy, OrigVarLoc);
12991   };
12992 
12993   // Make a copy of the NumIterations expression for each use: By the AST
12994   // constraints, every expression object in a DeclContext must be unique.
12995   CaptureVars CopyTransformer(*this);
12996   auto MakeNumIterations = [&CopyTransformer, &LoopHelper]() -> Expr * {
12997     return AssertSuccess(
12998         CopyTransformer.TransformExpr(LoopHelper.NumIterations));
12999   };
13000 
13001   // Inner For init-statement: auto .unroll_inner.iv = .unrolled.iv
13002   ExprResult LValueConv = DefaultLvalueConversion(MakeOuterRef());
13003   AddInitializerToDecl(InnerIVDecl, LValueConv.get(), /*DirectInit=*/false);
13004   StmtResult InnerInit = new (Context)
13005       DeclStmt(DeclGroupRef(InnerIVDecl), OrigVarLocBegin, OrigVarLocEnd);
13006   if (!InnerInit.isUsable())
13007     return StmtError();
13008 
13009   // Inner For cond-expression:
13010   // \code
13011   //   .unroll_inner.iv < .unrolled.iv + Factor &&
13012   //   .unroll_inner.iv < NumIterations
13013   // \endcode
13014   // This conjunction of two conditions allows ScalarEvolution to derive the
13015   // maximum trip count of the inner loop.
13016   ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
13017                                     BO_Add, MakeOuterRef(), MakeFactorExpr());
13018   if (!EndOfTile.isUsable())
13019     return StmtError();
13020   ExprResult InnerCond1 = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(),
13021                                      BO_LE, MakeInnerRef(), EndOfTile.get());
13022   if (!InnerCond1.isUsable())
13023     return StmtError();
13024   ExprResult InnerCond2 =
13025       BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LE, MakeInnerRef(),
13026                  MakeNumIterations());
13027   if (!InnerCond2.isUsable())
13028     return StmtError();
13029   ExprResult InnerCond =
13030       BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LAnd,
13031                  InnerCond1.get(), InnerCond2.get());
13032   if (!InnerCond.isUsable())
13033     return StmtError();
13034 
13035   // Inner For incr-statement: ++.unroll_inner.iv
13036   ExprResult InnerIncr = BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(),
13037                                       UO_PreInc, MakeInnerRef());
13038   if (!InnerIncr.isUsable())
13039     return StmtError();
13040 
13041   // Inner For statement.
13042   SmallVector<Stmt *> InnerBodyStmts;
13043   InnerBodyStmts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end());
13044   InnerBodyStmts.push_back(Body);
13045   CompoundStmt *InnerBody = CompoundStmt::Create(
13046       Context, InnerBodyStmts, Body->getBeginLoc(), Body->getEndLoc());
13047   ForStmt *InnerFor = new (Context)
13048       ForStmt(Context, InnerInit.get(), InnerCond.get(), nullptr,
13049               InnerIncr.get(), InnerBody, LoopHelper.Init->getBeginLoc(),
13050               LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
13051 
13052   // Unroll metadata for the inner loop.
13053   // This needs to take into account the remainder portion of the unrolled loop,
13054   // hence `unroll(full)` does not apply here, even though the LoopUnroll pass
13055   // supports multiple loop exits. Instead, unroll using a factor equivalent to
13056   // the maximum trip count, which will also generate a remainder loop. Just
13057   // `unroll(enable)` (which could have been useful if the user has not
13058   // specified a concrete factor; even though the outer loop cannot be
13059   // influenced anymore, would avoid more code bloat than necessary) will refuse
13060   // the loop because "Won't unroll; remainder loop could not be generated when
13061   // assuming runtime trip count". Even if it did work, it must not choose a
13062   // larger unroll factor than the maximum loop length, or it would always just
13063   // execute the remainder loop.
13064   LoopHintAttr *UnrollHintAttr =
13065       LoopHintAttr::CreateImplicit(Context, LoopHintAttr::UnrollCount,
13066                                    LoopHintAttr::Numeric, MakeFactorExpr());
13067   AttributedStmt *InnerUnrolled =
13068       AttributedStmt::Create(Context, StartLoc, {UnrollHintAttr}, InnerFor);
13069 
13070   // Outer For init-statement: auto .unrolled.iv = 0
13071   AddInitializerToDecl(
13072       OuterIVDecl, ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(),
13073       /*DirectInit=*/false);
13074   StmtResult OuterInit = new (Context)
13075       DeclStmt(DeclGroupRef(OuterIVDecl), OrigVarLocBegin, OrigVarLocEnd);
13076   if (!OuterInit.isUsable())
13077     return StmtError();
13078 
13079   // Outer For cond-expression: .unrolled.iv < NumIterations
13080   ExprResult OuterConde =
13081       BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeOuterRef(),
13082                  MakeNumIterations());
13083   if (!OuterConde.isUsable())
13084     return StmtError();
13085 
13086   // Outer For incr-statement: .unrolled.iv += Factor
13087   ExprResult OuterIncr =
13088       BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(), BO_AddAssign,
13089                  MakeOuterRef(), MakeFactorExpr());
13090   if (!OuterIncr.isUsable())
13091     return StmtError();
13092 
13093   // Outer For statement.
13094   ForStmt *OuterFor = new (Context)
13095       ForStmt(Context, OuterInit.get(), OuterConde.get(), nullptr,
13096               OuterIncr.get(), InnerUnrolled, LoopHelper.Init->getBeginLoc(),
13097               LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc());
13098 
13099   return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt,
13100                                     OuterFor, buildPreInits(Context, PreInits));
13101 }
13102 
ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind,Expr * Expr,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)13103 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
13104                                              SourceLocation StartLoc,
13105                                              SourceLocation LParenLoc,
13106                                              SourceLocation EndLoc) {
13107   OMPClause *Res = nullptr;
13108   switch (Kind) {
13109   case OMPC_final:
13110     Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc);
13111     break;
13112   case OMPC_num_threads:
13113     Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc);
13114     break;
13115   case OMPC_safelen:
13116     Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc);
13117     break;
13118   case OMPC_simdlen:
13119     Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc);
13120     break;
13121   case OMPC_allocator:
13122     Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc);
13123     break;
13124   case OMPC_collapse:
13125     Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc);
13126     break;
13127   case OMPC_ordered:
13128     Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr);
13129     break;
13130   case OMPC_num_teams:
13131     Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc);
13132     break;
13133   case OMPC_thread_limit:
13134     Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc);
13135     break;
13136   case OMPC_priority:
13137     Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc);
13138     break;
13139   case OMPC_grainsize:
13140     Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc);
13141     break;
13142   case OMPC_num_tasks:
13143     Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc);
13144     break;
13145   case OMPC_hint:
13146     Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc);
13147     break;
13148   case OMPC_depobj:
13149     Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc);
13150     break;
13151   case OMPC_detach:
13152     Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc);
13153     break;
13154   case OMPC_novariants:
13155     Res = ActOnOpenMPNovariantsClause(Expr, StartLoc, LParenLoc, EndLoc);
13156     break;
13157   case OMPC_nocontext:
13158     Res = ActOnOpenMPNocontextClause(Expr, StartLoc, LParenLoc, EndLoc);
13159     break;
13160   case OMPC_filter:
13161     Res = ActOnOpenMPFilterClause(Expr, StartLoc, LParenLoc, EndLoc);
13162     break;
13163   case OMPC_partial:
13164     Res = ActOnOpenMPPartialClause(Expr, StartLoc, LParenLoc, EndLoc);
13165     break;
13166   case OMPC_device:
13167   case OMPC_if:
13168   case OMPC_default:
13169   case OMPC_proc_bind:
13170   case OMPC_schedule:
13171   case OMPC_private:
13172   case OMPC_firstprivate:
13173   case OMPC_lastprivate:
13174   case OMPC_shared:
13175   case OMPC_reduction:
13176   case OMPC_task_reduction:
13177   case OMPC_in_reduction:
13178   case OMPC_linear:
13179   case OMPC_aligned:
13180   case OMPC_copyin:
13181   case OMPC_copyprivate:
13182   case OMPC_nowait:
13183   case OMPC_untied:
13184   case OMPC_mergeable:
13185   case OMPC_threadprivate:
13186   case OMPC_sizes:
13187   case OMPC_allocate:
13188   case OMPC_flush:
13189   case OMPC_read:
13190   case OMPC_write:
13191   case OMPC_update:
13192   case OMPC_capture:
13193   case OMPC_seq_cst:
13194   case OMPC_acq_rel:
13195   case OMPC_acquire:
13196   case OMPC_release:
13197   case OMPC_relaxed:
13198   case OMPC_depend:
13199   case OMPC_threads:
13200   case OMPC_simd:
13201   case OMPC_map:
13202   case OMPC_nogroup:
13203   case OMPC_dist_schedule:
13204   case OMPC_defaultmap:
13205   case OMPC_unknown:
13206   case OMPC_uniform:
13207   case OMPC_to:
13208   case OMPC_from:
13209   case OMPC_use_device_ptr:
13210   case OMPC_use_device_addr:
13211   case OMPC_is_device_ptr:
13212   case OMPC_unified_address:
13213   case OMPC_unified_shared_memory:
13214   case OMPC_reverse_offload:
13215   case OMPC_dynamic_allocators:
13216   case OMPC_atomic_default_mem_order:
13217   case OMPC_device_type:
13218   case OMPC_match:
13219   case OMPC_nontemporal:
13220   case OMPC_order:
13221   case OMPC_destroy:
13222   case OMPC_inclusive:
13223   case OMPC_exclusive:
13224   case OMPC_uses_allocators:
13225   case OMPC_affinity:
13226   default:
13227     llvm_unreachable("Clause is not allowed.");
13228   }
13229   return Res;
13230 }
13231 
13232 // An OpenMP directive such as 'target parallel' has two captured regions:
13233 // for the 'target' and 'parallel' respectively.  This function returns
13234 // the region in which to capture expressions associated with a clause.
13235 // A return value of OMPD_unknown signifies that the expression should not
13236 // be captured.
getOpenMPCaptureRegionForClause(OpenMPDirectiveKind DKind,OpenMPClauseKind CKind,unsigned OpenMPVersion,OpenMPDirectiveKind NameModifier=OMPD_unknown)13237 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
13238     OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion,
13239     OpenMPDirectiveKind NameModifier = OMPD_unknown) {
13240   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
13241   switch (CKind) {
13242   case OMPC_if:
13243     switch (DKind) {
13244     case OMPD_target_parallel_for_simd:
13245       if (OpenMPVersion >= 50 &&
13246           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
13247         CaptureRegion = OMPD_parallel;
13248         break;
13249       }
13250       LLVM_FALLTHROUGH;
13251     case OMPD_target_parallel:
13252     case OMPD_target_parallel_for:
13253       // If this clause applies to the nested 'parallel' region, capture within
13254       // the 'target' region, otherwise do not capture.
13255       if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
13256         CaptureRegion = OMPD_target;
13257       break;
13258     case OMPD_target_teams_distribute_parallel_for_simd:
13259       if (OpenMPVersion >= 50 &&
13260           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
13261         CaptureRegion = OMPD_parallel;
13262         break;
13263       }
13264       LLVM_FALLTHROUGH;
13265     case OMPD_target_teams_distribute_parallel_for:
13266       // If this clause applies to the nested 'parallel' region, capture within
13267       // the 'teams' region, otherwise do not capture.
13268       if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel)
13269         CaptureRegion = OMPD_teams;
13270       break;
13271     case OMPD_teams_distribute_parallel_for_simd:
13272       if (OpenMPVersion >= 50 &&
13273           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) {
13274         CaptureRegion = OMPD_parallel;
13275         break;
13276       }
13277       LLVM_FALLTHROUGH;
13278     case OMPD_teams_distribute_parallel_for:
13279       CaptureRegion = OMPD_teams;
13280       break;
13281     case OMPD_target_update:
13282     case OMPD_target_enter_data:
13283     case OMPD_target_exit_data:
13284       CaptureRegion = OMPD_task;
13285       break;
13286     case OMPD_parallel_master_taskloop:
13287       if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop)
13288         CaptureRegion = OMPD_parallel;
13289       break;
13290     case OMPD_parallel_master_taskloop_simd:
13291       if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) ||
13292           NameModifier == OMPD_taskloop) {
13293         CaptureRegion = OMPD_parallel;
13294         break;
13295       }
13296       if (OpenMPVersion <= 45)
13297         break;
13298       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
13299         CaptureRegion = OMPD_taskloop;
13300       break;
13301     case OMPD_parallel_for_simd:
13302       if (OpenMPVersion <= 45)
13303         break;
13304       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
13305         CaptureRegion = OMPD_parallel;
13306       break;
13307     case OMPD_taskloop_simd:
13308     case OMPD_master_taskloop_simd:
13309       if (OpenMPVersion <= 45)
13310         break;
13311       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
13312         CaptureRegion = OMPD_taskloop;
13313       break;
13314     case OMPD_distribute_parallel_for_simd:
13315       if (OpenMPVersion <= 45)
13316         break;
13317       if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)
13318         CaptureRegion = OMPD_parallel;
13319       break;
13320     case OMPD_target_simd:
13321       if (OpenMPVersion >= 50 &&
13322           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
13323         CaptureRegion = OMPD_target;
13324       break;
13325     case OMPD_teams_distribute_simd:
13326     case OMPD_target_teams_distribute_simd:
13327       if (OpenMPVersion >= 50 &&
13328           (NameModifier == OMPD_unknown || NameModifier == OMPD_simd))
13329         CaptureRegion = OMPD_teams;
13330       break;
13331     case OMPD_cancel:
13332     case OMPD_parallel:
13333     case OMPD_parallel_master:
13334     case OMPD_parallel_sections:
13335     case OMPD_parallel_for:
13336     case OMPD_target:
13337     case OMPD_target_teams:
13338     case OMPD_target_teams_distribute:
13339     case OMPD_distribute_parallel_for:
13340     case OMPD_task:
13341     case OMPD_taskloop:
13342     case OMPD_master_taskloop:
13343     case OMPD_target_data:
13344     case OMPD_simd:
13345     case OMPD_for_simd:
13346     case OMPD_distribute_simd:
13347       // Do not capture if-clause expressions.
13348       break;
13349     case OMPD_threadprivate:
13350     case OMPD_allocate:
13351     case OMPD_taskyield:
13352     case OMPD_barrier:
13353     case OMPD_taskwait:
13354     case OMPD_cancellation_point:
13355     case OMPD_flush:
13356     case OMPD_depobj:
13357     case OMPD_scan:
13358     case OMPD_declare_reduction:
13359     case OMPD_declare_mapper:
13360     case OMPD_declare_simd:
13361     case OMPD_declare_variant:
13362     case OMPD_begin_declare_variant:
13363     case OMPD_end_declare_variant:
13364     case OMPD_declare_target:
13365     case OMPD_end_declare_target:
13366     case OMPD_teams:
13367     case OMPD_tile:
13368     case OMPD_unroll:
13369     case OMPD_for:
13370     case OMPD_sections:
13371     case OMPD_section:
13372     case OMPD_single:
13373     case OMPD_master:
13374     case OMPD_masked:
13375     case OMPD_critical:
13376     case OMPD_taskgroup:
13377     case OMPD_distribute:
13378     case OMPD_ordered:
13379     case OMPD_atomic:
13380     case OMPD_teams_distribute:
13381     case OMPD_requires:
13382       llvm_unreachable("Unexpected OpenMP directive with if-clause");
13383     case OMPD_unknown:
13384     default:
13385       llvm_unreachable("Unknown OpenMP directive");
13386     }
13387     break;
13388   case OMPC_num_threads:
13389     switch (DKind) {
13390     case OMPD_target_parallel:
13391     case OMPD_target_parallel_for:
13392     case OMPD_target_parallel_for_simd:
13393       CaptureRegion = OMPD_target;
13394       break;
13395     case OMPD_teams_distribute_parallel_for:
13396     case OMPD_teams_distribute_parallel_for_simd:
13397     case OMPD_target_teams_distribute_parallel_for:
13398     case OMPD_target_teams_distribute_parallel_for_simd:
13399       CaptureRegion = OMPD_teams;
13400       break;
13401     case OMPD_parallel:
13402     case OMPD_parallel_master:
13403     case OMPD_parallel_sections:
13404     case OMPD_parallel_for:
13405     case OMPD_parallel_for_simd:
13406     case OMPD_distribute_parallel_for:
13407     case OMPD_distribute_parallel_for_simd:
13408     case OMPD_parallel_master_taskloop:
13409     case OMPD_parallel_master_taskloop_simd:
13410       // Do not capture num_threads-clause expressions.
13411       break;
13412     case OMPD_target_data:
13413     case OMPD_target_enter_data:
13414     case OMPD_target_exit_data:
13415     case OMPD_target_update:
13416     case OMPD_target:
13417     case OMPD_target_simd:
13418     case OMPD_target_teams:
13419     case OMPD_target_teams_distribute:
13420     case OMPD_target_teams_distribute_simd:
13421     case OMPD_cancel:
13422     case OMPD_task:
13423     case OMPD_taskloop:
13424     case OMPD_taskloop_simd:
13425     case OMPD_master_taskloop:
13426     case OMPD_master_taskloop_simd:
13427     case OMPD_threadprivate:
13428     case OMPD_allocate:
13429     case OMPD_taskyield:
13430     case OMPD_barrier:
13431     case OMPD_taskwait:
13432     case OMPD_cancellation_point:
13433     case OMPD_flush:
13434     case OMPD_depobj:
13435     case OMPD_scan:
13436     case OMPD_declare_reduction:
13437     case OMPD_declare_mapper:
13438     case OMPD_declare_simd:
13439     case OMPD_declare_variant:
13440     case OMPD_begin_declare_variant:
13441     case OMPD_end_declare_variant:
13442     case OMPD_declare_target:
13443     case OMPD_end_declare_target:
13444     case OMPD_teams:
13445     case OMPD_simd:
13446     case OMPD_tile:
13447     case OMPD_unroll:
13448     case OMPD_for:
13449     case OMPD_for_simd:
13450     case OMPD_sections:
13451     case OMPD_section:
13452     case OMPD_single:
13453     case OMPD_master:
13454     case OMPD_masked:
13455     case OMPD_critical:
13456     case OMPD_taskgroup:
13457     case OMPD_distribute:
13458     case OMPD_ordered:
13459     case OMPD_atomic:
13460     case OMPD_distribute_simd:
13461     case OMPD_teams_distribute:
13462     case OMPD_teams_distribute_simd:
13463     case OMPD_requires:
13464       llvm_unreachable("Unexpected OpenMP directive with num_threads-clause");
13465     case OMPD_unknown:
13466     default:
13467       llvm_unreachable("Unknown OpenMP directive");
13468     }
13469     break;
13470   case OMPC_num_teams:
13471     switch (DKind) {
13472     case OMPD_target_teams:
13473     case OMPD_target_teams_distribute:
13474     case OMPD_target_teams_distribute_simd:
13475     case OMPD_target_teams_distribute_parallel_for:
13476     case OMPD_target_teams_distribute_parallel_for_simd:
13477       CaptureRegion = OMPD_target;
13478       break;
13479     case OMPD_teams_distribute_parallel_for:
13480     case OMPD_teams_distribute_parallel_for_simd:
13481     case OMPD_teams:
13482     case OMPD_teams_distribute:
13483     case OMPD_teams_distribute_simd:
13484       // Do not capture num_teams-clause expressions.
13485       break;
13486     case OMPD_distribute_parallel_for:
13487     case OMPD_distribute_parallel_for_simd:
13488     case OMPD_task:
13489     case OMPD_taskloop:
13490     case OMPD_taskloop_simd:
13491     case OMPD_master_taskloop:
13492     case OMPD_master_taskloop_simd:
13493     case OMPD_parallel_master_taskloop:
13494     case OMPD_parallel_master_taskloop_simd:
13495     case OMPD_target_data:
13496     case OMPD_target_enter_data:
13497     case OMPD_target_exit_data:
13498     case OMPD_target_update:
13499     case OMPD_cancel:
13500     case OMPD_parallel:
13501     case OMPD_parallel_master:
13502     case OMPD_parallel_sections:
13503     case OMPD_parallel_for:
13504     case OMPD_parallel_for_simd:
13505     case OMPD_target:
13506     case OMPD_target_simd:
13507     case OMPD_target_parallel:
13508     case OMPD_target_parallel_for:
13509     case OMPD_target_parallel_for_simd:
13510     case OMPD_threadprivate:
13511     case OMPD_allocate:
13512     case OMPD_taskyield:
13513     case OMPD_barrier:
13514     case OMPD_taskwait:
13515     case OMPD_cancellation_point:
13516     case OMPD_flush:
13517     case OMPD_depobj:
13518     case OMPD_scan:
13519     case OMPD_declare_reduction:
13520     case OMPD_declare_mapper:
13521     case OMPD_declare_simd:
13522     case OMPD_declare_variant:
13523     case OMPD_begin_declare_variant:
13524     case OMPD_end_declare_variant:
13525     case OMPD_declare_target:
13526     case OMPD_end_declare_target:
13527     case OMPD_simd:
13528     case OMPD_tile:
13529     case OMPD_unroll:
13530     case OMPD_for:
13531     case OMPD_for_simd:
13532     case OMPD_sections:
13533     case OMPD_section:
13534     case OMPD_single:
13535     case OMPD_master:
13536     case OMPD_masked:
13537     case OMPD_critical:
13538     case OMPD_taskgroup:
13539     case OMPD_distribute:
13540     case OMPD_ordered:
13541     case OMPD_atomic:
13542     case OMPD_distribute_simd:
13543     case OMPD_requires:
13544       llvm_unreachable("Unexpected OpenMP directive with num_teams-clause");
13545     case OMPD_unknown:
13546     default:
13547       llvm_unreachable("Unknown OpenMP directive");
13548     }
13549     break;
13550   case OMPC_thread_limit:
13551     switch (DKind) {
13552     case OMPD_target_teams:
13553     case OMPD_target_teams_distribute:
13554     case OMPD_target_teams_distribute_simd:
13555     case OMPD_target_teams_distribute_parallel_for:
13556     case OMPD_target_teams_distribute_parallel_for_simd:
13557       CaptureRegion = OMPD_target;
13558       break;
13559     case OMPD_teams_distribute_parallel_for:
13560     case OMPD_teams_distribute_parallel_for_simd:
13561     case OMPD_teams:
13562     case OMPD_teams_distribute:
13563     case OMPD_teams_distribute_simd:
13564       // Do not capture thread_limit-clause expressions.
13565       break;
13566     case OMPD_distribute_parallel_for:
13567     case OMPD_distribute_parallel_for_simd:
13568     case OMPD_task:
13569     case OMPD_taskloop:
13570     case OMPD_taskloop_simd:
13571     case OMPD_master_taskloop:
13572     case OMPD_master_taskloop_simd:
13573     case OMPD_parallel_master_taskloop:
13574     case OMPD_parallel_master_taskloop_simd:
13575     case OMPD_target_data:
13576     case OMPD_target_enter_data:
13577     case OMPD_target_exit_data:
13578     case OMPD_target_update:
13579     case OMPD_cancel:
13580     case OMPD_parallel:
13581     case OMPD_parallel_master:
13582     case OMPD_parallel_sections:
13583     case OMPD_parallel_for:
13584     case OMPD_parallel_for_simd:
13585     case OMPD_target:
13586     case OMPD_target_simd:
13587     case OMPD_target_parallel:
13588     case OMPD_target_parallel_for:
13589     case OMPD_target_parallel_for_simd:
13590     case OMPD_threadprivate:
13591     case OMPD_allocate:
13592     case OMPD_taskyield:
13593     case OMPD_barrier:
13594     case OMPD_taskwait:
13595     case OMPD_cancellation_point:
13596     case OMPD_flush:
13597     case OMPD_depobj:
13598     case OMPD_scan:
13599     case OMPD_declare_reduction:
13600     case OMPD_declare_mapper:
13601     case OMPD_declare_simd:
13602     case OMPD_declare_variant:
13603     case OMPD_begin_declare_variant:
13604     case OMPD_end_declare_variant:
13605     case OMPD_declare_target:
13606     case OMPD_end_declare_target:
13607     case OMPD_simd:
13608     case OMPD_tile:
13609     case OMPD_unroll:
13610     case OMPD_for:
13611     case OMPD_for_simd:
13612     case OMPD_sections:
13613     case OMPD_section:
13614     case OMPD_single:
13615     case OMPD_master:
13616     case OMPD_masked:
13617     case OMPD_critical:
13618     case OMPD_taskgroup:
13619     case OMPD_distribute:
13620     case OMPD_ordered:
13621     case OMPD_atomic:
13622     case OMPD_distribute_simd:
13623     case OMPD_requires:
13624       llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause");
13625     case OMPD_unknown:
13626     default:
13627       llvm_unreachable("Unknown OpenMP directive");
13628     }
13629     break;
13630   case OMPC_schedule:
13631     switch (DKind) {
13632     case OMPD_parallel_for:
13633     case OMPD_parallel_for_simd:
13634     case OMPD_distribute_parallel_for:
13635     case OMPD_distribute_parallel_for_simd:
13636     case OMPD_teams_distribute_parallel_for:
13637     case OMPD_teams_distribute_parallel_for_simd:
13638     case OMPD_target_parallel_for:
13639     case OMPD_target_parallel_for_simd:
13640     case OMPD_target_teams_distribute_parallel_for:
13641     case OMPD_target_teams_distribute_parallel_for_simd:
13642       CaptureRegion = OMPD_parallel;
13643       break;
13644     case OMPD_for:
13645     case OMPD_for_simd:
13646       // Do not capture schedule-clause expressions.
13647       break;
13648     case OMPD_task:
13649     case OMPD_taskloop:
13650     case OMPD_taskloop_simd:
13651     case OMPD_master_taskloop:
13652     case OMPD_master_taskloop_simd:
13653     case OMPD_parallel_master_taskloop:
13654     case OMPD_parallel_master_taskloop_simd:
13655     case OMPD_target_data:
13656     case OMPD_target_enter_data:
13657     case OMPD_target_exit_data:
13658     case OMPD_target_update:
13659     case OMPD_teams:
13660     case OMPD_teams_distribute:
13661     case OMPD_teams_distribute_simd:
13662     case OMPD_target_teams_distribute:
13663     case OMPD_target_teams_distribute_simd:
13664     case OMPD_target:
13665     case OMPD_target_simd:
13666     case OMPD_target_parallel:
13667     case OMPD_cancel:
13668     case OMPD_parallel:
13669     case OMPD_parallel_master:
13670     case OMPD_parallel_sections:
13671     case OMPD_threadprivate:
13672     case OMPD_allocate:
13673     case OMPD_taskyield:
13674     case OMPD_barrier:
13675     case OMPD_taskwait:
13676     case OMPD_cancellation_point:
13677     case OMPD_flush:
13678     case OMPD_depobj:
13679     case OMPD_scan:
13680     case OMPD_declare_reduction:
13681     case OMPD_declare_mapper:
13682     case OMPD_declare_simd:
13683     case OMPD_declare_variant:
13684     case OMPD_begin_declare_variant:
13685     case OMPD_end_declare_variant:
13686     case OMPD_declare_target:
13687     case OMPD_end_declare_target:
13688     case OMPD_simd:
13689     case OMPD_tile:
13690     case OMPD_unroll:
13691     case OMPD_sections:
13692     case OMPD_section:
13693     case OMPD_single:
13694     case OMPD_master:
13695     case OMPD_masked:
13696     case OMPD_critical:
13697     case OMPD_taskgroup:
13698     case OMPD_distribute:
13699     case OMPD_ordered:
13700     case OMPD_atomic:
13701     case OMPD_distribute_simd:
13702     case OMPD_target_teams:
13703     case OMPD_requires:
13704       llvm_unreachable("Unexpected OpenMP directive with schedule clause");
13705     case OMPD_unknown:
13706     default:
13707       llvm_unreachable("Unknown OpenMP directive");
13708     }
13709     break;
13710   case OMPC_dist_schedule:
13711     switch (DKind) {
13712     case OMPD_teams_distribute_parallel_for:
13713     case OMPD_teams_distribute_parallel_for_simd:
13714     case OMPD_teams_distribute:
13715     case OMPD_teams_distribute_simd:
13716     case OMPD_target_teams_distribute_parallel_for:
13717     case OMPD_target_teams_distribute_parallel_for_simd:
13718     case OMPD_target_teams_distribute:
13719     case OMPD_target_teams_distribute_simd:
13720       CaptureRegion = OMPD_teams;
13721       break;
13722     case OMPD_distribute_parallel_for:
13723     case OMPD_distribute_parallel_for_simd:
13724     case OMPD_distribute:
13725     case OMPD_distribute_simd:
13726       // Do not capture dist_schedule-clause expressions.
13727       break;
13728     case OMPD_parallel_for:
13729     case OMPD_parallel_for_simd:
13730     case OMPD_target_parallel_for_simd:
13731     case OMPD_target_parallel_for:
13732     case OMPD_task:
13733     case OMPD_taskloop:
13734     case OMPD_taskloop_simd:
13735     case OMPD_master_taskloop:
13736     case OMPD_master_taskloop_simd:
13737     case OMPD_parallel_master_taskloop:
13738     case OMPD_parallel_master_taskloop_simd:
13739     case OMPD_target_data:
13740     case OMPD_target_enter_data:
13741     case OMPD_target_exit_data:
13742     case OMPD_target_update:
13743     case OMPD_teams:
13744     case OMPD_target:
13745     case OMPD_target_simd:
13746     case OMPD_target_parallel:
13747     case OMPD_cancel:
13748     case OMPD_parallel:
13749     case OMPD_parallel_master:
13750     case OMPD_parallel_sections:
13751     case OMPD_threadprivate:
13752     case OMPD_allocate:
13753     case OMPD_taskyield:
13754     case OMPD_barrier:
13755     case OMPD_taskwait:
13756     case OMPD_cancellation_point:
13757     case OMPD_flush:
13758     case OMPD_depobj:
13759     case OMPD_scan:
13760     case OMPD_declare_reduction:
13761     case OMPD_declare_mapper:
13762     case OMPD_declare_simd:
13763     case OMPD_declare_variant:
13764     case OMPD_begin_declare_variant:
13765     case OMPD_end_declare_variant:
13766     case OMPD_declare_target:
13767     case OMPD_end_declare_target:
13768     case OMPD_simd:
13769     case OMPD_tile:
13770     case OMPD_unroll:
13771     case OMPD_for:
13772     case OMPD_for_simd:
13773     case OMPD_sections:
13774     case OMPD_section:
13775     case OMPD_single:
13776     case OMPD_master:
13777     case OMPD_masked:
13778     case OMPD_critical:
13779     case OMPD_taskgroup:
13780     case OMPD_ordered:
13781     case OMPD_atomic:
13782     case OMPD_target_teams:
13783     case OMPD_requires:
13784       llvm_unreachable("Unexpected OpenMP directive with dist_schedule clause");
13785     case OMPD_unknown:
13786     default:
13787       llvm_unreachable("Unknown OpenMP directive");
13788     }
13789     break;
13790   case OMPC_device:
13791     switch (DKind) {
13792     case OMPD_target_update:
13793     case OMPD_target_enter_data:
13794     case OMPD_target_exit_data:
13795     case OMPD_target:
13796     case OMPD_target_simd:
13797     case OMPD_target_teams:
13798     case OMPD_target_parallel:
13799     case OMPD_target_teams_distribute:
13800     case OMPD_target_teams_distribute_simd:
13801     case OMPD_target_parallel_for:
13802     case OMPD_target_parallel_for_simd:
13803     case OMPD_target_teams_distribute_parallel_for:
13804     case OMPD_target_teams_distribute_parallel_for_simd:
13805     case OMPD_dispatch:
13806       CaptureRegion = OMPD_task;
13807       break;
13808     case OMPD_target_data:
13809     case OMPD_interop:
13810       // Do not capture device-clause expressions.
13811       break;
13812     case OMPD_teams_distribute_parallel_for:
13813     case OMPD_teams_distribute_parallel_for_simd:
13814     case OMPD_teams:
13815     case OMPD_teams_distribute:
13816     case OMPD_teams_distribute_simd:
13817     case OMPD_distribute_parallel_for:
13818     case OMPD_distribute_parallel_for_simd:
13819     case OMPD_task:
13820     case OMPD_taskloop:
13821     case OMPD_taskloop_simd:
13822     case OMPD_master_taskloop:
13823     case OMPD_master_taskloop_simd:
13824     case OMPD_parallel_master_taskloop:
13825     case OMPD_parallel_master_taskloop_simd:
13826     case OMPD_cancel:
13827     case OMPD_parallel:
13828     case OMPD_parallel_master:
13829     case OMPD_parallel_sections:
13830     case OMPD_parallel_for:
13831     case OMPD_parallel_for_simd:
13832     case OMPD_threadprivate:
13833     case OMPD_allocate:
13834     case OMPD_taskyield:
13835     case OMPD_barrier:
13836     case OMPD_taskwait:
13837     case OMPD_cancellation_point:
13838     case OMPD_flush:
13839     case OMPD_depobj:
13840     case OMPD_scan:
13841     case OMPD_declare_reduction:
13842     case OMPD_declare_mapper:
13843     case OMPD_declare_simd:
13844     case OMPD_declare_variant:
13845     case OMPD_begin_declare_variant:
13846     case OMPD_end_declare_variant:
13847     case OMPD_declare_target:
13848     case OMPD_end_declare_target:
13849     case OMPD_simd:
13850     case OMPD_tile:
13851     case OMPD_unroll:
13852     case OMPD_for:
13853     case OMPD_for_simd:
13854     case OMPD_sections:
13855     case OMPD_section:
13856     case OMPD_single:
13857     case OMPD_master:
13858     case OMPD_masked:
13859     case OMPD_critical:
13860     case OMPD_taskgroup:
13861     case OMPD_distribute:
13862     case OMPD_ordered:
13863     case OMPD_atomic:
13864     case OMPD_distribute_simd:
13865     case OMPD_requires:
13866       llvm_unreachable("Unexpected OpenMP directive with device-clause");
13867     case OMPD_unknown:
13868     default:
13869       llvm_unreachable("Unknown OpenMP directive");
13870     }
13871     break;
13872   case OMPC_grainsize:
13873   case OMPC_num_tasks:
13874   case OMPC_final:
13875   case OMPC_priority:
13876     switch (DKind) {
13877     case OMPD_task:
13878     case OMPD_taskloop:
13879     case OMPD_taskloop_simd:
13880     case OMPD_master_taskloop:
13881     case OMPD_master_taskloop_simd:
13882       break;
13883     case OMPD_parallel_master_taskloop:
13884     case OMPD_parallel_master_taskloop_simd:
13885       CaptureRegion = OMPD_parallel;
13886       break;
13887     case OMPD_target_update:
13888     case OMPD_target_enter_data:
13889     case OMPD_target_exit_data:
13890     case OMPD_target:
13891     case OMPD_target_simd:
13892     case OMPD_target_teams:
13893     case OMPD_target_parallel:
13894     case OMPD_target_teams_distribute:
13895     case OMPD_target_teams_distribute_simd:
13896     case OMPD_target_parallel_for:
13897     case OMPD_target_parallel_for_simd:
13898     case OMPD_target_teams_distribute_parallel_for:
13899     case OMPD_target_teams_distribute_parallel_for_simd:
13900     case OMPD_target_data:
13901     case OMPD_teams_distribute_parallel_for:
13902     case OMPD_teams_distribute_parallel_for_simd:
13903     case OMPD_teams:
13904     case OMPD_teams_distribute:
13905     case OMPD_teams_distribute_simd:
13906     case OMPD_distribute_parallel_for:
13907     case OMPD_distribute_parallel_for_simd:
13908     case OMPD_cancel:
13909     case OMPD_parallel:
13910     case OMPD_parallel_master:
13911     case OMPD_parallel_sections:
13912     case OMPD_parallel_for:
13913     case OMPD_parallel_for_simd:
13914     case OMPD_threadprivate:
13915     case OMPD_allocate:
13916     case OMPD_taskyield:
13917     case OMPD_barrier:
13918     case OMPD_taskwait:
13919     case OMPD_cancellation_point:
13920     case OMPD_flush:
13921     case OMPD_depobj:
13922     case OMPD_scan:
13923     case OMPD_declare_reduction:
13924     case OMPD_declare_mapper:
13925     case OMPD_declare_simd:
13926     case OMPD_declare_variant:
13927     case OMPD_begin_declare_variant:
13928     case OMPD_end_declare_variant:
13929     case OMPD_declare_target:
13930     case OMPD_end_declare_target:
13931     case OMPD_simd:
13932     case OMPD_tile:
13933     case OMPD_unroll:
13934     case OMPD_for:
13935     case OMPD_for_simd:
13936     case OMPD_sections:
13937     case OMPD_section:
13938     case OMPD_single:
13939     case OMPD_master:
13940     case OMPD_masked:
13941     case OMPD_critical:
13942     case OMPD_taskgroup:
13943     case OMPD_distribute:
13944     case OMPD_ordered:
13945     case OMPD_atomic:
13946     case OMPD_distribute_simd:
13947     case OMPD_requires:
13948       llvm_unreachable("Unexpected OpenMP directive with grainsize-clause");
13949     case OMPD_unknown:
13950     default:
13951       llvm_unreachable("Unknown OpenMP directive");
13952     }
13953     break;
13954   case OMPC_novariants:
13955   case OMPC_nocontext:
13956     switch (DKind) {
13957     case OMPD_dispatch:
13958       CaptureRegion = OMPD_task;
13959       break;
13960     default:
13961       llvm_unreachable("Unexpected OpenMP directive");
13962     }
13963     break;
13964   case OMPC_filter:
13965     // Do not capture filter-clause expressions.
13966     break;
13967   case OMPC_firstprivate:
13968   case OMPC_lastprivate:
13969   case OMPC_reduction:
13970   case OMPC_task_reduction:
13971   case OMPC_in_reduction:
13972   case OMPC_linear:
13973   case OMPC_default:
13974   case OMPC_proc_bind:
13975   case OMPC_safelen:
13976   case OMPC_simdlen:
13977   case OMPC_sizes:
13978   case OMPC_allocator:
13979   case OMPC_collapse:
13980   case OMPC_private:
13981   case OMPC_shared:
13982   case OMPC_aligned:
13983   case OMPC_copyin:
13984   case OMPC_copyprivate:
13985   case OMPC_ordered:
13986   case OMPC_nowait:
13987   case OMPC_untied:
13988   case OMPC_mergeable:
13989   case OMPC_threadprivate:
13990   case OMPC_allocate:
13991   case OMPC_flush:
13992   case OMPC_depobj:
13993   case OMPC_read:
13994   case OMPC_write:
13995   case OMPC_update:
13996   case OMPC_capture:
13997   case OMPC_seq_cst:
13998   case OMPC_acq_rel:
13999   case OMPC_acquire:
14000   case OMPC_release:
14001   case OMPC_relaxed:
14002   case OMPC_depend:
14003   case OMPC_threads:
14004   case OMPC_simd:
14005   case OMPC_map:
14006   case OMPC_nogroup:
14007   case OMPC_hint:
14008   case OMPC_defaultmap:
14009   case OMPC_unknown:
14010   case OMPC_uniform:
14011   case OMPC_to:
14012   case OMPC_from:
14013   case OMPC_use_device_ptr:
14014   case OMPC_use_device_addr:
14015   case OMPC_is_device_ptr:
14016   case OMPC_unified_address:
14017   case OMPC_unified_shared_memory:
14018   case OMPC_reverse_offload:
14019   case OMPC_dynamic_allocators:
14020   case OMPC_atomic_default_mem_order:
14021   case OMPC_device_type:
14022   case OMPC_match:
14023   case OMPC_nontemporal:
14024   case OMPC_order:
14025   case OMPC_destroy:
14026   case OMPC_detach:
14027   case OMPC_inclusive:
14028   case OMPC_exclusive:
14029   case OMPC_uses_allocators:
14030   case OMPC_affinity:
14031   default:
14032     llvm_unreachable("Unexpected OpenMP clause.");
14033   }
14034   return CaptureRegion;
14035 }
14036 
ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation NameModifierLoc,SourceLocation ColonLoc,SourceLocation EndLoc)14037 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier,
14038                                      Expr *Condition, SourceLocation StartLoc,
14039                                      SourceLocation LParenLoc,
14040                                      SourceLocation NameModifierLoc,
14041                                      SourceLocation ColonLoc,
14042                                      SourceLocation EndLoc) {
14043   Expr *ValExpr = Condition;
14044   Stmt *HelperValStmt = nullptr;
14045   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
14046   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
14047       !Condition->isInstantiationDependent() &&
14048       !Condition->containsUnexpandedParameterPack()) {
14049     ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
14050     if (Val.isInvalid())
14051       return nullptr;
14052 
14053     ValExpr = Val.get();
14054 
14055     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
14056     CaptureRegion = getOpenMPCaptureRegionForClause(
14057         DKind, OMPC_if, LangOpts.OpenMP, NameModifier);
14058     if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
14059       ValExpr = MakeFullExpr(ValExpr).get();
14060       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14061       ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
14062       HelperValStmt = buildPreInits(Context, Captures);
14063     }
14064   }
14065 
14066   return new (Context)
14067       OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
14068                   LParenLoc, NameModifierLoc, ColonLoc, EndLoc);
14069 }
14070 
ActOnOpenMPFinalClause(Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14071 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition,
14072                                         SourceLocation StartLoc,
14073                                         SourceLocation LParenLoc,
14074                                         SourceLocation EndLoc) {
14075   Expr *ValExpr = Condition;
14076   Stmt *HelperValStmt = nullptr;
14077   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
14078   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
14079       !Condition->isInstantiationDependent() &&
14080       !Condition->containsUnexpandedParameterPack()) {
14081     ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
14082     if (Val.isInvalid())
14083       return nullptr;
14084 
14085     ValExpr = MakeFullExpr(Val.get()).get();
14086 
14087     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
14088     CaptureRegion =
14089         getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP);
14090     if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
14091       ValExpr = MakeFullExpr(ValExpr).get();
14092       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14093       ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
14094       HelperValStmt = buildPreInits(Context, Captures);
14095     }
14096   }
14097 
14098   return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion,
14099                                       StartLoc, LParenLoc, EndLoc);
14100 }
14101 
PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,Expr * Op)14102 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc,
14103                                                         Expr *Op) {
14104   if (!Op)
14105     return ExprError();
14106 
14107   class IntConvertDiagnoser : public ICEConvertDiagnoser {
14108   public:
14109     IntConvertDiagnoser()
14110         : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {}
14111     SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc,
14112                                          QualType T) override {
14113       return S.Diag(Loc, diag::err_omp_not_integral) << T;
14114     }
14115     SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc,
14116                                              QualType T) override {
14117       return S.Diag(Loc, diag::err_omp_incomplete_type) << T;
14118     }
14119     SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc,
14120                                                QualType T,
14121                                                QualType ConvTy) override {
14122       return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy;
14123     }
14124     SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv,
14125                                            QualType ConvTy) override {
14126       return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
14127              << ConvTy->isEnumeralType() << ConvTy;
14128     }
14129     SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc,
14130                                             QualType T) override {
14131       return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T;
14132     }
14133     SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv,
14134                                         QualType ConvTy) override {
14135       return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here)
14136              << ConvTy->isEnumeralType() << ConvTy;
14137     }
14138     SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType,
14139                                              QualType) override {
14140       llvm_unreachable("conversion functions are permitted");
14141     }
14142   } ConvertDiagnoser;
14143   return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser);
14144 }
14145 
14146 static bool
isNonNegativeIntegerValue(Expr * & ValExpr,Sema & SemaRef,OpenMPClauseKind CKind,bool StrictlyPositive,bool BuildCapture=false,OpenMPDirectiveKind DKind=OMPD_unknown,OpenMPDirectiveKind * CaptureRegion=nullptr,Stmt ** HelperValStmt=nullptr)14147 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind,
14148                           bool StrictlyPositive, bool BuildCapture = false,
14149                           OpenMPDirectiveKind DKind = OMPD_unknown,
14150                           OpenMPDirectiveKind *CaptureRegion = nullptr,
14151                           Stmt **HelperValStmt = nullptr) {
14152   if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() &&
14153       !ValExpr->isInstantiationDependent()) {
14154     SourceLocation Loc = ValExpr->getExprLoc();
14155     ExprResult Value =
14156         SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr);
14157     if (Value.isInvalid())
14158       return false;
14159 
14160     ValExpr = Value.get();
14161     // The expression must evaluate to a non-negative integer value.
14162     if (Optional<llvm::APSInt> Result =
14163             ValExpr->getIntegerConstantExpr(SemaRef.Context)) {
14164       if (Result->isSigned() &&
14165           !((!StrictlyPositive && Result->isNonNegative()) ||
14166             (StrictlyPositive && Result->isStrictlyPositive()))) {
14167         SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause)
14168             << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
14169             << ValExpr->getSourceRange();
14170         return false;
14171       }
14172     }
14173     if (!BuildCapture)
14174       return true;
14175     *CaptureRegion =
14176         getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP);
14177     if (*CaptureRegion != OMPD_unknown &&
14178         !SemaRef.CurContext->isDependentContext()) {
14179       ValExpr = SemaRef.MakeFullExpr(ValExpr).get();
14180       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14181       ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get();
14182       *HelperValStmt = buildPreInits(SemaRef.Context, Captures);
14183     }
14184   }
14185   return true;
14186 }
14187 
ActOnOpenMPNumThreadsClause(Expr * NumThreads,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14188 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads,
14189                                              SourceLocation StartLoc,
14190                                              SourceLocation LParenLoc,
14191                                              SourceLocation EndLoc) {
14192   Expr *ValExpr = NumThreads;
14193   Stmt *HelperValStmt = nullptr;
14194 
14195   // OpenMP [2.5, Restrictions]
14196   //  The num_threads expression must evaluate to a positive integer value.
14197   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads,
14198                                  /*StrictlyPositive=*/true))
14199     return nullptr;
14200 
14201   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
14202   OpenMPDirectiveKind CaptureRegion =
14203       getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP);
14204   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
14205     ValExpr = MakeFullExpr(ValExpr).get();
14206     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14207     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
14208     HelperValStmt = buildPreInits(Context, Captures);
14209   }
14210 
14211   return new (Context) OMPNumThreadsClause(
14212       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
14213 }
14214 
VerifyPositiveIntegerConstantInClause(Expr * E,OpenMPClauseKind CKind,bool StrictlyPositive,bool SuppressExprDiags)14215 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E,
14216                                                        OpenMPClauseKind CKind,
14217                                                        bool StrictlyPositive,
14218                                                        bool SuppressExprDiags) {
14219   if (!E)
14220     return ExprError();
14221   if (E->isValueDependent() || E->isTypeDependent() ||
14222       E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
14223     return E;
14224 
14225   llvm::APSInt Result;
14226   ExprResult ICE;
14227   if (SuppressExprDiags) {
14228     // Use a custom diagnoser that suppresses 'note' diagnostics about the
14229     // expression.
14230     struct SuppressedDiagnoser : public Sema::VerifyICEDiagnoser {
14231       SuppressedDiagnoser() : VerifyICEDiagnoser(/*Suppress=*/true) {}
14232       Sema::SemaDiagnosticBuilder diagnoseNotICE(Sema &S,
14233                                                  SourceLocation Loc) override {
14234         llvm_unreachable("Diagnostic suppressed");
14235       }
14236     } Diagnoser;
14237     ICE = VerifyIntegerConstantExpression(E, &Result, Diagnoser, AllowFold);
14238   } else {
14239     ICE = VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold);
14240   }
14241   if (ICE.isInvalid())
14242     return ExprError();
14243 
14244   if ((StrictlyPositive && !Result.isStrictlyPositive()) ||
14245       (!StrictlyPositive && !Result.isNonNegative())) {
14246     Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause)
14247         << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0)
14248         << E->getSourceRange();
14249     return ExprError();
14250   }
14251   if (CKind == OMPC_aligned && !Result.isPowerOf2()) {
14252     Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two)
14253         << E->getSourceRange();
14254     return ExprError();
14255   }
14256   if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1)
14257     DSAStack->setAssociatedLoops(Result.getExtValue());
14258   else if (CKind == OMPC_ordered)
14259     DSAStack->setAssociatedLoops(Result.getExtValue());
14260   return ICE;
14261 }
14262 
ActOnOpenMPSafelenClause(Expr * Len,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14263 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc,
14264                                           SourceLocation LParenLoc,
14265                                           SourceLocation EndLoc) {
14266   // OpenMP [2.8.1, simd construct, Description]
14267   // The parameter of the safelen clause must be a constant
14268   // positive integer expression.
14269   ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen);
14270   if (Safelen.isInvalid())
14271     return nullptr;
14272   return new (Context)
14273       OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc);
14274 }
14275 
ActOnOpenMPSimdlenClause(Expr * Len,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14276 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc,
14277                                           SourceLocation LParenLoc,
14278                                           SourceLocation EndLoc) {
14279   // OpenMP [2.8.1, simd construct, Description]
14280   // The parameter of the simdlen clause must be a constant
14281   // positive integer expression.
14282   ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen);
14283   if (Simdlen.isInvalid())
14284     return nullptr;
14285   return new (Context)
14286       OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc);
14287 }
14288 
14289 /// Tries to find omp_allocator_handle_t type.
findOMPAllocatorHandleT(Sema & S,SourceLocation Loc,DSAStackTy * Stack)14290 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc,
14291                                     DSAStackTy *Stack) {
14292   QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT();
14293   if (!OMPAllocatorHandleT.isNull())
14294     return true;
14295   // Build the predefined allocator expressions.
14296   bool ErrorFound = false;
14297   for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
14298     auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
14299     StringRef Allocator =
14300         OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
14301     DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator);
14302     auto *VD = dyn_cast_or_null<ValueDecl>(
14303         S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName));
14304     if (!VD) {
14305       ErrorFound = true;
14306       break;
14307     }
14308     QualType AllocatorType =
14309         VD->getType().getNonLValueExprType(S.getASTContext());
14310     ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc);
14311     if (!Res.isUsable()) {
14312       ErrorFound = true;
14313       break;
14314     }
14315     if (OMPAllocatorHandleT.isNull())
14316       OMPAllocatorHandleT = AllocatorType;
14317     if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) {
14318       ErrorFound = true;
14319       break;
14320     }
14321     Stack->setAllocator(AllocatorKind, Res.get());
14322   }
14323   if (ErrorFound) {
14324     S.Diag(Loc, diag::err_omp_implied_type_not_found)
14325         << "omp_allocator_handle_t";
14326     return false;
14327   }
14328   OMPAllocatorHandleT.addConst();
14329   Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT);
14330   return true;
14331 }
14332 
ActOnOpenMPAllocatorClause(Expr * A,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14333 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc,
14334                                             SourceLocation LParenLoc,
14335                                             SourceLocation EndLoc) {
14336   // OpenMP [2.11.3, allocate Directive, Description]
14337   // allocator is an expression of omp_allocator_handle_t type.
14338   if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack))
14339     return nullptr;
14340 
14341   ExprResult Allocator = DefaultLvalueConversion(A);
14342   if (Allocator.isInvalid())
14343     return nullptr;
14344   Allocator = PerformImplicitConversion(Allocator.get(),
14345                                         DSAStack->getOMPAllocatorHandleT(),
14346                                         Sema::AA_Initializing,
14347                                         /*AllowExplicit=*/true);
14348   if (Allocator.isInvalid())
14349     return nullptr;
14350   return new (Context)
14351       OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc);
14352 }
14353 
ActOnOpenMPCollapseClause(Expr * NumForLoops,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14354 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops,
14355                                            SourceLocation StartLoc,
14356                                            SourceLocation LParenLoc,
14357                                            SourceLocation EndLoc) {
14358   // OpenMP [2.7.1, loop construct, Description]
14359   // OpenMP [2.8.1, simd construct, Description]
14360   // OpenMP [2.9.6, distribute construct, Description]
14361   // The parameter of the collapse clause must be a constant
14362   // positive integer expression.
14363   ExprResult NumForLoopsResult =
14364       VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse);
14365   if (NumForLoopsResult.isInvalid())
14366     return nullptr;
14367   return new (Context)
14368       OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc);
14369 }
14370 
ActOnOpenMPOrderedClause(SourceLocation StartLoc,SourceLocation EndLoc,SourceLocation LParenLoc,Expr * NumForLoops)14371 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc,
14372                                           SourceLocation EndLoc,
14373                                           SourceLocation LParenLoc,
14374                                           Expr *NumForLoops) {
14375   // OpenMP [2.7.1, loop construct, Description]
14376   // OpenMP [2.8.1, simd construct, Description]
14377   // OpenMP [2.9.6, distribute construct, Description]
14378   // The parameter of the ordered clause must be a constant
14379   // positive integer expression if any.
14380   if (NumForLoops && LParenLoc.isValid()) {
14381     ExprResult NumForLoopsResult =
14382         VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered);
14383     if (NumForLoopsResult.isInvalid())
14384       return nullptr;
14385     NumForLoops = NumForLoopsResult.get();
14386   } else {
14387     NumForLoops = nullptr;
14388   }
14389   auto *Clause = OMPOrderedClause::Create(
14390       Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0,
14391       StartLoc, LParenLoc, EndLoc);
14392   DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause);
14393   return Clause;
14394 }
14395 
ActOnOpenMPSimpleClause(OpenMPClauseKind Kind,unsigned Argument,SourceLocation ArgumentLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14396 OMPClause *Sema::ActOnOpenMPSimpleClause(
14397     OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc,
14398     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
14399   OMPClause *Res = nullptr;
14400   switch (Kind) {
14401   case OMPC_default:
14402     Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument),
14403                                    ArgumentLoc, StartLoc, LParenLoc, EndLoc);
14404     break;
14405   case OMPC_proc_bind:
14406     Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument),
14407                                     ArgumentLoc, StartLoc, LParenLoc, EndLoc);
14408     break;
14409   case OMPC_atomic_default_mem_order:
14410     Res = ActOnOpenMPAtomicDefaultMemOrderClause(
14411         static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument),
14412         ArgumentLoc, StartLoc, LParenLoc, EndLoc);
14413     break;
14414   case OMPC_order:
14415     Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument),
14416                                  ArgumentLoc, StartLoc, LParenLoc, EndLoc);
14417     break;
14418   case OMPC_update:
14419     Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument),
14420                                   ArgumentLoc, StartLoc, LParenLoc, EndLoc);
14421     break;
14422   case OMPC_if:
14423   case OMPC_final:
14424   case OMPC_num_threads:
14425   case OMPC_safelen:
14426   case OMPC_simdlen:
14427   case OMPC_sizes:
14428   case OMPC_allocator:
14429   case OMPC_collapse:
14430   case OMPC_schedule:
14431   case OMPC_private:
14432   case OMPC_firstprivate:
14433   case OMPC_lastprivate:
14434   case OMPC_shared:
14435   case OMPC_reduction:
14436   case OMPC_task_reduction:
14437   case OMPC_in_reduction:
14438   case OMPC_linear:
14439   case OMPC_aligned:
14440   case OMPC_copyin:
14441   case OMPC_copyprivate:
14442   case OMPC_ordered:
14443   case OMPC_nowait:
14444   case OMPC_untied:
14445   case OMPC_mergeable:
14446   case OMPC_threadprivate:
14447   case OMPC_allocate:
14448   case OMPC_flush:
14449   case OMPC_depobj:
14450   case OMPC_read:
14451   case OMPC_write:
14452   case OMPC_capture:
14453   case OMPC_seq_cst:
14454   case OMPC_acq_rel:
14455   case OMPC_acquire:
14456   case OMPC_release:
14457   case OMPC_relaxed:
14458   case OMPC_depend:
14459   case OMPC_device:
14460   case OMPC_threads:
14461   case OMPC_simd:
14462   case OMPC_map:
14463   case OMPC_num_teams:
14464   case OMPC_thread_limit:
14465   case OMPC_priority:
14466   case OMPC_grainsize:
14467   case OMPC_nogroup:
14468   case OMPC_num_tasks:
14469   case OMPC_hint:
14470   case OMPC_dist_schedule:
14471   case OMPC_defaultmap:
14472   case OMPC_unknown:
14473   case OMPC_uniform:
14474   case OMPC_to:
14475   case OMPC_from:
14476   case OMPC_use_device_ptr:
14477   case OMPC_use_device_addr:
14478   case OMPC_is_device_ptr:
14479   case OMPC_unified_address:
14480   case OMPC_unified_shared_memory:
14481   case OMPC_reverse_offload:
14482   case OMPC_dynamic_allocators:
14483   case OMPC_device_type:
14484   case OMPC_match:
14485   case OMPC_nontemporal:
14486   case OMPC_destroy:
14487   case OMPC_novariants:
14488   case OMPC_nocontext:
14489   case OMPC_detach:
14490   case OMPC_inclusive:
14491   case OMPC_exclusive:
14492   case OMPC_uses_allocators:
14493   case OMPC_affinity:
14494   default:
14495     llvm_unreachable("Clause is not allowed.");
14496   }
14497   return Res;
14498 }
14499 
14500 static std::string
getListOfPossibleValues(OpenMPClauseKind K,unsigned First,unsigned Last,ArrayRef<unsigned> Exclude=llvm::None)14501 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last,
14502                         ArrayRef<unsigned> Exclude = llvm::None) {
14503   SmallString<256> Buffer;
14504   llvm::raw_svector_ostream Out(Buffer);
14505   unsigned Skipped = Exclude.size();
14506   auto S = Exclude.begin(), E = Exclude.end();
14507   for (unsigned I = First; I < Last; ++I) {
14508     if (std::find(S, E, I) != E) {
14509       --Skipped;
14510       continue;
14511     }
14512     Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'";
14513     if (I + Skipped + 2 == Last)
14514       Out << " or ";
14515     else if (I + Skipped + 1 != Last)
14516       Out << ", ";
14517   }
14518   return std::string(Out.str());
14519 }
14520 
ActOnOpenMPDefaultClause(DefaultKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14521 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind,
14522                                           SourceLocation KindKwLoc,
14523                                           SourceLocation StartLoc,
14524                                           SourceLocation LParenLoc,
14525                                           SourceLocation EndLoc) {
14526   if (Kind == OMP_DEFAULT_unknown) {
14527     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14528         << getListOfPossibleValues(OMPC_default, /*First=*/0,
14529                                    /*Last=*/unsigned(OMP_DEFAULT_unknown))
14530         << getOpenMPClauseName(OMPC_default);
14531     return nullptr;
14532   }
14533 
14534   switch (Kind) {
14535   case OMP_DEFAULT_none:
14536     DSAStack->setDefaultDSANone(KindKwLoc);
14537     break;
14538   case OMP_DEFAULT_shared:
14539     DSAStack->setDefaultDSAShared(KindKwLoc);
14540     break;
14541   case OMP_DEFAULT_firstprivate:
14542     DSAStack->setDefaultDSAFirstPrivate(KindKwLoc);
14543     break;
14544   default:
14545     llvm_unreachable("DSA unexpected in OpenMP default clause");
14546   }
14547 
14548   return new (Context)
14549       OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
14550 }
14551 
ActOnOpenMPProcBindClause(ProcBindKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14552 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind,
14553                                            SourceLocation KindKwLoc,
14554                                            SourceLocation StartLoc,
14555                                            SourceLocation LParenLoc,
14556                                            SourceLocation EndLoc) {
14557   if (Kind == OMP_PROC_BIND_unknown) {
14558     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14559         << getListOfPossibleValues(OMPC_proc_bind,
14560                                    /*First=*/unsigned(OMP_PROC_BIND_master),
14561                                    /*Last=*/
14562                                    unsigned(LangOpts.OpenMP > 50
14563                                                 ? OMP_PROC_BIND_primary
14564                                                 : OMP_PROC_BIND_spread) +
14565                                        1)
14566         << getOpenMPClauseName(OMPC_proc_bind);
14567     return nullptr;
14568   }
14569   if (Kind == OMP_PROC_BIND_primary && LangOpts.OpenMP < 51)
14570     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14571         << getListOfPossibleValues(OMPC_proc_bind,
14572                                    /*First=*/unsigned(OMP_PROC_BIND_master),
14573                                    /*Last=*/
14574                                    unsigned(OMP_PROC_BIND_spread) + 1)
14575         << getOpenMPClauseName(OMPC_proc_bind);
14576   return new (Context)
14577       OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
14578 }
14579 
ActOnOpenMPAtomicDefaultMemOrderClause(OpenMPAtomicDefaultMemOrderClauseKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14580 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause(
14581     OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc,
14582     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
14583   if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) {
14584     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14585         << getListOfPossibleValues(
14586                OMPC_atomic_default_mem_order, /*First=*/0,
14587                /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown)
14588         << getOpenMPClauseName(OMPC_atomic_default_mem_order);
14589     return nullptr;
14590   }
14591   return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc,
14592                                                       LParenLoc, EndLoc);
14593 }
14594 
ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14595 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind,
14596                                         SourceLocation KindKwLoc,
14597                                         SourceLocation StartLoc,
14598                                         SourceLocation LParenLoc,
14599                                         SourceLocation EndLoc) {
14600   if (Kind == OMPC_ORDER_unknown) {
14601     static_assert(OMPC_ORDER_unknown > 0,
14602                   "OMPC_ORDER_unknown not greater than 0");
14603     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14604         << getListOfPossibleValues(OMPC_order, /*First=*/0,
14605                                    /*Last=*/OMPC_ORDER_unknown)
14606         << getOpenMPClauseName(OMPC_order);
14607     return nullptr;
14608   }
14609   return new (Context)
14610       OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc);
14611 }
14612 
ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,SourceLocation KindKwLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14613 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind,
14614                                          SourceLocation KindKwLoc,
14615                                          SourceLocation StartLoc,
14616                                          SourceLocation LParenLoc,
14617                                          SourceLocation EndLoc) {
14618   if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source ||
14619       Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) {
14620     unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink,
14621                          OMPC_DEPEND_depobj};
14622     Diag(KindKwLoc, diag::err_omp_unexpected_clause_value)
14623         << getListOfPossibleValues(OMPC_depend, /*First=*/0,
14624                                    /*Last=*/OMPC_DEPEND_unknown, Except)
14625         << getOpenMPClauseName(OMPC_update);
14626     return nullptr;
14627   }
14628   return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind,
14629                                  EndLoc);
14630 }
14631 
ActOnOpenMPSizesClause(ArrayRef<Expr * > SizeExprs,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14632 OMPClause *Sema::ActOnOpenMPSizesClause(ArrayRef<Expr *> SizeExprs,
14633                                         SourceLocation StartLoc,
14634                                         SourceLocation LParenLoc,
14635                                         SourceLocation EndLoc) {
14636   for (Expr *SizeExpr : SizeExprs) {
14637     ExprResult NumForLoopsResult = VerifyPositiveIntegerConstantInClause(
14638         SizeExpr, OMPC_sizes, /*StrictlyPositive=*/true);
14639     if (!NumForLoopsResult.isUsable())
14640       return nullptr;
14641   }
14642 
14643   DSAStack->setAssociatedLoops(SizeExprs.size());
14644   return OMPSizesClause::Create(Context, StartLoc, LParenLoc, EndLoc,
14645                                 SizeExprs);
14646 }
14647 
ActOnOpenMPFullClause(SourceLocation StartLoc,SourceLocation EndLoc)14648 OMPClause *Sema::ActOnOpenMPFullClause(SourceLocation StartLoc,
14649                                        SourceLocation EndLoc) {
14650   return OMPFullClause::Create(Context, StartLoc, EndLoc);
14651 }
14652 
ActOnOpenMPPartialClause(Expr * FactorExpr,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)14653 OMPClause *Sema::ActOnOpenMPPartialClause(Expr *FactorExpr,
14654                                           SourceLocation StartLoc,
14655                                           SourceLocation LParenLoc,
14656                                           SourceLocation EndLoc) {
14657   if (FactorExpr) {
14658     // If an argument is specified, it must be a constant (or an unevaluated
14659     // template expression).
14660     ExprResult FactorResult = VerifyPositiveIntegerConstantInClause(
14661         FactorExpr, OMPC_partial, /*StrictlyPositive=*/true);
14662     if (FactorResult.isInvalid())
14663       return nullptr;
14664     FactorExpr = FactorResult.get();
14665   }
14666 
14667   return OMPPartialClause::Create(Context, StartLoc, LParenLoc, EndLoc,
14668                                   FactorExpr);
14669 }
14670 
ActOnOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind,ArrayRef<unsigned> Argument,Expr * Expr,SourceLocation StartLoc,SourceLocation LParenLoc,ArrayRef<SourceLocation> ArgumentLoc,SourceLocation DelimLoc,SourceLocation EndLoc)14671 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
14672     OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr,
14673     SourceLocation StartLoc, SourceLocation LParenLoc,
14674     ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc,
14675     SourceLocation EndLoc) {
14676   OMPClause *Res = nullptr;
14677   switch (Kind) {
14678   case OMPC_schedule:
14679     enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements };
14680     assert(Argument.size() == NumberOfElements &&
14681            ArgumentLoc.size() == NumberOfElements);
14682     Res = ActOnOpenMPScheduleClause(
14683         static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]),
14684         static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]),
14685         static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr,
14686         StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2],
14687         ArgumentLoc[ScheduleKind], DelimLoc, EndLoc);
14688     break;
14689   case OMPC_if:
14690     assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
14691     Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()),
14692                               Expr, StartLoc, LParenLoc, ArgumentLoc.back(),
14693                               DelimLoc, EndLoc);
14694     break;
14695   case OMPC_dist_schedule:
14696     Res = ActOnOpenMPDistScheduleClause(
14697         static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr,
14698         StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc);
14699     break;
14700   case OMPC_defaultmap:
14701     enum { Modifier, DefaultmapKind };
14702     Res = ActOnOpenMPDefaultmapClause(
14703         static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]),
14704         static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]),
14705         StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind],
14706         EndLoc);
14707     break;
14708   case OMPC_device:
14709     assert(Argument.size() == 1 && ArgumentLoc.size() == 1);
14710     Res = ActOnOpenMPDeviceClause(
14711         static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr,
14712         StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc);
14713     break;
14714   case OMPC_final:
14715   case OMPC_num_threads:
14716   case OMPC_safelen:
14717   case OMPC_simdlen:
14718   case OMPC_sizes:
14719   case OMPC_allocator:
14720   case OMPC_collapse:
14721   case OMPC_default:
14722   case OMPC_proc_bind:
14723   case OMPC_private:
14724   case OMPC_firstprivate:
14725   case OMPC_lastprivate:
14726   case OMPC_shared:
14727   case OMPC_reduction:
14728   case OMPC_task_reduction:
14729   case OMPC_in_reduction:
14730   case OMPC_linear:
14731   case OMPC_aligned:
14732   case OMPC_copyin:
14733   case OMPC_copyprivate:
14734   case OMPC_ordered:
14735   case OMPC_nowait:
14736   case OMPC_untied:
14737   case OMPC_mergeable:
14738   case OMPC_threadprivate:
14739   case OMPC_allocate:
14740   case OMPC_flush:
14741   case OMPC_depobj:
14742   case OMPC_read:
14743   case OMPC_write:
14744   case OMPC_update:
14745   case OMPC_capture:
14746   case OMPC_seq_cst:
14747   case OMPC_acq_rel:
14748   case OMPC_acquire:
14749   case OMPC_release:
14750   case OMPC_relaxed:
14751   case OMPC_depend:
14752   case OMPC_threads:
14753   case OMPC_simd:
14754   case OMPC_map:
14755   case OMPC_num_teams:
14756   case OMPC_thread_limit:
14757   case OMPC_priority:
14758   case OMPC_grainsize:
14759   case OMPC_nogroup:
14760   case OMPC_num_tasks:
14761   case OMPC_hint:
14762   case OMPC_unknown:
14763   case OMPC_uniform:
14764   case OMPC_to:
14765   case OMPC_from:
14766   case OMPC_use_device_ptr:
14767   case OMPC_use_device_addr:
14768   case OMPC_is_device_ptr:
14769   case OMPC_unified_address:
14770   case OMPC_unified_shared_memory:
14771   case OMPC_reverse_offload:
14772   case OMPC_dynamic_allocators:
14773   case OMPC_atomic_default_mem_order:
14774   case OMPC_device_type:
14775   case OMPC_match:
14776   case OMPC_nontemporal:
14777   case OMPC_order:
14778   case OMPC_destroy:
14779   case OMPC_novariants:
14780   case OMPC_nocontext:
14781   case OMPC_detach:
14782   case OMPC_inclusive:
14783   case OMPC_exclusive:
14784   case OMPC_uses_allocators:
14785   case OMPC_affinity:
14786   default:
14787     llvm_unreachable("Clause is not allowed.");
14788   }
14789   return Res;
14790 }
14791 
checkScheduleModifiers(Sema & S,OpenMPScheduleClauseModifier M1,OpenMPScheduleClauseModifier M2,SourceLocation M1Loc,SourceLocation M2Loc)14792 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1,
14793                                    OpenMPScheduleClauseModifier M2,
14794                                    SourceLocation M1Loc, SourceLocation M2Loc) {
14795   if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) {
14796     SmallVector<unsigned, 2> Excluded;
14797     if (M2 != OMPC_SCHEDULE_MODIFIER_unknown)
14798       Excluded.push_back(M2);
14799     if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic)
14800       Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic);
14801     if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic)
14802       Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic);
14803     S.Diag(M1Loc, diag::err_omp_unexpected_clause_value)
14804         << getListOfPossibleValues(OMPC_schedule,
14805                                    /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1,
14806                                    /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
14807                                    Excluded)
14808         << getOpenMPClauseName(OMPC_schedule);
14809     return true;
14810   }
14811   return false;
14812 }
14813 
ActOnOpenMPScheduleClause(OpenMPScheduleClauseModifier M1,OpenMPScheduleClauseModifier M2,OpenMPScheduleClauseKind Kind,Expr * ChunkSize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation M1Loc,SourceLocation M2Loc,SourceLocation KindLoc,SourceLocation CommaLoc,SourceLocation EndLoc)14814 OMPClause *Sema::ActOnOpenMPScheduleClause(
14815     OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2,
14816     OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
14817     SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc,
14818     SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) {
14819   if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) ||
14820       checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc))
14821     return nullptr;
14822   // OpenMP, 2.7.1, Loop Construct, Restrictions
14823   // Either the monotonic modifier or the nonmonotonic modifier can be specified
14824   // but not both.
14825   if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) ||
14826       (M1 == OMPC_SCHEDULE_MODIFIER_monotonic &&
14827        M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) ||
14828       (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic &&
14829        M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) {
14830     Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier)
14831         << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2)
14832         << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1);
14833     return nullptr;
14834   }
14835   if (Kind == OMPC_SCHEDULE_unknown) {
14836     std::string Values;
14837     if (M1Loc.isInvalid() && M2Loc.isInvalid()) {
14838       unsigned Exclude[] = {OMPC_SCHEDULE_unknown};
14839       Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
14840                                        /*Last=*/OMPC_SCHEDULE_MODIFIER_last,
14841                                        Exclude);
14842     } else {
14843       Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0,
14844                                        /*Last=*/OMPC_SCHEDULE_unknown);
14845     }
14846     Diag(KindLoc, diag::err_omp_unexpected_clause_value)
14847         << Values << getOpenMPClauseName(OMPC_schedule);
14848     return nullptr;
14849   }
14850   // OpenMP, 2.7.1, Loop Construct, Restrictions
14851   // The nonmonotonic modifier can only be specified with schedule(dynamic) or
14852   // schedule(guided).
14853   // OpenMP 5.0 does not have this restriction.
14854   if (LangOpts.OpenMP < 50 &&
14855       (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ||
14856        M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) &&
14857       Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) {
14858     Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc,
14859          diag::err_omp_schedule_nonmonotonic_static);
14860     return nullptr;
14861   }
14862   Expr *ValExpr = ChunkSize;
14863   Stmt *HelperValStmt = nullptr;
14864   if (ChunkSize) {
14865     if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
14866         !ChunkSize->isInstantiationDependent() &&
14867         !ChunkSize->containsUnexpandedParameterPack()) {
14868       SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
14869       ExprResult Val =
14870           PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
14871       if (Val.isInvalid())
14872         return nullptr;
14873 
14874       ValExpr = Val.get();
14875 
14876       // OpenMP [2.7.1, Restrictions]
14877       //  chunk_size must be a loop invariant integer expression with a positive
14878       //  value.
14879       if (Optional<llvm::APSInt> Result =
14880               ValExpr->getIntegerConstantExpr(Context)) {
14881         if (Result->isSigned() && !Result->isStrictlyPositive()) {
14882           Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
14883               << "schedule" << 1 << ChunkSize->getSourceRange();
14884           return nullptr;
14885         }
14886       } else if (getOpenMPCaptureRegionForClause(
14887                      DSAStack->getCurrentDirective(), OMPC_schedule,
14888                      LangOpts.OpenMP) != OMPD_unknown &&
14889                  !CurContext->isDependentContext()) {
14890         ValExpr = MakeFullExpr(ValExpr).get();
14891         llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
14892         ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
14893         HelperValStmt = buildPreInits(Context, Captures);
14894       }
14895     }
14896   }
14897 
14898   return new (Context)
14899       OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind,
14900                         ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc);
14901 }
14902 
ActOnOpenMPClause(OpenMPClauseKind Kind,SourceLocation StartLoc,SourceLocation EndLoc)14903 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
14904                                    SourceLocation StartLoc,
14905                                    SourceLocation EndLoc) {
14906   OMPClause *Res = nullptr;
14907   switch (Kind) {
14908   case OMPC_ordered:
14909     Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc);
14910     break;
14911   case OMPC_nowait:
14912     Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc);
14913     break;
14914   case OMPC_untied:
14915     Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc);
14916     break;
14917   case OMPC_mergeable:
14918     Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc);
14919     break;
14920   case OMPC_read:
14921     Res = ActOnOpenMPReadClause(StartLoc, EndLoc);
14922     break;
14923   case OMPC_write:
14924     Res = ActOnOpenMPWriteClause(StartLoc, EndLoc);
14925     break;
14926   case OMPC_update:
14927     Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc);
14928     break;
14929   case OMPC_capture:
14930     Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc);
14931     break;
14932   case OMPC_seq_cst:
14933     Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc);
14934     break;
14935   case OMPC_acq_rel:
14936     Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc);
14937     break;
14938   case OMPC_acquire:
14939     Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc);
14940     break;
14941   case OMPC_release:
14942     Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc);
14943     break;
14944   case OMPC_relaxed:
14945     Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc);
14946     break;
14947   case OMPC_threads:
14948     Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc);
14949     break;
14950   case OMPC_simd:
14951     Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc);
14952     break;
14953   case OMPC_nogroup:
14954     Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc);
14955     break;
14956   case OMPC_unified_address:
14957     Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc);
14958     break;
14959   case OMPC_unified_shared_memory:
14960     Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
14961     break;
14962   case OMPC_reverse_offload:
14963     Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc);
14964     break;
14965   case OMPC_dynamic_allocators:
14966     Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc);
14967     break;
14968   case OMPC_destroy:
14969     Res = ActOnOpenMPDestroyClause(/*InteropVar=*/nullptr, StartLoc,
14970                                    /*LParenLoc=*/SourceLocation(),
14971                                    /*VarLoc=*/SourceLocation(), EndLoc);
14972     break;
14973   case OMPC_full:
14974     Res = ActOnOpenMPFullClause(StartLoc, EndLoc);
14975     break;
14976   case OMPC_partial:
14977     Res = ActOnOpenMPPartialClause(nullptr, StartLoc, /*LParenLoc=*/{}, EndLoc);
14978     break;
14979   case OMPC_if:
14980   case OMPC_final:
14981   case OMPC_num_threads:
14982   case OMPC_safelen:
14983   case OMPC_simdlen:
14984   case OMPC_sizes:
14985   case OMPC_allocator:
14986   case OMPC_collapse:
14987   case OMPC_schedule:
14988   case OMPC_private:
14989   case OMPC_firstprivate:
14990   case OMPC_lastprivate:
14991   case OMPC_shared:
14992   case OMPC_reduction:
14993   case OMPC_task_reduction:
14994   case OMPC_in_reduction:
14995   case OMPC_linear:
14996   case OMPC_aligned:
14997   case OMPC_copyin:
14998   case OMPC_copyprivate:
14999   case OMPC_default:
15000   case OMPC_proc_bind:
15001   case OMPC_threadprivate:
15002   case OMPC_allocate:
15003   case OMPC_flush:
15004   case OMPC_depobj:
15005   case OMPC_depend:
15006   case OMPC_device:
15007   case OMPC_map:
15008   case OMPC_num_teams:
15009   case OMPC_thread_limit:
15010   case OMPC_priority:
15011   case OMPC_grainsize:
15012   case OMPC_num_tasks:
15013   case OMPC_hint:
15014   case OMPC_dist_schedule:
15015   case OMPC_defaultmap:
15016   case OMPC_unknown:
15017   case OMPC_uniform:
15018   case OMPC_to:
15019   case OMPC_from:
15020   case OMPC_use_device_ptr:
15021   case OMPC_use_device_addr:
15022   case OMPC_is_device_ptr:
15023   case OMPC_atomic_default_mem_order:
15024   case OMPC_device_type:
15025   case OMPC_match:
15026   case OMPC_nontemporal:
15027   case OMPC_order:
15028   case OMPC_novariants:
15029   case OMPC_nocontext:
15030   case OMPC_detach:
15031   case OMPC_inclusive:
15032   case OMPC_exclusive:
15033   case OMPC_uses_allocators:
15034   case OMPC_affinity:
15035   default:
15036     llvm_unreachable("Clause is not allowed.");
15037   }
15038   return Res;
15039 }
15040 
ActOnOpenMPNowaitClause(SourceLocation StartLoc,SourceLocation EndLoc)15041 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc,
15042                                          SourceLocation EndLoc) {
15043   DSAStack->setNowaitRegion();
15044   return new (Context) OMPNowaitClause(StartLoc, EndLoc);
15045 }
15046 
ActOnOpenMPUntiedClause(SourceLocation StartLoc,SourceLocation EndLoc)15047 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc,
15048                                          SourceLocation EndLoc) {
15049   return new (Context) OMPUntiedClause(StartLoc, EndLoc);
15050 }
15051 
ActOnOpenMPMergeableClause(SourceLocation StartLoc,SourceLocation EndLoc)15052 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc,
15053                                             SourceLocation EndLoc) {
15054   return new (Context) OMPMergeableClause(StartLoc, EndLoc);
15055 }
15056 
ActOnOpenMPReadClause(SourceLocation StartLoc,SourceLocation EndLoc)15057 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc,
15058                                        SourceLocation EndLoc) {
15059   return new (Context) OMPReadClause(StartLoc, EndLoc);
15060 }
15061 
ActOnOpenMPWriteClause(SourceLocation StartLoc,SourceLocation EndLoc)15062 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc,
15063                                         SourceLocation EndLoc) {
15064   return new (Context) OMPWriteClause(StartLoc, EndLoc);
15065 }
15066 
ActOnOpenMPUpdateClause(SourceLocation StartLoc,SourceLocation EndLoc)15067 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc,
15068                                          SourceLocation EndLoc) {
15069   return OMPUpdateClause::Create(Context, StartLoc, EndLoc);
15070 }
15071 
ActOnOpenMPCaptureClause(SourceLocation StartLoc,SourceLocation EndLoc)15072 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc,
15073                                           SourceLocation EndLoc) {
15074   return new (Context) OMPCaptureClause(StartLoc, EndLoc);
15075 }
15076 
ActOnOpenMPSeqCstClause(SourceLocation StartLoc,SourceLocation EndLoc)15077 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc,
15078                                          SourceLocation EndLoc) {
15079   return new (Context) OMPSeqCstClause(StartLoc, EndLoc);
15080 }
15081 
ActOnOpenMPAcqRelClause(SourceLocation StartLoc,SourceLocation EndLoc)15082 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc,
15083                                          SourceLocation EndLoc) {
15084   return new (Context) OMPAcqRelClause(StartLoc, EndLoc);
15085 }
15086 
ActOnOpenMPAcquireClause(SourceLocation StartLoc,SourceLocation EndLoc)15087 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc,
15088                                           SourceLocation EndLoc) {
15089   return new (Context) OMPAcquireClause(StartLoc, EndLoc);
15090 }
15091 
ActOnOpenMPReleaseClause(SourceLocation StartLoc,SourceLocation EndLoc)15092 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc,
15093                                           SourceLocation EndLoc) {
15094   return new (Context) OMPReleaseClause(StartLoc, EndLoc);
15095 }
15096 
ActOnOpenMPRelaxedClause(SourceLocation StartLoc,SourceLocation EndLoc)15097 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc,
15098                                           SourceLocation EndLoc) {
15099   return new (Context) OMPRelaxedClause(StartLoc, EndLoc);
15100 }
15101 
ActOnOpenMPThreadsClause(SourceLocation StartLoc,SourceLocation EndLoc)15102 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc,
15103                                           SourceLocation EndLoc) {
15104   return new (Context) OMPThreadsClause(StartLoc, EndLoc);
15105 }
15106 
ActOnOpenMPSIMDClause(SourceLocation StartLoc,SourceLocation EndLoc)15107 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc,
15108                                        SourceLocation EndLoc) {
15109   return new (Context) OMPSIMDClause(StartLoc, EndLoc);
15110 }
15111 
ActOnOpenMPNogroupClause(SourceLocation StartLoc,SourceLocation EndLoc)15112 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc,
15113                                           SourceLocation EndLoc) {
15114   return new (Context) OMPNogroupClause(StartLoc, EndLoc);
15115 }
15116 
ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,SourceLocation EndLoc)15117 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc,
15118                                                  SourceLocation EndLoc) {
15119   return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc);
15120 }
15121 
ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,SourceLocation EndLoc)15122 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc,
15123                                                       SourceLocation EndLoc) {
15124   return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc);
15125 }
15126 
ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,SourceLocation EndLoc)15127 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc,
15128                                                  SourceLocation EndLoc) {
15129   return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc);
15130 }
15131 
ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,SourceLocation EndLoc)15132 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc,
15133                                                     SourceLocation EndLoc) {
15134   return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc);
15135 }
15136 
ActOnOpenMPInteropDirective(ArrayRef<OMPClause * > Clauses,SourceLocation StartLoc,SourceLocation EndLoc)15137 StmtResult Sema::ActOnOpenMPInteropDirective(ArrayRef<OMPClause *> Clauses,
15138                                              SourceLocation StartLoc,
15139                                              SourceLocation EndLoc) {
15140 
15141   // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
15142   // At least one action-clause must appear on a directive.
15143   if (!hasClauses(Clauses, OMPC_init, OMPC_use, OMPC_destroy, OMPC_nowait)) {
15144     StringRef Expected = "'init', 'use', 'destroy', or 'nowait'";
15145     Diag(StartLoc, diag::err_omp_no_clause_for_directive)
15146         << Expected << getOpenMPDirectiveName(OMPD_interop);
15147     return StmtError();
15148   }
15149 
15150   // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
15151   // A depend clause can only appear on the directive if a targetsync
15152   // interop-type is present or the interop-var was initialized with
15153   // the targetsync interop-type.
15154 
15155   // If there is any 'init' clause diagnose if there is no 'init' clause with
15156   // interop-type of 'targetsync'. Cases involving other directives cannot be
15157   // diagnosed.
15158   const OMPDependClause *DependClause = nullptr;
15159   bool HasInitClause = false;
15160   bool IsTargetSync = false;
15161   for (const OMPClause *C : Clauses) {
15162     if (IsTargetSync)
15163       break;
15164     if (const auto *InitClause = dyn_cast<OMPInitClause>(C)) {
15165       HasInitClause = true;
15166       if (InitClause->getIsTargetSync())
15167         IsTargetSync = true;
15168     } else if (const auto *DC = dyn_cast<OMPDependClause>(C)) {
15169       DependClause = DC;
15170     }
15171   }
15172   if (DependClause && HasInitClause && !IsTargetSync) {
15173     Diag(DependClause->getBeginLoc(), diag::err_omp_interop_bad_depend_clause);
15174     return StmtError();
15175   }
15176 
15177   // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
15178   // Each interop-var may be specified for at most one action-clause of each
15179   // interop construct.
15180   llvm::SmallPtrSet<const VarDecl *, 4> InteropVars;
15181   for (const OMPClause *C : Clauses) {
15182     OpenMPClauseKind ClauseKind = C->getClauseKind();
15183     const DeclRefExpr *DRE = nullptr;
15184     SourceLocation VarLoc;
15185 
15186     if (ClauseKind == OMPC_init) {
15187       const auto *IC = cast<OMPInitClause>(C);
15188       VarLoc = IC->getVarLoc();
15189       DRE = dyn_cast_or_null<DeclRefExpr>(IC->getInteropVar());
15190     } else if (ClauseKind == OMPC_use) {
15191       const auto *UC = cast<OMPUseClause>(C);
15192       VarLoc = UC->getVarLoc();
15193       DRE = dyn_cast_or_null<DeclRefExpr>(UC->getInteropVar());
15194     } else if (ClauseKind == OMPC_destroy) {
15195       const auto *DC = cast<OMPDestroyClause>(C);
15196       VarLoc = DC->getVarLoc();
15197       DRE = dyn_cast_or_null<DeclRefExpr>(DC->getInteropVar());
15198     }
15199 
15200     if (!DRE)
15201       continue;
15202 
15203     if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
15204       if (!InteropVars.insert(VD->getCanonicalDecl()).second) {
15205         Diag(VarLoc, diag::err_omp_interop_var_multiple_actions) << VD;
15206         return StmtError();
15207       }
15208     }
15209   }
15210 
15211   return OMPInteropDirective::Create(Context, StartLoc, EndLoc, Clauses);
15212 }
15213 
isValidInteropVariable(Sema & SemaRef,Expr * InteropVarExpr,SourceLocation VarLoc,OpenMPClauseKind Kind)15214 static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr,
15215                                    SourceLocation VarLoc,
15216                                    OpenMPClauseKind Kind) {
15217   if (InteropVarExpr->isValueDependent() || InteropVarExpr->isTypeDependent() ||
15218       InteropVarExpr->isInstantiationDependent() ||
15219       InteropVarExpr->containsUnexpandedParameterPack())
15220     return true;
15221 
15222   const auto *DRE = dyn_cast<DeclRefExpr>(InteropVarExpr);
15223   if (!DRE || !isa<VarDecl>(DRE->getDecl())) {
15224     SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected) << 0;
15225     return false;
15226   }
15227 
15228   // Interop variable should be of type omp_interop_t.
15229   bool HasError = false;
15230   QualType InteropType;
15231   LookupResult Result(SemaRef, &SemaRef.Context.Idents.get("omp_interop_t"),
15232                       VarLoc, Sema::LookupOrdinaryName);
15233   if (SemaRef.LookupName(Result, SemaRef.getCurScope())) {
15234     NamedDecl *ND = Result.getFoundDecl();
15235     if (const auto *TD = dyn_cast<TypeDecl>(ND)) {
15236       InteropType = QualType(TD->getTypeForDecl(), 0);
15237     } else {
15238       HasError = true;
15239     }
15240   } else {
15241     HasError = true;
15242   }
15243 
15244   if (HasError) {
15245     SemaRef.Diag(VarLoc, diag::err_omp_implied_type_not_found)
15246         << "omp_interop_t";
15247     return false;
15248   }
15249 
15250   QualType VarType = InteropVarExpr->getType().getUnqualifiedType();
15251   if (!SemaRef.Context.hasSameType(InteropType, VarType)) {
15252     SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_wrong_type);
15253     return false;
15254   }
15255 
15256   // OpenMP 5.1 [2.15.1, interop Construct, Restrictions]
15257   // The interop-var passed to init or destroy must be non-const.
15258   if ((Kind == OMPC_init || Kind == OMPC_destroy) &&
15259       isConstNotMutableType(SemaRef, InteropVarExpr->getType())) {
15260     SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected)
15261         << /*non-const*/ 1;
15262     return false;
15263   }
15264   return true;
15265 }
15266 
15267 OMPClause *
ActOnOpenMPInitClause(Expr * InteropVar,ArrayRef<Expr * > PrefExprs,bool IsTarget,bool IsTargetSync,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation VarLoc,SourceLocation EndLoc)15268 Sema::ActOnOpenMPInitClause(Expr *InteropVar, ArrayRef<Expr *> PrefExprs,
15269                             bool IsTarget, bool IsTargetSync,
15270                             SourceLocation StartLoc, SourceLocation LParenLoc,
15271                             SourceLocation VarLoc, SourceLocation EndLoc) {
15272 
15273   if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_init))
15274     return nullptr;
15275 
15276   // Check prefer_type values.  These foreign-runtime-id values are either
15277   // string literals or constant integral expressions.
15278   for (const Expr *E : PrefExprs) {
15279     if (E->isValueDependent() || E->isTypeDependent() ||
15280         E->isInstantiationDependent() || E->containsUnexpandedParameterPack())
15281       continue;
15282     if (E->isIntegerConstantExpr(Context))
15283       continue;
15284     if (isa<StringLiteral>(E))
15285       continue;
15286     Diag(E->getExprLoc(), diag::err_omp_interop_prefer_type);
15287     return nullptr;
15288   }
15289 
15290   return OMPInitClause::Create(Context, InteropVar, PrefExprs, IsTarget,
15291                                IsTargetSync, StartLoc, LParenLoc, VarLoc,
15292                                EndLoc);
15293 }
15294 
ActOnOpenMPUseClause(Expr * InteropVar,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation VarLoc,SourceLocation EndLoc)15295 OMPClause *Sema::ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc,
15296                                       SourceLocation LParenLoc,
15297                                       SourceLocation VarLoc,
15298                                       SourceLocation EndLoc) {
15299 
15300   if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_use))
15301     return nullptr;
15302 
15303   return new (Context)
15304       OMPUseClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
15305 }
15306 
ActOnOpenMPDestroyClause(Expr * InteropVar,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation VarLoc,SourceLocation EndLoc)15307 OMPClause *Sema::ActOnOpenMPDestroyClause(Expr *InteropVar,
15308                                           SourceLocation StartLoc,
15309                                           SourceLocation LParenLoc,
15310                                           SourceLocation VarLoc,
15311                                           SourceLocation EndLoc) {
15312   if (InteropVar &&
15313       !isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_destroy))
15314     return nullptr;
15315 
15316   return new (Context)
15317       OMPDestroyClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc);
15318 }
15319 
ActOnOpenMPNovariantsClause(Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)15320 OMPClause *Sema::ActOnOpenMPNovariantsClause(Expr *Condition,
15321                                              SourceLocation StartLoc,
15322                                              SourceLocation LParenLoc,
15323                                              SourceLocation EndLoc) {
15324   Expr *ValExpr = Condition;
15325   Stmt *HelperValStmt = nullptr;
15326   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
15327   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
15328       !Condition->isInstantiationDependent() &&
15329       !Condition->containsUnexpandedParameterPack()) {
15330     ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
15331     if (Val.isInvalid())
15332       return nullptr;
15333 
15334     ValExpr = MakeFullExpr(Val.get()).get();
15335 
15336     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
15337     CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_novariants,
15338                                                     LangOpts.OpenMP);
15339     if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
15340       ValExpr = MakeFullExpr(ValExpr).get();
15341       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15342       ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
15343       HelperValStmt = buildPreInits(Context, Captures);
15344     }
15345   }
15346 
15347   return new (Context) OMPNovariantsClause(
15348       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
15349 }
15350 
ActOnOpenMPNocontextClause(Expr * Condition,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)15351 OMPClause *Sema::ActOnOpenMPNocontextClause(Expr *Condition,
15352                                             SourceLocation StartLoc,
15353                                             SourceLocation LParenLoc,
15354                                             SourceLocation EndLoc) {
15355   Expr *ValExpr = Condition;
15356   Stmt *HelperValStmt = nullptr;
15357   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
15358   if (!Condition->isValueDependent() && !Condition->isTypeDependent() &&
15359       !Condition->isInstantiationDependent() &&
15360       !Condition->containsUnexpandedParameterPack()) {
15361     ExprResult Val = CheckBooleanCondition(StartLoc, Condition);
15362     if (Val.isInvalid())
15363       return nullptr;
15364 
15365     ValExpr = MakeFullExpr(Val.get()).get();
15366 
15367     OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
15368     CaptureRegion =
15369         getOpenMPCaptureRegionForClause(DKind, OMPC_nocontext, LangOpts.OpenMP);
15370     if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
15371       ValExpr = MakeFullExpr(ValExpr).get();
15372       llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15373       ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
15374       HelperValStmt = buildPreInits(Context, Captures);
15375     }
15376   }
15377 
15378   return new (Context) OMPNocontextClause(ValExpr, HelperValStmt, CaptureRegion,
15379                                           StartLoc, LParenLoc, EndLoc);
15380 }
15381 
ActOnOpenMPFilterClause(Expr * ThreadID,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)15382 OMPClause *Sema::ActOnOpenMPFilterClause(Expr *ThreadID,
15383                                          SourceLocation StartLoc,
15384                                          SourceLocation LParenLoc,
15385                                          SourceLocation EndLoc) {
15386   Expr *ValExpr = ThreadID;
15387   Stmt *HelperValStmt = nullptr;
15388 
15389   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
15390   OpenMPDirectiveKind CaptureRegion =
15391       getOpenMPCaptureRegionForClause(DKind, OMPC_filter, LangOpts.OpenMP);
15392   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
15393     ValExpr = MakeFullExpr(ValExpr).get();
15394     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
15395     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
15396     HelperValStmt = buildPreInits(Context, Captures);
15397   }
15398 
15399   return new (Context) OMPFilterClause(ValExpr, HelperValStmt, CaptureRegion,
15400                                        StartLoc, LParenLoc, EndLoc);
15401 }
15402 
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)15403 OMPClause *Sema::ActOnOpenMPVarListClause(
15404     OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr,
15405     const OMPVarListLocTy &Locs, SourceLocation ColonLoc,
15406     CXXScopeSpec &ReductionOrMapperIdScopeSpec,
15407     DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier,
15408     ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
15409     ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit,
15410     SourceLocation ExtraModifierLoc,
15411     ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
15412     ArrayRef<SourceLocation> MotionModifiersLoc) {
15413   SourceLocation StartLoc = Locs.StartLoc;
15414   SourceLocation LParenLoc = Locs.LParenLoc;
15415   SourceLocation EndLoc = Locs.EndLoc;
15416   OMPClause *Res = nullptr;
15417   switch (Kind) {
15418   case OMPC_private:
15419     Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc);
15420     break;
15421   case OMPC_firstprivate:
15422     Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
15423     break;
15424   case OMPC_lastprivate:
15425     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown &&
15426            "Unexpected lastprivate modifier.");
15427     Res = ActOnOpenMPLastprivateClause(
15428         VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier),
15429         ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc);
15430     break;
15431   case OMPC_shared:
15432     Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc);
15433     break;
15434   case OMPC_reduction:
15435     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown &&
15436            "Unexpected lastprivate modifier.");
15437     Res = ActOnOpenMPReductionClause(
15438         VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier),
15439         StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc,
15440         ReductionOrMapperIdScopeSpec, ReductionOrMapperId);
15441     break;
15442   case OMPC_task_reduction:
15443     Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
15444                                          EndLoc, ReductionOrMapperIdScopeSpec,
15445                                          ReductionOrMapperId);
15446     break;
15447   case OMPC_in_reduction:
15448     Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
15449                                        EndLoc, ReductionOrMapperIdScopeSpec,
15450                                        ReductionOrMapperId);
15451     break;
15452   case OMPC_linear:
15453     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown &&
15454            "Unexpected linear modifier.");
15455     Res = ActOnOpenMPLinearClause(
15456         VarList, DepModOrTailExpr, StartLoc, LParenLoc,
15457         static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc,
15458         ColonLoc, EndLoc);
15459     break;
15460   case OMPC_aligned:
15461     Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc,
15462                                    LParenLoc, ColonLoc, EndLoc);
15463     break;
15464   case OMPC_copyin:
15465     Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc);
15466     break;
15467   case OMPC_copyprivate:
15468     Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc);
15469     break;
15470   case OMPC_flush:
15471     Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc);
15472     break;
15473   case OMPC_depend:
15474     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown &&
15475            "Unexpected depend modifier.");
15476     Res = ActOnOpenMPDependClause(
15477         DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier),
15478         ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc);
15479     break;
15480   case OMPC_map:
15481     assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown &&
15482            "Unexpected map modifier.");
15483     Res = ActOnOpenMPMapClause(
15484         MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec,
15485         ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier),
15486         IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs);
15487     break;
15488   case OMPC_to:
15489     Res = ActOnOpenMPToClause(MotionModifiers, MotionModifiersLoc,
15490                               ReductionOrMapperIdScopeSpec, ReductionOrMapperId,
15491                               ColonLoc, VarList, Locs);
15492     break;
15493   case OMPC_from:
15494     Res = ActOnOpenMPFromClause(MotionModifiers, MotionModifiersLoc,
15495                                 ReductionOrMapperIdScopeSpec,
15496                                 ReductionOrMapperId, ColonLoc, VarList, Locs);
15497     break;
15498   case OMPC_use_device_ptr:
15499     Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs);
15500     break;
15501   case OMPC_use_device_addr:
15502     Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs);
15503     break;
15504   case OMPC_is_device_ptr:
15505     Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs);
15506     break;
15507   case OMPC_allocate:
15508     Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc,
15509                                     LParenLoc, ColonLoc, EndLoc);
15510     break;
15511   case OMPC_nontemporal:
15512     Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc);
15513     break;
15514   case OMPC_inclusive:
15515     Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
15516     break;
15517   case OMPC_exclusive:
15518     Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc);
15519     break;
15520   case OMPC_affinity:
15521     Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc,
15522                                     DepModOrTailExpr, VarList);
15523     break;
15524   case OMPC_if:
15525   case OMPC_depobj:
15526   case OMPC_final:
15527   case OMPC_num_threads:
15528   case OMPC_safelen:
15529   case OMPC_simdlen:
15530   case OMPC_sizes:
15531   case OMPC_allocator:
15532   case OMPC_collapse:
15533   case OMPC_default:
15534   case OMPC_proc_bind:
15535   case OMPC_schedule:
15536   case OMPC_ordered:
15537   case OMPC_nowait:
15538   case OMPC_untied:
15539   case OMPC_mergeable:
15540   case OMPC_threadprivate:
15541   case OMPC_read:
15542   case OMPC_write:
15543   case OMPC_update:
15544   case OMPC_capture:
15545   case OMPC_seq_cst:
15546   case OMPC_acq_rel:
15547   case OMPC_acquire:
15548   case OMPC_release:
15549   case OMPC_relaxed:
15550   case OMPC_device:
15551   case OMPC_threads:
15552   case OMPC_simd:
15553   case OMPC_num_teams:
15554   case OMPC_thread_limit:
15555   case OMPC_priority:
15556   case OMPC_grainsize:
15557   case OMPC_nogroup:
15558   case OMPC_num_tasks:
15559   case OMPC_hint:
15560   case OMPC_dist_schedule:
15561   case OMPC_defaultmap:
15562   case OMPC_unknown:
15563   case OMPC_uniform:
15564   case OMPC_unified_address:
15565   case OMPC_unified_shared_memory:
15566   case OMPC_reverse_offload:
15567   case OMPC_dynamic_allocators:
15568   case OMPC_atomic_default_mem_order:
15569   case OMPC_device_type:
15570   case OMPC_match:
15571   case OMPC_order:
15572   case OMPC_destroy:
15573   case OMPC_novariants:
15574   case OMPC_nocontext:
15575   case OMPC_detach:
15576   case OMPC_uses_allocators:
15577   default:
15578     llvm_unreachable("Clause is not allowed.");
15579   }
15580   return Res;
15581 }
15582 
getOpenMPCapturedExpr(VarDecl * Capture,ExprValueKind VK,ExprObjectKind OK,SourceLocation Loc)15583 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK,
15584                                        ExprObjectKind OK, SourceLocation Loc) {
15585   ExprResult Res = BuildDeclRefExpr(
15586       Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc);
15587   if (!Res.isUsable())
15588     return ExprError();
15589   if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) {
15590     Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get());
15591     if (!Res.isUsable())
15592       return ExprError();
15593   }
15594   if (VK != VK_LValue && Res.get()->isGLValue()) {
15595     Res = DefaultLvalueConversion(Res.get());
15596     if (!Res.isUsable())
15597       return ExprError();
15598   }
15599   return Res;
15600 }
15601 
ActOnOpenMPPrivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)15602 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList,
15603                                           SourceLocation StartLoc,
15604                                           SourceLocation LParenLoc,
15605                                           SourceLocation EndLoc) {
15606   SmallVector<Expr *, 8> Vars;
15607   SmallVector<Expr *, 8> PrivateCopies;
15608   for (Expr *RefExpr : VarList) {
15609     assert(RefExpr && "NULL expr in OpenMP private clause.");
15610     SourceLocation ELoc;
15611     SourceRange ERange;
15612     Expr *SimpleRefExpr = RefExpr;
15613     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15614     if (Res.second) {
15615       // It will be analyzed later.
15616       Vars.push_back(RefExpr);
15617       PrivateCopies.push_back(nullptr);
15618     }
15619     ValueDecl *D = Res.first;
15620     if (!D)
15621       continue;
15622 
15623     QualType Type = D->getType();
15624     auto *VD = dyn_cast<VarDecl>(D);
15625 
15626     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
15627     //  A variable that appears in a private clause must not have an incomplete
15628     //  type or a reference type.
15629     if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type))
15630       continue;
15631     Type = Type.getNonReferenceType();
15632 
15633     // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
15634     // A variable that is privatized must not have a const-qualified type
15635     // unless it is of class type with a mutable member. This restriction does
15636     // not apply to the firstprivate clause.
15637     //
15638     // OpenMP 3.1 [2.9.3.3, private clause, Restrictions]
15639     // A variable that appears in a private clause must not have a
15640     // const-qualified type unless it is of class type with a mutable member.
15641     if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc))
15642       continue;
15643 
15644     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
15645     // in a Construct]
15646     //  Variables with the predetermined data-sharing attributes may not be
15647     //  listed in data-sharing attributes clauses, except for the cases
15648     //  listed below. For these exceptions only, listing a predetermined
15649     //  variable in a data-sharing attribute clause is allowed and overrides
15650     //  the variable's predetermined data-sharing attributes.
15651     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
15652     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) {
15653       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
15654                                           << getOpenMPClauseName(OMPC_private);
15655       reportOriginalDsa(*this, DSAStack, D, DVar);
15656       continue;
15657     }
15658 
15659     OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
15660     // Variably modified types are not supported for tasks.
15661     if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
15662         isOpenMPTaskingDirective(CurrDir)) {
15663       Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
15664           << getOpenMPClauseName(OMPC_private) << Type
15665           << getOpenMPDirectiveName(CurrDir);
15666       bool IsDecl =
15667           !VD ||
15668           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
15669       Diag(D->getLocation(),
15670            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15671           << D;
15672       continue;
15673     }
15674 
15675     // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
15676     // A list item cannot appear in both a map clause and a data-sharing
15677     // attribute clause on the same construct
15678     //
15679     // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
15680     // A list item cannot appear in both a map clause and a data-sharing
15681     // attribute clause on the same construct unless the construct is a
15682     // combined construct.
15683     if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) ||
15684         CurrDir == OMPD_target) {
15685       OpenMPClauseKind ConflictKind;
15686       if (DSAStack->checkMappableExprComponentListsForDecl(
15687               VD, /*CurrentRegionOnly=*/true,
15688               [&](OMPClauseMappableExprCommon::MappableExprComponentListRef,
15689                   OpenMPClauseKind WhereFoundClauseKind) -> bool {
15690                 ConflictKind = WhereFoundClauseKind;
15691                 return true;
15692               })) {
15693         Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
15694             << getOpenMPClauseName(OMPC_private)
15695             << getOpenMPClauseName(ConflictKind)
15696             << getOpenMPDirectiveName(CurrDir);
15697         reportOriginalDsa(*this, DSAStack, D, DVar);
15698         continue;
15699       }
15700     }
15701 
15702     // OpenMP [2.9.3.3, Restrictions, C/C++, p.1]
15703     //  A variable of class type (or array thereof) that appears in a private
15704     //  clause requires an accessible, unambiguous default constructor for the
15705     //  class type.
15706     // Generate helper private variable and initialize it with the default
15707     // value. The address of the original variable is replaced by the address of
15708     // the new private variable in CodeGen. This new variable is not added to
15709     // IdResolver, so the code in the OpenMP region uses original variable for
15710     // proper diagnostics.
15711     Type = Type.getUnqualifiedType();
15712     VarDecl *VDPrivate =
15713         buildVarDecl(*this, ELoc, Type, D->getName(),
15714                      D->hasAttrs() ? &D->getAttrs() : nullptr,
15715                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
15716     ActOnUninitializedDecl(VDPrivate);
15717     if (VDPrivate->isInvalidDecl())
15718       continue;
15719     DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
15720         *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
15721 
15722     DeclRefExpr *Ref = nullptr;
15723     if (!VD && !CurContext->isDependentContext())
15724       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
15725     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref);
15726     Vars.push_back((VD || CurContext->isDependentContext())
15727                        ? RefExpr->IgnoreParens()
15728                        : Ref);
15729     PrivateCopies.push_back(VDPrivateRefExpr);
15730   }
15731 
15732   if (Vars.empty())
15733     return nullptr;
15734 
15735   return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
15736                                   PrivateCopies);
15737 }
15738 
15739 namespace {
15740 class DiagsUninitializedSeveretyRAII {
15741 private:
15742   DiagnosticsEngine &Diags;
15743   SourceLocation SavedLoc;
15744   bool IsIgnored = false;
15745 
15746 public:
DiagsUninitializedSeveretyRAII(DiagnosticsEngine & Diags,SourceLocation Loc,bool IsIgnored)15747   DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc,
15748                                  bool IsIgnored)
15749       : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) {
15750     if (!IsIgnored) {
15751       Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init,
15752                         /*Map*/ diag::Severity::Ignored, Loc);
15753     }
15754   }
~DiagsUninitializedSeveretyRAII()15755   ~DiagsUninitializedSeveretyRAII() {
15756     if (!IsIgnored)
15757       Diags.popMappings(SavedLoc);
15758   }
15759 };
15760 }
15761 
ActOnOpenMPFirstprivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)15762 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList,
15763                                                SourceLocation StartLoc,
15764                                                SourceLocation LParenLoc,
15765                                                SourceLocation EndLoc) {
15766   SmallVector<Expr *, 8> Vars;
15767   SmallVector<Expr *, 8> PrivateCopies;
15768   SmallVector<Expr *, 8> Inits;
15769   SmallVector<Decl *, 4> ExprCaptures;
15770   bool IsImplicitClause =
15771       StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid();
15772   SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc();
15773 
15774   for (Expr *RefExpr : VarList) {
15775     assert(RefExpr && "NULL expr in OpenMP firstprivate clause.");
15776     SourceLocation ELoc;
15777     SourceRange ERange;
15778     Expr *SimpleRefExpr = RefExpr;
15779     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
15780     if (Res.second) {
15781       // It will be analyzed later.
15782       Vars.push_back(RefExpr);
15783       PrivateCopies.push_back(nullptr);
15784       Inits.push_back(nullptr);
15785     }
15786     ValueDecl *D = Res.first;
15787     if (!D)
15788       continue;
15789 
15790     ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc;
15791     QualType Type = D->getType();
15792     auto *VD = dyn_cast<VarDecl>(D);
15793 
15794     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
15795     //  A variable that appears in a private clause must not have an incomplete
15796     //  type or a reference type.
15797     if (RequireCompleteType(ELoc, Type,
15798                             diag::err_omp_firstprivate_incomplete_type))
15799       continue;
15800     Type = Type.getNonReferenceType();
15801 
15802     // OpenMP [2.9.3.4, Restrictions, C/C++, p.1]
15803     //  A variable of class type (or array thereof) that appears in a private
15804     //  clause requires an accessible, unambiguous copy constructor for the
15805     //  class type.
15806     QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
15807 
15808     // If an implicit firstprivate variable found it was checked already.
15809     DSAStackTy::DSAVarData TopDVar;
15810     if (!IsImplicitClause) {
15811       DSAStackTy::DSAVarData DVar =
15812           DSAStack->getTopDSA(D, /*FromParent=*/false);
15813       TopDVar = DVar;
15814       OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
15815       bool IsConstant = ElemType.isConstant(Context);
15816       // OpenMP [2.4.13, Data-sharing Attribute Clauses]
15817       //  A list item that specifies a given variable may not appear in more
15818       // than one clause on the same directive, except that a variable may be
15819       //  specified in both firstprivate and lastprivate clauses.
15820       // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
15821       // A list item may appear in a firstprivate or lastprivate clause but not
15822       // both.
15823       if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
15824           (isOpenMPDistributeDirective(CurrDir) ||
15825            DVar.CKind != OMPC_lastprivate) &&
15826           DVar.RefExpr) {
15827         Diag(ELoc, diag::err_omp_wrong_dsa)
15828             << getOpenMPClauseName(DVar.CKind)
15829             << getOpenMPClauseName(OMPC_firstprivate);
15830         reportOriginalDsa(*this, DSAStack, D, DVar);
15831         continue;
15832       }
15833 
15834       // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
15835       // in a Construct]
15836       //  Variables with the predetermined data-sharing attributes may not be
15837       //  listed in data-sharing attributes clauses, except for the cases
15838       //  listed below. For these exceptions only, listing a predetermined
15839       //  variable in a data-sharing attribute clause is allowed and overrides
15840       //  the variable's predetermined data-sharing attributes.
15841       // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
15842       // in a Construct, C/C++, p.2]
15843       //  Variables with const-qualified type having no mutable member may be
15844       //  listed in a firstprivate clause, even if they are static data members.
15845       if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr &&
15846           DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) {
15847         Diag(ELoc, diag::err_omp_wrong_dsa)
15848             << getOpenMPClauseName(DVar.CKind)
15849             << getOpenMPClauseName(OMPC_firstprivate);
15850         reportOriginalDsa(*this, DSAStack, D, DVar);
15851         continue;
15852       }
15853 
15854       // OpenMP [2.9.3.4, Restrictions, p.2]
15855       //  A list item that is private within a parallel region must not appear
15856       //  in a firstprivate clause on a worksharing construct if any of the
15857       //  worksharing regions arising from the worksharing construct ever bind
15858       //  to any of the parallel regions arising from the parallel construct.
15859       // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
15860       // A list item that is private within a teams region must not appear in a
15861       // firstprivate clause on a distribute construct if any of the distribute
15862       // regions arising from the distribute construct ever bind to any of the
15863       // teams regions arising from the teams construct.
15864       // OpenMP 4.5 [2.15.3.4, Restrictions, p.3]
15865       // A list item that appears in a reduction clause of a teams construct
15866       // must not appear in a firstprivate clause on a distribute construct if
15867       // any of the distribute regions arising from the distribute construct
15868       // ever bind to any of the teams regions arising from the teams construct.
15869       if ((isOpenMPWorksharingDirective(CurrDir) ||
15870            isOpenMPDistributeDirective(CurrDir)) &&
15871           !isOpenMPParallelDirective(CurrDir) &&
15872           !isOpenMPTeamsDirective(CurrDir)) {
15873         DVar = DSAStack->getImplicitDSA(D, true);
15874         if (DVar.CKind != OMPC_shared &&
15875             (isOpenMPParallelDirective(DVar.DKind) ||
15876              isOpenMPTeamsDirective(DVar.DKind) ||
15877              DVar.DKind == OMPD_unknown)) {
15878           Diag(ELoc, diag::err_omp_required_access)
15879               << getOpenMPClauseName(OMPC_firstprivate)
15880               << getOpenMPClauseName(OMPC_shared);
15881           reportOriginalDsa(*this, DSAStack, D, DVar);
15882           continue;
15883         }
15884       }
15885       // OpenMP [2.9.3.4, Restrictions, p.3]
15886       //  A list item that appears in a reduction clause of a parallel construct
15887       //  must not appear in a firstprivate clause on a worksharing or task
15888       //  construct if any of the worksharing or task regions arising from the
15889       //  worksharing or task construct ever bind to any of the parallel regions
15890       //  arising from the parallel construct.
15891       // OpenMP [2.9.3.4, Restrictions, p.4]
15892       //  A list item that appears in a reduction clause in worksharing
15893       //  construct must not appear in a firstprivate clause in a task construct
15894       //  encountered during execution of any of the worksharing regions arising
15895       //  from the worksharing construct.
15896       if (isOpenMPTaskingDirective(CurrDir)) {
15897         DVar = DSAStack->hasInnermostDSA(
15898             D,
15899             [](OpenMPClauseKind C, bool AppliedToPointee) {
15900               return C == OMPC_reduction && !AppliedToPointee;
15901             },
15902             [](OpenMPDirectiveKind K) {
15903               return isOpenMPParallelDirective(K) ||
15904                      isOpenMPWorksharingDirective(K) ||
15905                      isOpenMPTeamsDirective(K);
15906             },
15907             /*FromParent=*/true);
15908         if (DVar.CKind == OMPC_reduction &&
15909             (isOpenMPParallelDirective(DVar.DKind) ||
15910              isOpenMPWorksharingDirective(DVar.DKind) ||
15911              isOpenMPTeamsDirective(DVar.DKind))) {
15912           Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate)
15913               << getOpenMPDirectiveName(DVar.DKind);
15914           reportOriginalDsa(*this, DSAStack, D, DVar);
15915           continue;
15916         }
15917       }
15918 
15919       // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
15920       // A list item cannot appear in both a map clause and a data-sharing
15921       // attribute clause on the same construct
15922       //
15923       // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
15924       // A list item cannot appear in both a map clause and a data-sharing
15925       // attribute clause on the same construct unless the construct is a
15926       // combined construct.
15927       if ((LangOpts.OpenMP <= 45 &&
15928            isOpenMPTargetExecutionDirective(CurrDir)) ||
15929           CurrDir == OMPD_target) {
15930         OpenMPClauseKind ConflictKind;
15931         if (DSAStack->checkMappableExprComponentListsForDecl(
15932                 VD, /*CurrentRegionOnly=*/true,
15933                 [&ConflictKind](
15934                     OMPClauseMappableExprCommon::MappableExprComponentListRef,
15935                     OpenMPClauseKind WhereFoundClauseKind) {
15936                   ConflictKind = WhereFoundClauseKind;
15937                   return true;
15938                 })) {
15939           Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
15940               << getOpenMPClauseName(OMPC_firstprivate)
15941               << getOpenMPClauseName(ConflictKind)
15942               << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
15943           reportOriginalDsa(*this, DSAStack, D, DVar);
15944           continue;
15945         }
15946       }
15947     }
15948 
15949     // Variably modified types are not supported for tasks.
15950     if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() &&
15951         isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
15952       Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
15953           << getOpenMPClauseName(OMPC_firstprivate) << Type
15954           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
15955       bool IsDecl =
15956           !VD ||
15957           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
15958       Diag(D->getLocation(),
15959            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
15960           << D;
15961       continue;
15962     }
15963 
15964     Type = Type.getUnqualifiedType();
15965     VarDecl *VDPrivate =
15966         buildVarDecl(*this, ELoc, Type, D->getName(),
15967                      D->hasAttrs() ? &D->getAttrs() : nullptr,
15968                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
15969     // Generate helper private variable and initialize it with the value of the
15970     // original variable. The address of the original variable is replaced by
15971     // the address of the new private variable in the CodeGen. This new variable
15972     // is not added to IdResolver, so the code in the OpenMP region uses
15973     // original variable for proper diagnostics and variable capturing.
15974     Expr *VDInitRefExpr = nullptr;
15975     // For arrays generate initializer for single element and replace it by the
15976     // original array element in CodeGen.
15977     if (Type->isArrayType()) {
15978       VarDecl *VDInit =
15979           buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName());
15980       VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc);
15981       Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get();
15982       ElemType = ElemType.getUnqualifiedType();
15983       VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType,
15984                                          ".firstprivate.temp");
15985       InitializedEntity Entity =
15986           InitializedEntity::InitializeVariable(VDInitTemp);
15987       InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc);
15988 
15989       InitializationSequence InitSeq(*this, Entity, Kind, Init);
15990       ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init);
15991       if (Result.isInvalid())
15992         VDPrivate->setInvalidDecl();
15993       else
15994         VDPrivate->setInit(Result.getAs<Expr>());
15995       // Remove temp variable declaration.
15996       Context.Deallocate(VDInitTemp);
15997     } else {
15998       VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type,
15999                                      ".firstprivate.temp");
16000       VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(),
16001                                        RefExpr->getExprLoc());
16002       AddInitializerToDecl(VDPrivate,
16003                            DefaultLvalueConversion(VDInitRefExpr).get(),
16004                            /*DirectInit=*/false);
16005     }
16006     if (VDPrivate->isInvalidDecl()) {
16007       if (IsImplicitClause) {
16008         Diag(RefExpr->getExprLoc(),
16009              diag::note_omp_task_predetermined_firstprivate_here);
16010       }
16011       continue;
16012     }
16013     CurContext->addDecl(VDPrivate);
16014     DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
16015         *this, VDPrivate, RefExpr->getType().getUnqualifiedType(),
16016         RefExpr->getExprLoc());
16017     DeclRefExpr *Ref = nullptr;
16018     if (!VD && !CurContext->isDependentContext()) {
16019       if (TopDVar.CKind == OMPC_lastprivate) {
16020         Ref = TopDVar.PrivateCopy;
16021       } else {
16022         Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
16023         if (!isOpenMPCapturedDecl(D))
16024           ExprCaptures.push_back(Ref->getDecl());
16025       }
16026     }
16027     if (!IsImplicitClause)
16028       DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
16029     Vars.push_back((VD || CurContext->isDependentContext())
16030                        ? RefExpr->IgnoreParens()
16031                        : Ref);
16032     PrivateCopies.push_back(VDPrivateRefExpr);
16033     Inits.push_back(VDInitRefExpr);
16034   }
16035 
16036   if (Vars.empty())
16037     return nullptr;
16038 
16039   return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16040                                        Vars, PrivateCopies, Inits,
16041                                        buildPreInits(Context, ExprCaptures));
16042 }
16043 
ActOnOpenMPLastprivateClause(ArrayRef<Expr * > VarList,OpenMPLastprivateModifier LPKind,SourceLocation LPKindLoc,SourceLocation ColonLoc,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16044 OMPClause *Sema::ActOnOpenMPLastprivateClause(
16045     ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind,
16046     SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc,
16047     SourceLocation LParenLoc, SourceLocation EndLoc) {
16048   if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) {
16049     assert(ColonLoc.isValid() && "Colon location must be valid.");
16050     Diag(LPKindLoc, diag::err_omp_unexpected_clause_value)
16051         << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0,
16052                                    /*Last=*/OMPC_LASTPRIVATE_unknown)
16053         << getOpenMPClauseName(OMPC_lastprivate);
16054     return nullptr;
16055   }
16056 
16057   SmallVector<Expr *, 8> Vars;
16058   SmallVector<Expr *, 8> SrcExprs;
16059   SmallVector<Expr *, 8> DstExprs;
16060   SmallVector<Expr *, 8> AssignmentOps;
16061   SmallVector<Decl *, 4> ExprCaptures;
16062   SmallVector<Expr *, 4> ExprPostUpdates;
16063   for (Expr *RefExpr : VarList) {
16064     assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
16065     SourceLocation ELoc;
16066     SourceRange ERange;
16067     Expr *SimpleRefExpr = RefExpr;
16068     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
16069     if (Res.second) {
16070       // It will be analyzed later.
16071       Vars.push_back(RefExpr);
16072       SrcExprs.push_back(nullptr);
16073       DstExprs.push_back(nullptr);
16074       AssignmentOps.push_back(nullptr);
16075     }
16076     ValueDecl *D = Res.first;
16077     if (!D)
16078       continue;
16079 
16080     QualType Type = D->getType();
16081     auto *VD = dyn_cast<VarDecl>(D);
16082 
16083     // OpenMP [2.14.3.5, Restrictions, C/C++, p.2]
16084     //  A variable that appears in a lastprivate clause must not have an
16085     //  incomplete type or a reference type.
16086     if (RequireCompleteType(ELoc, Type,
16087                             diag::err_omp_lastprivate_incomplete_type))
16088       continue;
16089     Type = Type.getNonReferenceType();
16090 
16091     // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
16092     // A variable that is privatized must not have a const-qualified type
16093     // unless it is of class type with a mutable member. This restriction does
16094     // not apply to the firstprivate clause.
16095     //
16096     // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions]
16097     // A variable that appears in a lastprivate clause must not have a
16098     // const-qualified type unless it is of class type with a mutable member.
16099     if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc))
16100       continue;
16101 
16102     // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions]
16103     // A list item that appears in a lastprivate clause with the conditional
16104     // modifier must be a scalar variable.
16105     if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) {
16106       Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar);
16107       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
16108                                VarDecl::DeclarationOnly;
16109       Diag(D->getLocation(),
16110            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16111           << D;
16112       continue;
16113     }
16114 
16115     OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
16116     // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
16117     // in a Construct]
16118     //  Variables with the predetermined data-sharing attributes may not be
16119     //  listed in data-sharing attributes clauses, except for the cases
16120     //  listed below.
16121     // OpenMP 4.5 [2.10.8, Distribute Construct, p.3]
16122     // A list item may appear in a firstprivate or lastprivate clause but not
16123     // both.
16124     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
16125     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate &&
16126         (isOpenMPDistributeDirective(CurrDir) ||
16127          DVar.CKind != OMPC_firstprivate) &&
16128         (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) {
16129       Diag(ELoc, diag::err_omp_wrong_dsa)
16130           << getOpenMPClauseName(DVar.CKind)
16131           << getOpenMPClauseName(OMPC_lastprivate);
16132       reportOriginalDsa(*this, DSAStack, D, DVar);
16133       continue;
16134     }
16135 
16136     // OpenMP [2.14.3.5, Restrictions, p.2]
16137     // A list item that is private within a parallel region, or that appears in
16138     // the reduction clause of a parallel construct, must not appear in a
16139     // lastprivate clause on a worksharing construct if any of the corresponding
16140     // worksharing regions ever binds to any of the corresponding parallel
16141     // regions.
16142     DSAStackTy::DSAVarData TopDVar = DVar;
16143     if (isOpenMPWorksharingDirective(CurrDir) &&
16144         !isOpenMPParallelDirective(CurrDir) &&
16145         !isOpenMPTeamsDirective(CurrDir)) {
16146       DVar = DSAStack->getImplicitDSA(D, true);
16147       if (DVar.CKind != OMPC_shared) {
16148         Diag(ELoc, diag::err_omp_required_access)
16149             << getOpenMPClauseName(OMPC_lastprivate)
16150             << getOpenMPClauseName(OMPC_shared);
16151         reportOriginalDsa(*this, DSAStack, D, DVar);
16152         continue;
16153       }
16154     }
16155 
16156     // OpenMP [2.14.3.5, Restrictions, C++, p.1,2]
16157     //  A variable of class type (or array thereof) that appears in a
16158     //  lastprivate clause requires an accessible, unambiguous default
16159     //  constructor for the class type, unless the list item is also specified
16160     //  in a firstprivate clause.
16161     //  A variable of class type (or array thereof) that appears in a
16162     //  lastprivate clause requires an accessible, unambiguous copy assignment
16163     //  operator for the class type.
16164     Type = Context.getBaseElementType(Type).getNonReferenceType();
16165     VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(),
16166                                   Type.getUnqualifiedType(), ".lastprivate.src",
16167                                   D->hasAttrs() ? &D->getAttrs() : nullptr);
16168     DeclRefExpr *PseudoSrcExpr =
16169         buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc);
16170     VarDecl *DstVD =
16171         buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst",
16172                      D->hasAttrs() ? &D->getAttrs() : nullptr);
16173     DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
16174     // For arrays generate assignment operation for single element and replace
16175     // it by the original array element in CodeGen.
16176     ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign,
16177                                          PseudoDstExpr, PseudoSrcExpr);
16178     if (AssignmentOp.isInvalid())
16179       continue;
16180     AssignmentOp =
16181         ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
16182     if (AssignmentOp.isInvalid())
16183       continue;
16184 
16185     DeclRefExpr *Ref = nullptr;
16186     if (!VD && !CurContext->isDependentContext()) {
16187       if (TopDVar.CKind == OMPC_firstprivate) {
16188         Ref = TopDVar.PrivateCopy;
16189       } else {
16190         Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
16191         if (!isOpenMPCapturedDecl(D))
16192           ExprCaptures.push_back(Ref->getDecl());
16193       }
16194       if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) ||
16195           (!isOpenMPCapturedDecl(D) &&
16196            Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) {
16197         ExprResult RefRes = DefaultLvalueConversion(Ref);
16198         if (!RefRes.isUsable())
16199           continue;
16200         ExprResult PostUpdateRes =
16201             BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
16202                        RefRes.get());
16203         if (!PostUpdateRes.isUsable())
16204           continue;
16205         ExprPostUpdates.push_back(
16206             IgnoredValueConversions(PostUpdateRes.get()).get());
16207       }
16208     }
16209     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref);
16210     Vars.push_back((VD || CurContext->isDependentContext())
16211                        ? RefExpr->IgnoreParens()
16212                        : Ref);
16213     SrcExprs.push_back(PseudoSrcExpr);
16214     DstExprs.push_back(PseudoDstExpr);
16215     AssignmentOps.push_back(AssignmentOp.get());
16216   }
16217 
16218   if (Vars.empty())
16219     return nullptr;
16220 
16221   return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
16222                                       Vars, SrcExprs, DstExprs, AssignmentOps,
16223                                       LPKind, LPKindLoc, ColonLoc,
16224                                       buildPreInits(Context, ExprCaptures),
16225                                       buildPostUpdate(*this, ExprPostUpdates));
16226 }
16227 
ActOnOpenMPSharedClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)16228 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList,
16229                                          SourceLocation StartLoc,
16230                                          SourceLocation LParenLoc,
16231                                          SourceLocation EndLoc) {
16232   SmallVector<Expr *, 8> Vars;
16233   for (Expr *RefExpr : VarList) {
16234     assert(RefExpr && "NULL expr in OpenMP lastprivate clause.");
16235     SourceLocation ELoc;
16236     SourceRange ERange;
16237     Expr *SimpleRefExpr = RefExpr;
16238     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
16239     if (Res.second) {
16240       // It will be analyzed later.
16241       Vars.push_back(RefExpr);
16242     }
16243     ValueDecl *D = Res.first;
16244     if (!D)
16245       continue;
16246 
16247     auto *VD = dyn_cast<VarDecl>(D);
16248     // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced
16249     // in a Construct]
16250     //  Variables with the predetermined data-sharing attributes may not be
16251     //  listed in data-sharing attributes clauses, except for the cases
16252     //  listed below. For these exceptions only, listing a predetermined
16253     //  variable in a data-sharing attribute clause is allowed and overrides
16254     //  the variable's predetermined data-sharing attributes.
16255     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
16256     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared &&
16257         DVar.RefExpr) {
16258       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
16259                                           << getOpenMPClauseName(OMPC_shared);
16260       reportOriginalDsa(*this, DSAStack, D, DVar);
16261       continue;
16262     }
16263 
16264     DeclRefExpr *Ref = nullptr;
16265     if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext())
16266       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
16267     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref);
16268     Vars.push_back((VD || !Ref || CurContext->isDependentContext())
16269                        ? RefExpr->IgnoreParens()
16270                        : Ref);
16271   }
16272 
16273   if (Vars.empty())
16274     return nullptr;
16275 
16276   return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
16277 }
16278 
16279 namespace {
16280 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> {
16281   DSAStackTy *Stack;
16282 
16283 public:
VisitDeclRefExpr(DeclRefExpr * E)16284   bool VisitDeclRefExpr(DeclRefExpr *E) {
16285     if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) {
16286       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false);
16287       if (DVar.CKind == OMPC_shared && !DVar.RefExpr)
16288         return false;
16289       if (DVar.CKind != OMPC_unknown)
16290         return true;
16291       DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA(
16292           VD,
16293           [](OpenMPClauseKind C, bool AppliedToPointee) {
16294             return isOpenMPPrivate(C) && !AppliedToPointee;
16295           },
16296           [](OpenMPDirectiveKind) { return true; },
16297           /*FromParent=*/true);
16298       return DVarPrivate.CKind != OMPC_unknown;
16299     }
16300     return false;
16301   }
VisitStmt(Stmt * S)16302   bool VisitStmt(Stmt *S) {
16303     for (Stmt *Child : S->children()) {
16304       if (Child && Visit(Child))
16305         return true;
16306     }
16307     return false;
16308   }
DSARefChecker(DSAStackTy * S)16309   explicit DSARefChecker(DSAStackTy *S) : Stack(S) {}
16310 };
16311 } // namespace
16312 
16313 namespace {
16314 // Transform MemberExpression for specified FieldDecl of current class to
16315 // DeclRefExpr to specified OMPCapturedExprDecl.
16316 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> {
16317   typedef TreeTransform<TransformExprToCaptures> BaseTransform;
16318   ValueDecl *Field = nullptr;
16319   DeclRefExpr *CapturedExpr = nullptr;
16320 
16321 public:
TransformExprToCaptures(Sema & SemaRef,ValueDecl * FieldDecl)16322   TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl)
16323       : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {}
16324 
TransformMemberExpr(MemberExpr * E)16325   ExprResult TransformMemberExpr(MemberExpr *E) {
16326     if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) &&
16327         E->getMemberDecl() == Field) {
16328       CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false);
16329       return CapturedExpr;
16330     }
16331     return BaseTransform::TransformMemberExpr(E);
16332   }
getCapturedExpr()16333   DeclRefExpr *getCapturedExpr() { return CapturedExpr; }
16334 };
16335 } // namespace
16336 
16337 template <typename T, typename U>
filterLookupForUDReductionAndMapper(SmallVectorImpl<U> & Lookups,const llvm::function_ref<T (ValueDecl *)> Gen)16338 static T filterLookupForUDReductionAndMapper(
16339     SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) {
16340   for (U &Set : Lookups) {
16341     for (auto *D : Set) {
16342       if (T Res = Gen(cast<ValueDecl>(D)))
16343         return Res;
16344     }
16345   }
16346   return T();
16347 }
16348 
findAcceptableDecl(Sema & SemaRef,NamedDecl * D)16349 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) {
16350   assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case");
16351 
16352   for (auto RD : D->redecls()) {
16353     // Don't bother with extra checks if we already know this one isn't visible.
16354     if (RD == D)
16355       continue;
16356 
16357     auto ND = cast<NamedDecl>(RD);
16358     if (LookupResult::isVisible(SemaRef, ND))
16359       return ND;
16360   }
16361 
16362   return nullptr;
16363 }
16364 
16365 static void
argumentDependentLookup(Sema & SemaRef,const DeclarationNameInfo & Id,SourceLocation Loc,QualType Ty,SmallVectorImpl<UnresolvedSet<8>> & Lookups)16366 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id,
16367                         SourceLocation Loc, QualType Ty,
16368                         SmallVectorImpl<UnresolvedSet<8>> &Lookups) {
16369   // Find all of the associated namespaces and classes based on the
16370   // arguments we have.
16371   Sema::AssociatedNamespaceSet AssociatedNamespaces;
16372   Sema::AssociatedClassSet AssociatedClasses;
16373   OpaqueValueExpr OVE(Loc, Ty, VK_LValue);
16374   SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces,
16375                                              AssociatedClasses);
16376 
16377   // C++ [basic.lookup.argdep]p3:
16378   //   Let X be the lookup set produced by unqualified lookup (3.4.1)
16379   //   and let Y be the lookup set produced by argument dependent
16380   //   lookup (defined as follows). If X contains [...] then Y is
16381   //   empty. Otherwise Y is the set of declarations found in the
16382   //   namespaces associated with the argument types as described
16383   //   below. The set of declarations found by the lookup of the name
16384   //   is the union of X and Y.
16385   //
16386   // Here, we compute Y and add its members to the overloaded
16387   // candidate set.
16388   for (auto *NS : AssociatedNamespaces) {
16389     //   When considering an associated namespace, the lookup is the
16390     //   same as the lookup performed when the associated namespace is
16391     //   used as a qualifier (3.4.3.2) except that:
16392     //
16393     //     -- Any using-directives in the associated namespace are
16394     //        ignored.
16395     //
16396     //     -- Any namespace-scope friend functions declared in
16397     //        associated classes are visible within their respective
16398     //        namespaces even if they are not visible during an ordinary
16399     //        lookup (11.4).
16400     DeclContext::lookup_result R = NS->lookup(Id.getName());
16401     for (auto *D : R) {
16402       auto *Underlying = D;
16403       if (auto *USD = dyn_cast<UsingShadowDecl>(D))
16404         Underlying = USD->getTargetDecl();
16405 
16406       if (!isa<OMPDeclareReductionDecl>(Underlying) &&
16407           !isa<OMPDeclareMapperDecl>(Underlying))
16408         continue;
16409 
16410       if (!SemaRef.isVisible(D)) {
16411         D = findAcceptableDecl(SemaRef, D);
16412         if (!D)
16413           continue;
16414         if (auto *USD = dyn_cast<UsingShadowDecl>(D))
16415           Underlying = USD->getTargetDecl();
16416       }
16417       Lookups.emplace_back();
16418       Lookups.back().addDecl(Underlying);
16419     }
16420   }
16421 }
16422 
16423 static ExprResult
buildDeclareReductionRef(Sema & SemaRef,SourceLocation Loc,SourceRange Range,Scope * S,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,QualType Ty,CXXCastPath & BasePath,Expr * UnresolvedReduction)16424 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
16425                          Scope *S, CXXScopeSpec &ReductionIdScopeSpec,
16426                          const DeclarationNameInfo &ReductionId, QualType Ty,
16427                          CXXCastPath &BasePath, Expr *UnresolvedReduction) {
16428   if (ReductionIdScopeSpec.isInvalid())
16429     return ExprError();
16430   SmallVector<UnresolvedSet<8>, 4> Lookups;
16431   if (S) {
16432     LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
16433     Lookup.suppressDiagnostics();
16434     while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) {
16435       NamedDecl *D = Lookup.getRepresentativeDecl();
16436       do {
16437         S = S->getParent();
16438       } while (S && !S->isDeclScope(D));
16439       if (S)
16440         S = S->getParent();
16441       Lookups.emplace_back();
16442       Lookups.back().append(Lookup.begin(), Lookup.end());
16443       Lookup.clear();
16444     }
16445   } else if (auto *ULE =
16446                  cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) {
16447     Lookups.push_back(UnresolvedSet<8>());
16448     Decl *PrevD = nullptr;
16449     for (NamedDecl *D : ULE->decls()) {
16450       if (D == PrevD)
16451         Lookups.push_back(UnresolvedSet<8>());
16452       else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D))
16453         Lookups.back().addDecl(DRD);
16454       PrevD = D;
16455     }
16456   }
16457   if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() ||
16458       Ty->isInstantiationDependentType() ||
16459       Ty->containsUnexpandedParameterPack() ||
16460       filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
16461         return !D->isInvalidDecl() &&
16462                (D->getType()->isDependentType() ||
16463                 D->getType()->isInstantiationDependentType() ||
16464                 D->getType()->containsUnexpandedParameterPack());
16465       })) {
16466     UnresolvedSet<8> ResSet;
16467     for (const UnresolvedSet<8> &Set : Lookups) {
16468       if (Set.empty())
16469         continue;
16470       ResSet.append(Set.begin(), Set.end());
16471       // The last item marks the end of all declarations at the specified scope.
16472       ResSet.addDecl(Set[Set.size() - 1]);
16473     }
16474     return UnresolvedLookupExpr::Create(
16475         SemaRef.Context, /*NamingClass=*/nullptr,
16476         ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId,
16477         /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end());
16478   }
16479   // Lookup inside the classes.
16480   // C++ [over.match.oper]p3:
16481   //   For a unary operator @ with an operand of a type whose
16482   //   cv-unqualified version is T1, and for a binary operator @ with
16483   //   a left operand of a type whose cv-unqualified version is T1 and
16484   //   a right operand of a type whose cv-unqualified version is T2,
16485   //   three sets of candidate functions, designated member
16486   //   candidates, non-member candidates and built-in candidates, are
16487   //   constructed as follows:
16488   //     -- If T1 is a complete class type or a class currently being
16489   //        defined, the set of member candidates is the result of the
16490   //        qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
16491   //        the set of member candidates is empty.
16492   LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName);
16493   Lookup.suppressDiagnostics();
16494   if (const auto *TyRec = Ty->getAs<RecordType>()) {
16495     // Complete the type if it can be completed.
16496     // If the type is neither complete nor being defined, bail out now.
16497     if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
16498         TyRec->getDecl()->getDefinition()) {
16499       Lookup.clear();
16500       SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
16501       if (Lookup.empty()) {
16502         Lookups.emplace_back();
16503         Lookups.back().append(Lookup.begin(), Lookup.end());
16504       }
16505     }
16506   }
16507   // Perform ADL.
16508   if (SemaRef.getLangOpts().CPlusPlus)
16509     argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups);
16510   if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
16511           Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * {
16512             if (!D->isInvalidDecl() &&
16513                 SemaRef.Context.hasSameType(D->getType(), Ty))
16514               return D;
16515             return nullptr;
16516           }))
16517     return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(),
16518                                     VK_LValue, Loc);
16519   if (SemaRef.getLangOpts().CPlusPlus) {
16520     if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
16521             Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * {
16522               if (!D->isInvalidDecl() &&
16523                   SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) &&
16524                   !Ty.isMoreQualifiedThan(D->getType()))
16525                 return D;
16526               return nullptr;
16527             })) {
16528       CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
16529                          /*DetectVirtual=*/false);
16530       if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) {
16531         if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
16532                 VD->getType().getUnqualifiedType()))) {
16533           if (SemaRef.CheckBaseClassAccess(
16534                   Loc, VD->getType(), Ty, Paths.front(),
16535                   /*DiagID=*/0) != Sema::AR_inaccessible) {
16536             SemaRef.BuildBasePathArray(Paths, BasePath);
16537             return SemaRef.BuildDeclRefExpr(
16538                 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc);
16539           }
16540         }
16541       }
16542     }
16543   }
16544   if (ReductionIdScopeSpec.isSet()) {
16545     SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier)
16546         << Ty << Range;
16547     return ExprError();
16548   }
16549   return ExprEmpty();
16550 }
16551 
16552 namespace {
16553 /// Data for the reduction-based clauses.
16554 struct ReductionData {
16555   /// List of original reduction items.
16556   SmallVector<Expr *, 8> Vars;
16557   /// List of private copies of the reduction items.
16558   SmallVector<Expr *, 8> Privates;
16559   /// LHS expressions for the reduction_op expressions.
16560   SmallVector<Expr *, 8> LHSs;
16561   /// RHS expressions for the reduction_op expressions.
16562   SmallVector<Expr *, 8> RHSs;
16563   /// Reduction operation expression.
16564   SmallVector<Expr *, 8> ReductionOps;
16565   /// inscan copy operation expressions.
16566   SmallVector<Expr *, 8> InscanCopyOps;
16567   /// inscan copy temp array expressions for prefix sums.
16568   SmallVector<Expr *, 8> InscanCopyArrayTemps;
16569   /// inscan copy temp array element expressions for prefix sums.
16570   SmallVector<Expr *, 8> InscanCopyArrayElems;
16571   /// Taskgroup descriptors for the corresponding reduction items in
16572   /// in_reduction clauses.
16573   SmallVector<Expr *, 8> TaskgroupDescriptors;
16574   /// List of captures for clause.
16575   SmallVector<Decl *, 4> ExprCaptures;
16576   /// List of postupdate expressions.
16577   SmallVector<Expr *, 4> ExprPostUpdates;
16578   /// Reduction modifier.
16579   unsigned RedModifier = 0;
16580   ReductionData() = delete;
16581   /// Reserves required memory for the reduction data.
ReductionData__anondf8189525311::ReductionData16582   ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) {
16583     Vars.reserve(Size);
16584     Privates.reserve(Size);
16585     LHSs.reserve(Size);
16586     RHSs.reserve(Size);
16587     ReductionOps.reserve(Size);
16588     if (RedModifier == OMPC_REDUCTION_inscan) {
16589       InscanCopyOps.reserve(Size);
16590       InscanCopyArrayTemps.reserve(Size);
16591       InscanCopyArrayElems.reserve(Size);
16592     }
16593     TaskgroupDescriptors.reserve(Size);
16594     ExprCaptures.reserve(Size);
16595     ExprPostUpdates.reserve(Size);
16596   }
16597   /// Stores reduction item and reduction operation only (required for dependent
16598   /// reduction item).
push__anondf8189525311::ReductionData16599   void push(Expr *Item, Expr *ReductionOp) {
16600     Vars.emplace_back(Item);
16601     Privates.emplace_back(nullptr);
16602     LHSs.emplace_back(nullptr);
16603     RHSs.emplace_back(nullptr);
16604     ReductionOps.emplace_back(ReductionOp);
16605     TaskgroupDescriptors.emplace_back(nullptr);
16606     if (RedModifier == OMPC_REDUCTION_inscan) {
16607       InscanCopyOps.push_back(nullptr);
16608       InscanCopyArrayTemps.push_back(nullptr);
16609       InscanCopyArrayElems.push_back(nullptr);
16610     }
16611   }
16612   /// Stores reduction data.
push__anondf8189525311::ReductionData16613   void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp,
16614             Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp,
16615             Expr *CopyArrayElem) {
16616     Vars.emplace_back(Item);
16617     Privates.emplace_back(Private);
16618     LHSs.emplace_back(LHS);
16619     RHSs.emplace_back(RHS);
16620     ReductionOps.emplace_back(ReductionOp);
16621     TaskgroupDescriptors.emplace_back(TaskgroupDescriptor);
16622     if (RedModifier == OMPC_REDUCTION_inscan) {
16623       InscanCopyOps.push_back(CopyOp);
16624       InscanCopyArrayTemps.push_back(CopyArrayTemp);
16625       InscanCopyArrayElems.push_back(CopyArrayElem);
16626     } else {
16627       assert(CopyOp == nullptr && CopyArrayTemp == nullptr &&
16628              CopyArrayElem == nullptr &&
16629              "Copy operation must be used for inscan reductions only.");
16630     }
16631   }
16632 };
16633 } // namespace
16634 
checkOMPArraySectionConstantForReduction(ASTContext & Context,const OMPArraySectionExpr * OASE,bool & SingleElement,SmallVectorImpl<llvm::APSInt> & ArraySizes)16635 static bool checkOMPArraySectionConstantForReduction(
16636     ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement,
16637     SmallVectorImpl<llvm::APSInt> &ArraySizes) {
16638   const Expr *Length = OASE->getLength();
16639   if (Length == nullptr) {
16640     // For array sections of the form [1:] or [:], we would need to analyze
16641     // the lower bound...
16642     if (OASE->getColonLocFirst().isValid())
16643       return false;
16644 
16645     // This is an array subscript which has implicit length 1!
16646     SingleElement = true;
16647     ArraySizes.push_back(llvm::APSInt::get(1));
16648   } else {
16649     Expr::EvalResult Result;
16650     if (!Length->EvaluateAsInt(Result, Context))
16651       return false;
16652 
16653     llvm::APSInt ConstantLengthValue = Result.Val.getInt();
16654     SingleElement = (ConstantLengthValue.getSExtValue() == 1);
16655     ArraySizes.push_back(ConstantLengthValue);
16656   }
16657 
16658   // Get the base of this array section and walk up from there.
16659   const Expr *Base = OASE->getBase()->IgnoreParenImpCasts();
16660 
16661   // We require length = 1 for all array sections except the right-most to
16662   // guarantee that the memory region is contiguous and has no holes in it.
16663   while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) {
16664     Length = TempOASE->getLength();
16665     if (Length == nullptr) {
16666       // For array sections of the form [1:] or [:], we would need to analyze
16667       // the lower bound...
16668       if (OASE->getColonLocFirst().isValid())
16669         return false;
16670 
16671       // This is an array subscript which has implicit length 1!
16672       ArraySizes.push_back(llvm::APSInt::get(1));
16673     } else {
16674       Expr::EvalResult Result;
16675       if (!Length->EvaluateAsInt(Result, Context))
16676         return false;
16677 
16678       llvm::APSInt ConstantLengthValue = Result.Val.getInt();
16679       if (ConstantLengthValue.getSExtValue() != 1)
16680         return false;
16681 
16682       ArraySizes.push_back(ConstantLengthValue);
16683     }
16684     Base = TempOASE->getBase()->IgnoreParenImpCasts();
16685   }
16686 
16687   // If we have a single element, we don't need to add the implicit lengths.
16688   if (!SingleElement) {
16689     while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) {
16690       // Has implicit length 1!
16691       ArraySizes.push_back(llvm::APSInt::get(1));
16692       Base = TempASE->getBase()->IgnoreParenImpCasts();
16693     }
16694   }
16695 
16696   // This array section can be privatized as a single value or as a constant
16697   // sized array.
16698   return true;
16699 }
16700 
16701 static BinaryOperatorKind
getRelatedCompoundReductionOp(BinaryOperatorKind BOK)16702 getRelatedCompoundReductionOp(BinaryOperatorKind BOK) {
16703   if (BOK == BO_Add)
16704     return BO_AddAssign;
16705   if (BOK == BO_Mul)
16706     return BO_MulAssign;
16707   if (BOK == BO_And)
16708     return BO_AndAssign;
16709   if (BOK == BO_Or)
16710     return BO_OrAssign;
16711   if (BOK == BO_Xor)
16712     return BO_XorAssign;
16713   return BOK;
16714 }
16715 
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)16716 static bool actOnOMPReductionKindClause(
16717     Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
16718     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
16719     SourceLocation ColonLoc, SourceLocation EndLoc,
16720     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
16721     ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
16722   DeclarationName DN = ReductionId.getName();
16723   OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator();
16724   BinaryOperatorKind BOK = BO_Comma;
16725 
16726   ASTContext &Context = S.Context;
16727   // OpenMP [2.14.3.6, reduction clause]
16728   // C
16729   // reduction-identifier is either an identifier or one of the following
16730   // operators: +, -, *,  &, |, ^, && and ||
16731   // C++
16732   // reduction-identifier is either an id-expression or one of the following
16733   // operators: +, -, *, &, |, ^, && and ||
16734   switch (OOK) {
16735   case OO_Plus:
16736   case OO_Minus:
16737     BOK = BO_Add;
16738     break;
16739   case OO_Star:
16740     BOK = BO_Mul;
16741     break;
16742   case OO_Amp:
16743     BOK = BO_And;
16744     break;
16745   case OO_Pipe:
16746     BOK = BO_Or;
16747     break;
16748   case OO_Caret:
16749     BOK = BO_Xor;
16750     break;
16751   case OO_AmpAmp:
16752     BOK = BO_LAnd;
16753     break;
16754   case OO_PipePipe:
16755     BOK = BO_LOr;
16756     break;
16757   case OO_New:
16758   case OO_Delete:
16759   case OO_Array_New:
16760   case OO_Array_Delete:
16761   case OO_Slash:
16762   case OO_Percent:
16763   case OO_Tilde:
16764   case OO_Exclaim:
16765   case OO_Equal:
16766   case OO_Less:
16767   case OO_Greater:
16768   case OO_LessEqual:
16769   case OO_GreaterEqual:
16770   case OO_PlusEqual:
16771   case OO_MinusEqual:
16772   case OO_StarEqual:
16773   case OO_SlashEqual:
16774   case OO_PercentEqual:
16775   case OO_CaretEqual:
16776   case OO_AmpEqual:
16777   case OO_PipeEqual:
16778   case OO_LessLess:
16779   case OO_GreaterGreater:
16780   case OO_LessLessEqual:
16781   case OO_GreaterGreaterEqual:
16782   case OO_EqualEqual:
16783   case OO_ExclaimEqual:
16784   case OO_Spaceship:
16785   case OO_PlusPlus:
16786   case OO_MinusMinus:
16787   case OO_Comma:
16788   case OO_ArrowStar:
16789   case OO_Arrow:
16790   case OO_Call:
16791   case OO_Subscript:
16792   case OO_Conditional:
16793   case OO_Coawait:
16794   case NUM_OVERLOADED_OPERATORS:
16795     llvm_unreachable("Unexpected reduction identifier");
16796   case OO_None:
16797     if (IdentifierInfo *II = DN.getAsIdentifierInfo()) {
16798       if (II->isStr("max"))
16799         BOK = BO_GT;
16800       else if (II->isStr("min"))
16801         BOK = BO_LT;
16802     }
16803     break;
16804   }
16805   SourceRange ReductionIdRange;
16806   if (ReductionIdScopeSpec.isValid())
16807     ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
16808   else
16809     ReductionIdRange.setBegin(ReductionId.getBeginLoc());
16810   ReductionIdRange.setEnd(ReductionId.getEndLoc());
16811 
16812   auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
16813   bool FirstIter = true;
16814   for (Expr *RefExpr : VarList) {
16815     assert(RefExpr && "nullptr expr in OpenMP reduction clause.");
16816     // OpenMP [2.1, C/C++]
16817     //  A list item is a variable or array section, subject to the restrictions
16818     //  specified in Section 2.4 on page 42 and in each of the sections
16819     // describing clauses and directives for which a list appears.
16820     // OpenMP  [2.14.3.3, Restrictions, p.1]
16821     //  A variable that is part of another variable (as an array or
16822     //  structure element) cannot appear in a private clause.
16823     if (!FirstIter && IR != ER)
16824       ++IR;
16825     FirstIter = false;
16826     SourceLocation ELoc;
16827     SourceRange ERange;
16828     Expr *SimpleRefExpr = RefExpr;
16829     auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
16830                               /*AllowArraySection=*/true);
16831     if (Res.second) {
16832       // Try to find 'declare reduction' corresponding construct before using
16833       // builtin/overloaded operators.
16834       QualType Type = Context.DependentTy;
16835       CXXCastPath BasePath;
16836       ExprResult DeclareReductionRef = buildDeclareReductionRef(
16837           S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
16838           ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
16839       Expr *ReductionOp = nullptr;
16840       if (S.CurContext->isDependentContext() &&
16841           (DeclareReductionRef.isUnset() ||
16842            isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
16843         ReductionOp = DeclareReductionRef.get();
16844       // It will be analyzed later.
16845       RD.push(RefExpr, ReductionOp);
16846     }
16847     ValueDecl *D = Res.first;
16848     if (!D)
16849       continue;
16850 
16851     Expr *TaskgroupDescriptor = nullptr;
16852     QualType Type;
16853     auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens());
16854     auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens());
16855     if (ASE) {
16856       Type = ASE->getType().getNonReferenceType();
16857     } else if (OASE) {
16858       QualType BaseType =
16859           OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
16860       if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
16861         Type = ATy->getElementType();
16862       else
16863         Type = BaseType->getPointeeType();
16864       Type = Type.getNonReferenceType();
16865     } else {
16866       Type = Context.getBaseElementType(D->getType().getNonReferenceType());
16867     }
16868     auto *VD = dyn_cast<VarDecl>(D);
16869 
16870     // OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
16871     //  A variable that appears in a private clause must not have an incomplete
16872     //  type or a reference type.
16873     if (S.RequireCompleteType(ELoc, D->getType(),
16874                               diag::err_omp_reduction_incomplete_type))
16875       continue;
16876     // OpenMP [2.14.3.6, reduction clause, Restrictions]
16877     // A list item that appears in a reduction clause must not be
16878     // const-qualified.
16879     if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc,
16880                                   /*AcceptIfMutable*/ false, ASE || OASE))
16881       continue;
16882 
16883     OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
16884     // OpenMP [2.9.3.6, Restrictions, C/C++, p.4]
16885     //  If a list-item is a reference type then it must bind to the same object
16886     //  for all threads of the team.
16887     if (!ASE && !OASE) {
16888       if (VD) {
16889         VarDecl *VDDef = VD->getDefinition();
16890         if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
16891           DSARefChecker Check(Stack);
16892           if (Check.Visit(VDDef->getInit())) {
16893             S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
16894                 << getOpenMPClauseName(ClauseKind) << ERange;
16895             S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
16896             continue;
16897           }
16898         }
16899       }
16900 
16901       // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced
16902       // in a Construct]
16903       //  Variables with the predetermined data-sharing attributes may not be
16904       //  listed in data-sharing attributes clauses, except for the cases
16905       //  listed below. For these exceptions only, listing a predetermined
16906       //  variable in a data-sharing attribute clause is allowed and overrides
16907       //  the variable's predetermined data-sharing attributes.
16908       // OpenMP [2.14.3.6, Restrictions, p.3]
16909       //  Any number of reduction clauses can be specified on the directive,
16910       //  but a list item can appear only once in the reduction clauses for that
16911       //  directive.
16912       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
16913       if (DVar.CKind == OMPC_reduction) {
16914         S.Diag(ELoc, diag::err_omp_once_referenced)
16915             << getOpenMPClauseName(ClauseKind);
16916         if (DVar.RefExpr)
16917           S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
16918         continue;
16919       }
16920       if (DVar.CKind != OMPC_unknown) {
16921         S.Diag(ELoc, diag::err_omp_wrong_dsa)
16922             << getOpenMPClauseName(DVar.CKind)
16923             << getOpenMPClauseName(OMPC_reduction);
16924         reportOriginalDsa(S, Stack, D, DVar);
16925         continue;
16926       }
16927 
16928       // OpenMP [2.14.3.6, Restrictions, p.1]
16929       //  A list item that appears in a reduction clause of a worksharing
16930       //  construct must be shared in the parallel regions to which any of the
16931       //  worksharing regions arising from the worksharing construct bind.
16932       if (isOpenMPWorksharingDirective(CurrDir) &&
16933           !isOpenMPParallelDirective(CurrDir) &&
16934           !isOpenMPTeamsDirective(CurrDir)) {
16935         DVar = Stack->getImplicitDSA(D, true);
16936         if (DVar.CKind != OMPC_shared) {
16937           S.Diag(ELoc, diag::err_omp_required_access)
16938               << getOpenMPClauseName(OMPC_reduction)
16939               << getOpenMPClauseName(OMPC_shared);
16940           reportOriginalDsa(S, Stack, D, DVar);
16941           continue;
16942         }
16943       }
16944     } else {
16945       // Threadprivates cannot be shared between threads, so dignose if the base
16946       // is a threadprivate variable.
16947       DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false);
16948       if (DVar.CKind == OMPC_threadprivate) {
16949         S.Diag(ELoc, diag::err_omp_wrong_dsa)
16950             << getOpenMPClauseName(DVar.CKind)
16951             << getOpenMPClauseName(OMPC_reduction);
16952         reportOriginalDsa(S, Stack, D, DVar);
16953         continue;
16954       }
16955     }
16956 
16957     // Try to find 'declare reduction' corresponding construct before using
16958     // builtin/overloaded operators.
16959     CXXCastPath BasePath;
16960     ExprResult DeclareReductionRef = buildDeclareReductionRef(
16961         S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
16962         ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
16963     if (DeclareReductionRef.isInvalid())
16964       continue;
16965     if (S.CurContext->isDependentContext() &&
16966         (DeclareReductionRef.isUnset() ||
16967          isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
16968       RD.push(RefExpr, DeclareReductionRef.get());
16969       continue;
16970     }
16971     if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
16972       // Not allowed reduction identifier is found.
16973       S.Diag(ReductionId.getBeginLoc(),
16974              diag::err_omp_unknown_reduction_identifier)
16975           << Type << ReductionIdRange;
16976       continue;
16977     }
16978 
16979     // OpenMP [2.14.3.6, reduction clause, Restrictions]
16980     // The type of a list item that appears in a reduction clause must be valid
16981     // for the reduction-identifier. For a max or min reduction in C, the type
16982     // of the list item must be an allowed arithmetic data type: char, int,
16983     // float, double, or _Bool, possibly modified with long, short, signed, or
16984     // unsigned. For a max or min reduction in C++, the type of the list item
16985     // must be an allowed arithmetic data type: char, wchar_t, int, float,
16986     // double, or bool, possibly modified with long, short, signed, or unsigned.
16987     if (DeclareReductionRef.isUnset()) {
16988       if ((BOK == BO_GT || BOK == BO_LT) &&
16989           !(Type->isScalarType() ||
16990             (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
16991         S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
16992             << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
16993         if (!ASE && !OASE) {
16994           bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
16995                                    VarDecl::DeclarationOnly;
16996           S.Diag(D->getLocation(),
16997                  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
16998               << D;
16999         }
17000         continue;
17001       }
17002       if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
17003           !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
17004         S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
17005             << getOpenMPClauseName(ClauseKind);
17006         if (!ASE && !OASE) {
17007           bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
17008                                    VarDecl::DeclarationOnly;
17009           S.Diag(D->getLocation(),
17010                  IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17011               << D;
17012         }
17013         continue;
17014       }
17015     }
17016 
17017     Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
17018     VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
17019                                   D->hasAttrs() ? &D->getAttrs() : nullptr);
17020     VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
17021                                   D->hasAttrs() ? &D->getAttrs() : nullptr);
17022     QualType PrivateTy = Type;
17023 
17024     // Try if we can determine constant lengths for all array sections and avoid
17025     // the VLA.
17026     bool ConstantLengthOASE = false;
17027     if (OASE) {
17028       bool SingleElement;
17029       llvm::SmallVector<llvm::APSInt, 4> ArraySizes;
17030       ConstantLengthOASE = checkOMPArraySectionConstantForReduction(
17031           Context, OASE, SingleElement, ArraySizes);
17032 
17033       // If we don't have a single element, we must emit a constant array type.
17034       if (ConstantLengthOASE && !SingleElement) {
17035         for (llvm::APSInt &Size : ArraySizes)
17036           PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr,
17037                                                    ArrayType::Normal,
17038                                                    /*IndexTypeQuals=*/0);
17039       }
17040     }
17041 
17042     if ((OASE && !ConstantLengthOASE) ||
17043         (!OASE && !ASE &&
17044          D->getType().getNonReferenceType()->isVariablyModifiedType())) {
17045       if (!Context.getTargetInfo().isVLASupported()) {
17046         if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) {
17047           S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
17048           S.Diag(ELoc, diag::note_vla_unsupported);
17049           continue;
17050         } else {
17051           S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE;
17052           S.targetDiag(ELoc, diag::note_vla_unsupported);
17053         }
17054       }
17055       // For arrays/array sections only:
17056       // Create pseudo array type for private copy. The size for this array will
17057       // be generated during codegen.
17058       // For array subscripts or single variables Private Ty is the same as Type
17059       // (type of the variable or single array element).
17060       PrivateTy = Context.getVariableArrayType(
17061           Type,
17062           new (Context)
17063               OpaqueValueExpr(ELoc, Context.getSizeType(), VK_PRValue),
17064           ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
17065     } else if (!ASE && !OASE &&
17066                Context.getAsArrayType(D->getType().getNonReferenceType())) {
17067       PrivateTy = D->getType().getNonReferenceType();
17068     }
17069     // Private copy.
17070     VarDecl *PrivateVD =
17071         buildVarDecl(S, ELoc, PrivateTy, D->getName(),
17072                      D->hasAttrs() ? &D->getAttrs() : nullptr,
17073                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
17074     // Add initializer for private variable.
17075     Expr *Init = nullptr;
17076     DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
17077     DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
17078     if (DeclareReductionRef.isUsable()) {
17079       auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
17080       auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
17081       if (DRD->getInitializer()) {
17082         Init = DRDRef;
17083         RHSVD->setInit(DRDRef);
17084         RHSVD->setInitStyle(VarDecl::CallInit);
17085       }
17086     } else {
17087       switch (BOK) {
17088       case BO_Add:
17089       case BO_Xor:
17090       case BO_Or:
17091       case BO_LOr:
17092         // '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
17093         if (Type->isScalarType() || Type->isAnyComplexType())
17094           Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
17095         break;
17096       case BO_Mul:
17097       case BO_LAnd:
17098         if (Type->isScalarType() || Type->isAnyComplexType()) {
17099           // '*' and '&&' reduction ops - initializer is '1'.
17100           Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
17101         }
17102         break;
17103       case BO_And: {
17104         // '&' reduction op - initializer is '~0'.
17105         QualType OrigType = Type;
17106         if (auto *ComplexTy = OrigType->getAs<ComplexType>())
17107           Type = ComplexTy->getElementType();
17108         if (Type->isRealFloatingType()) {
17109           llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue(
17110               Context.getFloatTypeSemantics(Type),
17111               Context.getTypeSize(Type));
17112           Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
17113                                          Type, ELoc);
17114         } else if (Type->isScalarType()) {
17115           uint64_t Size = Context.getTypeSize(Type);
17116           QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0);
17117           llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size);
17118           Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
17119         }
17120         if (Init && OrigType->isAnyComplexType()) {
17121           // Init = 0xFFFF + 0xFFFFi;
17122           auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
17123           Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
17124         }
17125         Type = OrigType;
17126         break;
17127       }
17128       case BO_LT:
17129       case BO_GT: {
17130         // 'min' reduction op - initializer is 'Largest representable number in
17131         // the reduction list item type'.
17132         // 'max' reduction op - initializer is 'Least representable number in
17133         // the reduction list item type'.
17134         if (Type->isIntegerType() || Type->isPointerType()) {
17135           bool IsSigned = Type->hasSignedIntegerRepresentation();
17136           uint64_t Size = Context.getTypeSize(Type);
17137           QualType IntTy =
17138               Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
17139           llvm::APInt InitValue =
17140               (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
17141                                         : llvm::APInt::getMinValue(Size)
17142                              : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
17143                                         : llvm::APInt::getMaxValue(Size);
17144           Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
17145           if (Type->isPointerType()) {
17146             // Cast to pointer type.
17147             ExprResult CastExpr = S.BuildCStyleCastExpr(
17148                 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init);
17149             if (CastExpr.isInvalid())
17150               continue;
17151             Init = CastExpr.get();
17152           }
17153         } else if (Type->isRealFloatingType()) {
17154           llvm::APFloat InitValue = llvm::APFloat::getLargest(
17155               Context.getFloatTypeSemantics(Type), BOK != BO_LT);
17156           Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true,
17157                                          Type, ELoc);
17158         }
17159         break;
17160       }
17161       case BO_PtrMemD:
17162       case BO_PtrMemI:
17163       case BO_MulAssign:
17164       case BO_Div:
17165       case BO_Rem:
17166       case BO_Sub:
17167       case BO_Shl:
17168       case BO_Shr:
17169       case BO_LE:
17170       case BO_GE:
17171       case BO_EQ:
17172       case BO_NE:
17173       case BO_Cmp:
17174       case BO_AndAssign:
17175       case BO_XorAssign:
17176       case BO_OrAssign:
17177       case BO_Assign:
17178       case BO_AddAssign:
17179       case BO_SubAssign:
17180       case BO_DivAssign:
17181       case BO_RemAssign:
17182       case BO_ShlAssign:
17183       case BO_ShrAssign:
17184       case BO_Comma:
17185         llvm_unreachable("Unexpected reduction operation");
17186       }
17187     }
17188     if (Init && DeclareReductionRef.isUnset()) {
17189       S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
17190       // Store initializer for single element in private copy. Will be used
17191       // during codegen.
17192       PrivateVD->setInit(RHSVD->getInit());
17193       PrivateVD->setInitStyle(RHSVD->getInitStyle());
17194     } else if (!Init) {
17195       S.ActOnUninitializedDecl(RHSVD);
17196       // Store initializer for single element in private copy. Will be used
17197       // during codegen.
17198       PrivateVD->setInit(RHSVD->getInit());
17199       PrivateVD->setInitStyle(RHSVD->getInitStyle());
17200     }
17201     if (RHSVD->isInvalidDecl())
17202       continue;
17203     if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) {
17204       S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
17205           << Type << ReductionIdRange;
17206       bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
17207                                VarDecl::DeclarationOnly;
17208       S.Diag(D->getLocation(),
17209              IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17210           << D;
17211       continue;
17212     }
17213     DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
17214     ExprResult ReductionOp;
17215     if (DeclareReductionRef.isUsable()) {
17216       QualType RedTy = DeclareReductionRef.get()->getType();
17217       QualType PtrRedTy = Context.getPointerType(RedTy);
17218       ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
17219       ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
17220       if (!BasePath.empty()) {
17221         LHS = S.DefaultLvalueConversion(LHS.get());
17222         RHS = S.DefaultLvalueConversion(RHS.get());
17223         LHS = ImplicitCastExpr::Create(
17224             Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath,
17225             LHS.get()->getValueKind(), FPOptionsOverride());
17226         RHS = ImplicitCastExpr::Create(
17227             Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath,
17228             RHS.get()->getValueKind(), FPOptionsOverride());
17229       }
17230       FunctionProtoType::ExtProtoInfo EPI;
17231       QualType Params[] = {PtrRedTy, PtrRedTy};
17232       QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
17233       auto *OVE = new (Context) OpaqueValueExpr(
17234           ELoc, Context.getPointerType(FnTy), VK_PRValue, OK_Ordinary,
17235           S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
17236       Expr *Args[] = {LHS.get(), RHS.get()};
17237       ReductionOp =
17238           CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_PRValue, ELoc,
17239                            S.CurFPFeatureOverrides());
17240     } else {
17241       BinaryOperatorKind CombBOK = getRelatedCompoundReductionOp(BOK);
17242       if (Type->isRecordType() && CombBOK != BOK) {
17243         Sema::TentativeAnalysisScope Trap(S);
17244         ReductionOp =
17245             S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
17246                          CombBOK, LHSDRE, RHSDRE);
17247       }
17248       if (!ReductionOp.isUsable()) {
17249         ReductionOp =
17250             S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), BOK,
17251                          LHSDRE, RHSDRE);
17252         if (ReductionOp.isUsable()) {
17253           if (BOK != BO_LT && BOK != BO_GT) {
17254             ReductionOp =
17255                 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
17256                              BO_Assign, LHSDRE, ReductionOp.get());
17257           } else {
17258             auto *ConditionalOp = new (Context)
17259                 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc,
17260                                     RHSDRE, Type, VK_LValue, OK_Ordinary);
17261             ReductionOp =
17262                 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(),
17263                              BO_Assign, LHSDRE, ConditionalOp);
17264           }
17265         }
17266       }
17267       if (ReductionOp.isUsable())
17268         ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(),
17269                                             /*DiscardedValue*/ false);
17270       if (!ReductionOp.isUsable())
17271         continue;
17272     }
17273 
17274     // Add copy operations for inscan reductions.
17275     // LHS = RHS;
17276     ExprResult CopyOpRes, TempArrayRes, TempArrayElem;
17277     if (ClauseKind == OMPC_reduction &&
17278         RD.RedModifier == OMPC_REDUCTION_inscan) {
17279       ExprResult RHS = S.DefaultLvalueConversion(RHSDRE);
17280       CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE,
17281                                RHS.get());
17282       if (!CopyOpRes.isUsable())
17283         continue;
17284       CopyOpRes =
17285           S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true);
17286       if (!CopyOpRes.isUsable())
17287         continue;
17288       // For simd directive and simd-based directives in simd mode no need to
17289       // construct temp array, need just a single temp element.
17290       if (Stack->getCurrentDirective() == OMPD_simd ||
17291           (S.getLangOpts().OpenMPSimd &&
17292            isOpenMPSimdDirective(Stack->getCurrentDirective()))) {
17293         VarDecl *TempArrayVD =
17294             buildVarDecl(S, ELoc, PrivateTy, D->getName(),
17295                          D->hasAttrs() ? &D->getAttrs() : nullptr);
17296         // Add a constructor to the temp decl.
17297         S.ActOnUninitializedDecl(TempArrayVD);
17298         TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc);
17299       } else {
17300         // Build temp array for prefix sum.
17301         auto *Dim = new (S.Context)
17302             OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue);
17303         QualType ArrayTy =
17304             S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal,
17305                                            /*IndexTypeQuals=*/0, {ELoc, ELoc});
17306         VarDecl *TempArrayVD =
17307             buildVarDecl(S, ELoc, ArrayTy, D->getName(),
17308                          D->hasAttrs() ? &D->getAttrs() : nullptr);
17309         // Add a constructor to the temp decl.
17310         S.ActOnUninitializedDecl(TempArrayVD);
17311         TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc);
17312         TempArrayElem =
17313             S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get());
17314         auto *Idx = new (S.Context)
17315             OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue);
17316         TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(),
17317                                                           ELoc, Idx, ELoc);
17318       }
17319     }
17320 
17321     // OpenMP [2.15.4.6, Restrictions, p.2]
17322     // A list item that appears in an in_reduction clause of a task construct
17323     // must appear in a task_reduction clause of a construct associated with a
17324     // taskgroup region that includes the participating task in its taskgroup
17325     // set. The construct associated with the innermost region that meets this
17326     // condition must specify the same reduction-identifier as the in_reduction
17327     // clause.
17328     if (ClauseKind == OMPC_in_reduction) {
17329       SourceRange ParentSR;
17330       BinaryOperatorKind ParentBOK;
17331       const Expr *ParentReductionOp = nullptr;
17332       Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr;
17333       DSAStackTy::DSAVarData ParentBOKDSA =
17334           Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK,
17335                                                   ParentBOKTD);
17336       DSAStackTy::DSAVarData ParentReductionOpDSA =
17337           Stack->getTopMostTaskgroupReductionData(
17338               D, ParentSR, ParentReductionOp, ParentReductionOpTD);
17339       bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown;
17340       bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown;
17341       if ((DeclareReductionRef.isUnset() && IsParentReductionOp) ||
17342           (DeclareReductionRef.isUsable() && IsParentBOK) ||
17343           (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) {
17344         bool EmitError = true;
17345         if (IsParentReductionOp && DeclareReductionRef.isUsable()) {
17346           llvm::FoldingSetNodeID RedId, ParentRedId;
17347           ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true);
17348           DeclareReductionRef.get()->Profile(RedId, Context,
17349                                              /*Canonical=*/true);
17350           EmitError = RedId != ParentRedId;
17351         }
17352         if (EmitError) {
17353           S.Diag(ReductionId.getBeginLoc(),
17354                  diag::err_omp_reduction_identifier_mismatch)
17355               << ReductionIdRange << RefExpr->getSourceRange();
17356           S.Diag(ParentSR.getBegin(),
17357                  diag::note_omp_previous_reduction_identifier)
17358               << ParentSR
17359               << (IsParentBOK ? ParentBOKDSA.RefExpr
17360                               : ParentReductionOpDSA.RefExpr)
17361                      ->getSourceRange();
17362           continue;
17363         }
17364       }
17365       TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD;
17366     }
17367 
17368     DeclRefExpr *Ref = nullptr;
17369     Expr *VarsExpr = RefExpr->IgnoreParens();
17370     if (!VD && !S.CurContext->isDependentContext()) {
17371       if (ASE || OASE) {
17372         TransformExprToCaptures RebuildToCapture(S, D);
17373         VarsExpr =
17374             RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
17375         Ref = RebuildToCapture.getCapturedExpr();
17376       } else {
17377         VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
17378       }
17379       if (!S.isOpenMPCapturedDecl(D)) {
17380         RD.ExprCaptures.emplace_back(Ref->getDecl());
17381         if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
17382           ExprResult RefRes = S.DefaultLvalueConversion(Ref);
17383           if (!RefRes.isUsable())
17384             continue;
17385           ExprResult PostUpdateRes =
17386               S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
17387                            RefRes.get());
17388           if (!PostUpdateRes.isUsable())
17389             continue;
17390           if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
17391               Stack->getCurrentDirective() == OMPD_taskgroup) {
17392             S.Diag(RefExpr->getExprLoc(),
17393                    diag::err_omp_reduction_non_addressable_expression)
17394                 << RefExpr->getSourceRange();
17395             continue;
17396           }
17397           RD.ExprPostUpdates.emplace_back(
17398               S.IgnoredValueConversions(PostUpdateRes.get()).get());
17399         }
17400       }
17401     }
17402     // All reduction items are still marked as reduction (to do not increase
17403     // code base size).
17404     unsigned Modifier = RD.RedModifier;
17405     // Consider task_reductions as reductions with task modifier. Required for
17406     // correct analysis of in_reduction clauses.
17407     if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction)
17408       Modifier = OMPC_REDUCTION_task;
17409     Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier,
17410                   ASE || OASE);
17411     if (Modifier == OMPC_REDUCTION_task &&
17412         (CurrDir == OMPD_taskgroup ||
17413          ((isOpenMPParallelDirective(CurrDir) ||
17414            isOpenMPWorksharingDirective(CurrDir)) &&
17415           !isOpenMPSimdDirective(CurrDir)))) {
17416       if (DeclareReductionRef.isUsable())
17417         Stack->addTaskgroupReductionData(D, ReductionIdRange,
17418                                          DeclareReductionRef.get());
17419       else
17420         Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK);
17421     }
17422     RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(),
17423             TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(),
17424             TempArrayElem.get());
17425   }
17426   return RD.Vars.empty();
17427 }
17428 
ActOnOpenMPReductionClause(ArrayRef<Expr * > VarList,OpenMPReductionClauseModifier Modifier,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ModifierLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)17429 OMPClause *Sema::ActOnOpenMPReductionClause(
17430     ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier,
17431     SourceLocation StartLoc, SourceLocation LParenLoc,
17432     SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
17433     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
17434     ArrayRef<Expr *> UnresolvedReductions) {
17435   if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) {
17436     Diag(LParenLoc, diag::err_omp_unexpected_clause_value)
17437         << getListOfPossibleValues(OMPC_reduction, /*First=*/0,
17438                                    /*Last=*/OMPC_REDUCTION_unknown)
17439         << getOpenMPClauseName(OMPC_reduction);
17440     return nullptr;
17441   }
17442   // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions
17443   // A reduction clause with the inscan reduction-modifier may only appear on a
17444   // worksharing-loop construct, a worksharing-loop SIMD construct, a simd
17445   // construct, a parallel worksharing-loop construct or a parallel
17446   // worksharing-loop SIMD construct.
17447   if (Modifier == OMPC_REDUCTION_inscan &&
17448       (DSAStack->getCurrentDirective() != OMPD_for &&
17449        DSAStack->getCurrentDirective() != OMPD_for_simd &&
17450        DSAStack->getCurrentDirective() != OMPD_simd &&
17451        DSAStack->getCurrentDirective() != OMPD_parallel_for &&
17452        DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) {
17453     Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction);
17454     return nullptr;
17455   }
17456 
17457   ReductionData RD(VarList.size(), Modifier);
17458   if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList,
17459                                   StartLoc, LParenLoc, ColonLoc, EndLoc,
17460                                   ReductionIdScopeSpec, ReductionId,
17461                                   UnresolvedReductions, RD))
17462     return nullptr;
17463 
17464   return OMPReductionClause::Create(
17465       Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier,
17466       RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
17467       RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps,
17468       RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems,
17469       buildPreInits(Context, RD.ExprCaptures),
17470       buildPostUpdate(*this, RD.ExprPostUpdates));
17471 }
17472 
ActOnOpenMPTaskReductionClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)17473 OMPClause *Sema::ActOnOpenMPTaskReductionClause(
17474     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
17475     SourceLocation ColonLoc, SourceLocation EndLoc,
17476     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
17477     ArrayRef<Expr *> UnresolvedReductions) {
17478   ReductionData RD(VarList.size());
17479   if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList,
17480                                   StartLoc, LParenLoc, ColonLoc, EndLoc,
17481                                   ReductionIdScopeSpec, ReductionId,
17482                                   UnresolvedReductions, RD))
17483     return nullptr;
17484 
17485   return OMPTaskReductionClause::Create(
17486       Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
17487       ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
17488       RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
17489       buildPreInits(Context, RD.ExprCaptures),
17490       buildPostUpdate(*this, RD.ExprPostUpdates));
17491 }
17492 
ActOnOpenMPInReductionClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,CXXScopeSpec & ReductionIdScopeSpec,const DeclarationNameInfo & ReductionId,ArrayRef<Expr * > UnresolvedReductions)17493 OMPClause *Sema::ActOnOpenMPInReductionClause(
17494     ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
17495     SourceLocation ColonLoc, SourceLocation EndLoc,
17496     CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
17497     ArrayRef<Expr *> UnresolvedReductions) {
17498   ReductionData RD(VarList.size());
17499   if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList,
17500                                   StartLoc, LParenLoc, ColonLoc, EndLoc,
17501                                   ReductionIdScopeSpec, ReductionId,
17502                                   UnresolvedReductions, RD))
17503     return nullptr;
17504 
17505   return OMPInReductionClause::Create(
17506       Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
17507       ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
17508       RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors,
17509       buildPreInits(Context, RD.ExprCaptures),
17510       buildPostUpdate(*this, RD.ExprPostUpdates));
17511 }
17512 
CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,SourceLocation LinLoc)17513 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
17514                                      SourceLocation LinLoc) {
17515   if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) ||
17516       LinKind == OMPC_LINEAR_unknown) {
17517     Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus;
17518     return true;
17519   }
17520   return false;
17521 }
17522 
CheckOpenMPLinearDecl(const ValueDecl * D,SourceLocation ELoc,OpenMPLinearClauseKind LinKind,QualType Type,bool IsDeclareSimd)17523 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc,
17524                                  OpenMPLinearClauseKind LinKind, QualType Type,
17525                                  bool IsDeclareSimd) {
17526   const auto *VD = dyn_cast_or_null<VarDecl>(D);
17527   // A variable must not have an incomplete type or a reference type.
17528   if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type))
17529     return true;
17530   if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) &&
17531       !Type->isReferenceType()) {
17532     Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference)
17533         << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind);
17534     return true;
17535   }
17536   Type = Type.getNonReferenceType();
17537 
17538   // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions]
17539   // A variable that is privatized must not have a const-qualified type
17540   // unless it is of class type with a mutable member. This restriction does
17541   // not apply to the firstprivate clause, nor to the linear clause on
17542   // declarative directives (like declare simd).
17543   if (!IsDeclareSimd &&
17544       rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc))
17545     return true;
17546 
17547   // A list item must be of integral or pointer type.
17548   Type = Type.getUnqualifiedType().getCanonicalType();
17549   const auto *Ty = Type.getTypePtrOrNull();
17550   if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() &&
17551               !Ty->isIntegralType(Context) && !Ty->isPointerType())) {
17552     Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type;
17553     if (D) {
17554       bool IsDecl =
17555           !VD ||
17556           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
17557       Diag(D->getLocation(),
17558            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17559           << D;
17560     }
17561     return true;
17562   }
17563   return false;
17564 }
17565 
ActOnOpenMPLinearClause(ArrayRef<Expr * > VarList,Expr * Step,SourceLocation StartLoc,SourceLocation LParenLoc,OpenMPLinearClauseKind LinKind,SourceLocation LinLoc,SourceLocation ColonLoc,SourceLocation EndLoc)17566 OMPClause *Sema::ActOnOpenMPLinearClause(
17567     ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc,
17568     SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind,
17569     SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
17570   SmallVector<Expr *, 8> Vars;
17571   SmallVector<Expr *, 8> Privates;
17572   SmallVector<Expr *, 8> Inits;
17573   SmallVector<Decl *, 4> ExprCaptures;
17574   SmallVector<Expr *, 4> ExprPostUpdates;
17575   if (CheckOpenMPLinearModifier(LinKind, LinLoc))
17576     LinKind = OMPC_LINEAR_val;
17577   for (Expr *RefExpr : VarList) {
17578     assert(RefExpr && "NULL expr in OpenMP linear clause.");
17579     SourceLocation ELoc;
17580     SourceRange ERange;
17581     Expr *SimpleRefExpr = RefExpr;
17582     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17583     if (Res.second) {
17584       // It will be analyzed later.
17585       Vars.push_back(RefExpr);
17586       Privates.push_back(nullptr);
17587       Inits.push_back(nullptr);
17588     }
17589     ValueDecl *D = Res.first;
17590     if (!D)
17591       continue;
17592 
17593     QualType Type = D->getType();
17594     auto *VD = dyn_cast<VarDecl>(D);
17595 
17596     // OpenMP [2.14.3.7, linear clause]
17597     //  A list-item cannot appear in more than one linear clause.
17598     //  A list-item that appears in a linear clause cannot appear in any
17599     //  other data-sharing attribute clause.
17600     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
17601     if (DVar.RefExpr) {
17602       Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind)
17603                                           << getOpenMPClauseName(OMPC_linear);
17604       reportOriginalDsa(*this, DSAStack, D, DVar);
17605       continue;
17606     }
17607 
17608     if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type))
17609       continue;
17610     Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType();
17611 
17612     // Build private copy of original var.
17613     VarDecl *Private =
17614         buildVarDecl(*this, ELoc, Type, D->getName(),
17615                      D->hasAttrs() ? &D->getAttrs() : nullptr,
17616                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
17617     DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc);
17618     // Build var to save initial value.
17619     VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start");
17620     Expr *InitExpr;
17621     DeclRefExpr *Ref = nullptr;
17622     if (!VD && !CurContext->isDependentContext()) {
17623       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
17624       if (!isOpenMPCapturedDecl(D)) {
17625         ExprCaptures.push_back(Ref->getDecl());
17626         if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
17627           ExprResult RefRes = DefaultLvalueConversion(Ref);
17628           if (!RefRes.isUsable())
17629             continue;
17630           ExprResult PostUpdateRes =
17631               BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
17632                          SimpleRefExpr, RefRes.get());
17633           if (!PostUpdateRes.isUsable())
17634             continue;
17635           ExprPostUpdates.push_back(
17636               IgnoredValueConversions(PostUpdateRes.get()).get());
17637         }
17638       }
17639     }
17640     if (LinKind == OMPC_LINEAR_uval)
17641       InitExpr = VD ? VD->getInit() : SimpleRefExpr;
17642     else
17643       InitExpr = VD ? SimpleRefExpr : Ref;
17644     AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(),
17645                          /*DirectInit=*/false);
17646     DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc);
17647 
17648     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref);
17649     Vars.push_back((VD || CurContext->isDependentContext())
17650                        ? RefExpr->IgnoreParens()
17651                        : Ref);
17652     Privates.push_back(PrivateRef);
17653     Inits.push_back(InitRef);
17654   }
17655 
17656   if (Vars.empty())
17657     return nullptr;
17658 
17659   Expr *StepExpr = Step;
17660   Expr *CalcStepExpr = nullptr;
17661   if (Step && !Step->isValueDependent() && !Step->isTypeDependent() &&
17662       !Step->isInstantiationDependent() &&
17663       !Step->containsUnexpandedParameterPack()) {
17664     SourceLocation StepLoc = Step->getBeginLoc();
17665     ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step);
17666     if (Val.isInvalid())
17667       return nullptr;
17668     StepExpr = Val.get();
17669 
17670     // Build var to save the step value.
17671     VarDecl *SaveVar =
17672         buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step");
17673     ExprResult SaveRef =
17674         buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc);
17675     ExprResult CalcStep =
17676         BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr);
17677     CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false);
17678 
17679     // Warn about zero linear step (it would be probably better specified as
17680     // making corresponding variables 'const').
17681     if (Optional<llvm::APSInt> Result =
17682             StepExpr->getIntegerConstantExpr(Context)) {
17683       if (!Result->isNegative() && !Result->isStrictlyPositive())
17684         Diag(StepLoc, diag::warn_omp_linear_step_zero)
17685             << Vars[0] << (Vars.size() > 1);
17686     } else if (CalcStep.isUsable()) {
17687       // Calculate the step beforehand instead of doing this on each iteration.
17688       // (This is not used if the number of iterations may be kfold-ed).
17689       CalcStepExpr = CalcStep.get();
17690     }
17691   }
17692 
17693   return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc,
17694                                  ColonLoc, EndLoc, Vars, Privates, Inits,
17695                                  StepExpr, CalcStepExpr,
17696                                  buildPreInits(Context, ExprCaptures),
17697                                  buildPostUpdate(*this, ExprPostUpdates));
17698 }
17699 
FinishOpenMPLinearClause(OMPLinearClause & Clause,DeclRefExpr * IV,Expr * NumIterations,Sema & SemaRef,Scope * S,DSAStackTy * Stack)17700 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV,
17701                                      Expr *NumIterations, Sema &SemaRef,
17702                                      Scope *S, DSAStackTy *Stack) {
17703   // Walk the vars and build update/final expressions for the CodeGen.
17704   SmallVector<Expr *, 8> Updates;
17705   SmallVector<Expr *, 8> Finals;
17706   SmallVector<Expr *, 8> UsedExprs;
17707   Expr *Step = Clause.getStep();
17708   Expr *CalcStep = Clause.getCalcStep();
17709   // OpenMP [2.14.3.7, linear clause]
17710   // If linear-step is not specified it is assumed to be 1.
17711   if (!Step)
17712     Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get();
17713   else if (CalcStep)
17714     Step = cast<BinaryOperator>(CalcStep)->getLHS();
17715   bool HasErrors = false;
17716   auto CurInit = Clause.inits().begin();
17717   auto CurPrivate = Clause.privates().begin();
17718   OpenMPLinearClauseKind LinKind = Clause.getModifier();
17719   for (Expr *RefExpr : Clause.varlists()) {
17720     SourceLocation ELoc;
17721     SourceRange ERange;
17722     Expr *SimpleRefExpr = RefExpr;
17723     auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange);
17724     ValueDecl *D = Res.first;
17725     if (Res.second || !D) {
17726       Updates.push_back(nullptr);
17727       Finals.push_back(nullptr);
17728       HasErrors = true;
17729       continue;
17730     }
17731     auto &&Info = Stack->isLoopControlVariable(D);
17732     // OpenMP [2.15.11, distribute simd Construct]
17733     // A list item may not appear in a linear clause, unless it is the loop
17734     // iteration variable.
17735     if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) &&
17736         isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) {
17737       SemaRef.Diag(ELoc,
17738                    diag::err_omp_linear_distribute_var_non_loop_iteration);
17739       Updates.push_back(nullptr);
17740       Finals.push_back(nullptr);
17741       HasErrors = true;
17742       continue;
17743     }
17744     Expr *InitExpr = *CurInit;
17745 
17746     // Build privatized reference to the current linear var.
17747     auto *DE = cast<DeclRefExpr>(SimpleRefExpr);
17748     Expr *CapturedRef;
17749     if (LinKind == OMPC_LINEAR_uval)
17750       CapturedRef = cast<VarDecl>(DE->getDecl())->getInit();
17751     else
17752       CapturedRef =
17753           buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()),
17754                            DE->getType().getUnqualifiedType(), DE->getExprLoc(),
17755                            /*RefersToCapture=*/true);
17756 
17757     // Build update: Var = InitExpr + IV * Step
17758     ExprResult Update;
17759     if (!Info.first)
17760       Update = buildCounterUpdate(
17761           SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step,
17762           /*Subtract=*/false, /*IsNonRectangularLB=*/false);
17763     else
17764       Update = *CurPrivate;
17765     Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(),
17766                                          /*DiscardedValue*/ false);
17767 
17768     // Build final: Var = InitExpr + NumIterations * Step
17769     ExprResult Final;
17770     if (!Info.first)
17771       Final =
17772           buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef,
17773                              InitExpr, NumIterations, Step, /*Subtract=*/false,
17774                              /*IsNonRectangularLB=*/false);
17775     else
17776       Final = *CurPrivate;
17777     Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(),
17778                                         /*DiscardedValue*/ false);
17779 
17780     if (!Update.isUsable() || !Final.isUsable()) {
17781       Updates.push_back(nullptr);
17782       Finals.push_back(nullptr);
17783       UsedExprs.push_back(nullptr);
17784       HasErrors = true;
17785     } else {
17786       Updates.push_back(Update.get());
17787       Finals.push_back(Final.get());
17788       if (!Info.first)
17789         UsedExprs.push_back(SimpleRefExpr);
17790     }
17791     ++CurInit;
17792     ++CurPrivate;
17793   }
17794   if (Expr *S = Clause.getStep())
17795     UsedExprs.push_back(S);
17796   // Fill the remaining part with the nullptr.
17797   UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr);
17798   Clause.setUpdates(Updates);
17799   Clause.setFinals(Finals);
17800   Clause.setUsedExprs(UsedExprs);
17801   return HasErrors;
17802 }
17803 
ActOnOpenMPAlignedClause(ArrayRef<Expr * > VarList,Expr * Alignment,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc)17804 OMPClause *Sema::ActOnOpenMPAlignedClause(
17805     ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc,
17806     SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) {
17807   SmallVector<Expr *, 8> Vars;
17808   for (Expr *RefExpr : VarList) {
17809     assert(RefExpr && "NULL expr in OpenMP linear clause.");
17810     SourceLocation ELoc;
17811     SourceRange ERange;
17812     Expr *SimpleRefExpr = RefExpr;
17813     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17814     if (Res.second) {
17815       // It will be analyzed later.
17816       Vars.push_back(RefExpr);
17817     }
17818     ValueDecl *D = Res.first;
17819     if (!D)
17820       continue;
17821 
17822     QualType QType = D->getType();
17823     auto *VD = dyn_cast<VarDecl>(D);
17824 
17825     // OpenMP  [2.8.1, simd construct, Restrictions]
17826     // The type of list items appearing in the aligned clause must be
17827     // array, pointer, reference to array, or reference to pointer.
17828     QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType();
17829     const Type *Ty = QType.getTypePtrOrNull();
17830     if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) {
17831       Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr)
17832           << QType << getLangOpts().CPlusPlus << ERange;
17833       bool IsDecl =
17834           !VD ||
17835           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
17836       Diag(D->getLocation(),
17837            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
17838           << D;
17839       continue;
17840     }
17841 
17842     // OpenMP  [2.8.1, simd construct, Restrictions]
17843     // A list-item cannot appear in more than one aligned clause.
17844     if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) {
17845       Diag(ELoc, diag::err_omp_used_in_clause_twice)
17846           << 0 << getOpenMPClauseName(OMPC_aligned) << ERange;
17847       Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
17848           << getOpenMPClauseName(OMPC_aligned);
17849       continue;
17850     }
17851 
17852     DeclRefExpr *Ref = nullptr;
17853     if (!VD && isOpenMPCapturedDecl(D))
17854       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
17855     Vars.push_back(DefaultFunctionArrayConversion(
17856                        (VD || !Ref) ? RefExpr->IgnoreParens() : Ref)
17857                        .get());
17858   }
17859 
17860   // OpenMP [2.8.1, simd construct, Description]
17861   // The parameter of the aligned clause, alignment, must be a constant
17862   // positive integer expression.
17863   // If no optional parameter is specified, implementation-defined default
17864   // alignments for SIMD instructions on the target platforms are assumed.
17865   if (Alignment != nullptr) {
17866     ExprResult AlignResult =
17867         VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned);
17868     if (AlignResult.isInvalid())
17869       return nullptr;
17870     Alignment = AlignResult.get();
17871   }
17872   if (Vars.empty())
17873     return nullptr;
17874 
17875   return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
17876                                   EndLoc, Vars, Alignment);
17877 }
17878 
ActOnOpenMPCopyinClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)17879 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList,
17880                                          SourceLocation StartLoc,
17881                                          SourceLocation LParenLoc,
17882                                          SourceLocation EndLoc) {
17883   SmallVector<Expr *, 8> Vars;
17884   SmallVector<Expr *, 8> SrcExprs;
17885   SmallVector<Expr *, 8> DstExprs;
17886   SmallVector<Expr *, 8> AssignmentOps;
17887   for (Expr *RefExpr : VarList) {
17888     assert(RefExpr && "NULL expr in OpenMP copyin clause.");
17889     if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
17890       // It will be analyzed later.
17891       Vars.push_back(RefExpr);
17892       SrcExprs.push_back(nullptr);
17893       DstExprs.push_back(nullptr);
17894       AssignmentOps.push_back(nullptr);
17895       continue;
17896     }
17897 
17898     SourceLocation ELoc = RefExpr->getExprLoc();
17899     // OpenMP [2.1, C/C++]
17900     //  A list item is a variable name.
17901     // OpenMP  [2.14.4.1, Restrictions, p.1]
17902     //  A list item that appears in a copyin clause must be threadprivate.
17903     auto *DE = dyn_cast<DeclRefExpr>(RefExpr);
17904     if (!DE || !isa<VarDecl>(DE->getDecl())) {
17905       Diag(ELoc, diag::err_omp_expected_var_name_member_expr)
17906           << 0 << RefExpr->getSourceRange();
17907       continue;
17908     }
17909 
17910     Decl *D = DE->getDecl();
17911     auto *VD = cast<VarDecl>(D);
17912 
17913     QualType Type = VD->getType();
17914     if (Type->isDependentType() || Type->isInstantiationDependentType()) {
17915       // It will be analyzed later.
17916       Vars.push_back(DE);
17917       SrcExprs.push_back(nullptr);
17918       DstExprs.push_back(nullptr);
17919       AssignmentOps.push_back(nullptr);
17920       continue;
17921     }
17922 
17923     // OpenMP [2.14.4.1, Restrictions, C/C++, p.1]
17924     //  A list item that appears in a copyin clause must be threadprivate.
17925     if (!DSAStack->isThreadPrivate(VD)) {
17926       Diag(ELoc, diag::err_omp_required_access)
17927           << getOpenMPClauseName(OMPC_copyin)
17928           << getOpenMPDirectiveName(OMPD_threadprivate);
17929       continue;
17930     }
17931 
17932     // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
17933     //  A variable of class type (or array thereof) that appears in a
17934     //  copyin clause requires an accessible, unambiguous copy assignment
17935     //  operator for the class type.
17936     QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType();
17937     VarDecl *SrcVD =
17938         buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(),
17939                      ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr);
17940     DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(
17941         *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc());
17942     VarDecl *DstVD =
17943         buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst",
17944                      VD->hasAttrs() ? &VD->getAttrs() : nullptr);
17945     DeclRefExpr *PseudoDstExpr =
17946         buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc());
17947     // For arrays generate assignment operation for single element and replace
17948     // it by the original array element in CodeGen.
17949     ExprResult AssignmentOp =
17950         BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr,
17951                    PseudoSrcExpr);
17952     if (AssignmentOp.isInvalid())
17953       continue;
17954     AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(),
17955                                        /*DiscardedValue*/ false);
17956     if (AssignmentOp.isInvalid())
17957       continue;
17958 
17959     DSAStack->addDSA(VD, DE, OMPC_copyin);
17960     Vars.push_back(DE);
17961     SrcExprs.push_back(PseudoSrcExpr);
17962     DstExprs.push_back(PseudoDstExpr);
17963     AssignmentOps.push_back(AssignmentOp.get());
17964   }
17965 
17966   if (Vars.empty())
17967     return nullptr;
17968 
17969   return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars,
17970                                  SrcExprs, DstExprs, AssignmentOps);
17971 }
17972 
ActOnOpenMPCopyprivateClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)17973 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList,
17974                                               SourceLocation StartLoc,
17975                                               SourceLocation LParenLoc,
17976                                               SourceLocation EndLoc) {
17977   SmallVector<Expr *, 8> Vars;
17978   SmallVector<Expr *, 8> SrcExprs;
17979   SmallVector<Expr *, 8> DstExprs;
17980   SmallVector<Expr *, 8> AssignmentOps;
17981   for (Expr *RefExpr : VarList) {
17982     assert(RefExpr && "NULL expr in OpenMP linear clause.");
17983     SourceLocation ELoc;
17984     SourceRange ERange;
17985     Expr *SimpleRefExpr = RefExpr;
17986     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
17987     if (Res.second) {
17988       // It will be analyzed later.
17989       Vars.push_back(RefExpr);
17990       SrcExprs.push_back(nullptr);
17991       DstExprs.push_back(nullptr);
17992       AssignmentOps.push_back(nullptr);
17993     }
17994     ValueDecl *D = Res.first;
17995     if (!D)
17996       continue;
17997 
17998     QualType Type = D->getType();
17999     auto *VD = dyn_cast<VarDecl>(D);
18000 
18001     // OpenMP [2.14.4.2, Restrictions, p.2]
18002     //  A list item that appears in a copyprivate clause may not appear in a
18003     //  private or firstprivate clause on the single construct.
18004     if (!VD || !DSAStack->isThreadPrivate(VD)) {
18005       DSAStackTy::DSAVarData DVar =
18006           DSAStack->getTopDSA(D, /*FromParent=*/false);
18007       if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate &&
18008           DVar.RefExpr) {
18009         Diag(ELoc, diag::err_omp_wrong_dsa)
18010             << getOpenMPClauseName(DVar.CKind)
18011             << getOpenMPClauseName(OMPC_copyprivate);
18012         reportOriginalDsa(*this, DSAStack, D, DVar);
18013         continue;
18014       }
18015 
18016       // OpenMP [2.11.4.2, Restrictions, p.1]
18017       //  All list items that appear in a copyprivate clause must be either
18018       //  threadprivate or private in the enclosing context.
18019       if (DVar.CKind == OMPC_unknown) {
18020         DVar = DSAStack->getImplicitDSA(D, false);
18021         if (DVar.CKind == OMPC_shared) {
18022           Diag(ELoc, diag::err_omp_required_access)
18023               << getOpenMPClauseName(OMPC_copyprivate)
18024               << "threadprivate or private in the enclosing context";
18025           reportOriginalDsa(*this, DSAStack, D, DVar);
18026           continue;
18027         }
18028       }
18029     }
18030 
18031     // Variably modified types are not supported.
18032     if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) {
18033       Diag(ELoc, diag::err_omp_variably_modified_type_not_supported)
18034           << getOpenMPClauseName(OMPC_copyprivate) << Type
18035           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
18036       bool IsDecl =
18037           !VD ||
18038           VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
18039       Diag(D->getLocation(),
18040            IsDecl ? diag::note_previous_decl : diag::note_defined_here)
18041           << D;
18042       continue;
18043     }
18044 
18045     // OpenMP [2.14.4.1, Restrictions, C/C++, p.2]
18046     //  A variable of class type (or array thereof) that appears in a
18047     //  copyin clause requires an accessible, unambiguous copy assignment
18048     //  operator for the class type.
18049     Type = Context.getBaseElementType(Type.getNonReferenceType())
18050                .getUnqualifiedType();
18051     VarDecl *SrcVD =
18052         buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src",
18053                      D->hasAttrs() ? &D->getAttrs() : nullptr);
18054     DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc);
18055     VarDecl *DstVD =
18056         buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst",
18057                      D->hasAttrs() ? &D->getAttrs() : nullptr);
18058     DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc);
18059     ExprResult AssignmentOp = BuildBinOp(
18060         DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr);
18061     if (AssignmentOp.isInvalid())
18062       continue;
18063     AssignmentOp =
18064         ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false);
18065     if (AssignmentOp.isInvalid())
18066       continue;
18067 
18068     // No need to mark vars as copyprivate, they are already threadprivate or
18069     // implicitly private.
18070     assert(VD || isOpenMPCapturedDecl(D));
18071     Vars.push_back(
18072         VD ? RefExpr->IgnoreParens()
18073            : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false));
18074     SrcExprs.push_back(PseudoSrcExpr);
18075     DstExprs.push_back(PseudoDstExpr);
18076     AssignmentOps.push_back(AssignmentOp.get());
18077   }
18078 
18079   if (Vars.empty())
18080     return nullptr;
18081 
18082   return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc,
18083                                       Vars, SrcExprs, DstExprs, AssignmentOps);
18084 }
18085 
ActOnOpenMPFlushClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18086 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList,
18087                                         SourceLocation StartLoc,
18088                                         SourceLocation LParenLoc,
18089                                         SourceLocation EndLoc) {
18090   if (VarList.empty())
18091     return nullptr;
18092 
18093   return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList);
18094 }
18095 
18096 /// Tries to find omp_depend_t. type.
findOMPDependT(Sema & S,SourceLocation Loc,DSAStackTy * Stack,bool Diagnose=true)18097 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack,
18098                            bool Diagnose = true) {
18099   QualType OMPDependT = Stack->getOMPDependT();
18100   if (!OMPDependT.isNull())
18101     return true;
18102   IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t");
18103   ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
18104   if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
18105     if (Diagnose)
18106       S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t";
18107     return false;
18108   }
18109   Stack->setOMPDependT(PT.get());
18110   return true;
18111 }
18112 
ActOnOpenMPDepobjClause(Expr * Depobj,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18113 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc,
18114                                          SourceLocation LParenLoc,
18115                                          SourceLocation EndLoc) {
18116   if (!Depobj)
18117     return nullptr;
18118 
18119   bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack);
18120 
18121   // OpenMP 5.0, 2.17.10.1 depobj Construct
18122   // depobj is an lvalue expression of type omp_depend_t.
18123   if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() &&
18124       !Depobj->isInstantiationDependent() &&
18125       !Depobj->containsUnexpandedParameterPack() &&
18126       (OMPDependTFound &&
18127        !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(),
18128                                    /*CompareUnqualified=*/true))) {
18129     Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
18130         << 0 << Depobj->getType() << Depobj->getSourceRange();
18131   }
18132 
18133   if (!Depobj->isLValue()) {
18134     Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue)
18135         << 1 << Depobj->getSourceRange();
18136   }
18137 
18138   return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj);
18139 }
18140 
18141 OMPClause *
ActOnOpenMPDependClause(Expr * DepModifier,OpenMPDependClauseKind DepKind,SourceLocation DepLoc,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)18142 Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind,
18143                               SourceLocation DepLoc, SourceLocation ColonLoc,
18144                               ArrayRef<Expr *> VarList, SourceLocation StartLoc,
18145                               SourceLocation LParenLoc, SourceLocation EndLoc) {
18146   if (DSAStack->getCurrentDirective() == OMPD_ordered &&
18147       DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) {
18148     Diag(DepLoc, diag::err_omp_unexpected_clause_value)
18149         << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend);
18150     return nullptr;
18151   }
18152   if ((DSAStack->getCurrentDirective() != OMPD_ordered ||
18153        DSAStack->getCurrentDirective() == OMPD_depobj) &&
18154       (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source ||
18155        DepKind == OMPC_DEPEND_sink ||
18156        ((LangOpts.OpenMP < 50 ||
18157          DSAStack->getCurrentDirective() == OMPD_depobj) &&
18158         DepKind == OMPC_DEPEND_depobj))) {
18159     SmallVector<unsigned, 3> Except;
18160     Except.push_back(OMPC_DEPEND_source);
18161     Except.push_back(OMPC_DEPEND_sink);
18162     if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj)
18163       Except.push_back(OMPC_DEPEND_depobj);
18164     std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier)
18165                                ? "depend modifier(iterator) or "
18166                                : "";
18167     Diag(DepLoc, diag::err_omp_unexpected_clause_value)
18168         << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0,
18169                                               /*Last=*/OMPC_DEPEND_unknown,
18170                                               Except)
18171         << getOpenMPClauseName(OMPC_depend);
18172     return nullptr;
18173   }
18174   if (DepModifier &&
18175       (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) {
18176     Diag(DepModifier->getExprLoc(),
18177          diag::err_omp_depend_sink_source_with_modifier);
18178     return nullptr;
18179   }
18180   if (DepModifier &&
18181       !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator))
18182     Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator);
18183 
18184   SmallVector<Expr *, 8> Vars;
18185   DSAStackTy::OperatorOffsetTy OpsOffs;
18186   llvm::APSInt DepCounter(/*BitWidth=*/32);
18187   llvm::APSInt TotalDepCount(/*BitWidth=*/32);
18188   if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) {
18189     if (const Expr *OrderedCountExpr =
18190             DSAStack->getParentOrderedRegionParam().first) {
18191       TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context);
18192       TotalDepCount.setIsUnsigned(/*Val=*/true);
18193     }
18194   }
18195   for (Expr *RefExpr : VarList) {
18196     assert(RefExpr && "NULL expr in OpenMP shared clause.");
18197     if (isa<DependentScopeDeclRefExpr>(RefExpr)) {
18198       // It will be analyzed later.
18199       Vars.push_back(RefExpr);
18200       continue;
18201     }
18202 
18203     SourceLocation ELoc = RefExpr->getExprLoc();
18204     Expr *SimpleExpr = RefExpr->IgnoreParenCasts();
18205     if (DepKind == OMPC_DEPEND_sink) {
18206       if (DSAStack->getParentOrderedRegionParam().first &&
18207           DepCounter >= TotalDepCount) {
18208         Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr);
18209         continue;
18210       }
18211       ++DepCounter;
18212       // OpenMP  [2.13.9, Summary]
18213       // depend(dependence-type : vec), where dependence-type is:
18214       // 'sink' and where vec is the iteration vector, which has the form:
18215       //  x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn]
18216       // where n is the value specified by the ordered clause in the loop
18217       // directive, xi denotes the loop iteration variable of the i-th nested
18218       // loop associated with the loop directive, and di is a constant
18219       // non-negative integer.
18220       if (CurContext->isDependentContext()) {
18221         // It will be analyzed later.
18222         Vars.push_back(RefExpr);
18223         continue;
18224       }
18225       SimpleExpr = SimpleExpr->IgnoreImplicit();
18226       OverloadedOperatorKind OOK = OO_None;
18227       SourceLocation OOLoc;
18228       Expr *LHS = SimpleExpr;
18229       Expr *RHS = nullptr;
18230       if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) {
18231         OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode());
18232         OOLoc = BO->getOperatorLoc();
18233         LHS = BO->getLHS()->IgnoreParenImpCasts();
18234         RHS = BO->getRHS()->IgnoreParenImpCasts();
18235       } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) {
18236         OOK = OCE->getOperator();
18237         OOLoc = OCE->getOperatorLoc();
18238         LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
18239         RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
18240       } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) {
18241         OOK = MCE->getMethodDecl()
18242                   ->getNameInfo()
18243                   .getName()
18244                   .getCXXOverloadedOperator();
18245         OOLoc = MCE->getCallee()->getExprLoc();
18246         LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts();
18247         RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
18248       }
18249       SourceLocation ELoc;
18250       SourceRange ERange;
18251       auto Res = getPrivateItem(*this, LHS, ELoc, ERange);
18252       if (Res.second) {
18253         // It will be analyzed later.
18254         Vars.push_back(RefExpr);
18255       }
18256       ValueDecl *D = Res.first;
18257       if (!D)
18258         continue;
18259 
18260       if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) {
18261         Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus);
18262         continue;
18263       }
18264       if (RHS) {
18265         ExprResult RHSRes = VerifyPositiveIntegerConstantInClause(
18266             RHS, OMPC_depend, /*StrictlyPositive=*/false);
18267         if (RHSRes.isInvalid())
18268           continue;
18269       }
18270       if (!CurContext->isDependentContext() &&
18271           DSAStack->getParentOrderedRegionParam().first &&
18272           DepCounter != DSAStack->isParentLoopControlVariable(D).first) {
18273         const ValueDecl *VD =
18274             DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue());
18275         if (VD)
18276           Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration)
18277               << 1 << VD;
18278         else
18279           Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0;
18280         continue;
18281       }
18282       OpsOffs.emplace_back(RHS, OOK);
18283     } else {
18284       bool OMPDependTFound = LangOpts.OpenMP >= 50;
18285       if (OMPDependTFound)
18286         OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack,
18287                                          DepKind == OMPC_DEPEND_depobj);
18288       if (DepKind == OMPC_DEPEND_depobj) {
18289         // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
18290         // List items used in depend clauses with the depobj dependence type
18291         // must be expressions of the omp_depend_t type.
18292         if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
18293             !RefExpr->isInstantiationDependent() &&
18294             !RefExpr->containsUnexpandedParameterPack() &&
18295             (OMPDependTFound &&
18296              !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(),
18297                                              RefExpr->getType()))) {
18298           Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
18299               << 0 << RefExpr->getType() << RefExpr->getSourceRange();
18300           continue;
18301         }
18302         if (!RefExpr->isLValue()) {
18303           Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue)
18304               << 1 << RefExpr->getType() << RefExpr->getSourceRange();
18305           continue;
18306         }
18307       } else {
18308         // OpenMP 5.0 [2.17.11, Restrictions]
18309         // List items used in depend clauses cannot be zero-length array
18310         // sections.
18311         QualType ExprTy = RefExpr->getType().getNonReferenceType();
18312         const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr);
18313         if (OASE) {
18314           QualType BaseType =
18315               OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
18316           if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
18317             ExprTy = ATy->getElementType();
18318           else
18319             ExprTy = BaseType->getPointeeType();
18320           ExprTy = ExprTy.getNonReferenceType();
18321           const Expr *Length = OASE->getLength();
18322           Expr::EvalResult Result;
18323           if (Length && !Length->isValueDependent() &&
18324               Length->EvaluateAsInt(Result, Context) &&
18325               Result.Val.getInt().isNullValue()) {
18326             Diag(ELoc,
18327                  diag::err_omp_depend_zero_length_array_section_not_allowed)
18328                 << SimpleExpr->getSourceRange();
18329             continue;
18330           }
18331         }
18332 
18333         // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++
18334         // List items used in depend clauses with the in, out, inout or
18335         // mutexinoutset dependence types cannot be expressions of the
18336         // omp_depend_t type.
18337         if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() &&
18338             !RefExpr->isInstantiationDependent() &&
18339             !RefExpr->containsUnexpandedParameterPack() &&
18340             (OMPDependTFound &&
18341              DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) {
18342           Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
18343               << (LangOpts.OpenMP >= 50 ? 1 : 0) << 1
18344               << RefExpr->getSourceRange();
18345           continue;
18346         }
18347 
18348         auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr);
18349         if (!RefExpr->IgnoreParenImpCasts()->isLValue() ||
18350             (ASE && !ASE->getBase()->isTypeDependent() &&
18351              !ASE->getBase()
18352                   ->getType()
18353                   .getNonReferenceType()
18354                   ->isPointerType() &&
18355              !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) {
18356           Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
18357               << (LangOpts.OpenMP >= 50 ? 1 : 0)
18358               << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
18359           continue;
18360         }
18361 
18362         ExprResult Res;
18363         {
18364           Sema::TentativeAnalysisScope Trap(*this);
18365           Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf,
18366                                      RefExpr->IgnoreParenImpCasts());
18367         }
18368         if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
18369             !isa<OMPArrayShapingExpr>(SimpleExpr)) {
18370           Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
18371               << (LangOpts.OpenMP >= 50 ? 1 : 0)
18372               << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange();
18373           continue;
18374         }
18375       }
18376     }
18377     Vars.push_back(RefExpr->IgnoreParenImpCasts());
18378   }
18379 
18380   if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink &&
18381       TotalDepCount > VarList.size() &&
18382       DSAStack->getParentOrderedRegionParam().first &&
18383       DSAStack->getParentLoopControlVariable(VarList.size() + 1)) {
18384     Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration)
18385         << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1);
18386   }
18387   if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink &&
18388       Vars.empty())
18389     return nullptr;
18390 
18391   auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc,
18392                                     DepModifier, DepKind, DepLoc, ColonLoc,
18393                                     Vars, TotalDepCount.getZExtValue());
18394   if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) &&
18395       DSAStack->isParentOrderedRegion())
18396     DSAStack->addDoacrossDependClause(C, OpsOffs);
18397   return C;
18398 }
18399 
ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,Expr * Device,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ModifierLoc,SourceLocation EndLoc)18400 OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier,
18401                                          Expr *Device, SourceLocation StartLoc,
18402                                          SourceLocation LParenLoc,
18403                                          SourceLocation ModifierLoc,
18404                                          SourceLocation EndLoc) {
18405   assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) &&
18406          "Unexpected device modifier in OpenMP < 50.");
18407 
18408   bool ErrorFound = false;
18409   if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) {
18410     std::string Values =
18411         getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown);
18412     Diag(ModifierLoc, diag::err_omp_unexpected_clause_value)
18413         << Values << getOpenMPClauseName(OMPC_device);
18414     ErrorFound = true;
18415   }
18416 
18417   Expr *ValExpr = Device;
18418   Stmt *HelperValStmt = nullptr;
18419 
18420   // OpenMP [2.9.1, Restrictions]
18421   // The device expression must evaluate to a non-negative integer value.
18422   ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device,
18423                                           /*StrictlyPositive=*/false) ||
18424                ErrorFound;
18425   if (ErrorFound)
18426     return nullptr;
18427 
18428   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
18429   OpenMPDirectiveKind CaptureRegion =
18430       getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP);
18431   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
18432     ValExpr = MakeFullExpr(ValExpr).get();
18433     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
18434     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
18435     HelperValStmt = buildPreInits(Context, Captures);
18436   }
18437 
18438   return new (Context)
18439       OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc,
18440                       LParenLoc, ModifierLoc, EndLoc);
18441 }
18442 
checkTypeMappable(SourceLocation SL,SourceRange SR,Sema & SemaRef,DSAStackTy * Stack,QualType QTy,bool FullCheck=true)18443 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef,
18444                               DSAStackTy *Stack, QualType QTy,
18445                               bool FullCheck = true) {
18446   NamedDecl *ND;
18447   if (QTy->isIncompleteType(&ND)) {
18448     SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR;
18449     return false;
18450   }
18451   if (FullCheck && !SemaRef.CurContext->isDependentContext() &&
18452       !QTy.isTriviallyCopyableType(SemaRef.Context))
18453     SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR;
18454   return true;
18455 }
18456 
18457 /// Return true if it can be proven that the provided array expression
18458 /// (array section or array subscript) does NOT specify the whole size of the
18459 /// array whose base type is \a BaseQTy.
checkArrayExpressionDoesNotReferToWholeSize(Sema & SemaRef,const Expr * E,QualType BaseQTy)18460 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
18461                                                         const Expr *E,
18462                                                         QualType BaseQTy) {
18463   const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
18464 
18465   // If this is an array subscript, it refers to the whole size if the size of
18466   // the dimension is constant and equals 1. Also, an array section assumes the
18467   // format of an array subscript if no colon is used.
18468   if (isa<ArraySubscriptExpr>(E) ||
18469       (OASE && OASE->getColonLocFirst().isInvalid())) {
18470     if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
18471       return ATy->getSize().getSExtValue() != 1;
18472     // Size can't be evaluated statically.
18473     return false;
18474   }
18475 
18476   assert(OASE && "Expecting array section if not an array subscript.");
18477   const Expr *LowerBound = OASE->getLowerBound();
18478   const Expr *Length = OASE->getLength();
18479 
18480   // If there is a lower bound that does not evaluates to zero, we are not
18481   // covering the whole dimension.
18482   if (LowerBound) {
18483     Expr::EvalResult Result;
18484     if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext()))
18485       return false; // Can't get the integer value as a constant.
18486 
18487     llvm::APSInt ConstLowerBound = Result.Val.getInt();
18488     if (ConstLowerBound.getSExtValue())
18489       return true;
18490   }
18491 
18492   // If we don't have a length we covering the whole dimension.
18493   if (!Length)
18494     return false;
18495 
18496   // If the base is a pointer, we don't have a way to get the size of the
18497   // pointee.
18498   if (BaseQTy->isPointerType())
18499     return false;
18500 
18501   // We can only check if the length is the same as the size of the dimension
18502   // if we have a constant array.
18503   const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr());
18504   if (!CATy)
18505     return false;
18506 
18507   Expr::EvalResult Result;
18508   if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
18509     return false; // Can't get the integer value as a constant.
18510 
18511   llvm::APSInt ConstLength = Result.Val.getInt();
18512   return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
18513 }
18514 
18515 // Return true if it can be proven that the provided array expression (array
18516 // section or array subscript) does NOT specify a single element of the array
18517 // whose base type is \a BaseQTy.
checkArrayExpressionDoesNotReferToUnitySize(Sema & SemaRef,const Expr * E,QualType BaseQTy)18518 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
18519                                                         const Expr *E,
18520                                                         QualType BaseQTy) {
18521   const auto *OASE = dyn_cast<OMPArraySectionExpr>(E);
18522 
18523   // An array subscript always refer to a single element. Also, an array section
18524   // assumes the format of an array subscript if no colon is used.
18525   if (isa<ArraySubscriptExpr>(E) ||
18526       (OASE && OASE->getColonLocFirst().isInvalid()))
18527     return false;
18528 
18529   assert(OASE && "Expecting array section if not an array subscript.");
18530   const Expr *Length = OASE->getLength();
18531 
18532   // If we don't have a length we have to check if the array has unitary size
18533   // for this dimension. Also, we should always expect a length if the base type
18534   // is pointer.
18535   if (!Length) {
18536     if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
18537       return ATy->getSize().getSExtValue() != 1;
18538     // We cannot assume anything.
18539     return false;
18540   }
18541 
18542   // Check if the length evaluates to 1.
18543   Expr::EvalResult Result;
18544   if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext()))
18545     return false; // Can't get the integer value as a constant.
18546 
18547   llvm::APSInt ConstLength = Result.Val.getInt();
18548   return ConstLength.getSExtValue() != 1;
18549 }
18550 
18551 // The base of elements of list in a map clause have to be either:
18552 //  - a reference to variable or field.
18553 //  - a member expression.
18554 //  - an array expression.
18555 //
18556 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the
18557 // reference to 'r'.
18558 //
18559 // If we have:
18560 //
18561 // struct SS {
18562 //   Bla S;
18563 //   foo() {
18564 //     #pragma omp target map (S.Arr[:12]);
18565 //   }
18566 // }
18567 //
18568 // We want to retrieve the member expression 'this->S';
18569 
18570 // OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2]
18571 //  If a list item is an array section, it must specify contiguous storage.
18572 //
18573 // For this restriction it is sufficient that we make sure only references
18574 // to variables or fields and array expressions, and that no array sections
18575 // exist except in the rightmost expression (unless they cover the whole
18576 // dimension of the array). E.g. these would be invalid:
18577 //
18578 //   r.ArrS[3:5].Arr[6:7]
18579 //
18580 //   r.ArrS[3:5].x
18581 //
18582 // but these would be valid:
18583 //   r.ArrS[3].Arr[6:7]
18584 //
18585 //   r.ArrS[3].x
18586 namespace {
18587 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> {
18588   Sema &SemaRef;
18589   OpenMPClauseKind CKind = OMPC_unknown;
18590   OpenMPDirectiveKind DKind = OMPD_unknown;
18591   OMPClauseMappableExprCommon::MappableExprComponentList &Components;
18592   bool IsNonContiguous = false;
18593   bool NoDiagnose = false;
18594   const Expr *RelevantExpr = nullptr;
18595   bool AllowUnitySizeArraySection = true;
18596   bool AllowWholeSizeArraySection = true;
18597   bool AllowAnotherPtr = true;
18598   SourceLocation ELoc;
18599   SourceRange ERange;
18600 
emitErrorMsg()18601   void emitErrorMsg() {
18602     // If nothing else worked, this is not a valid map clause expression.
18603     if (SemaRef.getLangOpts().OpenMP < 50) {
18604       SemaRef.Diag(ELoc,
18605                    diag::err_omp_expected_named_var_member_or_array_expression)
18606           << ERange;
18607     } else {
18608       SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
18609           << getOpenMPClauseName(CKind) << ERange;
18610     }
18611   }
18612 
18613 public:
VisitDeclRefExpr(DeclRefExpr * DRE)18614   bool VisitDeclRefExpr(DeclRefExpr *DRE) {
18615     if (!isa<VarDecl>(DRE->getDecl())) {
18616       emitErrorMsg();
18617       return false;
18618     }
18619     assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
18620     RelevantExpr = DRE;
18621     // Record the component.
18622     Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous);
18623     return true;
18624   }
18625 
VisitMemberExpr(MemberExpr * ME)18626   bool VisitMemberExpr(MemberExpr *ME) {
18627     Expr *E = ME;
18628     Expr *BaseE = ME->getBase()->IgnoreParenCasts();
18629 
18630     if (isa<CXXThisExpr>(BaseE)) {
18631       assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
18632       // We found a base expression: this->Val.
18633       RelevantExpr = ME;
18634     } else {
18635       E = BaseE;
18636     }
18637 
18638     if (!isa<FieldDecl>(ME->getMemberDecl())) {
18639       if (!NoDiagnose) {
18640         SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field)
18641           << ME->getSourceRange();
18642         return false;
18643       }
18644       if (RelevantExpr)
18645         return false;
18646       return Visit(E);
18647     }
18648 
18649     auto *FD = cast<FieldDecl>(ME->getMemberDecl());
18650 
18651     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3]
18652     //  A bit-field cannot appear in a map clause.
18653     //
18654     if (FD->isBitField()) {
18655       if (!NoDiagnose) {
18656         SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause)
18657           << ME->getSourceRange() << getOpenMPClauseName(CKind);
18658         return false;
18659       }
18660       if (RelevantExpr)
18661         return false;
18662       return Visit(E);
18663     }
18664 
18665     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
18666     //  If the type of a list item is a reference to a type T then the type
18667     //  will be considered to be T for all purposes of this clause.
18668     QualType CurType = BaseE->getType().getNonReferenceType();
18669 
18670     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2]
18671     //  A list item cannot be a variable that is a member of a structure with
18672     //  a union type.
18673     //
18674     if (CurType->isUnionType()) {
18675       if (!NoDiagnose) {
18676         SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed)
18677           << ME->getSourceRange();
18678         return false;
18679       }
18680       return RelevantExpr || Visit(E);
18681     }
18682 
18683     // If we got a member expression, we should not expect any array section
18684     // before that:
18685     //
18686     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7]
18687     //  If a list item is an element of a structure, only the rightmost symbol
18688     //  of the variable reference can be an array section.
18689     //
18690     AllowUnitySizeArraySection = false;
18691     AllowWholeSizeArraySection = false;
18692 
18693     // Record the component.
18694     Components.emplace_back(ME, FD, IsNonContiguous);
18695     return RelevantExpr || Visit(E);
18696   }
18697 
VisitArraySubscriptExpr(ArraySubscriptExpr * AE)18698   bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) {
18699     Expr *E = AE->getBase()->IgnoreParenImpCasts();
18700 
18701     if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) {
18702       if (!NoDiagnose) {
18703         SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
18704           << 0 << AE->getSourceRange();
18705         return false;
18706       }
18707       return RelevantExpr || Visit(E);
18708     }
18709 
18710     // If we got an array subscript that express the whole dimension we
18711     // can have any array expressions before. If it only expressing part of
18712     // the dimension, we can only have unitary-size array expressions.
18713     if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE,
18714                                                     E->getType()))
18715       AllowWholeSizeArraySection = false;
18716 
18717     if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) {
18718       Expr::EvalResult Result;
18719       if (!AE->getIdx()->isValueDependent() &&
18720           AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) &&
18721           !Result.Val.getInt().isNullValue()) {
18722         SemaRef.Diag(AE->getIdx()->getExprLoc(),
18723                      diag::err_omp_invalid_map_this_expr);
18724         SemaRef.Diag(AE->getIdx()->getExprLoc(),
18725                      diag::note_omp_invalid_subscript_on_this_ptr_map);
18726       }
18727       assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
18728       RelevantExpr = TE;
18729     }
18730 
18731     // Record the component - we don't have any declaration associated.
18732     Components.emplace_back(AE, nullptr, IsNonContiguous);
18733 
18734     return RelevantExpr || Visit(E);
18735   }
18736 
VisitOMPArraySectionExpr(OMPArraySectionExpr * OASE)18737   bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) {
18738     assert(!NoDiagnose && "Array sections cannot be implicitly mapped.");
18739     Expr *E = OASE->getBase()->IgnoreParenImpCasts();
18740     QualType CurType =
18741       OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
18742 
18743     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
18744     //  If the type of a list item is a reference to a type T then the type
18745     //  will be considered to be T for all purposes of this clause.
18746     if (CurType->isReferenceType())
18747       CurType = CurType->getPointeeType();
18748 
18749     bool IsPointer = CurType->isAnyPointerType();
18750 
18751     if (!IsPointer && !CurType->isArrayType()) {
18752       SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name)
18753         << 0 << OASE->getSourceRange();
18754       return false;
18755     }
18756 
18757     bool NotWhole =
18758       checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType);
18759     bool NotUnity =
18760       checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType);
18761 
18762     if (AllowWholeSizeArraySection) {
18763       // Any array section is currently allowed. Allowing a whole size array
18764       // section implies allowing a unity array section as well.
18765       //
18766       // If this array section refers to the whole dimension we can still
18767       // accept other array sections before this one, except if the base is a
18768       // pointer. Otherwise, only unitary sections are accepted.
18769       if (NotWhole || IsPointer)
18770         AllowWholeSizeArraySection = false;
18771     } else if (DKind == OMPD_target_update &&
18772                SemaRef.getLangOpts().OpenMP >= 50) {
18773       if (IsPointer && !AllowAnotherPtr)
18774         SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined)
18775             << /*array of unknown bound */ 1;
18776       else
18777         IsNonContiguous = true;
18778     } else if (AllowUnitySizeArraySection && NotUnity) {
18779       // A unity or whole array section is not allowed and that is not
18780       // compatible with the properties of the current array section.
18781       SemaRef.Diag(
18782         ELoc, diag::err_array_section_does_not_specify_contiguous_storage)
18783         << OASE->getSourceRange();
18784       return false;
18785     }
18786 
18787     if (IsPointer)
18788       AllowAnotherPtr = false;
18789 
18790     if (const auto *TE = dyn_cast<CXXThisExpr>(E)) {
18791       Expr::EvalResult ResultR;
18792       Expr::EvalResult ResultL;
18793       if (!OASE->getLength()->isValueDependent() &&
18794           OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) &&
18795           !ResultR.Val.getInt().isOneValue()) {
18796         SemaRef.Diag(OASE->getLength()->getExprLoc(),
18797                      diag::err_omp_invalid_map_this_expr);
18798         SemaRef.Diag(OASE->getLength()->getExprLoc(),
18799                      diag::note_omp_invalid_length_on_this_ptr_mapping);
18800       }
18801       if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() &&
18802           OASE->getLowerBound()->EvaluateAsInt(ResultL,
18803                                                SemaRef.getASTContext()) &&
18804           !ResultL.Val.getInt().isNullValue()) {
18805         SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
18806                      diag::err_omp_invalid_map_this_expr);
18807         SemaRef.Diag(OASE->getLowerBound()->getExprLoc(),
18808                      diag::note_omp_invalid_lower_bound_on_this_ptr_mapping);
18809       }
18810       assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
18811       RelevantExpr = TE;
18812     }
18813 
18814     // Record the component - we don't have any declaration associated.
18815     Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false);
18816     return RelevantExpr || Visit(E);
18817   }
VisitOMPArrayShapingExpr(OMPArrayShapingExpr * E)18818   bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) {
18819     Expr *Base = E->getBase();
18820 
18821     // Record the component - we don't have any declaration associated.
18822     Components.emplace_back(E, nullptr, IsNonContiguous);
18823 
18824     return Visit(Base->IgnoreParenImpCasts());
18825   }
18826 
VisitUnaryOperator(UnaryOperator * UO)18827   bool VisitUnaryOperator(UnaryOperator *UO) {
18828     if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() ||
18829         UO->getOpcode() != UO_Deref) {
18830       emitErrorMsg();
18831       return false;
18832     }
18833     if (!RelevantExpr) {
18834       // Record the component if haven't found base decl.
18835       Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false);
18836     }
18837     return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts());
18838   }
VisitBinaryOperator(BinaryOperator * BO)18839   bool VisitBinaryOperator(BinaryOperator *BO) {
18840     if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) {
18841       emitErrorMsg();
18842       return false;
18843     }
18844 
18845     // Pointer arithmetic is the only thing we expect to happen here so after we
18846     // make sure the binary operator is a pointer type, the we only thing need
18847     // to to is to visit the subtree that has the same type as root (so that we
18848     // know the other subtree is just an offset)
18849     Expr *LE = BO->getLHS()->IgnoreParenImpCasts();
18850     Expr *RE = BO->getRHS()->IgnoreParenImpCasts();
18851     Components.emplace_back(BO, nullptr, false);
18852     assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() ||
18853             RE->getType().getTypePtr() == BO->getType().getTypePtr()) &&
18854            "Either LHS or RHS have base decl inside");
18855     if (BO->getType().getTypePtr() == LE->getType().getTypePtr())
18856       return RelevantExpr || Visit(LE);
18857     return RelevantExpr || Visit(RE);
18858   }
VisitCXXThisExpr(CXXThisExpr * CTE)18859   bool VisitCXXThisExpr(CXXThisExpr *CTE) {
18860     assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
18861     RelevantExpr = CTE;
18862     Components.emplace_back(CTE, nullptr, IsNonContiguous);
18863     return true;
18864   }
VisitCXXOperatorCallExpr(CXXOperatorCallExpr * COCE)18865   bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) {
18866     assert(!RelevantExpr && "RelevantExpr is expected to be nullptr");
18867     Components.emplace_back(COCE, nullptr, IsNonContiguous);
18868     return true;
18869   }
VisitOpaqueValueExpr(OpaqueValueExpr * E)18870   bool VisitOpaqueValueExpr(OpaqueValueExpr *E) {
18871     Expr *Source = E->getSourceExpr();
18872     if (!Source) {
18873       emitErrorMsg();
18874       return false;
18875     }
18876     return Visit(Source);
18877   }
VisitStmt(Stmt *)18878   bool VisitStmt(Stmt *) {
18879     emitErrorMsg();
18880     return false;
18881   }
getFoundBase() const18882   const Expr *getFoundBase() const {
18883     return RelevantExpr;
18884   }
MapBaseChecker(Sema & SemaRef,OpenMPClauseKind CKind,OpenMPDirectiveKind DKind,OMPClauseMappableExprCommon::MappableExprComponentList & Components,bool NoDiagnose,SourceLocation & ELoc,SourceRange & ERange)18885   explicit MapBaseChecker(
18886       Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind,
18887       OMPClauseMappableExprCommon::MappableExprComponentList &Components,
18888       bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange)
18889       : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components),
18890         NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {}
18891 };
18892 } // namespace
18893 
18894 /// Return the expression of the base of the mappable expression or null if it
18895 /// cannot be determined and do all the necessary checks to see if the expression
18896 /// is valid as a standalone mappable expression. In the process, record all the
18897 /// components of the expression.
checkMapClauseExpressionBase(Sema & SemaRef,Expr * E,OMPClauseMappableExprCommon::MappableExprComponentList & CurComponents,OpenMPClauseKind CKind,OpenMPDirectiveKind DKind,bool NoDiagnose)18898 static const Expr *checkMapClauseExpressionBase(
18899     Sema &SemaRef, Expr *E,
18900     OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents,
18901     OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) {
18902   SourceLocation ELoc = E->getExprLoc();
18903   SourceRange ERange = E->getSourceRange();
18904   MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc,
18905                          ERange);
18906   if (Checker.Visit(E->IgnoreParens())) {
18907     // Check if the highest dimension array section has length specified
18908     if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() &&
18909         (CKind == OMPC_to || CKind == OMPC_from)) {
18910       auto CI = CurComponents.rbegin();
18911       auto CE = CurComponents.rend();
18912       for (; CI != CE; ++CI) {
18913         const auto *OASE =
18914             dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression());
18915         if (!OASE)
18916           continue;
18917         if (OASE && OASE->getLength())
18918           break;
18919         SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length)
18920             << ERange;
18921       }
18922     }
18923     return Checker.getFoundBase();
18924   }
18925   return nullptr;
18926 }
18927 
18928 // Return true if expression E associated with value VD has conflicts with other
18929 // map information.
checkMapConflicts(Sema & SemaRef,DSAStackTy * DSAS,const ValueDecl * VD,const Expr * E,bool CurrentRegionOnly,OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,OpenMPClauseKind CKind)18930 static bool checkMapConflicts(
18931     Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E,
18932     bool CurrentRegionOnly,
18933     OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents,
18934     OpenMPClauseKind CKind) {
18935   assert(VD && E);
18936   SourceLocation ELoc = E->getExprLoc();
18937   SourceRange ERange = E->getSourceRange();
18938 
18939   // In order to easily check the conflicts we need to match each component of
18940   // the expression under test with the components of the expressions that are
18941   // already in the stack.
18942 
18943   assert(!CurComponents.empty() && "Map clause expression with no components!");
18944   assert(CurComponents.back().getAssociatedDeclaration() == VD &&
18945          "Map clause expression with unexpected base!");
18946 
18947   // Variables to help detecting enclosing problems in data environment nests.
18948   bool IsEnclosedByDataEnvironmentExpr = false;
18949   const Expr *EnclosingExpr = nullptr;
18950 
18951   bool FoundError = DSAS->checkMappableExprComponentListsForDecl(
18952       VD, CurrentRegionOnly,
18953       [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc,
18954        ERange, CKind, &EnclosingExpr,
18955        CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef
18956                           StackComponents,
18957                       OpenMPClauseKind Kind) {
18958         if (CKind == Kind && SemaRef.LangOpts.OpenMP >= 50)
18959           return false;
18960         assert(!StackComponents.empty() &&
18961                "Map clause expression with no components!");
18962         assert(StackComponents.back().getAssociatedDeclaration() == VD &&
18963                "Map clause expression with unexpected base!");
18964         (void)VD;
18965 
18966         // The whole expression in the stack.
18967         const Expr *RE = StackComponents.front().getAssociatedExpression();
18968 
18969         // Expressions must start from the same base. Here we detect at which
18970         // point both expressions diverge from each other and see if we can
18971         // detect if the memory referred to both expressions is contiguous and
18972         // do not overlap.
18973         auto CI = CurComponents.rbegin();
18974         auto CE = CurComponents.rend();
18975         auto SI = StackComponents.rbegin();
18976         auto SE = StackComponents.rend();
18977         for (; CI != CE && SI != SE; ++CI, ++SI) {
18978 
18979           // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3]
18980           //  At most one list item can be an array item derived from a given
18981           //  variable in map clauses of the same construct.
18982           if (CurrentRegionOnly &&
18983               (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) ||
18984                isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) ||
18985                isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) &&
18986               (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) ||
18987                isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) ||
18988                isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) {
18989             SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(),
18990                          diag::err_omp_multiple_array_items_in_map_clause)
18991                 << CI->getAssociatedExpression()->getSourceRange();
18992             SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(),
18993                          diag::note_used_here)
18994                 << SI->getAssociatedExpression()->getSourceRange();
18995             return true;
18996           }
18997 
18998           // Do both expressions have the same kind?
18999           if (CI->getAssociatedExpression()->getStmtClass() !=
19000               SI->getAssociatedExpression()->getStmtClass())
19001             break;
19002 
19003           // Are we dealing with different variables/fields?
19004           if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration())
19005             break;
19006         }
19007         // Check if the extra components of the expressions in the enclosing
19008         // data environment are redundant for the current base declaration.
19009         // If they are, the maps completely overlap, which is legal.
19010         for (; SI != SE; ++SI) {
19011           QualType Type;
19012           if (const auto *ASE =
19013                   dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) {
19014             Type = ASE->getBase()->IgnoreParenImpCasts()->getType();
19015           } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(
19016                          SI->getAssociatedExpression())) {
19017             const Expr *E = OASE->getBase()->IgnoreParenImpCasts();
19018             Type =
19019                 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType();
19020           } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>(
19021                          SI->getAssociatedExpression())) {
19022             Type = OASE->getBase()->getType()->getPointeeType();
19023           }
19024           if (Type.isNull() || Type->isAnyPointerType() ||
19025               checkArrayExpressionDoesNotReferToWholeSize(
19026                   SemaRef, SI->getAssociatedExpression(), Type))
19027             break;
19028         }
19029 
19030         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
19031         //  List items of map clauses in the same construct must not share
19032         //  original storage.
19033         //
19034         // If the expressions are exactly the same or one is a subset of the
19035         // other, it means they are sharing storage.
19036         if (CI == CE && SI == SE) {
19037           if (CurrentRegionOnly) {
19038             if (CKind == OMPC_map) {
19039               SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
19040             } else {
19041               assert(CKind == OMPC_to || CKind == OMPC_from);
19042               SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
19043                   << ERange;
19044             }
19045             SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
19046                 << RE->getSourceRange();
19047             return true;
19048           }
19049           // If we find the same expression in the enclosing data environment,
19050           // that is legal.
19051           IsEnclosedByDataEnvironmentExpr = true;
19052           return false;
19053         }
19054 
19055         QualType DerivedType =
19056             std::prev(CI)->getAssociatedDeclaration()->getType();
19057         SourceLocation DerivedLoc =
19058             std::prev(CI)->getAssociatedExpression()->getExprLoc();
19059 
19060         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
19061         //  If the type of a list item is a reference to a type T then the type
19062         //  will be considered to be T for all purposes of this clause.
19063         DerivedType = DerivedType.getNonReferenceType();
19064 
19065         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1]
19066         //  A variable for which the type is pointer and an array section
19067         //  derived from that variable must not appear as list items of map
19068         //  clauses of the same construct.
19069         //
19070         // Also, cover one of the cases in:
19071         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
19072         //  If any part of the original storage of a list item has corresponding
19073         //  storage in the device data environment, all of the original storage
19074         //  must have corresponding storage in the device data environment.
19075         //
19076         if (DerivedType->isAnyPointerType()) {
19077           if (CI == CE || SI == SE) {
19078             SemaRef.Diag(
19079                 DerivedLoc,
19080                 diag::err_omp_pointer_mapped_along_with_derived_section)
19081                 << DerivedLoc;
19082             SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
19083                 << RE->getSourceRange();
19084             return true;
19085           }
19086           if (CI->getAssociatedExpression()->getStmtClass() !=
19087                          SI->getAssociatedExpression()->getStmtClass() ||
19088                      CI->getAssociatedDeclaration()->getCanonicalDecl() ==
19089                          SI->getAssociatedDeclaration()->getCanonicalDecl()) {
19090             assert(CI != CE && SI != SE);
19091             SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced)
19092                 << DerivedLoc;
19093             SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
19094                 << RE->getSourceRange();
19095             return true;
19096           }
19097         }
19098 
19099         // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4]
19100         //  List items of map clauses in the same construct must not share
19101         //  original storage.
19102         //
19103         // An expression is a subset of the other.
19104         if (CurrentRegionOnly && (CI == CE || SI == SE)) {
19105           if (CKind == OMPC_map) {
19106             if (CI != CE || SI != SE) {
19107               // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is
19108               // a pointer.
19109               auto Begin =
19110                   CI != CE ? CurComponents.begin() : StackComponents.begin();
19111               auto End = CI != CE ? CurComponents.end() : StackComponents.end();
19112               auto It = Begin;
19113               while (It != End && !It->getAssociatedDeclaration())
19114                 std::advance(It, 1);
19115               assert(It != End &&
19116                      "Expected at least one component with the declaration.");
19117               if (It != Begin && It->getAssociatedDeclaration()
19118                                      ->getType()
19119                                      .getCanonicalType()
19120                                      ->isAnyPointerType()) {
19121                 IsEnclosedByDataEnvironmentExpr = false;
19122                 EnclosingExpr = nullptr;
19123                 return false;
19124               }
19125             }
19126             SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange;
19127           } else {
19128             assert(CKind == OMPC_to || CKind == OMPC_from);
19129             SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update)
19130                 << ERange;
19131           }
19132           SemaRef.Diag(RE->getExprLoc(), diag::note_used_here)
19133               << RE->getSourceRange();
19134           return true;
19135         }
19136 
19137         // The current expression uses the same base as other expression in the
19138         // data environment but does not contain it completely.
19139         if (!CurrentRegionOnly && SI != SE)
19140           EnclosingExpr = RE;
19141 
19142         // The current expression is a subset of the expression in the data
19143         // environment.
19144         IsEnclosedByDataEnvironmentExpr |=
19145             (!CurrentRegionOnly && CI != CE && SI == SE);
19146 
19147         return false;
19148       });
19149 
19150   if (CurrentRegionOnly)
19151     return FoundError;
19152 
19153   // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5]
19154   //  If any part of the original storage of a list item has corresponding
19155   //  storage in the device data environment, all of the original storage must
19156   //  have corresponding storage in the device data environment.
19157   // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6]
19158   //  If a list item is an element of a structure, and a different element of
19159   //  the structure has a corresponding list item in the device data environment
19160   //  prior to a task encountering the construct associated with the map clause,
19161   //  then the list item must also have a corresponding list item in the device
19162   //  data environment prior to the task encountering the construct.
19163   //
19164   if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) {
19165     SemaRef.Diag(ELoc,
19166                  diag::err_omp_original_storage_is_shared_and_does_not_contain)
19167         << ERange;
19168     SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here)
19169         << EnclosingExpr->getSourceRange();
19170     return true;
19171   }
19172 
19173   return FoundError;
19174 }
19175 
19176 // Look up the user-defined mapper given the mapper name and mapped type, and
19177 // build a reference to it.
buildUserDefinedMapperRef(Sema & SemaRef,Scope * S,CXXScopeSpec & MapperIdScopeSpec,const DeclarationNameInfo & MapperId,QualType Type,Expr * UnresolvedMapper)19178 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S,
19179                                             CXXScopeSpec &MapperIdScopeSpec,
19180                                             const DeclarationNameInfo &MapperId,
19181                                             QualType Type,
19182                                             Expr *UnresolvedMapper) {
19183   if (MapperIdScopeSpec.isInvalid())
19184     return ExprError();
19185   // Get the actual type for the array type.
19186   if (Type->isArrayType()) {
19187     assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type");
19188     Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType();
19189   }
19190   // Find all user-defined mappers with the given MapperId.
19191   SmallVector<UnresolvedSet<8>, 4> Lookups;
19192   LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName);
19193   Lookup.suppressDiagnostics();
19194   if (S) {
19195     while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) {
19196       NamedDecl *D = Lookup.getRepresentativeDecl();
19197       while (S && !S->isDeclScope(D))
19198         S = S->getParent();
19199       if (S)
19200         S = S->getParent();
19201       Lookups.emplace_back();
19202       Lookups.back().append(Lookup.begin(), Lookup.end());
19203       Lookup.clear();
19204     }
19205   } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) {
19206     // Extract the user-defined mappers with the given MapperId.
19207     Lookups.push_back(UnresolvedSet<8>());
19208     for (NamedDecl *D : ULE->decls()) {
19209       auto *DMD = cast<OMPDeclareMapperDecl>(D);
19210       assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation.");
19211       Lookups.back().addDecl(DMD);
19212     }
19213   }
19214   // Defer the lookup for dependent types. The results will be passed through
19215   // UnresolvedMapper on instantiation.
19216   if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() ||
19217       Type->isInstantiationDependentType() ||
19218       Type->containsUnexpandedParameterPack() ||
19219       filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) {
19220         return !D->isInvalidDecl() &&
19221                (D->getType()->isDependentType() ||
19222                 D->getType()->isInstantiationDependentType() ||
19223                 D->getType()->containsUnexpandedParameterPack());
19224       })) {
19225     UnresolvedSet<8> URS;
19226     for (const UnresolvedSet<8> &Set : Lookups) {
19227       if (Set.empty())
19228         continue;
19229       URS.append(Set.begin(), Set.end());
19230     }
19231     return UnresolvedLookupExpr::Create(
19232         SemaRef.Context, /*NamingClass=*/nullptr,
19233         MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId,
19234         /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end());
19235   }
19236   SourceLocation Loc = MapperId.getLoc();
19237   // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
19238   //  The type must be of struct, union or class type in C and C++
19239   if (!Type->isStructureOrClassType() && !Type->isUnionType() &&
19240       (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) {
19241     SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type);
19242     return ExprError();
19243   }
19244   // Perform argument dependent lookup.
19245   if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet())
19246     argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups);
19247   // Return the first user-defined mapper with the desired type.
19248   if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
19249           Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * {
19250             if (!D->isInvalidDecl() &&
19251                 SemaRef.Context.hasSameType(D->getType(), Type))
19252               return D;
19253             return nullptr;
19254           }))
19255     return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
19256   // Find the first user-defined mapper with a type derived from the desired
19257   // type.
19258   if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>(
19259           Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * {
19260             if (!D->isInvalidDecl() &&
19261                 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) &&
19262                 !Type.isMoreQualifiedThan(D->getType()))
19263               return D;
19264             return nullptr;
19265           })) {
19266     CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
19267                        /*DetectVirtual=*/false);
19268     if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) {
19269       if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType(
19270               VD->getType().getUnqualifiedType()))) {
19271         if (SemaRef.CheckBaseClassAccess(
19272                 Loc, VD->getType(), Type, Paths.front(),
19273                 /*DiagID=*/0) != Sema::AR_inaccessible) {
19274           return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc);
19275         }
19276       }
19277     }
19278   }
19279   // Report error if a mapper is specified, but cannot be found.
19280   if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") {
19281     SemaRef.Diag(Loc, diag::err_omp_invalid_mapper)
19282         << Type << MapperId.getName();
19283     return ExprError();
19284   }
19285   return ExprEmpty();
19286 }
19287 
19288 namespace {
19289 // Utility struct that gathers all the related lists associated with a mappable
19290 // expression.
19291 struct MappableVarListInfo {
19292   // The list of expressions.
19293   ArrayRef<Expr *> VarList;
19294   // The list of processed expressions.
19295   SmallVector<Expr *, 16> ProcessedVarList;
19296   // The mappble components for each expression.
19297   OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents;
19298   // The base declaration of the variable.
19299   SmallVector<ValueDecl *, 16> VarBaseDeclarations;
19300   // The reference to the user-defined mapper associated with every expression.
19301   SmallVector<Expr *, 16> UDMapperList;
19302 
MappableVarListInfo__anondf8189525911::MappableVarListInfo19303   MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) {
19304     // We have a list of components and base declarations for each entry in the
19305     // variable list.
19306     VarComponents.reserve(VarList.size());
19307     VarBaseDeclarations.reserve(VarList.size());
19308   }
19309 };
19310 }
19311 
19312 // Check the validity of the provided variable list for the provided clause kind
19313 // \a CKind. In the check process the valid expressions, mappable expression
19314 // components, variables, and user-defined mappers are extracted and used to
19315 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a
19316 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec,
19317 // 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)19318 static void checkMappableExpressionList(
19319     Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind,
19320     MappableVarListInfo &MVLI, SourceLocation StartLoc,
19321     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId,
19322     ArrayRef<Expr *> UnresolvedMappers,
19323     OpenMPMapClauseKind MapType = OMPC_MAP_unknown,
19324     bool IsMapTypeImplicit = false) {
19325   // We only expect mappable expressions in 'to', 'from', and 'map' clauses.
19326   assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) &&
19327          "Unexpected clause kind with mappable expressions!");
19328 
19329   // If the identifier of user-defined mapper is not specified, it is "default".
19330   // We do not change the actual name in this clause to distinguish whether a
19331   // mapper is specified explicitly, i.e., it is not explicitly specified when
19332   // MapperId.getName() is empty.
19333   if (!MapperId.getName() || MapperId.getName().isEmpty()) {
19334     auto &DeclNames = SemaRef.getASTContext().DeclarationNames;
19335     MapperId.setName(DeclNames.getIdentifier(
19336         &SemaRef.getASTContext().Idents.get("default")));
19337     MapperId.setLoc(StartLoc);
19338   }
19339 
19340   // Iterators to find the current unresolved mapper expression.
19341   auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end();
19342   bool UpdateUMIt = false;
19343   Expr *UnresolvedMapper = nullptr;
19344 
19345   // Keep track of the mappable components and base declarations in this clause.
19346   // Each entry in the list is going to have a list of components associated. We
19347   // record each set of the components so that we can build the clause later on.
19348   // In the end we should have the same amount of declarations and component
19349   // lists.
19350 
19351   for (Expr *RE : MVLI.VarList) {
19352     assert(RE && "Null expr in omp to/from/map clause");
19353     SourceLocation ELoc = RE->getExprLoc();
19354 
19355     // Find the current unresolved mapper expression.
19356     if (UpdateUMIt && UMIt != UMEnd) {
19357       UMIt++;
19358       assert(
19359           UMIt != UMEnd &&
19360           "Expect the size of UnresolvedMappers to match with that of VarList");
19361     }
19362     UpdateUMIt = true;
19363     if (UMIt != UMEnd)
19364       UnresolvedMapper = *UMIt;
19365 
19366     const Expr *VE = RE->IgnoreParenLValueCasts();
19367 
19368     if (VE->isValueDependent() || VE->isTypeDependent() ||
19369         VE->isInstantiationDependent() ||
19370         VE->containsUnexpandedParameterPack()) {
19371       // Try to find the associated user-defined mapper.
19372       ExprResult ER = buildUserDefinedMapperRef(
19373           SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
19374           VE->getType().getCanonicalType(), UnresolvedMapper);
19375       if (ER.isInvalid())
19376         continue;
19377       MVLI.UDMapperList.push_back(ER.get());
19378       // We can only analyze this information once the missing information is
19379       // resolved.
19380       MVLI.ProcessedVarList.push_back(RE);
19381       continue;
19382     }
19383 
19384     Expr *SimpleExpr = RE->IgnoreParenCasts();
19385 
19386     if (!RE->isLValue()) {
19387       if (SemaRef.getLangOpts().OpenMP < 50) {
19388         SemaRef.Diag(
19389             ELoc, diag::err_omp_expected_named_var_member_or_array_expression)
19390             << RE->getSourceRange();
19391       } else {
19392         SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses)
19393             << getOpenMPClauseName(CKind) << RE->getSourceRange();
19394       }
19395       continue;
19396     }
19397 
19398     OMPClauseMappableExprCommon::MappableExprComponentList CurComponents;
19399     ValueDecl *CurDeclaration = nullptr;
19400 
19401     // Obtain the array or member expression bases if required. Also, fill the
19402     // components array with all the components identified in the process.
19403     const Expr *BE = checkMapClauseExpressionBase(
19404         SemaRef, SimpleExpr, CurComponents, CKind, DSAS->getCurrentDirective(),
19405         /*NoDiagnose=*/false);
19406     if (!BE)
19407       continue;
19408 
19409     assert(!CurComponents.empty() &&
19410            "Invalid mappable expression information.");
19411 
19412     if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) {
19413       // Add store "this" pointer to class in DSAStackTy for future checking
19414       DSAS->addMappedClassesQualTypes(TE->getType());
19415       // Try to find the associated user-defined mapper.
19416       ExprResult ER = buildUserDefinedMapperRef(
19417           SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
19418           VE->getType().getCanonicalType(), UnresolvedMapper);
19419       if (ER.isInvalid())
19420         continue;
19421       MVLI.UDMapperList.push_back(ER.get());
19422       // Skip restriction checking for variable or field declarations
19423       MVLI.ProcessedVarList.push_back(RE);
19424       MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
19425       MVLI.VarComponents.back().append(CurComponents.begin(),
19426                                        CurComponents.end());
19427       MVLI.VarBaseDeclarations.push_back(nullptr);
19428       continue;
19429     }
19430 
19431     // For the following checks, we rely on the base declaration which is
19432     // expected to be associated with the last component. The declaration is
19433     // expected to be a variable or a field (if 'this' is being mapped).
19434     CurDeclaration = CurComponents.back().getAssociatedDeclaration();
19435     assert(CurDeclaration && "Null decl on map clause.");
19436     assert(
19437         CurDeclaration->isCanonicalDecl() &&
19438         "Expecting components to have associated only canonical declarations.");
19439 
19440     auto *VD = dyn_cast<VarDecl>(CurDeclaration);
19441     const auto *FD = dyn_cast<FieldDecl>(CurDeclaration);
19442 
19443     assert((VD || FD) && "Only variables or fields are expected here!");
19444     (void)FD;
19445 
19446     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10]
19447     // threadprivate variables cannot appear in a map clause.
19448     // OpenMP 4.5 [2.10.5, target update Construct]
19449     // threadprivate variables cannot appear in a from clause.
19450     if (VD && DSAS->isThreadPrivate(VD)) {
19451       DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
19452       SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause)
19453           << getOpenMPClauseName(CKind);
19454       reportOriginalDsa(SemaRef, DSAS, VD, DVar);
19455       continue;
19456     }
19457 
19458     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
19459     //  A list item cannot appear in both a map clause and a data-sharing
19460     //  attribute clause on the same construct.
19461 
19462     // Check conflicts with other map clause expressions. We check the conflicts
19463     // with the current construct separately from the enclosing data
19464     // environment, because the restrictions are different. We only have to
19465     // check conflicts across regions for the map clauses.
19466     if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
19467                           /*CurrentRegionOnly=*/true, CurComponents, CKind))
19468       break;
19469     if (CKind == OMPC_map &&
19470         (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) &&
19471         checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr,
19472                           /*CurrentRegionOnly=*/false, CurComponents, CKind))
19473       break;
19474 
19475     // OpenMP 4.5 [2.10.5, target update Construct]
19476     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1]
19477     //  If the type of a list item is a reference to a type T then the type will
19478     //  be considered to be T for all purposes of this clause.
19479     auto I = llvm::find_if(
19480         CurComponents,
19481         [](const OMPClauseMappableExprCommon::MappableComponent &MC) {
19482           return MC.getAssociatedDeclaration();
19483         });
19484     assert(I != CurComponents.end() && "Null decl on map clause.");
19485     (void)I;
19486     QualType Type;
19487     auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens());
19488     auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens());
19489     auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens());
19490     if (ASE) {
19491       Type = ASE->getType().getNonReferenceType();
19492     } else if (OASE) {
19493       QualType BaseType =
19494           OMPArraySectionExpr::getBaseOriginalType(OASE->getBase());
19495       if (const auto *ATy = BaseType->getAsArrayTypeUnsafe())
19496         Type = ATy->getElementType();
19497       else
19498         Type = BaseType->getPointeeType();
19499       Type = Type.getNonReferenceType();
19500     } else if (OAShE) {
19501       Type = OAShE->getBase()->getType()->getPointeeType();
19502     } else {
19503       Type = VE->getType();
19504     }
19505 
19506     // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4]
19507     // A list item in a to or from clause must have a mappable type.
19508     // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9]
19509     //  A list item must have a mappable type.
19510     if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef,
19511                            DSAS, Type))
19512       continue;
19513 
19514     if (CKind == OMPC_map) {
19515       // target enter data
19516       // OpenMP [2.10.2, Restrictions, p. 99]
19517       // A map-type must be specified in all map clauses and must be either
19518       // to or alloc.
19519       OpenMPDirectiveKind DKind = DSAS->getCurrentDirective();
19520       if (DKind == OMPD_target_enter_data &&
19521           !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) {
19522         SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
19523             << (IsMapTypeImplicit ? 1 : 0)
19524             << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
19525             << getOpenMPDirectiveName(DKind);
19526         continue;
19527       }
19528 
19529       // target exit_data
19530       // OpenMP [2.10.3, Restrictions, p. 102]
19531       // A map-type must be specified in all map clauses and must be either
19532       // from, release, or delete.
19533       if (DKind == OMPD_target_exit_data &&
19534           !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release ||
19535             MapType == OMPC_MAP_delete)) {
19536         SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
19537             << (IsMapTypeImplicit ? 1 : 0)
19538             << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
19539             << getOpenMPDirectiveName(DKind);
19540         continue;
19541       }
19542 
19543       // target, target data
19544       // OpenMP 5.0 [2.12.2, Restrictions, p. 163]
19545       // OpenMP 5.0 [2.12.5, Restrictions, p. 174]
19546       // A map-type in a map clause must be to, from, tofrom or alloc
19547       if ((DKind == OMPD_target_data ||
19548            isOpenMPTargetExecutionDirective(DKind)) &&
19549           !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from ||
19550             MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) {
19551         SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive)
19552             << (IsMapTypeImplicit ? 1 : 0)
19553             << getOpenMPSimpleClauseTypeName(OMPC_map, MapType)
19554             << getOpenMPDirectiveName(DKind);
19555         continue;
19556       }
19557 
19558       // OpenMP 4.5 [2.15.5.1, Restrictions, p.3]
19559       // A list item cannot appear in both a map clause and a data-sharing
19560       // attribute clause on the same construct
19561       //
19562       // OpenMP 5.0 [2.19.7.1, Restrictions, p.7]
19563       // A list item cannot appear in both a map clause and a data-sharing
19564       // attribute clause on the same construct unless the construct is a
19565       // combined construct.
19566       if (VD && ((SemaRef.LangOpts.OpenMP <= 45 &&
19567                   isOpenMPTargetExecutionDirective(DKind)) ||
19568                  DKind == OMPD_target)) {
19569         DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false);
19570         if (isOpenMPPrivate(DVar.CKind)) {
19571           SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
19572               << getOpenMPClauseName(DVar.CKind)
19573               << getOpenMPClauseName(OMPC_map)
19574               << getOpenMPDirectiveName(DSAS->getCurrentDirective());
19575           reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar);
19576           continue;
19577         }
19578       }
19579     }
19580 
19581     // Try to find the associated user-defined mapper.
19582     ExprResult ER = buildUserDefinedMapperRef(
19583         SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId,
19584         Type.getCanonicalType(), UnresolvedMapper);
19585     if (ER.isInvalid())
19586       continue;
19587     MVLI.UDMapperList.push_back(ER.get());
19588 
19589     // Save the current expression.
19590     MVLI.ProcessedVarList.push_back(RE);
19591 
19592     // Store the components in the stack so that they can be used to check
19593     // against other clauses later on.
19594     DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents,
19595                                           /*WhereFoundClauseKind=*/OMPC_map);
19596 
19597     // Save the components and declaration to create the clause. For purposes of
19598     // the clause creation, any component list that has has base 'this' uses
19599     // null as base declaration.
19600     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
19601     MVLI.VarComponents.back().append(CurComponents.begin(),
19602                                      CurComponents.end());
19603     MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr
19604                                                            : CurDeclaration);
19605   }
19606 }
19607 
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)19608 OMPClause *Sema::ActOnOpenMPMapClause(
19609     ArrayRef<OpenMPMapModifierKind> MapTypeModifiers,
19610     ArrayRef<SourceLocation> MapTypeModifiersLoc,
19611     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
19612     OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc,
19613     SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
19614     const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
19615   OpenMPMapModifierKind Modifiers[] = {
19616       OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown,
19617       OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown};
19618   SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers];
19619 
19620   // Process map-type-modifiers, flag errors for duplicate modifiers.
19621   unsigned Count = 0;
19622   for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) {
19623     if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown &&
19624         llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) {
19625       Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier);
19626       continue;
19627     }
19628     assert(Count < NumberOfOMPMapClauseModifiers &&
19629            "Modifiers exceed the allowed number of map type modifiers");
19630     Modifiers[Count] = MapTypeModifiers[I];
19631     ModifiersLoc[Count] = MapTypeModifiersLoc[I];
19632     ++Count;
19633   }
19634 
19635   MappableVarListInfo MVLI(VarList);
19636   checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc,
19637                               MapperIdScopeSpec, MapperId, UnresolvedMappers,
19638                               MapType, IsMapTypeImplicit);
19639 
19640   // We need to produce a map clause even if we don't have variables so that
19641   // other diagnostics related with non-existing map clauses are accurate.
19642   return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList,
19643                               MVLI.VarBaseDeclarations, MVLI.VarComponents,
19644                               MVLI.UDMapperList, Modifiers, ModifiersLoc,
19645                               MapperIdScopeSpec.getWithLocInContext(Context),
19646                               MapperId, MapType, IsMapTypeImplicit, MapLoc);
19647 }
19648 
ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,TypeResult ParsedType)19649 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc,
19650                                                TypeResult ParsedType) {
19651   assert(ParsedType.isUsable());
19652 
19653   QualType ReductionType = GetTypeFromParser(ParsedType.get());
19654   if (ReductionType.isNull())
19655     return QualType();
19656 
19657   // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++
19658   // A type name in a declare reduction directive cannot be a function type, an
19659   // array type, a reference type, or a type qualified with const, volatile or
19660   // restrict.
19661   if (ReductionType.hasQualifiers()) {
19662     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0;
19663     return QualType();
19664   }
19665 
19666   if (ReductionType->isFunctionType()) {
19667     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1;
19668     return QualType();
19669   }
19670   if (ReductionType->isReferenceType()) {
19671     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2;
19672     return QualType();
19673   }
19674   if (ReductionType->isArrayType()) {
19675     Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3;
19676     return QualType();
19677   }
19678   return ReductionType;
19679 }
19680 
ActOnOpenMPDeclareReductionDirectiveStart(Scope * S,DeclContext * DC,DeclarationName Name,ArrayRef<std::pair<QualType,SourceLocation>> ReductionTypes,AccessSpecifier AS,Decl * PrevDeclInScope)19681 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart(
19682     Scope *S, DeclContext *DC, DeclarationName Name,
19683     ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes,
19684     AccessSpecifier AS, Decl *PrevDeclInScope) {
19685   SmallVector<Decl *, 8> Decls;
19686   Decls.reserve(ReductionTypes.size());
19687 
19688   LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName,
19689                       forRedeclarationInCurContext());
19690   // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions
19691   // A reduction-identifier may not be re-declared in the current scope for the
19692   // same type or for a type that is compatible according to the base language
19693   // rules.
19694   llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
19695   OMPDeclareReductionDecl *PrevDRD = nullptr;
19696   bool InCompoundScope = true;
19697   if (S != nullptr) {
19698     // Find previous declaration with the same name not referenced in other
19699     // declarations.
19700     FunctionScopeInfo *ParentFn = getEnclosingFunction();
19701     InCompoundScope =
19702         (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
19703     LookupName(Lookup, S);
19704     FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
19705                          /*AllowInlineNamespace=*/false);
19706     llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious;
19707     LookupResult::Filter Filter = Lookup.makeFilter();
19708     while (Filter.hasNext()) {
19709       auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next());
19710       if (InCompoundScope) {
19711         auto I = UsedAsPrevious.find(PrevDecl);
19712         if (I == UsedAsPrevious.end())
19713           UsedAsPrevious[PrevDecl] = false;
19714         if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope())
19715           UsedAsPrevious[D] = true;
19716       }
19717       PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
19718           PrevDecl->getLocation();
19719     }
19720     Filter.done();
19721     if (InCompoundScope) {
19722       for (const auto &PrevData : UsedAsPrevious) {
19723         if (!PrevData.second) {
19724           PrevDRD = PrevData.first;
19725           break;
19726         }
19727       }
19728     }
19729   } else if (PrevDeclInScope != nullptr) {
19730     auto *PrevDRDInScope = PrevDRD =
19731         cast<OMPDeclareReductionDecl>(PrevDeclInScope);
19732     do {
19733       PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] =
19734           PrevDRDInScope->getLocation();
19735       PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope();
19736     } while (PrevDRDInScope != nullptr);
19737   }
19738   for (const auto &TyData : ReductionTypes) {
19739     const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType());
19740     bool Invalid = false;
19741     if (I != PreviousRedeclTypes.end()) {
19742       Diag(TyData.second, diag::err_omp_declare_reduction_redefinition)
19743           << TyData.first;
19744       Diag(I->second, diag::note_previous_definition);
19745       Invalid = true;
19746     }
19747     PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second;
19748     auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second,
19749                                                 Name, TyData.first, PrevDRD);
19750     DC->addDecl(DRD);
19751     DRD->setAccess(AS);
19752     Decls.push_back(DRD);
19753     if (Invalid)
19754       DRD->setInvalidDecl();
19755     else
19756       PrevDRD = DRD;
19757   }
19758 
19759   return DeclGroupPtrTy::make(
19760       DeclGroupRef::Create(Context, Decls.begin(), Decls.size()));
19761 }
19762 
ActOnOpenMPDeclareReductionCombinerStart(Scope * S,Decl * D)19763 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) {
19764   auto *DRD = cast<OMPDeclareReductionDecl>(D);
19765 
19766   // Enter new function scope.
19767   PushFunctionScope();
19768   setFunctionHasBranchProtectedScope();
19769   getCurFunction()->setHasOMPDeclareReductionCombiner();
19770 
19771   if (S != nullptr)
19772     PushDeclContext(S, DRD);
19773   else
19774     CurContext = DRD;
19775 
19776   PushExpressionEvaluationContext(
19777       ExpressionEvaluationContext::PotentiallyEvaluated);
19778 
19779   QualType ReductionType = DRD->getType();
19780   // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will
19781   // be replaced by '*omp_parm' during codegen. This required because 'omp_in'
19782   // uses semantics of argument handles by value, but it should be passed by
19783   // reference. C lang does not support references, so pass all parameters as
19784   // pointers.
19785   // Create 'T omp_in;' variable.
19786   VarDecl *OmpInParm =
19787       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in");
19788   // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will
19789   // be replaced by '*omp_parm' during codegen. This required because 'omp_out'
19790   // uses semantics of argument handles by value, but it should be passed by
19791   // reference. C lang does not support references, so pass all parameters as
19792   // pointers.
19793   // Create 'T omp_out;' variable.
19794   VarDecl *OmpOutParm =
19795       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out");
19796   if (S != nullptr) {
19797     PushOnScopeChains(OmpInParm, S);
19798     PushOnScopeChains(OmpOutParm, S);
19799   } else {
19800     DRD->addDecl(OmpInParm);
19801     DRD->addDecl(OmpOutParm);
19802   }
19803   Expr *InE =
19804       ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation());
19805   Expr *OutE =
19806       ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation());
19807   DRD->setCombinerData(InE, OutE);
19808 }
19809 
ActOnOpenMPDeclareReductionCombinerEnd(Decl * D,Expr * Combiner)19810 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) {
19811   auto *DRD = cast<OMPDeclareReductionDecl>(D);
19812   DiscardCleanupsInEvaluationContext();
19813   PopExpressionEvaluationContext();
19814 
19815   PopDeclContext();
19816   PopFunctionScopeInfo();
19817 
19818   if (Combiner != nullptr)
19819     DRD->setCombiner(Combiner);
19820   else
19821     DRD->setInvalidDecl();
19822 }
19823 
ActOnOpenMPDeclareReductionInitializerStart(Scope * S,Decl * D)19824 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) {
19825   auto *DRD = cast<OMPDeclareReductionDecl>(D);
19826 
19827   // Enter new function scope.
19828   PushFunctionScope();
19829   setFunctionHasBranchProtectedScope();
19830 
19831   if (S != nullptr)
19832     PushDeclContext(S, DRD);
19833   else
19834     CurContext = DRD;
19835 
19836   PushExpressionEvaluationContext(
19837       ExpressionEvaluationContext::PotentiallyEvaluated);
19838 
19839   QualType ReductionType = DRD->getType();
19840   // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will
19841   // be replaced by '*omp_parm' during codegen. This required because 'omp_priv'
19842   // uses semantics of argument handles by value, but it should be passed by
19843   // reference. C lang does not support references, so pass all parameters as
19844   // pointers.
19845   // Create 'T omp_priv;' variable.
19846   VarDecl *OmpPrivParm =
19847       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv");
19848   // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will
19849   // be replaced by '*omp_parm' during codegen. This required because 'omp_orig'
19850   // uses semantics of argument handles by value, but it should be passed by
19851   // reference. C lang does not support references, so pass all parameters as
19852   // pointers.
19853   // Create 'T omp_orig;' variable.
19854   VarDecl *OmpOrigParm =
19855       buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig");
19856   if (S != nullptr) {
19857     PushOnScopeChains(OmpPrivParm, S);
19858     PushOnScopeChains(OmpOrigParm, S);
19859   } else {
19860     DRD->addDecl(OmpPrivParm);
19861     DRD->addDecl(OmpOrigParm);
19862   }
19863   Expr *OrigE =
19864       ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation());
19865   Expr *PrivE =
19866       ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation());
19867   DRD->setInitializerData(OrigE, PrivE);
19868   return OmpPrivParm;
19869 }
19870 
ActOnOpenMPDeclareReductionInitializerEnd(Decl * D,Expr * Initializer,VarDecl * OmpPrivParm)19871 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer,
19872                                                      VarDecl *OmpPrivParm) {
19873   auto *DRD = cast<OMPDeclareReductionDecl>(D);
19874   DiscardCleanupsInEvaluationContext();
19875   PopExpressionEvaluationContext();
19876 
19877   PopDeclContext();
19878   PopFunctionScopeInfo();
19879 
19880   if (Initializer != nullptr) {
19881     DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit);
19882   } else if (OmpPrivParm->hasInit()) {
19883     DRD->setInitializer(OmpPrivParm->getInit(),
19884                         OmpPrivParm->isDirectInit()
19885                             ? OMPDeclareReductionDecl::DirectInit
19886                             : OMPDeclareReductionDecl::CopyInit);
19887   } else {
19888     DRD->setInvalidDecl();
19889   }
19890 }
19891 
ActOnOpenMPDeclareReductionDirectiveEnd(Scope * S,DeclGroupPtrTy DeclReductions,bool IsValid)19892 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd(
19893     Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) {
19894   for (Decl *D : DeclReductions.get()) {
19895     if (IsValid) {
19896       if (S)
19897         PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S,
19898                           /*AddToContext=*/false);
19899     } else {
19900       D->setInvalidDecl();
19901     }
19902   }
19903   return DeclReductions;
19904 }
19905 
ActOnOpenMPDeclareMapperVarDecl(Scope * S,Declarator & D)19906 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) {
19907   TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
19908   QualType T = TInfo->getType();
19909   if (D.isInvalidType())
19910     return true;
19911 
19912   if (getLangOpts().CPlusPlus) {
19913     // Check that there are no default arguments (C++ only).
19914     CheckExtraCXXDefaultArguments(D);
19915   }
19916 
19917   return CreateParsedType(T, TInfo);
19918 }
19919 
ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,TypeResult ParsedType)19920 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc,
19921                                             TypeResult ParsedType) {
19922   assert(ParsedType.isUsable() && "Expect usable parsed mapper type");
19923 
19924   QualType MapperType = GetTypeFromParser(ParsedType.get());
19925   assert(!MapperType.isNull() && "Expect valid mapper type");
19926 
19927   // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
19928   //  The type must be of struct, union or class type in C and C++
19929   if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) {
19930     Diag(TyLoc, diag::err_omp_mapper_wrong_type);
19931     return QualType();
19932   }
19933   return MapperType;
19934 }
19935 
ActOnOpenMPDeclareMapperDirective(Scope * S,DeclContext * DC,DeclarationName Name,QualType MapperType,SourceLocation StartLoc,DeclarationName VN,AccessSpecifier AS,Expr * MapperVarRef,ArrayRef<OMPClause * > Clauses,Decl * PrevDeclInScope)19936 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective(
19937     Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType,
19938     SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS,
19939     Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) {
19940   LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName,
19941                       forRedeclarationInCurContext());
19942   // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions
19943   //  A mapper-identifier may not be redeclared in the current scope for the
19944   //  same type or for a type that is compatible according to the base language
19945   //  rules.
19946   llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes;
19947   OMPDeclareMapperDecl *PrevDMD = nullptr;
19948   bool InCompoundScope = true;
19949   if (S != nullptr) {
19950     // Find previous declaration with the same name not referenced in other
19951     // declarations.
19952     FunctionScopeInfo *ParentFn = getEnclosingFunction();
19953     InCompoundScope =
19954         (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty();
19955     LookupName(Lookup, S);
19956     FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false,
19957                          /*AllowInlineNamespace=*/false);
19958     llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious;
19959     LookupResult::Filter Filter = Lookup.makeFilter();
19960     while (Filter.hasNext()) {
19961       auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next());
19962       if (InCompoundScope) {
19963         auto I = UsedAsPrevious.find(PrevDecl);
19964         if (I == UsedAsPrevious.end())
19965           UsedAsPrevious[PrevDecl] = false;
19966         if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope())
19967           UsedAsPrevious[D] = true;
19968       }
19969       PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] =
19970           PrevDecl->getLocation();
19971     }
19972     Filter.done();
19973     if (InCompoundScope) {
19974       for (const auto &PrevData : UsedAsPrevious) {
19975         if (!PrevData.second) {
19976           PrevDMD = PrevData.first;
19977           break;
19978         }
19979       }
19980     }
19981   } else if (PrevDeclInScope) {
19982     auto *PrevDMDInScope = PrevDMD =
19983         cast<OMPDeclareMapperDecl>(PrevDeclInScope);
19984     do {
19985       PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] =
19986           PrevDMDInScope->getLocation();
19987       PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope();
19988     } while (PrevDMDInScope != nullptr);
19989   }
19990   const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType());
19991   bool Invalid = false;
19992   if (I != PreviousRedeclTypes.end()) {
19993     Diag(StartLoc, diag::err_omp_declare_mapper_redefinition)
19994         << MapperType << Name;
19995     Diag(I->second, diag::note_previous_definition);
19996     Invalid = true;
19997   }
19998   // Build expressions for implicit maps of data members with 'default'
19999   // mappers.
20000   SmallVector<OMPClause *, 4> ClausesWithImplicit(Clauses.begin(),
20001                                                   Clauses.end());
20002   if (LangOpts.OpenMP >= 50)
20003     processImplicitMapsWithDefaultMappers(*this, DSAStack, ClausesWithImplicit);
20004   auto *DMD =
20005       OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, MapperType, VN,
20006                                    ClausesWithImplicit, PrevDMD);
20007   if (S)
20008     PushOnScopeChains(DMD, S);
20009   else
20010     DC->addDecl(DMD);
20011   DMD->setAccess(AS);
20012   if (Invalid)
20013     DMD->setInvalidDecl();
20014 
20015   auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl();
20016   VD->setDeclContext(DMD);
20017   VD->setLexicalDeclContext(DMD);
20018   DMD->addDecl(VD);
20019   DMD->setMapperVarRef(MapperVarRef);
20020 
20021   return DeclGroupPtrTy::make(DeclGroupRef(DMD));
20022 }
20023 
20024 ExprResult
ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope * S,QualType MapperType,SourceLocation StartLoc,DeclarationName VN)20025 Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType,
20026                                                SourceLocation StartLoc,
20027                                                DeclarationName VN) {
20028   TypeSourceInfo *TInfo =
20029       Context.getTrivialTypeSourceInfo(MapperType, StartLoc);
20030   auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(),
20031                              StartLoc, StartLoc, VN.getAsIdentifierInfo(),
20032                              MapperType, TInfo, SC_None);
20033   if (S)
20034     PushOnScopeChains(VD, S, /*AddToContext=*/false);
20035   Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc);
20036   DSAStack->addDeclareMapperVarRef(E);
20037   return E;
20038 }
20039 
isOpenMPDeclareMapperVarDeclAllowed(const VarDecl * VD) const20040 bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const {
20041   assert(LangOpts.OpenMP && "Expected OpenMP mode.");
20042   const Expr *Ref = DSAStack->getDeclareMapperVarRef();
20043   if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref)) {
20044     if (VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl())
20045       return true;
20046     if (VD->isUsableInConstantExpressions(Context))
20047       return true;
20048     return false;
20049   }
20050   return true;
20051 }
20052 
getOpenMPDeclareMapperVarName() const20053 const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const {
20054   assert(LangOpts.OpenMP && "Expected OpenMP mode.");
20055   return cast<DeclRefExpr>(DSAStack->getDeclareMapperVarRef())->getDecl();
20056 }
20057 
ActOnOpenMPNumTeamsClause(Expr * NumTeams,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)20058 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams,
20059                                            SourceLocation StartLoc,
20060                                            SourceLocation LParenLoc,
20061                                            SourceLocation EndLoc) {
20062   Expr *ValExpr = NumTeams;
20063   Stmt *HelperValStmt = nullptr;
20064 
20065   // OpenMP [teams Constrcut, Restrictions]
20066   // The num_teams expression must evaluate to a positive integer value.
20067   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams,
20068                                  /*StrictlyPositive=*/true))
20069     return nullptr;
20070 
20071   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
20072   OpenMPDirectiveKind CaptureRegion =
20073       getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP);
20074   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
20075     ValExpr = MakeFullExpr(ValExpr).get();
20076     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
20077     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
20078     HelperValStmt = buildPreInits(Context, Captures);
20079   }
20080 
20081   return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion,
20082                                          StartLoc, LParenLoc, EndLoc);
20083 }
20084 
ActOnOpenMPThreadLimitClause(Expr * ThreadLimit,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)20085 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit,
20086                                               SourceLocation StartLoc,
20087                                               SourceLocation LParenLoc,
20088                                               SourceLocation EndLoc) {
20089   Expr *ValExpr = ThreadLimit;
20090   Stmt *HelperValStmt = nullptr;
20091 
20092   // OpenMP [teams Constrcut, Restrictions]
20093   // The thread_limit expression must evaluate to a positive integer value.
20094   if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit,
20095                                  /*StrictlyPositive=*/true))
20096     return nullptr;
20097 
20098   OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective();
20099   OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause(
20100       DKind, OMPC_thread_limit, LangOpts.OpenMP);
20101   if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) {
20102     ValExpr = MakeFullExpr(ValExpr).get();
20103     llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
20104     ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
20105     HelperValStmt = buildPreInits(Context, Captures);
20106   }
20107 
20108   return new (Context) OMPThreadLimitClause(
20109       ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc);
20110 }
20111 
ActOnOpenMPPriorityClause(Expr * Priority,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)20112 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority,
20113                                            SourceLocation StartLoc,
20114                                            SourceLocation LParenLoc,
20115                                            SourceLocation EndLoc) {
20116   Expr *ValExpr = Priority;
20117   Stmt *HelperValStmt = nullptr;
20118   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
20119 
20120   // OpenMP [2.9.1, task Constrcut]
20121   // The priority-value is a non-negative numerical scalar expression.
20122   if (!isNonNegativeIntegerValue(
20123           ValExpr, *this, OMPC_priority,
20124           /*StrictlyPositive=*/false, /*BuildCapture=*/true,
20125           DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
20126     return nullptr;
20127 
20128   return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion,
20129                                          StartLoc, LParenLoc, EndLoc);
20130 }
20131 
ActOnOpenMPGrainsizeClause(Expr * Grainsize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)20132 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize,
20133                                             SourceLocation StartLoc,
20134                                             SourceLocation LParenLoc,
20135                                             SourceLocation EndLoc) {
20136   Expr *ValExpr = Grainsize;
20137   Stmt *HelperValStmt = nullptr;
20138   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
20139 
20140   // OpenMP [2.9.2, taskloop Constrcut]
20141   // The parameter of the grainsize clause must be a positive integer
20142   // expression.
20143   if (!isNonNegativeIntegerValue(
20144           ValExpr, *this, OMPC_grainsize,
20145           /*StrictlyPositive=*/true, /*BuildCapture=*/true,
20146           DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
20147     return nullptr;
20148 
20149   return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion,
20150                                           StartLoc, LParenLoc, EndLoc);
20151 }
20152 
ActOnOpenMPNumTasksClause(Expr * NumTasks,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)20153 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks,
20154                                            SourceLocation StartLoc,
20155                                            SourceLocation LParenLoc,
20156                                            SourceLocation EndLoc) {
20157   Expr *ValExpr = NumTasks;
20158   Stmt *HelperValStmt = nullptr;
20159   OpenMPDirectiveKind CaptureRegion = OMPD_unknown;
20160 
20161   // OpenMP [2.9.2, taskloop Constrcut]
20162   // The parameter of the num_tasks clause must be a positive integer
20163   // expression.
20164   if (!isNonNegativeIntegerValue(
20165           ValExpr, *this, OMPC_num_tasks,
20166           /*StrictlyPositive=*/true, /*BuildCapture=*/true,
20167           DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt))
20168     return nullptr;
20169 
20170   return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion,
20171                                          StartLoc, LParenLoc, EndLoc);
20172 }
20173 
ActOnOpenMPHintClause(Expr * Hint,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)20174 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc,
20175                                        SourceLocation LParenLoc,
20176                                        SourceLocation EndLoc) {
20177   // OpenMP [2.13.2, critical construct, Description]
20178   // ... where hint-expression is an integer constant expression that evaluates
20179   // to a valid lock hint.
20180   ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint);
20181   if (HintExpr.isInvalid())
20182     return nullptr;
20183   return new (Context)
20184       OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc);
20185 }
20186 
20187 /// Tries to find omp_event_handle_t type.
findOMPEventHandleT(Sema & S,SourceLocation Loc,DSAStackTy * Stack)20188 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc,
20189                                 DSAStackTy *Stack) {
20190   QualType OMPEventHandleT = Stack->getOMPEventHandleT();
20191   if (!OMPEventHandleT.isNull())
20192     return true;
20193   IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t");
20194   ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope());
20195   if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
20196     S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t";
20197     return false;
20198   }
20199   Stack->setOMPEventHandleT(PT.get());
20200   return true;
20201 }
20202 
ActOnOpenMPDetachClause(Expr * Evt,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)20203 OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc,
20204                                          SourceLocation LParenLoc,
20205                                          SourceLocation EndLoc) {
20206   if (!Evt->isValueDependent() && !Evt->isTypeDependent() &&
20207       !Evt->isInstantiationDependent() &&
20208       !Evt->containsUnexpandedParameterPack()) {
20209     if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack))
20210       return nullptr;
20211     // OpenMP 5.0, 2.10.1 task Construct.
20212     // event-handle is a variable of the omp_event_handle_t type.
20213     auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts());
20214     if (!Ref) {
20215       Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
20216           << "omp_event_handle_t" << 0 << Evt->getSourceRange();
20217       return nullptr;
20218     }
20219     auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl());
20220     if (!VD) {
20221       Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
20222           << "omp_event_handle_t" << 0 << Evt->getSourceRange();
20223       return nullptr;
20224     }
20225     if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(),
20226                                         VD->getType()) ||
20227         VD->getType().isConstant(Context)) {
20228       Diag(Evt->getExprLoc(), diag::err_omp_var_expected)
20229           << "omp_event_handle_t" << 1 << VD->getType()
20230           << Evt->getSourceRange();
20231       return nullptr;
20232     }
20233     // OpenMP 5.0, 2.10.1 task Construct
20234     // [detach clause]... The event-handle will be considered as if it was
20235     // specified on a firstprivate clause.
20236     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false);
20237     if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate &&
20238         DVar.RefExpr) {
20239       Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa)
20240           << getOpenMPClauseName(DVar.CKind)
20241           << getOpenMPClauseName(OMPC_firstprivate);
20242       reportOriginalDsa(*this, DSAStack, VD, DVar);
20243       return nullptr;
20244     }
20245   }
20246 
20247   return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc);
20248 }
20249 
ActOnOpenMPDistScheduleClause(OpenMPDistScheduleClauseKind Kind,Expr * ChunkSize,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation KindLoc,SourceLocation CommaLoc,SourceLocation EndLoc)20250 OMPClause *Sema::ActOnOpenMPDistScheduleClause(
20251     OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc,
20252     SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc,
20253     SourceLocation EndLoc) {
20254   if (Kind == OMPC_DIST_SCHEDULE_unknown) {
20255     std::string Values;
20256     Values += "'";
20257     Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0);
20258     Values += "'";
20259     Diag(KindLoc, diag::err_omp_unexpected_clause_value)
20260         << Values << getOpenMPClauseName(OMPC_dist_schedule);
20261     return nullptr;
20262   }
20263   Expr *ValExpr = ChunkSize;
20264   Stmt *HelperValStmt = nullptr;
20265   if (ChunkSize) {
20266     if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() &&
20267         !ChunkSize->isInstantiationDependent() &&
20268         !ChunkSize->containsUnexpandedParameterPack()) {
20269       SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc();
20270       ExprResult Val =
20271           PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize);
20272       if (Val.isInvalid())
20273         return nullptr;
20274 
20275       ValExpr = Val.get();
20276 
20277       // OpenMP [2.7.1, Restrictions]
20278       //  chunk_size must be a loop invariant integer expression with a positive
20279       //  value.
20280       if (Optional<llvm::APSInt> Result =
20281               ValExpr->getIntegerConstantExpr(Context)) {
20282         if (Result->isSigned() && !Result->isStrictlyPositive()) {
20283           Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause)
20284               << "dist_schedule" << ChunkSize->getSourceRange();
20285           return nullptr;
20286         }
20287       } else if (getOpenMPCaptureRegionForClause(
20288                      DSAStack->getCurrentDirective(), OMPC_dist_schedule,
20289                      LangOpts.OpenMP) != OMPD_unknown &&
20290                  !CurContext->isDependentContext()) {
20291         ValExpr = MakeFullExpr(ValExpr).get();
20292         llvm::MapVector<const Expr *, DeclRefExpr *> Captures;
20293         ValExpr = tryBuildCapture(*this, ValExpr, Captures).get();
20294         HelperValStmt = buildPreInits(Context, Captures);
20295       }
20296     }
20297   }
20298 
20299   return new (Context)
20300       OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc,
20301                             Kind, ValExpr, HelperValStmt);
20302 }
20303 
ActOnOpenMPDefaultmapClause(OpenMPDefaultmapClauseModifier M,OpenMPDefaultmapClauseKind Kind,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation MLoc,SourceLocation KindLoc,SourceLocation EndLoc)20304 OMPClause *Sema::ActOnOpenMPDefaultmapClause(
20305     OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind,
20306     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc,
20307     SourceLocation KindLoc, SourceLocation EndLoc) {
20308   if (getLangOpts().OpenMP < 50) {
20309     if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom ||
20310         Kind != OMPC_DEFAULTMAP_scalar) {
20311       std::string Value;
20312       SourceLocation Loc;
20313       Value += "'";
20314       if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) {
20315         Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
20316                                                OMPC_DEFAULTMAP_MODIFIER_tofrom);
20317         Loc = MLoc;
20318       } else {
20319         Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap,
20320                                                OMPC_DEFAULTMAP_scalar);
20321         Loc = KindLoc;
20322       }
20323       Value += "'";
20324       Diag(Loc, diag::err_omp_unexpected_clause_value)
20325           << Value << getOpenMPClauseName(OMPC_defaultmap);
20326       return nullptr;
20327     }
20328   } else {
20329     bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown);
20330     bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) ||
20331                             (LangOpts.OpenMP >= 50 && KindLoc.isInvalid());
20332     if (!isDefaultmapKind || !isDefaultmapModifier) {
20333       StringRef KindValue = "'scalar', 'aggregate', 'pointer'";
20334       if (LangOpts.OpenMP == 50) {
20335         StringRef ModifierValue = "'alloc', 'from', 'to', 'tofrom', "
20336                                   "'firstprivate', 'none', 'default'";
20337         if (!isDefaultmapKind && isDefaultmapModifier) {
20338           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
20339               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
20340         } else if (isDefaultmapKind && !isDefaultmapModifier) {
20341           Diag(MLoc, diag::err_omp_unexpected_clause_value)
20342               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
20343         } else {
20344           Diag(MLoc, diag::err_omp_unexpected_clause_value)
20345               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
20346           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
20347               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
20348         }
20349       } else {
20350         StringRef ModifierValue =
20351             "'alloc', 'from', 'to', 'tofrom', "
20352             "'firstprivate', 'none', 'default', 'present'";
20353         if (!isDefaultmapKind && isDefaultmapModifier) {
20354           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
20355               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
20356         } else if (isDefaultmapKind && !isDefaultmapModifier) {
20357           Diag(MLoc, diag::err_omp_unexpected_clause_value)
20358               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
20359         } else {
20360           Diag(MLoc, diag::err_omp_unexpected_clause_value)
20361               << ModifierValue << getOpenMPClauseName(OMPC_defaultmap);
20362           Diag(KindLoc, diag::err_omp_unexpected_clause_value)
20363               << KindValue << getOpenMPClauseName(OMPC_defaultmap);
20364         }
20365       }
20366       return nullptr;
20367     }
20368 
20369     // OpenMP [5.0, 2.12.5, Restrictions, p. 174]
20370     //  At most one defaultmap clause for each category can appear on the
20371     //  directive.
20372     if (DSAStack->checkDefaultmapCategory(Kind)) {
20373       Diag(StartLoc, diag::err_omp_one_defaultmap_each_category);
20374       return nullptr;
20375     }
20376   }
20377   if (Kind == OMPC_DEFAULTMAP_unknown) {
20378     // Variable category is not specified - mark all categories.
20379     DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc);
20380     DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc);
20381     DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc);
20382   } else {
20383     DSAStack->setDefaultDMAAttr(M, Kind, StartLoc);
20384   }
20385 
20386   return new (Context)
20387       OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M);
20388 }
20389 
ActOnStartOpenMPDeclareTargetContext(DeclareTargetContextInfo & DTCI)20390 bool Sema::ActOnStartOpenMPDeclareTargetContext(
20391     DeclareTargetContextInfo &DTCI) {
20392   DeclContext *CurLexicalContext = getCurLexicalContext();
20393   if (!CurLexicalContext->isFileContext() &&
20394       !CurLexicalContext->isExternCContext() &&
20395       !CurLexicalContext->isExternCXXContext() &&
20396       !isa<CXXRecordDecl>(CurLexicalContext) &&
20397       !isa<ClassTemplateDecl>(CurLexicalContext) &&
20398       !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) &&
20399       !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) {
20400     Diag(DTCI.Loc, diag::err_omp_region_not_file_context);
20401     return false;
20402   }
20403   DeclareTargetNesting.push_back(DTCI);
20404   return true;
20405 }
20406 
20407 const Sema::DeclareTargetContextInfo
ActOnOpenMPEndDeclareTargetDirective()20408 Sema::ActOnOpenMPEndDeclareTargetDirective() {
20409   assert(!DeclareTargetNesting.empty() &&
20410          "check isInOpenMPDeclareTargetContext() first!");
20411   return DeclareTargetNesting.pop_back_val();
20412 }
20413 
ActOnFinishedOpenMPDeclareTargetContext(DeclareTargetContextInfo & DTCI)20414 void Sema::ActOnFinishedOpenMPDeclareTargetContext(
20415     DeclareTargetContextInfo &DTCI) {
20416   for (auto &It : DTCI.ExplicitlyMapped)
20417     ActOnOpenMPDeclareTargetName(It.first, It.second.Loc, It.second.MT,
20418                                  DTCI.DT);
20419 }
20420 
lookupOpenMPDeclareTargetName(Scope * CurScope,CXXScopeSpec & ScopeSpec,const DeclarationNameInfo & Id)20421 NamedDecl *Sema::lookupOpenMPDeclareTargetName(Scope *CurScope,
20422                                                CXXScopeSpec &ScopeSpec,
20423                                                const DeclarationNameInfo &Id) {
20424   LookupResult Lookup(*this, Id, LookupOrdinaryName);
20425   LookupParsedName(Lookup, CurScope, &ScopeSpec, true);
20426 
20427   if (Lookup.isAmbiguous())
20428     return nullptr;
20429   Lookup.suppressDiagnostics();
20430 
20431   if (!Lookup.isSingleResult()) {
20432     VarOrFuncDeclFilterCCC CCC(*this);
20433     if (TypoCorrection Corrected =
20434             CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC,
20435                         CTK_ErrorRecovery)) {
20436       diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest)
20437                                   << Id.getName());
20438       checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl());
20439       return nullptr;
20440     }
20441 
20442     Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName();
20443     return nullptr;
20444   }
20445 
20446   NamedDecl *ND = Lookup.getAsSingle<NamedDecl>();
20447   if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) &&
20448       !isa<FunctionTemplateDecl>(ND)) {
20449     Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName();
20450     return nullptr;
20451   }
20452   return ND;
20453 }
20454 
ActOnOpenMPDeclareTargetName(NamedDecl * ND,SourceLocation Loc,OMPDeclareTargetDeclAttr::MapTypeTy MT,OMPDeclareTargetDeclAttr::DevTypeTy DT)20455 void Sema::ActOnOpenMPDeclareTargetName(
20456     NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT,
20457     OMPDeclareTargetDeclAttr::DevTypeTy DT) {
20458   assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) ||
20459           isa<FunctionTemplateDecl>(ND)) &&
20460          "Expected variable, function or function template.");
20461 
20462   // Diagnose marking after use as it may lead to incorrect diagnosis and
20463   // codegen.
20464   if (LangOpts.OpenMP >= 50 &&
20465       (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced()))
20466     Diag(Loc, diag::warn_omp_declare_target_after_first_use);
20467 
20468   // Explicit declare target lists have precedence.
20469   const unsigned Level = -1;
20470 
20471   auto *VD = cast<ValueDecl>(ND);
20472   llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
20473       OMPDeclareTargetDeclAttr::getActiveAttr(VD);
20474   if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getDevType() != DT &&
20475       ActiveAttr.getValue()->getLevel() == Level) {
20476     Diag(Loc, diag::err_omp_device_type_mismatch)
20477         << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT)
20478         << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(
20479                ActiveAttr.getValue()->getDevType());
20480     return;
20481   }
20482   if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getMapType() != MT &&
20483       ActiveAttr.getValue()->getLevel() == Level) {
20484     Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND;
20485     return;
20486   }
20487 
20488   if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getLevel() == Level)
20489     return;
20490 
20491   auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, Level,
20492                                                      SourceRange(Loc, Loc));
20493   ND->addAttr(A);
20494   if (ASTMutationListener *ML = Context.getASTMutationListener())
20495     ML->DeclarationMarkedOpenMPDeclareTarget(ND, A);
20496   checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc);
20497 }
20498 
checkDeclInTargetContext(SourceLocation SL,SourceRange SR,Sema & SemaRef,Decl * D)20499 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR,
20500                                      Sema &SemaRef, Decl *D) {
20501   if (!D || !isa<VarDecl>(D))
20502     return;
20503   auto *VD = cast<VarDecl>(D);
20504   Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy =
20505       OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD);
20506   if (SemaRef.LangOpts.OpenMP >= 50 &&
20507       (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) ||
20508        SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) &&
20509       VD->hasGlobalStorage()) {
20510     if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) {
20511       // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions
20512       // If a lambda declaration and definition appears between a
20513       // declare target directive and the matching end declare target
20514       // directive, all variables that are captured by the lambda
20515       // expression must also appear in a to clause.
20516       SemaRef.Diag(VD->getLocation(),
20517                    diag::err_omp_lambda_capture_in_declare_target_not_to);
20518       SemaRef.Diag(SL, diag::note_var_explicitly_captured_here)
20519           << VD << 0 << SR;
20520       return;
20521     }
20522   }
20523   if (MapTy.hasValue())
20524     return;
20525   SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context);
20526   SemaRef.Diag(SL, diag::note_used_here) << SR;
20527 }
20528 
checkValueDeclInTarget(SourceLocation SL,SourceRange SR,Sema & SemaRef,DSAStackTy * Stack,ValueDecl * VD)20529 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR,
20530                                    Sema &SemaRef, DSAStackTy *Stack,
20531                                    ValueDecl *VD) {
20532   return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) ||
20533          checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(),
20534                            /*FullCheck=*/false);
20535 }
20536 
checkDeclIsAllowedInOpenMPTarget(Expr * E,Decl * D,SourceLocation IdLoc)20537 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D,
20538                                             SourceLocation IdLoc) {
20539   if (!D || D->isInvalidDecl())
20540     return;
20541   SourceRange SR = E ? E->getSourceRange() : D->getSourceRange();
20542   SourceLocation SL = E ? E->getBeginLoc() : D->getLocation();
20543   if (auto *VD = dyn_cast<VarDecl>(D)) {
20544     // Only global variables can be marked as declare target.
20545     if (!VD->isFileVarDecl() && !VD->isStaticLocal() &&
20546         !VD->isStaticDataMember())
20547       return;
20548     // 2.10.6: threadprivate variable cannot appear in a declare target
20549     // directive.
20550     if (DSAStack->isThreadPrivate(VD)) {
20551       Diag(SL, diag::err_omp_threadprivate_in_target);
20552       reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false));
20553       return;
20554     }
20555   }
20556   if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
20557     D = FTD->getTemplatedDecl();
20558   if (auto *FD = dyn_cast<FunctionDecl>(D)) {
20559     llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res =
20560         OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD);
20561     if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) {
20562       Diag(IdLoc, diag::err_omp_function_in_link_clause);
20563       Diag(FD->getLocation(), diag::note_defined_here) << FD;
20564       return;
20565     }
20566   }
20567   if (auto *VD = dyn_cast<ValueDecl>(D)) {
20568     // Problem if any with var declared with incomplete type will be reported
20569     // as normal, so no need to check it here.
20570     if ((E || !VD->getType()->isIncompleteType()) &&
20571         !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD))
20572       return;
20573     if (!E && isInOpenMPDeclareTargetContext()) {
20574       // Checking declaration inside declare target region.
20575       if (isa<VarDecl>(D) || isa<FunctionDecl>(D) ||
20576           isa<FunctionTemplateDecl>(D)) {
20577         llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr =
20578             OMPDeclareTargetDeclAttr::getActiveAttr(VD);
20579         unsigned Level = DeclareTargetNesting.size();
20580         if (ActiveAttr.hasValue() && ActiveAttr.getValue()->getLevel() >= Level)
20581           return;
20582         DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back();
20583         auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(
20584             Context, OMPDeclareTargetDeclAttr::MT_To, DTCI.DT, Level,
20585             SourceRange(DTCI.Loc, DTCI.Loc));
20586         D->addAttr(A);
20587         if (ASTMutationListener *ML = Context.getASTMutationListener())
20588           ML->DeclarationMarkedOpenMPDeclareTarget(D, A);
20589       }
20590       return;
20591     }
20592   }
20593   if (!E)
20594     return;
20595   checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D);
20596 }
20597 
ActOnOpenMPToClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,ArrayRef<SourceLocation> MotionModifiersLoc,CXXScopeSpec & MapperIdScopeSpec,DeclarationNameInfo & MapperId,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs,ArrayRef<Expr * > UnresolvedMappers)20598 OMPClause *Sema::ActOnOpenMPToClause(
20599     ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
20600     ArrayRef<SourceLocation> MotionModifiersLoc,
20601     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
20602     SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
20603     const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
20604   OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
20605                                           OMPC_MOTION_MODIFIER_unknown};
20606   SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
20607 
20608   // Process motion-modifiers, flag errors for duplicate modifiers.
20609   unsigned Count = 0;
20610   for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
20611     if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
20612         llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) {
20613       Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
20614       continue;
20615     }
20616     assert(Count < NumberOfOMPMotionModifiers &&
20617            "Modifiers exceed the allowed number of motion modifiers");
20618     Modifiers[Count] = MotionModifiers[I];
20619     ModifiersLoc[Count] = MotionModifiersLoc[I];
20620     ++Count;
20621   }
20622 
20623   MappableVarListInfo MVLI(VarList);
20624   checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc,
20625                               MapperIdScopeSpec, MapperId, UnresolvedMappers);
20626   if (MVLI.ProcessedVarList.empty())
20627     return nullptr;
20628 
20629   return OMPToClause::Create(
20630       Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
20631       MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
20632       MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
20633 }
20634 
ActOnOpenMPFromClause(ArrayRef<OpenMPMotionModifierKind> MotionModifiers,ArrayRef<SourceLocation> MotionModifiersLoc,CXXScopeSpec & MapperIdScopeSpec,DeclarationNameInfo & MapperId,SourceLocation ColonLoc,ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs,ArrayRef<Expr * > UnresolvedMappers)20635 OMPClause *Sema::ActOnOpenMPFromClause(
20636     ArrayRef<OpenMPMotionModifierKind> MotionModifiers,
20637     ArrayRef<SourceLocation> MotionModifiersLoc,
20638     CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId,
20639     SourceLocation ColonLoc, ArrayRef<Expr *> VarList,
20640     const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) {
20641   OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown,
20642                                           OMPC_MOTION_MODIFIER_unknown};
20643   SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers];
20644 
20645   // Process motion-modifiers, flag errors for duplicate modifiers.
20646   unsigned Count = 0;
20647   for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) {
20648     if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown &&
20649         llvm::find(Modifiers, MotionModifiers[I]) != std::end(Modifiers)) {
20650       Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier);
20651       continue;
20652     }
20653     assert(Count < NumberOfOMPMotionModifiers &&
20654            "Modifiers exceed the allowed number of motion modifiers");
20655     Modifiers[Count] = MotionModifiers[I];
20656     ModifiersLoc[Count] = MotionModifiersLoc[I];
20657     ++Count;
20658   }
20659 
20660   MappableVarListInfo MVLI(VarList);
20661   checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc,
20662                               MapperIdScopeSpec, MapperId, UnresolvedMappers);
20663   if (MVLI.ProcessedVarList.empty())
20664     return nullptr;
20665 
20666   return OMPFromClause::Create(
20667       Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations,
20668       MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc,
20669       MapperIdScopeSpec.getWithLocInContext(Context), MapperId);
20670 }
20671 
ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs)20672 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList,
20673                                                const OMPVarListLocTy &Locs) {
20674   MappableVarListInfo MVLI(VarList);
20675   SmallVector<Expr *, 8> PrivateCopies;
20676   SmallVector<Expr *, 8> Inits;
20677 
20678   for (Expr *RefExpr : VarList) {
20679     assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause.");
20680     SourceLocation ELoc;
20681     SourceRange ERange;
20682     Expr *SimpleRefExpr = RefExpr;
20683     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20684     if (Res.second) {
20685       // It will be analyzed later.
20686       MVLI.ProcessedVarList.push_back(RefExpr);
20687       PrivateCopies.push_back(nullptr);
20688       Inits.push_back(nullptr);
20689     }
20690     ValueDecl *D = Res.first;
20691     if (!D)
20692       continue;
20693 
20694     QualType Type = D->getType();
20695     Type = Type.getNonReferenceType().getUnqualifiedType();
20696 
20697     auto *VD = dyn_cast<VarDecl>(D);
20698 
20699     // Item should be a pointer or reference to pointer.
20700     if (!Type->isPointerType()) {
20701       Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer)
20702           << 0 << RefExpr->getSourceRange();
20703       continue;
20704     }
20705 
20706     // Build the private variable and the expression that refers to it.
20707     auto VDPrivate =
20708         buildVarDecl(*this, ELoc, Type, D->getName(),
20709                      D->hasAttrs() ? &D->getAttrs() : nullptr,
20710                      VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr);
20711     if (VDPrivate->isInvalidDecl())
20712       continue;
20713 
20714     CurContext->addDecl(VDPrivate);
20715     DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr(
20716         *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc);
20717 
20718     // Add temporary variable to initialize the private copy of the pointer.
20719     VarDecl *VDInit =
20720         buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp");
20721     DeclRefExpr *VDInitRefExpr = buildDeclRefExpr(
20722         *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc());
20723     AddInitializerToDecl(VDPrivate,
20724                          DefaultLvalueConversion(VDInitRefExpr).get(),
20725                          /*DirectInit=*/false);
20726 
20727     // If required, build a capture to implement the privatization initialized
20728     // with the current list item value.
20729     DeclRefExpr *Ref = nullptr;
20730     if (!VD)
20731       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
20732     MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
20733     PrivateCopies.push_back(VDPrivateRefExpr);
20734     Inits.push_back(VDInitRefExpr);
20735 
20736     // We need to add a data sharing attribute for this variable to make sure it
20737     // is correctly captured. A variable that shows up in a use_device_ptr has
20738     // similar properties of a first private variable.
20739     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
20740 
20741     // Create a mappable component for the list item. List items in this clause
20742     // only need a component.
20743     MVLI.VarBaseDeclarations.push_back(D);
20744     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
20745     MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D,
20746                                            /*IsNonContiguous=*/false);
20747   }
20748 
20749   if (MVLI.ProcessedVarList.empty())
20750     return nullptr;
20751 
20752   return OMPUseDevicePtrClause::Create(
20753       Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits,
20754       MVLI.VarBaseDeclarations, MVLI.VarComponents);
20755 }
20756 
ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs)20757 OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList,
20758                                                 const OMPVarListLocTy &Locs) {
20759   MappableVarListInfo MVLI(VarList);
20760 
20761   for (Expr *RefExpr : VarList) {
20762     assert(RefExpr && "NULL expr in OpenMP use_device_addr clause.");
20763     SourceLocation ELoc;
20764     SourceRange ERange;
20765     Expr *SimpleRefExpr = RefExpr;
20766     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
20767                               /*AllowArraySection=*/true);
20768     if (Res.second) {
20769       // It will be analyzed later.
20770       MVLI.ProcessedVarList.push_back(RefExpr);
20771     }
20772     ValueDecl *D = Res.first;
20773     if (!D)
20774       continue;
20775     auto *VD = dyn_cast<VarDecl>(D);
20776 
20777     // If required, build a capture to implement the privatization initialized
20778     // with the current list item value.
20779     DeclRefExpr *Ref = nullptr;
20780     if (!VD)
20781       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true);
20782     MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref);
20783 
20784     // We need to add a data sharing attribute for this variable to make sure it
20785     // is correctly captured. A variable that shows up in a use_device_addr has
20786     // similar properties of a first private variable.
20787     DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref);
20788 
20789     // Create a mappable component for the list item. List items in this clause
20790     // only need a component.
20791     MVLI.VarBaseDeclarations.push_back(D);
20792     MVLI.VarComponents.emplace_back();
20793     Expr *Component = SimpleRefExpr;
20794     if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) ||
20795                isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts())))
20796       Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get();
20797     MVLI.VarComponents.back().emplace_back(Component, D,
20798                                            /*IsNonContiguous=*/false);
20799   }
20800 
20801   if (MVLI.ProcessedVarList.empty())
20802     return nullptr;
20803 
20804   return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList,
20805                                         MVLI.VarBaseDeclarations,
20806                                         MVLI.VarComponents);
20807 }
20808 
ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr * > VarList,const OMPVarListLocTy & Locs)20809 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList,
20810                                               const OMPVarListLocTy &Locs) {
20811   MappableVarListInfo MVLI(VarList);
20812   for (Expr *RefExpr : VarList) {
20813     assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause.");
20814     SourceLocation ELoc;
20815     SourceRange ERange;
20816     Expr *SimpleRefExpr = RefExpr;
20817     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20818     if (Res.second) {
20819       // It will be analyzed later.
20820       MVLI.ProcessedVarList.push_back(RefExpr);
20821     }
20822     ValueDecl *D = Res.first;
20823     if (!D)
20824       continue;
20825 
20826     QualType Type = D->getType();
20827     // item should be a pointer or array or reference to pointer or array
20828     if (!Type.getNonReferenceType()->isPointerType() &&
20829         !Type.getNonReferenceType()->isArrayType()) {
20830       Diag(ELoc, diag::err_omp_argument_type_isdeviceptr)
20831           << 0 << RefExpr->getSourceRange();
20832       continue;
20833     }
20834 
20835     // Check if the declaration in the clause does not show up in any data
20836     // sharing attribute.
20837     DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false);
20838     if (isOpenMPPrivate(DVar.CKind)) {
20839       Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa)
20840           << getOpenMPClauseName(DVar.CKind)
20841           << getOpenMPClauseName(OMPC_is_device_ptr)
20842           << getOpenMPDirectiveName(DSAStack->getCurrentDirective());
20843       reportOriginalDsa(*this, DSAStack, D, DVar);
20844       continue;
20845     }
20846 
20847     const Expr *ConflictExpr;
20848     if (DSAStack->checkMappableExprComponentListsForDecl(
20849             D, /*CurrentRegionOnly=*/true,
20850             [&ConflictExpr](
20851                 OMPClauseMappableExprCommon::MappableExprComponentListRef R,
20852                 OpenMPClauseKind) -> bool {
20853               ConflictExpr = R.front().getAssociatedExpression();
20854               return true;
20855             })) {
20856       Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange();
20857       Diag(ConflictExpr->getExprLoc(), diag::note_used_here)
20858           << ConflictExpr->getSourceRange();
20859       continue;
20860     }
20861 
20862     // Store the components in the stack so that they can be used to check
20863     // against other clauses later on.
20864     OMPClauseMappableExprCommon::MappableComponent MC(
20865         SimpleRefExpr, D, /*IsNonContiguous=*/false);
20866     DSAStack->addMappableExpressionComponents(
20867         D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr);
20868 
20869     // Record the expression we've just processed.
20870     MVLI.ProcessedVarList.push_back(SimpleRefExpr);
20871 
20872     // Create a mappable component for the list item. List items in this clause
20873     // only need a component. We use a null declaration to signal fields in
20874     // 'this'.
20875     assert((isa<DeclRefExpr>(SimpleRefExpr) ||
20876             isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) &&
20877            "Unexpected device pointer expression!");
20878     MVLI.VarBaseDeclarations.push_back(
20879         isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr);
20880     MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1);
20881     MVLI.VarComponents.back().push_back(MC);
20882   }
20883 
20884   if (MVLI.ProcessedVarList.empty())
20885     return nullptr;
20886 
20887   return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList,
20888                                       MVLI.VarBaseDeclarations,
20889                                       MVLI.VarComponents);
20890 }
20891 
ActOnOpenMPAllocateClause(Expr * Allocator,ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation ColonLoc,SourceLocation LParenLoc,SourceLocation EndLoc)20892 OMPClause *Sema::ActOnOpenMPAllocateClause(
20893     Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc,
20894     SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) {
20895   if (Allocator) {
20896     // OpenMP [2.11.4 allocate Clause, Description]
20897     // allocator is an expression of omp_allocator_handle_t type.
20898     if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack))
20899       return nullptr;
20900 
20901     ExprResult AllocatorRes = DefaultLvalueConversion(Allocator);
20902     if (AllocatorRes.isInvalid())
20903       return nullptr;
20904     AllocatorRes = PerformImplicitConversion(AllocatorRes.get(),
20905                                              DSAStack->getOMPAllocatorHandleT(),
20906                                              Sema::AA_Initializing,
20907                                              /*AllowExplicit=*/true);
20908     if (AllocatorRes.isInvalid())
20909       return nullptr;
20910     Allocator = AllocatorRes.get();
20911   } else {
20912     // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions.
20913     // allocate clauses that appear on a target construct or on constructs in a
20914     // target region must specify an allocator expression unless a requires
20915     // directive with the dynamic_allocators clause is present in the same
20916     // compilation unit.
20917     if (LangOpts.OpenMPIsDevice &&
20918         !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())
20919       targetDiag(StartLoc, diag::err_expected_allocator_expression);
20920   }
20921   // Analyze and build list of variables.
20922   SmallVector<Expr *, 8> Vars;
20923   for (Expr *RefExpr : VarList) {
20924     assert(RefExpr && "NULL expr in OpenMP private clause.");
20925     SourceLocation ELoc;
20926     SourceRange ERange;
20927     Expr *SimpleRefExpr = RefExpr;
20928     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20929     if (Res.second) {
20930       // It will be analyzed later.
20931       Vars.push_back(RefExpr);
20932     }
20933     ValueDecl *D = Res.first;
20934     if (!D)
20935       continue;
20936 
20937     auto *VD = dyn_cast<VarDecl>(D);
20938     DeclRefExpr *Ref = nullptr;
20939     if (!VD && !CurContext->isDependentContext())
20940       Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
20941     Vars.push_back((VD || CurContext->isDependentContext())
20942                        ? RefExpr->IgnoreParens()
20943                        : Ref);
20944   }
20945 
20946   if (Vars.empty())
20947     return nullptr;
20948 
20949   if (Allocator)
20950     DSAStack->addInnerAllocatorExpr(Allocator);
20951   return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator,
20952                                    ColonLoc, EndLoc, Vars);
20953 }
20954 
ActOnOpenMPNontemporalClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)20955 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList,
20956                                               SourceLocation StartLoc,
20957                                               SourceLocation LParenLoc,
20958                                               SourceLocation EndLoc) {
20959   SmallVector<Expr *, 8> Vars;
20960   for (Expr *RefExpr : VarList) {
20961     assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
20962     SourceLocation ELoc;
20963     SourceRange ERange;
20964     Expr *SimpleRefExpr = RefExpr;
20965     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange);
20966     if (Res.second)
20967       // It will be analyzed later.
20968       Vars.push_back(RefExpr);
20969     ValueDecl *D = Res.first;
20970     if (!D)
20971       continue;
20972 
20973     // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions.
20974     // A list-item cannot appear in more than one nontemporal clause.
20975     if (const Expr *PrevRef =
20976             DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) {
20977       Diag(ELoc, diag::err_omp_used_in_clause_twice)
20978           << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange;
20979       Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa)
20980           << getOpenMPClauseName(OMPC_nontemporal);
20981       continue;
20982     }
20983 
20984     Vars.push_back(RefExpr);
20985   }
20986 
20987   if (Vars.empty())
20988     return nullptr;
20989 
20990   return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc,
20991                                       Vars);
20992 }
20993 
ActOnOpenMPInclusiveClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)20994 OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList,
20995                                             SourceLocation StartLoc,
20996                                             SourceLocation LParenLoc,
20997                                             SourceLocation EndLoc) {
20998   SmallVector<Expr *, 8> Vars;
20999   for (Expr *RefExpr : VarList) {
21000     assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
21001     SourceLocation ELoc;
21002     SourceRange ERange;
21003     Expr *SimpleRefExpr = RefExpr;
21004     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
21005                               /*AllowArraySection=*/true);
21006     if (Res.second)
21007       // It will be analyzed later.
21008       Vars.push_back(RefExpr);
21009     ValueDecl *D = Res.first;
21010     if (!D)
21011       continue;
21012 
21013     const DSAStackTy::DSAVarData DVar =
21014         DSAStack->getTopDSA(D, /*FromParent=*/true);
21015     // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
21016     // A list item that appears in the inclusive or exclusive clause must appear
21017     // in a reduction clause with the inscan modifier on the enclosing
21018     // worksharing-loop, worksharing-loop SIMD, or simd construct.
21019     if (DVar.CKind != OMPC_reduction ||
21020         DVar.Modifier != OMPC_REDUCTION_inscan)
21021       Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
21022           << RefExpr->getSourceRange();
21023 
21024     if (DSAStack->getParentDirective() != OMPD_unknown)
21025       DSAStack->markDeclAsUsedInScanDirective(D);
21026     Vars.push_back(RefExpr);
21027   }
21028 
21029   if (Vars.empty())
21030     return nullptr;
21031 
21032   return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
21033 }
21034 
ActOnOpenMPExclusiveClause(ArrayRef<Expr * > VarList,SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc)21035 OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList,
21036                                             SourceLocation StartLoc,
21037                                             SourceLocation LParenLoc,
21038                                             SourceLocation EndLoc) {
21039   SmallVector<Expr *, 8> Vars;
21040   for (Expr *RefExpr : VarList) {
21041     assert(RefExpr && "NULL expr in OpenMP nontemporal clause.");
21042     SourceLocation ELoc;
21043     SourceRange ERange;
21044     Expr *SimpleRefExpr = RefExpr;
21045     auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
21046                               /*AllowArraySection=*/true);
21047     if (Res.second)
21048       // It will be analyzed later.
21049       Vars.push_back(RefExpr);
21050     ValueDecl *D = Res.first;
21051     if (!D)
21052       continue;
21053 
21054     OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective();
21055     DSAStackTy::DSAVarData DVar;
21056     if (ParentDirective != OMPD_unknown)
21057       DVar = DSAStack->getTopDSA(D, /*FromParent=*/true);
21058     // OpenMP 5.0, 2.9.6, scan Directive, Restrictions.
21059     // A list item that appears in the inclusive or exclusive clause must appear
21060     // in a reduction clause with the inscan modifier on the enclosing
21061     // worksharing-loop, worksharing-loop SIMD, or simd construct.
21062     if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction ||
21063         DVar.Modifier != OMPC_REDUCTION_inscan) {
21064       Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction)
21065           << RefExpr->getSourceRange();
21066     } else {
21067       DSAStack->markDeclAsUsedInScanDirective(D);
21068     }
21069     Vars.push_back(RefExpr);
21070   }
21071 
21072   if (Vars.empty())
21073     return nullptr;
21074 
21075   return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars);
21076 }
21077 
21078 /// Tries to find omp_alloctrait_t type.
findOMPAlloctraitT(Sema & S,SourceLocation Loc,DSAStackTy * Stack)21079 static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) {
21080   QualType OMPAlloctraitT = Stack->getOMPAlloctraitT();
21081   if (!OMPAlloctraitT.isNull())
21082     return true;
21083   IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t");
21084   ParsedType PT = S.getTypeName(II, Loc, S.getCurScope());
21085   if (!PT.getAsOpaquePtr() || PT.get().isNull()) {
21086     S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t";
21087     return false;
21088   }
21089   Stack->setOMPAlloctraitT(PT.get());
21090   return true;
21091 }
21092 
ActOnOpenMPUsesAllocatorClause(SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation EndLoc,ArrayRef<UsesAllocatorsData> Data)21093 OMPClause *Sema::ActOnOpenMPUsesAllocatorClause(
21094     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc,
21095     ArrayRef<UsesAllocatorsData> Data) {
21096   // OpenMP [2.12.5, target Construct]
21097   // allocator is an identifier of omp_allocator_handle_t type.
21098   if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack))
21099     return nullptr;
21100   // OpenMP [2.12.5, target Construct]
21101   // allocator-traits-array is an identifier of const omp_alloctrait_t * type.
21102   if (llvm::any_of(
21103           Data,
21104           [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) &&
21105       !findOMPAlloctraitT(*this, StartLoc, DSAStack))
21106     return nullptr;
21107   llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators;
21108   for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) {
21109     auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I);
21110     StringRef Allocator =
21111         OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind);
21112     DeclarationName AllocatorName = &Context.Idents.get(Allocator);
21113     PredefinedAllocators.insert(LookupSingleName(
21114         TUScope, AllocatorName, StartLoc, Sema::LookupAnyName));
21115   }
21116 
21117   SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData;
21118   for (const UsesAllocatorsData &D : Data) {
21119     Expr *AllocatorExpr = nullptr;
21120     // Check allocator expression.
21121     if (D.Allocator->isTypeDependent()) {
21122       AllocatorExpr = D.Allocator;
21123     } else {
21124       // Traits were specified - need to assign new allocator to the specified
21125       // allocator, so it must be an lvalue.
21126       AllocatorExpr = D.Allocator->IgnoreParenImpCasts();
21127       auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr);
21128       bool IsPredefinedAllocator = false;
21129       if (DRE)
21130         IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl());
21131       if (!DRE ||
21132           !(Context.hasSameUnqualifiedType(
21133                 AllocatorExpr->getType(), DSAStack->getOMPAllocatorHandleT()) ||
21134             Context.typesAreCompatible(AllocatorExpr->getType(),
21135                                        DSAStack->getOMPAllocatorHandleT(),
21136                                        /*CompareUnqualified=*/true)) ||
21137           (!IsPredefinedAllocator &&
21138            (AllocatorExpr->getType().isConstant(Context) ||
21139             !AllocatorExpr->isLValue()))) {
21140         Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected)
21141             << "omp_allocator_handle_t" << (DRE ? 1 : 0)
21142             << AllocatorExpr->getType() << D.Allocator->getSourceRange();
21143         continue;
21144       }
21145       // OpenMP [2.12.5, target Construct]
21146       // Predefined allocators appearing in a uses_allocators clause cannot have
21147       // traits specified.
21148       if (IsPredefinedAllocator && D.AllocatorTraits) {
21149         Diag(D.AllocatorTraits->getExprLoc(),
21150              diag::err_omp_predefined_allocator_with_traits)
21151             << D.AllocatorTraits->getSourceRange();
21152         Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator)
21153             << cast<NamedDecl>(DRE->getDecl())->getName()
21154             << D.Allocator->getSourceRange();
21155         continue;
21156       }
21157       // OpenMP [2.12.5, target Construct]
21158       // Non-predefined allocators appearing in a uses_allocators clause must
21159       // have traits specified.
21160       if (!IsPredefinedAllocator && !D.AllocatorTraits) {
21161         Diag(D.Allocator->getExprLoc(),
21162              diag::err_omp_nonpredefined_allocator_without_traits);
21163         continue;
21164       }
21165       // No allocator traits - just convert it to rvalue.
21166       if (!D.AllocatorTraits)
21167         AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get();
21168       DSAStack->addUsesAllocatorsDecl(
21169           DRE->getDecl(),
21170           IsPredefinedAllocator
21171               ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator
21172               : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator);
21173     }
21174     Expr *AllocatorTraitsExpr = nullptr;
21175     if (D.AllocatorTraits) {
21176       if (D.AllocatorTraits->isTypeDependent()) {
21177         AllocatorTraitsExpr = D.AllocatorTraits;
21178       } else {
21179         // OpenMP [2.12.5, target Construct]
21180         // Arrays that contain allocator traits that appear in a uses_allocators
21181         // clause must be constant arrays, have constant values and be defined
21182         // in the same scope as the construct in which the clause appears.
21183         AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts();
21184         // Check that traits expr is a constant array.
21185         QualType TraitTy;
21186         if (const ArrayType *Ty =
21187                 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe())
21188           if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty))
21189             TraitTy = ConstArrayTy->getElementType();
21190         if (TraitTy.isNull() ||
21191             !(Context.hasSameUnqualifiedType(TraitTy,
21192                                              DSAStack->getOMPAlloctraitT()) ||
21193               Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(),
21194                                          /*CompareUnqualified=*/true))) {
21195           Diag(D.AllocatorTraits->getExprLoc(),
21196                diag::err_omp_expected_array_alloctraits)
21197               << AllocatorTraitsExpr->getType();
21198           continue;
21199         }
21200         // Do not map by default allocator traits if it is a standalone
21201         // variable.
21202         if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr))
21203           DSAStack->addUsesAllocatorsDecl(
21204               DRE->getDecl(),
21205               DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait);
21206       }
21207     }
21208     OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back();
21209     NewD.Allocator = AllocatorExpr;
21210     NewD.AllocatorTraits = AllocatorTraitsExpr;
21211     NewD.LParenLoc = D.LParenLoc;
21212     NewD.RParenLoc = D.RParenLoc;
21213   }
21214   return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc,
21215                                          NewData);
21216 }
21217 
ActOnOpenMPAffinityClause(SourceLocation StartLoc,SourceLocation LParenLoc,SourceLocation ColonLoc,SourceLocation EndLoc,Expr * Modifier,ArrayRef<Expr * > Locators)21218 OMPClause *Sema::ActOnOpenMPAffinityClause(
21219     SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc,
21220     SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) {
21221   SmallVector<Expr *, 8> Vars;
21222   for (Expr *RefExpr : Locators) {
21223     assert(RefExpr && "NULL expr in OpenMP shared clause.");
21224     if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) {
21225       // It will be analyzed later.
21226       Vars.push_back(RefExpr);
21227       continue;
21228     }
21229 
21230     SourceLocation ELoc = RefExpr->getExprLoc();
21231     Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts();
21232 
21233     if (!SimpleExpr->isLValue()) {
21234       Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
21235           << 1 << 0 << RefExpr->getSourceRange();
21236       continue;
21237     }
21238 
21239     ExprResult Res;
21240     {
21241       Sema::TentativeAnalysisScope Trap(*this);
21242       Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr);
21243     }
21244     if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) &&
21245         !isa<OMPArrayShapingExpr>(SimpleExpr)) {
21246       Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item)
21247           << 1 << 0 << RefExpr->getSourceRange();
21248       continue;
21249     }
21250     Vars.push_back(SimpleExpr);
21251   }
21252 
21253   return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc,
21254                                    EndLoc, Modifier, Vars);
21255 }
21256